From 3d9b350a9cab7faaf718313c197ff868c4af3c6a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marko=20M=C3=A4kel=C3=A4?= Date: Fri, 14 Oct 2022 11:00:34 +0300 Subject: [PATCH 01/72] Fix clang -Wunused-but-set-variable --- storage/innobase/data/data0data.cc | 8 +++----- storage/innobase/gis/gis0rtree.cc | 6 +++--- storage/innobase/include/ut0lst.h | 31 +++++++++++++----------------- 3 files changed, 19 insertions(+), 26 deletions(-) diff --git a/storage/innobase/data/data0data.cc b/storage/innobase/data/data0data.cc index 3e23cd6f662..885f79d1239 100644 --- a/storage/innobase/data/data0data.cc +++ b/storage/innobase/data/data0data.cc @@ -1,7 +1,7 @@ /***************************************************************************** Copyright (c) 1994, 2016, Oracle and/or its affiliates. All Rights Reserved. -Copyright (c) 2017, 2020, MariaDB Corporation. +Copyright (c) 2017, 2022, 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 @@ -575,7 +575,6 @@ dtuple_convert_big_rec( dfield_t* dfield; dict_field_t* ifield; ulint size; - ulint n_fields; ulint local_prefix_len; if (!dict_index_is_clust(index)) { @@ -604,7 +603,7 @@ dtuple_convert_big_rec( a variable-length field that yields the biggest savings when stored externally */ - n_fields = 0; + ut_d(ulint n_fields = 0); while (page_zip_rec_needs_ext(rec_get_converted_size(index, entry, *n_ext), @@ -700,9 +699,8 @@ skip_field: dfield_set_data(dfield, data, local_len); dfield_set_ext(dfield); - n_fields++; (*n_ext)++; - ut_ad(n_fields < dtuple_get_n_fields(entry)); + ut_ad(++n_fields < dtuple_get_n_fields(entry)); if (upd && !upd->is_modified(longest_i)) { diff --git a/storage/innobase/gis/gis0rtree.cc b/storage/innobase/gis/gis0rtree.cc index bbcf36b74fe..350d1689977 100644 --- a/storage/innobase/gis/gis0rtree.cc +++ b/storage/innobase/gis/gis0rtree.cc @@ -998,7 +998,7 @@ rtr_page_split_and_insert( lock_prdt_t new_prdt; rec_t* first_rec = NULL; int first_rec_group = 1; - ulint n_iterations = 0; + IF_DBUG(bool iterated = false,); if (!*heap) { *heap = mem_heap_create(1024); @@ -1207,7 +1207,7 @@ func_start: the page, and it'll need the second round split in this case. We test this scenario here*/ DBUG_EXECUTE_IF("rtr_page_need_second_split", - if (n_iterations == 0) { + if (!iterated) { rec = NULL; goto after_insert; } ); @@ -1272,7 +1272,7 @@ after_insert: parent. */ rtr_clean_rtr_info(cursor->rtr_info, true); cursor->rtr_info = NULL; - n_iterations++; + IF_DBUG(iterated=true,); rec_t* i_rec = page_rec_get_next(page_get_infimum_rec( buf_block_get_frame(block))); diff --git a/storage/innobase/include/ut0lst.h b/storage/innobase/include/ut0lst.h index 9a5f3059826..fb15d6276f8 100644 --- a/storage/innobase/include/ut0lst.h +++ b/storage/innobase/include/ut0lst.h @@ -1,7 +1,7 @@ /***************************************************************************** Copyright (c) 1995, 2015, Oracle and/or its affiliates. All Rights Reserved. -Copyright (c) 2019, MariaDB Corporation. +Copyright (c) 2019, 2022, 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 @@ -25,8 +25,7 @@ Created 9/10/1995 Heikki Tuuri Rewritten by Sunny Bains Dec 2011. ***********************************************************************/ -#ifndef ut0lst_h -#define ut0lst_h +#pragma once /* Do not include univ.i because univ.i includes this. */ @@ -474,17 +473,17 @@ template void ut_list_validate(const List& list, Functor& functor) { ut_list_map(list, functor); - +#ifdef UNIV_DEBUG /* Validate the list backwards. */ - ulint count = 0; + auto count = list.count; for (typename List::elem_type* elem = list.end; elem != 0; elem = (elem->*list.node).prev) { - ++count; + --count; } - - ut_a(count == list.count); + ut_ad(!count); +#endif } /** Check the consistency of a doubly linked list. @@ -494,23 +493,24 @@ template inline void ut_list_validate(const List& list, const Functor& functor) { ut_list_map(list, functor); - +#ifdef UNIV_DEBUG /* Validate the list backwards. */ - ulint count = 0; + auto count = list.count; for (typename List::elem_type* elem = list.end; elem != 0; elem = (elem->*list.node).prev) { - ++count; + --count; } - ut_a(count == list.count); + ut_ad(!count); +#endif } template inline void ut_list_validate(const List& list) { - ut_list_validate(list, NullValidate()); + ut_d(ut_list_validate(list, NullValidate())); } #ifdef UNIV_DEBUG @@ -561,8 +561,3 @@ ut_list_move_to_front( ut_list_prepend(list, elem); } } - -#ifdef UNIV_DEBUG -#endif - -#endif /* ut0lst.h */ From 78030b67b9cbc7b2c29f1d7aeaf3b9942bf94bb6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marko=20M=C3=A4kel=C3=A4?= Date: Fri, 14 Oct 2022 11:54:05 +0300 Subject: [PATCH 02/72] Do not use C++11 before MariaDB 10.4 This fixes up 3d9b350a9cab7faaf718313c197ff868c4af3c6a --- storage/innobase/include/ut0lst.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/storage/innobase/include/ut0lst.h b/storage/innobase/include/ut0lst.h index fb15d6276f8..7b7ed7b8e80 100644 --- a/storage/innobase/include/ut0lst.h +++ b/storage/innobase/include/ut0lst.h @@ -475,7 +475,7 @@ void ut_list_validate(const List& list, Functor& functor) ut_list_map(list, functor); #ifdef UNIV_DEBUG /* Validate the list backwards. */ - auto count = list.count; + ulint count = list.count; for (typename List::elem_type* elem = list.end; elem != 0; @@ -495,7 +495,7 @@ inline void ut_list_validate(const List& list, const Functor& functor) ut_list_map(list, functor); #ifdef UNIV_DEBUG /* Validate the list backwards. */ - auto count = list.count; + ulint count = list.count; for (typename List::elem_type* elem = list.end; elem != 0; From e0b4db5ba3d1fb14a1ec9e4ab0b346c6a8eebfd6 Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Tue, 11 Oct 2022 12:56:01 +0200 Subject: [PATCH 03/72] MDEV-29750 triggers can modify history should be the same behavior as for virtual columns: * a warning on every inserted row * silently ignored in a trigger --- mysql-test/suite/versioning/r/misc.result | 27 +++++++++++++++++++++++ mysql-test/suite/versioning/t/misc.test | 20 +++++++++++++++++ sql/item.cc | 2 ++ 3 files changed, 49 insertions(+) create mode 100644 mysql-test/suite/versioning/r/misc.result create mode 100644 mysql-test/suite/versioning/t/misc.test diff --git a/mysql-test/suite/versioning/r/misc.result b/mysql-test/suite/versioning/r/misc.result new file mode 100644 index 00000000000..398e3b8be70 --- /dev/null +++ b/mysql-test/suite/versioning/r/misc.result @@ -0,0 +1,27 @@ +set time_zone='+00:00'; +# +# MDEV-29750 triggers can modify history +# +set sql_mode='', timestamp=unix_timestamp('2010-10-10 10:10:10'); +create table t (a int, b int as (a+1), s timestamp(6) as row start, e timestamp(6) as row end, period for system_time(s,e)) with system versioning; +insert into t values (1,1, '2022-01-01','2023-01-01'),(2,2, '2022-02-02','2023-02-02'); +Warnings: +Warning 1906 The value specified for generated column 'b' in table 't' has been ignored +Warning 1906 The value specified for generated column 's' in table 't' has been ignored +Warning 1906 The value specified for generated column 'e' in table 't' has been ignored +Warning 1906 The value specified for generated column 'b' in table 't' has been ignored +Warning 1906 The value specified for generated column 's' in table 't' has been ignored +Warning 1906 The value specified for generated column 'e' in table 't' has been ignored +create trigger tr before insert on t for each row set new.b=1, new.s = '2022-03-03', new.e = '2023-03-03'; +insert into t (a) values (3),(4); +select * from t for system_time all; +a b s e +1 2 2010-10-10 10:10:10.000000 2038-01-19 03:14:07.999999 +2 3 2010-10-10 10:10:10.000000 2038-01-19 03:14:07.999999 +3 4 2010-10-10 10:10:10.000000 2038-01-19 03:14:07.999999 +4 5 2010-10-10 10:10:10.000000 2038-01-19 03:14:07.999999 +drop table t; +set sql_mode=default, timestamp=default; +# +# End of 10.3 tests +# diff --git a/mysql-test/suite/versioning/t/misc.test b/mysql-test/suite/versioning/t/misc.test new file mode 100644 index 00000000000..dce1e0deced --- /dev/null +++ b/mysql-test/suite/versioning/t/misc.test @@ -0,0 +1,20 @@ +# +# simple tests that don't need to be run in multiple various combinations +# +set time_zone='+00:00'; + +--echo # +--echo # MDEV-29750 triggers can modify history +--echo # +set sql_mode='', timestamp=unix_timestamp('2010-10-10 10:10:10'); +create table t (a int, b int as (a+1), s timestamp(6) as row start, e timestamp(6) as row end, period for system_time(s,e)) with system versioning; +insert into t values (1,1, '2022-01-01','2023-01-01'),(2,2, '2022-02-02','2023-02-02'); +create trigger tr before insert on t for each row set new.b=1, new.s = '2022-03-03', new.e = '2023-03-03'; +insert into t (a) values (3),(4); +select * from t for system_time all; +drop table t; +set sql_mode=default, timestamp=default; + +--echo # +--echo # End of 10.3 tests +--echo # diff --git a/sql/item.cc b/sql/item.cc index 6681d5e375d..8b127cf2626 100644 --- a/sql/item.cc +++ b/sql/item.cc @@ -9804,6 +9804,8 @@ bool Item_trigger_field::set_value(THD *thd, sp_rcontext * /*ctx*/, Item **it) if (!item || fix_fields_if_needed(thd, NULL)) return true; + if (field->vers_sys_field()) + return false; // NOTE: field->table->copy_blobs should be false here, but let's // remember the value at runtime to avoid subtle bugs. From 5f25a9114051b078696813628c37add0e15d88f2 Mon Sep 17 00:00:00 2001 From: Brad Smith Date: Sun, 16 Oct 2022 13:44:51 -0400 Subject: [PATCH 04/72] Cleanup the alloca.h header handling to further reduce hardcoded OS lists (#2289) --- include/mysql/service_encryption.h | 5 +++-- plugin/cracklib_password_check/cracklib_password_check.c | 2 +- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/include/mysql/service_encryption.h b/include/mysql/service_encryption.h index a4e908f9aff..69d205a27e8 100644 --- a/include/mysql/service_encryption.h +++ b/include/mysql/service_encryption.h @@ -34,12 +34,13 @@ extern "C" { #ifndef __cplusplus #define inline __inline #endif -#elif defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__) || defined(__DragonFly__) -#include #else +#include +#ifdef HAVE_ALLOCA_H #include #endif #endif +#endif /* returned from encryption_key_get_latest_version() */ #define ENCRYPTION_KEY_VERSION_INVALID (~(unsigned int)0) diff --git a/plugin/cracklib_password_check/cracklib_password_check.c b/plugin/cracklib_password_check/cracklib_password_check.c index 72f87db94da..55a1fd1c738 100644 --- a/plugin/cracklib_password_check/cracklib_password_check.c +++ b/plugin/cracklib_password_check/cracklib_password_check.c @@ -13,10 +13,10 @@ along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1335 USA */ +#include #include #include #include -#include #include static char *dictionary; From b20f608d4f9a3e77db1381ea6ccaab4ae83c07c2 Mon Sep 17 00:00:00 2001 From: Anel Date: Sun, 16 Oct 2022 20:38:04 +0200 Subject: [PATCH 05/72] Update ODBC instructions for Connect SE and update ODBC result file (#2284) * ODBC Connect cosmetic fixes - Update command for connection for default `peer` authentication for user `postgres` (unless changed in `pg_hba.conf`). - Update command for privilege to be more verbose. - Update path for `.sql` file - Update instructions for `pg_hba.conf` file to use unix socket (`local`) type as well as TCP/IP type `host`. - Update instruction about usage of user dsn (data source file) over system dsn. - Update path of `odbc-postgresql` driver path in comment * Connect SE: update ODBC result file --- .../connect/r/odbc_postgresql.result | 26 +++++++++---------- .../mysql-test/connect/t/odbc_postgresql.sql | 6 ++--- .../mysql-test/connect/t/odbc_postgresql.test | 17 +++++++----- 3 files changed, 27 insertions(+), 22 deletions(-) diff --git a/storage/connect/mysql-test/connect/r/odbc_postgresql.result b/storage/connect/mysql-test/connect/r/odbc_postgresql.result index fd23197c37f..4a41dcf6ab8 100644 --- a/storage/connect/mysql-test/connect/r/odbc_postgresql.result +++ b/storage/connect/mysql-test/connect/r/odbc_postgresql.result @@ -2,7 +2,7 @@ Table Create Table t1 CREATE TABLE `t1` ( `Name` varchar(256) NOT NULL, `Description` varchar(256) DEFAULT NULL -) ENGINE=CONNECT DEFAULT CHARSET=latin1 `TABLE_TYPE`='ODBC' `CATFUNC`='Sources' +) ENGINE=CONNECT DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci `TABLE_TYPE`='ODBC' `CATFUNC`='Sources' SET NAMES utf8; # # Checking CATFUNC=Tables @@ -157,7 +157,7 @@ SHOW CREATE TABLE t1; Table Create Table t1 CREATE TABLE `t1` ( `a` int(10) NOT NULL -) ENGINE=CONNECT DEFAULT CHARSET=latin1 CONNECTION='DSN=ConnectEnginePostgresql;UID=mtr;PWD=mtr' `TABLE_TYPE`='ODBC' +) ENGINE=CONNECT DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci CONNECTION='DSN=ConnectEnginePostgresql;UID=mtr;PWD=mtr' `TABLE_TYPE`='ODBC' SELECT * FROM t1; a 10 @@ -168,7 +168,7 @@ SHOW CREATE TABLE t2; Table Create Table t2 CREATE TABLE `t2` ( `a` int(10) NOT NULL -) ENGINE=MyISAM DEFAULT CHARSET=latin1 +) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci SELECT * FROM t2; a 10 @@ -189,7 +189,7 @@ SHOW CREATE TABLE t1; Table Create Table t1 CREATE TABLE `t1` ( `a` int(10) NOT NULL -) ENGINE=CONNECT DEFAULT CHARSET=latin1 CONNECTION='DSN=ConnectEnginePostgresql;UID=mtr;PWD=mtr' `TABLE_TYPE`='ODBC' `TABNAME`='public.t1' +) ENGINE=CONNECT DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci CONNECTION='DSN=ConnectEnginePostgresql;UID=mtr;PWD=mtr' `TABLE_TYPE`='ODBC' `TABNAME`='public.t1' SELECT * FROM t1; a 10 @@ -202,7 +202,7 @@ SHOW CREATE TABLE t1; Table Create Table t1 CREATE TABLE `t1` ( `a` char(10) NOT NULL -) ENGINE=CONNECT DEFAULT CHARSET=utf8mb3 CONNECTION='DSN=ConnectEnginePostgresql;UID=mtr;PWD=mtr' `TABLE_TYPE`='ODBC' `TABNAME`='schema1.t1' `DATA_CHARSET`='utf8' +) ENGINE=CONNECT DEFAULT CHARSET=utf8 COLLATE=utf8_general_ci CONNECTION='DSN=ConnectEnginePostgresql;UID=mtr;PWD=mtr' `TABLE_TYPE`='ODBC' `TABNAME`='schema1.t1' `DATA_CHARSET`='utf8' SELECT * FROM t1; a aaa @@ -213,8 +213,8 @@ CREATE TABLE t2 AS SELECT * FROM t1; SHOW CREATE TABLE t2; Table Create Table t2 CREATE TABLE `t2` ( - `a` char(10) CHARACTER SET utf8mb3 NOT NULL -) ENGINE=MyISAM DEFAULT CHARSET=latin1 + `a` char(10) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci SELECT * FROM t2; a aaa @@ -237,7 +237,7 @@ SHOW CREATE TABLE t1; Table Create Table t1 CREATE TABLE `t1` ( `a` char(10) DEFAULT NULL -) ENGINE=CONNECT DEFAULT CHARSET=utf8mb3 CONNECTION='DSN=ConnectEnginePostgresql;UID=mtr;PWD=mtr' `TABLE_TYPE`='ODBC' `TABNAME`='schema1.v1' `DATA_CHARSET`='utf8' +) ENGINE=CONNECT DEFAULT CHARSET=utf8 COLLATE=utf8_general_ci CONNECTION='DSN=ConnectEnginePostgresql;UID=mtr;PWD=mtr' `TABLE_TYPE`='ODBC' `TABNAME`='schema1.v1' `DATA_CHARSET`='utf8' SELECT * FROM t1; a aaa @@ -248,8 +248,8 @@ CREATE TABLE t2 AS SELECT * FROM t1; SHOW CREATE TABLE t2; Table Create Table t2 CREATE TABLE `t2` ( - `a` char(10) CHARACTER SET utf8mb3 DEFAULT NULL -) ENGINE=MyISAM DEFAULT CHARSET=latin1 + `a` char(10) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT NULL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci SELECT * FROM t2; a aaa @@ -272,7 +272,7 @@ SHOW CREATE TABLE t1; Table Create Table t1 CREATE TABLE `t1` ( `a` char(10) NOT NULL -) ENGINE=CONNECT DEFAULT CHARSET=utf8mb3 CONNECTION='DSN=ConnectEnginePostgresql;UID=mtr;PWD=mtr' `TABLE_TYPE`='ODBC' `TABNAME`='schema1.t2' `DATA_CHARSET`='utf8' +) ENGINE=CONNECT DEFAULT CHARSET=utf8 COLLATE=utf8_general_ci CONNECTION='DSN=ConnectEnginePostgresql;UID=mtr;PWD=mtr' `TABLE_TYPE`='ODBC' `TABNAME`='schema1.t2' `DATA_CHARSET`='utf8' SELECT * FROM t1; a xxx @@ -283,8 +283,8 @@ CREATE TABLE t2 AS SELECT * FROM t1; SHOW CREATE TABLE t2; Table Create Table t2 CREATE TABLE `t2` ( - `a` char(10) CHARACTER SET utf8mb3 NOT NULL -) ENGINE=MyISAM DEFAULT CHARSET=latin1 + `a` char(10) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci SELECT * FROM t2; a xxx diff --git a/storage/connect/mysql-test/connect/t/odbc_postgresql.sql b/storage/connect/mysql-test/connect/t/odbc_postgresql.sql index a795817a4d3..e6452f70b37 100644 --- a/storage/connect/mysql-test/connect/t/odbc_postgresql.sql +++ b/storage/connect/mysql-test/connect/t/odbc_postgresql.sql @@ -2,7 +2,7 @@ -- The SQL script to create PostgreSQL data for odbc_postgresql.test -- -- Run this script as a admin user: --- psql -U postgres < odbc_postgresql.sql +-- sudo -u postgres psql < storage/connect/mysql-test/connect/t/odbc_postgresql.sql SET NAMES 'UTF8'; @@ -11,7 +11,7 @@ DROP USER IF EXISTS mtr; CREATE USER mtr WITH PASSWORD 'mtr'; CREATE DATABASE mtr OWNER=mtr ENCODING='UTF8'; -GRANT ALL ON DATABASE mtr TO mtr; +GRANT ALL PRIVILEGES ON DATABASE mtr TO mtr; \c mtr SET role mtr; CREATE TABLE t1 (a INT NOT NULL); @@ -27,4 +27,4 @@ CREATE TABLE schema1.t2 (a CHAR(10) NOT NULL); INSERT INTO schema1.t2 VALUES ('xxx'),('yyy'),('zzz'),('ÄÖÜ'); CREATE TABLE schema1.t3 (a CHAR(10) NOT NULL, b CHAR(10) NOT NULL); INSERT INTO schema1.t3 VALUES ('xxx', 'aaa'),('yyy', 'bbb'),('zzz', 'ccc'),('ÄÖÜ', 'яяя'); - +\dt schema1.* diff --git a/storage/connect/mysql-test/connect/t/odbc_postgresql.test b/storage/connect/mysql-test/connect/t/odbc_postgresql.test index 86597423d04..2c3d4040c79 100644 --- a/storage/connect/mysql-test/connect/t/odbc_postgresql.test +++ b/storage/connect/mysql-test/connect/t/odbc_postgresql.test @@ -5,10 +5,10 @@ # To configure your system to be able to run this test, # follow through the following steps: # -# 1. Install and configure PostgreSQL database to stat on the system startup +# 1. Install and configure PostgreSQL database to start on the system startup # # 2. Create user, database, schema and tables to be used by mtr: -# psql -U postgres < odbc_postgresql.sql +# sudo -u postgres psql < storage/connect/mysql-test/connect/t/odbc_postgresql.sql # # 3. Install PostgreSQL ODBC Driver. # - On CentOS, Fedora: @@ -18,18 +18,23 @@ # # 4. Create a data source with the name "ConnectEnginePostgresql" # - On Windows: use odbcadm.exe -# - On Linux: put these lines into /etc/odbc.ini +# - On Linux: put these lines into /etc/odbc.ini or in ~/.odbc.ini # #[ConnectEnginePostgresql] #Description=PostgreSQL DSN for ConnectSE -#Driver=PostgreSQL (should the path to the driver so file) +#Driver=PostgreSQL (should the path to the driver so file, on linux: /usr/lib/x86_64-linux-gnu/odbc/psqlodbca.so) #Database=mtr #Servername=localhost #Port=5432 # # 5. Allow user "mtr" to connect to the database "mtr" -# Add this line into the begginning of pg_hba.conf -# (usually /var/lib/pgsql/data/pg_hba.conf on Linux): +# Find `pg_hba.conf` file: +# Run `SHOW hba_file;` or `locate pg_hba.conf` to find right location +# (usually /var/lib/pgsql/data/pg_hba.conf or /etc/postgresql/[version]/main/pg_hba.conf on Linux) +# Add this line into the beginning of pg_hba.conf: +# For unix socket connection (connect with `psql -U mtr`) +#local mtr mtr password +# For TCP/IP connection (connect with `psql -U mtr -h 127.0.0.1`) #host mtr mtr 127.0.0.1/32 password # # 6. Restart the server: From 4b92fedc62600af4fed4436575638c884340dcb4 Mon Sep 17 00:00:00 2001 From: Oleksandr Byelkin Date: Sat, 15 Oct 2022 23:50:09 +0200 Subject: [PATCH 06/72] new 3.1 --- libmariadb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libmariadb b/libmariadb index 7fdb3eab663..9ca66a70388 160000 --- a/libmariadb +++ b/libmariadb @@ -1 +1 @@ -Subproject commit 7fdb3eab66384a355475704332d11cc1ab82499a +Subproject commit 9ca66a70388cb77adefbc449c3beda2db4eb5993 From db330c87d6d253a1e2e93a747327040d9205c5fe Mon Sep 17 00:00:00 2001 From: Oleksandr Byelkin Date: Sun, 16 Oct 2022 22:02:27 +0200 Subject: [PATCH 07/72] new CC v3.3 --- libmariadb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libmariadb b/libmariadb index 380ee32375b..72b40bfaa86 160000 --- a/libmariadb +++ b/libmariadb @@ -1 +1 @@ -Subproject commit 380ee32375bb36b68796c1c3eb09285f03fea5f5 +Subproject commit 72b40bfaa869f3fe84242471dda989d13983d84c From bd9274faa469cc164099c7497c18a0e0a9b1184b Mon Sep 17 00:00:00 2001 From: Dmitry Shulga Date: Mon, 17 Oct 2022 15:05:17 +0700 Subject: [PATCH 08/72] MDEV-16128: Server crash in Item_func::print_op on 2nd execution of PS For some queries that involve tables with different but convertible character sets for columns taking part in the query, repeatable execution of such queries in PS mode or as part of a stored routine would result in server abnormal termination. For example, CREATE TABLE t1 (a2 varchar(10)); CREATE TABLE t2 (u1 varchar(10) CHARACTER SET utf8); CREATE TABLE t3 (u2 varchar(10) CHARACTER SET utf8); PREPARE stmt FROM "SELECT t1.* FROM (t1 JOIN t2 ON (t2.u1 = t1.a2)) WHERE (EXISTS (SELECT 1 FROM t3 WHERE t3.u2 = t1.a2))"; EXECUTE stmt; EXECUTE stmt; <== Running this prepared statement the second time results in server crash. The reason of server crash is that an instance of the class Item_func_conv_charset, that created for conversion of a column from one character set to another, is allocated on execution memory root but pointer to this instance is stored in an item placed on prepared statement memory root. Below is calls trace to the place where an instance of the class Item_func_conv_charset is created. setup_conds Item_func::fix_fields Item_bool_rowready_func2::fix_length_and_dec Item_func::setup_args_and_comparator Item_func_or_sum::agg_arg_charsets_for_comparison Item_func_or_sum::agg_arg_charsets Item_func_or_sum::agg_item_set_converter Item::safe_charset_converter And the following trace shows the place where a pointer to the instance of the class Item_func_conv_charset is passed to the class Item_func_eq, that is created on a memory root of the prepared statement. Prepared_statement::execute mysql_execute_command execute_sqlcom_select handle_select mysql_select JOIN::optimize JOIN::optimize_inner convert_join_subqueries_to_semijoins convert_subq_to_sj To fix the issue, switch to the Prepared Statement memory root before calling the method Item_func::setup_args_and_comparator in order to place any created Items on permanent memory root. It may seem that such approach would result in a memory leakage in case the parameter marker '?' is used in the query as in the following example PREPARE stmt FROM "SELECT t1.* FROM (t1 JOIN t2 ON (t2.u1 = t1.a2)) WHERE (EXISTS (SELECT 1 FROM t3 WHERE t3.u2 = ?))"; EXECUTE stmt USING convert('A' using latin1); but it wouldn't since for such case any of the parameter markers is treated as a constant and no subquery to semijoin optimization is performed. --- libmariadb | 2 +- mysql-test/main/ps.result | 98 ++++++++++++++++++++++++++++++++++++++ mysql-test/main/ps.test | 71 ++++++++++++++++++++++++++++ sql/item_cmpfunc.cc | 13 ++++- tests/mysql_client_test.c | 99 +++++++++++++++++++++++++++++++++++++++ 5 files changed, 280 insertions(+), 3 deletions(-) diff --git a/libmariadb b/libmariadb index 9ca66a70388..7fdb3eab663 160000 --- a/libmariadb +++ b/libmariadb @@ -1 +1 @@ -Subproject commit 9ca66a70388cb77adefbc449c3beda2db4eb5993 +Subproject commit 7fdb3eab66384a355475704332d11cc1ab82499a diff --git a/mysql-test/main/ps.result b/mysql-test/main/ps.result index e3180175eac..26c41526389 100644 --- a/mysql-test/main/ps.result +++ b/mysql-test/main/ps.result @@ -5602,3 +5602,101 @@ a.a a.b 10 20 DEALLOCATE PREPARE stmt; DROP PROCEDURE p1; +# +# MDEV-16128: Server crash in Item_func::print_op on 2nd execution of PS +# +CREATE TABLE t1 (a varchar(10)); +CREATE TABLE t2 (b varchar(10) CHARACTER SET utf8 ); +CREATE TABLE t3 (c varchar(10) CHARACTER SET utf8); +INSERT INTO t1 VALUES ('b'); +INSERT INTO t2 VALUES ('b'); +INSERT INTO t3 VALUES ('b'); +PREPARE stmt FROM "SELECT t1.* FROM (t1 JOIN t2 ON (t2.b = t1.a)) WHERE (EXISTS (SELECT 1 FROM t3 WHERE t3.c = t1.a))"; +EXECUTE stmt; +a +b +# Without the patch second execution of the prepared statement +# would lead to server crash. +EXECUTE stmt; +a +b +# Clean up +DEALLOCATE PREPARE stmt; +DROP TABLE t1, t2, t3; +CREATE TABLE t1 (a varchar(10)); +CREATE TABLE t2 (b varchar(10) CHARACTER SET utf8); +INSERT INTO t1 VALUES ('b'); +INSERT INTO t2 VALUES ('b'); +PREPARE stmt FROM 'SELECT STRAIGHT_JOIN 1 FROM t1 WHERE EXISTS (SELECT 1 FROM t2 WHERE t2.b = t1.a)'; +EXECUTE stmt; +1 +1 +# Without the patch second execution of the prepared statement +# would lead to server crash. +EXECUTE stmt; +1 +1 +# Clean up +DEALLOCATE PREPARE stmt; +# Check that EXECUTE USING is run correctly +PREPARE stmt FROM 'SELECT 300 FROM t1 WHERE EXISTS (SELECT 100 FROM t2 WHERE t2.b = ?)'; +EXECUTE stmt USING 'b'; +300 +300 +EXECUTE stmt USING 'b'; +300 +300 +EXECUTE stmt USING 'd'; +300 +EXECUTE stmt USING 'd'; +300 +EXECUTE stmt USING _binary 'b'; +300 +300 +EXECUTE stmt USING _binary 'b'; +300 +300 +EXECUTE stmt USING _binary 'B'; +300 +300 +EXECUTE stmt USING 'B'; +300 +300 +EXECUTE stmt USING _binary 'd'; +300 +EXECUTE stmt USING _binary 'd'; +300 +EXECUTE stmt USING _ucs2 'b'; +300 +300 +EXECUTE stmt USING _ucs2 'b'; +300 +300 +EXECUTE stmt USING _ucs2 'd'; +300 +EXECUTE stmt USING _ucs2 'd'; +300 +EXECUTE stmt USING _latin1 'b'; +300 +300 +EXECUTE stmt USING _latin1 'b'; +300 +300 +EXECUTE stmt USING _latin1 'd'; +300 +EXECUTE stmt USING _latin1 'd'; +300 +CREATE TABLE t3 (c VARCHAR(10) CHARACTER SET ucs2); +INSERT INTO t3 VALUES ('b'); +PREPARE stmt FROM 'SELECT 300 FROM t1 WHERE EXISTS (SELECT 100 FROM t3 WHERE t3.c = ?)'; +EXECUTE stmt USING 'b'; +300 +300 +EXECUTE stmt USING 'b'; +300 +300 +EXECUTE stmt USING 'd'; +300 +EXECUTE stmt USING 'd'; +300 +DROP TABLE t1, t2, t3; diff --git a/mysql-test/main/ps.test b/mysql-test/main/ps.test index 8c59f1e0840..2ccfac3c119 100644 --- a/mysql-test/main/ps.test +++ b/mysql-test/main/ps.test @@ -5045,3 +5045,74 @@ EXECUTE stmt; DEALLOCATE PREPARE stmt; DROP PROCEDURE p1; + +--echo # +--echo # MDEV-16128: Server crash in Item_func::print_op on 2nd execution of PS +--echo # + +CREATE TABLE t1 (a varchar(10)); +CREATE TABLE t2 (b varchar(10) CHARACTER SET utf8 ); +CREATE TABLE t3 (c varchar(10) CHARACTER SET utf8); +INSERT INTO t1 VALUES ('b'); +INSERT INTO t2 VALUES ('b'); +INSERT INTO t3 VALUES ('b'); + +PREPARE stmt FROM "SELECT t1.* FROM (t1 JOIN t2 ON (t2.b = t1.a)) WHERE (EXISTS (SELECT 1 FROM t3 WHERE t3.c = t1.a))"; +EXECUTE stmt; +--echo # Without the patch second execution of the prepared statement +--echo # would lead to server crash. +EXECUTE stmt; +--echo # Clean up +DEALLOCATE PREPARE stmt; +DROP TABLE t1, t2, t3; + +CREATE TABLE t1 (a varchar(10)); +CREATE TABLE t2 (b varchar(10) CHARACTER SET utf8); +INSERT INTO t1 VALUES ('b'); +INSERT INTO t2 VALUES ('b'); +PREPARE stmt FROM 'SELECT STRAIGHT_JOIN 1 FROM t1 WHERE EXISTS (SELECT 1 FROM t2 WHERE t2.b = t1.a)'; +EXECUTE stmt; +--echo # Without the patch second execution of the prepared statement +--echo # would lead to server crash. +EXECUTE stmt; + +--echo # Clean up +DEALLOCATE PREPARE stmt; + +--echo # Check that EXECUTE USING is run correctly +PREPARE stmt FROM 'SELECT 300 FROM t1 WHERE EXISTS (SELECT 100 FROM t2 WHERE t2.b = ?)'; +EXECUTE stmt USING 'b'; +EXECUTE stmt USING 'b'; + +EXECUTE stmt USING 'd'; +EXECUTE stmt USING 'd'; + +EXECUTE stmt USING _binary 'b'; +EXECUTE stmt USING _binary 'b'; + +EXECUTE stmt USING _binary 'B'; +EXECUTE stmt USING 'B'; + +EXECUTE stmt USING _binary 'd'; +EXECUTE stmt USING _binary 'd'; + +EXECUTE stmt USING _ucs2 'b'; +EXECUTE stmt USING _ucs2 'b'; + +EXECUTE stmt USING _ucs2 'd'; +EXECUTE stmt USING _ucs2 'd'; + +EXECUTE stmt USING _latin1 'b'; +EXECUTE stmt USING _latin1 'b'; + +EXECUTE stmt USING _latin1 'd'; +EXECUTE stmt USING _latin1 'd'; + +CREATE TABLE t3 (c VARCHAR(10) CHARACTER SET ucs2); +INSERT INTO t3 VALUES ('b'); +PREPARE stmt FROM 'SELECT 300 FROM t1 WHERE EXISTS (SELECT 100 FROM t3 WHERE t3.c = ?)'; +EXECUTE stmt USING 'b'; +EXECUTE stmt USING 'b'; +EXECUTE stmt USING 'd'; +EXECUTE stmt USING 'd'; +DROP TABLE t1, t2, t3; diff --git a/sql/item_cmpfunc.cc b/sql/item_cmpfunc.cc index fe6b8feb4de..b7b0c981c2d 100644 --- a/sql/item_cmpfunc.cc +++ b/sql/item_cmpfunc.cc @@ -442,9 +442,18 @@ bool Item_func::setup_args_and_comparator(THD *thd, Arg_comparator *cmp) if (args[0]->cmp_type() == STRING_RESULT && args[1]->cmp_type() == STRING_RESULT) { + Query_arena *arena, backup; + arena= thd->activate_stmt_arena_if_needed(&backup); + DTCollation tmp; - if (agg_arg_charsets_for_comparison(tmp, args, 2)) - return true; + bool ret= agg_arg_charsets_for_comparison(tmp, args, 2); + + if (arena) + thd->restore_active_arena(arena, &backup); + + if (ret) + return ret; + cmp->m_compare_collation= tmp.collation; } // Convert constants when compared to int/year field diff --git a/tests/mysql_client_test.c b/tests/mysql_client_test.c index 482bb106af7..d09ab5e3e4e 100644 --- a/tests/mysql_client_test.c +++ b/tests/mysql_client_test.c @@ -21017,6 +21017,104 @@ static void test_explain_meta() mct_close_log(); } +static void test_mdev_16128() +{ + int rc, res; + MYSQL_STMT *stmt; + MYSQL_BIND bind, bind_res; + char bind_arg_1[]="d", bind_arg_2[]="b"; + ulong length= 0; + const char *query= + "SELECT 300 FROM t1 WHERE EXISTS (SELECT 100 FROM t2 WHERE t2.b = ?)"; + + myheader("test_mdev_16128"); + + rc= mysql_query(mysql, "DROP TABLE IF EXISTS t1"); + myquery(rc); + + rc= mysql_query(mysql, "DROP TABLE IF EXISTS t2"); + myquery(rc); + + rc= mysql_query(mysql, "CREATE TABLE t1 (a VARCHAR(10))"); + myquery(rc); + + rc= mysql_query(mysql, "CREATE TABLE t2 (b VARCHAR(10) CHARACTER SET utf8)"); + myquery(rc); + + rc= mysql_query(mysql, "INSERT INTO t1 VALUES('b')"); + myquery(rc); + + rc= mysql_query(mysql, "INSERT INTO t2 VALUES('d')"); + myquery(rc); + + stmt= mysql_stmt_init(mysql); + check_stmt(stmt); + + rc= mysql_stmt_prepare(stmt, query, strlen(query)); + check_execute(stmt, rc); + + memset(&bind, 0, sizeof(bind)); + bind.buffer_type= MYSQL_TYPE_STRING; + bind.buffer_length= strlen(bind_arg_1); + bind.buffer= bind_arg_1; + + rc= mysql_stmt_bind_param(stmt, &bind); + check_execute(stmt, rc); + + memset(&bind_res, 0, sizeof(bind_res)); + bind_res.buffer_type= MYSQL_TYPE_LONG; + bind_res.buffer= &res; + bind_res.is_null= NULL; + bind_res.length= &length; + + rc= mysql_stmt_bind_result(stmt, &bind_res); + check_execute(stmt, rc); + + rc= mysql_stmt_execute(stmt); + check_execute(stmt, rc); + + rc= mysql_stmt_store_result(stmt); + check_execute(stmt, rc); + + rc= mysql_stmt_fetch(stmt); + + /** + It's expected that the query + SELECT 300 FROM t1 WHERE EXISTS (SELECT 100 FROM t2 WHERE t2.b = ?)" + executed in PS-mode and bound with the value 'd' returns exactly + one row containing the value (300). + */ + check_execute(stmt, rc); + DIE_UNLESS(bind_res.buffer_type == MYSQL_TYPE_LONG); + DIE_UNLESS(res == 300); + + memset(&bind, 0, sizeof(bind)); + bind.buffer_type= MYSQL_TYPE_STRING; + bind.buffer_length= strlen(bind_arg_2); + bind.buffer= bind_arg_2; + + rc= mysql_stmt_bind_param(stmt, &bind); + check_execute(stmt, rc); + + rc= mysql_stmt_execute(stmt); + check_execute(stmt, rc); + + rc= mysql_stmt_store_result(stmt); + check_execute(stmt, rc); + + rc= mysql_stmt_fetch(stmt); + /** + It's expected that the query + SELECT 300 FROM t1 WHERE EXISTS (SELECT 100 FROM t2 WHERE t2.b = ?)" + executed in PS-mode and bound with the value 'd' returns empty result set. + */ + DIE_UNLESS(rc == MYSQL_NO_DATA); + + mysql_stmt_close(stmt); + + rc= mysql_query(mysql, "DROP TABLE t1, t2"); + myquery(rc); +} #ifndef EMBEDDED_LIBRARY #define MDEV19838_MAX_PARAM_COUNT 32 @@ -21466,6 +21564,7 @@ static struct my_tests_st my_tests[]= { #ifndef EMBEDDED_LIBRARY { "test_mdev19838", test_mdev19838 }, #endif + { "test_mdev_16128", test_mdev_16128 }, { 0, 0 } }; From 64f822c14264c65ed94d48d3cee1bad01e5c5e84 Mon Sep 17 00:00:00 2001 From: Anel Husakovic Date: Mon, 4 Jul 2022 08:27:36 -0500 Subject: [PATCH 09/72] MDEV-28455: CREATE TEMPORARY TABLES privilege is insufficient for SHOW COLUMNS =========== Problem ============= - `show columns` is not working for temporary tables, even though there is enough privilege `create temporary tables`. =========== Solution ============= - Append `TMP_TABLE_ACLS` privilege when running `show columns` for temp tables. - Additionally `check_access()` for database only once, not for each field =========== Additionally ============= - Update comments for function `check_table_access` arguments Reviewed by: --- mysql-test/main/grant2.result | 1 + mysql-test/main/grant5.result | 54 +++++++++++++++++++++++++++++++++++ mysql-test/main/grant5.test | 52 +++++++++++++++++++++++++++++++++ sql/sql_acl.h | 2 +- sql/sql_parse.cc | 6 ++-- sql/sql_show.cc | 13 +++++++-- 6 files changed, 122 insertions(+), 6 deletions(-) diff --git a/mysql-test/main/grant2.result b/mysql-test/main/grant2.result index 5bd44d0bd22..de192ecc28e 100644 --- a/mysql-test/main/grant2.result +++ b/mysql-test/main/grant2.result @@ -723,6 +723,7 @@ a # SHOW COLUMNS FROM t1; Field Type Null Key Default Extra +a int(11) YES NULL SHOW KEYS FROM t3; Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment Index_comment t3 0 PRIMARY 1 a A 0 NULL NULL BTREE diff --git a/mysql-test/main/grant5.result b/mysql-test/main/grant5.result index 7868effeb2c..908a05aadf1 100644 --- a/mysql-test/main/grant5.result +++ b/mysql-test/main/grant5.result @@ -242,4 +242,58 @@ connection default; disconnect con1; drop database db1; drop user foo@localhost; +# +# MDEV-28455: CREATE TEMPORARY TABLES privilege +# is insufficient for SHOW COLUMNS +# +create database db; +create user foo@localhost; +create user bar@localhost; +create user buz@localhost; +grant create temporary tables on db.* to foo@localhost; +grant create temporary tables on db.* to bar@localhost; +connect con1,localhost,foo,,db; +create temporary table tmp (a int, key(a)); +show tables; +Tables_in_db +show full tables; +Tables_in_db Table_type +show table status; +Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary +show index in tmp; +Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment Index_comment +tmp 1 a 1 a A NULL NULL NULL YES BTREE +show columns in tmp; +Field Type Null Key Default Extra +a int(11) YES MUL NULL +show full columns in tmp; +Field Type Collation Null Key Default Extra Privileges Comment +a int(11) NULL YES MUL NULL select,insert,update,references +# we don't expect to show temporary tables in information_schema.columns +select * from information_schema.columns where table_schema='db'; +TABLE_CATALOG TABLE_SCHEMA TABLE_NAME COLUMN_NAME ORDINAL_POSITION COLUMN_DEFAULT IS_NULLABLE DATA_TYPE CHARACTER_MAXIMUM_LENGTH CHARACTER_OCTET_LENGTH NUMERIC_PRECISION NUMERIC_SCALE DATETIME_PRECISION CHARACTER_SET_NAME COLLATION_NAME COLUMN_TYPE COLUMN_KEY EXTRA PRIVILEGES COLUMN_COMMENT IS_GENERATED GENERATION_EXPRESSION +disconnect con1; +connect con1,localhost,bar,,db; +show full columns in tmp; +ERROR 42000: SELECT command denied to user 'bar'@'localhost' for table `db`.`tmp` +disconnect con1; +connection default; +grant select on db.* to bar@localhost; +connect con1,localhost,bar,,db; +show grants for current_user; +Grants for bar@localhost +GRANT USAGE ON *.* TO `bar`@`localhost` +GRANT SELECT, CREATE TEMPORARY TABLES ON `db`.* TO `bar`@`localhost` +show full columns in tmp; +ERROR 42S02: Table 'db.tmp' doesn't exist +disconnect con1; +connect con1,localhost,buz,,; +show columns in db.tmp; +ERROR 42000: SELECT command denied to user 'buz'@'localhost' for table `db`.`tmp` +disconnect con1; +connection default; +drop database db; +drop user foo@localhost; +drop user bar@localhost; +drop user buz@localhost; # End of 10.3 tests diff --git a/mysql-test/main/grant5.test b/mysql-test/main/grant5.test index dc61c10646b..35df5a6ec03 100644 --- a/mysql-test/main/grant5.test +++ b/mysql-test/main/grant5.test @@ -206,5 +206,57 @@ show create view t_v; --disconnect con1 drop database db1; drop user foo@localhost; +--echo # +--echo # MDEV-28455: CREATE TEMPORARY TABLES privilege +--echo # is insufficient for SHOW COLUMNS +--echo # + +create database db; +create user foo@localhost; +create user bar@localhost; +create user buz@localhost; +grant create temporary tables on db.* to foo@localhost; +grant create temporary tables on db.* to bar@localhost; + +--connect (con1,localhost,foo,,db) +create temporary table tmp (a int, key(a)); +show tables; +show full tables; +show table status; +show index in tmp; +show columns in tmp; +show full columns in tmp; +--echo # we don't expect to show temporary tables in information_schema.columns +select * from information_schema.columns where table_schema='db'; +--disconnect con1 + +--connect (con1,localhost,bar,,db) +# User doesn't have `select` privilege on table +--error ER_TABLEACCESS_DENIED_ERROR +show full columns in tmp; + +--disconnect con1 + +--connection default +grant select on db.* to bar@localhost; + +--connect (con1,localhost,bar,,db) +# Table doesn't exist for this session +show grants for current_user; +--error ER_NO_SUCH_TABLE +show full columns in tmp; +--disconnect con1 + +--connect (con1,localhost,buz,,) +--error ER_TABLEACCESS_DENIED_ERROR +show columns in db.tmp; +--disconnect con1 + +--connection default +# Cleanup +drop database db; +drop user foo@localhost; +drop user bar@localhost; +drop user buz@localhost; --echo # End of 10.3 tests diff --git a/sql/sql_acl.h b/sql/sql_acl.h index dc8a085c96c..3d415051f28 100644 --- a/sql/sql_acl.h +++ b/sql/sql_acl.h @@ -103,7 +103,7 @@ */ #define TMP_TABLE_ACLS \ (SELECT_ACL | INSERT_ACL | UPDATE_ACL | DELETE_ACL | CREATE_ACL | DROP_ACL | \ - INDEX_ACL | ALTER_ACL) + INDEX_ACL | ALTER_ACL | REFERENCES_ACL) /* Defines to change the above bits to how things are stored in tables diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index ca82c36d568..385360168a1 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -6892,13 +6892,13 @@ static bool check_show_access(THD *thd, TABLE_LIST *table) @brief Check if the requested privileges exists in either User-, Host- or Db-tables. @param thd Thread context - @param want_access Privileges requested + @param requirements Privileges requested @param tables List of tables to be compared against - @param no_errors Don't report error to the client (using my_error() call). @param any_combination_of_privileges_will_do TRUE if any privileges on any column combination is enough. @param number Only the first 'number' tables in the linked list are relevant. + @param no_errors Don't report error to the client (using my_error() call). The suppled table list contains cached privileges. This functions calls the help functions check_access and check_grant to verify the first three steps @@ -6925,7 +6925,7 @@ static bool check_show_access(THD *thd, TABLE_LIST *table) bool check_table_access(THD *thd, ulong requirements,TABLE_LIST *tables, - bool any_combination_of_privileges_will_do, + bool any_combination_of_privileges_will_do, uint number, bool no_errors) { TABLE_LIST *org_tables= tables; diff --git a/sql/sql_show.cc b/sql/sql_show.cc index bae712a407d..17437e683f4 100644 --- a/sql/sql_show.cc +++ b/sql/sql_show.cc @@ -6029,6 +6029,15 @@ static int get_schema_column_record(THD *thd, TABLE_LIST *tables, show_table->use_all_columns(); // Required for default restore_record(show_table, s->default_values); +#ifndef NO_EMBEDDED_ACCESS_CHECKS + check_access(thd, SELECT_ACL, db_name->str, + &tables->grant.privilege, 0, 0, MY_TEST(tables->schema_table)); + if (is_temporary_table(tables)) + { + tables->grant.privilege|= TMP_TABLE_ACLS; + } +#endif + for (; (field= *ptr) ; ptr++) { if(field->invisible > INVISIBLE_USER) @@ -6049,13 +6058,13 @@ static int get_schema_column_record(THD *thd, TABLE_LIST *tables, #ifndef NO_EMBEDDED_ACCESS_CHECKS uint col_access; - check_access(thd,SELECT_ACL, db_name->str, - &tables->grant.privilege, 0, 0, MY_TEST(tables->schema_table)); col_access= get_column_grant(thd, &tables->grant, db_name->str, table_name->str, field->field_name.str) & COL_ACLS; + if (!tables->schema_table && !col_access) continue; + char *end= tmp; for (uint bitnr=0; col_access ; col_access>>=1,bitnr++) { From d6707ab11f65aec04014bb5a550324eba6ae0200 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marko=20M=C3=A4kel=C3=A4?= Date: Tue, 18 Oct 2022 10:29:15 +0300 Subject: [PATCH 10/72] MDEV-29753 fixup: Silence bogus GCC -Og -Wmaybe-uninitialized --- sql/table.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sql/table.cc b/sql/table.cc index 1d0edf88fb7..d6d68988a52 100644 --- a/sql/table.cc +++ b/sql/table.cc @@ -8170,7 +8170,7 @@ int TABLE::update_virtual_field(Field *vf, bool ignore_warnings) Counting_error_handler count_errors; Suppress_warnings_error_handler warning_handler; in_use->push_internal_handler(&count_errors); - bool abort_on_warning; + bool abort_on_warning= ignore_warnings; if (ignore_warnings) { abort_on_warning= in_use->abort_on_warning; From 8c389393695f052990610f8d4fe6935e5cb94c66 Mon Sep 17 00:00:00 2001 From: Daniel Black Date: Fri, 16 Sep 2022 11:20:41 +1000 Subject: [PATCH 11/72] MDEV-29540 Incorrect sequence values in INSERT SELECT The population of default values in INSERT SELECT was being performed twice. With sequences, this resulted in every second sequence value being used. With SELECT INSERT we remove the second invokation of table->update_default_fields(). This was already performed in store_values() invoking fill_record_n_invoke_before_triggers() which invoked update_default_fields() previously. We do need to return an error on duplicate values, so the ::store_values is extended to take the ignore option. --- mysql-test/suite/sql_sequence/default.result | 102 +++++++++++++++++++ mysql-test/suite/sql_sequence/default.test | 80 +++++++++++++++ sql/sql_class.h | 4 +- sql/sql_insert.cc | 23 ++--- 4 files changed, 195 insertions(+), 14 deletions(-) diff --git a/mysql-test/suite/sql_sequence/default.result b/mysql-test/suite/sql_sequence/default.result index d767b5fb030..abed796cb75 100644 --- a/mysql-test/suite/sql_sequence/default.result +++ b/mysql-test/suite/sql_sequence/default.result @@ -195,3 +195,105 @@ INSERT INTO t1 () values (); EXECUTE stmt; DROP TABLE t1; DROP SEQUENCE s; +# +# MDEV-29540 Incorrect sequence values in INSERT SELECT +# +CREATE SEQUENCE s1; +CREATE TABLE t1 ( +a BIGINT UNSIGNED NOT NULL PRIMARY KEY +DEFAULT (NEXT VALUE FOR s1), +b CHAR(1) NOT NULL +); +INSERT INTO t1 (b) VALUES ('a'); +INSERT INTO t1 (b) VALUES ('b'), ('c'); +INSERT INTO t1 (b) VALUES ('d'); +INSERT INTO t1 (b) SELECT c FROM ( +SELECT 'e' as c +UNION +SELECT 'f' + UNION +SELECT 'g' +) der; +SELECT a, b FROM t1; +a b +1 a +2 b +3 c +4 d +5 e +6 f +7 g +ALTER SEQUENCE s1 RESTART; +INSERT INTO t1 (b) SELECT c FROM ( +SELECT 'a' as c +UNION +SELECT 'b' + UNION +SELECT 'c' + UNION +SELECT 'd' + UNION +SELECT 'e' + UNION +SELECT 'f' + UNION +SELECT 'g' +) der; +ERROR 23000: Duplicate entry '1' for key 'PRIMARY' +ALTER SEQUENCE s1 RESTART; +INSERT IGNORE INTO t1 (b) SELECT c FROM ( +SELECT 'a' as c +UNION +SELECT 'b' + UNION +SELECT 'c' + UNION +SELECT 'd' + UNION +SELECT 'e' + UNION +SELECT 'f' + UNION +SELECT 'g' +) der; +Warnings: +Warning 1062 Duplicate entry '1' for key 'PRIMARY' +Warning 1062 Duplicate entry '2' for key 'PRIMARY' +Warning 1062 Duplicate entry '3' for key 'PRIMARY' +Warning 1062 Duplicate entry '4' for key 'PRIMARY' +Warning 1062 Duplicate entry '5' for key 'PRIMARY' +Warning 1062 Duplicate entry '6' for key 'PRIMARY' +Warning 1062 Duplicate entry '7' for key 'PRIMARY' +SELECT a, b FROM t1; +a b +1 a +2 b +3 c +4 d +5 e +6 f +7 g +INSERT IGNORE INTO t1 (b) SELECT c FROM ( +SELECT 'h' as c +UNION +SELECT 'i' + UNION +SELECT 'j' +) der; +SELECT a, b FROM t1; +a b +1 a +2 b +3 c +4 d +5 e +6 f +7 g +8 h +9 i +10 j +DROP TABLE t1; +DROP SEQUENCE s1; +# +# End of 10.3 tests +# diff --git a/mysql-test/suite/sql_sequence/default.test b/mysql-test/suite/sql_sequence/default.test index e7c13211013..28eb71e39cc 100644 --- a/mysql-test/suite/sql_sequence/default.test +++ b/mysql-test/suite/sql_sequence/default.test @@ -135,3 +135,83 @@ EXECUTE stmt; # Cleanup DROP TABLE t1; DROP SEQUENCE s; + +--echo # +--echo # MDEV-29540 Incorrect sequence values in INSERT SELECT +--echo # + +CREATE SEQUENCE s1; +CREATE TABLE t1 ( + a BIGINT UNSIGNED NOT NULL PRIMARY KEY + DEFAULT (NEXT VALUE FOR s1), + b CHAR(1) NOT NULL +); + +INSERT INTO t1 (b) VALUES ('a'); +INSERT INTO t1 (b) VALUES ('b'), ('c'); +INSERT INTO t1 (b) VALUES ('d'); +INSERT INTO t1 (b) SELECT c FROM ( + SELECT 'e' as c + UNION + SELECT 'f' + UNION + SELECT 'g' +) der; + +SELECT a, b FROM t1; + +ALTER SEQUENCE s1 RESTART; + +--error ER_DUP_ENTRY +INSERT INTO t1 (b) SELECT c FROM ( + SELECT 'a' as c + UNION + SELECT 'b' + UNION + SELECT 'c' + UNION + SELECT 'd' + UNION + SELECT 'e' + UNION + SELECT 'f' + UNION + SELECT 'g' +) der; + +ALTER SEQUENCE s1 RESTART; + +INSERT IGNORE INTO t1 (b) SELECT c FROM ( + SELECT 'a' as c + UNION + SELECT 'b' + UNION + SELECT 'c' + UNION + SELECT 'd' + UNION + SELECT 'e' + UNION + SELECT 'f' + UNION + SELECT 'g' +) der; + +SELECT a, b FROM t1; + +INSERT IGNORE INTO t1 (b) SELECT c FROM ( + SELECT 'h' as c + UNION + SELECT 'i' + UNION + SELECT 'j' +) der; + +SELECT a, b FROM t1; + +DROP TABLE t1; +DROP SEQUENCE s1; + +--echo # +--echo # End of 10.3 tests +--echo # diff --git a/sql/sql_class.h b/sql/sql_class.h index 4d1f5b40db5..9ac973dc640 100644 --- a/sql/sql_class.h +++ b/sql/sql_class.h @@ -5455,7 +5455,7 @@ class select_insert :public select_result_interceptor { int prepare(List &list, SELECT_LEX_UNIT *u); virtual int prepare2(JOIN *join); virtual int send_data(List &items); - virtual void store_values(List &values); + virtual bool store_values(List &values, bool ignore_errors); virtual bool can_rollback_data() { return 0; } bool prepare_eof(); bool send_ok_packet(); @@ -5497,7 +5497,7 @@ public: int prepare(List &list, SELECT_LEX_UNIT *u); int binlog_show_create_table(TABLE **tables, uint count); - void store_values(List &values); + bool store_values(List &values, bool ignore_errors); bool send_eof(); virtual void abort_result_set(); virtual bool can_rollback_data() { return 1; } diff --git a/sql/sql_insert.cc b/sql/sql_insert.cc index a180147190b..43007b2243a 100644 --- a/sql/sql_insert.cc +++ b/sql/sql_insert.cc @@ -3928,9 +3928,7 @@ int select_insert::send_data(List &values) DBUG_RETURN(0); thd->count_cuted_fields= CHECK_FIELD_WARN; // Calculate cuted fields - store_values(values); - if (table->default_field && - unlikely(table->update_default_fields(info.ignore))) + if (store_values(values, info.ignore)) DBUG_RETURN(1); thd->count_cuted_fields= CHECK_FIELD_ERROR_FOR_NULL; if (unlikely(thd->is_error())) @@ -3988,18 +3986,19 @@ int select_insert::send_data(List &values) } -void select_insert::store_values(List &values) +bool select_insert::store_values(List &values, bool ignore_errors) { DBUG_ENTER("select_insert::store_values"); + bool error; if (fields->elements) - fill_record_n_invoke_before_triggers(thd, table, *fields, values, 1, - TRG_EVENT_INSERT); + error= fill_record_n_invoke_before_triggers(thd, table, *fields, values, + ignore_errors, TRG_EVENT_INSERT); else - fill_record_n_invoke_before_triggers(thd, table, table->field_to_fill(), - values, 1, TRG_EVENT_INSERT); + error= fill_record_n_invoke_before_triggers(thd, table, table->field_to_fill(), + values, ignore_errors, TRG_EVENT_INSERT); - DBUG_VOID_RETURN; + DBUG_RETURN(error); } bool select_insert::prepare_eof() @@ -4670,10 +4669,10 @@ select_create::binlog_show_create_table(TABLE **tables, uint count) return result; } -void select_create::store_values(List &values) +bool select_create::store_values(List &values, bool ignore_errors) { - fill_record_n_invoke_before_triggers(thd, table, field, values, 1, - TRG_EVENT_INSERT); + return fill_record_n_invoke_before_triggers(thd, table, field, values, + ignore_errors, TRG_EVENT_INSERT); } From c92c1615852ecd4be2d04203600efd3eba578a02 Mon Sep 17 00:00:00 2001 From: Monty Date: Wed, 19 Oct 2022 01:02:29 +0300 Subject: [PATCH 12/72] Fixed compiler warning on AIX --- mysys/my_addr_resolve.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mysys/my_addr_resolve.c b/mysys/my_addr_resolve.c index 86670cf1db2..444a47bb7c5 100644 --- a/mysys/my_addr_resolve.c +++ b/mysys/my_addr_resolve.c @@ -324,7 +324,7 @@ int my_addr_resolve(void *ptr, my_addr_loc *loc) for the base program. This is depending on if the compilation is done with PIE or not. */ - addr_offset= info.dli_fbase; + addr_offset= (void*) info.dli_fbase; #ifndef __PIE__ if (strcmp(info.dli_fname, my_progname) == 0 && addr_resolve((void*) my_addr_resolve, loc) == 0 && From 120a4caf37aab145f6fad38fc63af95bab6b6b25 Mon Sep 17 00:00:00 2001 From: Monty Date: Wed, 19 Oct 2022 03:28:03 +0300 Subject: [PATCH 13/72] MDEV-27963 multisource_for_channel sometimes fails in bb with result content mismatch The problem was that SHOW SLAVE STATUS was exceuted before the slave IO thread had time to create a new relay log Fixed by writing a command on the master and syncing the slave data. This ensures that the slave creates a new relay log. --- .../suite/multi_source/multisource_for_channel.result | 4 ++++ .../suite/multi_source/multisource_for_channel.test | 9 +++++++++ 2 files changed, 13 insertions(+) diff --git a/mysql-test/suite/multi_source/multisource_for_channel.result b/mysql-test/suite/multi_source/multisource_for_channel.result index f96a5a93b97..cb1224b416f 100644 --- a/mysql-test/suite/multi_source/multisource_for_channel.result +++ b/mysql-test/suite/multi_source/multisource_for_channel.result @@ -279,6 +279,10 @@ Last_SQL_Errno = '0' # START SLAVE for channel 'master1'; include/wait_for_slave_to_start.inc +connection master1; +create table foo (a int); +drop table foo; +connection slave; show slave status for channel 'master1' Master_Port = 'MYPORT_1' diff --git a/mysql-test/suite/multi_source/multisource_for_channel.test b/mysql-test/suite/multi_source/multisource_for_channel.test index 9b74ea97742..a95b272d5b1 100644 --- a/mysql-test/suite/multi_source/multisource_for_channel.test +++ b/mysql-test/suite/multi_source/multisource_for_channel.test @@ -326,6 +326,15 @@ STOP SLAVE for channel 'master1'; START SLAVE for channel 'master1'; --source include/wait_for_slave_to_start.inc +# Force some data into the relay log to ensure that we get a new relay log +--connection master1 +create table foo (a int); +drop table foo; +--save_master_pos +--connection slave +--sync_with_master 0,'master1' +--source include/wait_for_sql_thread_read_all.inc + --echo --echo show slave status for channel 'master1' --let $status_items= Master_Port, Relay_Log_File, Slave_IO_Running, Slave_SQL_Running, Last_Errno, Last_SQL_Errno From 64d85c369bb67c47cdc87c517c1716742ec14c59 Mon Sep 17 00:00:00 2001 From: kurt Date: Thu, 22 Sep 2022 14:57:57 +0800 Subject: [PATCH 14/72] MDEV-28720 add log message if flush log failure --- client/mysqldump.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/client/mysqldump.c b/client/mysqldump.c index fba8eec60f3..294f29b7acd 100644 --- a/client/mysqldump.c +++ b/client/mysqldump.c @@ -6874,7 +6874,12 @@ int main(int argc, char **argv) if (flush_logs || opt_delete_master_logs) { if (mysql_refresh(mysql, REFRESH_LOG)) + { + fprintf(stderr, + "Flush logs or delete master logs failure in server \n"); + first_error= EX_MYSQLERR; goto err; + } verbose_msg("-- main : logs flushed successfully!\n"); } From cee7175b79a22c29a82ef328aba208f90afcea86 Mon Sep 17 00:00:00 2001 From: kurt Date: Wed, 21 Sep 2022 11:29:07 +0800 Subject: [PATCH 15/72] MDEV-25343 add read secret size in file key plugin --- .../encryption/r/filekeys_secret_too_long.result | 10 ++++++++++ .../suite/encryption/t/filekeys-data-too-long.key | 4 ++++ .../suite/encryption/t/filekeys_secret_too_long.opt | 3 +++ .../encryption/t/filekeys_secret_too_long.test | 4 ++++ plugin/file_key_management/parser.cc | 13 ++++++++++++- 5 files changed, 33 insertions(+), 1 deletion(-) create mode 100644 mysql-test/suite/encryption/r/filekeys_secret_too_long.result create mode 100644 mysql-test/suite/encryption/t/filekeys-data-too-long.key create mode 100644 mysql-test/suite/encryption/t/filekeys_secret_too_long.opt create mode 100644 mysql-test/suite/encryption/t/filekeys_secret_too_long.test diff --git a/mysql-test/suite/encryption/r/filekeys_secret_too_long.result b/mysql-test/suite/encryption/r/filekeys_secret_too_long.result new file mode 100644 index 00000000000..32e18513454 --- /dev/null +++ b/mysql-test/suite/encryption/r/filekeys_secret_too_long.result @@ -0,0 +1,10 @@ +call mtr.add_suppression("the secret file has incorrect length"); +call mtr.add_suppression("Plugin 'file_key_management' init function returned error"); +call mtr.add_suppression("Plugin 'file_key_management' registration.*failed"); +FOUND 1 /the secret file has incorrect length/ in mysqld.1.err +create table t1(c1 bigint not null, b char(200)) engine=innodb encrypted=yes encryption_key_id=1; +ERROR HY000: Can't create table `test`.`t1` (errno: 140 "Wrong create options") +select plugin_status from information_schema.plugins +where plugin_name = 'file_key_management'; +plugin_status +# Test checks if opening an too large secret does not crash the server. diff --git a/mysql-test/suite/encryption/t/filekeys-data-too-long.key b/mysql-test/suite/encryption/t/filekeys-data-too-long.key new file mode 100644 index 00000000000..ba1624fb324 --- /dev/null +++ b/mysql-test/suite/encryption/t/filekeys-data-too-long.key @@ -0,0 +1,4 @@ +secretsecretsecretsecretsecretsecretsecretsecretsecretsecretsecretsecretsecretsecretsecretsecretsecretsecretsecretsecretsecretsecretsecretsecretsecretsecretsecretsecretsecretsecretsecretsecretsecretsecretsecretsecretsecretsecretsecretsecretsecretsecretsecretsecretsecretsecretsecretsecretsecretsecretsecretsecretsecretsecret +secretsecretsecretsecretsecretsecretsecretsecretsecretsecretsecretsecretsecretsecretsecretsecretsecretsecretsecretsecretsecretsecretsecretsecretsecretsecretsecret +secretsecretsecretsecretsecretsecretsecretsecretsecretsecretsecretsecretsecretsecret + diff --git a/mysql-test/suite/encryption/t/filekeys_secret_too_long.opt b/mysql-test/suite/encryption/t/filekeys_secret_too_long.opt new file mode 100644 index 00000000000..c3f95019f2a --- /dev/null +++ b/mysql-test/suite/encryption/t/filekeys_secret_too_long.opt @@ -0,0 +1,3 @@ +--loose-file-key-management-filekey=FILE:$MTR_SUITE_DIR/t/filekeys-data-too-long.key +--loose-file-key-management-filename=$MTR_SUITE_DIR/t/filekeys-data.enc + diff --git a/mysql-test/suite/encryption/t/filekeys_secret_too_long.test b/mysql-test/suite/encryption/t/filekeys_secret_too_long.test new file mode 100644 index 00000000000..b675f892895 --- /dev/null +++ b/mysql-test/suite/encryption/t/filekeys_secret_too_long.test @@ -0,0 +1,4 @@ +let SEARCH_PATTERN=the secret file has incorrect length; +source filekeys_badtest.inc; + +--echo # Test checks if opening an too large secret does not crash the server. diff --git a/plugin/file_key_management/parser.cc b/plugin/file_key_management/parser.cc index 5a9e5e55d63..8e78e230964 100644 --- a/plugin/file_key_management/parser.cc +++ b/plugin/file_key_management/parser.cc @@ -174,13 +174,24 @@ bool Parser::read_filekey(const char *filekey, char *secret) return 1; } - int len= read(f, secret, MAX_SECRET_SIZE); + int len= read(f, secret, MAX_SECRET_SIZE + 1); if (len <= 0) { my_error(EE_READ,ME_ERROR_LOG, filekey, errno); close(f); return 1; } + + if (len > MAX_SECRET_SIZE) + { + my_printf_error(EE_READ, + "Cannot decrypt %s, the secret file has incorrect length, " + "max secret size is %dB ", + ME_ERROR_LOG, filekey, MAX_SECRET_SIZE); + close(f); + return 1; + } + close(f); while (secret[len - 1] == '\r' || secret[len - 1] == '\n') len--; secret[len]= '\0'; From 55227234ccbc6a05e8a196c7f37879d0f6c9aeaa Mon Sep 17 00:00:00 2001 From: Daniel Black Date: Wed, 19 Oct 2022 19:52:16 +1100 Subject: [PATCH 16/72] MDEV-26872 perfschema.prepared_statements non-deterministic test failure (#2290) Correct by ORDER BY in the output. --- .../perfschema/r/prepared_statements.result | 60 +++++++++---------- .../perfschema/t/prepared_statements.test | 2 +- 2 files changed, 31 insertions(+), 31 deletions(-) diff --git a/mysql-test/suite/perfschema/r/prepared_statements.result b/mysql-test/suite/perfschema/r/prepared_statements.result index c11b486094e..0b9a438cd2a 100644 --- a/mysql-test/suite/perfschema/r/prepared_statements.result +++ b/mysql-test/suite/perfschema/r/prepared_statements.result @@ -11,7 +11,7 @@ PREPARE st2 FROM @s; PREPARE st3 FROM 'INSERT INTO t1 SELECT * FROM t1 WHERE a<=?'; PREPARE st4 FROM '(SELECT a FROM t1) UNION (SELECT a+10 FROM t1) ORDER BY RAND()*0+a'; -SELECT STATEMENT_NAME, SQL_TEXT, COUNT_REPREPARE, COUNT_EXECUTE, SUM_ROWS_SENT, SUM_SELECT_SCAN, SUM_NO_INDEX_USED FROM performance_schema.prepared_statements_instances ; +SELECT STATEMENT_NAME, SQL_TEXT, COUNT_REPREPARE, COUNT_EXECUTE, SUM_ROWS_SENT, SUM_SELECT_SCAN, SUM_NO_INDEX_USED FROM performance_schema.prepared_statements_instances ORDER BY STATEMENT_NAME, SQL_TEXT; STATEMENT_NAME st1 SQL_TEXT SELECT SQRT(POW(?,2) + POW(?,2)) AS hypotenuse COUNT_REPREPARE 0 @@ -88,7 +88,7 @@ OBJECT_TYPE NULL OBJECT_SCHEMA NULL OBJECT_NAME NULL EVENT_NAME statement/sql/select -SQL_TEXT SELECT STATEMENT_NAME, SQL_TEXT, COUNT_REPREPARE, COUNT_EXECUTE, SUM_ROWS_SENT, SUM_SELECT_SCAN, SUM_NO_INDEX_USED FROM performance_schema.prepared_statements_instances +SQL_TEXT SELECT STATEMENT_NAME, SQL_TEXT, COUNT_REPREPARE, COUNT_EXECUTE, SUM_ROWS_SENT, SUM_SELECT_SCAN, SUM_NO_INDEX_USED FROM performance_schema.prepared_statements_instances ORDER BY STATEMENT_NAME, SQL_TEXT OBJECT_TYPE NULL OBJECT_SCHEMA NULL OBJECT_NAME NULL @@ -118,7 +118,7 @@ a 42 80 90 -SELECT STATEMENT_NAME, SQL_TEXT, COUNT_REPREPARE, COUNT_EXECUTE, SUM_ROWS_SENT, SUM_SELECT_SCAN, SUM_NO_INDEX_USED FROM performance_schema.prepared_statements_instances ; +SELECT STATEMENT_NAME, SQL_TEXT, COUNT_REPREPARE, COUNT_EXECUTE, SUM_ROWS_SENT, SUM_SELECT_SCAN, SUM_NO_INDEX_USED FROM performance_schema.prepared_statements_instances ORDER BY STATEMENT_NAME, SQL_TEXT; STATEMENT_NAME st1 SQL_TEXT SELECT SQRT(POW(?,2) + POW(?,2)) AS hypotenuse COUNT_REPREPARE 0 @@ -195,7 +195,7 @@ OBJECT_TYPE NULL OBJECT_SCHEMA NULL OBJECT_NAME NULL EVENT_NAME statement/sql/select -SQL_TEXT SELECT STATEMENT_NAME, SQL_TEXT, COUNT_REPREPARE, COUNT_EXECUTE, SUM_ROWS_SENT, SUM_SELECT_SCAN, SUM_NO_INDEX_USED FROM performance_schema.prepared_statements_instances +SQL_TEXT SELECT STATEMENT_NAME, SQL_TEXT, COUNT_REPREPARE, COUNT_EXECUTE, SUM_ROWS_SENT, SUM_SELECT_SCAN, SUM_NO_INDEX_USED FROM performance_schema.prepared_statements_instances ORDER BY STATEMENT_NAME, SQL_TEXT OBJECT_TYPE NULL OBJECT_SCHEMA NULL OBJECT_NAME NULL @@ -240,12 +240,12 @@ OBJECT_TYPE NULL OBJECT_SCHEMA NULL OBJECT_NAME NULL EVENT_NAME statement/sql/select -SQL_TEXT SELECT STATEMENT_NAME, SQL_TEXT, COUNT_REPREPARE, COUNT_EXECUTE, SUM_ROWS_SENT, SUM_SELECT_SCAN, SUM_NO_INDEX_USED FROM performance_schema.prepared_statements_instances +SQL_TEXT SELECT STATEMENT_NAME, SQL_TEXT, COUNT_REPREPARE, COUNT_EXECUTE, SUM_ROWS_SENT, SUM_SELECT_SCAN, SUM_NO_INDEX_USED FROM performance_schema.prepared_statements_instances ORDER BY STATEMENT_NAME, SQL_TEXT OBJECT_TYPE NULL OBJECT_SCHEMA NULL OBJECT_NAME NULL TRUNCATE TABLE performance_schema.prepared_statements_instances ; -SELECT STATEMENT_NAME, SQL_TEXT, COUNT_REPREPARE, COUNT_EXECUTE, SUM_ROWS_SENT, SUM_SELECT_SCAN, SUM_NO_INDEX_USED FROM performance_schema.prepared_statements_instances ; +SELECT STATEMENT_NAME, SQL_TEXT, COUNT_REPREPARE, COUNT_EXECUTE, SUM_ROWS_SENT, SUM_SELECT_SCAN, SUM_NO_INDEX_USED FROM performance_schema.prepared_statements_instances ORDER BY STATEMENT_NAME, SQL_TEXT; STATEMENT_NAME st1 SQL_TEXT SELECT SQRT(POW(?,2) + POW(?,2)) AS hypotenuse COUNT_REPREPARE 0 @@ -279,7 +279,7 @@ DEALLOCATE PREPARE st2; DEALLOCATE PREPARE st3; DEALLOCATE PREPARE st4; DROP TABLE t1; -SELECT STATEMENT_NAME, SQL_TEXT, COUNT_REPREPARE, COUNT_EXECUTE, SUM_ROWS_SENT, SUM_SELECT_SCAN, SUM_NO_INDEX_USED FROM performance_schema.prepared_statements_instances ; +SELECT STATEMENT_NAME, SQL_TEXT, COUNT_REPREPARE, COUNT_EXECUTE, SUM_ROWS_SENT, SUM_SELECT_SCAN, SUM_NO_INDEX_USED FROM performance_schema.prepared_statements_instances ORDER BY STATEMENT_NAME, SQL_TEXT; SELECT EVENT_NAME, SQL_TEXT, OBJECT_TYPE, OBJECT_SCHEMA, OBJECT_NAME FROM performance_schema.events_statements_history_long WHERE CURRENT_SCHEMA='db' ; EVENT_NAME statement/sql/truncate SQL_TEXT TRUNCATE TABLE performance_schema.events_statements_history_long @@ -328,7 +328,7 @@ OBJECT_TYPE NULL OBJECT_SCHEMA NULL OBJECT_NAME NULL EVENT_NAME statement/sql/select -SQL_TEXT SELECT STATEMENT_NAME, SQL_TEXT, COUNT_REPREPARE, COUNT_EXECUTE, SUM_ROWS_SENT, SUM_SELECT_SCAN, SUM_NO_INDEX_USED FROM performance_schema.prepared_statements_instances +SQL_TEXT SELECT STATEMENT_NAME, SQL_TEXT, COUNT_REPREPARE, COUNT_EXECUTE, SUM_ROWS_SENT, SUM_SELECT_SCAN, SUM_NO_INDEX_USED FROM performance_schema.prepared_statements_instances ORDER BY STATEMENT_NAME, SQL_TEXT OBJECT_TYPE NULL OBJECT_SCHEMA NULL OBJECT_NAME NULL @@ -373,7 +373,7 @@ OBJECT_TYPE NULL OBJECT_SCHEMA NULL OBJECT_NAME NULL EVENT_NAME statement/sql/select -SQL_TEXT SELECT STATEMENT_NAME, SQL_TEXT, COUNT_REPREPARE, COUNT_EXECUTE, SUM_ROWS_SENT, SUM_SELECT_SCAN, SUM_NO_INDEX_USED FROM performance_schema.prepared_statements_instances +SQL_TEXT SELECT STATEMENT_NAME, SQL_TEXT, COUNT_REPREPARE, COUNT_EXECUTE, SUM_ROWS_SENT, SUM_SELECT_SCAN, SUM_NO_INDEX_USED FROM performance_schema.prepared_statements_instances ORDER BY STATEMENT_NAME, SQL_TEXT OBJECT_TYPE NULL OBJECT_SCHEMA NULL OBJECT_NAME NULL @@ -388,7 +388,7 @@ OBJECT_TYPE NULL OBJECT_SCHEMA NULL OBJECT_NAME NULL EVENT_NAME statement/sql/select -SQL_TEXT SELECT STATEMENT_NAME, SQL_TEXT, COUNT_REPREPARE, COUNT_EXECUTE, SUM_ROWS_SENT, SUM_SELECT_SCAN, SUM_NO_INDEX_USED FROM performance_schema.prepared_statements_instances +SQL_TEXT SELECT STATEMENT_NAME, SQL_TEXT, COUNT_REPREPARE, COUNT_EXECUTE, SUM_ROWS_SENT, SUM_SELECT_SCAN, SUM_NO_INDEX_USED FROM performance_schema.prepared_statements_instances ORDER BY STATEMENT_NAME, SQL_TEXT OBJECT_TYPE NULL OBJECT_SCHEMA NULL OBJECT_NAME NULL @@ -418,7 +418,7 @@ OBJECT_TYPE NULL OBJECT_SCHEMA NULL OBJECT_NAME NULL EVENT_NAME statement/sql/select -SQL_TEXT SELECT STATEMENT_NAME, SQL_TEXT, COUNT_REPREPARE, COUNT_EXECUTE, SUM_ROWS_SENT, SUM_SELECT_SCAN, SUM_NO_INDEX_USED FROM performance_schema.prepared_statements_instances +SQL_TEXT SELECT STATEMENT_NAME, SQL_TEXT, COUNT_REPREPARE, COUNT_EXECUTE, SUM_ROWS_SENT, SUM_SELECT_SCAN, SUM_NO_INDEX_USED FROM performance_schema.prepared_statements_instances ORDER BY STATEMENT_NAME, SQL_TEXT OBJECT_TYPE NULL OBJECT_SCHEMA NULL OBJECT_NAME NULL @@ -433,7 +433,7 @@ PREPARE st2 FROM @s; PREPARE st3 FROM 'INSERT INTO t1 SELECT * FROM t1 WHERE a<=?'; PREPARE st4 FROM '(SELECT a FROM t1) UNION (SELECT a+10 FROM t1) ORDER BY RAND()*0+a'; -SELECT STATEMENT_NAME, SQL_TEXT, COUNT_REPREPARE, COUNT_EXECUTE, SUM_ROWS_SENT, SUM_SELECT_SCAN, SUM_NO_INDEX_USED FROM performance_schema.prepared_statements_instances ; +SELECT STATEMENT_NAME, SQL_TEXT, COUNT_REPREPARE, COUNT_EXECUTE, SUM_ROWS_SENT, SUM_SELECT_SCAN, SUM_NO_INDEX_USED FROM performance_schema.prepared_statements_instances ORDER BY STATEMENT_NAME, SQL_TEXT; SELECT EVENT_NAME, SQL_TEXT, OBJECT_TYPE, OBJECT_SCHEMA, OBJECT_NAME FROM performance_schema.events_statements_history_long WHERE CURRENT_SCHEMA='db' ; EVENT_NAME statement/sql/truncate SQL_TEXT TRUNCATE TABLE performance_schema.events_statements_history_long @@ -466,7 +466,7 @@ a 42 80 90 -SELECT STATEMENT_NAME, SQL_TEXT, COUNT_REPREPARE, COUNT_EXECUTE, SUM_ROWS_SENT, SUM_SELECT_SCAN, SUM_NO_INDEX_USED FROM performance_schema.prepared_statements_instances ; +SELECT STATEMENT_NAME, SQL_TEXT, COUNT_REPREPARE, COUNT_EXECUTE, SUM_ROWS_SENT, SUM_SELECT_SCAN, SUM_NO_INDEX_USED FROM performance_schema.prepared_statements_instances ORDER BY STATEMENT_NAME, SQL_TEXT; SELECT EVENT_NAME, SQL_TEXT, OBJECT_TYPE, OBJECT_SCHEMA, OBJECT_NAME FROM performance_schema.events_statements_history_long WHERE CURRENT_SCHEMA='db' ; EVENT_NAME statement/sql/truncate SQL_TEXT TRUNCATE TABLE performance_schema.events_statements_history_long @@ -478,7 +478,7 @@ DEALLOCATE PREPARE st2; DEALLOCATE PREPARE st3; DEALLOCATE PREPARE st4; DROP TABLE t1; -SELECT STATEMENT_NAME, SQL_TEXT, COUNT_REPREPARE, COUNT_EXECUTE, SUM_ROWS_SENT, SUM_SELECT_SCAN, SUM_NO_INDEX_USED FROM performance_schema.prepared_statements_instances ; +SELECT STATEMENT_NAME, SQL_TEXT, COUNT_REPREPARE, COUNT_EXECUTE, SUM_ROWS_SENT, SUM_SELECT_SCAN, SUM_NO_INDEX_USED FROM performance_schema.prepared_statements_instances ORDER BY STATEMENT_NAME, SQL_TEXT; SELECT EVENT_NAME, SQL_TEXT, OBJECT_TYPE, OBJECT_SCHEMA, OBJECT_NAME FROM performance_schema.events_statements_history_long WHERE CURRENT_SCHEMA='db' ; EVENT_NAME statement/sql/truncate SQL_TEXT TRUNCATE TABLE performance_schema.events_statements_history_long @@ -488,7 +488,7 @@ OBJECT_NAME NULL TRUNCATE TABLE performance_schema.events_statements_history_long ; UPDATE performance_schema.setup_consumers SET ENABLED = 'YES'; PREPARE st FROM 'SELECT SUM(1000 + ?) AS total'; -SELECT STATEMENT_NAME, SQL_TEXT, COUNT_REPREPARE, COUNT_EXECUTE, SUM_ROWS_SENT, SUM_SELECT_SCAN, SUM_NO_INDEX_USED FROM performance_schema.prepared_statements_instances ; +SELECT STATEMENT_NAME, SQL_TEXT, COUNT_REPREPARE, COUNT_EXECUTE, SUM_ROWS_SENT, SUM_SELECT_SCAN, SUM_NO_INDEX_USED FROM performance_schema.prepared_statements_instances ORDER BY STATEMENT_NAME, SQL_TEXT; STATEMENT_NAME st SQL_TEXT SELECT SUM(1000 + ?) AS total COUNT_REPREPARE 0 @@ -500,7 +500,7 @@ SET @d=100; EXECUTE st USING @d; total 1100 -SELECT STATEMENT_NAME, SQL_TEXT, COUNT_REPREPARE, COUNT_EXECUTE, SUM_ROWS_SENT, SUM_SELECT_SCAN, SUM_NO_INDEX_USED FROM performance_schema.prepared_statements_instances ; +SELECT STATEMENT_NAME, SQL_TEXT, COUNT_REPREPARE, COUNT_EXECUTE, SUM_ROWS_SENT, SUM_SELECT_SCAN, SUM_NO_INDEX_USED FROM performance_schema.prepared_statements_instances ORDER BY STATEMENT_NAME, SQL_TEXT; STATEMENT_NAME st SQL_TEXT SELECT SUM(1000 + ?) AS total COUNT_REPREPARE 0 @@ -512,7 +512,7 @@ SET @d = @d + 100; EXECUTE st USING @d; total 1200 -SELECT STATEMENT_NAME, SQL_TEXT, COUNT_REPREPARE, COUNT_EXECUTE, SUM_ROWS_SENT, SUM_SELECT_SCAN, SUM_NO_INDEX_USED FROM performance_schema.prepared_statements_instances ; +SELECT STATEMENT_NAME, SQL_TEXT, COUNT_REPREPARE, COUNT_EXECUTE, SUM_ROWS_SENT, SUM_SELECT_SCAN, SUM_NO_INDEX_USED FROM performance_schema.prepared_statements_instances ORDER BY STATEMENT_NAME, SQL_TEXT; STATEMENT_NAME st SQL_TEXT SELECT SUM(1000 + ?) AS total COUNT_REPREPARE 0 @@ -524,7 +524,7 @@ SET @d = @d + 100; EXECUTE st USING @d; total 1300 -SELECT STATEMENT_NAME, SQL_TEXT, COUNT_REPREPARE, COUNT_EXECUTE, SUM_ROWS_SENT, SUM_SELECT_SCAN, SUM_NO_INDEX_USED FROM performance_schema.prepared_statements_instances ; +SELECT STATEMENT_NAME, SQL_TEXT, COUNT_REPREPARE, COUNT_EXECUTE, SUM_ROWS_SENT, SUM_SELECT_SCAN, SUM_NO_INDEX_USED FROM performance_schema.prepared_statements_instances ORDER BY STATEMENT_NAME, SQL_TEXT; STATEMENT_NAME st SQL_TEXT SELECT SUM(1000 + ?) AS total COUNT_REPREPARE 0 @@ -536,7 +536,7 @@ SET @d = @d + 100; EXECUTE st USING @d; total 1400 -SELECT STATEMENT_NAME, SQL_TEXT, COUNT_REPREPARE, COUNT_EXECUTE, SUM_ROWS_SENT, SUM_SELECT_SCAN, SUM_NO_INDEX_USED FROM performance_schema.prepared_statements_instances ; +SELECT STATEMENT_NAME, SQL_TEXT, COUNT_REPREPARE, COUNT_EXECUTE, SUM_ROWS_SENT, SUM_SELECT_SCAN, SUM_NO_INDEX_USED FROM performance_schema.prepared_statements_instances ORDER BY STATEMENT_NAME, SQL_TEXT; STATEMENT_NAME st SQL_TEXT SELECT SUM(1000 + ?) AS total COUNT_REPREPARE 0 @@ -548,7 +548,7 @@ SET @d = @d + 100; EXECUTE st USING @d; total 1500 -SELECT STATEMENT_NAME, SQL_TEXT, COUNT_REPREPARE, COUNT_EXECUTE, SUM_ROWS_SENT, SUM_SELECT_SCAN, SUM_NO_INDEX_USED FROM performance_schema.prepared_statements_instances ; +SELECT STATEMENT_NAME, SQL_TEXT, COUNT_REPREPARE, COUNT_EXECUTE, SUM_ROWS_SENT, SUM_SELECT_SCAN, SUM_NO_INDEX_USED FROM performance_schema.prepared_statements_instances ORDER BY STATEMENT_NAME, SQL_TEXT; STATEMENT_NAME st SQL_TEXT SELECT SUM(1000 + ?) AS total COUNT_REPREPARE 0 @@ -560,7 +560,7 @@ SET @d = @d + 100; EXECUTE st USING @d; total 1600 -SELECT STATEMENT_NAME, SQL_TEXT, COUNT_REPREPARE, COUNT_EXECUTE, SUM_ROWS_SENT, SUM_SELECT_SCAN, SUM_NO_INDEX_USED FROM performance_schema.prepared_statements_instances ; +SELECT STATEMENT_NAME, SQL_TEXT, COUNT_REPREPARE, COUNT_EXECUTE, SUM_ROWS_SENT, SUM_SELECT_SCAN, SUM_NO_INDEX_USED FROM performance_schema.prepared_statements_instances ORDER BY STATEMENT_NAME, SQL_TEXT; STATEMENT_NAME st SQL_TEXT SELECT SUM(1000 + ?) AS total COUNT_REPREPARE 0 @@ -569,7 +569,7 @@ SUM_ROWS_SENT 6 SUM_SELECT_SCAN 0 SUM_NO_INDEX_USED 0 TRUNCATE TABLE performance_schema.prepared_statements_instances ; -SELECT STATEMENT_NAME, SQL_TEXT, COUNT_REPREPARE, COUNT_EXECUTE, SUM_ROWS_SENT, SUM_SELECT_SCAN, SUM_NO_INDEX_USED FROM performance_schema.prepared_statements_instances ; +SELECT STATEMENT_NAME, SQL_TEXT, COUNT_REPREPARE, COUNT_EXECUTE, SUM_ROWS_SENT, SUM_SELECT_SCAN, SUM_NO_INDEX_USED FROM performance_schema.prepared_statements_instances ORDER BY STATEMENT_NAME, SQL_TEXT; STATEMENT_NAME st SQL_TEXT SELECT SUM(1000 + ?) AS total COUNT_REPREPARE 0 @@ -583,7 +583,7 @@ SET @d=3274; EXECUTE st USING @d; total 4274 -SELECT STATEMENT_NAME, SQL_TEXT, COUNT_REPREPARE, COUNT_EXECUTE, SUM_ROWS_SENT, SUM_SELECT_SCAN, SUM_NO_INDEX_USED FROM performance_schema.prepared_statements_instances ; +SELECT STATEMENT_NAME, SQL_TEXT, COUNT_REPREPARE, COUNT_EXECUTE, SUM_ROWS_SENT, SUM_SELECT_SCAN, SUM_NO_INDEX_USED FROM performance_schema.prepared_statements_instances ORDER BY STATEMENT_NAME, SQL_TEXT; STATEMENT_NAME st SQL_TEXT SELECT SUM(1000 + ?) AS total COUNT_REPREPARE 0 @@ -594,7 +594,7 @@ SUM_NO_INDEX_USED 0 UPDATE performance_schema.setup_instruments SET ENABLED = 'NO' WHERE NAME like "statement/sql/prepare%"; DEALLOCATE PREPARE st; -SELECT STATEMENT_NAME, SQL_TEXT, COUNT_REPREPARE, COUNT_EXECUTE, SUM_ROWS_SENT, SUM_SELECT_SCAN, SUM_NO_INDEX_USED FROM performance_schema.prepared_statements_instances ; +SELECT STATEMENT_NAME, SQL_TEXT, COUNT_REPREPARE, COUNT_EXECUTE, SUM_ROWS_SENT, SUM_SELECT_SCAN, SUM_NO_INDEX_USED FROM performance_schema.prepared_statements_instances ORDER BY STATEMENT_NAME, SQL_TEXT; UPDATE performance_schema.setup_instruments SET ENABLED = 'YES' WHERE NAME like "statement/sql/prepare%"; UPDATE performance_schema.setup_instruments SET ENABLED = 'YES' @@ -606,7 +606,7 @@ age INT ); INSERT INTO tab VALUES(1,"Nakshatr",25),(2,"chanda",24),(3,"tejas",78); PREPARE st FROM 'SELECT * FROM tab'; -SELECT STATEMENT_NAME, SQL_TEXT, COUNT_REPREPARE, COUNT_EXECUTE, SUM_ROWS_SENT, SUM_SELECT_SCAN, SUM_NO_INDEX_USED FROM performance_schema.prepared_statements_instances ; +SELECT STATEMENT_NAME, SQL_TEXT, COUNT_REPREPARE, COUNT_EXECUTE, SUM_ROWS_SENT, SUM_SELECT_SCAN, SUM_NO_INDEX_USED FROM performance_schema.prepared_statements_instances ORDER BY STATEMENT_NAME, SQL_TEXT; STATEMENT_NAME st SQL_TEXT SELECT * FROM tab COUNT_REPREPARE 0 @@ -619,7 +619,7 @@ Id name age 1 Nakshatr 25 2 chanda 24 3 tejas 78 -SELECT STATEMENT_NAME, SQL_TEXT, COUNT_REPREPARE, COUNT_EXECUTE, SUM_ROWS_SENT, SUM_SELECT_SCAN, SUM_NO_INDEX_USED FROM performance_schema.prepared_statements_instances ; +SELECT STATEMENT_NAME, SQL_TEXT, COUNT_REPREPARE, COUNT_EXECUTE, SUM_ROWS_SENT, SUM_SELECT_SCAN, SUM_NO_INDEX_USED FROM performance_schema.prepared_statements_instances ORDER BY STATEMENT_NAME, SQL_TEXT; STATEMENT_NAME st SQL_TEXT SELECT * FROM tab COUNT_REPREPARE 0 @@ -633,7 +633,7 @@ Id name 1 Nakshatr 2 chanda 3 tejas -SELECT STATEMENT_NAME, SQL_TEXT, COUNT_REPREPARE, COUNT_EXECUTE, SUM_ROWS_SENT, SUM_SELECT_SCAN, SUM_NO_INDEX_USED FROM performance_schema.prepared_statements_instances ; +SELECT STATEMENT_NAME, SQL_TEXT, COUNT_REPREPARE, COUNT_EXECUTE, SUM_ROWS_SENT, SUM_SELECT_SCAN, SUM_NO_INDEX_USED FROM performance_schema.prepared_statements_instances ORDER BY STATEMENT_NAME, SQL_TEXT; STATEMENT_NAME st SQL_TEXT SELECT * FROM tab COUNT_REPREPARE 1 @@ -647,7 +647,7 @@ Id name age 1 Nakshatr NULL 2 chanda NULL 3 tejas NULL -SELECT STATEMENT_NAME, SQL_TEXT, COUNT_REPREPARE, COUNT_EXECUTE, SUM_ROWS_SENT, SUM_SELECT_SCAN, SUM_NO_INDEX_USED FROM performance_schema.prepared_statements_instances ; +SELECT STATEMENT_NAME, SQL_TEXT, COUNT_REPREPARE, COUNT_EXECUTE, SUM_ROWS_SENT, SUM_SELECT_SCAN, SUM_NO_INDEX_USED FROM performance_schema.prepared_statements_instances ORDER BY STATEMENT_NAME, SQL_TEXT; STATEMENT_NAME st SQL_TEXT SELECT * FROM tab COUNT_REPREPARE 2 @@ -656,7 +656,7 @@ SUM_ROWS_SENT 9 SUM_SELECT_SCAN 3 SUM_NO_INDEX_USED 3 TRUNCATE TABLE performance_schema.prepared_statements_instances ; -SELECT STATEMENT_NAME, SQL_TEXT, COUNT_REPREPARE, COUNT_EXECUTE, SUM_ROWS_SENT, SUM_SELECT_SCAN, SUM_NO_INDEX_USED FROM performance_schema.prepared_statements_instances ; +SELECT STATEMENT_NAME, SQL_TEXT, COUNT_REPREPARE, COUNT_EXECUTE, SUM_ROWS_SENT, SUM_SELECT_SCAN, SUM_NO_INDEX_USED FROM performance_schema.prepared_statements_instances ORDER BY STATEMENT_NAME, SQL_TEXT; STATEMENT_NAME st SQL_TEXT SELECT * FROM tab COUNT_REPREPARE 0 @@ -665,7 +665,7 @@ SUM_ROWS_SENT 0 SUM_SELECT_SCAN 0 SUM_NO_INDEX_USED 0 DEALLOCATE PREPARE st; -SELECT STATEMENT_NAME, SQL_TEXT, COUNT_REPREPARE, COUNT_EXECUTE, SUM_ROWS_SENT, SUM_SELECT_SCAN, SUM_NO_INDEX_USED FROM performance_schema.prepared_statements_instances ; +SELECT STATEMENT_NAME, SQL_TEXT, COUNT_REPREPARE, COUNT_EXECUTE, SUM_ROWS_SENT, SUM_SELECT_SCAN, SUM_NO_INDEX_USED FROM performance_schema.prepared_statements_instances ORDER BY STATEMENT_NAME, SQL_TEXT; TRUNCATE TABLE performance_schema.prepared_statements_instances ; TRUNCATE TABLE performance_schema.events_statements_history_long ; DROP TABLE tab; diff --git a/mysql-test/suite/perfschema/t/prepared_statements.test b/mysql-test/suite/perfschema/t/prepared_statements.test index 75d10238ac1..1c14b4cff65 100644 --- a/mysql-test/suite/perfschema/t/prepared_statements.test +++ b/mysql-test/suite/perfschema/t/prepared_statements.test @@ -7,7 +7,7 @@ CREATE DATABASE db; USE db; ---let $psi_select = SELECT STATEMENT_NAME, SQL_TEXT, COUNT_REPREPARE, COUNT_EXECUTE, SUM_ROWS_SENT, SUM_SELECT_SCAN, SUM_NO_INDEX_USED FROM performance_schema.prepared_statements_instances +--let $psi_select = SELECT STATEMENT_NAME, SQL_TEXT, COUNT_REPREPARE, COUNT_EXECUTE, SUM_ROWS_SENT, SUM_SELECT_SCAN, SUM_NO_INDEX_USED FROM performance_schema.prepared_statements_instances ORDER BY STATEMENT_NAME, SQL_TEXT --let $psi_truncate = TRUNCATE TABLE performance_schema.prepared_statements_instances --let $eshl_select = SELECT EVENT_NAME, SQL_TEXT, OBJECT_TYPE, OBJECT_SCHEMA, OBJECT_NAME FROM performance_schema.events_statements_history_long WHERE CURRENT_SCHEMA='db' --let $eshl_truncate = TRUNCATE TABLE performance_schema.events_statements_history_long From 3a62ff7e8980239a39e85393c6a797bb7acf97ed Mon Sep 17 00:00:00 2001 From: Daniel Black Date: Wed, 19 Oct 2022 19:25:48 +1100 Subject: [PATCH 17/72] Revert "MDEV-25343 add read secret size in file key plugin" This reverts commit cee7175b79a22c29a82ef328aba208f90afcea86. --- .../encryption/r/filekeys_secret_too_long.result | 10 ---------- .../suite/encryption/t/filekeys-data-too-long.key | 4 ---- .../suite/encryption/t/filekeys_secret_too_long.opt | 3 --- .../encryption/t/filekeys_secret_too_long.test | 4 ---- plugin/file_key_management/parser.cc | 13 +------------ 5 files changed, 1 insertion(+), 33 deletions(-) delete mode 100644 mysql-test/suite/encryption/r/filekeys_secret_too_long.result delete mode 100644 mysql-test/suite/encryption/t/filekeys-data-too-long.key delete mode 100644 mysql-test/suite/encryption/t/filekeys_secret_too_long.opt delete mode 100644 mysql-test/suite/encryption/t/filekeys_secret_too_long.test diff --git a/mysql-test/suite/encryption/r/filekeys_secret_too_long.result b/mysql-test/suite/encryption/r/filekeys_secret_too_long.result deleted file mode 100644 index 32e18513454..00000000000 --- a/mysql-test/suite/encryption/r/filekeys_secret_too_long.result +++ /dev/null @@ -1,10 +0,0 @@ -call mtr.add_suppression("the secret file has incorrect length"); -call mtr.add_suppression("Plugin 'file_key_management' init function returned error"); -call mtr.add_suppression("Plugin 'file_key_management' registration.*failed"); -FOUND 1 /the secret file has incorrect length/ in mysqld.1.err -create table t1(c1 bigint not null, b char(200)) engine=innodb encrypted=yes encryption_key_id=1; -ERROR HY000: Can't create table `test`.`t1` (errno: 140 "Wrong create options") -select plugin_status from information_schema.plugins -where plugin_name = 'file_key_management'; -plugin_status -# Test checks if opening an too large secret does not crash the server. diff --git a/mysql-test/suite/encryption/t/filekeys-data-too-long.key b/mysql-test/suite/encryption/t/filekeys-data-too-long.key deleted file mode 100644 index ba1624fb324..00000000000 --- a/mysql-test/suite/encryption/t/filekeys-data-too-long.key +++ /dev/null @@ -1,4 +0,0 @@ -secretsecretsecretsecretsecretsecretsecretsecretsecretsecretsecretsecretsecretsecretsecretsecretsecretsecretsecretsecretsecretsecretsecretsecretsecretsecretsecretsecretsecretsecretsecretsecretsecretsecretsecretsecretsecretsecretsecretsecretsecretsecretsecretsecretsecretsecretsecretsecretsecretsecretsecretsecretsecretsecret -secretsecretsecretsecretsecretsecretsecretsecretsecretsecretsecretsecretsecretsecretsecretsecretsecretsecretsecretsecretsecretsecretsecretsecretsecretsecretsecret -secretsecretsecretsecretsecretsecretsecretsecretsecretsecretsecretsecretsecretsecret - diff --git a/mysql-test/suite/encryption/t/filekeys_secret_too_long.opt b/mysql-test/suite/encryption/t/filekeys_secret_too_long.opt deleted file mode 100644 index c3f95019f2a..00000000000 --- a/mysql-test/suite/encryption/t/filekeys_secret_too_long.opt +++ /dev/null @@ -1,3 +0,0 @@ ---loose-file-key-management-filekey=FILE:$MTR_SUITE_DIR/t/filekeys-data-too-long.key ---loose-file-key-management-filename=$MTR_SUITE_DIR/t/filekeys-data.enc - diff --git a/mysql-test/suite/encryption/t/filekeys_secret_too_long.test b/mysql-test/suite/encryption/t/filekeys_secret_too_long.test deleted file mode 100644 index b675f892895..00000000000 --- a/mysql-test/suite/encryption/t/filekeys_secret_too_long.test +++ /dev/null @@ -1,4 +0,0 @@ -let SEARCH_PATTERN=the secret file has incorrect length; -source filekeys_badtest.inc; - ---echo # Test checks if opening an too large secret does not crash the server. diff --git a/plugin/file_key_management/parser.cc b/plugin/file_key_management/parser.cc index 8e78e230964..5a9e5e55d63 100644 --- a/plugin/file_key_management/parser.cc +++ b/plugin/file_key_management/parser.cc @@ -174,24 +174,13 @@ bool Parser::read_filekey(const char *filekey, char *secret) return 1; } - int len= read(f, secret, MAX_SECRET_SIZE + 1); + int len= read(f, secret, MAX_SECRET_SIZE); if (len <= 0) { my_error(EE_READ,ME_ERROR_LOG, filekey, errno); close(f); return 1; } - - if (len > MAX_SECRET_SIZE) - { - my_printf_error(EE_READ, - "Cannot decrypt %s, the secret file has incorrect length, " - "max secret size is %dB ", - ME_ERROR_LOG, filekey, MAX_SECRET_SIZE); - close(f); - return 1; - } - close(f); while (secret[len - 1] == '\r' || secret[len - 1] == '\n') len--; secret[len]= '\0'; From 81ad6787cc0a6df59e1115e307a2429daa11e079 Mon Sep 17 00:00:00 2001 From: Monty Date: Tue, 18 Oct 2022 19:44:07 +0300 Subject: [PATCH 18/72] MDEV-29508 perfschema.short_option_1 fails with MSAN - Error in accept This was caused by the short_option_1-master.opt file that had the option -T12, which means (among other things) to use blocking for sockets. This was supported up to MariaDB 10.4, but not in 10.5 where we removed the code that changes blocking sockets to non blocking in case of errors. Fixed by ignoring the TEST_BLOCKING flag and also by not using the -T12 argument in short_option_1. Other things: - Added back support for valgrind (the original issue had nothing to do with valgrind). - While debugging I noticed that the retry loop in handle_connections_sockets() was doing a lot of work during shutdown. Fixed by not doing retrys during shutdown. --- mysql-test/suite/perfschema/t/short_option_1-master.opt | 2 +- mysql-test/suite/perfschema/t/short_option_1.test | 1 - sql/mysqld.cc | 4 ++-- 3 files changed, 3 insertions(+), 4 deletions(-) diff --git a/mysql-test/suite/perfschema/t/short_option_1-master.opt b/mysql-test/suite/perfschema/t/short_option_1-master.opt index a9cda7a08ed..3b57e0826c0 100644 --- a/mysql-test/suite/perfschema/t/short_option_1-master.opt +++ b/mysql-test/suite/perfschema/t/short_option_1-master.opt @@ -1 +1 @@ --a -Cutf8 --collation-server=utf8_bin -T12 -W2 +-a -Cutf8 --collation-server=utf8_bin -W2 diff --git a/mysql-test/suite/perfschema/t/short_option_1.test b/mysql-test/suite/perfschema/t/short_option_1.test index fbfbdda1bbc..29ddaf43263 100644 --- a/mysql-test/suite/perfschema/t/short_option_1.test +++ b/mysql-test/suite/perfschema/t/short_option_1.test @@ -1,5 +1,4 @@ # Work around MDEV-29508 ---source include/not_valgrind.inc # Tests for PERFORMANCE_SCHEMA # Check server start for short server start options diff --git a/sql/mysqld.cc b/sql/mysqld.cc index 2cc9e878f74..7710716506a 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -6307,7 +6307,7 @@ void handle_connections_sockets() sock = unix_sock; #endif // HAVE_POLL - for (uint retry=0; retry < MAX_ACCEPT_RETRY; retry++) + for (uint retry=0; retry < MAX_ACCEPT_RETRY && !abort_loop; retry++) { size_socket length= sizeof(struct sockaddr_storage); MYSQL_SOCKET new_sock; @@ -8044,7 +8044,7 @@ mysqld_get_one_option(const struct my_option *opt, const char *argument, global_system_variables.log_warnings= atoi(argument); break; case 'T': - test_flags= argument ? (uint) atoi(argument) : 0; + test_flags= argument ? ((uint) atoi(argument) & ~TEST_BLOCKING) : 0; opt_endinfo=1; break; case OPT_THREAD_CONCURRENCY: From 9de37e07de860fdbaade1de482692a9221fbcc98 Mon Sep 17 00:00:00 2001 From: Alexey Botchkov Date: Tue, 18 Oct 2022 00:01:58 +0400 Subject: [PATCH 19/72] MDEV-19569 Assertion `table_list->table' failed in find_field_in_table_ref. Disallow subqueries in The PARTITIN BY INTERVAL syntax. Fix various interval types that now fail as they break syntax in the par file. --- .../suite/versioning/r/partition.result | 101 ++++++++++++++++++ mysql-test/suite/versioning/t/partition.test | 74 +++++++++++++ sql/sql_time.cc | 29 +++-- sql/sql_yacc.yy | 5 +- 4 files changed, 197 insertions(+), 12 deletions(-) diff --git a/mysql-test/suite/versioning/r/partition.result b/mysql-test/suite/versioning/r/partition.result index 9c94e76a68f..8adde14a875 100644 --- a/mysql-test/suite/versioning/r/partition.result +++ b/mysql-test/suite/versioning/r/partition.result @@ -1145,5 +1145,106 @@ insert into t values (1),(2); create trigger tr before insert on t for each row update tcount set c = c + 1; insert into t select * from t; drop table tcount, t; +# +# MDEV-19569 Assertion `table_list->table' failed in find_field_in_table_ref and Assertion `table_ref->table || table_ref->view' in Field_iterator_table_ref::set_field_iterator +# +create table t1 (i int); +create table t2 (i int); +alter table t1 partition by system_time +interval (select i from t2) day (partition p1 history, partition pn current); +ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near 'select i from t2) day (partition p1 history, partition pn current)' at line 2 +drop table t1; +create table t1 (id int) with system versioning +partition by system_time +interval (select i from t2) day (partition p1 history, partition pn current); +ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near 'select i from t2) day (partition p1 history, partition pn current)' at line 3 +create table t1 (id int) with system versioning +partition by system_time +interval "hello" day (partition p1 history, partition pn current); +ERROR HY000: Wrong parameters for partitioned `t1`: wrong value for 'INTERVAL' +create table t1 (id int) with system versioning +partition by system_time +interval 3.893 day (partition p1 history, partition pn current); +drop table t1, t2; +create table t1 (id int) with system versioning +partition by system_time interval "3-11" year_month (partition p1 history, partition pn current); +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `id` int(11) DEFAULT NULL +) ENGINE=DEFAULT_ENGINE DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci WITH SYSTEM VERSIONING + PARTITION BY SYSTEM_TIME INTERVAL '3-11' YEAR_MONTH +(PARTITION `p1` HISTORY ENGINE = DEFAULT_ENGINE, + PARTITION `pn` CURRENT ENGINE = DEFAULT_ENGINE) +drop table t1; +create table t1 (id int) with system versioning +partition by system_time interval "3 11" day_hour (partition p1 history, partition pn current); +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `id` int(11) DEFAULT NULL +) ENGINE=DEFAULT_ENGINE DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci WITH SYSTEM VERSIONING + PARTITION BY SYSTEM_TIME INTERVAL '3 11' DAY_HOUR +(PARTITION `p1` HISTORY ENGINE = DEFAULT_ENGINE, + PARTITION `pn` CURRENT ENGINE = DEFAULT_ENGINE) +drop table t1; +create table t1 (id int) with system versioning +partition by system_time interval "3 11:12" day_minute (partition p1 history, partition pn current); +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `id` int(11) DEFAULT NULL +) ENGINE=DEFAULT_ENGINE DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci WITH SYSTEM VERSIONING + PARTITION BY SYSTEM_TIME INTERVAL '3 11:12' DAY_MINUTE +(PARTITION `p1` HISTORY ENGINE = DEFAULT_ENGINE, + PARTITION `pn` CURRENT ENGINE = DEFAULT_ENGINE) +drop table t1; +create table t1 (id int) with system versioning +partition by system_time interval "3 11:12:13" day_second (partition p1 history, partition pn current); +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `id` int(11) DEFAULT NULL +) ENGINE=DEFAULT_ENGINE DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci WITH SYSTEM VERSIONING + PARTITION BY SYSTEM_TIME INTERVAL '3 11:12:13' DAY_SECOND +(PARTITION `p1` HISTORY ENGINE = DEFAULT_ENGINE, + PARTITION `pn` CURRENT ENGINE = DEFAULT_ENGINE) +drop table t1; +create table t1 (id int) with system versioning +partition by system_time interval "11:12" hour_minute (partition p1 history, partition pn current); +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `id` int(11) DEFAULT NULL +) ENGINE=DEFAULT_ENGINE DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci WITH SYSTEM VERSIONING + PARTITION BY SYSTEM_TIME INTERVAL '11:12' HOUR_MINUTE +(PARTITION `p1` HISTORY ENGINE = DEFAULT_ENGINE, + PARTITION `pn` CURRENT ENGINE = DEFAULT_ENGINE) +drop table t1; +create table t1 (id int) with system versioning +partition by system_time interval "11:12:13" hour_second (partition p1 history, partition pn current); +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `id` int(11) DEFAULT NULL +) ENGINE=DEFAULT_ENGINE DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci WITH SYSTEM VERSIONING + PARTITION BY SYSTEM_TIME INTERVAL '11:12:13' HOUR_SECOND +(PARTITION `p1` HISTORY ENGINE = DEFAULT_ENGINE, + PARTITION `pn` CURRENT ENGINE = DEFAULT_ENGINE) +drop table t1; +create table t1 (id int) with system versioning +partition by system_time interval "12:13" minute_second (partition p1 history, partition pn current); +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `id` int(11) DEFAULT NULL +) ENGINE=DEFAULT_ENGINE DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci WITH SYSTEM VERSIONING + PARTITION BY SYSTEM_TIME INTERVAL '12:13' MINUTE_SECOND +(PARTITION `p1` HISTORY ENGINE = DEFAULT_ENGINE, + PARTITION `pn` CURRENT ENGINE = DEFAULT_ENGINE) +drop table t1; +create table t1 (id int) with system versioning +partition by system_time interval "12:13.123" minute_microsecond (partition p1 history, partition pn current); +ERROR HY000: Wrong parameters for partitioned `t1`: wrong value for 'INTERVAL' # End of 10.3 tests set global innodb_stats_persistent= @save_persistent; diff --git a/mysql-test/suite/versioning/t/partition.test b/mysql-test/suite/versioning/t/partition.test index b18493ae91c..9cd6a5d21e8 100644 --- a/mysql-test/suite/versioning/t/partition.test +++ b/mysql-test/suite/versioning/t/partition.test @@ -1098,6 +1098,80 @@ insert into t select * from t; # cleanup drop table tcount, t; +--echo # +--echo # MDEV-19569 Assertion `table_list->table' failed in find_field_in_table_ref and Assertion `table_ref->table || table_ref->view' in Field_iterator_table_ref::set_field_iterator +--echo # +create table t1 (i int); +create table t2 (i int); + +--error ER_PARSE_ERROR +alter table t1 partition by system_time + interval (select i from t2) day (partition p1 history, partition pn current); + +drop table t1; + +--error ER_PARSE_ERROR +create table t1 (id int) with system versioning + partition by system_time + interval (select i from t2) day (partition p1 history, partition pn current); + +--error ER_PART_WRONG_VALUE +create table t1 (id int) with system versioning + partition by system_time + interval "hello" day (partition p1 history, partition pn current); + +create table t1 (id int) with system versioning + partition by system_time + interval 3.893 day (partition p1 history, partition pn current); + +drop table t1, t2; + +create table t1 (id int) with system versioning + partition by system_time interval "3-11" year_month (partition p1 history, partition pn current); +--replace_result $default_engine DEFAULT_ENGINE +show create table t1; +drop table t1; + +create table t1 (id int) with system versioning + partition by system_time interval "3 11" day_hour (partition p1 history, partition pn current); +--replace_result $default_engine DEFAULT_ENGINE +show create table t1; +drop table t1; + +create table t1 (id int) with system versioning + partition by system_time interval "3 11:12" day_minute (partition p1 history, partition pn current); +--replace_result $default_engine DEFAULT_ENGINE +show create table t1; +drop table t1; + +create table t1 (id int) with system versioning + partition by system_time interval "3 11:12:13" day_second (partition p1 history, partition pn current); +--replace_result $default_engine DEFAULT_ENGINE +show create table t1; +drop table t1; + +create table t1 (id int) with system versioning + partition by system_time interval "11:12" hour_minute (partition p1 history, partition pn current); +--replace_result $default_engine DEFAULT_ENGINE +show create table t1; +drop table t1; + +create table t1 (id int) with system versioning + partition by system_time interval "11:12:13" hour_second (partition p1 history, partition pn current); +--replace_result $default_engine DEFAULT_ENGINE +show create table t1; +drop table t1; + +create table t1 (id int) with system versioning + partition by system_time interval "12:13" minute_second (partition p1 history, partition pn current); +--replace_result $default_engine DEFAULT_ENGINE +show create table t1; +drop table t1; + +--error ER_PART_WRONG_VALUE +create table t1 (id int) with system versioning + partition by system_time interval "12:13.123" minute_microsecond (partition p1 history, partition pn current); + --echo # End of 10.3 tests set global innodb_stats_persistent= @save_persistent; diff --git a/sql/sql_time.cc b/sql/sql_time.cc index cb09daff6f5..ec9b76cb3eb 100644 --- a/sql/sql_time.cc +++ b/sql/sql_time.cc @@ -93,34 +93,43 @@ int append_interval(String *str, interval_type int_type, const INTERVAL &interva len= my_snprintf(buf,sizeof(buf),"%u", interval.second_part); break; case INTERVAL_YEAR_MONTH: - len= my_snprintf(buf,sizeof(buf),"%u-%02u", interval.day, interval.month); + len= my_snprintf(buf,sizeof(buf),"'%u-%02u'", + interval.year, interval.month); break; case INTERVAL_DAY_HOUR: - len= my_snprintf(buf,sizeof(buf),"%u %u", interval.day, interval.hour); + len= my_snprintf(buf,sizeof(buf),"'%u %u'", interval.day, interval.hour); break; case INTERVAL_DAY_MINUTE: - len= my_snprintf(buf,sizeof(buf),"%u %u:%02u", interval.day, interval.hour, interval.minute); + len= my_snprintf(buf,sizeof(buf),"'%u %u:%02u'", + interval.day, interval.hour, interval.minute); break; case INTERVAL_DAY_SECOND: - len= my_snprintf(buf,sizeof(buf),"%u %u:%02u:%02u", interval.day, interval.hour, interval.minute, interval.second); + len= my_snprintf(buf,sizeof(buf),"'%u %u:%02u:%02u'", + interval.day, interval.hour, interval.minute, interval.second); break; case INTERVAL_HOUR_MINUTE: - len= my_snprintf(buf,sizeof(buf),"%u:%02u", interval.hour, interval.minute); + len= my_snprintf(buf,sizeof(buf),"'%u:%02u'", interval.hour, interval.minute); break; case INTERVAL_HOUR_SECOND: - len= my_snprintf(buf,sizeof(buf),"%u:%02u:%02u", interval.hour, interval.minute, interval.second); + len= my_snprintf(buf,sizeof(buf),"'%u:%02u:%02u'", + interval.hour, interval.minute, interval.second); break; case INTERVAL_MINUTE_SECOND: - len= my_snprintf(buf,sizeof(buf),"%u:%02u", interval.minute, interval.second); + len= my_snprintf(buf,sizeof(buf),"'%u:%02u'", interval.minute, interval.second); break; case INTERVAL_DAY_MICROSECOND: - len= my_snprintf(buf,sizeof(buf),"%u %u:%02u:%02u.%06u", interval.day, interval.hour, interval.minute, interval.second, interval.second_part); + len= my_snprintf(buf,sizeof(buf),"'%u %u:%02u:%02u.%06u'", + interval.day, interval.hour, interval.minute, + interval.second, interval.second_part); break; case INTERVAL_HOUR_MICROSECOND: - len= my_snprintf(buf,sizeof(buf),"%u:%02u:%02u.%06u", interval.hour, interval.minute, interval.second, interval.second_part); + len= my_snprintf(buf,sizeof(buf),"'%u:%02u:%02u.%06u'", + interval.hour, interval.minute, interval.second, + interval.second_part); break; case INTERVAL_MINUTE_MICROSECOND: - len= my_snprintf(buf,sizeof(buf),"%u:%02u.%06u", interval.minute, interval.second, interval.second_part); + len= my_snprintf(buf,sizeof(buf),"'%u:%02u.%06u'", + interval.minute, interval.second, interval.second_part); break; case INTERVAL_SECOND_MICROSECOND: len= my_snprintf(buf,sizeof(buf),"%u.%06u", interval.second, interval.second_part); diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy index 73783f26fdd..1f6485dac6a 100644 --- a/sql/sql_yacc.yy +++ b/sql/sql_yacc.yy @@ -6094,10 +6094,11 @@ opt_part_option: opt_versioning_rotation: /* empty */ {} - | INTERVAL_SYM expr interval opt_versioning_interval_start + | { Lex->expr_allows_subselect= false; } + INTERVAL_SYM expr interval opt_versioning_interval_start { partition_info *part_info= Lex->part_info; - if (unlikely(part_info->vers_set_interval(thd, $2, $3, $4))) + if (unlikely(part_info->vers_set_interval(thd, $3, $4, $5))) MYSQL_YYABORT; } | LIMIT ulonglong_num From 99e14aa5922666842175bf9bad180f5803ed9956 Mon Sep 17 00:00:00 2001 From: Monty Date: Mon, 10 May 2021 18:36:13 +0300 Subject: [PATCH 20/72] MDEV-25606: Concurrent CREATE TRIGGER statements mix up in binlog and break replication The bug is that we don't have a a lock on the trigger name, so it is possible for two threads to try to create the same trigger at the same time and both thinks that they have succeed. Same thing can happen with drop trigger or a combinations of create and drop trigger. Fixed by adding a mdl lock for the trigger name for the duration of the create/drop. --- sql/sql_trigger.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sql/sql_trigger.cc b/sql/sql_trigger.cc index 501d3fc8841..6dead4fef16 100644 --- a/sql/sql_trigger.cc +++ b/sql/sql_trigger.cc @@ -471,7 +471,7 @@ bool mysql_create_or_drop_trigger(THD *thd, TABLE_LIST *tables, bool create) } /* Protect against concurrent create/drop */ - MDL_REQUEST_INIT(&mdl_request_for_trn, MDL_key::TABLE, + MDL_REQUEST_INIT(&mdl_request_for_trn, MDL_key::TRIGGER, create ? tables->db.str : thd->lex->spname->m_db.str, thd->lex->spname->m_name.str, MDL_EXCLUSIVE, MDL_EXPLICIT); From 44f2ece543819c19f956584846b02992c68ba99f Mon Sep 17 00:00:00 2001 From: Oleksandr Byelkin Date: Thu, 20 Oct 2022 18:55:09 +0200 Subject: [PATCH 21/72] columnstore-6.4.6-1 --- storage/columnstore/columnstore | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/storage/columnstore/columnstore b/storage/columnstore/columnstore index ac0741e82d7..1071ce95480 160000 --- a/storage/columnstore/columnstore +++ b/storage/columnstore/columnstore @@ -1 +1 @@ -Subproject commit ac0741e82d71ea8faf6865c4c6604f02449cfa27 +Subproject commit 1071ce954807104d25c0951f422e83d5e17406fe From 3905c12b0938a760dd99886fc69b7c5ae214e302 Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Thu, 20 Oct 2022 20:41:44 +0200 Subject: [PATCH 22/72] MDEV-29031 Change maturity of plugins for October 2022 Releases --- plugin/password_reuse_check/password_reuse_check.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugin/password_reuse_check/password_reuse_check.c b/plugin/password_reuse_check/password_reuse_check.c index 103eb4e4144..8f5973721d8 100644 --- a/plugin/password_reuse_check/password_reuse_check.c +++ b/plugin/password_reuse_check/password_reuse_check.c @@ -257,6 +257,6 @@ maria_declare_plugin(password_reuse_check) NULL, sysvars, "2.0", - MariaDB_PLUGIN_MATURITY_GAMMA + MariaDB_PLUGIN_MATURITY_STABLE } maria_declare_plugin_end; From e11661a4a2c0d50d78b86dac71a0e3d226f0ddcf Mon Sep 17 00:00:00 2001 From: kurt Date: Wed, 21 Sep 2022 11:29:07 +0800 Subject: [PATCH 23/72] MDEV-25343 Error log message not helpful when filekey is too long Add a test related to the Encrypted Key File by following instructions in kb example https://mariadb.com/kb/en/file-key-management-encryption-plugin/#creating-the-key-file Reviewed by Daniel Black (with minor formatting and re-org of duplicate close(f) calls). --- .../filekeys_secret_openssl_rand_128bits.result | 17 +++++++++++++++++ .../r/filekeys_secret_too_long.result | 10 ++++++++++ .../encryption/t/filekeys-data-too-long.key | 4 ++++ .../t/filekeys_secret_openssl_rand_128bits.enc | 4 ++++ .../t/filekeys_secret_openssl_rand_128bits.key | 1 + .../t/filekeys_secret_openssl_rand_128bits.opt | 3 +++ .../t/filekeys_secret_openssl_rand_128bits.test | 13 +++++++++++++ .../encryption/t/filekeys_secret_too_long.opt | 3 +++ .../encryption/t/filekeys_secret_too_long.test | 4 ++++ plugin/file_key_management/parser.cc | 15 ++++++++++++--- 10 files changed, 71 insertions(+), 3 deletions(-) create mode 100644 mysql-test/suite/encryption/r/filekeys_secret_openssl_rand_128bits.result create mode 100644 mysql-test/suite/encryption/r/filekeys_secret_too_long.result create mode 100644 mysql-test/suite/encryption/t/filekeys-data-too-long.key create mode 100644 mysql-test/suite/encryption/t/filekeys_secret_openssl_rand_128bits.enc create mode 100644 mysql-test/suite/encryption/t/filekeys_secret_openssl_rand_128bits.key create mode 100644 mysql-test/suite/encryption/t/filekeys_secret_openssl_rand_128bits.opt create mode 100644 mysql-test/suite/encryption/t/filekeys_secret_openssl_rand_128bits.test create mode 100644 mysql-test/suite/encryption/t/filekeys_secret_too_long.opt create mode 100644 mysql-test/suite/encryption/t/filekeys_secret_too_long.test diff --git a/mysql-test/suite/encryption/r/filekeys_secret_openssl_rand_128bits.result b/mysql-test/suite/encryption/r/filekeys_secret_openssl_rand_128bits.result new file mode 100644 index 00000000000..880245c7a09 --- /dev/null +++ b/mysql-test/suite/encryption/r/filekeys_secret_openssl_rand_128bits.result @@ -0,0 +1,17 @@ +create table t1(c1 bigint not null, b char(200)) engine=innodb encrypted=yes encryption_key_id=1; +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `c1` bigint(20) NOT NULL, + `b` char(200) DEFAULT NULL +) ENGINE=InnoDB DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci `encrypted`=yes `encryption_key_id`=1 +insert t1 values (12345, repeat('1234567890', 20)); +alter table t1 encryption_key_id=2; +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `c1` bigint(20) NOT NULL, + `b` char(200) DEFAULT NULL +) ENGINE=InnoDB DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci `encrypted`=yes `encryption_key_id`=2 +drop table t1; +# Test checks if opening an too large secret does not crash the server. diff --git a/mysql-test/suite/encryption/r/filekeys_secret_too_long.result b/mysql-test/suite/encryption/r/filekeys_secret_too_long.result new file mode 100644 index 00000000000..bd11e8d925e --- /dev/null +++ b/mysql-test/suite/encryption/r/filekeys_secret_too_long.result @@ -0,0 +1,10 @@ +call mtr.add_suppression("the filekey is too long"); +call mtr.add_suppression("Plugin 'file_key_management' init function returned error"); +call mtr.add_suppression("Plugin 'file_key_management' registration.*failed"); +FOUND 1 /the filekey is too long/ in mysqld.1.err +create table t1(c1 bigint not null, b char(200)) engine=innodb encrypted=yes encryption_key_id=1; +ERROR HY000: Can't create table `test`.`t1` (errno: 140 "Wrong create options") +select plugin_status from information_schema.plugins +where plugin_name = 'file_key_management'; +plugin_status +# Test checks if opening an too large secret does not crash the server. diff --git a/mysql-test/suite/encryption/t/filekeys-data-too-long.key b/mysql-test/suite/encryption/t/filekeys-data-too-long.key new file mode 100644 index 00000000000..ba1624fb324 --- /dev/null +++ b/mysql-test/suite/encryption/t/filekeys-data-too-long.key @@ -0,0 +1,4 @@ +secretsecretsecretsecretsecretsecretsecretsecretsecretsecretsecretsecretsecretsecretsecretsecretsecretsecretsecretsecretsecretsecretsecretsecretsecretsecretsecretsecretsecretsecretsecretsecretsecretsecretsecretsecretsecretsecretsecretsecretsecretsecretsecretsecretsecretsecretsecretsecretsecretsecretsecretsecretsecretsecret +secretsecretsecretsecretsecretsecretsecretsecretsecretsecretsecretsecretsecretsecretsecretsecretsecretsecretsecretsecretsecretsecretsecretsecretsecretsecretsecret +secretsecretsecretsecretsecretsecretsecretsecretsecretsecretsecretsecretsecretsecret + diff --git a/mysql-test/suite/encryption/t/filekeys_secret_openssl_rand_128bits.enc b/mysql-test/suite/encryption/t/filekeys_secret_openssl_rand_128bits.enc new file mode 100644 index 00000000000..3257ff7d6de --- /dev/null +++ b/mysql-test/suite/encryption/t/filekeys_secret_openssl_rand_128bits.enc @@ -0,0 +1,4 @@ +Salted__40-6L sK?p\am8N?q n<*g( |F/! + kok6y7t67D#g洄ʗԣiyu*i#ƈ82#6 .C8۝;7Bԣ +0 / +w0w"xԱQu04xkj{W΢3C5՜ ᔪP$=Ҳ \ No newline at end of file diff --git a/mysql-test/suite/encryption/t/filekeys_secret_openssl_rand_128bits.key b/mysql-test/suite/encryption/t/filekeys_secret_openssl_rand_128bits.key new file mode 100644 index 00000000000..bba639aeaac --- /dev/null +++ b/mysql-test/suite/encryption/t/filekeys_secret_openssl_rand_128bits.key @@ -0,0 +1 @@ +c9518399cbec2b5edf773e06d1b934b90ec0f46ae455b8f1e001b5629ef31a513b83e676bf654c08ba98659461410e5e040e46237a7d50b40bd9bb90576f841275506e61523e5e9a0beb7641127ed2d946395b6fee7ff5263a9019cbe71bd907bf1ac6365940fa391086830a4e6c1d2972b99505467ef31cfb46d0cb7ab8f4f1 diff --git a/mysql-test/suite/encryption/t/filekeys_secret_openssl_rand_128bits.opt b/mysql-test/suite/encryption/t/filekeys_secret_openssl_rand_128bits.opt new file mode 100644 index 00000000000..9dee47bb96f --- /dev/null +++ b/mysql-test/suite/encryption/t/filekeys_secret_openssl_rand_128bits.opt @@ -0,0 +1,3 @@ +--loose-file-key-management-filekey=FILE:$MTR_SUITE_DIR/t/filekeys_secret_openssl_rand_128bits.key +--loose-file-key-management-filename=$MTR_SUITE_DIR/t/filekeys_secret_openssl_rand_128bits.enc + diff --git a/mysql-test/suite/encryption/t/filekeys_secret_openssl_rand_128bits.test b/mysql-test/suite/encryption/t/filekeys_secret_openssl_rand_128bits.test new file mode 100644 index 00000000000..60718d21a10 --- /dev/null +++ b/mysql-test/suite/encryption/t/filekeys_secret_openssl_rand_128bits.test @@ -0,0 +1,13 @@ +-- source include/have_innodb.inc +-- source filekeys_plugin.inc + +create table t1(c1 bigint not null, b char(200)) engine=innodb encrypted=yes encryption_key_id=1; +show create table t1; +insert t1 values (12345, repeat('1234567890', 20)); + +alter table t1 encryption_key_id=2; +show create table t1; + +drop table t1; + +--echo # Test checks if opening an too large secret does not crash the server. diff --git a/mysql-test/suite/encryption/t/filekeys_secret_too_long.opt b/mysql-test/suite/encryption/t/filekeys_secret_too_long.opt new file mode 100644 index 00000000000..c3f95019f2a --- /dev/null +++ b/mysql-test/suite/encryption/t/filekeys_secret_too_long.opt @@ -0,0 +1,3 @@ +--loose-file-key-management-filekey=FILE:$MTR_SUITE_DIR/t/filekeys-data-too-long.key +--loose-file-key-management-filename=$MTR_SUITE_DIR/t/filekeys-data.enc + diff --git a/mysql-test/suite/encryption/t/filekeys_secret_too_long.test b/mysql-test/suite/encryption/t/filekeys_secret_too_long.test new file mode 100644 index 00000000000..0032e94de37 --- /dev/null +++ b/mysql-test/suite/encryption/t/filekeys_secret_too_long.test @@ -0,0 +1,4 @@ +let SEARCH_PATTERN=the filekey is too long; +source filekeys_badtest.inc; + +--echo # Test checks if opening an too large secret does not crash the server. diff --git a/plugin/file_key_management/parser.cc b/plugin/file_key_management/parser.cc index 5a9e5e55d63..ec1b528da24 100644 --- a/plugin/file_key_management/parser.cc +++ b/plugin/file_key_management/parser.cc @@ -170,19 +170,28 @@ bool Parser::read_filekey(const char *filekey, char *secret) int f= open(filekey, O_RDONLY|O_BINARY); if (f == -1) { - my_error(EE_FILENOTFOUND,ME_ERROR_LOG, filekey, errno); + my_error(EE_FILENOTFOUND, ME_ERROR_LOG, filekey, errno); return 1; } - int len= read(f, secret, MAX_SECRET_SIZE); + int len= read(f, secret, MAX_SECRET_SIZE + 1); if (len <= 0) { - my_error(EE_READ,ME_ERROR_LOG, filekey, errno); + my_error(EE_READ, ME_ERROR_LOG, filekey, errno); close(f); return 1; } close(f); + while (secret[len - 1] == '\r' || secret[len - 1] == '\n') len--; + if (len > MAX_SECRET_SIZE) + { + my_printf_error(EE_READ, + "Cannot read %s, the filekey is too long, " + "max secret size is %dB ", + ME_ERROR_LOG, filekey, MAX_SECRET_SIZE); + return 1; + } secret[len]= '\0'; return 0; } From 1be451ca797f59b23e70edf02d9c17a29c19e608 Mon Sep 17 00:00:00 2001 From: Alexander Barkov Date: Fri, 7 Oct 2022 13:39:02 +0400 Subject: [PATCH 24/72] Revert "MDEV-28727 ALTER TABLE ALGORITHM=NOCOPY does not work after upgrade" This reverts commit 1ea5e402a89a1e3fb9ba8045e58570d23837714a --- mysql-test/main/mysql_upgrade.result | 38 ---------------------- mysql-test/main/mysql_upgrade.test | 41 ------------------------ mysql-test/std_data/mdev-28727-pet4.frm | Bin 934 -> 0 bytes sql/handler.cc | 19 ++--------- 4 files changed, 2 insertions(+), 96 deletions(-) delete mode 100644 mysql-test/std_data/mdev-28727-pet4.frm diff --git a/mysql-test/main/mysql_upgrade.result b/mysql-test/main/mysql_upgrade.result index f06aa5dd792..7d01a428ca1 100644 --- a/mysql-test/main/mysql_upgrade.result +++ b/mysql-test/main/mysql_upgrade.result @@ -947,42 +947,4 @@ disconnect con1; connection default; drop table mysql.global_priv; rename table mysql.global_priv_bak to mysql.global_priv; -# -# MDEV-28727 ALTER TABLE ALGORITHM=NOCOPY does not work after upgrade -# -create or replace table pet4 ( -build_time double(18, 7) default null, -key idx1 (build_time) -) engine innodb; -check table pet4; -Table Op Msg_type Msg_text -test.pet4 check error Table rebuild required. Please do "ALTER TABLE `pet4` FORCE" or dump/reload to fix it! -check table pet4 for upgrade; -Table Op Msg_type Msg_text -test.pet4 check error Table rebuild required. Please do "ALTER TABLE `pet4` FORCE" or dump/reload to fix it! -alter table pet4 add i1 int, algorithm=nocopy; -ERROR 0A000: ALGORITHM=NOCOPY is not supported for this operation. Try ALGORITHM=INPLACE -# Running mysqlcheck -test.pet4 -error : Table rebuild required. Please do "ALTER TABLE `pet4` FORCE" or dump/reload to fix it! - -Repairing tables -check table pet4; -Table Op Msg_type Msg_text -test.pet4 check status OK -alter table pet4 add i1 int, algorithm=nocopy; -create or replace table pet4 ( -build_time double(18, 7) default null, -key idx1 (build_time) -) engine innodb; -alter table pet4 add i1 int, algorithm=nocopy; -ERROR 0A000: ALGORITHM=NOCOPY is not supported for this operation. Try ALGORITHM=INPLACE -# Running mysql_upgrade -test.pet4 -error : Table rebuild required. Please do "ALTER TABLE `pet4` FORCE" or dump/reload to fix it! -check table pet4; -Table Op Msg_type Msg_text -test.pet4 check status OK -alter table pet4 add i1 int, algorithm=nocopy; -drop table pet4; # End of 10.4 tests diff --git a/mysql-test/main/mysql_upgrade.test b/mysql-test/main/mysql_upgrade.test index f9b4304e2a3..591e62048eb 100644 --- a/mysql-test/main/mysql_upgrade.test +++ b/mysql-test/main/mysql_upgrade.test @@ -472,45 +472,4 @@ drop table mysql.global_priv; rename table mysql.global_priv_bak to mysql.global_priv; --remove_file $MYSQLD_DATADIR/mysql_upgrade_info ---echo # ---echo # MDEV-28727 ALTER TABLE ALGORITHM=NOCOPY does not work after upgrade ---echo # -create or replace table pet4 ( - build_time double(18, 7) default null, - key idx1 (build_time) -) engine innodb; - ---remove_file $MYSQLD_DATADIR/test/pet4.frm ---copy_file std_data/mdev-28727-pet4.frm $MYSQLD_DATADIR/test/pet4.frm - -check table pet4; -check table pet4 for upgrade; ---error ER_ALTER_OPERATION_NOT_SUPPORTED -alter table pet4 add i1 int, algorithm=nocopy; - ---echo # Running mysqlcheck ---exec $MYSQL_CHECK --auto-repair --databases test 2>&1 -check table pet4; -alter table pet4 add i1 int, algorithm=nocopy; - -create or replace table pet4 ( - build_time double(18, 7) default null, - key idx1 (build_time) -) engine innodb; - ---remove_file $MYSQLD_DATADIR/test/pet4.frm ---copy_file std_data/mdev-28727-pet4.frm $MYSQLD_DATADIR/test/pet4.frm - ---error ER_ALTER_OPERATION_NOT_SUPPORTED -alter table pet4 add i1 int, algorithm=nocopy; - ---echo # Running mysql_upgrade ---exec $MYSQL_UPGRADE --silent 2>&1 -file_exists $MYSQLD_DATADIR/mysql_upgrade_info; -check table pet4; -alter table pet4 add i1 int, algorithm=nocopy; - ---remove_file $MYSQLD_DATADIR/mysql_upgrade_info -drop table pet4; - --echo # End of 10.4 tests diff --git a/mysql-test/std_data/mdev-28727-pet4.frm b/mysql-test/std_data/mdev-28727-pet4.frm deleted file mode 100644 index 3ff86d1dca1d299301b9bcf0c19ed928e9c81faa..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 934 zcmeyz$jKwb5XQjBu#B03;U^;}0~|2PF>o+2u!8uCFu|XU3=ACYj0^%W0R{oJWtLAL zcL}~(b(F37M*Xhh3?>E!MxZiwhD@M-AcKLi0Vt&1&cX0MGo`}tKV0i5W7vfNQslBR zc;@BhyEsAoXvb&=N(v(wfV?jR#GDMg@K6X~5Ci8Buz(N)IGX_3tcnZ_|C35Hb5i0< KGILY^GXMbmSRTCq diff --git a/sql/handler.cc b/sql/handler.cc index e6e665f0e12..bf819733b81 100644 --- a/sql/handler.cc +++ b/sql/handler.cc @@ -4370,32 +4370,17 @@ int handler::ha_check(THD *thd, HA_CHECK_OPT *check_opt) DBUG_ASSERT(table_share->tmp_table != NO_TMP_TABLE || m_lock_type != F_UNLCK); - const ulong v= table->s->mysql_version; - - if ((v >= MYSQL_VERSION_ID) && + if ((table->s->mysql_version >= MYSQL_VERSION_ID) && (check_opt->sql_flags & TT_FOR_UPGRADE)) return 0; - if (v < MYSQL_VERSION_ID) + if (table->s->mysql_version < MYSQL_VERSION_ID) { if (unlikely((error= check_old_types()))) return error; error= ha_check_for_upgrade(check_opt); if (unlikely(error && (error != HA_ADMIN_NEEDS_CHECK))) return error; - if (table->s->table_category == TABLE_CATEGORY_USER && - (v < 100142 || - (v >= 100200 && v < 100228) || - (v >= 100300 && v < 100319) || - (v >= 100400 && v < 100409))) - { - for (const KEY *key= table->key_info, - *end= table->key_info + table->s->keys; key < end; key++) - { - if (key->flags & HA_BINARY_PACK_KEY && key->flags & HA_VAR_LENGTH_KEY) - return HA_ADMIN_NEEDS_UPGRADE; - } - } if (unlikely(!error && (check_opt->sql_flags & TT_FOR_UPGRADE))) return 0; } From e1414fc7e38e561dba74ed8bf694828d1277b714 Mon Sep 17 00:00:00 2001 From: Thirunarayanan Balathandayuthapani Date: Thu, 20 Oct 2022 08:29:56 +0530 Subject: [PATCH 25/72] MDEV-29778 Having Unique index interference with MATCH from a FULLTEXT InnoDB fails to fetch FTS_DOC_ID if the select query uses secondary index. So always do extra lookup on clustered index in case of fts query --- mysql-test/suite/innodb_fts/r/fulltext.result | 11 +++++++++++ mysql-test/suite/innodb_fts/t/fulltext.test | 10 ++++++++++ storage/innobase/handler/ha_innodb.cc | 5 +++++ 3 files changed, 26 insertions(+) diff --git a/mysql-test/suite/innodb_fts/r/fulltext.result b/mysql-test/suite/innodb_fts/r/fulltext.result index 0b9b45f18f1..a1cdaf1804a 100644 --- a/mysql-test/suite/innodb_fts/r/fulltext.result +++ b/mysql-test/suite/innodb_fts/r/fulltext.result @@ -774,4 +774,15 @@ UNLOCK TABLES; ALTER TABLE t1 DISCARD TABLESPACE; ALTER TABLE t2 IMPORT TABLESPACE; DROP TABLE t2, t1; +# +# MDEV-29778 Having Unique index interference with MATCH +# from a FULLTEXT +# +CREATE TABLE t1(f1 VARCHAR(100), FULLTEXT(f1), +UNIQUE INDEX(f1))ENGINE=InnoDB; +INSERT INTO t1 VALUES("test"); +SELECT f1, MATCH(f1) AGAINST ("test" IN BOOLEAN MODE) FROM t1; +f1 MATCH(f1) AGAINST ("test" IN BOOLEAN MODE) +test 0.000000001885928302414186 +DROP TABLE t1; # End of 10.3 tests diff --git a/mysql-test/suite/innodb_fts/t/fulltext.test b/mysql-test/suite/innodb_fts/t/fulltext.test index 2cf82d0fe90..d9387c8d4e8 100644 --- a/mysql-test/suite/innodb_fts/t/fulltext.test +++ b/mysql-test/suite/innodb_fts/t/fulltext.test @@ -790,4 +790,14 @@ ALTER TABLE t2 IMPORT TABLESPACE; --enable_warnings DROP TABLE t2, t1; +--echo # +--echo # MDEV-29778 Having Unique index interference with MATCH +--echo # from a FULLTEXT +--echo # +CREATE TABLE t1(f1 VARCHAR(100), FULLTEXT(f1), + UNIQUE INDEX(f1))ENGINE=InnoDB; +INSERT INTO t1 VALUES("test"); +SELECT f1, MATCH(f1) AGAINST ("test" IN BOOLEAN MODE) FROM t1; +DROP TABLE t1; + --echo # End of 10.3 tests diff --git a/storage/innobase/handler/ha_innodb.cc b/storage/innobase/handler/ha_innodb.cc index 0fe60ccabe6..cd2d36df112 100644 --- a/storage/innobase/handler/ha_innodb.cc +++ b/storage/innobase/handler/ha_innodb.cc @@ -7703,6 +7703,11 @@ ha_innobase::build_template( m_prebuilt->versioned_write = table->versioned_write(VERS_TRX_ID); m_prebuilt->need_to_access_clustered = (index == clust_index); + if (m_prebuilt->in_fts_query) { + /* Do clustered index lookup to fetch the FTS_DOC_ID */ + m_prebuilt->need_to_access_clustered = true; + } + /* Either m_prebuilt->index should be a secondary index, or it should be the clustered index. */ ut_ad(dict_index_is_clust(index) == (index == clust_index)); From ab0190101b0587e0e03b2d75a967050b9a85fd1b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marko=20M=C3=A4kel=C3=A4?= Date: Fri, 21 Oct 2022 10:02:54 +0300 Subject: [PATCH 26/72] MDEV-24402: InnoDB CHECK TABLE ... EXTENDED Until now, the attribute EXTENDED of CHECK TABLE was ignored by InnoDB, and InnoDB only counted the records in each index according to the current read view. Unless the attribute QUICK was specified, the function btr_validate_index() would be invoked to validate the B-tree structure (the sibling and child links between index pages). The EXTENDED check will not only count all index records according to the current read view, but also ensure that any delete-marked records in the clustered index are waiting for the purge of history, and that all secondary index records point to a version of the clustered index record that is waiting for the purge of history. In other words, no index may contain orphan records. Normal MVCC reads and the non-EXTENDED version of CHECK TABLE would ignore these orphans. Unpurged records merely result in warnings (at most one per index), not errors, and no indexes will be flagged as corrupted due to such garbage. It will remain possible to SELECT data from such indexes or tables (which will skip such records) or to rebuild the table to reclaim some space. We introduce purge_sys.end_view that will be (almost) a copy of purge_sys.view at the end of a batch of purging committed transaction history. It is not an exact copy, because if the size of a purge batch is limited by innodb_purge_batch_size, some records that purge_sys.view would allow to be purged will be left over for subsequent batches. The purge_sys.view is relevant in the purge of committed transaction history, to determine if records are safe to remove. The new purge_sys.end_view is relevant in MVCC operations and in CHECK TABLE ... EXTENDED. It tells which undo log records are safe to access (have not been discarded at the end of a purge batch). purge_sys.clone_oldest_view(): In trx_lists_init_at_db_start(), clone the oldest read view similar to purge_sys_t::clone_end_view() so that CHECK TABLE ... EXTENDED will not report bogus failures between InnoDB restart and the completed purge of committed transaction history. purge_sys_t::is_purgeable(): Replaces purge_sys_t::changes_visible() in the case that purge_sys.latch will not be held by the caller. Among other things, this guards access to BLOBs. It is not safe to dereference any BLOBs of a delete-marked purgeable record, because they may have already been freed. purge_sys_t::view_guard::view(): Return a reference to purge_sys.view that will be protected by purge_sys.latch, held by purge_sys_t::view_guard. purge_sys_t::end_view_guard::view(): Return a reference to purge_sys.end_view while it is protected by purge_sys.end_latch. Whenever a thread needs to retrieve an older version of a clustered index record, it will hold a page latch on the clustered index page and potentially also on a secondary index page that points to the clustered index page. If these pages contain purgeable records that would be accessed by a currently running purge batch, the progress of the purge batch would be blocked by the page latches. Hence, it is safe to make a copy of purge_sys.end_view while holding an index page latch, and consult the copy of the view to determine whether a record should already have been purged. btr_validate_index(): Remove a redundant check. row_check_index_match(): Check if a secondary index record and a version of a clustered index record match each other. row_check_index(): Replaces row_scan_index_for_mysql(). Count the records in each index directly, duplicating the relevant logic from row_search_mvcc(). Initialize check_table_extended_view for CHECK ... EXTENDED while holding an index leaf page latch. If we encounter an orphan record, the copy of purge_sys.end_view that we make is safe for visibility checks, and trx_undo_get_undo_rec() will check for the safety to access each undo log record. Should that check fail, we should return DB_MISSING_HISTORY to report a corrupted index. The EXTENDED check tries to match each secondary index record with every available clustered index record version, by duplicating the logic of row_vers_build_for_consistent_read() and invoking trx_undo_prev_version_build() directly. Before invoking row_check_index_match() on delete-marked clustered index record versions, we will consult purge_sys.is_purgeable() in order to avoid accessing freed BLOBs. We will always check that the DB_TRX_ID or PAGE_MAX_TRX_ID does not exceed the global maximum. Orphan secondary index records will be flagged only if everything up to PAGE_MAX_TRX_ID has been purged. We warn also about clustered index records whose nonzero DB_TRX_ID should have been reset in purge or rollback. trx_set_rw_mode(): Move an assertion from ReadView::set_creator_trx_id(). trx_undo_prev_version_build(): Remove two debug-only parameters, and return an error code instead of a Boolean. trx_undo_get_undo_rec(): Return a pointer to the undo log record, or nullptr if one cannot be retrieved. Instead of consulting the purge_sys.view, consult the purge_sys.end_view to determine which records can be accessed. trx_undo_get_rec_if_purgeable(): A variant of trx_undo_get_undo_rec() that will consult purge_sys.view instead of purge_sys.end_view. TRX_UNDO_CHECK_PURGEABILITY: A new parameter to trx_undo_prev_version_build(), passed by row_vers_old_has_index_entry() so that purge_sys.view instead of purge_sys.end_view will be consulted to determine whether a secondary index record may be safely purged. row_upd_changes_disowned_external(): Remove. This should be more expensive than briefly latching purge_sys in trx_undo_prev_version_build() (which may make use of transactional memory). row_sel_reset_old_vers_heap(): New function, split from row_sel_build_prev_vers_for_mysql(). row_sel_build_prev_vers_for_mysql(): Reorder some parameters to simplify the call to row_sel_reset_old_vers_heap(). row_search_for_mysql(): Replaced with direct calls to row_search_mvcc(). sel_node_get_nth_plan(): Define inline in row0sel.h open_step(): Define at the call site, in simplified form. sel_node_reset_cursor(): Merged with the only caller open_step(). --- ReadViewBase::check_trx_id_sanity(): Remove. Let us handle "future" DB_TRX_ID in a more meaningful way: row_sel_clust_sees(): Return DB_SUCCESS if the record is visible, DB_SUCCESS_LOCKED_REC if it is invisible, and DB_CORRUPTION if the DB_TRX_ID is in the future. row_undo_mod_must_purge(), row_undo_mod_clust(): Silently ignore corrupted DB_TRX_ID. We are in ROLLBACK, and we should have noticed that corruption when we were about to modify the record in the first place (leading us to refuse the operation). row_vers_build_for_consistent_read(): Return DB_CORRUPTION if DB_TRX_ID is in the future. Tested by: Matthias Leich Reviewed by: Vladislav Lesin --- .../suite/gcol/r/innodb_virtual_purge.result | 6 +- .../suite/gcol/t/innodb_virtual_purge.test | 6 +- .../suite/innodb/r/trx_id_future.result | 10 +- mysql-test/suite/innodb/t/trx_id_future.test | 14 +- storage/innobase/CMakeLists.txt | 1 - storage/innobase/btr/btr0btr.cc | 5 - storage/innobase/dict/dict0stats.cc | 1 + storage/innobase/fts/fts0ast.cc | 3 +- storage/innobase/handler/ha_innodb.cc | 83 +- storage/innobase/include/read0types.h | 43 +- storage/innobase/include/row0mysql.h | 26 +- storage/innobase/include/row0sel.h | 87 +- storage/innobase/include/row0sel.inl | 138 --- storage/innobase/include/row0upd.h | 10 +- storage/innobase/include/row0vers.h | 8 +- storage/innobase/include/trx0purge.h | 76 +- storage/innobase/include/trx0rec.h | 22 +- storage/innobase/lock/lock0lock.cc | 1 + storage/innobase/que/que0que.cc | 25 +- storage/innobase/row/row0log.cc | 10 +- storage/innobase/row/row0merge.cc | 14 +- storage/innobase/row/row0mysql.cc | 181 +--- storage/innobase/row/row0sel.cc | 957 ++++++++++++++++-- storage/innobase/row/row0umod.cc | 53 +- storage/innobase/row/row0upd.cc | 40 - storage/innobase/row/row0vers.cc | 54 +- storage/innobase/trx/trx0purge.cc | 68 +- storage/innobase/trx/trx0rec.cc | 146 ++- storage/innobase/trx/trx0sys.cc | 34 - storage/innobase/trx/trx0trx.cc | 3 +- 30 files changed, 1247 insertions(+), 878 deletions(-) delete mode 100644 storage/innobase/include/row0sel.inl diff --git a/mysql-test/suite/gcol/r/innodb_virtual_purge.result b/mysql-test/suite/gcol/r/innodb_virtual_purge.result index ee88527ec2e..48a2d313382 100644 --- a/mysql-test/suite/gcol/r/innodb_virtual_purge.result +++ b/mysql-test/suite/gcol/r/innodb_virtual_purge.result @@ -24,7 +24,7 @@ COMMIT; UPDATE t1 SET a=1; connection default; InnoDB 0 transactions not purged -CHECK TABLE t1; +CHECK TABLE t1 EXTENDED; Table Op Msg_type Msg_text test.t1 check status OK SELECT b1 FROM t1; @@ -123,7 +123,7 @@ COMMIT; disconnect con1; connection default; InnoDB 0 transactions not purged -CHECK TABLE t1; +CHECK TABLE t1 EXTENDED; Table Op Msg_type Msg_text test.t1 check status OK SELECT b1 FROM t1; @@ -134,7 +134,7 @@ SELECT * FROM t1; a b b1 a1 a4 b3 100 10 10 100 90 100 100 10 10 100 90 100 -CHECK TABLE t2; +CHECK TABLE t2 EXTENDED; Table Op Msg_type Msg_text test.t2 check status OK DROP TABLE t2, t1, t0; diff --git a/mysql-test/suite/gcol/t/innodb_virtual_purge.test b/mysql-test/suite/gcol/t/innodb_virtual_purge.test index c79a817dd4e..e9e4caf8e07 100644 --- a/mysql-test/suite/gcol/t/innodb_virtual_purge.test +++ b/mysql-test/suite/gcol/t/innodb_virtual_purge.test @@ -38,7 +38,7 @@ UPDATE t1 SET a=1; connection default; --source ../../innodb/include/wait_all_purged.inc -CHECK TABLE t1; +CHECK TABLE t1 EXTENDED; SELECT b1 FROM t1; @@ -123,11 +123,11 @@ disconnect con1; connection default; --source ../../innodb/include/wait_all_purged.inc -CHECK TABLE t1; +CHECK TABLE t1 EXTENDED; SELECT b1 FROM t1; SELECT * FROM t1; -CHECK TABLE t2; +CHECK TABLE t2 EXTENDED; DROP TABLE t2, t1, t0; CREATE TABLE t1 (a VARCHAR(30), b INT, a2 VARCHAR(30) GENERATED ALWAYS AS (a) VIRTUAL); diff --git a/mysql-test/suite/innodb/r/trx_id_future.result b/mysql-test/suite/innodb/r/trx_id_future.result index 1ddc0e64f8b..4f88b1d4783 100644 --- a/mysql-test/suite/innodb/r/trx_id_future.result +++ b/mysql-test/suite/innodb/r/trx_id_future.result @@ -6,13 +6,9 @@ SET GLOBAL innodb_purge_rseg_truncate_frequency=1; CREATE TABLE t1(a INT) row_format=redundant engine=innoDB; INSERT INTO t1 VALUES(1); InnoDB 0 transactions not purged -NOT FOUND /\[Warning\] InnoDB: A transaction id in a record of table `test`\.`t1` is newer than the system-wide maximum/ in mysqld.1.err call mtr.add_suppression("\\[Warning\\] InnoDB: A transaction id in a record of table `test`\\.`t1` is newer than the system-wide maximum"); -SET @save_count = @@max_error_count; -SET max_error_count = 1; +call mtr.add_suppression("\\[ERROR\\] InnoDB: We detected index corruption"); +call mtr.add_suppression("Index for table 't1' is corrupt; try to repair it"); SELECT * FROM t1; -a -Warnings: -Warning 1642 InnoDB: Transaction id in a record of table `test`.`t1` is newer than system-wide maximum. -SET max_error_count = @save_count; +ERROR HY000: Index for table 't1' is corrupt; try to repair it DROP TABLE t1; diff --git a/mysql-test/suite/innodb/t/trx_id_future.test b/mysql-test/suite/innodb/t/trx_id_future.test index b897800fa91..18077549cf6 100644 --- a/mysql-test/suite/innodb/t/trx_id_future.test +++ b/mysql-test/suite/innodb/t/trx_id_future.test @@ -57,19 +57,11 @@ syswrite(FILE, $page, $ps)==$ps || die "Unable to write $file\n"; close(FILE) || die "Unable to close $file"; EOF -# Debug assertions would fail due to the injected corruption. ---let $restart_parameters= --loose-skip-debug-assert --source include/start_mysqld.inc - -let SEARCH_FILE= $MYSQLTEST_VARDIR/log/mysqld.1.err; -let SEARCH_PATTERN= \[Warning\] InnoDB: A transaction id in a record of table `test`\.`t1` is newer than the system-wide maximum; ---source include/search_pattern_in_file.inc - call mtr.add_suppression("\\[Warning\\] InnoDB: A transaction id in a record of table `test`\\.`t1` is newer than the system-wide maximum"); +call mtr.add_suppression("\\[ERROR\\] InnoDB: We detected index corruption"); +call mtr.add_suppression("Index for table 't1' is corrupt; try to repair it"); -# A debug assertion would cause a duplicated message to be output. -SET @save_count = @@max_error_count; -SET max_error_count = 1; +--error ER_NOT_KEYFILE SELECT * FROM t1; -SET max_error_count = @save_count; DROP TABLE t1; diff --git a/storage/innobase/CMakeLists.txt b/storage/innobase/CMakeLists.txt index fa6f3490fb1..422d7cd6f4c 100644 --- a/storage/innobase/CMakeLists.txt +++ b/storage/innobase/CMakeLists.txt @@ -338,7 +338,6 @@ SET(INNOBASE_SOURCES include/row0row.h include/row0row.inl include/row0sel.h - include/row0sel.inl include/row0types.h include/row0uins.h include/row0umod.h diff --git a/storage/innobase/btr/btr0btr.cc b/storage/innobase/btr/btr0btr.cc index 6843771ac8c..e503215e05b 100644 --- a/storage/innobase/btr/btr0btr.cc +++ b/storage/innobase/btr/btr0btr.cc @@ -5276,11 +5276,6 @@ btr_validate_index( dict_index_t* index, /*!< in: index */ const trx_t* trx) /*!< in: transaction or NULL */ { - /* Full Text index are implemented by auxiliary tables, not the B-tree */ - if (index->online_status != ONLINE_INDEX_COMPLETE || - (index->type & (DICT_FTS | DICT_CORRUPT))) - return DB_SUCCESS; - const bool lockout= index->is_spatial(); mtr_t mtr; diff --git a/storage/innobase/dict/dict0stats.cc b/storage/innobase/dict/dict0stats.cc index cd81d4c7386..8d2fa9cdc42 100644 --- a/storage/innobase/dict/dict0stats.cc +++ b/storage/innobase/dict/dict0stats.cc @@ -33,6 +33,7 @@ Created Jan 06, 2010 Vasil Dimov #include #include "log.h" #include "btr0btr.h" +#include "que0que.h" #include #include diff --git a/storage/innobase/fts/fts0ast.cc b/storage/innobase/fts/fts0ast.cc index bb42f7c9f54..74d02d63817 100644 --- a/storage/innobase/fts/fts0ast.cc +++ b/storage/innobase/fts/fts0ast.cc @@ -1,7 +1,7 @@ /***************************************************************************** Copyright (c) 2007, 2020, Oracle and/or its affiliates. All Rights Reserved. -Copyright (c) 2018, MariaDB Corporation. +Copyright (c) 2018, 2022, 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 @@ -28,6 +28,7 @@ Created 2007/3/16 Sunny Bains. #include "fts0ast.h" #include "fts0pars.h" #include "fts0fts.h" +#include "trx0trx.h" /* The FTS ast visit pass. */ enum fts_ast_visit_pass_t { diff --git a/storage/innobase/handler/ha_innodb.cc b/storage/innobase/handler/ha_innodb.cc index 4c7a9d6e6a4..de407ce9ae5 100644 --- a/storage/innobase/handler/ha_innodb.cc +++ b/storage/innobase/handler/ha_innodb.cc @@ -3662,7 +3662,7 @@ ha_innobase::init_table_handle_for_HANDLER(void) innobase_register_trx(ht, m_user_thd, m_prebuilt->trx); /* We did the necessary inits in this function, no need to repeat them - in row_search_for_mysql */ + in row_search_mvcc() */ m_prebuilt->sql_stat_start = FALSE; @@ -7411,7 +7411,7 @@ ha_innobase::build_template( /* We must at least fetch all primary key cols. Note that if the clustered index was internally generated by InnoDB on the row id (no primary key was - defined), then row_search_for_mysql() will always + defined), then row_search_mvcc() will always retrieve the row id to a special buffer in the m_prebuilt struct. */ @@ -8943,7 +8943,7 @@ statement issued by the user. We also increment trx->n_mysql_tables_in_use. instructions to m_prebuilt->template of the table handle instance in ::index_read. The template is used to save CPU time in large joins. - 3) In row_search_for_mysql, if m_prebuilt->sql_stat_start is true, we + 3) In row_search_mvcc(), if m_prebuilt->sql_stat_start is true, we allocate a new consistent read view for the trx if it does not yet have one, or in the case of a locking read, set an InnoDB 'intention' table level lock on the table. @@ -9245,7 +9245,7 @@ ha_innobase::change_active_index( } /* The caller seems to ignore this. Thus, we must check - this again in row_search_for_mysql(). */ + this again in row_search_mvcc(). */ DBUG_RETURN(convert_error_code_to_mysql(DB_MISSING_HISTORY, 0, NULL)); } @@ -9845,9 +9845,9 @@ next_record: int error; - switch (dberr_t ret = row_search_for_mysql(buf, PAGE_CUR_GE, - m_prebuilt, - ROW_SEL_EXACT, 0)) { + switch (dberr_t ret = row_search_mvcc(buf, PAGE_CUR_GE, + m_prebuilt, + ROW_SEL_EXACT, 0)) { case DB_SUCCESS: error = 0; table->status = 0; @@ -15186,8 +15186,10 @@ ha_innobase::check( DBUG_ENTER("ha_innobase::check"); DBUG_ASSERT(thd == ha_thd()); + DBUG_ASSERT(thd == m_user_thd); ut_a(m_prebuilt->trx->magic_n == TRX_MAGIC_N); ut_a(m_prebuilt->trx == thd_to_trx(thd)); + ut_ad(m_prebuilt->trx->mysql_thd == thd); if (m_prebuilt->mysql_template == NULL) { /* Build the template; we will use a dummy template @@ -15197,7 +15199,6 @@ ha_innobase::check( } if (!m_prebuilt->table->space) { - ib_senderrf( thd, IB_LOG_LEVEL_ERROR, @@ -15205,10 +15206,7 @@ ha_innobase::check( table->s->table_name.str); DBUG_RETURN(HA_ADMIN_CORRUPT); - - } else if (!m_prebuilt->table->is_readable() && - !m_prebuilt->table->space) { - + } else if (!m_prebuilt->table->is_readable()) { ib_senderrf( thd, IB_LOG_LEVEL_ERROR, ER_TABLESPACE_MISSING, @@ -15229,6 +15227,9 @@ ha_innobase::check( ? TRX_ISO_READ_UNCOMMITTED : TRX_ISO_REPEATABLE_READ; + trx_start_if_not_started(m_prebuilt->trx, false); + m_prebuilt->trx->read_view.open(m_prebuilt->trx); + for (dict_index_t* index = dict_table_get_first_index(m_prebuilt->table); index; @@ -15237,25 +15238,22 @@ ha_innobase::check( if (!index->is_committed()) { continue; } + if (index->type & DICT_FTS) { + /* We do not check any FULLTEXT INDEX. */ + continue; + } - if (!(check_opt->flags & T_QUICK) - && !index->is_corrupted()) { - - dberr_t err = btr_validate_index( - index, m_prebuilt->trx); - - if (err != DB_SUCCESS) { - is_ok = false; - - push_warning_printf( - thd, - Sql_condition::WARN_LEVEL_WARN, - ER_NOT_KEYFILE, - "InnoDB: The B-tree of" - " index %s is corrupted.", - index->name()); - continue; - } + if ((check_opt->flags & T_QUICK) || index->is_corrupted()) { + } else if (btr_validate_index(index, m_prebuilt->trx) + != DB_SUCCESS) { + is_ok = false; + push_warning_printf(thd, + Sql_condition::WARN_LEVEL_WARN, + ER_NOT_KEYFILE, + "InnoDB: The B-tree of" + " index %s is corrupted.", + index->name()); + continue; } /* Instead of invoking change_active_index(), set up @@ -15277,7 +15275,7 @@ ha_innobase::check( if (UNIV_UNLIKELY(!m_prebuilt->index_usable)) { if (index->is_corrupted()) { push_warning_printf( - m_user_thd, + thd, Sql_condition::WARN_LEVEL_WARN, HA_ERR_INDEX_CORRUPT, "InnoDB: Index %s is marked as" @@ -15286,7 +15284,7 @@ ha_innobase::check( is_ok = false; } else { push_warning_printf( - m_user_thd, + thd, Sql_condition::WARN_LEVEL_WARN, HA_ERR_TABLE_DEF_CHANGED, "InnoDB: Insufficient history for" @@ -15299,18 +15297,22 @@ ha_innobase::check( m_prebuilt->sql_stat_start = TRUE; m_prebuilt->template_type = ROW_MYSQL_DUMMY_TEMPLATE; m_prebuilt->n_template = 0; - m_prebuilt->need_to_access_clustered = FALSE; + m_prebuilt->read_just_key = 0; + m_prebuilt->autoinc_error = DB_SUCCESS; + m_prebuilt->need_to_access_clustered = + !!(check_opt->flags & T_EXTEND); dtuple_set_n_fields(m_prebuilt->search_tuple, 0); m_prebuilt->select_lock_type = LOCK_NONE; /* Scan this index. */ - if (dict_index_is_spatial(index)) { + if (index->is_spatial()) { ret = row_count_rtree_recs(m_prebuilt, &n_rows); + } else if (index->type & DICT_FTS) { + ret = DB_SUCCESS; } else { - ret = row_scan_index_for_mysql( - m_prebuilt, index, &n_rows); + ret = row_check_index(m_prebuilt, &n_rows); } DBUG_EXECUTE_IF( @@ -15319,11 +15321,18 @@ ha_innobase::check( ret = DB_CORRUPTION; }); - if (ret == DB_INTERRUPTED || thd_killed(m_user_thd)) { + if (ret == DB_INTERRUPTED || thd_killed(thd)) { /* Do not report error since this could happen during shutdown */ break; } + + if (ret == DB_SUCCESS + && m_prebuilt->autoinc_error != DB_MISSING_HISTORY) { + /* See if any non-fatal errors were reported. */ + ret = m_prebuilt->autoinc_error; + } + if (ret != DB_SUCCESS) { /* Assume some kind of corruption. */ push_warning_printf( diff --git a/storage/innobase/include/read0types.h b/storage/innobase/include/read0types.h index bc02fc065f5..e002f1b77e1 100644 --- a/storage/innobase/include/read0types.h +++ b/storage/innobase/include/read0types.h @@ -121,19 +121,6 @@ loop: inline void snapshot(trx_t *trx); - /** - Check whether transaction id is valid. - @param[in] id transaction id to check - @param[in] name table name - - @todo changes_visible() was an unfortunate choice for this check. - It should be moved towards the functions that load trx id like - trx_read_trx_id(). No need to issue a warning, error log message should - be enough. Although statement should ideally fail if it sees corrupt - data. - */ - static void check_trx_id_sanity(trx_id_t id, const table_name_t &name); - /** Check whether the changes by id are visible. @param[in] id transaction id to check against the view @@ -149,26 +136,6 @@ loop: !std::binary_search(m_ids.begin(), m_ids.end(), id); } - /** - Check whether the changes by id are visible. - @param[in] id transaction id to check against the view - @param[in] name table name - @return whether the view sees the modifications of id. - */ - bool changes_visible(trx_id_t id, const table_name_t &name) const - MY_ATTRIBUTE((warn_unused_result)) - { - if (id >= m_low_limit_id) - { - check_trx_id_sanity(id, name); - return false; - } - return id < m_up_limit_id || - m_ids.empty() || - !std::binary_search(m_ids.begin(), m_ids.end(), id); - } - - /** @param id transaction to check @return true if view sees transaction id @@ -180,6 +147,13 @@ loop: /** @return the low limit id */ trx_id_t low_limit_id() const { return m_low_limit_id; } + + /** Clamp the low limit id for purge_sys.end_view */ + void clamp_low_limit_id(trx_id_t limit) + { + if (m_low_limit_id > limit) + m_low_limit_id= limit; + } }; @@ -250,7 +224,6 @@ public: */ void set_creator_trx_id(trx_id_t id) { - ut_ad(id > 0); ut_ad(m_creator_trx_id == 0); m_creator_trx_id= id; } @@ -275,8 +248,6 @@ public: A wrapper around ReadViewBase::changes_visible(). Intended to be called by the ReadView owner thread. */ - bool changes_visible(trx_id_t id, const table_name_t &name) const - { return id == m_creator_trx_id || ReadViewBase::changes_visible(id, name); } bool changes_visible(trx_id_t id) const { return id == m_creator_trx_id || ReadViewBase::changes_visible(id); } diff --git a/storage/innobase/include/row0mysql.h b/storage/innobase/include/row0mysql.h index 3c624621b1d..a49e2c3f441 100644 --- a/storage/innobase/include/row0mysql.h +++ b/storage/innobase/include/row0mysql.h @@ -1,7 +1,7 @@ /***************************************************************************** Copyright (c) 2000, 2017, Oracle and/or its affiliates. All Rights Reserved. -Copyright (c) 2017, 2021, MariaDB Corporation. +Copyright (c) 2017, 2022, 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 @@ -263,7 +263,7 @@ row_update_for_mysql( /** This can only be used when the current transaction is at READ COMMITTED or READ UNCOMMITTED isolation level. -Before calling this function row_search_for_mysql() must have +Before calling this function row_search_mvcc() must have initialized prebuilt->new_rec_locks to store the information which new record locks really were set. This function removes a newly set clustered index record lock under prebuilt->pcur or @@ -382,22 +382,6 @@ row_rename_table_for_mysql( FOREIGN KEY constraints */ MY_ATTRIBUTE((nonnull, warn_unused_result)); -/*********************************************************************//** -Scans an index for either COOUNT(*) or CHECK TABLE. -If CHECK TABLE; Checks that the index contains entries in an ascending order, -unique constraint is not broken, and calculates the number of index entries -in the read view of the current transaction. -@return DB_SUCCESS or other error */ -dberr_t -row_scan_index_for_mysql( -/*=====================*/ - row_prebuilt_t* prebuilt, /*!< in: prebuilt struct - in MySQL handle */ - const dict_index_t* index, /*!< in: index */ - ulint* n_rows) /*!< out: number of entries - seen in the consistent read */ - MY_ATTRIBUTE((warn_unused_result)); - /* A struct describing a place for an individual column in the MySQL row format which is presented to the table handler in ha_innobase. This template struct is used to speed up row transformations between @@ -606,7 +590,7 @@ struct row_prebuilt_t { ROW_READ_TRY_SEMI_CONSISTENT and to simply skip the row. If the row matches, the next call to - row_search_for_mysql() will lock + row_search_mvcc() will lock the row. This eliminates lock waits in some cases; note that this breaks @@ -615,7 +599,7 @@ struct row_prebuilt_t { the session is using READ COMMITTED or READ UNCOMMITTED isolation level, set in - row_search_for_mysql() if we set a new + row_search_mvcc() if we set a new record lock on the secondary or clustered index; this is used in row_unlock_for_mysql() @@ -847,7 +831,7 @@ innobase_rename_vc_templ( #define ROW_MYSQL_REC_FIELDS 1 #define ROW_MYSQL_NO_TEMPLATE 2 #define ROW_MYSQL_DUMMY_TEMPLATE 3 /* dummy template used in - row_scan_and_check_index */ + row_check_index() */ /* Values for hint_need_to_fetch_extra_cols */ #define ROW_RETRIEVE_PRIMARY_KEY 1 diff --git a/storage/innobase/include/row0sel.h b/storage/innobase/include/row0sel.h index eb83a4bcad6..8134c60fe72 100644 --- a/storage/innobase/include/row0sel.h +++ b/storage/innobase/include/row0sel.h @@ -1,7 +1,7 @@ /***************************************************************************** Copyright (c) 1997, 2017, Oracle and/or its affiliates. -Copyright (c) 2017, MariaDB Corporation. +Copyright (c) 2017, 2022, 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 @@ -24,8 +24,7 @@ Select Created 12/19/1997 Heikki Tuuri *******************************************************/ -#ifndef row0sel_h -#define row0sel_h +#pragma once #include "data0data.h" #include "que0types.h" @@ -58,15 +57,6 @@ void sel_col_prefetch_buf_free( /*======================*/ sel_buf_t* prefetch_buf); /*!< in, own: prefetch buffer */ -/*********************************************************************//** -Gets the plan node for the nth table in a join. -@return plan node */ -UNIV_INLINE -plan_t* -sel_node_get_nth_plan( -/*==================*/ - sel_node_t* node, /*!< in: select node */ - ulint i); /*!< in: get ith plan node */ /**********************************************************************//** Performs a select step. This is a high-level function used in SQL execution graphs. @@ -76,14 +66,6 @@ row_sel_step( /*=========*/ que_thr_t* thr); /*!< in: query thread */ /**********************************************************************//** -Performs an execution step of an open or close cursor statement node. -@return query thread to run next or NULL */ -UNIV_INLINE -que_thr_t* -open_step( -/*======*/ - que_thr_t* thr); /*!< in: query thread */ -/**********************************************************************//** Performs a fetch for a cursor. @return query thread to run next or NULL */ que_thr_t* @@ -136,37 +118,7 @@ row_sel_convert_mysql_key_to_innobase( ulint key_len); /*!< in: MySQL key value length */ -/** Searches for rows in the database. This is used in the interface to -MySQL. This function opens a cursor, and also implements fetch next -and fetch prev. NOTE that if we do a search with a full key value -from a unique index (ROW_SEL_EXACT), then we will not store the cursor -position and fetch next or fetch prev must not be tried to the cursor! - -@param[out] buf buffer for the fetched row in MySQL format -@param[in] mode search mode PAGE_CUR_L -@param[in,out] prebuilt prebuilt struct for the table handler; - this contains the info to search_tuple, - index; if search tuple contains 0 field then - we position the cursor at start or the end of - index, depending on 'mode' -@param[in] match_mode 0 or ROW_SEL_EXACT or ROW_SEL_EXACT_PREFIX -@param[in] direction 0 or ROW_SEL_NEXT or ROW_SEL_PREV; - Note: if this is != 0, then prebuilt must has a - pcur with stored position! In opening of a - cursor 'direction' should be 0. -@return DB_SUCCESS, DB_RECORD_NOT_FOUND, DB_END_OF_INDEX, DB_DEADLOCK, -DB_LOCK_TABLE_FULL, DB_CORRUPTION, or DB_TOO_BIG_RECORD */ -UNIV_INLINE -dberr_t -row_search_for_mysql( - byte* buf, - page_cur_mode_t mode, - row_prebuilt_t* prebuilt, - ulint match_mode, - ulint direction) - MY_ATTRIBUTE((warn_unused_result)); - -/** Searches for rows in the database using cursor. +/** Search for rows in the database using cursor. Function is mainly used for tables that are shared across connections and so it employs technique that can help re-construct the rows that transaction is suppose to see. @@ -184,7 +136,8 @@ It also has optimization such as pre-caching the rows, using AHI, etc. Note: if this is != 0, then prebuilt must has a pcur with stored position! In opening of a cursor 'direction' should be 0. -@return DB_SUCCESS or error code */ +@return DB_SUCCESS, DB_RECORD_NOT_FOUND, DB_END_OF_INDEX, DB_DEADLOCK, +DB_LOCK_TABLE_FULL, DB_CORRUPTION, or DB_TOO_BIG_RECORD */ dberr_t row_search_mvcc( byte* buf, @@ -210,6 +163,21 @@ row_count_rtree_recs( ulint* n_rows); /*!< out: number of entries seen in the consistent read */ +/** +Check the index records in CHECK TABLE. +The index must contain entries in an ascending order, +unique constraint must not be violated by duplicated keys, +and the number of index entries is counted in according to the +current read view. + +@param prebuilt index and transaction +@param n_rows number of records counted + +@return error code +@retval DB_SUCCESS if no error was found */ +dberr_t row_check_index(row_prebuilt_t *prebuilt, ulint *n_rows) + MY_ATTRIBUTE((nonnull, warn_unused_result)); + /** Read the max AUTOINC value from an index. @param[in] index index starting with an AUTO_INCREMENT column @return the largest AUTO_INCREMENT value @@ -382,6 +350,17 @@ struct sel_node_t{ fetches */ }; +/** +Get the plan node for a table in a join. +@param node query graph node for SELECT +@param i plan node element +@return ith plan node */ +inline plan_t *sel_node_get_nth_plan(sel_node_t *node, ulint i) +{ + ut_ad(i < node->n_tables); + return &node->plans[i]; +} + /** Fetch statement node */ struct fetch_node_t{ que_common_t common; /*!< type: QUE_NODE_FETCH */ @@ -476,7 +455,3 @@ row_sel_field_store_in_mysql_format_func( #endif /* UNIV_DEBUG */ const byte* data, /*!< in: data to store */ ulint len); /*!< in: length of the data */ - -#include "row0sel.inl" - -#endif diff --git a/storage/innobase/include/row0sel.inl b/storage/innobase/include/row0sel.inl deleted file mode 100644 index 7880605ca8f..00000000000 --- a/storage/innobase/include/row0sel.inl +++ /dev/null @@ -1,138 +0,0 @@ -/***************************************************************************** - -Copyright (c) 1997, 2014, Oracle and/or its affiliates. All Rights Reserved. - -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 Street, Fifth Floor, Boston, MA 02110-1335 USA - -*****************************************************************************/ - -/**************************************************//** -@file include/row0sel.ic -Select - -Created 12/19/1997 Heikki Tuuri -*******************************************************/ - -#include "que0que.h" - -/*********************************************************************//** -Gets the plan node for the nth table in a join. -@return plan node */ -UNIV_INLINE -plan_t* -sel_node_get_nth_plan( -/*==================*/ - sel_node_t* node, /*!< in: select node */ - ulint i) /*!< in: get ith plan node */ -{ - ut_ad(i < node->n_tables); - - return(node->plans + i); -} - -/*********************************************************************//** -Resets the cursor defined by sel_node to the SEL_NODE_OPEN state, which means -that it will start fetching from the start of the result set again, regardless -of where it was before, and it will set intention locks on the tables. */ -UNIV_INLINE -void -sel_node_reset_cursor( -/*==================*/ - sel_node_t* node) /*!< in: select node */ -{ - node->state = SEL_NODE_OPEN; -} - -/**********************************************************************//** -Performs an execution step of an open or close cursor statement node. -@return query thread to run next or NULL */ -UNIV_INLINE -que_thr_t* -open_step( -/*======*/ - que_thr_t* thr) /*!< in: query thread */ -{ - sel_node_t* sel_node; - open_node_t* node; - ulint err; - - ut_ad(thr); - - node = (open_node_t*) thr->run_node; - ut_ad(que_node_get_type(node) == QUE_NODE_OPEN); - - sel_node = node->cursor_def; - - err = DB_SUCCESS; - - if (node->op_type == ROW_SEL_OPEN_CURSOR) { - - /* if (sel_node->state == SEL_NODE_CLOSED) { */ - - sel_node_reset_cursor(sel_node); - /* } else { - err = DB_ERROR; - } */ - } else { - if (sel_node->state != SEL_NODE_CLOSED) { - - sel_node->state = SEL_NODE_CLOSED; - } else { - err = DB_ERROR; - } - } - - if (err != DB_SUCCESS) { - /* SQL error detected */ - fprintf(stderr, "SQL error %lu\n", (ulong) err); - - ut_error; - } - - thr->run_node = que_node_get_parent(node); - - return(thr); -} - - -/** Searches for rows in the database. This is used in the interface to -MySQL. This function opens a cursor, and also implements fetch next -and fetch prev. NOTE that if we do a search with a full key value -from a unique index (ROW_SEL_EXACT), then we will not store the cursor -position and fetch next or fetch prev must not be tried to the cursor! - -@param[out] buf buffer for the fetched row in MySQL format -@param[in] mode search mode PAGE_CUR_L -@param[in,out] prebuilt prebuilt struct for the table handler; - this contains the info to search_tuple, - index; if search tuple contains 0 field then - we position the cursor at start or the end of - index, depending on 'mode' -@param[in] match_mode 0 or ROW_SEL_EXACT or ROW_SEL_EXACT_PREFIX -@param[in] direction 0 or ROW_SEL_NEXT or ROW_SEL_PREV; - Note: if this is != 0, then prebuilt must has a - pcur with stored position! In opening of a - cursor 'direction' should be 0. -@return DB_SUCCESS, DB_RECORD_NOT_FOUND, DB_END_OF_INDEX, DB_DEADLOCK, -DB_LOCK_TABLE_FULL, DB_CORRUPTION, or DB_TOO_BIG_RECORD */ -UNIV_INLINE -dberr_t -row_search_for_mysql( - byte* buf, - page_cur_mode_t mode, - row_prebuilt_t* prebuilt, - ulint match_mode, - ulint direction) -{ - return(row_search_mvcc(buf, mode, prebuilt, match_mode, direction)); -} diff --git a/storage/innobase/include/row0upd.h b/storage/innobase/include/row0upd.h index d47ec793f89..cc05df395ea 100644 --- a/storage/innobase/include/row0upd.h +++ b/storage/innobase/include/row0upd.h @@ -1,7 +1,7 @@ /***************************************************************************** Copyright (c) 1996, 2018, Oracle and/or its affiliates. All Rights Reserved. -Copyright (c) 2017, 2020, MariaDB Corporation. +Copyright (c) 2017, 2022, 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 @@ -118,14 +118,6 @@ row_upd_changes_field_size_or_external( dict_index_t* index, /*!< in: index */ const rec_offs* offsets,/*!< in: rec_get_offsets(rec, index) */ const upd_t* update);/*!< in: update vector */ -/***********************************************************//** -Returns true if row update contains disowned external fields. -@return true if the update contains disowned external fields. */ -bool -row_upd_changes_disowned_external( -/*==============================*/ - const upd_t* update) /*!< in: update vector */ - MY_ATTRIBUTE((nonnull, warn_unused_result)); /***************************************************************//** Builds an update vector from those fields which in a secondary index entry diff --git a/storage/innobase/include/row0vers.h b/storage/innobase/include/row0vers.h index e05b18a8ccc..60f310e1b0f 100644 --- a/storage/innobase/include/row0vers.h +++ b/storage/innobase/include/row0vers.h @@ -1,7 +1,7 @@ /***************************************************************************** Copyright (c) 1997, 2016, Oracle and/or its affiliates. All Rights Reserved. -Copyright (c) 2017, 2019, MariaDB Corporation. +Copyright (c) 2017, 2022, 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 @@ -55,7 +55,7 @@ row_vers_impl_x_locked( const rec_offs* offsets); /** Finds out if a version of the record, where the version >= the current -purge view, should have ientry as its secondary index entry. We check +purge_sys.view, should have ientry as its secondary index entry. We check if there is any not delete marked version of the record where the trx id >= purge view, and the secondary index entry == ientry; exactly in this case we return TRUE. @@ -85,7 +85,9 @@ row_vers_old_has_index_entry( Constructs the version of a clustered index record which a consistent read should see. We assume that the trx id stored in rec is such that the consistent read should not see rec in its present version. -@return DB_SUCCESS or DB_MISSING_HISTORY */ +@return error code +@retval DB_SUCCESS if a previous version was fetched +@retval DB_MISSING_HISTORY if the history is missing (a sign of corruption) */ dberr_t row_vers_build_for_consistent_read( /*===============================*/ diff --git a/storage/innobase/include/trx0purge.h b/storage/innobase/include/trx0purge.h index 6109f7fb358..3711599bd8c 100644 --- a/storage/innobase/include/trx0purge.h +++ b/storage/innobase/include/trx0purge.h @@ -24,8 +24,7 @@ Purge old versions Created 3/26/1996 Heikki Tuuri *******************************************************/ -#ifndef trx0purge_h -#define trx0purge_h +#pragma once #include "trx0sys.h" #include "que0types.h" @@ -123,7 +122,8 @@ public: /** latch protecting view, m_enabled */ alignas(CPU_LEVEL1_DCACHE_LINESIZE) mutable srw_spin_lock latch; private: - /** The purge will not remove undo logs which are >= this view */ + /** Read view at the start of a purge batch. Any encountered index records + that are older than view will be removed. */ ReadViewBase view; /** whether purge is enabled; protected by latch and std::atomic */ std::atomic m_enabled; @@ -133,6 +133,12 @@ private: Atomic_counter m_SYS_paused; /** number of stop_FTS() calls without resume_FTS() */ Atomic_counter m_FTS_paused; + + /** latch protecting end_view */ + alignas(CPU_LEVEL1_DCACHE_LINESIZE) srw_spin_lock_low end_latch; + /** Read view at the end of a purge batch (copied from view). Any undo pages + containing records older than end_view may be freed. */ + ReadViewBase end_view; public: que_t* query; /*!< The query graph which will do the parallelized purge operation */ @@ -261,28 +267,56 @@ public: /** check stop_SYS() */ void check_stop_FTS() { if (must_wait_FTS()) wait_FTS(); } - /** A wrapper around ReadView::changes_visible(). */ - bool changes_visible(trx_id_t id, const table_name_t &name) const - { - return view.changes_visible(id, name); - } + /** Determine if the history of a transaction is purgeable. + @param trx_id transaction identifier + @return whether the history is purgeable */ + TRANSACTIONAL_TARGET bool is_purgeable(trx_id_t trx_id) const; + /** A wrapper around ReadView::low_limit_no(). */ trx_id_t low_limit_no() const { - /* Other callers than purge_coordinator_callback() must be holding - purge_sys.latch here. The purge coordinator task may call this - without holding any latch, because it is the only thread that may - modify purge_sys.view. */ + /* This function may only be called by purge_coordinator_callback(). + + The purge coordinator task may call this without holding any latch, + because it is the only thread that may modify purge_sys.view. + + Any other threads that access purge_sys.view must hold purge_sys.latch, + typically via purge_sys_t::view_guard. */ return view.low_limit_no(); } /** A wrapper around trx_sys_t::clone_oldest_view(). */ + template void clone_oldest_view() { latch.wr_lock(SRW_LOCK_CALL); trx_sys.clone_oldest_view(&view); + if (also_end_view) + (end_view= view). + clamp_low_limit_id(head.trx_no ? head.trx_no : tail.trx_no); latch.wr_unlock(); } + /** Update end_view at the end of a purge batch. */ + inline void clone_end_view(); + + struct view_guard + { + inline view_guard(); + inline ~view_guard(); + + /** @return purge_sys.view */ + inline const ReadViewBase &view() const; + }; + + struct end_view_guard + { + inline end_view_guard(); + inline ~end_view_guard(); + + /** @return purge_sys.end_view */ + inline const ReadViewBase &view() const; + }; + /** Stop the purge thread and check n_ref_count of all auxiliary and common table associated with the fts table. @param table parent FTS table @@ -294,4 +328,20 @@ public: /** The global data structure coordinating a purge */ extern purge_sys_t purge_sys; -#endif /* trx0purge_h */ +purge_sys_t::view_guard::view_guard() +{ purge_sys.latch.rd_lock(SRW_LOCK_CALL); } + +purge_sys_t::view_guard::~view_guard() +{ purge_sys.latch.rd_unlock(); } + +const ReadViewBase &purge_sys_t::view_guard::view() const +{ return purge_sys.view; } + +purge_sys_t::end_view_guard::end_view_guard() +{ purge_sys.end_latch.rd_lock(); } + +purge_sys_t::end_view_guard::~end_view_guard() +{ purge_sys.end_latch.rd_unlock(); } + +const ReadViewBase &purge_sys_t::end_view_guard::view() const +{ return purge_sys.end_view; } diff --git a/storage/innobase/include/trx0rec.h b/storage/innobase/include/trx0rec.h index 52fd97fef9d..58ec5ab1707 100644 --- a/storage/innobase/include/trx0rec.h +++ b/storage/innobase/include/trx0rec.h @@ -181,17 +181,17 @@ trx_undo_report_row_operation( is being called purge view and we would like to get the purge record even it is in the purge view (in normal case, it will return without fetching the purge record */ -#define TRX_UNDO_PREV_IN_PURGE 0x1 +static constexpr ulint TRX_UNDO_PREV_IN_PURGE = 1; /** This tells trx_undo_prev_version_build() to fetch the old value in the undo log (which is the after image for an update) */ -#define TRX_UNDO_GET_OLD_V_VALUE 0x2 +static constexpr ulint TRX_UNDO_GET_OLD_V_VALUE = 2; + +/** indicate a call from row_vers_old_has_index_entry() */ +static constexpr ulint TRX_UNDO_CHECK_PURGEABILITY = 4; /** Build a previous version of a clustered index record. The caller must hold a latch on the index page of the clustered index record. -@param index_rec clustered index record in the index tree -@param index_mtr mtr which contains the latch to index_rec page - and purge_view @param rec version of a clustered index record @param index clustered index @param offsets rec_get_offsets(rec, index) @@ -210,14 +210,12 @@ must hold a latch on the index page of the clustered index record. @param v_status status determine if it is going into this function by purge thread or not. And if we read "after image" of undo log -@retval true if previous version was built, or if it was an insert -or the table has been rebuilt -@retval false if the previous version is earlier than purge_view, -or being purged, which means that it may have been removed */ -bool +@return error code +@retval DB_SUCCESS if previous version was successfully built, +or if it was an insert or the undo record refers to the table before rebuild +@retval DB_MISSING_HISTORY if the history is missing */ +dberr_t trx_undo_prev_version_build( - const rec_t *index_rec, - mtr_t *index_mtr, const rec_t *rec, dict_index_t *index, rec_offs *offsets, diff --git a/storage/innobase/lock/lock0lock.cc b/storage/innobase/lock/lock0lock.cc index 8490773dc68..0d6a069d50d 100644 --- a/storage/innobase/lock/lock0lock.cc +++ b/storage/innobase/lock/lock0lock.cc @@ -44,6 +44,7 @@ Created 5/7/1996 Heikki Tuuri #include "row0vers.h" #include "pars0pars.h" #include "srv0mon.h" +#include "que0que.h" #include diff --git a/storage/innobase/que/que0que.cc b/storage/innobase/que/que0que.cc index 3ea5c15bccc..80c34af2790 100644 --- a/storage/innobase/que/que0que.cc +++ b/storage/innobase/que/que0que.cc @@ -1,7 +1,7 @@ /***************************************************************************** Copyright (c) 1996, 2016, Oracle and/or its affiliates. All Rights Reserved. -Copyright (c) 2017, 2021, MariaDB Corporation. +Copyright (c) 2017, 2022, 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 @@ -566,6 +566,27 @@ que_node_type_string( } #endif /* DBUG_TRACE */ + +/**********************************************************************//** +Performs an execution step of an open or close cursor statement node. +@param thr query thread */ +static void open_step(que_thr_t *thr) +{ + open_node_t *node= static_cast(thr->run_node); + ut_ad(que_node_get_type(node) == QUE_NODE_OPEN); + sel_node_t *sel_node= node->cursor_def; + + if (node->op_type == ROW_SEL_OPEN_CURSOR) + sel_node->state= SEL_NODE_OPEN; + else + { + ut_ad(sel_node->state != SEL_NODE_CLOSED); + sel_node->state= SEL_NODE_CLOSED; + } + + thr->run_node= que_node_get_parent(node); +} + /**********************************************************************//** Performs an execution step on a query thread. @return query thread to run next: it may differ from the input @@ -636,7 +657,7 @@ que_thr_step( } else if (type == QUE_NODE_FETCH) { thr = fetch_step(thr); } else if (type == QUE_NODE_OPEN) { - thr = open_step(thr); + open_step(thr); } else if (type == QUE_NODE_FUNC) { proc_eval_step(thr); diff --git a/storage/innobase/row/row0log.cc b/storage/innobase/row/row0log.cc index ac011697e2c..cfc3d6f18f2 100644 --- a/storage/innobase/row/row0log.cc +++ b/storage/innobase/row/row0log.cc @@ -3842,9 +3842,8 @@ UndorecApplier::get_old_rec(const dtuple_t &tuple, dict_index_t *index, ut_ad(len == DATA_ROLL_PTR_LEN); if (is_same(roll_ptr)) return version; - trx_undo_prev_version_build(*clust_rec, &mtr, version, index, - *offsets, heap, &prev_version, nullptr, - nullptr, 0); + trx_undo_prev_version_build(version, index, *offsets, heap, &prev_version, + nullptr, nullptr, 0); version= prev_version; } while (version); @@ -4014,9 +4013,8 @@ void UndorecApplier::log_update(const dtuple_t &tuple, if (match_rec == rec) copy_rec= rec_copy(mem_heap_alloc( heap, rec_offs_size(offsets)), match_rec, offsets); - trx_undo_prev_version_build(rec, &mtr, match_rec, clust_index, - offsets, heap, &prev_version, nullptr, - nullptr, 0); + trx_undo_prev_version_build(match_rec, clust_index, offsets, heap, + &prev_version, nullptr, nullptr, 0); prev_offsets= rec_get_offsets(prev_version, clust_index, prev_offsets, clust_index->n_core_fields, diff --git a/storage/innobase/row/row0merge.cc b/storage/innobase/row/row0merge.cc index 1b6d23660bb..f2b29ae0f16 100644 --- a/storage/innobase/row/row0merge.cc +++ b/storage/innobase/row/row0merge.cc @@ -2124,8 +2124,14 @@ end_of_index: ut_ad(trx->read_view.is_open()); ut_ad(rec_trx_id != trx->id); - if (!trx->read_view.changes_visible( - rec_trx_id, old_table->name)) { + if (!trx->read_view.changes_visible(rec_trx_id)) { + if (rec_trx_id + >= trx->read_view.low_limit_id() + && rec_trx_id + >= trx_sys.get_max_trx_id()) { + goto corrupted_rec; + } + rec_t* old_vers; row_vers_build_for_consistent_read( @@ -4412,9 +4418,7 @@ row_merge_is_index_usable( && (index->table->is_temporary() || index->table->no_rollback() || index->trx_id == 0 || !trx->read_view.is_open() - || trx->read_view.changes_visible( - index->trx_id, - index->table->name))); + || trx->read_view.changes_visible(index->trx_id))); } /** Build indexes on a table by reading a clustered index, creating a temporary diff --git a/storage/innobase/row/row0mysql.cc b/storage/innobase/row/row0mysql.cc index 10fe321a702..de469c5b088 100644 --- a/storage/innobase/row/row0mysql.cc +++ b/storage/innobase/row/row0mysql.cc @@ -1766,7 +1766,7 @@ error: /** This can only be used when the current transaction is at READ COMMITTED or READ UNCOMMITTED isolation level. -Before calling this function row_search_for_mysql() must have +Before calling this function row_search_mvcc() must have initialized prebuilt->new_rec_locks to store the information which new record locks really were set. This function removes a newly set clustered index record lock under prebuilt->pcur or @@ -2937,182 +2937,3 @@ funct_exit: return(err); } - -/*********************************************************************//** -Scans an index for either COUNT(*) or CHECK TABLE. -If CHECK TABLE; Checks that the index contains entries in an ascending order, -unique constraint is not broken, and calculates the number of index entries -in the read view of the current transaction. -@return DB_SUCCESS or other error */ -dberr_t -row_scan_index_for_mysql( -/*=====================*/ - row_prebuilt_t* prebuilt, /*!< in: prebuilt struct - in MySQL handle */ - const dict_index_t* index, /*!< in: index */ - ulint* n_rows) /*!< out: number of entries - seen in the consistent read */ -{ - dtuple_t* prev_entry = NULL; - ulint matched_fields; - byte* buf; - dberr_t ret; - rec_t* rec; - int cmp; - ibool contains_null; - ulint i; - ulint cnt; - mem_heap_t* heap = NULL; - rec_offs offsets_[REC_OFFS_NORMAL_SIZE]; - rec_offs* offsets; - rec_offs_init(offsets_); - - *n_rows = 0; - - /* Don't support RTree Leaf level scan */ - ut_ad(!dict_index_is_spatial(index)); - - if (dict_index_is_clust(index)) { - /* The clustered index of a table is always available. - During online ALTER TABLE that rebuilds the table, the - clustered index in the old table will have - index->online_log pointing to the new table. All - indexes of the old table will remain valid and the new - table will be unaccessible to MySQL until the - completion of the ALTER TABLE. */ - } else if (dict_index_is_online_ddl(index) - || (index->type & DICT_FTS)) { - /* Full Text index are implemented by auxiliary tables, - not the B-tree. We also skip secondary indexes that are - being created online. */ - return(DB_SUCCESS); - } - - ulint bufsize = std::max(srv_page_size, - prebuilt->mysql_row_len); - buf = static_cast(ut_malloc_nokey(bufsize)); - heap = mem_heap_create(100); - - cnt = 1000; - - ret = row_search_for_mysql(buf, PAGE_CUR_G, prebuilt, 0, 0); -loop: - /* Check thd->killed every 1,000 scanned rows */ - if (--cnt == 0) { - if (trx_is_interrupted(prebuilt->trx)) { - ret = DB_INTERRUPTED; - goto func_exit; - } - cnt = 1000; - } - - switch (ret) { - case DB_SUCCESS: - break; - case DB_DEADLOCK: - case DB_LOCK_TABLE_FULL: - case DB_LOCK_WAIT_TIMEOUT: - case DB_INTERRUPTED: - goto func_exit; - default: - ib::warn() << "CHECK TABLE on index " << index->name << " of" - " table " << index->table->name << " returned " << ret; - /* (this error is ignored by CHECK TABLE) */ - /* fall through */ - case DB_END_OF_INDEX: - ret = DB_SUCCESS; -func_exit: - ut_free(buf); - mem_heap_free(heap); - - return(ret); - } - - *n_rows = *n_rows + 1; - - /* else this code is doing handler::check() for CHECK TABLE */ - - /* row_search... returns the index record in buf, record origin offset - within buf stored in the first 4 bytes, because we have built a dummy - template */ - - rec = buf + mach_read_from_4(buf); - - offsets = rec_get_offsets(rec, index, offsets_, index->n_core_fields, - ULINT_UNDEFINED, &heap); - - if (prev_entry != NULL) { - matched_fields = 0; - - cmp = cmp_dtuple_rec_with_match(prev_entry, rec, offsets, - &matched_fields); - contains_null = FALSE; - - /* In a unique secondary index we allow equal key values if - they contain SQL NULLs */ - - for (i = 0; - i < dict_index_get_n_ordering_defined_by_user(index); - i++) { - if (UNIV_SQL_NULL == dfield_get_len( - dtuple_get_nth_field(prev_entry, i))) { - - contains_null = TRUE; - break; - } - } - - const char* msg; - - if (cmp > 0) { - ret = DB_INDEX_CORRUPT; - msg = "index records in a wrong order in "; -not_ok: - ib::error() - << msg << index->name - << " of table " << index->table->name - << ": " << *prev_entry << ", " - << rec_offsets_print(rec, offsets); - /* Continue reading */ - } else if (dict_index_is_unique(index) - && !contains_null - && matched_fields - >= dict_index_get_n_ordering_defined_by_user( - index)) { - ret = DB_DUPLICATE_KEY; - msg = "duplicate key in "; - goto not_ok; - } - } - - { - mem_heap_t* tmp_heap = NULL; - - /* Empty the heap on each round. But preserve offsets[] - for the row_rec_to_index_entry() call, by copying them - into a separate memory heap when needed. */ - if (UNIV_UNLIKELY(offsets != offsets_)) { - ulint size = rec_offs_get_n_alloc(offsets) - * sizeof *offsets; - - tmp_heap = mem_heap_create(size); - - offsets = static_cast( - mem_heap_dup(tmp_heap, offsets, size)); - } - - mem_heap_empty(heap); - - prev_entry = row_rec_to_index_entry( - rec, index, offsets, heap); - - if (UNIV_LIKELY_NULL(tmp_heap)) { - mem_heap_free(tmp_heap); - } - } - - ret = row_search_for_mysql( - buf, PAGE_CUR_G, prebuilt, 0, ROW_SEL_NEXT); - - goto loop; -} diff --git a/storage/innobase/row/row0sel.cc b/storage/innobase/row/row0sel.cc index 8e18aedef21..9162fda91ed 100644 --- a/storage/innobase/row/row0sel.cc +++ b/storage/innobase/row/row0sel.cc @@ -36,6 +36,8 @@ Created 12/19/1997 Heikki Tuuri #include "dict0boot.h" #include "trx0undo.h" #include "trx0trx.h" +#include "trx0purge.h" +#include "trx0rec.h" #include "btr0btr.h" #include "btr0cur.h" #include "btr0sea.h" @@ -54,6 +56,7 @@ Created 12/19/1997 Heikki Tuuri #include "buf0lru.h" #include "srv0srv.h" #include "srv0mon.h" +#include "sql_error.h" #ifdef WITH_WSREP #include "mysql/service_wsrep.h" /* For wsrep_thd_skip_locking */ #endif @@ -282,7 +285,6 @@ row_sel_sec_rec_is_for_clust_rec( rec_offs_init(clust_offsets_); rec_offs_init(sec_offsets_); - ib_vcol_row vc(heap); clust_offs = rec_get_offsets(clust_rec, clust_index, clust_offs, @@ -952,9 +954,12 @@ row_sel_test_other_conds( @param index clustered index @param offsets rec_get_offsets(rec, index) @param view consistent read view -@return whether rec is visible in view */ -static bool row_sel_clust_sees(const rec_t *rec, const dict_index_t &index, - const rec_offs *offsets, const ReadView &view) +@retval DB_SUCCESS if rec is visible in view +@retval DB_SUCCESS_LOCKED_REC if rec is not visible in view +@retval DB_CORRUPTION if the DB_TRX_ID is corrupted */ +static dberr_t row_sel_clust_sees(const rec_t *rec, const dict_index_t &index, + const rec_offs *offsets, + const ReadView &view) { ut_ad(index.is_primary()); ut_ad(page_rec_is_user_rec(rec)); @@ -962,8 +967,16 @@ static bool row_sel_clust_sees(const rec_t *rec, const dict_index_t &index, ut_ad(!rec_is_metadata(rec, index)); ut_ad(!index.table->is_temporary()); - return view.changes_visible(row_get_rec_trx_id(rec, &index, offsets), - index.table->name); + const trx_id_t id= row_get_rec_trx_id(rec, &index, offsets); + + if (view.changes_visible(id)) + return DB_SUCCESS; + if (UNIV_LIKELY(id < view.low_limit_id() || id < trx_sys.get_max_trx_id())) + return DB_SUCCESS_LOCKED_REC; + + ib::warn() << "A transaction id in a record of table " << index.table->name + << " is newer than the system-wide maximum."; + return DB_CORRUPTION; } /*********************************************************************//** @@ -1074,9 +1087,15 @@ row_sel_get_clust_rec( old_vers = NULL; - if (!row_sel_clust_sees(clust_rec, *index, offsets, - *node->read_view)) { + err = row_sel_clust_sees(clust_rec, *index, offsets, + *node->read_view); + switch (err) { + default: + goto err_exit; + case DB_SUCCESS: + break; + case DB_SUCCESS_LOCKED_REC: err = row_sel_build_prev_vers( node->read_view, index, clust_rec, &offsets, &heap, &plan->old_vers_heap, @@ -1594,8 +1613,8 @@ row_sel_try_search_shortcut( ULINT_UNDEFINED, &heap); if (dict_index_is_clust(index)) { - if (!row_sel_clust_sees(rec, *index, offsets, - *node->read_view)) { + if (row_sel_clust_sees(rec, *index, offsets, *node->read_view) + != DB_SUCCESS) { return SEL_RETRY; } } else if (!srv_read_only_mode) { @@ -1962,9 +1981,16 @@ skip_lock: a previous version of the record */ if (dict_index_is_clust(index)) { - if (!node->read_view->changes_visible( - row_get_rec_trx_id(rec, index, offsets), - index->table->name)) { + const trx_id_t id = row_get_rec_trx_id( + rec, index, offsets); + + if (!node->read_view->changes_visible(id)) { + if (id >= node->read_view->low_limit_id() + && id >= trx_sys.get_max_trx_id()) { + err = DB_CORRUPTION; + goto lock_wait_or_error; + } + err = row_sel_build_prev_vers( node->read_view, index, rec, &offsets, &heap, &plan->old_vers_heap, @@ -3230,6 +3256,14 @@ static bool row_sel_store_mysql_rec( DBUG_RETURN(true); } +static void row_sel_reset_old_vers_heap(row_prebuilt_t *prebuilt) +{ + if (prebuilt->old_vers_heap) + mem_heap_empty(prebuilt->old_vers_heap); + else + prebuilt->old_vers_heap= mem_heap_create(200); +} + /*********************************************************************//** Builds a previous version of a clustered index record for a consistent read @return DB_SUCCESS or error code */ @@ -3237,9 +3271,8 @@ static MY_ATTRIBUTE((warn_unused_result)) dberr_t row_sel_build_prev_vers_for_mysql( /*==============================*/ - ReadView* read_view, /*!< in: read view */ + row_prebuilt_t* prebuilt, /*!< in/out: prebuilt struct */ dict_index_t* clust_index, /*!< in: clustered index */ - row_prebuilt_t* prebuilt, /*!< in: prebuilt struct */ const rec_t* rec, /*!< in: record in a clustered index */ rec_offs** offsets, /*!< in/out: offsets returned by rec_get_offsets(rec, clust_index) */ @@ -3253,18 +3286,12 @@ row_sel_build_prev_vers_for_mysql( column data */ mtr_t* mtr) /*!< in: mtr */ { - dberr_t err; + row_sel_reset_old_vers_heap(prebuilt); - if (prebuilt->old_vers_heap) { - mem_heap_empty(prebuilt->old_vers_heap); - } else { - prebuilt->old_vers_heap = mem_heap_create(200); - } - - err = row_vers_build_for_consistent_read( - rec, mtr, clust_index, offsets, read_view, offset_heap, + return row_vers_build_for_consistent_read( + rec, mtr, clust_index, offsets, + &prebuilt->trx->read_view, offset_heap, prebuilt->old_vers_heap, old_vers, vrow); - return(err); } /** Helper class to cache clust_rec and old_vers */ @@ -3341,7 +3368,6 @@ Row_sel_get_clust_rec_for_mysql::operator()( access the clustered index */ { dict_index_t* clust_index; - const rec_t* clust_rec; rec_t* old_vers; trx_t* trx; @@ -3364,7 +3390,7 @@ Row_sel_get_clust_rec_for_mysql::operator()( return err; } - clust_rec = btr_pcur_get_rec(prebuilt->clust_pcur); + const rec_t* clust_rec = btr_pcur_get_rec(prebuilt->clust_pcur); prebuilt->clust_pcur->trx_if_known = trx; @@ -3392,8 +3418,6 @@ Row_sel_get_clust_rec_for_mysql::operator()( if (!rtr_info->matches->valid) { mysql_mutex_unlock(&rtr_info->matches->rtr_match_mutex); clust_rec = NULL; - - err = DB_SUCCESS; goto func_exit; } mysql_mutex_unlock(&rtr_info->matches->rtr_match_mutex); @@ -3403,15 +3427,11 @@ Row_sel_get_clust_rec_for_mysql::operator()( && prebuilt->select_lock_type == LOCK_NONE) { clust_rec = NULL; - - err = DB_SUCCESS; goto func_exit; } if (rec != btr_pcur_get_rec(prebuilt->pcur)) { clust_rec = NULL; - - err = DB_SUCCESS; goto func_exit; } @@ -3437,18 +3457,14 @@ Row_sel_get_clust_rec_for_mysql::operator()( nullptr)); ut_ad(low_match < dtuple_get_n_fields_cmp(tuple)); mem_heap_free(heap); - clust_rec = NULL; - err = DB_SUCCESS; - goto func_exit; #endif /* UNIV_DEBUG */ } else if (!rec_get_deleted_flag(rec, dict_table_is_comp(sec_index->table)) || prebuilt->select_lock_type != LOCK_NONE) { /* In a rare case it is possible that no clust rec is found for a delete-marked secondary index - record: if in row0umod.cc in - row_undo_mod_remove_clust_low() we have already removed + record: if row_undo_mod_clust() has already removed the clust rec, while purge is still cleaning and removing secondary index records associated with earlier versions of the clustered index record. @@ -3464,11 +3480,8 @@ Row_sel_get_clust_rec_for_mysql::operator()( "InnoDB: clust index record ", stderr); rec_print(stderr, clust_rec, clust_index); err = DB_CORRUPTION; - clust_rec = NULL; - goto func_exit; } - err = DB_SUCCESS; clust_rec = NULL; goto func_exit; } @@ -3504,11 +3517,20 @@ Row_sel_get_clust_rec_for_mysql::operator()( if (trx->isolation_level == TRX_ISO_READ_UNCOMMITTED || clust_index->table->is_temporary()) { + } else { /* If the isolation level allows reading of uncommitted data, then we never look for an earlier version */ - } else if (!row_sel_clust_sees(clust_rec, *clust_index, - *offsets, trx->read_view)) { + err = row_sel_clust_sees(clust_rec, *clust_index, + *offsets, trx->read_view); + } + + switch (err) { + default: + return err; + case DB_SUCCESS: + break; + case DB_SUCCESS_LOCKED_REC: const buf_page_t& bpage = btr_pcur_get_block( prebuilt->clust_pcur)->page; @@ -3521,7 +3543,7 @@ Row_sel_get_clust_rec_for_mysql::operator()( /* The following call returns 'offsets' associated with 'old_vers' */ err = row_sel_build_prev_vers_for_mysql( - &trx->read_view, clust_index, prebuilt, + prebuilt, clust_index, clust_rec, offsets, offset_heap, &old_vers, vrow, mtr); @@ -3978,7 +4000,8 @@ row_sel_try_search_shortcut_for_mysql( *offsets = rec_get_offsets(rec, index, *offsets, index->n_core_fields, ULINT_UNDEFINED, heap); - if (!row_sel_clust_sees(rec, *index, *offsets, trx->read_view)) { + if (row_sel_clust_sees(rec, *index, *offsets, trx->read_view) + != DB_SUCCESS) { return SEL_RETRY; } @@ -4376,8 +4399,8 @@ row_search_mvcc( /* We need to get the virtual column values stored in secondary index key, if this is covered index scan or virtual key read is requested. */ - bool need_vrow = dict_index_has_virtual(prebuilt->index) - && prebuilt->read_just_key; + bool need_vrow = prebuilt->read_just_key + && prebuilt->index->has_virtual(); /* Reset the new record lock info if READ UNCOMMITTED or READ COMMITED isolation level is used. Then @@ -4881,11 +4904,6 @@ rec_loop: rec = btr_pcur_get_rec(pcur); - if (!index->table->is_readable()) { - err = DB_DECRYPTION_FAILED; - goto page_read_error; - } - ut_ad(!!page_rec_is_comp(rec) == comp); ut_ad(page_rec_is_leaf(rec)); @@ -5324,18 +5342,24 @@ no_gap_lock: high force recovery level set, we try to avoid crashes by skipping this lookup */ - if (!row_sel_clust_sees(rec, *index, offsets, - trx->read_view)) { + err = row_sel_clust_sees(rec, *index, offsets, + trx->read_view); + + switch (err) { + default: + goto lock_wait_or_error; + case DB_SUCCESS: + break; + case DB_SUCCESS_LOCKED_REC: ut_ad(srv_force_recovery < SRV_FORCE_NO_UNDO_LOG_SCAN); rec_t* old_vers; /* The following call returns 'offsets' associated with 'old_vers' */ err = row_sel_build_prev_vers_for_mysql( - &trx->read_view, clust_index, - prebuilt, rec, &offsets, &heap, - &old_vers, need_vrow ? &vrow : NULL, - &mtr); + prebuilt, clust_index, + rec, &offsets, &heap, &old_vers, + need_vrow ? &vrow : nullptr, &mtr); if (err != DB_SUCCESS) { @@ -5476,8 +5500,7 @@ requires_clust_rec: &offsets, &heap, need_vrow ? &vrow : NULL, &mtr); - if (prebuilt->skip_locked && - err == DB_LOCK_WAIT) { + if (err == DB_LOCK_WAIT && prebuilt->skip_locked) { err = lock_trx_handle_wait(trx); } switch (err) { @@ -5486,7 +5509,6 @@ requires_clust_rec: /* The record did not exist in the read view */ ut_ad(prebuilt->select_lock_type == LOCK_NONE || dict_index_is_spatial(index)); - goto next_rec; } break; @@ -5581,9 +5603,7 @@ use_covering_index: && !prebuilt->templ_contains_blob && !prebuilt->clust_index_was_generated && !prebuilt->used_in_HANDLER - && prebuilt->template_type != ROW_MYSQL_DUMMY_TEMPLATE && !prebuilt->in_fts_query) { - /* Inside an update, for example, we do not cache rows, since we may use the cursor position to do the actual update, that is why we require ...lock_type == LOCK_NONE. @@ -5648,29 +5668,8 @@ use_covering_index: if (prebuilt->n_fetch_cached < MYSQL_FETCH_CACHE_SIZE) { goto next_rec; } - } else { - if (UNIV_UNLIKELY - (prebuilt->template_type == ROW_MYSQL_DUMMY_TEMPLATE)) { - /* CHECK TABLE: fetch the row */ - - if (result_rec != rec - && !prebuilt->need_to_access_clustered) { - /* We used 'offsets' for the clust - rec, recalculate them for 'rec' */ - offsets = rec_get_offsets(rec, index, offsets, - index->n_core_fields, - ULINT_UNDEFINED, - &heap); - result_rec = rec; - } - - memcpy(buf + 4, result_rec - - rec_offs_extra_size(offsets), - rec_offs_size(offsets)); - mach_write_to_4(buf, - rec_offs_extra_size(offsets) + 4); - } else if (!prebuilt->pk_filter && !prebuilt->idx_cond) { + if (!prebuilt->pk_filter && !prebuilt->idx_cond) { /* The record was not yet converted to MySQL format. */ if (!row_sel_store_mysql_rec( buf, prebuilt, result_rec, vrow, @@ -6026,18 +6025,11 @@ row_count_rtree_recs( prebuilt->mysql_row_len); buf = static_cast(ut_malloc_nokey(bufsize)); - ulint cnt = 1000; + ulint direction = 0; - ret = row_search_for_mysql(buf, PAGE_CUR_WITHIN, prebuilt, 0, 0); loop: - /* Check thd->killed every 1,000 scanned rows */ - if (--cnt == 0) { - if (trx_is_interrupted(prebuilt->trx)) { - ret = DB_INTERRUPTED; - goto func_exit; - } - cnt = 1000; - } + ret = row_search_mvcc(buf, PAGE_CUR_WITHIN, prebuilt, 0, direction); + direction = ROW_SEL_NEXT; switch (ret) { case DB_SUCCESS: @@ -6059,14 +6051,779 @@ func_exit: return(ret); } - *n_rows = *n_rows + 1; - - ret = row_search_for_mysql( - buf, PAGE_CUR_WITHIN, prebuilt, 0, ROW_SEL_NEXT); - + ++*n_rows; goto loop; } +/** Check if a version of a clustered index record and a secondary +index record match. + +@param prebuilt index and transaction +@param clust_rec a version of a clustered index record +@param clust_index clustered index +@param clust_offsets rec_get_offsets(clust_rec, clust_index) +@param rec secondary index leaf page record +@param offsets rec_get_offsets(rec, index) +@return an error code +@retval DB_SUCCESS if rec matches clust_rec +@retval DB_SUCCESS_LOCKED_REC if rec does not match clust_rec +*/ +static dberr_t row_check_index_match(row_prebuilt_t *prebuilt, + const rec_t *clust_rec, + const dict_index_t *clust_index, + const rec_offs *clust_offsets, + const rec_t *rec, + const dict_index_t *index, + const rec_offs *offsets) +{ + ut_ad(index == prebuilt->index); + + ib_vcol_row vc(index->has_virtual() ? mem_heap_create(256) : nullptr); + + const uint16_t n= index->n_user_defined_cols; + + for (uint16_t i= 0; i < n; i++) + { + ulint pos= 0; + ulint len, sec_len; + + const dict_field_t &ifield= index->fields[i]; + const byte *sec_field= rec_get_nth_field(rec, offsets, i, &sec_len); + const byte *field; + + if (ifield.col->is_virtual()) + { + /* Virtual column values must be reconstructed from the base columns. */ + row_ext_t *ext; + byte *record= vc.record(prebuilt->trx->mysql_thd, clust_index, + &prebuilt->m_mysql_table); + const dict_v_col_t *v_col= reinterpret_cast + (ifield.col); + dtuple_t *row= row_build(ROW_COPY_POINTERS, + clust_index, clust_rec, clust_offsets, + nullptr, nullptr, nullptr, &ext, vc.heap); + if (dfield_t *vfield= + innobase_get_computed_value(row, v_col, clust_index, &vc.heap, + nullptr, nullptr, + prebuilt->trx->mysql_thd, + prebuilt->m_mysql_table, + record, nullptr, nullptr)) + { + len= vfield->len; + field= static_cast(vfield->data); + } + else + { + innobase_report_computed_value_failed(row); + return DB_COMPUTE_VALUE_FAILED; + } + } + else + { + pos= dict_col_get_clust_pos(ifield.col, clust_index); + field= rec_get_nth_cfield(clust_rec, clust_index, clust_offsets, pos, + &len); + if (len == UNIV_SQL_NULL) + { + if (sec_len == UNIV_SQL_NULL) + continue; + return DB_SUCCESS_LOCKED_REC; + } + if (sec_len == UNIV_SQL_NULL) + return DB_SUCCESS_LOCKED_REC; + + if (rec_offs_nth_extern(clust_offsets, pos)) + { + if (len == BTR_EXTERN_FIELD_REF_SIZE) + goto compare_blobs; + len-= BTR_EXTERN_FIELD_REF_SIZE; + } + + if (ifield.prefix_len) + { + len= + dtype_get_at_most_n_mbchars(ifield.col->prtype, ifield.col->mbminlen, + ifield.col->mbmaxlen, + ifield.prefix_len, len, + reinterpret_cast(field)); + if (len < sec_len) + goto check_for_blob; + } + else + { +check_for_blob: + if (rec_offs_nth_extern(clust_offsets, pos)) + { +compare_blobs: + if (!row_sel_sec_rec_is_for_blob(ifield.col->mtype, + ifield.col->prtype, + ifield.col->mbminlen, + ifield.col->mbmaxlen, + field, len, sec_field, sec_len, + ifield.prefix_len, + clust_index->table)) + return DB_SUCCESS_LOCKED_REC; + continue; + } + } + } + + if (cmp_data_data(ifield.col->mtype, ifield.col->prtype, + field, len, sec_field, sec_len)) + return DB_SUCCESS_LOCKED_REC; + } + + return DB_SUCCESS; +} + +/** +Check the index records in CHECK TABLE. +The index must contain entries in an ascending order, +unique constraint must not be violated by duplicated keys, +and the number of index entries is counted in according to the +current read view. + +@param prebuilt index and transaction +@param n_rows number of records counted + +@return error code +@retval DB_SUCCESS if no error was found */ +dberr_t row_check_index(row_prebuilt_t *prebuilt, ulint *n_rows) +{ + rec_offs offsets_[REC_OFFS_NORMAL_SIZE]; + rec_offs_init(offsets_); + + *n_rows= 0; + dict_index_t *const index= prebuilt->index; + + prebuilt->fetch_direction= ROW_SEL_NEXT; + + if (!index->is_btree()) + return DB_CORRUPTION; + + mem_heap_t *heap= mem_heap_create(100); + + dtuple_t *prev_entry= nullptr; + mtr_t mtr; + mtr.start(); + + dict_index_t *clust_index= dict_table_get_first_index(prebuilt->table); + + dberr_t err= btr_pcur_open_at_index_side(true, index, BTR_SEARCH_LEAF, + prebuilt->pcur, false, 0, &mtr); + if (UNIV_UNLIKELY(err != DB_SUCCESS)) + { +func_exit: + mtr.commit(); + mem_heap_free(heap); + return err; + } + + if (const trx_id_t bulk_trx_id= index->table->bulk_trx_id) + if (!prebuilt->trx->read_view.changes_visible(bulk_trx_id)) + goto func_exit; + + ReadView check_table_extended_view; + ReadView &view= + prebuilt->need_to_access_clustered && + prebuilt->trx->isolation_level != TRX_ISO_READ_UNCOMMITTED + ? check_table_extended_view : prebuilt->trx->read_view; + if (&view == &check_table_extended_view) + check_table_extended_view.set_creator_trx_id(prebuilt->trx->id); + +page_loop: + if (&view == &check_table_extended_view) + /* In CHECK TABLE...EXTENDED, we make a copy of purge_sys.end_view + while holding a shared latch on the index leaf page. + Should a currently active purge batch desire to remove any further + records from this page, it would be blocked by our page latch. + + We will consult check_table_extended_view to determine if a + clustered index record corresponding to a secondary index record + is visible to the current purge batch. Right after we have made our + copy, purge_sys.end_view is free to be changed again. + + If we have an orphan secondary index record, we may attempt to + request a clustered index record version that cannot be retrieved + any more because the undo log records may have been freed + (according to the purge_sys.end_view). In such a case, + trx_undo_get_undo_rec() would cause + trx_undo_prev_version_build() and trx_undo_prev_version_build() + to return DB_MISSING_HISTORY. */ + static_cast(check_table_extended_view)= + purge_sys_t::end_view_guard{}.view(); + +rec_loop: + ut_ad(err == DB_SUCCESS); + + if (!btr_pcur_move_to_next_on_page(prebuilt->pcur)) + { + err= DB_CORRUPTION; + goto func_exit; + } + + const rec_t *rec= btr_pcur_get_rec(prebuilt->pcur); + rec_offs *offsets= offsets_; + + if (page_rec_is_supremum(rec)) + { + next_page: + if (btr_pcur_is_after_last_in_tree(prebuilt->pcur)) + goto func_exit; + err= btr_pcur_move_to_next_page(prebuilt->pcur, &mtr); + if (err == DB_SUCCESS && trx_is_interrupted(prebuilt->trx)) + err= DB_INTERRUPTED; + if (UNIV_UNLIKELY(err != DB_SUCCESS)) + goto func_exit; + goto page_loop; + } + + offsets= rec_get_offsets(rec, index, offsets, index->n_core_fields, + ULINT_UNDEFINED, &heap); + + const auto info_bits= + rec_get_info_bits(rec, prebuilt->table->not_redundant()); + const bool rec_deleted= info_bits & REC_INFO_DELETED_FLAG; + + if (UNIV_UNLIKELY(info_bits & REC_INFO_MIN_REC_FLAG)) + { + if (*n_rows || !index->is_instant()) + { + push_warning_printf(prebuilt->trx->mysql_thd, + Sql_condition::WARN_LEVEL_WARN, ER_NOT_KEYFILE, + "InnoDB: invalid record encountered"); + prebuilt->autoinc_error= DB_INDEX_CORRUPT; + } + goto next_rec; + } + + if (index->is_clust()) + { + if (prebuilt->trx->isolation_level == TRX_ISO_READ_UNCOMMITTED) + { + if (!rec_deleted) + goto count_row; + goto next_rec; + } + + trx_id_t rec_trx_id= row_get_rec_trx_id(rec, index, offsets); + + if (rec_trx_id >= prebuilt->trx->read_view.low_limit_id() && + UNIV_UNLIKELY(rec_trx_id >= trx_sys.get_max_trx_id())) + { + invalid_trx_id: + if (prebuilt->autoinc_error == DB_SUCCESS) + push_warning_printf(prebuilt->trx->mysql_thd, + Sql_condition::WARN_LEVEL_WARN, + ER_NOT_KEYFILE, + "InnoDB: DB_TRX_ID=" TRX_ID_FMT + " exceeds the system-wide maximum", + rec_trx_id); + prebuilt->autoinc_error= DB_CORRUPTION; + goto next_rec; + } + + if (!prebuilt->trx->read_view.changes_visible(rec_trx_id)) + { + ut_ad(srv_force_recovery < SRV_FORCE_NO_UNDO_LOG_SCAN); + rec_t *old_vers; + /* The following call returns 'offsets' associated with 'old_vers' */ + err= row_sel_build_prev_vers_for_mysql(prebuilt, index, rec, &offsets, + &heap, &old_vers, nullptr, &mtr); + + if (err != DB_SUCCESS) + goto func_exit; + + if (old_vers) + { + rec= old_vers; + rec_trx_id= row_get_rec_trx_id(rec, index, offsets); + + if (rec_trx_id >= prebuilt->trx->read_view.low_limit_id() && + UNIV_UNLIKELY(rec_trx_id >= trx_sys.get_max_trx_id())) + goto invalid_trx_id; + + if (!rec_get_deleted_flag(rec, prebuilt->table->not_redundant())) + goto count_row; + } + else + offsets= rec_get_offsets(rec, index, offsets, index->n_core_fields, + ULINT_UNDEFINED, &heap); + goto next_rec; + } + else if (!rec_deleted && !rec_trx_id); + else if (!check_table_extended_view.changes_visible(rec_trx_id)); + else if (prebuilt->autoinc_error == DB_SUCCESS) + { + const char *msg= rec_deleted + ? "Unpurged clustered index record" + : "Clustered index record with stale history"; + + ib::warn w; + w << msg << " in table " << index->table->name << ": " + << rec_offsets_print(rec, offsets); + prebuilt->autoinc_error= DB_MISSING_HISTORY; + push_warning_printf(prebuilt->trx->mysql_thd, + Sql_condition::WARN_LEVEL_WARN, + ER_NOT_KEYFILE, "InnoDB: %s", w.m_oss.str().c_str()); + } + + if (!rec_deleted) + goto count_row; + + goto next_rec; + } + else if (const trx_id_t page_trx_id= page_get_max_trx_id(page_align(rec))) + { + if (page_trx_id >= trx_sys.get_max_trx_id()) + goto invalid_PAGE_MAX_TRX_ID; + if (prebuilt->trx->isolation_level == TRX_ISO_READ_UNCOMMITTED); + else if (&view == &check_table_extended_view || rec_deleted || + !view.sees(page_trx_id)) + { + bool got_extended_match= &view == &check_table_extended_view; + const auto savepoint= mtr.get_savepoint(); + + row_build_row_ref_in_tuple(prebuilt->clust_ref, rec, index, offsets); + err= btr_pcur_open_with_no_init(clust_index, prebuilt->clust_ref, + PAGE_CUR_LE, BTR_SEARCH_LEAF, + prebuilt->clust_pcur, &mtr); + if (err != DB_SUCCESS) + goto func_exit; + + const rec_t *clust_rec= btr_pcur_get_rec(prebuilt->clust_pcur); + + /* Note: only if the search ends up on a non-infimum record is the + low_match value the real match to the search tuple */ + + if (!page_rec_is_user_rec(clust_rec) || + btr_pcur_get_low_match(prebuilt->clust_pcur) < clust_index->n_uniq) + { + if (!rec_deleted) + { + not_found: + /* MDEV-29823 FIXME: There is a race condition between + rollback, purge, and possibly other SQL connections that + are creating and releasing read views. At the time + row_undo_mod_del_mark_or_remove_sec_low() is executing + rollback on a secondary index record, purge_sys.view + may not allow it to delete the record, and it will be + delete-marked. Eventually purge_sys.view would advance, + but the delete-marked record could never be removed, + because no undo log record was ever added to + the purge queue by trx_purge_add_undo_to_history(). + + For now, we will not flag an error about orphan secondary index + records that are delete-marked; we will only warn about them. */ + + if (!rec_deleted || prebuilt->autoinc_error == DB_SUCCESS) + { + ib::error_or_warn w(!rec_deleted); + w << "Clustered index record not found for index " + << index->name << " of table " << index->table->name + << ": " << rec_offsets_print(rec, offsets); + push_warning_printf(prebuilt->trx->mysql_thd, + Sql_condition::WARN_LEVEL_WARN, + ER_NOT_KEYFILE, "InnoDB: %s", + w.m_oss.str().c_str()); + } + + if (prebuilt->autoinc_error == DB_SUCCESS) + prebuilt->autoinc_error= rec_deleted + ? DB_MISSING_HISTORY + : DB_CORRUPTION; + } + else if (&view == &check_table_extended_view) + extended_not_found: + if (view.changes_visible(page_trx_id)) + goto not_found; + did_not_find: + mtr.rollback_to_savepoint(savepoint); + goto next_rec; + } + + rec_offs *clust_offsets; + trx_id_t rec_trx_id; + rec_t *old_vers= nullptr; + + bool found_in_view= false; + trx_id_t visible_trx_id= ~0ULL; + + if (ulint trx_id_offset= clust_index->trx_id_offset) + { + clust_offsets= nullptr; + read_trx_id: + rec_trx_id= trx_read_trx_id(clust_rec + trx_id_offset); + + if (clust_rec[trx_id_offset + DATA_TRX_ID_LEN] & 0x80) + { + if (UNIV_UNLIKELY + (rec_get_deleted_flag(clust_rec, + prebuilt->table->not_redundant()))) + { + err= DB_CORRUPTION; + goto func_exit; + } + + /* This is the oldest available record version (fresh insert). */ + if (!view.changes_visible(rec_trx_id)) + { + if (rec_trx_id >= view.low_limit_id() && + UNIV_UNLIKELY(rec_trx_id >= trx_sys.get_max_trx_id())) + goto invalid_rec_trx_id; + if (got_extended_match) + goto check_latest_version; + goto did_not_find; + } + } + } + else + { + clust_offsets= rec_get_offsets(clust_rec, clust_index, nullptr, + clust_index->n_core_fields, + ULINT_UNDEFINED, &heap); + ulint trx_id_pos= clust_index->n_uniq ? clust_index->n_uniq : 1; + ulint len; + trx_id_offset= rec_get_nth_field_offs(clust_offsets, trx_id_pos, &len); + ut_ad(len == DATA_TRX_ID_LEN); + goto read_trx_id; + } + + if (got_extended_match) + { + check_latest_version: + /* In CHECK TABLE...EXTENDED, always check if the secondary + index record matches the latest clustered index record + version, no matter if it is visible in our own read view. + + If the latest clustered index version is delete-marked and + purgeable, it is not safe to fetch any BLOBs for column prefix + indexes because they may already have been freed. */ + if (rec_trx_id && + rec_get_deleted_flag(clust_rec, + prebuilt->table->not_redundant()) && + purge_sys.is_purgeable(rec_trx_id)) + goto did_not_find; + + if (!clust_offsets) + clust_offsets= rec_get_offsets(clust_rec, clust_index, nullptr, + clust_index->n_core_fields, + ULINT_UNDEFINED, &heap); + err= row_check_index_match(prebuilt, + clust_rec, clust_index, clust_offsets, + rec, index, offsets); + + switch (err) { + default: + goto func_exit; + case DB_SUCCESS_LOCKED_REC: + case DB_SUCCESS: + break; + } + + got_extended_match= err == DB_SUCCESS; + err= DB_SUCCESS; + + if (!prebuilt->trx->read_view.changes_visible(rec_trx_id)) + /* While CHECK TABLE ... EXTENDED checks for a matching + clustered index record version for each secondary index + record, it must count only those records that belong to its + own read view. + + If the latest version of clust_rec matches rec but is not + in our read view, there may still be an older version of + clust_rec that not only matches rec but is in our view. + We must evaluate old versions before deciding whether rec + should be counted. */ + goto check_old_vers; + + /* Remember that this is the visible clust_rec for rec, + and whether it matches rec. */ + visible_trx_id= rec_trx_id; + found_in_view= got_extended_match && + !rec_get_deleted_flag(clust_rec, + prebuilt->table->not_redundant()); + + if (!got_extended_match) + goto check_old_vers; + + if (!found_in_view) + goto did_not_find; + + found_match: + mtr.rollback_to_savepoint(savepoint); + goto count_row; + } + else if (!view.changes_visible(rec_trx_id)) + { + check_old_vers: + if (rec_trx_id >= view.low_limit_id() && + UNIV_UNLIKELY(rec_trx_id >= trx_sys.get_max_trx_id())) + { + invalid_rec_trx_id: + if (prebuilt->autoinc_error == DB_SUCCESS) + push_warning_printf(prebuilt->trx->mysql_thd, + Sql_condition::WARN_LEVEL_WARN, + ER_NOT_KEYFILE, + "InnoDB: DB_TRX_ID=" TRX_ID_FMT + " exceeds the system-wide maximum", + rec_trx_id); + goto not_found; + } + + if (!clust_offsets) + clust_offsets= rec_get_offsets(clust_rec, clust_index, nullptr, + clust_index->n_core_fields, + ULINT_UNDEFINED, &heap); + + row_sel_reset_old_vers_heap(prebuilt); + /* The following is adapted from row_vers_build_for_consistent_read() + because when using check_table_extended_view, we must + consider every available version of the clustered index record. */ + mem_heap_t *vers_heap= nullptr; + + for (;;) + { + mem_heap_t *prev_heap= vers_heap; + vers_heap= mem_heap_create(1024); + err= trx_undo_prev_version_build(clust_rec, + clust_index, clust_offsets, + vers_heap, &old_vers, + nullptr, nullptr, 0); + if (prev_heap) + mem_heap_free(prev_heap); + if (err != DB_SUCCESS) + { + old_vers_err: + mem_heap_free(vers_heap); + if (err == DB_MISSING_HISTORY) + { + err= DB_SUCCESS; + if (got_extended_match) + goto did_not_find; + goto not_found; + } + goto func_exit; + } + + if (UNIV_UNLIKELY(!old_vers)) + { + mem_heap_free(vers_heap); + /* We did not find a matching clustered index record version + for the secondary index record. Normal CHECK TABLE will simply + not count the secondary index record; CHECK TABLE ... EXTENDED + will flag such orphan records if appropriate. + + A secondary index record may may be "temporarily orphan" + if purge is in progress. We will only flag them if + everything up to PAGE_MAX_TRX_ID has been fully purged. + + "Temporary orphans" may be produced when + row_undo_mod_clust() resets the DB_TRX_ID of the latest + clust_rec version or when trx_undo_prev_version_build() + encounters a BLOB that may have been freed according to + purge_sys.view (not purge_sys.end_view). */ + if (&view == &check_table_extended_view && !got_extended_match) + goto extended_not_found; + goto did_not_find; + } + + clust_rec= old_vers; + clust_offsets= rec_get_offsets(clust_rec, clust_index, clust_offsets, + clust_index->n_core_fields, + ULINT_UNDEFINED, &heap); + + rec_trx_id= row_get_rec_trx_id(clust_rec, clust_index, + clust_offsets); + + if (UNIV_UNLIKELY(rec_trx_id >= + prebuilt->trx->read_view.low_limit_id() && + rec_trx_id >= trx_sys.get_max_trx_id())) + { + mem_heap_free(vers_heap); + goto invalid_rec_trx_id; + } + + const bool rec_visible= + prebuilt->trx->read_view.changes_visible(rec_trx_id); + const bool clust_rec_deleted= + rec_get_deleted_flag(clust_rec, prebuilt->table->not_redundant()); + + if (&view != &prebuilt->trx->read_view) + { + /* It is not safe to fetch BLOBs of committed delete-marked + records that may have been freed in purge. */ + err= clust_rec_deleted && rec_trx_id && + purge_sys.is_purgeable(rec_trx_id) + ? DB_SUCCESS_LOCKED_REC + : row_check_index_match(prebuilt, + clust_rec, clust_index, clust_offsets, + rec, index, offsets); + + switch (err) { + default: + goto old_vers_err; + case DB_SUCCESS_LOCKED_REC: + if (rec_visible && !~visible_trx_id) + visible_trx_id= rec_trx_id; + continue; + case DB_SUCCESS: + got_extended_match= true; + if (!rec_visible) + continue; + if (!~visible_trx_id) + { + visible_trx_id= rec_trx_id; + found_in_view= !clust_rec_deleted; + } + mem_heap_free(vers_heap); + if (!found_in_view) + goto did_not_find; + goto found_match; + } + } + else if (rec_visible) + { + if (!clust_rec_deleted) + { + clust_rec= rec_copy(mem_heap_alloc(heap, + rec_offs_size(clust_offsets)), + clust_rec, clust_offsets); + rec_offs_make_valid(clust_rec, clust_index, true, clust_offsets); + } + mem_heap_free(vers_heap); + if (clust_rec_deleted) + goto did_not_find; + goto check_match; + } + } + } + else if (rec_get_deleted_flag(clust_rec, + prebuilt->table->not_redundant())) + goto did_not_find; + + ut_ad(clust_rec); + ut_ad(&view != &check_table_extended_view); + + /* If we had to go to an earlier version of row or the secondary + index record is delete marked, then it may be that the secondary + index record corresponding to clust_rec (or old_vers) is not + rec; in that case we must ignore such row because in our + snapshot rec would not have existed. Remember that from rec we + cannot see directly which transaction id corresponds to it: we + have to go to the clustered index record. A query where we want + to fetch all rows where the secondary index value is in some + interval would return a wrong result if we would not drop rows + which we come to visit through secondary index records that + would not really exist in our snapshot. */ + + if (rec_deleted) + { + if (!clust_offsets) + clust_offsets= rec_get_offsets(clust_rec, clust_index, nullptr, + clust_index->n_core_fields, + ULINT_UNDEFINED, &heap); + check_match: + /* This clustered index record version exists in + prebuilt->trx->read_view and is not delete-marked. + By design, any BLOBs in it are not allowed to be + freed in the purge of committed transaction history. */ + err= row_check_index_match(prebuilt, clust_rec, clust_index, + clust_offsets, rec, index, offsets); + switch (err) { + case DB_SUCCESS: + break; + case DB_SUCCESS_LOCKED_REC: + err= DB_SUCCESS; + goto did_not_find; + default: + goto func_exit; + } + } + + mtr.rollback_to_savepoint(savepoint); + } + } + else + { + invalid_PAGE_MAX_TRX_ID: + if (UNIV_LIKELY(srv_force_recovery < SRV_FORCE_NO_UNDO_LOG_SCAN)) + { + push_warning_printf(prebuilt->trx->mysql_thd, + Sql_condition::WARN_LEVEL_WARN, ER_NOT_KEYFILE, + "InnoDB: Invalid PAGE_MAX_TRX_ID=%llu" + " in index '%-.200s'", + page_trx_id, index->name()); + prebuilt->autoinc_error= DB_INDEX_CORRUPT; + } + goto next_rec; + } + +count_row: + ++*n_rows; + + if (prev_entry) + { + ulint matched_fields= 0; + int cmp= cmp_dtuple_rec_with_match(prev_entry, rec, offsets, + &matched_fields); + const char* msg; + + if (UNIV_LIKELY(cmp < 0)); + else if (cmp > 0) + { + prebuilt->autoinc_error= DB_INDEX_CORRUPT; + msg= "index records in a wrong order in "; +not_ok: + ib::error() << msg << index->name << " of table " << index->table->name + << ": " << *prev_entry << ", " + << rec_offsets_print(rec, offsets); + } + else if (index->is_unique() && matched_fields >= + dict_index_get_n_ordering_defined_by_user(index)) + { + /* NULL values in unique indexes are considered not to be duplicates */ + for (ulint i= 0; i < dict_index_get_n_ordering_defined_by_user(index); + i++) + if (dfield_is_null(dtuple_get_nth_field(prev_entry, i))) + goto next_rec; + + if (prebuilt->autoinc_error == DB_SUCCESS) + prebuilt->autoinc_error= DB_DUPLICATE_KEY; + msg= "duplicate key in "; + goto not_ok; + } + } + +next_rec: + ut_ad(err == DB_SUCCESS); + + { + mem_heap_t *tmp_heap= nullptr; + + /* Empty the heap on each round. But preserve offsets[] + for the row_rec_to_index_entry() call, by copying them + into a separate memory heap when needed. */ + if (UNIV_UNLIKELY(offsets != offsets_)) + { + ulint size= rec_offs_get_n_alloc(offsets) * sizeof *offsets; + tmp_heap= mem_heap_create(size); + offsets= static_cast(mem_heap_dup(tmp_heap, offsets, size)); + } + + mem_heap_empty(heap); + prev_entry= row_rec_to_index_entry(rec, index, offsets, heap); + + if (UNIV_LIKELY_NULL(tmp_heap)) + mem_heap_free(tmp_heap); + } + + if (btr_pcur_is_after_last_on_page(prebuilt->pcur)) + goto next_page; + + goto rec_loop; +} + /*******************************************************************//** Read the AUTOINC column from the current row. If the value is less than 0 and the type is not unsigned then we reset the value to 0. diff --git a/storage/innobase/row/row0umod.cc b/storage/innobase/row/row0umod.cc index 91925219ea8..cca44f01920 100644 --- a/storage/innobase/row/row0umod.cc +++ b/storage/innobase/row/row0umod.cc @@ -216,26 +216,23 @@ static ulint row_trx_id_offset(const rec_t* rec, const dict_index_t* index) } /** Determine if rollback must execute a purge-like operation. -@param[in,out] node row undo -@param[in,out] mtr mini-transaction +@param node row undo @return whether the record should be purged */ -static bool row_undo_mod_must_purge(undo_node_t* node, mtr_t* mtr) +static bool row_undo_mod_must_purge(const undo_node_t &node) { - ut_ad(node->rec_type == TRX_UNDO_UPD_DEL_REC); - ut_ad(!node->table->is_temporary()); + ut_ad(node.rec_type == TRX_UNDO_UPD_DEL_REC); + ut_ad(!node.table->is_temporary()); - btr_cur_t* btr_cur = btr_pcur_get_btr_cur(&node->pcur); - ut_ad(btr_cur->index->is_primary()); - DEBUG_SYNC_C("rollback_purge_clust"); + const btr_cur_t &btr_cur= node.pcur.btr_cur; + ut_ad(btr_cur.index->is_primary()); + DEBUG_SYNC_C("rollback_purge_clust"); - if (!purge_sys.changes_visible(node->new_trx_id, node->table->name)) { - return false; - } + if (!purge_sys.is_purgeable(node.new_trx_id)) + return false; - const rec_t* rec = btr_cur_get_rec(btr_cur); - - return trx_read_trx_id(rec + row_trx_id_offset(rec, btr_cur->index)) - == node->new_trx_id; + const rec_t *rec= btr_cur_get_rec(&btr_cur); + return trx_read_trx_id(rec + row_trx_id_offset(rec, btr_cur.index)) == + node.new_trx_id; } /***********************************************************//** @@ -251,7 +248,6 @@ row_undo_mod_clust( { btr_pcur_t* pcur; mtr_t mtr; - bool have_latch = false; dberr_t err; dict_index_t* index; @@ -347,9 +343,7 @@ row_undo_mod_clust( btr_pcur_commit_specify_mtr(pcur, &mtr); } else { index->set_modified(mtr); - have_latch = true; - purge_sys.latch.rd_lock(SRW_LOCK_CALL); - if (!row_undo_mod_must_purge(node, &mtr)) { + if (!row_undo_mod_must_purge(*node)) { goto mtr_commit_exit; } err = btr_cur_optimistic_delete(&pcur->btr_cur, 0, @@ -358,9 +352,7 @@ row_undo_mod_clust( goto mtr_commit_exit; } err = DB_SUCCESS; - purge_sys.latch.rd_unlock(); btr_pcur_commit_specify_mtr(pcur, &mtr); - have_latch = false; } mtr.start(); @@ -376,9 +368,7 @@ row_undo_mod_clust( if (index->table->is_temporary()) { mtr.set_log_mode(MTR_LOG_NO_REDO); } else { - have_latch = true; - purge_sys.latch.rd_lock(SRW_LOCK_CALL); - if (!row_undo_mod_must_purge(node, &mtr)) { + if (!row_undo_mod_must_purge(*node)) { goto mtr_commit_exit; } index->set_modified(mtr); @@ -400,17 +390,12 @@ row_undo_mod_clust( mtr.start(); if (pcur->restore_position(BTR_MODIFY_LEAF, &mtr) - != btr_pcur_t::SAME_ALL) { - goto mtr_commit_exit; - } - rec_t* rec = btr_pcur_get_rec(pcur); - have_latch = true; - purge_sys.latch.rd_lock(SRW_LOCK_CALL); - if (!purge_sys.changes_visible(node->new_trx_id, - node->table->name)) { + != btr_pcur_t::SAME_ALL + || !purge_sys.is_purgeable(node->new_trx_id)) { goto mtr_commit_exit; } + rec_t* rec = btr_pcur_get_rec(pcur); ulint trx_id_offset = index->trx_id_offset; ulint trx_id_pos = index->n_uniq ? index->n_uniq : 1; /* Reserve enough offsets for the PRIMARY KEY and @@ -477,10 +462,6 @@ row_undo_mod_clust( } mtr_commit_exit: - if (have_latch) { - purge_sys.latch.rd_unlock(); - } - btr_pcur_commit_specify_mtr(pcur, &mtr); func_exit: diff --git a/storage/innobase/row/row0upd.cc b/storage/innobase/row/row0upd.cc index 61ac22ca27a..26c434ca474 100644 --- a/storage/innobase/row/row0upd.cc +++ b/storage/innobase/row/row0upd.cc @@ -469,46 +469,6 @@ row_upd_changes_field_size_or_external( return(FALSE); } -/***********************************************************//** -Returns true if row update contains disowned external fields. -@return true if the update contains disowned external fields. */ -bool -row_upd_changes_disowned_external( -/*==============================*/ - const upd_t* update) /*!< in: update vector */ -{ - const upd_field_t* upd_field; - const dfield_t* new_val; - ulint new_len; - ulint n_fields; - ulint i; - - n_fields = upd_get_n_fields(update); - - for (i = 0; i < n_fields; i++) { - const byte* field_ref; - - upd_field = upd_get_nth_field(update, i); - new_val = &(upd_field->new_val); - new_len = dfield_get_len(new_val); - - if (!dfield_is_ext(new_val)) { - continue; - } - - ut_ad(new_len >= BTR_EXTERN_FIELD_REF_SIZE); - - field_ref = static_cast(dfield_get_data(new_val)) - + new_len - BTR_EXTERN_FIELD_REF_SIZE; - - if (field_ref[BTR_EXTERN_LEN] & BTR_EXTERN_OWNER_FLAG) { - return(true); - } - } - - return(false); -} - /***************************************************************//** Builds an update vector from those fields which in a secondary index entry differ from a record that has the equal ordering fields. NOTE: we compare diff --git a/storage/innobase/row/row0vers.cc b/storage/innobase/row/row0vers.cc index 04cf9640f05..372d30149f0 100644 --- a/storage/innobase/row/row0vers.cc +++ b/storage/innobase/row/row0vers.cc @@ -1,7 +1,7 @@ /***************************************************************************** Copyright (c) 1997, 2017, Oracle and/or its affiliates. All Rights Reserved. -Copyright (c) 2017, 2021, MariaDB Corporation. +Copyright (c) 2017, 2022, 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 @@ -104,6 +104,9 @@ row_vers_impl_x_locked_low( DBUG_ENTER("row_vers_impl_x_locked_low"); ut_ad(rec_offs_validate(rec, index, offsets)); + ut_ad(mtr->memo_contains_page_flagged(clust_rec, + MTR_MEMO_PAGE_S_FIX + | MTR_MEMO_PAGE_X_FIX)); if (ulint trx_id_offset = clust_index->trx_id_offset) { trx_id = mach_read_from_6(clust_rec + trx_id_offset); @@ -190,7 +193,7 @@ row_vers_impl_x_locked_low( heap = mem_heap_create(1024); trx_undo_prev_version_build( - clust_rec, mtr, version, clust_index, clust_offsets, + version, clust_index, clust_offsets, heap, &prev_version, NULL, dict_index_has_virtual(index) ? &vrow : NULL, 0); @@ -527,6 +530,10 @@ row_vers_build_cur_vrow_low( = DATA_MISSING; } + ut_ad(mtr->memo_contains_page_flagged(rec, + MTR_MEMO_PAGE_S_FIX + | MTR_MEMO_PAGE_X_FIX)); + version = rec; /* If this is called by purge thread, set TRX_UNDO_PREV_IN_PURGE @@ -543,7 +550,7 @@ row_vers_build_cur_vrow_low( version, clust_index, clust_offsets); trx_undo_prev_version_build( - rec, mtr, version, clust_index, clust_offsets, + version, clust_index, clust_offsets, heap, &prev_version, NULL, vrow, status); if (heap2) { @@ -643,6 +650,10 @@ row_vers_vc_matches_cluster( /* First compare non-virtual columns (primary keys) */ ut_ad(index->n_fields == n_fields); ut_ad(n_fields == dtuple_get_n_fields(icentry)); + ut_ad(mtr->memo_contains_page_flagged(rec, + MTR_MEMO_PAGE_S_FIX + | MTR_MEMO_PAGE_X_FIX)); + { const dfield_t* a = ientry->fields; const dfield_t* b = icentry->fields; @@ -684,7 +695,7 @@ row_vers_vc_matches_cluster( ut_ad(roll_ptr != 0); trx_undo_prev_version_build( - rec, mtr, version, clust_index, clust_offsets, + version, clust_index, clust_offsets, heap, &prev_version, NULL, vrow, TRX_UNDO_PREV_IN_PURGE | TRX_UNDO_GET_OLD_V_VALUE); @@ -834,7 +845,7 @@ row_vers_build_cur_vrow( } /** Finds out if a version of the record, where the version >= the current -purge view, should have ientry as its secondary index entry. We check +purge_sys.view, should have ientry as its secondary index entry. We check if there is any not delete marked version of the record where the trx id >= purge view, and the secondary index entry == ientry; exactly in this case we return TRUE. @@ -1016,11 +1027,12 @@ unsafe_to_purge: heap = mem_heap_create(1024); vrow = NULL; - trx_undo_prev_version_build(rec, mtr, version, + trx_undo_prev_version_build(version, clust_index, clust_offsets, - heap, &prev_version, NULL, + heap, &prev_version, nullptr, dict_index_has_virtual(index) - ? &vrow : NULL, 0); + ? &vrow : nullptr, + TRX_UNDO_CHECK_PURGEABILITY); mem_heap_free(heap2); /* free version and clust_offsets */ if (!prev_version) { @@ -1099,7 +1111,9 @@ unsafe_to_purge: Constructs the version of a clustered index record which a consistent read should see. We assume that the trx id stored in rec is such that the consistent read should not see rec in its present version. -@return DB_SUCCESS or DB_MISSING_HISTORY */ +@return error code +@retval DB_SUCCESS if a previous version was fetched +@retval DB_MISSING_HISTORY if the history is missing (a sign of corruption) */ dberr_t row_vers_build_for_consistent_read( /*===============================*/ @@ -1139,7 +1153,7 @@ row_vers_build_for_consistent_read( trx_id = row_get_rec_trx_id(rec, index, *offsets); - ut_ad(!view->changes_visible(trx_id, index->table->name)); + ut_ad(!view->changes_visible(trx_id)); ut_ad(!vrow || !(*vrow)); @@ -1157,12 +1171,10 @@ row_vers_build_for_consistent_read( /* If purge can't see the record then we can't rely on the UNDO log record. */ - bool purge_sees = trx_undo_prev_version_build( - rec, mtr, version, index, *offsets, heap, + err = trx_undo_prev_version_build( + version, index, *offsets, heap, &prev_version, NULL, vrow, 0); - err = (purge_sees) ? DB_SUCCESS : DB_MISSING_HISTORY; - if (prev_heap != NULL) { mem_heap_free(prev_heap); } @@ -1184,7 +1196,7 @@ row_vers_build_for_consistent_read( trx_id = row_get_rec_trx_id(prev_version, index, *offsets); - if (view->changes_visible(trx_id, index->table->name)) { + if (view->changes_visible(trx_id)) { /* The view already sees this version: we can copy it to in_heap and return */ @@ -1201,8 +1213,11 @@ row_vers_build_for_consistent_read( dtuple_dup_v_fld(*vrow, in_heap); } break; + } else if (trx_id >= view->low_limit_id() + && trx_id >= trx_sys.get_max_trx_id()) { + err = DB_CORRUPTION; + break; } - version = prev_version; } @@ -1319,10 +1334,9 @@ committed_version_trx: heap2 = heap; heap = mem_heap_create(1024); - if (!trx_undo_prev_version_build(rec, mtr, version, index, - *offsets, heap, - &prev_version, - in_heap, vrow, 0)) { + if (trx_undo_prev_version_build(version, index, *offsets, heap, + &prev_version, in_heap, vrow, + 0) != DB_SUCCESS) { mem_heap_free(heap); heap = heap2; heap2 = NULL; diff --git a/storage/innobase/trx/trx0purge.cc b/storage/innobase/trx/trx0purge.cc index b5d00d9624f..625d3223bdc 100644 --- a/storage/innobase/trx/trx0purge.cc +++ b/storage/innobase/trx/trx0purge.cc @@ -42,10 +42,6 @@ Created 3/26/1996 Heikki Tuuri #include -#ifdef UNIV_PFS_RWLOCK -extern mysql_pfs_key_t trx_purge_latch_key; -#endif /* UNIV_PFS_RWLOCK */ - /** Maximum allowable purge history length. <=0 means 'infinite'. */ ulong srv_max_purge_lag = 0; @@ -184,6 +180,7 @@ void purge_sys_t::create() hdr_page_no= 0; hdr_offset= 0; latch.SRW_LOCK_INIT(trx_purge_latch_key); + end_latch.init(); mysql_mutex_init(purge_sys_pq_mutex_key, &pq_mutex, nullptr); truncate.current= NULL; truncate.last= NULL; @@ -205,11 +202,40 @@ void purge_sys_t::close() trx->state= TRX_STATE_NOT_STARTED; trx->free(); latch.destroy(); + end_latch.destroy(); mysql_mutex_destroy(&pq_mutex); mem_heap_free(heap); heap= nullptr; } +/** Determine if the history of a transaction is purgeable. +@param trx_id transaction identifier +@return whether the history is purgeable */ +TRANSACTIONAL_TARGET bool purge_sys_t::is_purgeable(trx_id_t trx_id) const +{ + bool purgeable; +#if !defined SUX_LOCK_GENERIC && !defined NO_ELISION + purgeable= false; + if (xbegin()) + { + if (!latch.is_write_locked()) + { + purgeable= view.changes_visible(trx_id); + xend(); + } + else + xabort(); + } + else +#endif + { + latch.rd_lock(SRW_LOCK_CALL); + purgeable= view.changes_visible(trx_id); + latch.rd_unlock(); + } + return purgeable; +} + /*================ UNDO LOG HISTORY LIST =============================*/ /** Prepend the history list with an undo log. @@ -1199,7 +1225,6 @@ trx_purge_attach_undo_recs(ulint n_purge_threads) i = 0; - const ulint batch_size = srv_purge_batch_size; std::unordered_map table_id_map; mem_heap_empty(purge_sys.heap); @@ -1251,7 +1276,7 @@ trx_purge_attach_undo_recs(ulint n_purge_threads) node->undo_recs.push(purge_rec); - if (n_pages_handled >= batch_size) { + if (n_pages_handled >= srv_purge_batch_size) { break; } } @@ -1303,14 +1328,14 @@ extern tpool::waitable_task purge_worker_task; /** Wait for pending purge jobs to complete. */ static void trx_purge_wait_for_workers_to_complete() { - bool notify_wait = purge_worker_task.is_running(); + const bool notify_wait{purge_worker_task.is_running()}; if (notify_wait) - tpool::tpool_wait_begin(); + tpool::tpool_wait_begin(); purge_worker_task.wait(); - if(notify_wait) + if (notify_wait) tpool::tpool_wait_end(); /* There should be no outstanding tasks as long @@ -1318,12 +1343,33 @@ static void trx_purge_wait_for_workers_to_complete() ut_ad(srv_get_task_queue_length() == 0); } +/** Update end_view at the end of a purge batch. */ +TRANSACTIONAL_INLINE void purge_sys_t::clone_end_view() +{ + /* This is only invoked only by the purge coordinator, + which is the only thread that can modify our inputs head, tail, view. + Therefore, we only need to protect end_view from concurrent reads. */ + + /* Limit the end_view similar to what trx_purge_truncate_history() does. */ + const trx_id_t trx_no= head.trx_no ? head.trx_no : tail.trx_no; +#ifdef SUX_LOCK_GENERIC + end_latch.wr_lock(); +#else + transactional_lock_guard g(end_latch); +#endif + end_view= view; + end_view.clamp_low_limit_id(trx_no); +#ifdef SUX_LOCK_GENERIC + end_latch.wr_unlock(); +#endif +} + /** Run a purge batch. @param n_tasks number of purge tasks to submit to the queue @param truncate whether to truncate the history at the end of the batch @return number of undo log pages handled in the batch */ -ulint trx_purge(ulint n_tasks, bool truncate) +TRANSACTIONAL_TARGET ulint trx_purge(ulint n_tasks, bool truncate) { que_thr_t* thr = NULL; ulint n_pages_handled; @@ -1357,6 +1403,8 @@ ulint trx_purge(ulint n_tasks, bool truncate) trx_purge_wait_for_workers_to_complete(); + purge_sys.clone_end_view(); + if (truncate) { trx_purge_truncate_history(); } diff --git a/storage/innobase/trx/trx0rec.cc b/storage/innobase/trx/trx0rec.cc index 766b7da1543..dc24f083d05 100644 --- a/storage/innobase/trx/trx0rec.cc +++ b/storage/innobase/trx/trx0rec.cc @@ -2069,51 +2069,49 @@ trx_undo_get_undo_rec_low( return undo_rec; } -/** Copy an undo record to heap. -@param[in] roll_ptr roll pointer to record -@param[in,out] heap memory heap where copied -@param[in] trx_id id of the trx that generated - the roll pointer: it points to an - undo log of this transaction -@param[in] name table name -@param[out] undo_rec own: copy of the record -@retval true if the undo log has been -truncated and we cannot fetch the old version -@retval false if the undo log record is available -NOTE: the caller must have latches on the clustered index page. */ -static MY_ATTRIBUTE((warn_unused_result)) -bool -trx_undo_get_undo_rec( - roll_ptr_t roll_ptr, - mem_heap_t* heap, - trx_id_t trx_id, - const table_name_t& name, - trx_undo_rec_t** undo_rec) +/** Copy an undo record to heap, to check if a secondary index record +can be safely purged. +@param trx_id DB_TRX_ID corresponding to roll_ptr +@param name table name +@param roll_ptr DB_ROLL_PTR pointing to the undo log record +@param heap memory heap for allocation +@return copy of the record +@retval nullptr if the version is visible to purge_sys.view */ +static trx_undo_rec_t *trx_undo_get_rec_if_purgeable(trx_id_t trx_id, + const table_name_t &name, + roll_ptr_t roll_ptr, + mem_heap_t* heap) { - purge_sys.latch.rd_lock(SRW_LOCK_CALL); - - bool missing_history = purge_sys.changes_visible(trx_id, name); - if (!missing_history) { - *undo_rec = trx_undo_get_undo_rec_low(roll_ptr, heap); - missing_history = !*undo_rec; - } - - purge_sys.latch.rd_unlock(); - - return missing_history; + { + purge_sys_t::view_guard check; + if (!check.view().changes_visible(trx_id)) + return trx_undo_get_undo_rec_low(roll_ptr, heap); + } + return nullptr; } -#ifdef UNIV_DEBUG -#define ATTRIB_USED_ONLY_IN_DEBUG -#else /* UNIV_DEBUG */ -#define ATTRIB_USED_ONLY_IN_DEBUG MY_ATTRIBUTE((unused)) -#endif /* UNIV_DEBUG */ +/** Copy an undo record to heap. +@param trx_id DB_TRX_ID corresponding to roll_ptr +@param name table name +@param roll_ptr DB_ROLL_PTR pointing to the undo log record +@param heap memory heap for allocation +@return copy of the record +@retval nullptr if the undo log is not available */ +static trx_undo_rec_t *trx_undo_get_undo_rec(trx_id_t trx_id, + const table_name_t &name, + roll_ptr_t roll_ptr, + mem_heap_t *heap) +{ + { + purge_sys_t::end_view_guard check; + if (!check.view().changes_visible(trx_id)) + return trx_undo_get_undo_rec_low(roll_ptr, heap); + } + return nullptr; +} /** Build a previous version of a clustered index record. The caller must hold a latch on the index page of the clustered index record. -@param index_rec clustered index record in the index tree -@param index_mtr mtr which contains the latch to index_rec page - and purge_view @param rec version of a clustered index record @param index clustered index @param offsets rec_get_offsets(rec, index) @@ -2134,14 +2132,13 @@ must hold a latch on the index page of the clustered index record. And if we read "after image" of undo log @param undo_block undo log block which was cached during online dml apply or nullptr -@retval true if previous version was built, or if it was an insert -or the table has been rebuilt -@retval false if the previous version is earlier than purge_view, -or being purged, which means that it may have been removed */ -bool +@return error code +@retval DB_SUCCESS if previous version was successfully built, +or if it was an insert or the undo record refers to the table before rebuild +@retval DB_MISSING_HISTORY if the history is missing */ +TRANSACTIONAL_TARGET +dberr_t trx_undo_prev_version_build( - const rec_t *index_rec ATTRIB_USED_ONLY_IN_DEBUG, - mtr_t *index_mtr ATTRIB_USED_ONLY_IN_DEBUG, const rec_t *rec, dict_index_t *index, rec_offs *offsets, @@ -2151,7 +2148,6 @@ trx_undo_prev_version_build( dtuple_t **vrow, ulint v_status) { - trx_undo_rec_t* undo_rec = NULL; dtuple_t* entry; trx_id_t rec_trx_id; ulint type; @@ -2166,11 +2162,7 @@ trx_undo_prev_version_build( byte* buf; ut_ad(!index->table->is_temporary()); - ut_ad(index_mtr->memo_contains_page_flagged(index_rec, - MTR_MEMO_PAGE_S_FIX - | MTR_MEMO_PAGE_X_FIX)); ut_ad(rec_offs_validate(rec, index, offsets)); - ut_a(index->is_primary()); roll_ptr = row_get_rec_roll_ptr(rec, index, offsets); @@ -2178,27 +2170,20 @@ trx_undo_prev_version_build( if (trx_undo_roll_ptr_is_insert(roll_ptr)) { /* The record rec is the first inserted version */ - return(true); + return DB_SUCCESS; } rec_trx_id = row_get_rec_trx_id(rec, index, offsets); ut_ad(!index->table->skip_alter_undo); - if (trx_undo_get_undo_rec( - roll_ptr, heap, rec_trx_id, index->table->name, - &undo_rec)) { - if (v_status & TRX_UNDO_PREV_IN_PURGE) { - /* We are fetching the record being purged */ - undo_rec = trx_undo_get_undo_rec_low(roll_ptr, heap); - if (!undo_rec) { - return false; - } - } else { - /* The undo record may already have been purged, - during purge or semi-consistent read. */ - return(false); - } + trx_undo_rec_t* undo_rec = v_status == TRX_UNDO_CHECK_PURGEABILITY + ? trx_undo_get_rec_if_purgeable(rec_trx_id, index->table->name, + roll_ptr, heap) + : trx_undo_get_undo_rec(rec_trx_id, index->table->name, + roll_ptr, heap); + if (!undo_rec) { + return DB_MISSING_HISTORY; } const byte *ptr = @@ -2209,7 +2194,7 @@ trx_undo_prev_version_build( /* The table should have been rebuilt, but purge has not yet removed the undo log records for the now-dropped old table (table_id). */ - return(true); + return DB_SUCCESS; } ptr = trx_undo_update_rec_get_sys_cols(ptr, &trx_id, &roll_ptr, @@ -2257,24 +2242,9 @@ trx_undo_prev_version_build( delete-marked record by trx_id, no transactions need to access the BLOB. */ - /* the row_upd_changes_disowned_external(update) call could be - omitted, but the synchronization on purge_sys.latch is likely - more expensive. */ - - if ((update->info_bits & REC_INFO_DELETED_FLAG) - && row_upd_changes_disowned_external(update)) { - purge_sys.latch.rd_lock(SRW_LOCK_CALL); - - bool missing_extern = purge_sys.changes_visible( - trx_id, index->table->name); - - purge_sys.latch.rd_unlock(); - - if (missing_extern) { - /* treat as a fresh insert, not to - cause assertion error at the caller. */ - return(true); - } + if (update->info_bits & REC_INFO_DELETED_FLAG + && purge_sys.is_purgeable(trx_id)) { + return DB_SUCCESS; } /* We have to set the appropriate extern storage bits in the @@ -2289,8 +2259,8 @@ trx_undo_prev_version_build( following call is safe. */ if (!row_upd_index_replace_new_col_vals(entry, *index, update, heap)) { - ut_a(v_status & TRX_UNDO_PREV_IN_PURGE); - return false; + return (v_status & TRX_UNDO_PREV_IN_PURGE) + ? DB_MISSING_HISTORY : DB_CORRUPTION; } /* Get number of externally stored columns in updated record */ @@ -2387,7 +2357,7 @@ trx_undo_prev_version_build( v_status & TRX_UNDO_PREV_IN_PURGE); } - return(true); + return DB_SUCCESS; } /** Read virtual column value from undo log diff --git a/storage/innobase/trx/trx0sys.cc b/storage/innobase/trx/trx0sys.cc index 2479e5a4cc1..d344f3a0c83 100644 --- a/storage/innobase/trx/trx0sys.cc +++ b/storage/innobase/trx/trx0sys.cc @@ -44,40 +44,6 @@ Created 3/26/1996 Heikki Tuuri /** The transaction system */ trx_sys_t trx_sys; -/** Check whether transaction id is valid. -@param[in] id transaction id to check -@param[in] name table name */ -void -ReadViewBase::check_trx_id_sanity( - trx_id_t id, - const table_name_t& name) -{ - if (id >= trx_sys.get_max_trx_id()) { - - ib::warn() << "A transaction id" - << " in a record of table " - << name - << " is newer than the" - << " system-wide maximum."; - ut_ad(0); - THD *thd = current_thd; - if (thd != NULL) { - char table_name[MAX_FULL_NAME_LEN + 1]; - - innobase_format_name( - table_name, sizeof(table_name), - name.m_name); - - push_warning_printf(thd, Sql_condition::WARN_LEVEL_WARN, - ER_SIGNAL_WARN, - "InnoDB: Transaction id" - " in a record of table" - " %s is newer than system-wide" - " maximum.", table_name); - } - } -} - #ifdef UNIV_DEBUG /* Flag to control TRX_RSEG_N_SLOTS behavior debugging. */ uint trx_rseg_n_slots_debug = 0; diff --git a/storage/innobase/trx/trx0trx.cc b/storage/innobase/trx/trx0trx.cc index 111f8fe5f3a..f9fe2c19fe1 100644 --- a/storage/innobase/trx/trx0trx.cc +++ b/storage/innobase/trx/trx0trx.cc @@ -785,7 +785,7 @@ corrupted: ib::info() << "Trx id counter is " << trx_sys.get_max_trx_id(); } - purge_sys.clone_oldest_view(); + purge_sys.clone_oldest_view(); return DB_SUCCESS; } @@ -2168,6 +2168,7 @@ trx_set_rw_mode( ut_ad(trx->rsegs.m_redo.rseg != 0); trx_sys.register_rw(trx); + ut_ad(trx->id); /* So that we can see our own changes. */ if (trx->read_view.is_open()) { From 7afc6ee8bcd4139248a860a25894efe0f5829746 Mon Sep 17 00:00:00 2001 From: Daniel Black Date: Fri, 23 Sep 2022 18:28:12 +1000 Subject: [PATCH 27/72] MDEV-29615 mtr to use mariadb names --- mysql-test/main/bug47671.test | 2 +- mysql-test/main/mysqladmin.result | 4 +- mysql-test/main/mysqladmin.test | 4 +- mysql-test/main/mysqlbinlog.result | 4 +- mysql-test/main/mysqlbinlog.test | 4 +- mysql-test/main/mysqldump-no-binlog.result | 2 +- mysql-test/main/mysqldump-no-binlog.test | 2 +- mysql-test/main/mysqldump.result | 82 +++++++++++----------- mysql-test/main/mysqldump.test | 69 +++++++++--------- mysql-test/main/openssl_1.result | 2 +- mysql-test/main/openssl_1.test | 2 +- mysql-test/main/ssl_crl_clients.result | 4 +- mysql-test/main/ssl_crl_clients.test | 4 +- mysql-test/mysql-test-run.pl | 44 ++++++------ 14 files changed, 115 insertions(+), 114 deletions(-) diff --git a/mysql-test/main/bug47671.test b/mysql-test/main/bug47671.test index c3f66a9f502..db8d64c6f60 100644 --- a/mysql-test/main/bug47671.test +++ b/mysql-test/main/bug47671.test @@ -5,5 +5,5 @@ --echo # Bug#47671 - wrong character-set after upgrade from 5.1.34 to 5.1.39 --echo # --echo # Extract only charset information from 'status' command output using regex ---replace_regex /.*mysql.*// /Connection.*// /Current.*// /SSL.*// /Using.*// /Server version.*// /Protocol.*// /UNIX.*// /Uptime.*// /Threads.*// /TCP.*// +--replace_regex /.*mariadb.*// /Connection.*// /Current.*// /SSL.*// /Using.*// /Server version.*// /Protocol.*// /UNIX.*// /Uptime.*// /Threads.*// /TCP.*// --exec $MYSQL -e "status"; diff --git a/mysql-test/main/mysqladmin.result b/mysql-test/main/mysqladmin.result index 8a9b009946b..8aac6cc59ae 100644 --- a/mysql-test/main/mysqladmin.result +++ b/mysql-test/main/mysqladmin.result @@ -1,6 +1,6 @@ mysqld is alive -mysqladmin: unknown variable 'database=db1' -Warning: mysqladmin: unknown variable 'loose-database=db2' +mariadb-admin: unknown variable 'database=db1' +Warning: mariadb-admin: unknown variable 'loose-database=db2' mysqld is alive # # Bug#58221 : mysqladmin --sleep=x --count=x keeps looping diff --git a/mysql-test/main/mysqladmin.test b/mysql-test/main/mysqladmin.test index 2580db88456..b7cc6d94628 100644 --- a/mysql-test/main/mysqladmin.test +++ b/mysql-test/main/mysqladmin.test @@ -11,13 +11,13 @@ # Bug#10608 mysqladmin breaks on "database" variable in my.cnf # ---replace_regex /.*mysqladmin.*: unknown/mysqladmin: unknown/ +--replace_regex /.*mariadb-admin.*: unknown/mariadb-admin: unknown/ --error 7 --exec $MYSQLADMIN --database=db1 --default-character-set=latin1 -S $MASTER_MYSOCK -P $MASTER_MYPORT -u root --password= ping 2>&1 # When mysqladmin finds "loose-database" it shall print # a warning and continue ---replace_regex /Warning: .*mysqladmin.*: unknown/Warning: mysqladmin: unknown/ +--replace_regex /Warning: .*mariadb-admin.*: unknown/Warning: mariadb-admin: unknown/ --exec $MYSQLADMIN --loose-database=db2 --default-character-set=latin1 -S $MASTER_MYSOCK -P $MASTER_MYPORT -u root --password= ping 2>&1 --echo # diff --git a/mysql-test/main/mysqlbinlog.result b/mysql-test/main/mysqlbinlog.result index 4edf6f8ad25..3e3d9d092e3 100644 --- a/mysql-test/main/mysqlbinlog.result +++ b/mysql-test/main/mysqlbinlog.result @@ -886,7 +886,7 @@ Alternatives are: 'NEVER','AUTO','UNSPEC','DECODE-ROWS' # # Expect error for incomplete --base64-output argument. # MYSQL_BINLOG std_data/master-bin.000001 --base64-output 2>&1 -mysqlbinlog: option '--base64-output' requires an argument +mariadb-binlog: option '--base64-output' requires an argument # # Ensure --base64-output=auto outputs the same result as unspecified # MYSQL_BINLOG -v MYSQLD_DATADIR/master-bin.000001 > MYSQLTEST_VARDIR/tmp/mysqlbinlog_nob64spec.out @@ -1267,7 +1267,7 @@ DELIMITER ; ROLLBACK /* added by mysqlbinlog */; /*!50003 SET COMPLETION_TYPE=@OLD_COMPLETION_TYPE*/; /*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=0*/; -mysqlbinlog Ver VER for OS at ARCH +mariadb-binlog Ver VER for OS at ARCH # # Test --rewrite-db # diff --git a/mysql-test/main/mysqlbinlog.test b/mysql-test/main/mysqlbinlog.test index c8a141404d0..b12709583e4 100644 --- a/mysql-test/main/mysqlbinlog.test +++ b/mysql-test/main/mysqlbinlog.test @@ -533,7 +533,7 @@ remove_file $MYSQLTEST_VARDIR/tmp/mysqlbinlog.warn; --echo # Expect error for incomplete --base64-output argument. --echo # MYSQL_BINLOG std_data/master-bin.000001 --base64-output 2>&1 # The error produces the absolute path of the mysqlbinlog executable, remove it. ---replace_regex /.*mysqlbinlog.*:/mysqlbinlog:/i +--replace_regex /.*mariadb-binlog.*:/mariadb-binlog:/i --error 1 --exec $MYSQL_BINLOG std_data/master-bin.000001 --base64-output 2>&1 @@ -608,7 +608,7 @@ eval SET GLOBAL SERVER_ID = $old_server_id; # # MDEV-12372 mysqlbinlog --version output is the same on 10.x as on 5.5.x, and contains not only version # -replace_regex /.*mysqlbinlog(\.exe)? Ver .* for .* at [-_a-zA-Z0-9]+/mysqlbinlog Ver VER for OS at ARCH/; +replace_regex /.*mariadb-binlog(\.exe)? Ver .* for .* at [-_a-zA-Z0-9]+/mariadb-binlog Ver VER for OS at ARCH/; exec $MYSQL_BINLOG --version; --echo # diff --git a/mysql-test/main/mysqldump-no-binlog.result b/mysql-test/main/mysqldump-no-binlog.result index 78bc19b7cba..223034d8401 100644 --- a/mysql-test/main/mysqldump-no-binlog.result +++ b/mysql-test/main/mysqldump-no-binlog.result @@ -1 +1 @@ -mysqldump: Error: Binlogging on server not active +mariadb-dump: Error: Binlogging on server not active diff --git a/mysql-test/main/mysqldump-no-binlog.test b/mysql-test/main/mysqldump-no-binlog.test index 5f934bc440f..0d2b2e49ded 100644 --- a/mysql-test/main/mysqldump-no-binlog.test +++ b/mysql-test/main/mysqldump-no-binlog.test @@ -2,6 +2,6 @@ --source include/not_embedded.inc --replace_regex /MASTER_LOG_POS=[0-9]+/XX/ ---replace_result mysqldump.exe mysqldump +--replace_result mariadb-dump.exe mariadb-dump --error 2 --exec $MYSQL_DUMP --compact --master-data=2 test 2>&1 diff --git a/mysql-test/main/mysqldump.result b/mysql-test/main/mysqldump.result index 87c95320b16..8e48f7d5d5d 100644 --- a/mysql-test/main/mysqldump.result +++ b/mysql-test/main/mysqldump.result @@ -1641,22 +1641,22 @@ create table t2(a varchar(30) primary key, b int not null); create table t3(a varchar(30) primary key, b int not null); test_sequence ------ Testing with illegal table names ------ -mysqldump: Couldn't find table: "\d-2-1.sql" -mysqldump: Couldn't find table: "\t1" -mysqldump: Couldn't find table: "\t1" -mysqldump: Couldn't find table: "\\t1" -mysqldump: Couldn't find table: "t\1" -mysqldump: Couldn't find table: "t\1" -mysqldump: Couldn't find table: "t/1" -mysqldump: Couldn't find table: "T_1" -mysqldump: Couldn't find table: "T%1" -mysqldump: Couldn't find table: "T'1" -mysqldump: Couldn't find table: "T_1" -mysqldump: Couldn't find table: "T_" +mariadb-dump: Couldn't find table: "\d-2-1.sql" +mariadb-dump: Couldn't find table: "\t1" +mariadb-dump: Couldn't find table: "\t1" +mariadb-dump: Couldn't find table: "\\t1" +mariadb-dump: Couldn't find table: "t\1" +mariadb-dump: Couldn't find table: "t\1" +mariadb-dump: Couldn't find table: "t/1" +mariadb-dump: Couldn't find table: "T_1" +mariadb-dump: Couldn't find table: "T%1" +mariadb-dump: Couldn't find table: "T'1" +mariadb-dump: Couldn't find table: "T_1" +mariadb-dump: Couldn't find table: "T_" test_sequence ------ Testing with illegal database names ------ -mysqldump: Got error: 1049: "Unknown database 'mysqldump_test_d'" when selecting the database -mysqldump: Got error: 1049: "Unknown database 'mysqld\ump_test_db'" when selecting the database +mariadb-dump: Got error: 1049: "Unknown database 'mysqldump_test_d'" when selecting the database +mariadb-dump: Got error: 1049: "Unknown database 'mysqld\ump_test_db'" when selecting the database drop table t1, t2, t3; drop database mysqldump_test_db; use test; @@ -1866,7 +1866,7 @@ drop table `t1`; create table t1(a int); create table t2(a int); create table t3(a int); -mysqldump: Couldn't find table: "non_existing" +mariadb-dump: Couldn't find table: "non_existing" /*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */; /*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */; @@ -1914,8 +1914,8 @@ drop table t1, t2, t3; # Bug#21288 mysqldump segmentation fault when using --where # create table t1 (a int); -mysqldump: Couldn't execute 'SELECT /*!40001 SQL_NO_CACHE */ `a` FROM `t1` WHERE xx xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx': You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx' at line 1 (1064) -mysqldump: Got error: 1064: "You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx' at line 1" when retrieving data from server +mariadb-dump: Couldn't execute 'SELECT /*!40001 SQL_NO_CACHE */ `a` FROM `t1` WHERE xx xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx': You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx' at line 1 (1064) +mariadb-dump: Got error: 1064: "You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx' at line 1" when retrieving data from server /*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */; /*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */; @@ -3444,8 +3444,8 @@ create table t1 ( id serial ); create view v1 as select * from t1; drop table t1; mysqldump { -mysqldump: Got error: 1356: "View 'test.v1' references invalid table(s) or column(s) or function(s) or definer/invoker of view lack rights to use them" when using LOCK TABLES -mysqldump: Couldn't execute 'SHOW FIELDS FROM `v1`': View 'test.v1' references invalid table(s) or column(s) or function(s) or definer/invoker of view lack rights to use them (1356) +mariadb-dump: Got error: 1356: "View 'test.v1' references invalid table(s) or column(s) or function(s) or definer/invoker of view lack rights to use them" when using LOCK TABLES +mariadb-dump: Couldn't execute 'SHOW FIELDS FROM `v1`': View 'test.v1' references invalid table(s) or column(s) or function(s) or definer/invoker of view lack rights to use them (1356) -- failed on view `v1`: CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v1` AS select `test`.`t1`.`id` AS `id` from `t1` @@ -3619,11 +3619,11 @@ use test; create user mysqltest_1@localhost; create table t1(a int, b varchar(34)); reset master; -mysqldump: Couldn't execute 'FLUSH /*!40101 LOCAL */ TABLES': Access denied; you need (at least one of) the RELOAD privilege(s) for this operation (1227) -mysqldump: Couldn't execute 'FLUSH /*!40101 LOCAL */ TABLES': Access denied; you need (at least one of) the RELOAD privilege(s) for this operation (1227) +mariadb-dump: Couldn't execute 'FLUSH /*!40101 LOCAL */ TABLES': Access denied; you need (at least one of) the RELOAD privilege(s) for this operation (1227) +mariadb-dump: Couldn't execute 'FLUSH /*!40101 LOCAL */ TABLES': Access denied; you need (at least one of) the RELOAD privilege(s) for this operation (1227) grant RELOAD on *.* to mysqltest_1@localhost; -mysqldump: Couldn't execute 'SHOW MASTER STATUS': Access denied; you need (at least one of) the SUPER, BINLOG MONITOR privilege(s) for this operation (1227) -mysqldump: Couldn't execute 'SHOW MASTER STATUS': Access denied; you need (at least one of) the SUPER, BINLOG MONITOR privilege(s) for this operation (1227) +mariadb-dump: Couldn't execute 'SHOW MASTER STATUS': Access denied; you need (at least one of) the SUPER, BINLOG MONITOR privilege(s) for this operation (1227) +mariadb-dump: Couldn't execute 'SHOW MASTER STATUS': Access denied; you need (at least one of) the SUPER, BINLOG MONITOR privilege(s) for this operation (1227) grant REPLICATION CLIENT on *.* to mysqltest_1@localhost; drop table t1; drop user mysqltest_1@localhost; @@ -3738,10 +3738,10 @@ DROP TABLE t1; # CREATE TABLE t1(a int); INSERT INTO t1 VALUES (1), (2); -mysqldump: Input filename too long: aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -mysqldump: Got error: 1083: "Field separator argument is not what is expected; check the manual" when executing 'SELECT INTO OUTFILE' -mysqldump: Got error: 1083: "Field separator argument is not what is expected; check the manual" when executing 'SELECT INTO OUTFILE' -mysqldump: Got error: 1083: "Field separator argument is not what is expected; check the manual" when executing 'SELECT INTO OUTFILE' +mariadb-dump: Input filename too long: aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +mariadb-dump: Got error: 1083: "Field separator argument is not what is expected; check the manual" when executing 'SELECT INTO OUTFILE' +mariadb-dump: Got error: 1083: "Field separator argument is not what is expected; check the manual" when executing 'SELECT INTO OUTFILE' +mariadb-dump: Got error: 1083: "Field separator argument is not what is expected; check the manual" when executing 'SELECT INTO OUTFILE' DROP TABLE t1; CREATE TABLE t2 (a INT) ENGINE=MyISAM; CREATE TABLE t3 (a INT) ENGINE=MyISAM; @@ -3835,7 +3835,7 @@ grant all privileges on mysqldump_test_db.* to user2; connect user27293,localhost,user1,,mysqldump_test_db,$MASTER_MYPORT,$MASTER_MYSOCK; connection user27293; create procedure mysqldump_test_db.sp1() select 'hello'; -mysqldump: user2 has insufficient privileges to SHOW CREATE PROCEDURE `sp1`! +mariadb-dump: user2 has insufficient privileges to SHOW CREATE PROCEDURE `sp1`! -- insufficient privileges to SHOW CREATE PROCEDURE `sp1` -- does user2 have permissions on mysql.proc? @@ -4067,7 +4067,7 @@ UNLOCK TABLES; /*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS */; /*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */; -mysqldump: Got error: 1146: "Table 'test.???????????????????????' doesn't exist" when using LOCK TABLES +mariadb-dump: Got error: 1146: "Table 'test.???????????????????????' doesn't exist" when using LOCK TABLES /*!40103 SET @OLD_TIME_ZONE=@@TIME_ZONE */; /*!40103 SET TIME_ZONE='+00:00' */; /*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */; @@ -4291,7 +4291,7 @@ Abernathy aberrant aberration drop table words; -mysqlimport: Error: 1146, Table 'test.words' doesn't exist, when using table: words +mariadb-import: Error: 1146, Table 'test.words' doesn't exist, when using table: words drop table t1; drop table t2; drop table words2; @@ -4612,8 +4612,8 @@ CREATE TABLE t1 (a INT, b CHAR(10) CHARSET koi8r, c CHAR(10) CHARSET latin1); CREATE TABLE t2 LIKE t1; INSERT INTO t1 VALUES (1, 'ABC-АБВ', 'DEF-ÂÃÄ'), (2, NULL, NULL); # error on multi-character ENCLOSED/ESCAPED BY -mysqldump: Got error: 1083: "Field separator argument is not what is expected; check the manual" when executing 'SELECT INTO OUTFILE' -mysqldump: Got error: 1083: "Field separator argument is not what is expected; check the manual" when executing 'SELECT INTO OUTFILE' +mariadb-dump: Got error: 1083: "Field separator argument is not what is expected; check the manual" when executing 'SELECT INTO OUTFILE' +mariadb-dump: Got error: 1083: "Field separator argument is not what is expected; check the manual" when executing 'SELECT INTO OUTFILE' # default '--default-charset' (binary): ################################################## 1 ABC- DEF- @@ -5100,7 +5100,7 @@ connection conn_1; 3 -mysqldump: user1 has insufficient privileges to SHOW CREATE FUNCTION `hello1`! +mariadb-dump: user1 has insufficient privileges to SHOW CREATE FUNCTION `hello1`! &1 ---replace_result mysqldump.exe mysqldump +--replace_result mariadb-dump.exe mariadb-dump --error 6 --exec $MYSQL_DUMP --compact --skip-comments mysqldump_test_db "\t1" 2>&1 ---replace_result mysqldump.exe mysqldump +--replace_result mariadb-dump.exe mariadb-dump --error 6 --exec $MYSQL_DUMP --compact --skip-comments mysqldump_test_db "\\t1" 2>&1 ---replace_result mysqldump.exe mysqldump +--replace_result mariadb-dump.exe mariadb-dump --error 6 --exec $MYSQL_DUMP --compact --skip-comments mysqldump_test_db "\\\\t1" 2>&1 ---replace_result mysqldump.exe mysqldump +--replace_result mariadb-dump.exe mariadb-dump --error 6 --exec $MYSQL_DUMP --compact --skip-comments mysqldump_test_db "t\1" 2>&1 ---replace_result mysqldump.exe mysqldump +--replace_result mariadb-dump.exe mariadb-dump --error 6 --exec $MYSQL_DUMP --compact --skip-comments mysqldump_test_db "t\\1" 2>&1 ---replace_result mysqldump.exe mysqldump +--replace_result mariadb-dump.exe mariadb-dump --error 6 --exec $MYSQL_DUMP --compact --skip-comments mysqldump_test_db "t/1" 2>&1 ---replace_result mysqldump.exe mysqldump +--replace_result mariadb-dump.exe mariadb-dump --error 6 --exec $MYSQL_DUMP --compact --skip-comments mysqldump_test_db "T_1" 2>&1 ---replace_result mysqldump.exe mysqldump +--replace_result mariadb-dump.exe mariadb-dump --error 6 --exec $MYSQL_DUMP --compact --skip-comments mysqldump_test_db "T%1" 2>&1 ---replace_result mysqldump.exe mysqldump +--replace_result mariadb-dump.exe mariadb-dump --error 6 --exec $MYSQL_DUMP --compact --skip-comments mysqldump_test_db "T'1" 2>&1 ---replace_result mysqldump.exe mysqldump +--replace_result mariadb-dump.exe mariadb-dump --error 6 --exec $MYSQL_DUMP --compact --skip-comments mysqldump_test_db "T_1" 2>&1 ---replace_result mysqldump.exe mysqldump +--replace_result mariadb-dump.exe mariadb-dump --error 6 --exec $MYSQL_DUMP --compact --skip-comments mysqldump_test_db "T_" 2>&1 --disable_query_log select '------ Testing with illegal database names ------' as test_sequence ; --enable_query_log ---replace_result mysqldump.exe mysqldump +--replace_result mariadb-dump.exe mariadb-dump --error 2 --exec $MYSQL_DUMP --compact --skip-comments mysqldump_test_d 2>&1 ---replace_result mysqldump.exe mysqldump +--replace_result mariadb-dump.exe mariadb-dump --error 2 --exec $MYSQL_DUMP --compact --skip-comments "mysqld\ump_test_db" 2>&1 @@ -738,7 +738,7 @@ drop table `t1`; create table t1(a int); create table t2(a int); create table t3(a int); ---replace_result mysqldump.exe mysqldump +--replace_result mariadb-dump.exe mariadb-dump --error 6 --exec $MYSQL_DUMP --default-character-set=utf8mb4 --skip-comments --force --no-data test t3 t1 non_existing t2 2>&1 drop table t1, t2, t3; @@ -749,7 +749,7 @@ drop table t1, t2, t3; --echo # create table t1 (a int); ---replace_result mysqldump.exe mysqldump +--replace_result mariadb-dump.exe mariadb-dump --error 2 --exec $MYSQL_DUMP --default-character-set=utf8mb4 --skip-comments --force test t1 --where="xx xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" 2>&1 drop table t1; @@ -1287,7 +1287,7 @@ create view v1 as select * from t1; drop table t1; # mysqldump gets 1356 from server, but gives us 2 --echo mysqldump { ---replace_result mysqldump.exe mysqldump +--replace_result mariadb-dump.exe mariadb-dump --error 2 --exec $MYSQL_DUMP --default-character-set=utf8mb4 --force -N --compact --skip-comments test 2>&1 --echo } mysqldump @@ -1385,13 +1385,13 @@ create table t1(a int, b varchar(34)); reset master; # Execute mysqldump, will fail on FLUSH TABLES ---replace_result mysqldump.exe mysqldump +--replace_result mariadb-dump.exe mariadb-dump --error 2 --exec $MYSQL_DUMP --default-character-set=utf8mb4 --compact --master-data -u mysqltest_1 test 2>&1 # Execute mysqldump, will fail on FLUSH TABLES # use --force, should no affect behaviour ---replace_result mysqldump.exe mysqldump +--replace_result mariadb-dump.exe mariadb-dump --error 2 --exec $MYSQL_DUMP --default-character-set=utf8mb4 --compact --force --master-data -u mysqltest_1 test 2>&1 @@ -1399,13 +1399,13 @@ reset master; grant RELOAD on *.* to mysqltest_1@localhost; # Execute mysqldump, will fail on SHOW MASTER STATUS ---replace_result mysqldump.exe mysqldump +--replace_result mariadb-dump.exe mariadb-dump --error 2 --exec $MYSQL_DUMP --default-character-set=utf8mb4 --compact --master-data -u mysqltest_1 test 2>&1 # Execute mysqldump, will fail on SHOW MASTER STATUS. # use --force, should not alter behaviour ---replace_result mysqldump.exe mysqldump +--replace_result mariadb-dump.exe mariadb-dump --error 2 --exec $MYSQL_DUMP --default-character-set=utf8mb4 --compact --force --master-data -u mysqltest_1 test 2>&1 @@ -1520,18 +1520,18 @@ CREATE TABLE t1(a int); INSERT INTO t1 VALUES (1), (2); # too long a file path causes an error ---replace_result mysqldump.exe mysqldump +--replace_result mariadb-dump.exe mariadb-dump --error 1 --exec $MYSQL_DUMP --default-character-set=utf8mb4 --tab=aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa test 2>&1 --exec $MYSQL_DUMP --default-character-set=utf8mb4 --tab=$MYSQLTEST_VARDIR/tmp/ --fields-terminated-by=aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa test ---replace_result mysqldump.exe mysqldump +--replace_result mariadb-dump.exe mariadb-dump --error 2 --exec $MYSQL_DUMP --default-character-set=utf8mb4 --tab=$MYSQLTEST_VARDIR/tmp/ --fields-enclosed-by=aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa test 2>&1 ---replace_result mysqldump.exe mysqldump +--replace_result mariadb-dump.exe mariadb-dump --error 2 --exec $MYSQL_DUMP --default-character-set=utf8mb4 --tab=$MYSQLTEST_VARDIR/tmp/ --fields-optionally-enclosed-by=aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa test 2>&1 ---replace_result mysqldump.exe mysqldump +--replace_result mariadb-dump.exe mariadb-dump --error 2 --exec $MYSQL_DUMP --default-character-set=utf8mb4 --tab=$MYSQLTEST_VARDIR/tmp/ --fields-escaped-by=aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa test 2>&1 --exec $MYSQL_DUMP --default-character-set=utf8mb4 --tab=$MYSQLTEST_VARDIR/tmp/ --lines-terminated-by=aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa test @@ -1605,7 +1605,7 @@ connection user27293; create procedure mysqldump_test_db.sp1() select 'hello'; ---replace_result mysqldump.exe mysqldump +--replace_result mariadb-dump.exe mariadb-dump --error 2 --exec $MYSQL_DUMP -f --compact --user=user2 --password= -h 127.0.0.1 -P $MASTER_MYPORT --routines mysqldump_test_db 2>&1 @@ -1711,7 +1711,7 @@ DROP TABLE `straße`; CREATE TABLE `כדשגכחךלדגכחשךדגחכךלדגכ` ( f1 INT ); --exec $MYSQL_DUMP --character-sets-dir=$MYSQL_SHAREDIR/charsets --skip-comments --default-character-set=utf8 --compatible=mysql323 test ---replace_result mysqldump.exe mysqldump +--replace_result mariadb-dump.exe mariadb-dump --error 2 --exec $MYSQL_DUMP --character-sets-dir=$MYSQL_SHAREDIR/charsets --skip-comments --default-character-set=latin1 --compatible=mysql323 test 2>&1 DROP TABLE `כדשגכחךלדגכחשךדגחכךלדגכ`; @@ -1766,7 +1766,7 @@ select * from words2; # Drop table "words" and run with threads, should fail drop table words; ---replace_regex /.*mysqlimport(\.exe)*/mysqlimport/ +--replace_regex /.*mariadb-import(\.exe)*/mariadb-import/ --error 1 --exec $MYSQL_IMPORT --silent --use-threads=2 test $MYSQLTEST_VARDIR/tmp/t1.txt $MYSQLTEST_VARDIR/tmp/t2.txt $MYSQLTEST_VARDIR/std_data/words.dat $MYSQLTEST_VARDIR/std_data/words2.dat 2>&1 @@ -2117,12 +2117,12 @@ INSERT INTO t1 VALUES (1, 'ABC-АБВ', 'DEF-ÂÃÄ'), (2, NULL, NULL); --echo # error on multi-character ENCLOSED/ESCAPED BY ---replace_result mysqldump.exe mysqldump +--replace_result mariadb-dump.exe mariadb-dump --error 2 --exec $MYSQL_DUMP --disable-default-character-set --tab=$MYSQLTEST_VARDIR/tmp/ --fields-enclosed-by='12345' test t1 2>&1 --remove_file $file ---replace_result mysqldump.exe mysqldump +--replace_result mariadb-dump.exe mariadb-dump --error 2 --exec $MYSQL_DUMP --disable-default-character-set --tab=$MYSQLTEST_VARDIR/tmp/ --fields-escaped-by='12345' test t1 2>&1 --remove_file $file @@ -2336,7 +2336,7 @@ connection conn_1; --echo # Running 'replace_regex on timestamp' --replace_regex /[0-9]{4}-[0-9]{2}-[0-9]{2} [0-9]{2}:[0-9]{2}:[0-9]{2}(.[0-9]{2})*/--TIME--/ ---replace_result mysqldump.exe mysqldump +--replace_result mariadb-dump.exe mariadb-dump --error 2 --exec $MYSQL_DUMP --user=user1 -R -E --triggers -X BUG52792 2>&1 @@ -2529,6 +2529,7 @@ SELECT ROUTINE_NAME FROM INFORMATION_SCHEMA.ROUTINES WHERE ROUTINE_SCHEMA='bug25717383' AND ROUTINE_TYPE= 'PROCEDURE' ORDER BY ROUTINE_NAME; +--replace_result mariadb-dump.exe mariadb-dump --exec $MYSQL_DUMP --default-character-set=utf8mb4 --triggers --events --routines --add-drop-database --databases bug25717383 > $MYSQLTEST_VARDIR/tmp/bug25717383.sql SHOW TABLES FROM bug25717383; @@ -2546,14 +2547,14 @@ DROP DATABASE bug25717383; # # MDEV-6091 mysqldump goes in a loop and segfaults if --dump-slave is specified and it cannot connect to the server # ---replace_regex /mysqldump\.exe/mysqldump/ /'unknownhost' \(.*\)/'unknownhost'/ +--replace_regex /mariadb-dump\.exe/mariadb-dump/ /'unknownhost' \(.*\)/'unknownhost'/ --error 2 --exec $MYSQL_DUMP --default-character-set=utf8mb4 -hunknownhost --dump-slave nulldb 2>&1 # # MDEV-6056 [PATCH] mysqldump writes usage to stdout even when not explicitly requested # ---replace_result mysqldump.exe mysqldump +--replace_result mariadb-dump.exe mariadb-dump --error 1 --exec $MYSQL_DUMP --default-character-set=utf8mb4 --user=foo 2>&1 --exec $MYSQL_DUMP --help 2>&1 > $MYSQLTEST_VARDIR/tmp/bug6056.out @@ -2676,7 +2677,7 @@ create table t2 ( 0 EOF ---replace_regex /.*mysqlimport(\.exe)*/mysqlimport/ +--replace_regex /.*mariadb-import(\.exe)*/mariadb-import/ --error 1 --exec $MYSQL_IMPORT --silent test $MYSQLTEST_VARDIR/tmp/t2.txt 2>&1 --exec $MYSQL_IMPORT --silent -k test $MYSQLTEST_VARDIR/tmp/t2.txt diff --git a/mysql-test/main/openssl_1.result b/mysql-test/main/openssl_1.result index 64672655ebe..029fa47f263 100644 --- a/mysql-test/main/openssl_1.result +++ b/mysql-test/main/openssl_1.result @@ -179,7 +179,7 @@ UNLOCK TABLES; /*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */; /*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */; -mysqldump: Got error: 2026: "TLS/SSL error: xxxx +mariadb-dump: Got error: 2026: "TLS/SSL error: xxxx DROP TABLE t1; GRANT SELECT ON test.* TO bug42158@localhost REQUIRE X509; FLUSH PRIVILEGES; diff --git a/mysql-test/main/openssl_1.test b/mysql-test/main/openssl_1.test index 968f6e13473..639fd0a294d 100644 --- a/mysql-test/main/openssl_1.test +++ b/mysql-test/main/openssl_1.test @@ -174,7 +174,7 @@ INSERT INTO t1 VALUES (1), (2); --exec $MYSQL_DUMP --default-character-set=utf8mb4 --skip-create-options --skip-comments --ssl --ssl-ca=$MYSQL_TEST_DIR/std_data/cacert.pem --ssl-key=$MYSQL_TEST_DIR/std_data/client-key.pem --ssl-cert=$MYSQL_TEST_DIR/std_data/client-cert.pem test # With wrong parameters ---replace_result $MYSQL_TEST_DIR MYSQL_TEST_DIR mysqldump.exe mysqldump +--replace_result $MYSQL_TEST_DIR MYSQL_TEST_DIR $MYSQL_DUMP mariadb-dump .\exe '' --replace_regex /TLS\/SSL error.*/TLS\/SSL error: xxxx/ --error 2 --exec $MYSQL_DUMP --default-character-set=utf8mb4 --skip-create-options --skip-comments --ssl --ssl-cert=$MYSQL_TEST_DIR/std_data/client-cert.pem test 2>&1 diff --git a/mysql-test/main/ssl_crl_clients.result b/mysql-test/main/ssl_crl_clients.result index 44ba101c892..7cc03deee0c 100644 --- a/mysql-test/main/ssl_crl_clients.result +++ b/mysql-test/main/ssl_crl_clients.result @@ -6,8 +6,8 @@ ERROR 2026 (HY000): TLS/SSL error: certificate revoked ERROR 2026 (HY000): TLS/SSL error: certificate revoked ############ Test mysqladmin ############## # Test mysqladmin connecting to a server with a certificate revoked by -crl -mysqladmin: connect to server at 'localhost' failed +mariadb-admin: connect to server at 'localhost' failed error: 'TLS/SSL error: certificate revoked' # Test mysqladmin connecting to a server with a certificate revoked by -crlpath -mysqladmin: connect to server at 'localhost' failed +mariadb-admin: connect to server at 'localhost' failed error: 'TLS/SSL error: certificate revoked' diff --git a/mysql-test/main/ssl_crl_clients.test b/mysql-test/main/ssl_crl_clients.test index 0023dee03ac..95b4ac3c0d5 100644 --- a/mysql-test/main/ssl_crl_clients.test +++ b/mysql-test/main/ssl_crl_clients.test @@ -34,11 +34,11 @@ copy_file $MYSQL_TEST_DIR/std_data/server-cert.crl $MYSQL_TMP_DIR/ed1f42db.r0; let $admin_suffix = --default-character-set=latin1 -S $MASTER_MYSOCK -P $MASTER_MYPORT -u root --password= ping; --echo # Test mysqladmin connecting to a server with a certificate revoked by -crl ---replace_regex /.*mysqladmin.*:/mysqladmin:/ /TLS\/SSL error: .*CRYPT_E_REVOKED./TLS\/SSL error: certificate revoked/ +--replace_regex /.*mariadb-admin.*:/mariadb-admin:/ /TLS\/SSL error: .*CRYPT_E_REVOKED./TLS\/SSL error: certificate revoked/ --error 1 --exec $MYSQLADMIN $ssl_crl $admin_suffix 2>&1 --echo # Test mysqladmin connecting to a server with a certificate revoked by -crlpath ---replace_regex /.*mysqladmin.*:/mysqladmin:/ /TLS\/SSL error: .*CRYPT_E_REVOKED./TLS\/SSL error: certificate revoked/ +--replace_regex /.*mariadb-admin.*:/mariadb-admin:/ /TLS\/SSL error: .*CRYPT_E_REVOKED./TLS\/SSL error: certificate revoked/ --error 1 --exec $MYSQLADMIN $ssl_crlpath $admin_suffix 2>&1 diff --git a/mysql-test/mysql-test-run.pl b/mysql-test/mysql-test-run.pl index dfe8c20a8ee..0ceb542849f 100755 --- a/mysql-test/mysql-test-run.pl +++ b/mysql-test/mysql-test-run.pl @@ -1835,9 +1835,9 @@ sub executable_setup () { $exe_patch='patch' if `patch -v`; # Look for the client binaries - $exe_mysqladmin= mtr_exe_exists("$path_client_bindir/mysqladmin"); - $exe_mysql= mtr_exe_exists("$path_client_bindir/mysql"); - $exe_mysql_plugin= mtr_exe_exists("$path_client_bindir/mysql_plugin"); + $exe_mysqladmin= mtr_exe_exists("$path_client_bindir/mariadb-admin"); + $exe_mysql= mtr_exe_exists("$path_client_bindir/mariadb"); + $exe_mysql_plugin= mtr_exe_exists("$path_client_bindir/mariadb-plugin"); $exe_mariadb_conv= mtr_exe_exists("$path_client_bindir/mariadb-conv"); $exe_mysql_embedded= mtr_exe_maybe_exists("$bindir/libmysqld/examples/mysql_embedded"); @@ -1860,7 +1860,7 @@ sub executable_setup () { } else { - $exe_mysqltest= mtr_exe_exists("$path_client_bindir/mysqltest"); + $exe_mysqltest= mtr_exe_exists("$path_client_bindir/mariadb-test"); } } @@ -1871,7 +1871,7 @@ sub client_debug_arg($$) { my ($args, $client_name)= @_; # Workaround for Bug #50627: drop any debug opt - return if $client_name =~ /^mysqlbinlog/; + return if $client_name =~ /^mariadb-binlog/; if ( $opt_debug ) { mtr_add_arg($args, @@ -1902,7 +1902,7 @@ sub client_arguments ($;$) { sub mysqlbinlog_arguments () { - my $exe= mtr_exe_exists("$path_client_bindir/mysqlbinlog"); + my $exe= mtr_exe_exists("$path_client_bindir/mariadb-binlog"); my $args; mtr_init_args(\$args); @@ -1914,14 +1914,14 @@ sub mysqlbinlog_arguments () { sub mysqlslap_arguments () { - my $exe= mtr_exe_maybe_exists("$path_client_bindir/mysqlslap"); + my $exe= mtr_exe_maybe_exists("$path_client_bindir/mariadb-slap"); if ( $exe eq "" ) { # mysqlap was not found if (defined $mysql_version_id and $mysql_version_id >= 50100 ) { - mtr_error("Could not find the mysqlslap binary"); + mtr_error("Could not find the mariadb-slap binary"); } - return ""; # Don't care about mysqlslap + return ""; # Don't care about mariadb-slap } my $args; @@ -1934,7 +1934,7 @@ sub mysqlslap_arguments () { sub mysqldump_arguments ($) { my($group_suffix) = @_; - my $exe= mtr_exe_exists("$path_client_bindir/mysqldump"); + my $exe= mtr_exe_exists("$path_client_bindir/mariadb-dump"); my $args; mtr_init_args(\$args); @@ -2109,17 +2109,17 @@ sub environment_setup { # ---------------------------------------------------- # mysql clients # ---------------------------------------------------- - $ENV{'MYSQL_CHECK'}= client_arguments("mysqlcheck"); + $ENV{'MYSQL_CHECK'}= client_arguments("mariadb-check"); $ENV{'MYSQL_DUMP'}= mysqldump_arguments(".1"); $ENV{'MYSQL_DUMP_SLAVE'}= mysqldump_arguments(".2"); $ENV{'MYSQL_SLAP'}= mysqlslap_arguments(); - $ENV{'MYSQL_IMPORT'}= client_arguments("mysqlimport"); - $ENV{'MYSQL_SHOW'}= client_arguments("mysqlshow"); + $ENV{'MYSQL_IMPORT'}= client_arguments("mariadb-import"); + $ENV{'MYSQL_SHOW'}= client_arguments("mariadb-show"); $ENV{'MYSQL_BINLOG'}= mysqlbinlog_arguments(); - $ENV{'MYSQL'}= client_arguments("mysql"); - $ENV{'MYSQL_SLAVE'}= client_arguments("mysql", ".2"); - $ENV{'MYSQL_UPGRADE'}= client_arguments("mysql_upgrade"); - $ENV{'MYSQLADMIN'}= client_arguments("mysqladmin"); + $ENV{'MYSQL'}= client_arguments("mariadb"); + $ENV{'MYSQL_SLAVE'}= client_arguments("mariadb", ".2"); + $ENV{'MYSQL_UPGRADE'}= client_arguments("mariadb-upgrade"); + $ENV{'MYSQLADMIN'}= client_arguments("mariadb-admin"); $ENV{'MYSQL_CLIENT_TEST'}= mysql_client_test_arguments(); $ENV{'EXE_MYSQL'}= $exe_mysql; $ENV{'MYSQL_PLUGIN'}= $exe_mysql_plugin; @@ -2127,8 +2127,8 @@ sub environment_setup { $ENV{'MARIADB_CONV'}= $exe_mariadb_conv; if(IS_WINDOWS) { - $ENV{'MYSQL_INSTALL_DB_EXE'}= mtr_exe_exists("$bindir/sql$multiconfig/mysql_install_db", - "$bindir/bin/mysql_install_db"); + $ENV{'MYSQL_INSTALL_DB_EXE'}= mtr_exe_exists("$bindir/sql$multiconfig/mariadb-install-db", + "$bindir/bin/mariadb-install-db"); } my $client_config_exe= @@ -2211,9 +2211,9 @@ sub environment_setup { # ---------------------------------------------------- # mysql_tzinfo_to_sql # ---------------------------------------------------- - my $exe_mysql_tzinfo_to_sql= mtr_exe_exists("$basedir/sql$multiconfig/mysql_tzinfo_to_sql", - "$path_client_bindir/mysql_tzinfo_to_sql", - "$bindir/sql$multiconfig/mysql_tzinfo_to_sql"); + my $exe_mysql_tzinfo_to_sql= mtr_exe_exists("$basedir/sql$multiconfig/mariadb-tzinfo-to-sql", + "$path_client_bindir/mariadb-tzinfo-to-sql", + "$bindir/sql$multiconfig/mariadb-tzinfo-to-sql"); $ENV{'MYSQL_TZINFO_TO_SQL'}= native_path($exe_mysql_tzinfo_to_sql); # ---------------------------------------------------- From acebe35719ceb9c79a7a24794b3c75e121d4a362 Mon Sep 17 00:00:00 2001 From: Vlad Lesin Date: Thu, 6 Oct 2022 16:54:00 +0300 Subject: [PATCH 28/72] MDEV-29635 race on trx->lock.wait_lock in deadlock resolution Returning DB_SUCCESS unconditionally if !trx->lock.wait_lock in lock_trx_handle_wait() is wrong. Because even if trx->lock.was_chosen_as_deadlock_victim was not set before the first check in lock_trx_handle_wait(), it can be set after the check, and trx->lock.wait_lock can be reset by another thread from lock_reset_lock_and_trx_wait() if the transaction was chosen as deadlock victim. In this case lock_trx_handle_wait() will return DB_SUCCESS even the transaction was marked as deadlock victim, and continue execution instead of rolling back. The fix is to check trx->lock.was_chosen_as_deadlock_victim once more if trx->lock.wait_lock is reset, as trx->lock.wait_lock can be reset only after trx->lock.was_chosen_as_deadlock_victim was set if the transaction was chosen as deadlock victim. --- .../innodb/r/deadlock_wait_lock_race.result | 31 ++++++++++ .../innodb/t/deadlock_wait_lock_race.test | 62 +++++++++++++++++++ storage/innobase/lock/lock0lock.cc | 11 +++- storage/innobase/row/row0sel.cc | 2 + 4 files changed, 105 insertions(+), 1 deletion(-) create mode 100644 mysql-test/suite/innodb/r/deadlock_wait_lock_race.result create mode 100644 mysql-test/suite/innodb/t/deadlock_wait_lock_race.test diff --git a/mysql-test/suite/innodb/r/deadlock_wait_lock_race.result b/mysql-test/suite/innodb/r/deadlock_wait_lock_race.result new file mode 100644 index 00000000000..8a7878b3078 --- /dev/null +++ b/mysql-test/suite/innodb/r/deadlock_wait_lock_race.result @@ -0,0 +1,31 @@ +connect suspend_purge,localhost,root,,; +START TRANSACTION WITH CONSISTENT SNAPSHOT; +connection default; +CREATE TABLE t (a int PRIMARY KEY, b int) engine = InnoDB; +CREATE TABLE t2 (a int PRIMARY KEY) engine = InnoDB; +INSERT INTO t VALUES (10, 10), (20, 20), (30, 30); +INSERT INTO t2 VALUES (10), (20), (30); +BEGIN; +UPDATE t2 SET a = a + 100; +SELECT * FROM t WHERE a = 20 FOR UPDATE; +a b +20 20 +connect con_2,localhost,root,,; +SET TRANSACTION ISOLATION LEVEL READ COMMITTED; +BEGIN; +SET DEBUG_SYNC = 'lock_trx_handle_wait_before_unlocked_wait_lock_check SIGNAL upd_locked WAIT_FOR upd_cont'; +UPDATE t SET b = 100; +connection default; +SET DEBUG_SYNC="now WAIT_FOR upd_locked"; +SET DEBUG_SYNC="lock_wait_before_suspend SIGNAL upd_cont"; +SELECT * FROM t WHERE a = 10 FOR UPDATE; +connection con_2; +ERROR 40001: Deadlock found when trying to get lock; try restarting transaction +disconnect con_2; +connection default; +a b +10 10 +SET DEBUG_SYNC = 'RESET'; +DROP TABLE t; +DROP TABLE t2; +disconnect suspend_purge; diff --git a/mysql-test/suite/innodb/t/deadlock_wait_lock_race.test b/mysql-test/suite/innodb/t/deadlock_wait_lock_race.test new file mode 100644 index 00000000000..2b3c9763a8c --- /dev/null +++ b/mysql-test/suite/innodb/t/deadlock_wait_lock_race.test @@ -0,0 +1,62 @@ +--source include/have_innodb.inc +--source include/have_debug_sync.inc +--source include/count_sessions.inc + +--connect(suspend_purge,localhost,root,,) +# Purge can cause deadlock in the test, requesting page's RW_X_LATCH for trx +# ids reseting, after trx 2 acqured RW_S_LATCH and suspended in debug sync point +# lock_trx_handle_wait_enter, waiting for upd_cont signal, which must be +# emitted after the last SELECT in this test. The last SELECT will hang waiting +# for purge RW_X_LATCH releasing, and trx 2 will be rolled back by timeout. +START TRANSACTION WITH CONSISTENT SNAPSHOT; + +--connection default +CREATE TABLE t (a int PRIMARY KEY, b int) engine = InnoDB; +CREATE TABLE t2 (a int PRIMARY KEY) engine = InnoDB; + +INSERT INTO t VALUES (10, 10), (20, 20), (30, 30); +INSERT INTO t2 VALUES (10), (20), (30); + +BEGIN; # trx 1 +# The following update is necessary to increase the transaction weight, which is +# calculated as the number of locks + the number of undo records during deadlock +# report. Victim's transaction should have minimum weight. We need trx 2 to be +# choosen as victim, that's why we need to increase the current transaction +# weight. +UPDATE t2 SET a = a + 100; +SELECT * FROM t WHERE a = 20 FOR UPDATE; + +--connect(con_2,localhost,root,,) +# RC is necessary to do semi-consistent read +SET TRANSACTION ISOLATION LEVEL READ COMMITTED; +BEGIN; # trx 2 +# The first time it will be hit on trying to lock (20,20), the second hit +# will be on (30,30). +SET DEBUG_SYNC = 'lock_trx_handle_wait_before_unlocked_wait_lock_check SIGNAL upd_locked WAIT_FOR upd_cont'; +# We must not modify primary key fields to cause rr_sequential() read record +# function choosing in mysql_update(), i.e. both query_plan.using_filesort and +# query_plan.using_io_buffer must be false during init_read_record() call. +--send UPDATE t SET b = 100 + +--connection default +SET DEBUG_SYNC="now WAIT_FOR upd_locked"; +SET DEBUG_SYNC="lock_wait_before_suspend SIGNAL upd_cont"; +--send SELECT * FROM t WHERE a = 10 FOR UPDATE + +--connection con_2 +# If the bug is not fixed, lock_trx_handle_wait() wrongly returns DB_SUCCESS +# instead of DB_DEADLOCK, row_search_mvcc() of trx 2 behaves so as if (20,20) +# was locked. Some debug assertion must crash the server. If the bug is fixed, +# trx 2 must just be rolled back by deadlock detector. +--error ER_LOCK_DEADLOCK +--reap + +--disconnect con_2 + +--connection default +--reap +SET DEBUG_SYNC = 'RESET'; +DROP TABLE t; +DROP TABLE t2; +--disconnect suspend_purge +--source include/wait_until_count_sessions.inc diff --git a/storage/innobase/lock/lock0lock.cc b/storage/innobase/lock/lock0lock.cc index 0d6a069d50d..f4d9ee6ceda 100644 --- a/storage/innobase/lock/lock0lock.cc +++ b/storage/innobase/lock/lock0lock.cc @@ -1822,6 +1822,7 @@ dberr_t lock_wait(que_thr_t *thr) while (trx->lock.wait_lock) { int err; + DEBUG_SYNC_C("lock_wait_before_suspend"); if (no_timeout) { @@ -5869,6 +5870,7 @@ lock_unlock_table_autoinc( /** Handle a pending lock wait (DB_LOCK_WAIT) in a semi-consistent read while holding a clustered index leaf page latch. + @param trx transaction that is or was waiting for a lock @retval DB_SUCCESS if the lock was granted @retval DB_DEADLOCK if the transaction must be aborted due to a deadlock @@ -5879,8 +5881,13 @@ dberr_t lock_trx_handle_wait(trx_t *trx) DEBUG_SYNC_C("lock_trx_handle_wait_enter"); if (trx->lock.was_chosen_as_deadlock_victim) return DB_DEADLOCK; + DEBUG_SYNC_C("lock_trx_handle_wait_before_unlocked_wait_lock_check"); + /* trx->lock.was_chosen_as_deadlock_victim must always be set before + trx->lock.wait_lock if the transaction was chosen as deadlock victim, + the function must not return DB_SUCCESS if + trx->lock.was_chosen_as_deadlock_victim is set. */ if (!trx->lock.wait_lock) - return DB_SUCCESS; + return trx->lock.was_chosen_as_deadlock_victim ? DB_DEADLOCK : DB_SUCCESS; dberr_t err= DB_SUCCESS; mysql_mutex_lock(&lock_sys.wait_mutex); if (trx->lock.was_chosen_as_deadlock_victim) @@ -6283,6 +6290,8 @@ namespace Deadlock ut_ad(victim->state == TRX_STATE_ACTIVE); + /* victim->lock.was_chosen_as_deadlock_victim must always be set before + releasing waiting locks and reseting trx->lock.wait_lock */ victim->lock.was_chosen_as_deadlock_victim= true; lock_cancel_waiting_and_release(victim->lock.wait_lock); #ifdef WITH_WSREP diff --git a/storage/innobase/row/row0sel.cc b/storage/innobase/row/row0sel.cc index 9162fda91ed..dab1ccd84b2 100644 --- a/storage/innobase/row/row0sel.cc +++ b/storage/innobase/row/row0sel.cc @@ -5270,6 +5270,8 @@ no_gap_lock: switch (err) { case DB_SUCCESS: + ut_ad( + !trx->lock.was_chosen_as_deadlock_victim); /* The lock was granted while we were searching for the last committed version. Do a normal locking read. */ From 9c04d66d11ba72addaa5adff64a0458d91c19c2c Mon Sep 17 00:00:00 2001 From: Vlad Lesin Date: Fri, 7 Oct 2022 23:25:58 +0300 Subject: [PATCH 29/72] MDEV-29622 Wrong assertions in lock_cancel_waiting_and_release() for deadlock resolving caller Suppose we have two transactions, trx 1 and trx 2. trx 2 does deadlock resolving from lock_wait(), it sets victim->lock.was_chosen_as_deadlock_victim=true for trx 1, but has not yet invoked lock_cancel_waiting_and_release(). trx 1 checks the flag in lock_trx_handle_wait(), and starts rollback from row_mysql_handle_errors(). It can change trx->lock.wait_thr and trx->state as it holds trx_t::mutex, but trx 2 has not yet requested it, as lock_cancel_waiting_and_release() has not yet been called. After that trx 1 tries to release locks in trx_t::rollback_low(), invoking trx_t::rollback_finish(). lock_release() is blocked on try to acquire lock_sys.rd_lock(SRW_LOCK_CALL) in lock_release_try(), as lock_sys is blocked by trx 2, as deadlock resolution works under lock_sys.wr_lock(SRW_LOCK_CALL), see Deadlock::report() for details. trx 2 executes lock_cancel_waiting_and_release() for deadlock victim, i. e. for trx 1. lock_cancel_waiting_and_release() contains some trx->lock.wait_thr and trx->state assertions, which will fail, because trx 1 has changed them during rollback execution. So, according to the above scenario, it's legal to have trx->lock.wait_thr==0 and trx->state!=TRX_STATE_ACTIVE in lock_cancel_waiting_and_release(), if it was invoked from Deadlock::report(), and the fix is just in the assertion conditions changing. The fix is just in changing assertion condition. There is also lock_wait() cleanup around trx->error_state. If trx->error_state can be changed not by the owned thread, it must be protected with lock_sys.wait_mutex, as lock_wait() uses trx->lock.cond along with that mutex. Also if trx->error_state was changed before lock_sys.wait_mutex acquision, then it could be reset with the following code, what is wrong. Also we need to check trx->error_state before entering waiting loop, otherwise it can be the case when trx->error_state was set before lock_sys.wait_mutex acquision, but the thread will be waiting on trx->lock.cond. --- .../innodb/r/deadlock_wait_thr_race.result | 37 +++++++++++ .../innodb/t/deadlock_wait_thr_race.test | 66 +++++++++++++++++++ storage/innobase/lock/lock0lock.cc | 35 +++++----- storage/innobase/trx/trx0trx.cc | 1 + 4 files changed, 124 insertions(+), 15 deletions(-) create mode 100644 mysql-test/suite/innodb/r/deadlock_wait_thr_race.result create mode 100644 mysql-test/suite/innodb/t/deadlock_wait_thr_race.test diff --git a/mysql-test/suite/innodb/r/deadlock_wait_thr_race.result b/mysql-test/suite/innodb/r/deadlock_wait_thr_race.result new file mode 100644 index 00000000000..cea74b0b1cb --- /dev/null +++ b/mysql-test/suite/innodb/r/deadlock_wait_thr_race.result @@ -0,0 +1,37 @@ +connect suspend_purge,localhost,root,,; +START TRANSACTION WITH CONSISTENT SNAPSHOT; +connection default; +CREATE TABLE t (a int PRIMARY KEY, b int) engine = InnoDB; +CREATE TABLE t2 (a int PRIMARY KEY) engine = InnoDB; +INSERT INTO t VALUES (10, 10), (20, 20), (30, 30); +INSERT INTO t2 VALUES (10), (20), (30); +BEGIN; +UPDATE t2 SET a = a + 100; +SELECT * FROM t WHERE a = 20 FOR UPDATE; +a b +20 20 +connect con_2,localhost,root,,; +SET TRANSACTION ISOLATION LEVEL READ COMMITTED; +SET DEBUG_SYNC = 'lock_trx_handle_wait_enter SIGNAL upd_locked WAIT_FOR upd_cont'; +SET DEBUG_SYNC = 'trx_t_release_locks_enter SIGNAL sel_cont WAIT_FOR upd_cont_2'; +BEGIN; +UPDATE t SET b = 100; +connection default; +SET DEBUG_SYNC="now WAIT_FOR upd_locked"; +SET DEBUG_SYNC="deadlock_report_before_lock_releasing SIGNAL upd_cont WAIT_FOR sel_cont"; +SET DEBUG_SYNC="lock_wait_before_suspend SIGNAL sel_before_suspend"; +SELECT * FROM t WHERE a = 10 FOR UPDATE;; +connect con_3,localhost,root,,; +SET DEBUG_SYNC="now WAIT_FOR sel_before_suspend"; +SET DEBUG_SYNC="now SIGNAL upd_cont_2"; +disconnect con_3; +connection con_2; +ERROR 40001: Deadlock found when trying to get lock; try restarting transaction +disconnect con_2; +connection default; +a b +10 10 +SET DEBUG_SYNC = 'RESET'; +DROP TABLE t; +DROP TABLE t2; +disconnect suspend_purge; diff --git a/mysql-test/suite/innodb/t/deadlock_wait_thr_race.test b/mysql-test/suite/innodb/t/deadlock_wait_thr_race.test new file mode 100644 index 00000000000..2027b45cbae --- /dev/null +++ b/mysql-test/suite/innodb/t/deadlock_wait_thr_race.test @@ -0,0 +1,66 @@ +--source include/have_innodb.inc +--source include/have_debug_sync.inc +--source include/count_sessions.inc + +--connect(suspend_purge,localhost,root,,) +# Purge can cause deadlock in the test, requesting page's RW_X_LATCH for trx +# ids reseting, after trx 2 acqured RW_S_LATCH and suspended in debug sync point +# lock_trx_handle_wait_enter, waiting for upd_cont signal, which must be +# emitted after the last SELECT in this test. The last SELECT will hang waiting +# for purge RW_X_LATCH releasing, and trx 2 will be rolled back by timeout. +START TRANSACTION WITH CONSISTENT SNAPSHOT; + +--connection default +CREATE TABLE t (a int PRIMARY KEY, b int) engine = InnoDB; +CREATE TABLE t2 (a int PRIMARY KEY) engine = InnoDB; + +INSERT INTO t VALUES (10, 10), (20, 20), (30, 30); +INSERT INTO t2 VALUES (10), (20), (30); + +BEGIN; # trx 1 +# The following update is necessary to increase the transaction weight, which is +# calculated as the number of locks + the number of undo records during deadlock +# report. Victim's transaction should have minimum weight. We need trx 2 to be +# choosen as victim, that's why we need to increase the current transaction +# weight. +UPDATE t2 SET a = a + 100; +SELECT * FROM t WHERE a = 20 FOR UPDATE; + +--connect(con_2,localhost,root,,) +# RC is necessary to do semi-consistent read +SET TRANSACTION ISOLATION LEVEL READ COMMITTED; +# It will be hit on trying to lock (20,20). +SET DEBUG_SYNC = 'lock_trx_handle_wait_enter SIGNAL upd_locked WAIT_FOR upd_cont'; +SET DEBUG_SYNC = 'trx_t_release_locks_enter SIGNAL sel_cont WAIT_FOR upd_cont_2'; +BEGIN; # trx 2 +# We must not modify primary key fields to cause rr_sequential() read record +# function choosing in mysql_update(), i.e. both query_plan.using_filesort and +# query_plan.using_io_buffer must be false during init_read_record() call. +# The following UPDATE will be chosen as deadlock victim and rolled back. +--send UPDATE t SET b = 100 + +--connection default +SET DEBUG_SYNC="now WAIT_FOR upd_locked"; +SET DEBUG_SYNC="deadlock_report_before_lock_releasing SIGNAL upd_cont WAIT_FOR sel_cont"; +SET DEBUG_SYNC="lock_wait_before_suspend SIGNAL sel_before_suspend"; +# If the bug is not fixed, the following SELECT will crash, as the above UPDATE +# will reset trx->lock.wait_thr during rollback +--send SELECT * FROM t WHERE a = 10 FOR UPDATE; + +--connect(con_3,localhost,root,,) +SET DEBUG_SYNC="now WAIT_FOR sel_before_suspend"; +SET DEBUG_SYNC="now SIGNAL upd_cont_2"; +--disconnect con_3 + +--connection con_2 +--error ER_LOCK_DEADLOCK +--reap +--disconnect con_2 + +--connection default +--reap +SET DEBUG_SYNC = 'RESET'; +DROP TABLE t; +DROP TABLE t2; +--disconnect suspend_purge +--source include/wait_until_count_sessions.inc diff --git a/storage/innobase/lock/lock0lock.cc b/storage/innobase/lock/lock0lock.cc index f4d9ee6ceda..484d04fdc14 100644 --- a/storage/innobase/lock/lock0lock.cc +++ b/storage/innobase/lock/lock0lock.cc @@ -1789,8 +1789,8 @@ dberr_t lock_wait(que_thr_t *thr) wait_lock->un_member.tab_lock.table->id <= DICT_FIELDS_ID); thd_wait_begin(trx->mysql_thd, (type_mode & LOCK_TABLE) ? THD_WAIT_TABLE_LOCK : THD_WAIT_ROW_LOCK); - trx->error_state= DB_SUCCESS; + int err= 0; mysql_mutex_lock(&lock_sys.wait_mutex); if (trx->lock.wait_lock) { @@ -1812,26 +1812,24 @@ dberr_t lock_wait(que_thr_t *thr) if (row_lock_wait) lock_sys.wait_start(); - trx->error_state= DB_SUCCESS; - #ifdef HAVE_REPLICATION if (rpl) lock_wait_rpl_report(trx); #endif + if (trx->error_state != DB_SUCCESS) + goto check_trx_error; + while (trx->lock.wait_lock) { - int err; DEBUG_SYNC_C("lock_wait_before_suspend"); if (no_timeout) - { my_cond_wait(&trx->lock.cond, &lock_sys.wait_mutex.m_mutex); - err= 0; - } else err= my_cond_timedwait(&trx->lock.cond, &lock_sys.wait_mutex.m_mutex, &abstime); +check_trx_error: switch (trx->error_state) { case DB_DEADLOCK: case DB_INTERRUPTED: @@ -1877,17 +1875,19 @@ end_wait: /** Resume a lock wait */ -static void lock_wait_end(trx_t *trx) +template +void lock_wait_end(trx_t *trx) { mysql_mutex_assert_owner(&lock_sys.wait_mutex); ut_ad(trx->mutex_is_owner()); ut_d(const auto state= trx->state); - ut_ad(state == TRX_STATE_ACTIVE || state == TRX_STATE_PREPARED); - ut_ad(trx->lock.wait_thr); + ut_ad(state == TRX_STATE_COMMITTED_IN_MEMORY || state == TRX_STATE_ACTIVE || + state == TRX_STATE_PREPARED); + ut_ad(from_deadlock || trx->lock.wait_thr); if (trx->lock.was_chosen_as_deadlock_victim) { - ut_ad(state == TRX_STATE_ACTIVE); + ut_ad(from_deadlock || state == TRX_STATE_ACTIVE); trx->error_state= DB_DEADLOCK; } @@ -5674,13 +5674,16 @@ static void lock_release_autoinc_locks(trx_t *trx) } /** Cancel a waiting lock request and release possibly waiting transactions */ -static void lock_cancel_waiting_and_release(lock_t *lock) +template +void lock_cancel_waiting_and_release(lock_t *lock) { lock_sys.assert_locked(*lock); mysql_mutex_assert_owner(&lock_sys.wait_mutex); trx_t *trx= lock->trx; trx->mutex_lock(); - ut_ad(trx->state == TRX_STATE_ACTIVE); + ut_d(const auto trx_state= trx->state); + ut_ad(trx_state == TRX_STATE_COMMITTED_IN_MEMORY || + trx_state == TRX_STATE_ACTIVE); if (!lock->is_table()) lock_rec_dequeue_from_page(lock, true); @@ -5699,7 +5702,8 @@ static void lock_cancel_waiting_and_release(lock_t *lock) /* Reset the wait flag and the back pointer to lock in trx. */ lock_reset_lock_and_trx_wait(lock); - lock_wait_end(trx); + lock_wait_end(trx); + trx->mutex_unlock(); } @@ -6293,7 +6297,8 @@ namespace Deadlock /* victim->lock.was_chosen_as_deadlock_victim must always be set before releasing waiting locks and reseting trx->lock.wait_lock */ victim->lock.was_chosen_as_deadlock_victim= true; - lock_cancel_waiting_and_release(victim->lock.wait_lock); + DEBUG_SYNC_C("deadlock_report_before_lock_releasing"); + lock_cancel_waiting_and_release(victim->lock.wait_lock); #ifdef WITH_WSREP if (victim->is_wsrep() && wsrep_thd_is_SR(victim->mysql_thd)) wsrep_handle_SR_rollback(trx->mysql_thd, victim->mysql_thd); diff --git a/storage/innobase/trx/trx0trx.cc b/storage/innobase/trx/trx0trx.cc index f9fe2c19fe1..a429ea9b7fb 100644 --- a/storage/innobase/trx/trx0trx.cc +++ b/storage/innobase/trx/trx0trx.cc @@ -485,6 +485,7 @@ TRANSACTIONAL_INLINE inline void trx_t::commit_state() /** Release any explicit locks of a committing transaction. */ inline void trx_t::release_locks() { + DEBUG_SYNC_C("trx_t_release_locks_enter"); DBUG_ASSERT(state == TRX_STATE_COMMITTED_IN_MEMORY); DBUG_ASSERT(!is_referenced()); From dca4fc24a2abde0fec5b1e5b7907944ca8d5f1cf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Otto=20Kek=C3=A4l=C3=A4inen?= Date: Fri, 21 Oct 2022 02:17:25 -0700 Subject: [PATCH 30/72] Deb: Use archive.mariadb.org for upgrade testing in Salsa-CI (#2294) The official deb.mariadb.org mirrors are intended for distribution of the current MariaDB releases. When a version goes end-of-life, they are removed from those mirrors. The upgrade tests should however work even after EOL. While we do want users to stop using EOL versions, we still expect the newer versions to support upgrades from old versions to the current versions. Therefore we should continue testing upgrades from EOL versions, and for that to work, switch the CI to use the archive.mariadb.org repositories instead. MERGE NOTE: This commit was made on the oldest branch with the salsa-ci.yml file. When merging 10.5->10.6->...->10.12 please include this commit in the merge and ensure all files end up with the change: deb.mariadb.org/10.([0-9]+)/ -> archive.mariadb.org/mariadb-10.$1/repo/ --- debian/salsa-ci.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/debian/salsa-ci.yml b/debian/salsa-ci.yml index 6fc90193e06..c44713d59e4 100644 --- a/debian/salsa-ci.yml +++ b/debian/salsa-ci.yml @@ -519,7 +519,7 @@ mariadb.org-10.5 to mariadb-10.5 upgrade: - *test-prepare-container - apt install -y curl - curl -sS https://mariadb.org/mariadb_release_signing_key.asc -o /etc/apt/trusted.gpg.d/mariadb.asc - - echo "deb https://deb.mariadb.org/10.5/debian ${RELEASE} main" > /etc/apt/sources.list.d/mariadb.list + - echo "deb https://archive.mariadb.org/mariadb-10.5/repo/debian ${RELEASE} main" > /etc/apt/sources.list.d/mariadb.list - apt-get update # The 10.5.9 release is missing mariadb-plugin-columnstore, define all other packages but it to avoid hitting the error: # The following packages have unmet dependencies: @@ -558,7 +558,7 @@ mariadb.org-10.4 to mariadb-10.5 upgrade: - *test-prepare-container - apt install -y curl - curl -sS https://mariadb.org/mariadb_release_signing_key.asc -o /etc/apt/trusted.gpg.d/mariadb.asc - - echo "deb https://deb.mariadb.org/10.4/debian ${RELEASE} main" > /etc/apt/sources.list.d/mariadb.list + - echo "deb https://archive.mariadb.org/mariadb-10.4/repo/debian ${RELEASE} main" > /etc/apt/sources.list.d/mariadb.list - apt-get update - apt-get install -y mariadb-server-10.4 # MariaDB.org version of 10.4 and early 10.5 do not install an init file, so @@ -591,7 +591,7 @@ mariadb.org-10.3 to mariadb-10.5 upgrade: - *test-prepare-container - apt install -y curl - curl -sS https://mariadb.org/mariadb_release_signing_key.asc -o /etc/apt/trusted.gpg.d/mariadb.asc - - echo "deb https://deb.mariadb.org/10.3/debian ${RELEASE} main" > /etc/apt/sources.list.d/mariadb.list + - echo "deb https://archive.mariadb.org/mariadb-10.3/repo/debian ${RELEASE} main" > /etc/apt/sources.list.d/mariadb.list - apt-get update - apt-get install -y mariadb-server-10.3 - *test-verify-initial @@ -624,7 +624,7 @@ mariadb.org-10.2 to mariadb-10.5 upgrade: - *test-prepare-container - apt install -y curl apt-transport-https - curl -sS https://mariadb.org/mariadb_release_signing_key.asc -o /etc/apt/trusted.gpg.d/mariadb.asc - - echo "deb https://deb.mariadb.org/10.2/debian ${RELEASE} main" > /etc/apt/sources.list.d/mariadb.list + - echo "deb https://archive.mariadb.org/mariadb-10.2/repo/debian ${RELEASE} main" > /etc/apt/sources.list.d/mariadb.list - apt-get update - apt-get install -y mariadb-server-10.2 # Verify initial state before upgrade From 0c06320ae9a78996c28539ac310ad4fbf9d419bb Mon Sep 17 00:00:00 2001 From: Anel Date: Fri, 21 Oct 2022 14:26:06 +0200 Subject: [PATCH 31/72] MDEV-29687:ODBC tables do not quote identifier names correctly (#2295) Reviewer: andrew@mariadb.org --- .../connect/r/odbc_postgresql.result | 13 ++++++ .../mysql-test/connect/t/odbc_postgresql.sql | 2 + .../mysql-test/connect/t/odbc_postgresql.test | 7 +++ storage/connect/odbconn.cpp | 6 +++ storage/connect/tabext.cpp | 44 ++++++++++++++++--- storage/connect/tabext.h | 1 + 6 files changed, 68 insertions(+), 5 deletions(-) diff --git a/storage/connect/mysql-test/connect/r/odbc_postgresql.result b/storage/connect/mysql-test/connect/r/odbc_postgresql.result index 4a41dcf6ab8..6bd8d75a601 100644 --- a/storage/connect/mysql-test/connect/r/odbc_postgresql.result +++ b/storage/connect/mysql-test/connect/r/odbc_postgresql.result @@ -15,6 +15,7 @@ Table_Cat Table_Schema Table_Name Table_Type Remark mtr public t1 TABLE mtr public t2 TABLE mtr public v1 VIEW +mtr schema1 space_in_column_name TABLE mtr schema1 t1 TABLE mtr schema1 t2 TABLE mtr schema1 t3 TABLE @@ -27,6 +28,7 @@ Table_Cat Table_Schema Table_Name Table_Type Remark mtr public t1 TABLE mtr public t2 TABLE mtr public v1 VIEW +mtr schema1 space_in_column_name TABLE mtr schema1 t1 TABLE mtr schema1 t2 TABLE mtr schema1 t3 TABLE @@ -39,6 +41,7 @@ Table_Cat Table_Schema Table_Name Table_Type Remark mtr public t1 TABLE mtr public t2 TABLE mtr public v1 VIEW +mtr schema1 space_in_column_name TABLE mtr schema1 t1 TABLE mtr schema1 t2 TABLE mtr schema1 t3 TABLE @@ -102,6 +105,7 @@ Table_Cat Table_Schema Table_Name Column_Name Data_Type Type_Name Column_Size Bu mtr public t1 a 4 int4 10 4 0 10 0 mtr public t2 a 4 int4 10 4 0 10 0 mtr public v1 a 4 int4 10 4 0 10 1 +mtr schema1 space_in_column_name my space column 1 bpchar 20 80 NULL NULL 0 mtr schema1 t1 a 1 bpchar 10 40 NULL NULL 0 mtr schema1 t2 a 1 bpchar 10 40 NULL NULL 0 mtr schema1 t3 a 1 bpchar 10 40 NULL NULL 0 @@ -115,6 +119,7 @@ Table_Cat Table_Schema Table_Name Column_Name Data_Type Type_Name Column_Size Bu mtr public t1 a 4 int4 10 4 0 10 0 mtr public t2 a 4 int4 10 4 0 10 0 mtr public v1 a 4 int4 10 4 0 10 1 +mtr schema1 space_in_column_name my space column 1 bpchar 20 80 NULL NULL 0 mtr schema1 t1 a 1 bpchar 10 40 NULL NULL 0 mtr schema1 t2 a 1 bpchar 10 40 NULL NULL 0 mtr schema1 t3 a 1 bpchar 10 40 NULL NULL 0 @@ -306,3 +311,11 @@ DELETE FROM t1 WHERE a='20'; Warnings: Note 1105 schema1.t3: 0 affected rows DROP TABLE t1; +# +# MDEV-29687 ODBC tables do not quote identifier names correctly +# +CREATE TABLE pg_in_maria ENGINE=CONNECT TABNAME='schema1.space_in_column_name' CHARSET=utf8 DATA_CHARSET=utf8 TABLE_TYPE=ODBC CONNECTION='DSN=ConnectEnginePostgresql;UID=mtr;PWD=mtr' quoted=1; +SELECT * from pg_in_maria; +my space column +My value +DROP TABLE pg_in_maria; diff --git a/storage/connect/mysql-test/connect/t/odbc_postgresql.sql b/storage/connect/mysql-test/connect/t/odbc_postgresql.sql index e6452f70b37..9b22c69af13 100644 --- a/storage/connect/mysql-test/connect/t/odbc_postgresql.sql +++ b/storage/connect/mysql-test/connect/t/odbc_postgresql.sql @@ -27,4 +27,6 @@ CREATE TABLE schema1.t2 (a CHAR(10) NOT NULL); INSERT INTO schema1.t2 VALUES ('xxx'),('yyy'),('zzz'),('ÄÖÜ'); CREATE TABLE schema1.t3 (a CHAR(10) NOT NULL, b CHAR(10) NOT NULL); INSERT INTO schema1.t3 VALUES ('xxx', 'aaa'),('yyy', 'bbb'),('zzz', 'ccc'),('ÄÖÜ', 'яяя'); +CREATE TABLE schema1.space_in_column_name ("my space column" CHAR(20) NOT NULL); +INSERT INTO schema1.space_in_column_name VALUES ('My value'); \dt schema1.* diff --git a/storage/connect/mysql-test/connect/t/odbc_postgresql.test b/storage/connect/mysql-test/connect/t/odbc_postgresql.test index 2c3d4040c79..ec98453d630 100644 --- a/storage/connect/mysql-test/connect/t/odbc_postgresql.test +++ b/storage/connect/mysql-test/connect/t/odbc_postgresql.test @@ -216,3 +216,10 @@ DROP TABLE t1; CREATE TABLE t1 (a VARCHAR(6), b VARCHAR(6), PRIMARY KEY(a, b)) ENGINE=CONNECT TABNAME='schema1.t3' CHARSET=utf8 DATA_CHARSET=utf8 TABLE_TYPE=ODBC CONNECTION='DSN=ConnectEnginePostgresql;UID=mtr;PWD=mtr'; DELETE FROM t1 WHERE a='20'; DROP TABLE t1; + +--echo # +--echo # MDEV-29687 ODBC tables do not quote identifier names correctly +--echo # +CREATE TABLE pg_in_maria ENGINE=CONNECT TABNAME='schema1.space_in_column_name' CHARSET=utf8 DATA_CHARSET=utf8 TABLE_TYPE=ODBC CONNECTION='DSN=ConnectEnginePostgresql;UID=mtr;PWD=mtr' quoted=1; +SELECT * from pg_in_maria; +DROP TABLE pg_in_maria; diff --git a/storage/connect/odbconn.cpp b/storage/connect/odbconn.cpp index 88ae12ea23c..33c2b0aaf70 100644 --- a/storage/connect/odbconn.cpp +++ b/storage/connect/odbconn.cpp @@ -997,6 +997,11 @@ ODBConn::ODBConn(PGLOBAL g, TDBODBC *tdbp) m_Full = false; m_UseCnc = false; m_IDQuoteChar[0] = '"'; + if (tdbp) + { + if (tdbp->Quoted && tdbp->Quote) + m_IDQuoteChar[0] = *tdbp->Quote; + } m_IDQuoteChar[1] = 0; //*m_ErrMsg = '\0'; } // end of ODBConn @@ -1179,6 +1184,7 @@ int ODBConn::Open(PCSZ ConnectString, POPARM sop, DWORD options) // Verify support for required functionality and cache info // VerifyConnect(); Deprecated GetConnectInfo(); + // Still we want to use the set QChar } catch(DBX *xp) { snprintf(g->Message, sizeof(g->Message), "%s: %s", xp->m_Msg, xp->GetErrorMessage(0)); Close(); diff --git a/storage/connect/tabext.cpp b/storage/connect/tabext.cpp index c408cf60c66..95725dfc44b 100644 --- a/storage/connect/tabext.cpp +++ b/storage/connect/tabext.cpp @@ -159,6 +159,9 @@ bool EXTDEF::DefineAM(PGLOBAL g, LPCSTR am, int poff) Maxerr = GetIntCatInfo("Maxerr", 0); Maxres = GetIntCatInfo("Maxres", 0); Quoted = GetIntCatInfo("Quoted", 0); + Qchar = GetStringCatInfo(g,"Qchar", NULL); + if (Qchar && !Quoted) + Quoted = 1; Options = 0; Cto = 0; Qto = 0; @@ -198,6 +201,7 @@ TDBEXT::TDBEXT(EXTDEF *tdp) : TDB(tdp) Cto = tdp->Cto; Qto = tdp->Qto; Quoted = MY_MAX(0, tdp->GetQuoted()); + Quote = tdp->GetQchar(); Rows = tdp->GetElemt(); Memory = tdp->Memory; Scrollable = tdp->Scrollable; @@ -214,12 +218,12 @@ TDBEXT::TDBEXT(EXTDEF *tdp) : TDB(tdp) Cto = 0; Qto = 0; Quoted = 0; + Quote = NULL; Rows = 0; Memory = 0; Scrollable = false; } // endif tdp - Quote = NULL; Query = NULL; Count = NULL; //Where = NULL; @@ -252,6 +256,7 @@ TDBEXT::TDBEXT(PTDBEXT tdbp) : TDB(tdbp) Cto = tdbp->Cto; Qto = tdbp->Qto; Quoted = tdbp->Quoted; + Quote = tdbp->Quote; Rows = tdbp->Rows; Memory = tdbp->Memory; Scrollable = tdbp->Scrollable; @@ -390,6 +395,8 @@ bool TDBEXT::MakeSQL(PGLOBAL g, bool cnt) bool first = true; PTABLE tablep = To_Table; PCOL colp; + char *res= NULL, *my_schema_table= NULL; + size_t my_len= 0; if (Srcdef) return MakeSrcdef(g); @@ -459,10 +466,37 @@ bool TDBEXT::MakeSQL(PGLOBAL g, bool cnt) Decode(TableName, buf, sizeof(buf)); if (Quote) { - // Put table name between identifier quotes in case in contains blanks - Query->Append(Quote); - Query->Append(buf); - Query->Append(Quote); + // Tabname can have both database and table identifiers, we need to parse + if (res= strstr(buf, ".")) + { + // Parse schema + my_len= res - buf + 1; + my_schema_table= (char *) malloc(my_len); + memcpy(my_schema_table, buf, my_len - 1); + my_schema_table[my_len] = 0; + Query->Append(Quote); + Query->Append(my_schema_table); + Query->Append(Quote); + free(my_schema_table); + Query->Append("."); + // Parse table + my_len= strlen(buf) - my_len + 1; + my_schema_table= (char *) malloc(my_len); + memcpy(my_schema_table, ++res, my_len); + my_schema_table[my_len] = 0; + Query->Append(Quote); + Query->Append(my_schema_table); + Query->Append(Quote); + free(my_schema_table); + } + else + { + // Put table name between identifier quotes in case in contains blanks + Query->Append(Quote); + Query->Append(buf); + Query->Append(Quote); + } + } else Query->Append(buf); diff --git a/storage/connect/tabext.h b/storage/connect/tabext.h index 5fef1b9ece0..8a0d6c784a5 100644 --- a/storage/connect/tabext.h +++ b/storage/connect/tabext.h @@ -68,6 +68,7 @@ public: inline PSZ GetSrcdef(void) { return Srcdef; } inline char GetSep(void) { return (Sep) ? *Sep : 0; } inline int GetQuoted(void) { return Quoted; } + inline PSZ GetQchar(void) { return Qchar; } inline int GetOptions(void) { return Options; } // Methods From 6bc2e9338127cf9e97fa76cc97ab23f9c929991b Mon Sep 17 00:00:00 2001 From: Sergei Petrunia Date: Fri, 21 Oct 2022 12:04:00 +0300 Subject: [PATCH 32/72] MDEV-23160: SIGSEGV in Explain_node::print_explain_for_children on UNION SELECT and also MDEV-25564, MDEV-18157. Attempt to produce EXPLAIN output caused a crash in Explain_node::print_explain_for_children. The cause of this was that an Explain_node (actually a derived) had a link to child select#N, but there was no query plan present for select#N. The query plan wasn't present because the subquery was eliminated. - Either it was a degenerate subquery like "(SELECT 1)" in MDEV-25564. - Or it was a subquery in a UNION subquery's ORDER BY clause: col IN (SELECT ... UNION SELECT ... ORDER BY (SELECT FROM t1)) In such cases, legacy code structure in subquery/union processing code(*) makes it hard to detect that the subquery was eliminated, so we end up with EXPLAIN data structures (Explain_node::children) having dangling links to child subqueries. Do make the checks and don't follow the dangling links. (In ideal world, we should not have these dangling links. But fixing the code (*) would have high risk for the stable versions). --- mysql-test/main/explain.result | 46 ++++++++++++++++++++++++++++++++++ mysql-test/main/explain.test | 31 +++++++++++++++++++++++ sql/sql_explain.cc | 15 +++++++++-- 3 files changed, 90 insertions(+), 2 deletions(-) diff --git a/mysql-test/main/explain.result b/mysql-test/main/explain.result index f593e0dfaba..3a55e2aaf42 100644 --- a/mysql-test/main/explain.result +++ b/mysql-test/main/explain.result @@ -407,3 +407,49 @@ id select_type table type possible_keys key key_len ref rows Extra 2 SUBQUERY t1 system NULL NULL NULL NULL 1 drop table t1, t2; # End of 10.1 tests +# +# End of 10.2 test +# +# +# MDEV-25564: Server crashed on running some EXPLAIN statements +# +EXPLAIN (SELECT 1,3) UNION (SELECT 2,1) ORDER BY (SELECT 2); +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY NULL NULL NULL NULL NULL NULL NULL No tables used +2 UNION NULL NULL NULL NULL NULL NULL NULL No tables used +NULL UNION RESULT ALL NULL NULL NULL NULL NULL Using filesort +Warnings: +Note 1249 Select 3 was reduced during optimization +# +# MDEV-23160: SIGSEGV in Explain_node::print_explain_for_children on UNION SELECT +# +CREATE TABLE t1 (a INT); +INSERT INTO t1 VALUES (1),(2),(3); +EXPLAIN +SELECT * +FROM t1 +WHERE +a IN (SELECT a FROM t1 +UNION +SELECT a FROM t1 ORDER BY (SELECT a)) +UNION +SELECT * FROM t1 ORDER BY (SELECT a); +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 ALL NULL NULL NULL NULL 3 Using where +2 DEPENDENT SUBQUERY t1 ALL NULL NULL NULL NULL 3 Using where +3 DEPENDENT UNION t1 ALL NULL NULL NULL NULL 3 Using where +NULL UNION RESULT ALL NULL NULL NULL NULL NULL +5 UNION t1 ALL NULL NULL NULL NULL 3 +NULL UNION RESULT ALL NULL NULL NULL NULL NULL Using filesort +6 DEPENDENT SUBQUERY NULL NULL NULL NULL NULL NULL NULL No tables used +drop table t1; +explain +VALUES ( (VALUES (2))) UNION VALUES ( (SELECT 3)); +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY NULL NULL NULL NULL NULL NULL NULL No tables used +5 SUBQUERY ALL NULL NULL NULL NULL 2 +2 DERIVED NULL NULL NULL NULL NULL NULL NULL No tables used +3 UNION NULL NULL NULL NULL NULL NULL NULL No tables used +NULL UNION RESULT ALL NULL NULL NULL NULL NULL +Warnings: +Note 1249 Select 4 was reduced during optimization diff --git a/mysql-test/main/explain.test b/mysql-test/main/explain.test index d5be354c852..973b5a7a87e 100644 --- a/mysql-test/main/explain.test +++ b/mysql-test/main/explain.test @@ -333,3 +333,34 @@ explain replace into t2 select 100, (select a from t1); drop table t1, t2; --echo # End of 10.1 tests + +--echo # +--echo # End of 10.2 test +--echo # + +--echo # +--echo # MDEV-25564: Server crashed on running some EXPLAIN statements +--echo # + +EXPLAIN (SELECT 1,3) UNION (SELECT 2,1) ORDER BY (SELECT 2); + +--echo # +--echo # MDEV-23160: SIGSEGV in Explain_node::print_explain_for_children on UNION SELECT +--echo # + +CREATE TABLE t1 (a INT); +INSERT INTO t1 VALUES (1),(2),(3); + +EXPLAIN +SELECT * +FROM t1 +WHERE + a IN (SELECT a FROM t1 + UNION + SELECT a FROM t1 ORDER BY (SELECT a)) +UNION + SELECT * FROM t1 ORDER BY (SELECT a); +drop table t1; + +explain +VALUES ( (VALUES (2))) UNION VALUES ( (SELECT 3)); diff --git a/sql/sql_explain.cc b/sql/sql_explain.cc index 8690a4a38bb..1ac17de2663 100644 --- a/sql/sql_explain.cc +++ b/sql/sql_explain.cc @@ -639,7 +639,11 @@ int Explain_node::print_explain_for_children(Explain_query *query, for (int i= 0; i < (int) children.elements(); i++) { Explain_node *node= query->get_node(children.at(i)); - if (node->print_explain(query, output, explain_flags, is_analyze)) + /* + Note: node may not be present because for certain kinds of subqueries, + the optimizer is not able to see that they were eliminated. + */ + if (node && node->print_explain(query, output, explain_flags, is_analyze)) return 1; } return 0; @@ -683,8 +687,15 @@ void Explain_node::print_explain_json_for_children(Explain_query *query, for (int i= 0; i < (int) children.elements(); i++) { Explain_node *node= query->get_node(children.at(i)); - /* Derived tables are printed inside Explain_table_access objects */ + /* + Note: node may not be present because for certain kinds of subqueries, + the optimizer is not able to see that they were eliminated. + */ + if (!node) + continue; + + /* Derived tables are printed inside Explain_table_access objects */ if (!is_connection_printable_in_json(node->connection_type)) continue; From e46217182fab8f451799624402c2466474115926 Mon Sep 17 00:00:00 2001 From: Daniel Black Date: Wed, 12 Oct 2022 10:42:54 +1100 Subject: [PATCH 33/72] MDEV-29678 Valgrind/MSAN uninitialised value errors upon PS with ALTER under ONLY_FULL_GROUP_BY st_select_lex::init_query is called in the exectuion of EXECUTE IMMEDIATE 'alter table ...'. so reset the initialization at the same point we set join= 0. --- mysql-test/main/func_group.result | 4 ++++ mysql-test/main/func_group.test | 6 ++++++ sql/sql_lex.cc | 1 + 3 files changed, 11 insertions(+) diff --git a/mysql-test/main/func_group.result b/mysql-test/main/func_group.result index c52e31b86d7..0f3169e330f 100644 --- a/mysql-test/main/func_group.result +++ b/mysql-test/main/func_group.result @@ -2548,5 +2548,9 @@ Warning 1292 Truncated incorrect DOUBLE value: 'x' Warning 1292 Truncated incorrect DOUBLE value: 'x' DROP TABLE t1; # +# MDEV-29678 Valgrind/MSAN uninitialised value errors upon PS with ALTER under ONLY_FULL_GROUP_BY +# +SET STATEMENT sql_mode=ONLY_FULL_GROUP_BY FOR EXECUTE IMMEDIATE 'ALTER TABLE mysql.time_zone_transition ORDER BY Time_zone_id, Transition_time'; +# # End of 10.3 tests # diff --git a/mysql-test/main/func_group.test b/mysql-test/main/func_group.test index e34018aafd9..862ea453b46 100644 --- a/mysql-test/main/func_group.test +++ b/mysql-test/main/func_group.test @@ -1783,6 +1783,12 @@ CREATE TABLE t1 (a BIGINT) AS SELECT 1 AS v3 UNION SELECT FALSE ; SELECT DISTINCT a IN ( COLLATION (AVG ('x'))) FROM t1 ; DROP TABLE t1; +--echo # +--echo # MDEV-29678 Valgrind/MSAN uninitialised value errors upon PS with ALTER under ONLY_FULL_GROUP_BY +--echo # + +SET STATEMENT sql_mode=ONLY_FULL_GROUP_BY FOR EXECUTE IMMEDIATE 'ALTER TABLE mysql.time_zone_transition ORDER BY Time_zone_id, Transition_time'; + --echo # --echo # End of 10.3 tests --echo # diff --git a/sql/sql_lex.cc b/sql/sql_lex.cc index c5bdfb596eb..5e4c41fe42c 100644 --- a/sql/sql_lex.cc +++ b/sql/sql_lex.cc @@ -2321,6 +2321,7 @@ void st_select_lex::init_query() item_list.empty(); min_max_opt_list.empty(); join= 0; + cur_pos_in_select_list= UNDEF_POS; having= prep_having= where= prep_where= 0; cond_pushed_into_where= cond_pushed_into_having= 0; olap= UNSPECIFIED_OLAP_TYPE; From 45755c4e1bfbde5fe0d437dc56086ccd9dbdb37a Mon Sep 17 00:00:00 2001 From: Haidong Ji Date: Tue, 13 Sep 2022 00:41:43 +0000 Subject: [PATCH 34/72] Use OPENSSL_free instead of free to avoid instance crash OpenSSL handles memory management using **OPENSSL_xxx** API[^1]. For allocation, there is `OPENSSL_malloc`. To free it, `OPENSSL_free` should be called. We've been lucky that OPENSSL (and wolfSSL)'s implementation allowed the usage of `free` for memory cleanup. However, other OpenSSL forks, such as AWS-LC[^2], is not this forgiving. It will cause a server crash. Test case `openssl_1` provides good coverage for this issue. If a user is created using: `grant select on test.* to user1@localhost require SUBJECT "...";` user1 will crash the instance during connection under AWS-LC. There have been numerous OpenSSL forks[^3]. Due to FIPS[^4] and other related regulatory requirements, MariaDB will be built using them. This fix will increase MariaDB's adaptability by using more compliant and generally accepted API. All new code of the whole pull request, including one or several files that are either new files or modified ones, are contributed under the BSD-new license. I am contributing on behalf of my employer Amazon Web Services, Inc. [^1]: https://www.openssl.org/docs/man1.1.1/man3/OPENSSL_malloc.html [^2]: https://github.com/awslabs/aws-lc [^3]: https://en.wikipedia.org/wiki/OpenSSL#Forks [^4]: https://en.wikipedia.org/wiki/FIPS_140-2 --- sql/sql_acl.cc | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/sql/sql_acl.cc b/sql/sql_acl.cc index 5b5150acab1..7057c32f2f0 100644 --- a/sql/sql_acl.cc +++ b/sql/sql_acl.cc @@ -13257,11 +13257,11 @@ static bool acl_check_ssl(THD *thd, const ACL_USER *acl_user) if (global_system_variables.log_warnings) sql_print_information("X509 issuer mismatch: should be '%s' " "but is '%s'", acl_user->x509_issuer, ptr); - free(ptr); + OPENSSL_free(ptr); X509_free(cert); return 1; } - free(ptr); + OPENSSL_free(ptr); } /* X509 subject is specified, we check it .. */ if (acl_user->x509_subject) @@ -13274,11 +13274,11 @@ static bool acl_check_ssl(THD *thd, const ACL_USER *acl_user) if (global_system_variables.log_warnings) sql_print_information("X509 subject mismatch: should be '%s' but is '%s'", acl_user->x509_subject, ptr); - free(ptr); + OPENSSL_free(ptr); X509_free(cert); return 1; } - free(ptr); + OPENSSL_free(ptr); } X509_free(cert); return 0; From 68391acef239cc468d9c11c9bbdeebd143c188b7 Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Sat, 22 Oct 2022 10:22:56 +0200 Subject: [PATCH 35/72] fix for x86 and other 32-bit little engian arch (and for 64-bit big endian) --- sql/sql_time.cc | 36 ++++++++++++++++++------------------ 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/sql/sql_time.cc b/sql/sql_time.cc index ec9b76cb3eb..1d121b7b7be 100644 --- a/sql/sql_time.cc +++ b/sql/sql_time.cc @@ -68,71 +68,71 @@ int append_interval(String *str, interval_type int_type, const INTERVAL &interva size_t len; switch (int_type) { case INTERVAL_YEAR: - len= my_snprintf(buf,sizeof(buf),"%u", interval.year); + len= my_snprintf(buf,sizeof(buf),"%lu", interval.year); break; case INTERVAL_QUARTER: case INTERVAL_MONTH: - len= my_snprintf(buf,sizeof(buf),"%u", interval.month); + len= my_snprintf(buf,sizeof(buf),"%lu", interval.month); int_type=INTERVAL_MONTH; break; case INTERVAL_WEEK: case INTERVAL_DAY: - len= my_snprintf(buf,sizeof(buf),"%u", interval.day); + len= my_snprintf(buf,sizeof(buf),"%lu", interval.day); int_type=INTERVAL_DAY; break; case INTERVAL_HOUR: - len= my_snprintf(buf,sizeof(buf),"%u", interval.hour); + len= my_snprintf(buf,sizeof(buf),"%lu", interval.hour); break; case INTERVAL_MINUTE: - len= my_snprintf(buf,sizeof(buf),"%u", interval.minute); + len= my_snprintf(buf,sizeof(buf),"%llu", interval.minute); break; case INTERVAL_SECOND: - len= my_snprintf(buf,sizeof(buf),"%u", interval.second); + len= my_snprintf(buf,sizeof(buf),"%llu", interval.second); break; case INTERVAL_MICROSECOND: - len= my_snprintf(buf,sizeof(buf),"%u", interval.second_part); + len= my_snprintf(buf,sizeof(buf),"%llu", interval.second_part); break; case INTERVAL_YEAR_MONTH: - len= my_snprintf(buf,sizeof(buf),"'%u-%02u'", + len= my_snprintf(buf,sizeof(buf),"'%lu-%02lu'", interval.year, interval.month); break; case INTERVAL_DAY_HOUR: - len= my_snprintf(buf,sizeof(buf),"'%u %u'", interval.day, interval.hour); + len= my_snprintf(buf,sizeof(buf),"'%lu %lu'", interval.day, interval.hour); break; case INTERVAL_DAY_MINUTE: - len= my_snprintf(buf,sizeof(buf),"'%u %u:%02u'", + len= my_snprintf(buf,sizeof(buf),"'%lu %lu:%02llu'", interval.day, interval.hour, interval.minute); break; case INTERVAL_DAY_SECOND: - len= my_snprintf(buf,sizeof(buf),"'%u %u:%02u:%02u'", + len= my_snprintf(buf,sizeof(buf),"'%lu %lu:%02llu:%02llu'", interval.day, interval.hour, interval.minute, interval.second); break; case INTERVAL_HOUR_MINUTE: - len= my_snprintf(buf,sizeof(buf),"'%u:%02u'", interval.hour, interval.minute); + len= my_snprintf(buf,sizeof(buf),"'%lu:%02llu'", interval.hour, interval.minute); break; case INTERVAL_HOUR_SECOND: - len= my_snprintf(buf,sizeof(buf),"'%u:%02u:%02u'", + len= my_snprintf(buf,sizeof(buf),"'%lu:%02llu:%02llu'", interval.hour, interval.minute, interval.second); break; case INTERVAL_MINUTE_SECOND: - len= my_snprintf(buf,sizeof(buf),"'%u:%02u'", interval.minute, interval.second); + len= my_snprintf(buf,sizeof(buf),"'%llu:%02llu'", interval.minute, interval.second); break; case INTERVAL_DAY_MICROSECOND: - len= my_snprintf(buf,sizeof(buf),"'%u %u:%02u:%02u.%06u'", + len= my_snprintf(buf,sizeof(buf),"'%lu %lu:%02llu:%02llu.%06llu'", interval.day, interval.hour, interval.minute, interval.second, interval.second_part); break; case INTERVAL_HOUR_MICROSECOND: - len= my_snprintf(buf,sizeof(buf),"'%u:%02u:%02u.%06u'", + len= my_snprintf(buf,sizeof(buf),"'%lu:%02llu:%02llu.%06llu'", interval.hour, interval.minute, interval.second, interval.second_part); break; case INTERVAL_MINUTE_MICROSECOND: - len= my_snprintf(buf,sizeof(buf),"'%u:%02u.%06u'", + len= my_snprintf(buf,sizeof(buf),"'%llu:%02llu.%06llu'", interval.minute, interval.second, interval.second_part); break; case INTERVAL_SECOND_MICROSECOND: - len= my_snprintf(buf,sizeof(buf),"%u.%06u", interval.second, interval.second_part); + len= my_snprintf(buf,sizeof(buf),"%llu.%06llu", interval.second, interval.second_part); break; default: DBUG_ASSERT(0); From 3e377fd35bf78905ea5d6564ec865d4877e924e5 Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Fri, 21 Oct 2022 19:40:08 +0200 Subject: [PATCH 36/72] MDEV-15795 Stack exceeded if pthread_attr_setstacksize(&thr_attr,8196) succeeds on Linux this pthread_attr_setstacksize() fails with EINVAL "The stack size is less than PTHREAD_STACK_MIN (16384) bytes". But on FreeBSD it succeeds and causes a crash later, as 8196 is too little. Let's keep the stack at its default size in the timer thread. --- mysys/my_pthread.c | 1 - mysys/thr_alarm.c | 1 - mysys/thr_timer.c | 1 - 3 files changed, 3 deletions(-) diff --git a/mysys/my_pthread.c b/mysys/my_pthread.c index e2795ed7bb9..dc6e0904951 100644 --- a/mysys/my_pthread.c +++ b/mysys/my_pthread.c @@ -263,7 +263,6 @@ int sigwait(sigset_t *setp, int *sigp) pthread_attr_init(&thr_attr); pthread_attr_setscope(&thr_attr,PTHREAD_SCOPE_PROCESS); pthread_attr_setdetachstate(&thr_attr,PTHREAD_CREATE_DETACHED); - pthread_attr_setstacksize(&thr_attr,8196); pthread_create(&sigwait_thread_id, &thr_attr, sigwait_thread, setp); pthread_attr_destroy(&thr_attr); } diff --git a/mysys/thr_alarm.c b/mysys/thr_alarm.c index 8a89762de2a..f6eb963c34c 100644 --- a/mysys/thr_alarm.c +++ b/mysys/thr_alarm.c @@ -114,7 +114,6 @@ void init_thr_alarm(uint max_alarms) pthread_attr_init(&thr_attr); pthread_attr_setscope(&thr_attr,PTHREAD_SCOPE_PROCESS); pthread_attr_setdetachstate(&thr_attr,PTHREAD_CREATE_DETACHED); - pthread_attr_setstacksize(&thr_attr,8196); mysql_thread_create(key_thread_alarm, &alarm_thread, &thr_attr, alarm_handler, NULL); pthread_attr_destroy(&thr_attr); diff --git a/mysys/thr_timer.c b/mysys/thr_timer.c index 1532875d7f3..1b614ac48bd 100644 --- a/mysys/thr_timer.c +++ b/mysys/thr_timer.c @@ -85,7 +85,6 @@ my_bool init_thr_timer(uint alloc_timers) /* Create a thread to handle timers */ pthread_attr_init(&thr_attr); pthread_attr_setscope(&thr_attr,PTHREAD_SCOPE_PROCESS); - pthread_attr_setstacksize(&thr_attr,8196); thr_timer_inited= 1; if (mysql_thread_create(key_thread_timer, &timer_thread, &thr_attr, timer_handler, NULL)) From 0609b345554f9a148e165c497aadbe368e0900aa Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Fri, 21 Oct 2022 20:37:09 +0200 Subject: [PATCH 37/72] disable LTO in debian builds --- debian/rules | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/debian/rules b/debian/rules index 6c46c2f4670..99f7e3b7d2c 100755 --- a/debian/rules +++ b/debian/rules @@ -5,7 +5,7 @@ export DEB_BUILD_HARDENING=1 # enable Debian Hardening # see: https://wiki.debian.org/Hardening -export DEB_BUILD_MAINT_OPTIONS = hardening=+all +export DEB_BUILD_MAINT_OPTIONS = hardening=+all optimize=-lto DPKG_EXPORT_BUILDFLAGS = 1 include /usr/share/dpkg/default.mk From 16d4431ab67d77be78171edcf395a1300b0add57 Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Sat, 22 Oct 2022 11:45:38 +0200 Subject: [PATCH 38/72] CONNECT: compile with libxml2 2.10.x storage/connect/libdoc.cpp:603:17: error: 'void xmlXPathInit()' is deprecated [-Werror=deprecated-declarations] --- storage/connect/CMakeLists.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/storage/connect/CMakeLists.txt b/storage/connect/CMakeLists.txt index d7651680e1c..d4c19e9e34b 100644 --- a/storage/connect/CMakeLists.txt +++ b/storage/connect/CMakeLists.txt @@ -69,6 +69,7 @@ IF(UNIX) DISABLE_WARNING("format-truncation") DISABLE_WARNING("implicit-fallthrough") DISABLE_WARNING("type-limits") + DISABLE_WARNING("deprecated-declarations") endif(NOT WITH_WARNINGS) add_definitions( -DUNIX -DLINUX -DUBUNTU ) From 2a57396e59e42cbfac51bed5231c2bdb2d7fe39a Mon Sep 17 00:00:00 2001 From: Alexander Barkov Date: Fri, 21 Oct 2022 12:33:22 +0400 Subject: [PATCH 39/72] MDEV-29481 mariadb-upgrade prints confusing statement This is a new version of the patch instead of the reverted: MDEV-28727 ALTER TABLE ALGORITHM=NOCOPY does not work after upgrade Ignore the difference in key packing flags HA_BINARY_PACK_KEY and HA_PACK_KEY during ALTER to allow ALGORITHM=INSTANT and ALGORITHM=NOCOPY in more cases. If for some reasons (e.g. due to a bug fix such as MDEV-20704) these cumulative (over all segments) flags in KEY::flags are different for the old and new table inside compare_keys_but_name(), the difference in HA_BINARY_PACK_KEY and HA_PACK_KEY in KEY::flags is not really important: MyISAM and Aria can handle such cases well: per-segment flags are stored in MYI and MAI files anyway and they are read during ha_myisam::open() ha_maria::open() time. So indexes get opened with correct per-segment flags that were calculated during the table CREATE time, no matter what the old (CREATE time) and new (ALTER TIME) per-index compression flags are, and no matter if they are equal or not. All other engine ignore key compression flags, so this change is safe for other engines as well. --- include/my_base.h | 4 +- .../main/alter_table_upgrade_aria.result | 53 ++++++++++ mysql-test/main/alter_table_upgrade_aria.test | 21 ++++ ...er_table_upgrade_mdev29481_myisam_aria.inc | 59 +++++++++++ .../main/alter_table_upgrade_myisam.result | 52 ++++++++++ .../main/alter_table_upgrade_myisam.test | 17 ++++ .../alter_table_upgrade_myisam_debug.result | 92 ++++++++++++++++++ .../alter_table_upgrade_myisam_debug.test | 19 ++++ .../mysql_upgrade/mdev29481_100104_aria.MAD | Bin 0 -> 8192 bytes .../mysql_upgrade/mdev29481_100104_aria.MAI | Bin 0 -> 8192 bytes .../mysql_upgrade/mdev29481_100104_aria.frm | Bin 0 -> 923 bytes .../mysql_upgrade/mdev29481_100104_innodb.frm | Bin 0 -> 934 bytes .../mysql_upgrade/mdev29481_100104_myisam.MYD | 0 .../mysql_upgrade/mdev29481_100104_myisam.MYI | Bin 0 -> 1024 bytes .../mysql_upgrade/mdev29481_100104_myisam.frm | Bin 0 -> 925 bytes .../suite/innodb/r/alter_table_upgrade.result | 36 +++++++ .../suite/innodb/t/alter_table_upgrade.test | 36 +++++++ 17 files changed, 387 insertions(+), 2 deletions(-) create mode 100644 mysql-test/main/alter_table_upgrade_aria.result create mode 100644 mysql-test/main/alter_table_upgrade_aria.test create mode 100644 mysql-test/main/alter_table_upgrade_mdev29481_myisam_aria.inc create mode 100644 mysql-test/main/alter_table_upgrade_myisam.result create mode 100644 mysql-test/main/alter_table_upgrade_myisam.test create mode 100644 mysql-test/main/alter_table_upgrade_myisam_debug.result create mode 100644 mysql-test/main/alter_table_upgrade_myisam_debug.test create mode 100644 mysql-test/std_data/mysql_upgrade/mdev29481_100104_aria.MAD create mode 100644 mysql-test/std_data/mysql_upgrade/mdev29481_100104_aria.MAI create mode 100644 mysql-test/std_data/mysql_upgrade/mdev29481_100104_aria.frm create mode 100644 mysql-test/std_data/mysql_upgrade/mdev29481_100104_innodb.frm create mode 100644 mysql-test/std_data/mysql_upgrade/mdev29481_100104_myisam.MYD create mode 100644 mysql-test/std_data/mysql_upgrade/mdev29481_100104_myisam.MYI create mode 100644 mysql-test/std_data/mysql_upgrade/mdev29481_100104_myisam.frm create mode 100644 mysql-test/suite/innodb/r/alter_table_upgrade.result create mode 100644 mysql-test/suite/innodb/t/alter_table_upgrade.test diff --git a/include/my_base.h b/include/my_base.h index 7016766ce58..d045251778f 100644 --- a/include/my_base.h +++ b/include/my_base.h @@ -272,8 +272,8 @@ enum ha_base_keytype { #define HA_GENERATED_KEY 8192U /* Automatically generated key */ /* The combination of the above can be used for key type comparison. */ -#define HA_KEYFLAG_MASK (HA_NOSAME | HA_PACK_KEY | HA_AUTO_KEY | \ - HA_BINARY_PACK_KEY | HA_FULLTEXT | HA_UNIQUE_CHECK | \ +#define HA_KEYFLAG_MASK (HA_NOSAME | HA_AUTO_KEY | \ + HA_FULLTEXT | HA_UNIQUE_CHECK | \ HA_SPATIAL | HA_NULL_ARE_EQUAL | HA_GENERATED_KEY) /* diff --git a/mysql-test/main/alter_table_upgrade_aria.result b/mysql-test/main/alter_table_upgrade_aria.result new file mode 100644 index 00000000000..10afd128649 --- /dev/null +++ b/mysql-test/main/alter_table_upgrade_aria.result @@ -0,0 +1,53 @@ +# +# Start of 10.4 tests +# +# +# MDEV-29481 mariadb-upgrade prints confusing statement +# +SET @debug_key_flags=NULL; +SET default_storage_engine=ARIA; +CREATE PROCEDURE debug_show_key_flags() +BEGIN +IF @debug_key_flags IS TRUE +THEN +FLUSH TABLES; +-- Wrap SET into EXECUTE IMMEDIATE to avoid +-- parse time "Unknown system variable" errors in release builds. +EXECUTE IMMEDIATE "SET debug_dbug='+d,key'"; +SELECT * FROM t1 LIMIT 0; +EXECUTE IMMEDIATE "SET debug_dbug=''"; +END IF; +END; +$$ +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `d` double(18,7) DEFAULT NULL, + KEY `d` (`d`) +) ENGINE=Aria DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci PAGE_CHECKSUM=1 +CHECK TABLE t1 FOR UPGRADE; +Table Op Msg_type Msg_text +test.t1 check status OK +DROP TABLE t1; +CALL debug_show_key_flags(); +ALTER TABLE t1 MODIFY d DOUBLE DEFAULT 10, ALGORITHM=INSTANT; +CALL debug_show_key_flags(); +DROP TABLE t1; +CALL debug_show_key_flags(); +ALTER TABLE t1 MODIFY d DOUBLE DEFAULT 10, ALGORITHM=NOCOPY; +CALL debug_show_key_flags(); +DROP TABLE t1; +CALL debug_show_key_flags(); +REPAIR TABLE t1; +Table Op Msg_type Msg_text +test.t1 repair status OK +CALL debug_show_key_flags(); +DROP TABLE t1; +CALL debug_show_key_flags(); +ALTER TABLE t1 FORCE; +CALL debug_show_key_flags(); +DROP TABLE t1; +DROP PROCEDURE debug_show_key_flags; +# +# End of 10.4 tests +# diff --git a/mysql-test/main/alter_table_upgrade_aria.test b/mysql-test/main/alter_table_upgrade_aria.test new file mode 100644 index 00000000000..5b87095f515 --- /dev/null +++ b/mysql-test/main/alter_table_upgrade_aria.test @@ -0,0 +1,21 @@ +--source include/have_aria.inc + +--echo # +--echo # Start of 10.4 tests +--echo # + +--echo # +--echo # MDEV-29481 mariadb-upgrade prints confusing statement +--echo # + +let $table= std_data/mysql_upgrade/mdev29481_100104_aria; +let $EXT_DAT= MAD; +let $EXT_IDX= MAI; +SET @debug_key_flags=NULL; +SET default_storage_engine=ARIA; +--source alter_table_upgrade_mdev29481_myisam_aria.inc + + +--echo # +--echo # End of 10.4 tests +--echo # diff --git a/mysql-test/main/alter_table_upgrade_mdev29481_myisam_aria.inc b/mysql-test/main/alter_table_upgrade_mdev29481_myisam_aria.inc new file mode 100644 index 00000000000..0a8759eccdd --- /dev/null +++ b/mysql-test/main/alter_table_upgrade_mdev29481_myisam_aria.inc @@ -0,0 +1,59 @@ +let $datadir=`select @@datadir`; + +DELIMITER $$; +CREATE PROCEDURE debug_show_key_flags() +BEGIN + IF @debug_key_flags IS TRUE + THEN + FLUSH TABLES; + -- Wrap SET into EXECUTE IMMEDIATE to avoid + -- parse time "Unknown system variable" errors in release builds. + EXECUTE IMMEDIATE "SET debug_dbug='+d,key'"; + SELECT * FROM t1 LIMIT 0; + EXECUTE IMMEDIATE "SET debug_dbug=''"; + END IF; +END; +$$ +DELIMITER ;$$ + + +copy_file $table.frm $datadir/test/t1.frm; +copy_file $table.$EXT_DAT $datadir/test/t1.$EXT_DAT; +copy_file $table.$EXT_IDX $datadir/test/t1.$EXT_IDX; +SHOW CREATE TABLE t1; +CHECK TABLE t1 FOR UPGRADE; +DROP TABLE t1; + +copy_file $table.frm $datadir/test/t1.frm; +copy_file $table.$EXT_DAT $datadir/test/t1.$EXT_DAT; +copy_file $table.$EXT_IDX $datadir/test/t1.$EXT_IDX; +CALL debug_show_key_flags(); +ALTER TABLE t1 MODIFY d DOUBLE DEFAULT 10, ALGORITHM=INSTANT; +CALL debug_show_key_flags(); +DROP TABLE t1; + +copy_file $table.frm $datadir/test/t1.frm; +copy_file $table.$EXT_DAT $datadir/test/t1.$EXT_DAT; +copy_file $table.$EXT_IDX $datadir/test/t1.$EXT_IDX; +CALL debug_show_key_flags(); +ALTER TABLE t1 MODIFY d DOUBLE DEFAULT 10, ALGORITHM=NOCOPY; +CALL debug_show_key_flags(); +DROP TABLE t1; + +copy_file $table.frm $datadir/test/t1.frm; +copy_file $table.$EXT_DAT $datadir/test/t1.$EXT_DAT; +copy_file $table.$EXT_IDX $datadir/test/t1.$EXT_IDX; +CALL debug_show_key_flags(); +REPAIR TABLE t1; +CALL debug_show_key_flags(); +DROP TABLE t1; + +copy_file $table.frm $datadir/test/t1.frm; +copy_file $table.$EXT_DAT $datadir/test/t1.$EXT_DAT; +copy_file $table.$EXT_IDX $datadir/test/t1.$EXT_IDX; +CALL debug_show_key_flags(); +ALTER TABLE t1 FORCE; +CALL debug_show_key_flags(); +DROP TABLE t1; + +DROP PROCEDURE debug_show_key_flags; diff --git a/mysql-test/main/alter_table_upgrade_myisam.result b/mysql-test/main/alter_table_upgrade_myisam.result new file mode 100644 index 00000000000..06bd1b70a0a --- /dev/null +++ b/mysql-test/main/alter_table_upgrade_myisam.result @@ -0,0 +1,52 @@ +# +# Start of 10.4 tests +# +# +# MDEV-29481 mariadb-upgrade prints confusing statement +# +SET @debug_key_flags=NULL; +CREATE PROCEDURE debug_show_key_flags() +BEGIN +IF @debug_key_flags IS TRUE +THEN +FLUSH TABLES; +-- Wrap SET into EXECUTE IMMEDIATE to avoid +-- parse time "Unknown system variable" errors in release builds. +EXECUTE IMMEDIATE "SET debug_dbug='+d,key'"; +SELECT * FROM t1 LIMIT 0; +EXECUTE IMMEDIATE "SET debug_dbug=''"; +END IF; +END; +$$ +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `d` double(18,7) DEFAULT NULL, + KEY `d` (`d`) +) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci +CHECK TABLE t1 FOR UPGRADE; +Table Op Msg_type Msg_text +test.t1 check status OK +DROP TABLE t1; +CALL debug_show_key_flags(); +ALTER TABLE t1 MODIFY d DOUBLE DEFAULT 10, ALGORITHM=INSTANT; +CALL debug_show_key_flags(); +DROP TABLE t1; +CALL debug_show_key_flags(); +ALTER TABLE t1 MODIFY d DOUBLE DEFAULT 10, ALGORITHM=NOCOPY; +CALL debug_show_key_flags(); +DROP TABLE t1; +CALL debug_show_key_flags(); +REPAIR TABLE t1; +Table Op Msg_type Msg_text +test.t1 repair status OK +CALL debug_show_key_flags(); +DROP TABLE t1; +CALL debug_show_key_flags(); +ALTER TABLE t1 FORCE; +CALL debug_show_key_flags(); +DROP TABLE t1; +DROP PROCEDURE debug_show_key_flags; +# +# End of 10.4 tests +# diff --git a/mysql-test/main/alter_table_upgrade_myisam.test b/mysql-test/main/alter_table_upgrade_myisam.test new file mode 100644 index 00000000000..251ca3e3555 --- /dev/null +++ b/mysql-test/main/alter_table_upgrade_myisam.test @@ -0,0 +1,17 @@ +--echo # +--echo # Start of 10.4 tests +--echo # + +--echo # +--echo # MDEV-29481 mariadb-upgrade prints confusing statement +--echo # + +let $table= std_data/mysql_upgrade/mdev29481_100104_myisam; +let $EXT_DAT= MYD; +let $EXT_IDX= MYI; +SET @debug_key_flags=NULL; +--source alter_table_upgrade_mdev29481_myisam_aria.inc + +--echo # +--echo # End of 10.4 tests +--echo # diff --git a/mysql-test/main/alter_table_upgrade_myisam_debug.result b/mysql-test/main/alter_table_upgrade_myisam_debug.result new file mode 100644 index 00000000000..ed135585d9d --- /dev/null +++ b/mysql-test/main/alter_table_upgrade_myisam_debug.result @@ -0,0 +1,92 @@ +# +# Start of 10.4 tests +# +# +# MDEV-29481 mariadb-upgrade prints confusing statement +# +SET @debug_key_flags=TRUE; +CREATE PROCEDURE debug_show_key_flags() +BEGIN +IF @debug_key_flags IS TRUE +THEN +FLUSH TABLES; +-- Wrap SET into EXECUTE IMMEDIATE to avoid +-- parse time "Unknown system variable" errors in release builds. +EXECUTE IMMEDIATE "SET debug_dbug='+d,key'"; +SELECT * FROM t1 LIMIT 0; +EXECUTE IMMEDIATE "SET debug_dbug=''"; +END IF; +END; +$$ +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `d` double(18,7) DEFAULT NULL, + KEY `d` (`d`) +) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci +CHECK TABLE t1 FOR UPGRADE; +Table Op Msg_type Msg_text +test.t1 check status OK +DROP TABLE t1; +CALL debug_show_key_flags(); +d +Warnings: +Note 1105 DBUG: ha_myisam::open: name=`d` flags=00000068 (HA_NULL_PART_KEY|HA_BINARY_PACK_KEY|HA_VAR_LENGTH_KEY) +Note 1105 DBUG: seg[0].type=6 DOUBLE +Note 1105 DBUG: seg[0].flag=00000850 (HA_CAN_MEMCMP|HA_SWAP_KEY|HA_NULL_PART) +ALTER TABLE t1 MODIFY d DOUBLE DEFAULT 10, ALGORITHM=INSTANT; +CALL debug_show_key_flags(); +d +Warnings: +Note 1105 DBUG: ha_myisam::open: name=`d` flags=00000068 (HA_NULL_PART_KEY|HA_BINARY_PACK_KEY|HA_VAR_LENGTH_KEY) +Note 1105 DBUG: seg[0].type=6 DOUBLE +Note 1105 DBUG: seg[0].flag=00000850 (HA_CAN_MEMCMP|HA_SWAP_KEY|HA_NULL_PART) +DROP TABLE t1; +CALL debug_show_key_flags(); +d +Warnings: +Note 1105 DBUG: ha_myisam::open: name=`d` flags=00000068 (HA_NULL_PART_KEY|HA_BINARY_PACK_KEY|HA_VAR_LENGTH_KEY) +Note 1105 DBUG: seg[0].type=6 DOUBLE +Note 1105 DBUG: seg[0].flag=00000850 (HA_CAN_MEMCMP|HA_SWAP_KEY|HA_NULL_PART) +ALTER TABLE t1 MODIFY d DOUBLE DEFAULT 10, ALGORITHM=NOCOPY; +CALL debug_show_key_flags(); +d +Warnings: +Note 1105 DBUG: ha_myisam::open: name=`d` flags=00000068 (HA_NULL_PART_KEY|HA_BINARY_PACK_KEY|HA_VAR_LENGTH_KEY) +Note 1105 DBUG: seg[0].type=6 DOUBLE +Note 1105 DBUG: seg[0].flag=00000850 (HA_CAN_MEMCMP|HA_SWAP_KEY|HA_NULL_PART) +DROP TABLE t1; +CALL debug_show_key_flags(); +d +Warnings: +Note 1105 DBUG: ha_myisam::open: name=`d` flags=00000068 (HA_NULL_PART_KEY|HA_BINARY_PACK_KEY|HA_VAR_LENGTH_KEY) +Note 1105 DBUG: seg[0].type=6 DOUBLE +Note 1105 DBUG: seg[0].flag=00000850 (HA_CAN_MEMCMP|HA_SWAP_KEY|HA_NULL_PART) +REPAIR TABLE t1; +Table Op Msg_type Msg_text +test.t1 repair status OK +CALL debug_show_key_flags(); +d +Warnings: +Note 1105 DBUG: ha_myisam::open: name=`d` flags=00000068 (HA_NULL_PART_KEY|HA_BINARY_PACK_KEY|HA_VAR_LENGTH_KEY) +Note 1105 DBUG: seg[0].type=6 DOUBLE +Note 1105 DBUG: seg[0].flag=00000850 (HA_CAN_MEMCMP|HA_SWAP_KEY|HA_NULL_PART) +DROP TABLE t1; +CALL debug_show_key_flags(); +d +Warnings: +Note 1105 DBUG: ha_myisam::open: name=`d` flags=00000068 (HA_NULL_PART_KEY|HA_BINARY_PACK_KEY|HA_VAR_LENGTH_KEY) +Note 1105 DBUG: seg[0].type=6 DOUBLE +Note 1105 DBUG: seg[0].flag=00000850 (HA_CAN_MEMCMP|HA_SWAP_KEY|HA_NULL_PART) +ALTER TABLE t1 FORCE; +CALL debug_show_key_flags(); +d +Warnings: +Note 1105 DBUG: ha_myisam::open: name=`d` flags=00000048 (HA_NULL_PART_KEY|HA_VAR_LENGTH_KEY) +Note 1105 DBUG: seg[0].type=6 DOUBLE +Note 1105 DBUG: seg[0].flag=00000850 (HA_CAN_MEMCMP|HA_SWAP_KEY|HA_NULL_PART) +DROP TABLE t1; +DROP PROCEDURE debug_show_key_flags; +# +# End of 10.4 tests +# diff --git a/mysql-test/main/alter_table_upgrade_myisam_debug.test b/mysql-test/main/alter_table_upgrade_myisam_debug.test new file mode 100644 index 00000000000..8e26bcd2453 --- /dev/null +++ b/mysql-test/main/alter_table_upgrade_myisam_debug.test @@ -0,0 +1,19 @@ +--source include/have_debug.inc + +--echo # +--echo # Start of 10.4 tests +--echo # + +--echo # +--echo # MDEV-29481 mariadb-upgrade prints confusing statement +--echo # + +let $table= std_data/mysql_upgrade/mdev29481_100104_myisam; +let $EXT_DAT= MYD; +let $EXT_IDX= MYI; +SET @debug_key_flags=TRUE; +--source alter_table_upgrade_mdev29481_myisam_aria.inc + +--echo # +--echo # End of 10.4 tests +--echo # diff --git a/mysql-test/std_data/mysql_upgrade/mdev29481_100104_aria.MAD b/mysql-test/std_data/mysql_upgrade/mdev29481_100104_aria.MAD new file mode 100644 index 0000000000000000000000000000000000000000..3dcc005ec0d03681b402e75f595130e784a4a5d5 GIT binary patch literal 8192 zcmeIu0Sy2E3<4nghrZ_c1`$XwV8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b* J20jm5+W{%^1N;C0 literal 0 HcmV?d00001 diff --git a/mysql-test/std_data/mysql_upgrade/mdev29481_100104_aria.MAI b/mysql-test/std_data/mysql_upgrade/mdev29481_100104_aria.MAI new file mode 100644 index 0000000000000000000000000000000000000000..d11da43bf2bde4728b7301bc49c16fcf25ae6daf GIT binary patch literal 8192 zcmeIuu?oU45C-5s4XrJdf|HH~#W!$tc6AV3+*}+T++74mSD(STtIy#JDCi(guC14} z0V~xf_>U&n%NrP3Q&Lo i6rcbFC_n)UP=Epypa2CZKmiI+fC3bt00k(}B=837oHJ7Z literal 0 HcmV?d00001 diff --git a/mysql-test/std_data/mysql_upgrade/mdev29481_100104_aria.frm b/mysql-test/std_data/mysql_upgrade/mdev29481_100104_aria.frm new file mode 100644 index 0000000000000000000000000000000000000000..81d7672c4055329b46bf0b2722da021988142c98 GIT binary patch literal 923 zcmeyz$f+g75XQjBFq@fy;U^;}0~|0(GjK34u!8tN8UlVY0y*uB416#F27#6pyo#pt z1>Y_^_$1^-$=9c8ObiT+KxHfpnLvF&1_NUQP)NI-gW-S5f4II;#&8S)r1)iFa4gD9 sgm}`F(G-*rMlb+*UkHdff%yUk0vN==`2)-sVgP3nAe$AK+dw%50P?{ZKL7v# literal 0 HcmV?d00001 diff --git a/mysql-test/std_data/mysql_upgrade/mdev29481_100104_innodb.frm b/mysql-test/std_data/mysql_upgrade/mdev29481_100104_innodb.frm new file mode 100644 index 0000000000000000000000000000000000000000..3ff86d1dca1d299301b9bcf0c19ed928e9c81faa GIT binary patch literal 934 zcmeyz$jKwb5XQjBu#B03;U^;}0~|2PF>o+2u!8uCFu|XU3=ACYj0^%W0R{oJWtLAL zcL}~(b(F37M*Xhh3?>E!MxZiwhD@M-AcKLi0Vt&1&cX0MGo`}tKV0i5W7vfNQslBR zc;@BhyEsAoXvb&=N(v(wfV?jR#GDMg@K6X~5Ci8Buz(N)IGX_3tcnZ_|C35Hb5i0< KGILY^GXMbmSRTCq literal 0 HcmV?d00001 diff --git a/mysql-test/std_data/mysql_upgrade/mdev29481_100104_myisam.MYD b/mysql-test/std_data/mysql_upgrade/mdev29481_100104_myisam.MYD new file mode 100644 index 00000000000..e69de29bb2d diff --git a/mysql-test/std_data/mysql_upgrade/mdev29481_100104_myisam.MYI b/mysql-test/std_data/mysql_upgrade/mdev29481_100104_myisam.MYI new file mode 100644 index 0000000000000000000000000000000000000000..d36f27ac0cf00dce42d7f47571bcd566c7c18bbd GIT binary patch literal 1024 zcmezOkDZZ$i7|v>149bK5e7yEAmRX$K=2<-Vj=!R0Yr)giwYbY_^_$1^-$=9bDObiT+KxHfpnLvF&1_NUQP)NI-gW-S5f4II;#&8S)r1)iH@U8R= ucJzgK)0EK^loUoV0C`^sh&h2d0|o*Z#K1WO%okz+XA>Zs6`0>Zc?AH~4H^#s literal 0 HcmV?d00001 diff --git a/mysql-test/suite/innodb/r/alter_table_upgrade.result b/mysql-test/suite/innodb/r/alter_table_upgrade.result new file mode 100644 index 00000000000..eebabd561ca --- /dev/null +++ b/mysql-test/suite/innodb/r/alter_table_upgrade.result @@ -0,0 +1,36 @@ +# +# Start of 10.4 tests +# +# +# MDEV-29481 mariadb-upgrade prints confusing statement +# +CREATE TABLE pet4 ( +build_time double(18,7) DEFAULT NULL, +KEY idx1 (build_time)) ENGINE=InnoDB; +FLUSH TABLES; +SHOW CREATE TABLE pet4; +Table Create Table +pet4 CREATE TABLE `pet4` ( + `build_time` double(18,7) DEFAULT NULL, + KEY `idx1` (`build_time`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_general_ci +CHECK TABLE pet4 FOR UPGRADE; +Table Op Msg_type Msg_text +test.pet4 check status OK +ALTER TABLE pet4 ADD i1 INTEGER, ALGORITHM=INSTANT; +DROP TABLE pet4; +CREATE TABLE pet4 ( +build_time double(18,7) DEFAULT NULL, +KEY idx1 (build_time)) ENGINE=InnoDB; +FLUSH TABLES; +SHOW CREATE TABLE pet4; +Table Create Table +pet4 CREATE TABLE `pet4` ( + `build_time` double(18,7) DEFAULT NULL, + KEY `idx1` (`build_time`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_general_ci +ALTER TABLE pet4 ADD i1 INTEGER, ALGORITHM=NOCOPY; +DROP TABLE pet4; +# +# End of 10.4 tests +# diff --git a/mysql-test/suite/innodb/t/alter_table_upgrade.test b/mysql-test/suite/innodb/t/alter_table_upgrade.test new file mode 100644 index 00000000000..cd058aeee3c --- /dev/null +++ b/mysql-test/suite/innodb/t/alter_table_upgrade.test @@ -0,0 +1,36 @@ +--source include/have_innodb.inc + +let $datadir=`select @@datadir`; + +--echo # +--echo # Start of 10.4 tests +--echo # + +--echo # +--echo # MDEV-29481 mariadb-upgrade prints confusing statement +--echo # + +CREATE TABLE pet4 ( + build_time double(18,7) DEFAULT NULL, + KEY idx1 (build_time)) ENGINE=InnoDB; +FLUSH TABLES; +remove_file $datadir/test/pet4.frm; +copy_file std_data/mysql_upgrade/mdev29481_100104_innodb.frm $datadir/test/pet4.frm; +SHOW CREATE TABLE pet4; +CHECK TABLE pet4 FOR UPGRADE; +ALTER TABLE pet4 ADD i1 INTEGER, ALGORITHM=INSTANT; +DROP TABLE pet4; + +CREATE TABLE pet4 ( + build_time double(18,7) DEFAULT NULL, + KEY idx1 (build_time)) ENGINE=InnoDB; +FLUSH TABLES; +remove_file $datadir/test/pet4.frm; +copy_file std_data/mysql_upgrade/mdev29481_100104_innodb.frm $datadir/test/pet4.frm; +SHOW CREATE TABLE pet4; +ALTER TABLE pet4 ADD i1 INTEGER, ALGORITHM=NOCOPY; +DROP TABLE pet4; + +--echo # +--echo # End of 10.4 tests +--echo # From 741c14cbdd09ace171e0630a4231de27d8cc7dd0 Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Sat, 22 Oct 2022 12:33:09 +0200 Subject: [PATCH 40/72] remove two acl_cache->clear() * to "clear hostname cache" one needs to use hostname_cache->clear() * no need to clear acl_cache for SET DEFAULT ROLE --- sql/sql_acl.cc | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/sql/sql_acl.cc b/sql/sql_acl.cc index 7057c32f2f0..5a2865e535e 100644 --- a/sql/sql_acl.cc +++ b/sql/sql_acl.cc @@ -3456,7 +3456,7 @@ bool change_password(THD *thd, LEX_USER *user) goto end; } - acl_cache->clear(1); // Clear locked hostname cache + hostname_cache_refresh(); // Clear locked hostname cache mysql_mutex_unlock(&acl_cache->lock); result= 0; if (mysql_bin_log.is_open()) @@ -3621,7 +3621,6 @@ int acl_set_default_role(THD *thd, const char *host, const char *user, goto end; } - acl_cache->clear(1); mysql_mutex_unlock(&acl_cache->lock); result= 0; if (mysql_bin_log.is_open()) From 7a2f99564932ff51e7008da1f6e1553467e469a1 Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Sat, 22 Oct 2022 17:06:50 +0200 Subject: [PATCH 41/72] cleanup: rename test file --- ...propagate-29458.result => role_grant_propagate.result} | 6 ++++++ ...ant_propagate-29458.test => role_grant_propagate.test} | 8 ++++++++ 2 files changed, 14 insertions(+) rename mysql-test/suite/roles/{role_grant_propagate-29458.result => role_grant_propagate.result} (97%) rename mysql-test/suite/roles/{role_grant_propagate-29458.test => role_grant_propagate.test} (97%) diff --git a/mysql-test/suite/roles/role_grant_propagate-29458.result b/mysql-test/suite/roles/role_grant_propagate.result similarity index 97% rename from mysql-test/suite/roles/role_grant_propagate-29458.result rename to mysql-test/suite/roles/role_grant_propagate.result index 88d3c0e38fb..5f6288b08c0 100644 --- a/mysql-test/suite/roles/role_grant_propagate-29458.result +++ b/mysql-test/suite/roles/role_grant_propagate.result @@ -1,3 +1,6 @@ +# +# MDEV-29458 Role grant commands do not propagate all grants +# create user foo; create database some_db; create table some_db.t1 (a int, b int, secret int); @@ -134,3 +137,6 @@ grant select(user) on mysql.user to test_role2; drop role test_role1, test_role2; create role test_role1; drop role test_role1; +# +# End of 10.3 tests +# diff --git a/mysql-test/suite/roles/role_grant_propagate-29458.test b/mysql-test/suite/roles/role_grant_propagate.test similarity index 97% rename from mysql-test/suite/roles/role_grant_propagate-29458.test rename to mysql-test/suite/roles/role_grant_propagate.test index 1b0906dce25..b909b71a5bb 100644 --- a/mysql-test/suite/roles/role_grant_propagate-29458.test +++ b/mysql-test/suite/roles/role_grant_propagate.test @@ -1,5 +1,9 @@ --source include/not_embedded.inc +--echo # +--echo # MDEV-29458 Role grant commands do not propagate all grants +--echo # + create user foo; create database some_db; create table some_db.t1 (a int, b int, secret int); @@ -161,3 +165,7 @@ drop role test_role1, test_role2; create role test_role1; drop role test_role1; + +--echo # +--echo # End of 10.3 tests +--echo # From 68fb05c360897112fe14038beffff7937d4337e6 Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Sat, 22 Oct 2022 17:11:04 +0200 Subject: [PATCH 42/72] MDEV-29851 Cached role privileges are not invalidated when needed GRANT ROLE can update db-level privileges -> must invalidate acl_cache --- .../suite/roles/role_grant_propagate.result | 25 ++++++++++++++++ .../suite/roles/role_grant_propagate.test | 30 +++++++++++++++++++ sql/sql_acl.cc | 3 ++ 3 files changed, 58 insertions(+) diff --git a/mysql-test/suite/roles/role_grant_propagate.result b/mysql-test/suite/roles/role_grant_propagate.result index 5f6288b08c0..7804b7b7a3c 100644 --- a/mysql-test/suite/roles/role_grant_propagate.result +++ b/mysql-test/suite/roles/role_grant_propagate.result @@ -138,5 +138,30 @@ drop role test_role1, test_role2; create role test_role1; drop role test_role1; # +# MDEV-29851 Cached role privileges are not invalidated when needed +# +create role admin; +create role student; +create database crm; +grant create on crm.* to admin; +grant select on crm.* to student; +create user intern@localhost; +grant student to intern@localhost; +set default role student for intern@localhost; +connect con1, localhost, intern; +use crm; +disconnect con1; +connection default; +grant admin to student; +connect con1, localhost, intern; +use crm; +create table t1 (a int); +disconnect con1; +connection default; +drop user intern@localhost; +drop role student; +drop role admin; +drop database crm; +# # End of 10.3 tests # diff --git a/mysql-test/suite/roles/role_grant_propagate.test b/mysql-test/suite/roles/role_grant_propagate.test index b909b71a5bb..bf20bc00809 100644 --- a/mysql-test/suite/roles/role_grant_propagate.test +++ b/mysql-test/suite/roles/role_grant_propagate.test @@ -166,6 +166,36 @@ drop role test_role1, test_role2; create role test_role1; drop role test_role1; +--echo # +--echo # MDEV-29851 Cached role privileges are not invalidated when needed +--echo # +create role admin; +create role student; +create database crm; +grant create on crm.* to admin; +grant select on crm.* to student; +create user intern@localhost; +grant student to intern@localhost; +set default role student for intern@localhost; + +connect con1, localhost, intern; +use crm; +disconnect con1; + +connection default; +grant admin to student; + +connect con1, localhost, intern; +use crm; +create table t1 (a int); +disconnect con1; + +connection default; +drop user intern@localhost; +drop role student; +drop role admin; +drop database crm; + --echo # --echo # End of 10.3 tests --echo # diff --git a/sql/sql_acl.cc b/sql/sql_acl.cc index 5a2865e535e..059a6ed4127 100644 --- a/sql/sql_acl.cc +++ b/sql/sql_acl.cc @@ -7152,7 +7152,10 @@ bool mysql_grant_role(THD *thd, List &list, bool revoke) a role */ if (role_as_user) + { propagate_role_grants(role_as_user, PRIVS_TO_MERGE::ALL); + acl_cache->clear(1); + } } mysql_mutex_unlock(&acl_cache->lock); From e967e810899c28addb9369ebe3e6b9847976f267 Mon Sep 17 00:00:00 2001 From: Alexey Botchkov Date: Tue, 18 Jan 2022 12:14:25 +0400 Subject: [PATCH 43/72] MDEV-27233 Fixes to make SQL SERVICE working --- sql/sql_prepare.cc | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/sql/sql_prepare.cc b/sql/sql_prepare.cc index c82744ae48e..65d515d312f 100644 --- a/sql/sql_prepare.cc +++ b/sql/sql_prepare.cc @@ -5630,6 +5630,7 @@ public: MEM_ROOT *alloc; THD *new_thd; Security_context empty_ctx; + ulonglong client_capabilities; my_bool do_log_bin; @@ -6257,6 +6258,7 @@ loc_advanced_command(MYSQL *mysql, enum enum_server_command command, { Ed_connection con(p->thd); Security_context *ctx_orig= p->thd->security_ctx; + ulonglong cap_orig= p->thd->client_capabilities; MYSQL_LEX_STRING sql_text; my_bool log_bin_orig; p->set_binlog_vars(&log_bin_orig); @@ -6265,7 +6267,9 @@ loc_advanced_command(MYSQL *mysql, enum enum_server_command command, sql_text.str= (char *) arg; sql_text.length= arg_length; p->thd->security_ctx= &p->empty_ctx; + p->thd->client_capabilities= p->client_capabilities; result= con.execute_direct(p, sql_text); + p->thd->client_capabilities= cap_orig; p->thd->security_ctx= ctx_orig; p->restore_binlog_vars(log_bin_orig); } @@ -6391,6 +6395,7 @@ extern "C" MYSQL *mysql_real_connect_local(MYSQL *mysql) THD *thd_orig= current_thd; THD *new_thd; Protocol_local *p; + ulonglong client_flag; DBUG_ENTER("mysql_real_connect_local"); /* Test whether we're already connected */ @@ -6402,6 +6407,9 @@ extern "C" MYSQL *mysql_real_connect_local(MYSQL *mysql) mysql->methods= &local_methods; mysql->user= NULL; + client_flag= mysql->options.client_flag; + client_flag|= CLIENT_MULTI_RESULTS;; + client_flag&= ~(CLIENT_COMPRESS | CLIENT_PLUGIN_AUTH); mysql->info_buffer= (char *) my_malloc(PSI_INSTRUMENT_ME, MYSQL_ERRMSG_SIZE, MYF(0)); @@ -6425,6 +6433,7 @@ extern "C" MYSQL *mysql_real_connect_local(MYSQL *mysql) new_thd->variables.wsrep_on= 0; new_thd->variables.sql_log_bin= 0; new_thd->set_binlog_bit(); + new_thd->client_capabilities= client_flag; /* TOSO: decide if we should turn the auditing off @@ -6446,6 +6455,7 @@ extern "C" MYSQL *mysql_real_connect_local(MYSQL *mysql) { p->empty_ctx.init(); p->empty_ctx.skip_grants(); + p->client_capabilities= client_flag; } mysql->thd= p; From c160a115b8b6dcd54bb3daf1a751ee9c68b7ee47 Mon Sep 17 00:00:00 2001 From: Nayuta Yanagisawa Date: Mon, 25 Apr 2022 18:29:01 +0900 Subject: [PATCH 44/72] MDEV-27233 Server hangs when using --init-file which loads Spider and creates a Spider table Spider waits until the server initialization has been completed (i.e., mysqld_server_started has been set to 1) before creating the Spider system tables. Spider also wait until the system tables have been created before instantiating ha_spider. These waits leads to dead lock when a non-system Spider table is created by --in-file. This is because queries passed by --in-file are executed during the server initialization and creating the non-system Spider table causes an instantiation of ha_spider. In the first place, there seems to be no need for Spider to do such a synchronization. Thus, we simply remove the synchronization. --- .../spider/bugfix/r/mdev_27233.result | 3 + .../mysql-test/spider/bugfix/t/mdev_27233.opt | 1 + .../mysql-test/spider/bugfix/t/mdev_27233.sql | 3 + .../spider/bugfix/t/mdev_27233.test | 3 + .../spider/include/deinit_spider.inc | 5 +- .../mysql-test/spider/include/init_spider.inc | 4 +- storage/spider/spd_include.h | 1 - storage/spider/spd_init_query.h | 126 +---------------- storage/spider/spd_table.cc | 132 +++++++----------- 9 files changed, 64 insertions(+), 214 deletions(-) create mode 100644 storage/spider/mysql-test/spider/bugfix/r/mdev_27233.result create mode 100644 storage/spider/mysql-test/spider/bugfix/t/mdev_27233.opt create mode 100644 storage/spider/mysql-test/spider/bugfix/t/mdev_27233.sql create mode 100644 storage/spider/mysql-test/spider/bugfix/t/mdev_27233.test diff --git a/storage/spider/mysql-test/spider/bugfix/r/mdev_27233.result b/storage/spider/mysql-test/spider/bugfix/r/mdev_27233.result new file mode 100644 index 00000000000..53622bb6a23 --- /dev/null +++ b/storage/spider/mysql-test/spider/bugfix/r/mdev_27233.result @@ -0,0 +1,3 @@ +# +# MDEV-27233 Server hangs when using --init-file which loads Spider and creates a Spider table +# diff --git a/storage/spider/mysql-test/spider/bugfix/t/mdev_27233.opt b/storage/spider/mysql-test/spider/bugfix/t/mdev_27233.opt new file mode 100644 index 00000000000..7bc1c2127a6 --- /dev/null +++ b/storage/spider/mysql-test/spider/bugfix/t/mdev_27233.opt @@ -0,0 +1 @@ +--init-file=$MYSQL_TEST_DIR/../storage/spider/mysql-test/spider/bugfix/t/mdev_27233.sql diff --git a/storage/spider/mysql-test/spider/bugfix/t/mdev_27233.sql b/storage/spider/mysql-test/spider/bugfix/t/mdev_27233.sql new file mode 100644 index 00000000000..2be9ec1fad6 --- /dev/null +++ b/storage/spider/mysql-test/spider/bugfix/t/mdev_27233.sql @@ -0,0 +1,3 @@ +INSTALL SONAME 'ha_spider.so'; +USE test; +CREATE TABLE t (c INT) ENGINE=SPIDER; diff --git a/storage/spider/mysql-test/spider/bugfix/t/mdev_27233.test b/storage/spider/mysql-test/spider/bugfix/t/mdev_27233.test new file mode 100644 index 00000000000..79603439d35 --- /dev/null +++ b/storage/spider/mysql-test/spider/bugfix/t/mdev_27233.test @@ -0,0 +1,3 @@ +--echo # +--echo # MDEV-27233 Server hangs when using --init-file which loads Spider and creates a Spider table +--echo # diff --git a/storage/spider/mysql-test/spider/include/deinit_spider.inc b/storage/spider/mysql-test/spider/include/deinit_spider.inc index dd474c59bc7..3145aa2b55f 100644 --- a/storage/spider/mysql-test/spider/include/deinit_spider.inc +++ b/storage/spider/mysql-test/spider/include/deinit_spider.inc @@ -20,7 +20,6 @@ if (`SELECT IF($PLUGIN_VERSION = 3, 1, 0)`) if ($HAS_REWRITE) { DROP FUNCTION spider_flush_rewrite_cache; - UNINSTALL PLUGIN spider_rewrite; DROP TABLE IF EXISTS mysql.spider_rewrite_tables; DROP TABLE IF EXISTS mysql.spider_rewrite_table_tables; DROP TABLE IF EXISTS mysql.spider_rewrite_table_partitions; @@ -33,9 +32,7 @@ DROP FUNCTION spider_copy_tables; DROP FUNCTION spider_ping_table; DROP FUNCTION spider_bg_direct_sql; DROP FUNCTION spider_direct_sql; -UNINSTALL PLUGIN spider_wrapper_protocols; -UNINSTALL PLUGIN spider_alloc_mem; -UNINSTALL PLUGIN spider; +UNINSTALL SONAME "ha_spider.so"; DROP TABLE IF EXISTS mysql.spider_xa; DROP TABLE IF EXISTS mysql.spider_xa_member; DROP TABLE IF EXISTS mysql.spider_xa_failed_log; diff --git a/storage/spider/mysql-test/spider/include/init_spider.inc b/storage/spider/mysql-test/spider/include/init_spider.inc index b3fb4df239b..0d0e7f0ab5b 100644 --- a/storage/spider/mysql-test/spider/include/init_spider.inc +++ b/storage/spider/mysql-test/spider/include/init_spider.inc @@ -2,7 +2,7 @@ let $VERSION_COMPILE_OS_WIN= `SELECT IF(@@version_compile_os like 'Win%', 1, 0)`; if ($VERSION_COMPILE_OS_WIN) { - INSTALL PLUGIN spider SONAME 'ha_spider.dll'; + INSTALL SONAME 'ha_spider.dll'; if ($MASTER_1_MYPORT) { eval CREATE SERVER s_1 FOREIGN DATA WRAPPER mysql OPTIONS ( @@ -76,7 +76,7 @@ if ($VERSION_COMPILE_OS_WIN) } if (!$VERSION_COMPILE_OS_WIN) { - INSTALL PLUGIN spider SONAME 'ha_spider.so'; + INSTALL SONAME 'ha_spider.so'; if ($MASTER_1_MYSOCK) { eval CREATE SERVER s_1 FOREIGN DATA WRAPPER mysql OPTIONS ( diff --git a/storage/spider/spd_include.h b/storage/spider/spd_include.h index 25eeb87d5ff..391c4e9906e 100644 --- a/storage/spider/spd_include.h +++ b/storage/spider/spd_include.h @@ -324,7 +324,6 @@ typedef struct st_spider_thread volatile bool killed; volatile bool thd_wait; volatile bool first_free_wait; - volatile bool init_command; volatile int error; pthread_t thread; pthread_cond_t cond; diff --git a/storage/spider/spd_init_query.h b/storage/spider/spd_init_query.h index 0dcbcd50230..702a515b064 100644 --- a/storage/spider/spd_init_query.h +++ b/storage/spider/spd_init_query.h @@ -662,82 +662,6 @@ static LEX_STRING spider_init_queries[] = { "create procedure mysql.spider_plugin_installer()" "begin" " set @win_plugin := IF(@@version_compile_os like 'Win%', 1, 0);" -/* - Install spider plugin -*/ -/* - " set @have_spider_i_s_plugin := 0;" - " select @have_spider_i_s_plugin := 1 from INFORMATION_SCHEMA.plugins" - " where PLUGIN_NAME = 'SPIDER';" - " set @have_spider_plugin := 0;" - " select @have_spider_plugin := 1 from mysql.plugin" - " where name = 'spider';" - " if @have_spider_i_s_plugin = 0 then" - " if @have_spider_plugin = 1 then" - " / *" - " spider plugin is present in mysql.plugin but not in" - " information_schema.plugins. Remove spider plugin entry" - " in mysql.plugin first." - " * /" - " delete from mysql.plugin where name = 'spider';" - " end if;" - " if @win_plugin = 0 then " - " install plugin spider soname 'ha_spider.so';" - " else" - " install plugin spider soname 'ha_spider.dll';" - " end if;" - " end if;" -*/ -/* - Install spider_alloc_mem plugin -*/ - " set @have_spider_i_s_alloc_mem_plugin := 0;" - " select @have_spider_i_s_alloc_mem_plugin := 1" - " from INFORMATION_SCHEMA.plugins" - " where PLUGIN_NAME = 'SPIDER_ALLOC_MEM';" - " set @have_spider_alloc_mem_plugin := 0;" - " select @have_spider_alloc_mem_plugin := 1 from mysql.plugin" - " where name = 'spider_alloc_mem';" - " if @have_spider_i_s_alloc_mem_plugin = 0 then" - " if @have_spider_alloc_mem_plugin = 1 then" - " /*" - " spider_alloc_mem plugin is present in mysql.plugin but not in" - " information_schema.plugins. Remove spider_alloc_mem plugin entry" - " in mysql.plugin first." - " */" - " delete from mysql.plugin where name = 'spider_alloc_mem';" - " end if;" - " if @win_plugin = 0 then " - " install plugin spider_alloc_mem soname 'ha_spider.so';" - " else" - " install plugin spider_alloc_mem soname 'ha_spider.dll';" - " end if;" - " end if;" -/* - Install spider_wrapper_protocols plugin -*/ - " set @have_spider_i_s_wrapper_protocols_plugin := 0;" - " select @have_spider_i_s_wrapper_protocols_plugin := 1" - " from INFORMATION_SCHEMA.plugins" - " where PLUGIN_NAME = 'SPIDER_WRAPPER_PROTOCOLS';" - " set @have_spider_wrapper_protocols_plugin := 0;" - " select @have_spider_wrapper_protocols_plugin := 1 from mysql.plugin" - " where name = 'spider_wrapper_protocols';" - " if @have_spider_i_s_wrapper_protocols_plugin = 0 then" - " if @have_spider_wrapper_protocols_plugin = 1 then" - " /*" - " spider_wrapper_protocols plugin is present in mysql.plugin but not in" - " information_schema.plugins. Remove spider_wrapper_protocols plugin entry" - " in mysql.plugin first." - " */" - " delete from mysql.plugin where name = 'spider_wrapper_protocols';" - " end if;" - " if @win_plugin = 0 then " - " install plugin spider_wrapper_protocols soname 'ha_spider.so';" - " else" - " install plugin spider_wrapper_protocols soname 'ha_spider.dll';" - " end if;" - " end if;" " set @have_spider_direct_sql_udf := 0;" " select @have_spider_direct_sql_udf := 1 from mysql.func" " where name = 'spider_direct_sql';" @@ -798,53 +722,6 @@ static LEX_STRING spider_init_queries[] = { " soname 'ha_spider.dll';" " end if;" " end if;" - " if @server_name = 'MariaDB' and" - " (" - " @server_major_version > 10 or" - " (" - " @server_major_version = 10 and" - " @server_minor_version >= 8" - " )" - " )" - " then" -/* - Install spider_rewrite plugin -*/ - " set @have_spider_i_s_rewrite_plugin := 0;" - " select @have_spider_i_s_rewrite_plugin := 1" - " from INFORMATION_SCHEMA.plugins" - " where PLUGIN_NAME = 'SPIDER_REWRITE';" - " set @have_spider_rewrite_plugin := 0;" - " select @have_spider_rewrite_plugin := 1 from mysql.plugin" - " where name = 'spider_rewrite';" - " if @have_spider_i_s_rewrite_plugin = 0 then" - " if @have_spider_rewrite_plugin = 1 then" - " /*" - " spider_rewrite plugin is present in mysql.plugin but not in" - " information_schema.plugins. Remove spider_rewrite plugin entry" - " in mysql.plugin first." - " */" - " delete from mysql.plugin where name = 'spider_rewrite';" - " end if;" - " if @win_plugin = 0 then " - " install plugin spider_rewrite soname 'ha_spider.so';" - " else" - " install plugin spider_rewrite soname 'ha_spider.dll';" - " end if;" - " end if;" - " set @have_spider_flush_rewrite_cache_udf := 0;" - " select @have_spider_flush_rewrite_cache_udf := 1 from mysql.func" - " where name = 'spider_flush_rewrite_cache';" - " if @have_spider_flush_rewrite_cache_udf = 0 then" - " if @win_plugin = 0 then " - " create function spider_flush_rewrite_cache returns int" - " soname 'ha_spider.so';" - " else" - " create function spider_flush_rewrite_cache returns int" - " soname 'ha_spider.dll';" - " end if;" - " end if;" - " end if;" "end;" )}, {C_STRING_WITH_LEN( @@ -852,6 +729,5 @@ static LEX_STRING spider_init_queries[] = { )}, {C_STRING_WITH_LEN( "drop procedure mysql.spider_plugin_installer" - )}, - {C_STRING_WITH_LEN("")} + )} }; diff --git a/storage/spider/spd_table.cc b/storage/spider/spd_table.cc index f2fc6c089b0..049d6d06cdf 100644 --- a/storage/spider/spd_table.cc +++ b/storage/spider/spd_table.cc @@ -129,9 +129,6 @@ const char **spd_mysqld_unix_port; uint *spd_mysqld_port; bool volatile *spd_abort_loop; Time_zone *spd_tz_system; -static int *spd_mysqld_server_started; -static pthread_mutex_t *spd_LOCK_server_started; -static pthread_cond_t *spd_COND_server_started; extern long spider_conn_mutex_id; handlerton *spider_hton_ptr; SPIDER_DBTON spider_dbton[SPIDER_DBTON_SIZE]; @@ -7053,30 +7050,6 @@ handler* spider_create_handler( MEM_ROOT *mem_root ) { DBUG_ENTER("spider_create_handler"); -#ifndef WITHOUT_SPIDER_BG_SEARCH - SPIDER_THREAD *thread = &spider_table_sts_threads[0]; - if (unlikely(thread->init_command)) - { - THD *thd = current_thd; - pthread_cond_t *cond = thd->mysys_var->current_cond; - pthread_mutex_t *mutex = thd->mysys_var->current_mutex; - /* wait for finishing init_command */ - pthread_mutex_lock(&thread->mutex); - if (unlikely(thread->init_command)) - { - thd->mysys_var->current_cond = &thread->sync_cond; - thd->mysys_var->current_mutex = &thread->mutex; - pthread_cond_wait(&thread->sync_cond, &thread->mutex); - } - pthread_mutex_unlock(&thread->mutex); - thd->mysys_var->current_cond = cond; - thd->mysys_var->current_mutex = mutex; - if (thd->killed) - { - DBUG_RETURN(NULL); - } - } -#endif DBUG_RETURN(new (mem_root) ha_spider(hton, table)); } @@ -7397,6 +7370,50 @@ int spider_panic( DBUG_RETURN(0); } +/* + Create or fix the system tables. See spd_init_query.h for the details. +*/ +bool spider_init_system_tables() +{ + DBUG_ENTER("spider_init_system_tables"); + + MYSQL *mysql= mysql_init(NULL); + if (!mysql) + { + DBUG_RETURN(TRUE); + } + + if (!mysql_real_connect_local(mysql)) + { + mysql_close(mysql); + DBUG_RETURN(TRUE); + } + + int size= sizeof(spider_init_queries) / sizeof(spider_init_queries[0]); + for (int i= 0; i < size; i++) + { + if (mysql_real_query(mysql, spider_init_queries[i].str, + spider_init_queries[i].length)) + { + fprintf(stderr, + "[ERROR] SPIDER plugin initialization failed at '%s' by '%s'\n", + spider_init_queries[i].str, mysql_error(mysql)); + + mysql_close(mysql); + DBUG_RETURN(TRUE); + } + + if (MYSQL_RES *res= mysql_store_result(mysql)) + { + mysql_free_result(res); + } + } + + mysql_close(mysql); + + DBUG_RETURN(FALSE); +} + int spider_db_init( void *p ) { @@ -7484,9 +7501,6 @@ int spider_db_init( spd_mysqld_port = &mysqld_port; spd_abort_loop = &abort_loop; spd_tz_system = my_tz_SYSTEM; - spd_mysqld_server_started = &mysqld_server_started; - spd_LOCK_server_started = &LOCK_server_started; - spd_COND_server_started = &COND_server_started; #ifdef HAVE_PSI_INTERFACE init_spider_psi_keys(); @@ -7762,6 +7776,11 @@ int spider_db_init( spider_udf_table_mon_list_hash[roop_count].array.size_of_element); } + if (spider_init_system_tables()) + { + goto error_system_table_creation; + } + #ifndef WITHOUT_SPIDER_BG_SEARCH if (!(spider_table_sts_threads = (SPIDER_THREAD *) spider_bulk_malloc(NULL, 256, MYF(MY_WME | MY_ZEROFILL), @@ -7772,7 +7791,6 @@ int spider_db_init( NullS)) ) goto error_alloc_mon_mutxes; - spider_table_sts_threads[0].init_command = TRUE; for (roop_count = 0; roop_count < (int) spider_param_table_sts_thread_count(); @@ -7863,6 +7881,7 @@ error_init_udf_table_mon_list_hash: error_init_udf_table_mon_cond: for (; roop_count >= 0; roop_count--) pthread_cond_destroy(&spider_udf_table_mon_conds[roop_count]); +error_system_table_creation: roop_count = spider_param_udf_table_mon_mutex_count() - 1; error_init_udf_table_mon_mutex: for (; roop_count >= 0; roop_count--) @@ -10478,57 +10497,6 @@ void *spider_table_bg_sts_action( trx->thd = thd; /* init end */ - if (thread->init_command) - { - uint i = 0; - tmp_disable_binlog(thd); - thd->security_ctx->skip_grants(); - thd->client_capabilities |= CLIENT_MULTI_RESULTS; - if (!(*spd_mysqld_server_started) && !thd->killed) - { - pthread_mutex_lock(spd_LOCK_server_started); - thd->mysys_var->current_cond = spd_COND_server_started; - thd->mysys_var->current_mutex = spd_LOCK_server_started; - if (!(*spd_mysqld_server_started) && !thd->killed) - { - do - { - struct timespec abstime; - set_timespec_nsec(abstime, 1000); - error_num = pthread_cond_timedwait(spd_COND_server_started, - spd_LOCK_server_started, &abstime); - } while ( - (error_num == ETIMEDOUT || error_num == ETIME) && - !(*spd_mysqld_server_started) && !thd->killed && !thread->killed - ); - } - pthread_mutex_unlock(spd_LOCK_server_started); - thd->mysys_var->current_cond = &thread->cond; - thd->mysys_var->current_mutex = &thread->mutex; - } - while (spider_init_queries[i].length && !thd->killed && !thread->killed) - { - dispatch_command(COM_QUERY, thd, spider_init_queries[i].str, - (uint) spider_init_queries[i].length); - if (unlikely(thd->is_error())) - { - fprintf(stderr, "[ERROR] %s\n", spider_stmt_da_message(thd)); - thd->clear_error(); - break; - } - ++i; - } - thd->mysys_var->current_cond = &thread->cond; - thd->mysys_var->current_mutex = &thread->mutex; - thd->client_capabilities -= CLIENT_MULTI_RESULTS; - reenable_binlog(thd); - thread->init_command = FALSE; - pthread_cond_broadcast(&thread->sync_cond); - } - if (thd->killed) - { - thread->killed = TRUE; - } if (thd->killed) { thread->killed = TRUE; From 28d6f6a514366d0358a7215dc7ef202e2b758c10 Mon Sep 17 00:00:00 2001 From: Alexander Barkov Date: Mon, 24 Oct 2022 13:58:14 +0400 Subject: [PATCH 45/72] MDEV-14983 Wrong error message with SET sql_mode=sha2(ucs2_value) The problem was fixed earlier. Adding an MTR test only. --- mysql-test/main/ctype_ucs.result | 11 +++++++++++ mysql-test/main/ctype_ucs.test | 15 +++++++++++++++ 2 files changed, 26 insertions(+) diff --git a/mysql-test/main/ctype_ucs.result b/mysql-test/main/ctype_ucs.result index 7682134ea27..3cdb1c7968c 100644 --- a/mysql-test/main/ctype_ucs.result +++ b/mysql-test/main/ctype_ucs.result @@ -6391,3 +6391,14 @@ DEALLOCATE PREPARE stmt; # # End of 10.2 tests # +# +# Start of 10.3 tests +# +# +# MDEV-14983 Wrong error message with SET sql_mode=sha2(ucs2_value) +# +SET sql_mode=sha2(CONVERT('a' USING ucs2),0); +ERROR 42000: Variable 'sql_mode' can't be set to the value of '022a6979e6dab7aa5ae4c3e5e45f7e977112a7e63593820dbec1ec738a24f93c' +# +# End of 10.3 tests +# diff --git a/mysql-test/main/ctype_ucs.test b/mysql-test/main/ctype_ucs.test index d0d463c0340..00eade52a5a 100644 --- a/mysql-test/main/ctype_ucs.test +++ b/mysql-test/main/ctype_ucs.test @@ -1094,3 +1094,18 @@ DEALLOCATE PREPARE stmt; --echo # --echo # End of 10.2 tests --echo # + +--echo # +--echo # Start of 10.3 tests +--echo # + +--echo # +--echo # MDEV-14983 Wrong error message with SET sql_mode=sha2(ucs2_value) +--echo # + +--error ER_WRONG_VALUE_FOR_VAR +SET sql_mode=sha2(CONVERT('a' USING ucs2),0); + +--echo # +--echo # End of 10.3 tests +--echo # From e00ea301efd9e02f89341dfec3a5e0e751213ed8 Mon Sep 17 00:00:00 2001 From: Oleksandr Byelkin Date: Fri, 21 Oct 2022 13:47:17 +0200 Subject: [PATCH 46/72] MDEV-16549 Server crashes in Item_field::fix_fields on query with view and subquery, Assertion `context' failed, Assertion `field' failed Add one-table-resolve context for items created with an aim of switching to temporary table because then it can be cloned in push-down-condition. --- mysql-test/main/derived.result | 16 ++++++++++++++++ mysql-test/main/derived.test | 20 ++++++++++++++++++++ sql/item.cc | 14 ++++++++++++++ sql/item.h | 2 ++ sql/table.cc | 6 ++++-- 5 files changed, 56 insertions(+), 2 deletions(-) diff --git a/mysql-test/main/derived.result b/mysql-test/main/derived.result index c3421a288a1..2761fdfa287 100644 --- a/mysql-test/main/derived.result +++ b/mysql-test/main/derived.result @@ -1313,3 +1313,19 @@ a a 4 4 6 6 drop table t1,t2,t3; +# +# MDEV-16549: Server crashes in Item_field::fix_fields on query with +# view and subquery, Assertion `context' failed, Assertion `field' failed +# +CREATE TABLE t1 (a DECIMAL, b INT); +INSERT INTO t1 VALUES (1,1),(2,2); +CREATE VIEW v1 AS SELECT * FROM ( SELECT * FROM t1 WHERE a <> RAND() ) sq; +SELECT * FROM v1 WHERE b > 0; +a b +1 1 +2 2 +DROP VIEW v1; +DROP TABLE t1; +# +# End of 10.3 tests +# diff --git a/mysql-test/main/derived.test b/mysql-test/main/derived.test index 4ff0cf4165c..6a831000e57 100644 --- a/mysql-test/main/derived.test +++ b/mysql-test/main/derived.test @@ -1120,3 +1120,23 @@ analyze select * from t1 , ( (select t2.a from t2 order by c) union all (select select * from t1 , ( (select t2.a from t2 order by c) union all (select t2.a from t2 order by c) except(select t3.a from t3 order by b))q where t1.a=q.a; drop table t1,t2,t3; + + +--echo # +--echo # MDEV-16549: Server crashes in Item_field::fix_fields on query with +--echo # view and subquery, Assertion `context' failed, Assertion `field' failed +--echo # + +CREATE TABLE t1 (a DECIMAL, b INT); +INSERT INTO t1 VALUES (1,1),(2,2); # optional +CREATE VIEW v1 AS SELECT * FROM ( SELECT * FROM t1 WHERE a <> RAND() ) sq; + +SELECT * FROM v1 WHERE b > 0; + +# Cleanup +DROP VIEW v1; +DROP TABLE t1; + +--echo # +--echo # End of 10.3 tests +--echo # diff --git a/sql/item.cc b/sql/item.cc index 8b127cf2626..012dcebdaee 100644 --- a/sql/item.cc +++ b/sql/item.cc @@ -10753,6 +10753,20 @@ void view_error_processor(THD *thd, void *data) ((TABLE_LIST *)data)->hide_view_error(thd); } +/** + Name resolution context with resolution in only one table +*/ + +Name_resolution_context::Name_resolution_context(TABLE_LIST *table): + outer_context(0), table_list(0), select_lex(0), + error_processor_data(0), + security_ctx(0) +{ + resolve_in_select_list= FALSE; + error_processor= &dummy_error_processor; + // resolve only in this table + first_name_resolution_table= last_name_resolution_table= table; +} st_select_lex *Item_ident::get_depended_from() const { diff --git a/sql/item.h b/sql/item.h index f28e4fb4bd7..a291678529e 100644 --- a/sql/item.h +++ b/sql/item.h @@ -237,6 +237,8 @@ struct Name_resolution_context: Sql_alloc security_ctx(0) {} + Name_resolution_context(TABLE_LIST *table); + void init() { resolve_in_select_list= FALSE; diff --git a/sql/table.cc b/sql/table.cc index d6d68988a52..5a3e704d3ff 100644 --- a/sql/table.cc +++ b/sql/table.cc @@ -8826,7 +8826,8 @@ bool TABLE_LIST::change_refs_to_fields() Item **materialized_items= (Item **)thd->calloc(sizeof(void *) * table->s->fields); - if (!materialized_items) + Name_resolution_context *ctx= new Name_resolution_context(this); + if (!materialized_items || !ctx) return TRUE; while ((ref= (Item_direct_ref*)li++)) @@ -8842,7 +8843,8 @@ bool TABLE_LIST::change_refs_to_fields() DBUG_ASSERT(!field_it.end_of_fields()); if (!materialized_items[idx]) { - materialized_items[idx]= new (thd->mem_root) Item_field(thd, table->field[idx]); + materialized_items[idx]= + new (thd->mem_root) Item_field(thd, ctx, table->field[idx]); if (!materialized_items[idx]) return TRUE; } From 4fd6dd2d3b9bb08a3897d59160515a09fe357114 Mon Sep 17 00:00:00 2001 From: Oleksandr Byelkin Date: Wed, 12 Oct 2022 15:59:46 +0200 Subject: [PATCH 47/72] MDEV-29748 ASAN errors or server crash in File_parser::parse upon concurrent view operations Read the version of the view share when we read definition to prevent simultaniouse access to a view table SHARE (and so its MEM_ROOT) from different threads. --- sql/sql_view.cc | 24 ++++++++++-------------- sql/sql_view.h | 2 ++ sql/table.cc | 4 ++++ 3 files changed, 16 insertions(+), 14 deletions(-) diff --git a/sql/sql_view.cc b/sql/sql_view.cc index 68a8410f559..1b8762f90dd 100644 --- a/sql/sql_view.cc +++ b/sql/sql_view.cc @@ -1175,19 +1175,26 @@ err: bool mariadb_view_version_get(TABLE_SHARE *share) { DBUG_ASSERT(share->is_view); + DBUG_ASSERT(share->tabledef_version.length == 0); if (!(share->tabledef_version.str= (uchar*) alloc_root(&share->mem_root, MICROSECOND_TIMESTAMP_BUFFER_SIZE))) return TRUE; - share->tabledef_version.length= 0; // safety if the drfinition file is brocken DBUG_ASSERT(share->view_def != NULL); if (share->view_def->parse((uchar *) &share->tabledef_version, NULL, view_timestamp_parameters, 1, &file_parser_dummy_hook)) + { + // safety if the definition file is brocken + share->tabledef_version.length= 0; + my_error(ER_TABLE_CORRUPT, MYF(0), + share->db.str, share->table_name.str); return TRUE; + } DBUG_ASSERT(share->tabledef_version.length == MICROSECOND_TIMESTAMP_BUFFER_SIZE-1); + return FALSE; } @@ -1251,10 +1258,7 @@ bool mysql_make_view(THD *thd, TABLE_SHARE *share, TABLE_LIST *table, mysql_derived_reinit(thd, NULL, table); DEBUG_SYNC(thd, "after_cached_view_opened"); - if (!share->tabledef_version.length) - { - mariadb_view_version_get(share); - } + DBUG_ASSERT(share->tabledef_version.length); DBUG_RETURN(0); } @@ -1308,15 +1312,7 @@ bool mysql_make_view(THD *thd, TABLE_SHARE *share, TABLE_LIST *table, required_view_parameters, &file_parser_dummy_hook))) goto end; - if (!share->tabledef_version.length) - { - share->tabledef_version.str= (const uchar *) - memdup_root(&share->mem_root, - (const void *) - table->hr_timestamp.str, - (share->tabledef_version.length= - table->hr_timestamp.length)); - } + DBUG_ASSERT(share->tabledef_version.length); if (!table->tabledef_version.length) { table->set_view_def_version(&table->hr_timestamp); diff --git a/sql/sql_view.h b/sql/sql_view.h index c1e5dc49da3..0713b951de7 100644 --- a/sql/sql_view.h +++ b/sql/sql_view.h @@ -64,4 +64,6 @@ extern const LEX_CSTRING view_type; void make_valid_column_names(List &item_list); +bool mariadb_view_version_get(TABLE_SHARE *share); + #endif /* SQL_VIEW_INCLUDED */ diff --git a/sql/table.cc b/sql/table.cc index 5a3e704d3ff..9dc7cabffc6 100644 --- a/sql/table.cc +++ b/sql/table.cc @@ -633,7 +633,11 @@ enum open_frm_error open_table_def(THD *thd, TABLE_SHARE *share, uint flags) if (!share->view_def) share->error= OPEN_FRM_ERROR_ALREADY_ISSUED; else + { share->error= OPEN_FRM_OK; + if (mariadb_view_version_get(share)) + share->error= OPEN_FRM_ERROR_ALREADY_ISSUED; + } } else share->error= OPEN_FRM_NOT_A_TABLE; From ce2825a86702fcfa89974281c6e7ef6b9f964993 Mon Sep 17 00:00:00 2001 From: Andrew Hutchings Date: Mon, 24 Oct 2022 14:40:29 +0100 Subject: [PATCH 48/72] Fix Aria S3 building in FreeBSD (#2242) FreeBSD 13 has libcurl in /usr/local/lib so linking failed just trying to link curl by name. CMake finds curl's true place so let's use that. --- storage/maria/CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/storage/maria/CMakeLists.txt b/storage/maria/CMakeLists.txt index 13d8035bdc8..f55d78f0162 100644 --- a/storage/maria/CMakeLists.txt +++ b/storage/maria/CMakeLists.txt @@ -132,7 +132,7 @@ SET(CPACK_RPM_s3-engine_PACKAGE_DESCRIPTION "The S3 storage engine allows one to IF(TARGET s3) MYSQL_ADD_EXECUTABLE(aria_s3_copy aria_s3_copy.cc ${S3_SOURCES} COMPONENT s3-engine) - TARGET_LINK_LIBRARIES(aria_s3_copy aria myisam mysys mysys_ssl curl z) + TARGET_LINK_LIBRARIES(aria_s3_copy aria myisam mysys mysys_ssl ${CURL_LIBRARIES} ${ZLIB_LIBRARY}) INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR}/libmarias3) ADD_DEFINITIONS(-DWITH_S3_STORAGE_ENGINE) ENDIF() From 8128a468278a1466fe6364d0cf5ad626e2c987f3 Mon Sep 17 00:00:00 2001 From: Vlad Lesin Date: Wed, 29 Jun 2022 17:03:56 +0300 Subject: [PATCH 49/72] MDEV-28709 unexpected X lock on Supremum in READ COMMITTED The lock is created during page splitting after moving records and locks(lock_move_rec_list_(start|end)()) to the new page, and inheriting the locks to the supremum of left page from the successor of the infimum on right page. There is no need in such inheritance for READ COMMITTED isolation level and not-gap locks, so the fix is to add the corresponding condition in gap lock inheritance function. One more fix is to forbid gap lock inheritance if XA was prepared. Use the most significant bit of trx_t::n_ref to indicate that gap lock inheritance is forbidden. This fix is based on mysql/mysql-server@b063e52a8367dc9d5ed418e7f6d96400867e9f43 --- .../innodb/r/lock_update_split_rc.result | 34 +++++++ .../suite/innodb/t/lock_update_split_rc.test | 76 +++++++++++++++ storage/innobase/include/trx0trx.h | 58 ++++++++---- storage/innobase/lock/lock0lock.cc | 94 +++++++++++-------- storage/innobase/trx/trx0trx.cc | 4 +- 5 files changed, 208 insertions(+), 58 deletions(-) create mode 100644 mysql-test/suite/innodb/r/lock_update_split_rc.result create mode 100644 mysql-test/suite/innodb/t/lock_update_split_rc.test diff --git a/mysql-test/suite/innodb/r/lock_update_split_rc.result b/mysql-test/suite/innodb/r/lock_update_split_rc.result new file mode 100644 index 00000000000..6bdce124c5b --- /dev/null +++ b/mysql-test/suite/innodb/r/lock_update_split_rc.result @@ -0,0 +1,34 @@ +CREATE TABLE t ( +`a` INT NOT NULL, +`b` INT NOT NULL, +PRIMARY KEY (`a`) +) ENGINE=InnoDB; +SET GLOBAL innodb_limit_optimistic_insert_debug = 3; +INSERT INTO t VALUES(10, 0); +INSERT INTO t VALUES(20, 0); +INSERT INTO t VALUES(30, 0); +SET TRANSACTION ISOLATION LEVEL READ COMMITTED; +XA START '1'; +REPLACE INTO t VALUES(10, 1); +REPLACE INTO t VALUES(20, 1); +SET DEBUG_SYNC= 'ib_after_row_insert SIGNAL inserted WAIT_FOR cont'; +REPLACE INTO t VALUES(30, 1); +connect con1,localhost,root; +SET TRANSACTION ISOLATION LEVEL READ COMMITTED; +XA START '2'; +SET DEBUG_SYNC= 'now WAIT_FOR inserted'; +INSERT INTO t VALUES(40, 2); +SET DEBUG_SYNC= 'now SIGNAL cont'; +connection default; +XA END '1'; +XA PREPARE '1'; +connection default; +XA COMMIT '1'; +connection con1; +XA END '2'; +XA PREPARE '2'; +XA COMMIT '2'; +disconnect con1; +connection default; +SET DEBUG_SYNC= "RESET"; +DROP TABLE t; diff --git a/mysql-test/suite/innodb/t/lock_update_split_rc.test b/mysql-test/suite/innodb/t/lock_update_split_rc.test new file mode 100644 index 00000000000..38910e53ef3 --- /dev/null +++ b/mysql-test/suite/innodb/t/lock_update_split_rc.test @@ -0,0 +1,76 @@ +--source include/have_innodb.inc +--source include/have_debug.inc +--source include/count_sessions.inc + +CREATE TABLE t ( + `a` INT NOT NULL, + `b` INT NOT NULL, + PRIMARY KEY (`a`) +) ENGINE=InnoDB; + +--disable_query_log +SET @old_innodb_limit_optimistic_insert_debug = @@innodb_limit_optimistic_insert_debug; +--enable_query_log + +SET GLOBAL innodb_limit_optimistic_insert_debug = 3; + +INSERT INTO t VALUES(10, 0); +INSERT INTO t VALUES(20, 0); +INSERT INTO t VALUES(30, 0); + +SET TRANSACTION ISOLATION LEVEL READ COMMITTED; +XA START '1'; +REPLACE INTO t VALUES(10, 1); +REPLACE INTO t VALUES(20, 1); + +# We need the following sync point because mysql_insert() resets +# trx->duplicates with the following condition: +# +# if (duplic == DUP_REPLACE && +# (!table->triggers || !table->triggers->has_delete_triggers())) +# table->file->extra(HA_EXTRA_WRITE_CANNOT_REPLACE); +# +# and ha_innobase::extra() resets trx_t::duplicates, but we need +# lock_update_split_right() to be invoked when trx->duplicates is set to +# repeat the bug. So the transaction will hang just after +# row_insert_for_mysql() call until another transaction inserts new row and +# splits the page. +SET DEBUG_SYNC= 'ib_after_row_insert SIGNAL inserted WAIT_FOR cont'; +--send REPLACE INTO t VALUES(30, 1) + +connect (con1,localhost,root); +SET TRANSACTION ISOLATION LEVEL READ COMMITTED; +XA START '2'; +SET DEBUG_SYNC= 'now WAIT_FOR inserted'; +# The following statement will cause page split and (20, ...) will be split +# record. As the previous REPLACE set non-gap X-lock on it, +# lock_update_split_right() and lock_rec_inherit_to_gap() will 'inherit' the +# lock from the very first (20, ...) new right page record to the supremum of +# the old left page, what should not be for READ COMMITTED isolation level +INSERT INTO t VALUES(40, 2); +SET DEBUG_SYNC= 'now SIGNAL cont'; + +--connection default +--reap +XA END '1'; +# This will cause the assertion failure, because the supremum of the left page +# has X-lock. +XA PREPARE '1'; +--connection default +XA COMMIT '1'; + +--connection con1 +XA END '2'; +XA PREPARE '2'; +XA COMMIT '2'; +--disconnect con1 + +--connection default +SET DEBUG_SYNC= "RESET"; +DROP TABLE t; + +--disable_query_log +SET GLOBAL innodb_limit_optimistic_insert_debug = @old_innodb_limit_optimistic_insert_debug; +--enable_query_log + +--source include/wait_until_count_sessions.inc diff --git a/storage/innobase/include/trx0trx.h b/storage/innobase/include/trx0trx.h index 68a9812468f..ce3eca7593f 100644 --- a/storage/innobase/include/trx0trx.h +++ b/storage/innobase/include/trx0trx.h @@ -646,14 +646,19 @@ struct trx_rsegs_t { struct trx_t : ilist_node<> { private: /** - Count of references. + Least significant 31 bits is count of references. We can't release the locks nor commit the transaction until this reference is 0. We can change the state to TRX_STATE_COMMITTED_IN_MEMORY to signify that it is no longer "active". - */ - Atomic_counter n_ref; + If the most significant bit is set this transaction should stop inheriting + (GAP)locks. Generally set to true during transaction prepare for RC or lower + isolation, if requested. Needed for replication replay where + we don't want to get blocked on GAP locks taken for protecting + concurrent unique insert or replace operation. + */ + Atomic_relaxed skip_lock_inheritance_and_n_ref; public: @@ -983,27 +988,47 @@ public: /** Commit the transaction. */ void commit(); - - bool is_referenced() const { return n_ref > 0; } - + bool is_referenced() const + { + return (skip_lock_inheritance_and_n_ref & ~(1U << 31)) > 0; + } void reference() { -#ifdef UNIV_DEBUG - auto old_n_ref= -#endif - n_ref++; - ut_ad(old_n_ref >= 0); + ut_d(auto old_n_ref =) + skip_lock_inheritance_and_n_ref.fetch_add(1); + ut_ad(int32_t(old_n_ref << 1) >= 0); } - void release_reference() { -#ifdef UNIV_DEBUG - auto old_n_ref= + ut_d(auto old_n_ref =) + skip_lock_inheritance_and_n_ref.fetch_sub(1); + ut_ad(int32_t(old_n_ref << 1) > 0); + } + + bool is_not_inheriting_locks() const + { + return skip_lock_inheritance_and_n_ref >> 31; + } + + void set_skip_lock_inheritance() + { + ut_d(auto old_n_ref=) skip_lock_inheritance_and_n_ref.fetch_add(1U << 31); + ut_ad(!(old_n_ref >> 31)); + } + + void reset_skip_lock_inheritance() + { +#if defined __GNUC__ && (defined __i386__ || defined __x86_64__) + __asm__("lock btrl $31, %0" : : "m"(skip_lock_inheritance_and_n_ref)); +#elif defined _MSC_VER && (defined _M_IX86 || defined _M_X64) + _interlockedbittestandreset( + reinterpret_cast(&skip_lock_inheritance_and_n_ref), + 31); +#else + skip_lock_inheritance_and_n_ref.fetch_and(~1U << 31); #endif - n_ref--; - ut_ad(old_n_ref > 0); } /** @return whether the table has lock on @@ -1031,6 +1056,7 @@ public: ut_ad(!autoinc_locks || ib_vector_is_empty(autoinc_locks)); ut_ad(UT_LIST_GET_LEN(lock.evicted_tables) == 0); ut_ad(dict_operation == TRX_DICT_OP_NONE); + ut_ad(!is_not_inheriting_locks()); } /** @return whether this is a non-locking autocommit transaction */ diff --git a/storage/innobase/lock/lock0lock.cc b/storage/innobase/lock/lock0lock.cc index 380f9201ef5..da009ada289 100644 --- a/storage/innobase/lock/lock0lock.cc +++ b/storage/innobase/lock/lock0lock.cc @@ -2291,50 +2291,54 @@ lock_rec_reset_and_release_wait( &lock_sys.prdt_page_hash, block, PAGE_HEAP_NO_INFIMUM); } -/*************************************************************//** -Makes a record to inherit the locks (except LOCK_INSERT_INTENTION type) +/** Makes a record to inherit the locks (except LOCK_INSERT_INTENTION type) of another record as gap type locks, but does not reset the lock bits of the other record. Also waiting lock requests on rec are inherited as -GRANTED gap locks. */ -static -void -lock_rec_inherit_to_gap( -/*====================*/ - const buf_block_t* heir_block, /*!< in: block containing the - record which inherits */ - const buf_block_t* block, /*!< in: block containing the - record from which inherited; - does NOT reset the locks on - this record */ - ulint heir_heap_no, /*!< in: heap_no of the - inheriting record */ - ulint heap_no) /*!< in: heap_no of the - donating record */ +GRANTED gap locks. +@param heir_block block containing the record which inherits +@param block block containing the record from which inherited; does NOT reset + the locks on this record +@param heir_heap_no heap_no of the inheriting record +@param heap_no heap_no of the donating record +@tparam from_split true if the function is invoked from + lock_update_split_(left|right)(), in this case not-gap + locks are not inherited to supremum if transaction + isolation level less or equal to READ COMMITTED */ +template +static void lock_rec_inherit_to_gap(const buf_block_t *heir_block, + const buf_block_t *block, + ulint heir_heap_no, ulint heap_no) { - lock_t* lock; + ut_ad(lock_mutex_own()); + ut_ad(!from_split || heir_heap_no == PAGE_HEAP_NO_SUPREMUM); - ut_ad(lock_mutex_own()); + /* At READ UNCOMMITTED or READ COMMITTED isolation level, + we do not want locks set + by an UPDATE or a DELETE to be inherited as gap type locks. But we + DO want S-locks/X-locks(taken for replace) set by a consistency + constraint to be inherited also then. */ - /* At READ UNCOMMITTED or READ COMMITTED isolation level, - we do not want locks set - by an UPDATE or a DELETE to be inherited as gap type locks. But we - DO want S-locks/X-locks(taken for replace) set by a consistency - constraint to be inherited also then. */ + for (lock_t *lock= lock_rec_get_first(&lock_sys.rec_hash, block, heap_no); + lock != NULL; lock= lock_rec_get_next(heap_no, lock)) + { - for (lock = lock_rec_get_first(&lock_sys.rec_hash, block, heap_no); - lock != NULL; - lock = lock_rec_get_next(heap_no, lock)) { - - if (!lock_rec_get_insert_intention(lock) - && (lock->trx->isolation_level > TRX_ISO_READ_COMMITTED - || lock_get_mode(lock) != - (lock->trx->duplicates ? LOCK_S : LOCK_X))) { - lock_rec_add_to_queue( - LOCK_REC | LOCK_GAP | lock_get_mode(lock), - heir_block, heir_heap_no, lock->index, - lock->trx, FALSE); - } - } + if (!lock->trx->is_not_inheriting_locks() && + !lock_rec_get_insert_intention(lock) && + (lock->trx->isolation_level > TRX_ISO_READ_COMMITTED || + /* When we are in a page split (not purge), then we don't set a lock + on supremum if the donor lock type is LOCK_REC_NOT_GAP. That is, do + not create bogus gap locks for non-gap locks for READ UNCOMMITTED and + READ COMMITTED isolation levels. LOCK_ORDINARY and + LOCK_GAP require a gap before the record to be locked, that is why + setting lock on supremmum is necessary. */ + ((!from_split || !lock->is_record_not_gap()) && + (lock_get_mode(lock) != (lock->trx->duplicates ? LOCK_S : LOCK_X))))) + { + lock_rec_add_to_queue(LOCK_REC | LOCK_GAP | lock_get_mode(lock), + heir_block, heir_heap_no, lock->index, lock->trx, + FALSE); + } + } } /*************************************************************//** @@ -2361,7 +2365,8 @@ lock_rec_inherit_to_gap_if_gap_lock( lock != NULL; lock = lock_rec_get_next(heap_no, lock)) { - if (!lock_rec_get_insert_intention(lock) + if (!lock->trx->is_not_inheriting_locks() + && !lock_rec_get_insert_intention(lock) && (heap_no == PAGE_HEAP_NO_SUPREMUM || !lock_rec_get_rec_not_gap(lock))) { @@ -2943,7 +2948,7 @@ lock_update_split_right( /* Inherit the locks to the supremum of left page from the successor of the infimum on right page */ - lock_rec_inherit_to_gap(left_block, right_block, + lock_rec_inherit_to_gap(left_block, right_block, PAGE_HEAP_NO_SUPREMUM, heap_no); lock_mutex_exit(); @@ -3063,7 +3068,7 @@ lock_update_split_left( /* Inherit the locks to the supremum of the left page from the successor of the infimum on the right page */ - lock_rec_inherit_to_gap(left_block, right_block, + lock_rec_inherit_to_gap(left_block, right_block, PAGE_HEAP_NO_SUPREMUM, heap_no); lock_mutex_exit(); @@ -4251,6 +4256,11 @@ void lock_release_on_prepare(trx_t *trx) { ut_ad(trx->dict_operation || lock->index->table->id >= DICT_HDR_FIRST_ID); + ut_ad(lock->trx->isolation_level > TRX_ISO_READ_COMMITTED || + /* Insert-intention lock is valid for supremum for isolation + level > TRX_ISO_READ_COMMITTED */ + lock_get_mode(lock) == LOCK_X || + !lock_rec_get_nth_bit(lock, PAGE_HEAP_NO_SUPREMUM)); retain_lock: lock= UT_LIST_GET_PREV(trx_locks, lock); continue; @@ -4287,6 +4297,8 @@ retain_lock: } lock_mutex_exit(); + + trx->set_skip_lock_inheritance(); } /* True if a lock mode is S or X */ diff --git a/storage/innobase/trx/trx0trx.cc b/storage/innobase/trx/trx0trx.cc index d8c720da604..54783e2d1a0 100644 --- a/storage/innobase/trx/trx0trx.cc +++ b/storage/innobase/trx/trx0trx.cc @@ -412,7 +412,8 @@ void trx_t::free() mod_tables.clear(); - MEM_NOACCESS(&n_ref, sizeof n_ref); + MEM_NOACCESS(&skip_lock_inheritance_and_n_ref, + sizeof skip_lock_inheritance_and_n_ref); /* do not poison mutex */ MEM_NOACCESS(&id, sizeof id); MEM_NOACCESS(&state, sizeof state); @@ -518,6 +519,7 @@ inline void trx_t::release_locks() } lock.table_locks.clear(); + reset_skip_lock_inheritance(); } /** At shutdown, frees a transaction object. */ From 34ff5ca8952ff58d99be5028a5920bfe5268f17a Mon Sep 17 00:00:00 2001 From: Ian Gilfillan Date: Mon, 24 Oct 2022 15:52:29 +0200 Subject: [PATCH 50/72] MDEV-28701 Update 10.3 HELP tables --- scripts/fill_help_tables.sql | 3324 +++++++++++++--------------------- 1 file changed, 1285 insertions(+), 2039 deletions(-) diff --git a/scripts/fill_help_tables.sql b/scripts/fill_help_tables.sql index 71a44358c95..1ba58270e15 100644 --- a/scripts/fill_help_tables.sql +++ b/scripts/fill_help_tables.sql @@ -1,3 +1,4 @@ + -- Copyright (c) 2003, 2008-2012, Oracle and/or its affiliates. All rights reserved. -- -- This program is free software; you can redistribute it and/or modify @@ -11,7 +12,7 @@ -- -- 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 Street, Fifth Floor, Boston, MA 02110-1335 USA. +-- Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -- DO NOT EDIT THIS FILE. It is generated automatically. @@ -31,2045 +32,1290 @@ delete from help_category; delete from help_keyword; delete from help_relation; -insert into help_category (help_category_id,name,parent_category_id,url) values (1,'Geographic',0,''); -insert into help_category (help_category_id,name,parent_category_id,url) values (2,'Polygon properties',34,''); +lock tables help_topic write, help_category write, help_keyword write, help_relation write; +insert into help_category (help_category_id,name,parent_category_id,url) values (1,'Contents',0,''); +insert into help_category (help_category_id,name,parent_category_id,url) values (2,'Polygon Properties',34,''); insert into help_category (help_category_id,name,parent_category_id,url) values (3,'WKT',34,''); -insert into help_category (help_category_id,name,parent_category_id,url) values (4,'Numeric Functions',38,''); -insert into help_category (help_category_id,name,parent_category_id,url) values (5,'Plugins',35,''); +insert into help_category (help_category_id,name,parent_category_id,url) values (4,'Numeric Functions',37,''); +insert into help_category (help_category_id,name,parent_category_id,url) values (5,'Plugins',1,''); insert into help_category (help_category_id,name,parent_category_id,url) values (6,'MBR',34,''); -insert into help_category (help_category_id,name,parent_category_id,url) values (7,'Control flow functions',38,''); -insert into help_category (help_category_id,name,parent_category_id,url) values (8,'Transactions',35,''); -insert into help_category (help_category_id,name,parent_category_id,url) values (9,'Help Metadata',35,''); -insert into help_category (help_category_id,name,parent_category_id,url) values (10,'Account Management',35,''); -insert into help_category (help_category_id,name,parent_category_id,url) values (11,'Point properties',34,''); -insert into help_category (help_category_id,name,parent_category_id,url) values (12,'Encryption Functions',38,''); -insert into help_category (help_category_id,name,parent_category_id,url) values (13,'LineString properties',34,''); -insert into help_category (help_category_id,name,parent_category_id,url) values (14,'Miscellaneous Functions',38,''); -insert into help_category (help_category_id,name,parent_category_id,url) values (15,'Logical operators',38,''); -insert into help_category (help_category_id,name,parent_category_id,url) values (16,'Functions and Modifiers for Use with GROUP BY',35,''); -insert into help_category (help_category_id,name,parent_category_id,url) values (17,'Information Functions',38,''); -insert into help_category (help_category_id,name,parent_category_id,url) values (18,'Comparison operators',38,''); -insert into help_category (help_category_id,name,parent_category_id,url) values (19,'Bit Functions',38,''); -insert into help_category (help_category_id,name,parent_category_id,url) values (20,'Table Maintenance',35,''); -insert into help_category (help_category_id,name,parent_category_id,url) values (21,'User-Defined Functions',35,''); -insert into help_category (help_category_id,name,parent_category_id,url) values (22,'Data Types',35,''); -insert into help_category (help_category_id,name,parent_category_id,url) values (23,'Compound Statements',35,''); -insert into help_category (help_category_id,name,parent_category_id,url) values (24,'Geometry constructors',34,''); -insert into help_category (help_category_id,name,parent_category_id,url) values (25,'GeometryCollection properties',1,''); -insert into help_category (help_category_id,name,parent_category_id,url) values (26,'Administration',35,''); -insert into help_category (help_category_id,name,parent_category_id,url) values (27,'Data Manipulation',35,''); -insert into help_category (help_category_id,name,parent_category_id,url) values (28,'Utility',35,''); -insert into help_category (help_category_id,name,parent_category_id,url) values (29,'Language Structure',35,''); -insert into help_category (help_category_id,name,parent_category_id,url) values (30,'Geometry relations',34,''); -insert into help_category (help_category_id,name,parent_category_id,url) values (31,'Date and Time Functions',38,''); +insert into help_category (help_category_id,name,parent_category_id,url) values (7,'Control Flow Functions',37,''); +insert into help_category (help_category_id,name,parent_category_id,url) values (8,'Transactions',1,''); +insert into help_category (help_category_id,name,parent_category_id,url) values (9,'Help Metadata',1,''); +insert into help_category (help_category_id,name,parent_category_id,url) values (10,'Account Management',1,''); +insert into help_category (help_category_id,name,parent_category_id,url) values (11,'Point Properties',34,''); +insert into help_category (help_category_id,name,parent_category_id,url) values (12,'Encryption Functions',37,''); +insert into help_category (help_category_id,name,parent_category_id,url) values (13,'LineString Properties',34,''); +insert into help_category (help_category_id,name,parent_category_id,url) values (14,'Miscellaneous Functions',37,''); +insert into help_category (help_category_id,name,parent_category_id,url) values (15,'Logical Operators',46,''); +insert into help_category (help_category_id,name,parent_category_id,url) values (16,'Functions and Modifiers for Use with GROUP BY',1,''); +insert into help_category (help_category_id,name,parent_category_id,url) values (17,'Information Functions',37,''); +insert into help_category (help_category_id,name,parent_category_id,url) values (18,'Assignment Operators',46,''); +insert into help_category (help_category_id,name,parent_category_id,url) values (19,'Comparison Operators',46,''); +insert into help_category (help_category_id,name,parent_category_id,url) values (20,'Bit Functions',37,''); +insert into help_category (help_category_id,name,parent_category_id,url) values (21,'Table Maintenance',1,''); +insert into help_category (help_category_id,name,parent_category_id,url) values (22,'User-Defined Functions',1,''); +insert into help_category (help_category_id,name,parent_category_id,url) values (23,'Data Types',1,''); +insert into help_category (help_category_id,name,parent_category_id,url) values (24,'Compound Statements',1,''); +insert into help_category (help_category_id,name,parent_category_id,url) values (25,'Geometry Constructors',34,''); +insert into help_category (help_category_id,name,parent_category_id,url) values (26,'Administration',1,''); +insert into help_category (help_category_id,name,parent_category_id,url) values (27,'Data Manipulation',1,''); +insert into help_category (help_category_id,name,parent_category_id,url) values (28,'Utility',1,''); +insert into help_category (help_category_id,name,parent_category_id,url) values (29,'Language Structure',1,''); +insert into help_category (help_category_id,name,parent_category_id,url) values (30,'Geometry Relations',34,''); +insert into help_category (help_category_id,name,parent_category_id,url) values (31,'Date and Time Functions',37,''); insert into help_category (help_category_id,name,parent_category_id,url) values (32,'WKB',34,''); -insert into help_category (help_category_id,name,parent_category_id,url) values (33,'Procedures',35,''); -insert into help_category (help_category_id,name,parent_category_id,url) values (34,'Geographic Features',35,''); -insert into help_category (help_category_id,name,parent_category_id,url) values (35,'Contents',0,''); -insert into help_category (help_category_id,name,parent_category_id,url) values (36,'Geometry properties',34,''); -insert into help_category (help_category_id,name,parent_category_id,url) values (37,'String Functions',38,''); -insert into help_category (help_category_id,name,parent_category_id,url) values (38,'Functions',35,''); -insert into help_category (help_category_id,name,parent_category_id,url) values (39,'Data Definition',35,''); +insert into help_category (help_category_id,name,parent_category_id,url) values (33,'Procedures',1,''); +insert into help_category (help_category_id,name,parent_category_id,url) values (34,'Geographic Features',1,''); +insert into help_category (help_category_id,name,parent_category_id,url) values (35,'Geometry Properties',34,''); +insert into help_category (help_category_id,name,parent_category_id,url) values (36,'String Functions',37,''); +insert into help_category (help_category_id,name,parent_category_id,url) values (37,'Functions',1,''); +insert into help_category (help_category_id,name,parent_category_id,url) values (38,'Data Definition',1,''); +insert into help_category (help_category_id,name,parent_category_id,url) values (39,'Sequences',1,''); +insert into help_category (help_category_id,name,parent_category_id,url) values (40,'JSON Functions',37,''); +insert into help_category (help_category_id,name,parent_category_id,url) values (41,'Window Functions',37,''); +insert into help_category (help_category_id,name,parent_category_id,url) values (42,'Spider Functions',37,''); +insert into help_category (help_category_id,name,parent_category_id,url) values (43,'Dynamic Column Functions',37,''); +insert into help_category (help_category_id,name,parent_category_id,url) values (44,'Temporal Tables',1,''); +insert into help_category (help_category_id,name,parent_category_id,url) values (45,'GeoJSON',34,''); +insert into help_category (help_category_id,name,parent_category_id,url) values (46,'Operators',1,''); +insert into help_category (help_category_id,name,parent_category_id,url) values (47,'Arithmetic Operators',46,''); +insert into help_category (help_category_id,name,parent_category_id,url) values (48,'Replication',1,''); +insert into help_category (help_category_id,name,parent_category_id,url) values (49,'Prepared Statements',1,''); -insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (0,16,'MIN','Syntax:\nMIN([DISTINCT] expr)\n\nReturns the minimum value of expr. MIN() may take a string argument; in\nsuch cases, it returns the minimum string value.\nThe DISTINCT keyword can be used to find the minimum of the distinct values\nof expr, however, this produces the same result as omitting DISTINCT.\n\nMIN() returns NULL if there were no matching rows.\n\nURL: https://mariadb.com/kb/en/min/\n\n','MariaDB> SELECT student_name, MIN(test_score), MAX(test_score)\n -> FROM student\n -> GROUP BY student_name;\n','https://mariadb.com/kb/en/min/'); -insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (1,27,'JOIN','MySQL supports the following JOIN syntaxes for the table_references\npart of SELECT statements and multiple-table DELETE and UPDATE\nstatements:\n\ntable_references:\n table_reference [, table_reference] ...\n\ntable_reference:\n table_factor\n | join_table\n\ntable_factor:\n tbl_name [[AS] alias] [index_hint_list]\n | table_subquery [AS] alias\n | ( table_references )\n | { OJ table_reference LEFT OUTER JOIN table_reference\n ON conditional_expr }\n\njoin_table:\n table_reference [INNER | CROSS] JOIN table_factor [join_condition]\n | table_reference STRAIGHT_JOIN table_factor\n | table_reference STRAIGHT_JOIN table_factor ON conditional_expr\n | table_reference {LEFT|RIGHT} [OUTER] JOIN table_reference join_condition\n | table_reference NATURAL [{LEFT|RIGHT} [OUTER]] JOIN table_factor\n\njoin_condition:\n ON conditional_expr\n | USING (column_list)\n\nindex_hint_list:\n index_hint [, index_hint] ...\n\nindex_hint:\n USE {INDEX|KEY}\n [FOR {JOIN|ORDER BY|GROUP BY}] ([index_list])\n | IGNORE {INDEX|KEY}\n [FOR {JOIN|ORDER BY|GROUP BY}] (index_list)\n | FORCE {INDEX|KEY}\n [FOR {JOIN|ORDER BY|GROUP BY}] (index_list)\n\nindex_list:\n index_name [, index_name] ...\n\nA table reference is also known as a join expression.\n\nThe syntax of table_factor is extended in comparison with the SQL\nStandard. The latter accepts only table_reference, not a list of them\ninside a pair of parentheses.\n\nThis is a conservative extension if we consider each comma in a list of\ntable_reference items as equivalent to an inner join. For example:\n\nSELECT * FROM t1 LEFT JOIN (t2, t3, t4)\n ON (t2.a=t1.a AND t3.b=t1.b AND t4.c=t1.c)\n\nis equivalent to:\n\nSELECT * FROM t1 LEFT JOIN (t2 CROSS JOIN t3 CROSS JOIN t4)\n ON (t2.a=t1.a AND t3.b=t1.b AND t4.c=t1.c)\n\nIn MySQL, JOIN, CROSS JOIN, and INNER JOIN are syntactic equivalents\n(they can replace each other). In standard SQL, they are not\nequivalent. INNER JOIN is used with an ON clause, CROSS JOIN is used\notherwise.\n\nIn general, parentheses can be ignored in join expressions containing\nonly inner join operations.\n\nIndex hints can be specified to affect how the MySQL optimizer makes\nuse of indexes. For more information, see\nhttps://mariadb.com/kb/en/how-to-force-query-plans/.\n\nURL: https://mariadb.com/kb/en/join-syntax/\n\n','SELECT left_tbl.*\n FROM left_tbl LEFT JOIN right_tbl ON left_tbl.id = right_tbl.id\n WHERE right_tbl.id IS NULL;\n','https://mariadb.com/kb/en/join-syntax/'); -insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (2,37,'HEX','Syntax:\nHEX(str), HEX(N)\n\nFor a string argument str, HEX() returns a hexadecimal string\nrepresentation of str where each character in str is converted to two\nhexadecimal digits. The inverse of this operation is performed by the\nUNHEX() function.\n\nFor a numeric argument N, HEX() returns a hexadecimal string\nrepresentation of the value of N treated as a longlong (BIGINT) number.\nThis is equivalent to CONV(N,10,16). The inverse of this operation is\nperformed by CONV(HEX(N),16,10).\n\nURL: https://mariadb.com/kb/en/hex/\n\n','MariaDB> SELECT 0x616263, HEX(\'abc\'), UNHEX(HEX(\'abc\'));\n -> \'abc\', 616263, \'abc\'\nMariaDB> SELECT HEX(255), CONV(HEX(255),16,10);\n -> \'FF\', 255\n','https://mariadb.com/kb/en/hex/'); -insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (3,27,'REPLACE','Syntax:\nREPLACE [LOW_PRIORITY | DELAYED]\n [INTO] tbl_name [(col_name,...)]\n {VALUES | VALUE} ({expr | DEFAULT},...),(...),...\n\nOr:\n\nREPLACE [LOW_PRIORITY | DELAYED]\n [INTO] tbl_name\n SET col_name={expr | DEFAULT}, ...\n\nOr:\n\nREPLACE [LOW_PRIORITY | DELAYED]\n [INTO] tbl_name [(col_name,...)]\n SELECT ...\n\nREPLACE works exactly like INSERT, except that if an old row in the\ntable has the same value as a new row for a PRIMARY KEY or a UNIQUE\nindex, the old row is deleted before the new row is inserted. See [HELP\nINSERT].\n\nREPLACE is a MySQL extension to the SQL standard. It either inserts, or\ndeletes and inserts. For another MySQL extension to standard SQL---that\neither inserts or updates---see\nhttps://mariadb.com/kb/en/insert-on-duplicate-key-update/.\n\nNote that unless the table has a PRIMARY KEY or UNIQUE index, using a\nREPLACE statement makes no sense. It becomes equivalent to INSERT,\nbecause there is no index to be used to determine whether a new row\nduplicates another.\n\nValues for all columns are taken from the values specified in the\nREPLACE statement. Any missing columns are set to their default values,\njust as happens for INSERT. You cannot refer to values from the current\nrow and use them in the new row. If you use an assignment such as SET\ncol_name = col_name + 1, the reference to the column name on the right\nhand side is treated as DEFAULT(col_name), so the assignment is\nequivalent to SET col_name = DEFAULT(col_name) + 1.\n\nTo use REPLACE, you must have both the INSERT and DELETE privileges for\nthe table.\n\nURL: https://mariadb.com/kb/en/replace/\n\n','','https://mariadb.com/kb/en/replace/'); -insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (4,30,'CONTAINS','Contains(g1,g2)\n\nReturns 1 or 0 to indicate whether g1 completely contains g2. This\ntests the opposite relationship as Within().\n\nURL: https://mariadb.com/kb/en/contains/\n\n','','https://mariadb.com/kb/en/contains/'); -insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (5,36,'SRID','SRID(g)\n\nReturns an integer indicating the Spatial Reference System ID for the\ngeometry value g.\n\nIn MySQL, the SRID value is just an integer associated with the\ngeometry value. All calculations are done assuming Euclidean (planar)\ngeometry.\n\nURL: https://mariadb.com/kb/en/srid/\n\n','MariaDB> SELECT SRID(GeomFromText(\'LineString(1 1,2 2)\',101));\n+-----------------------------------------------+\n| SRID(GeomFromText(\'LineString(1 1,2 2)\',101)) |\n+-----------------------------------------------+\n| 101 |\n+-----------------------------------------------+\n','https://mariadb.com/kb/en/srid/'); -insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (6,31,'CURRENT_TIMESTAMP','Syntax:\nCURRENT_TIMESTAMP, CURRENT_TIMESTAMP()\n\nCURRENT_TIMESTAMP and CURRENT_TIMESTAMP() are synonyms for NOW().\n\nURL: https://mariadb.com/kb/en/current_timestamp/\n\n','','https://mariadb.com/kb/en/current_timestamp/'); -insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (7,26,'SHOW CONTRIBUTORS','Syntax:\nSHOW CONTRIBUTORS\n\nThe SHOW CONTRIBUTORS statement displays information about the people\nwho contribute to MySQL source or to causes that we support. For each\ncontributor, it displays Name, Location, and Comment values.\n\nURL: https://mariadb.com/kb/en/show-contributors/\n\n','','https://mariadb.com/kb/en/show-contributors/'); -insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (8,16,'VARIANCE','Syntax:\nVARIANCE(expr)\n\nReturns the population standard variance of expr. This is an extension\nto standard SQL. The standard SQL function VAR_POP() can be used\ninstead.\n\nVARIANCE() returns NULL if there were no matching rows.\n\nURL: https://mariadb.com/kb/en/variance/\n\n','','https://mariadb.com/kb/en/variance/'); -insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (9,39,'DROP SERVER','Syntax:\nDROP SERVER [ IF EXISTS ] server_name\n\nDrops the server definition for the server named server_name. The\ncorresponding row within the mysql.servers table will be deleted. This\nstatement requires the SUPER privilege.\n\nDropping a server for a table does not affect any FEDERATED tables that\nused this connection information when they were created. See [HELP\nCREATE SERVER].\n\nURL: https://mariadb.com/kb/en/drop-server/\n\n','','https://mariadb.com/kb/en/drop-server/'); -insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (10,26,'SHOW AUTHORS','Syntax:\nSHOW AUTHORS\n\nThe SHOW AUTHORS statement displays information about the people who\nwork on MySQL. For each author, it displays Name, Location, and Comment\nvalues.\n\nURL: https://mariadb.com/kb/en/show-authors/\n\n','','https://mariadb.com/kb/en/show-authors/'); -insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (11,16,'VAR_SAMP','Syntax:\nVAR_SAMP(expr)\n\nReturns the sample variance of expr. That is, the denominator is the\nnumber of rows minus one.\n\nVAR_SAMP() returns NULL if there were no matching rows.\n\nURL: https://mariadb.com/kb/en/var_samp/\n\n','','https://mariadb.com/kb/en/var_samp/'); -insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (12,37,'CONCAT','Syntax:\nCONCAT(str1,str2,...)\n\nReturns the string that results from concatenating the arguments. May\nhave one or more arguments. If all arguments are nonbinary strings, the\nresult is a nonbinary string. If the arguments include any binary\nstrings, the result is a binary string. A numeric argument is converted\nto its equivalent string form. This is a nonbinary string as of MySQL\n5.5.3. Before 5.5.3, it is a binary string; to to avoid that and\nproduce a nonbinary string, you can use an explicit type cast, as in\nthis example:\n\nSELECT CONCAT(CAST(int_col AS CHAR), char_col);\n\nCONCAT() returns NULL if any argument is NULL.\n\nURL: https://mariadb.com/kb/en/concat/\n\n','MariaDB> SELECT CONCAT(\'My\', \'S\', \'QL\');\n -> \'MySQL\'\nMariaDB> SELECT CONCAT(\'My\', NULL, \'QL\');\n -> NULL\nMariaDB> SELECT CONCAT(14.3);\n -> \'14.3\'\n','https://mariadb.com/kb/en/concat/'); -insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (13,34,'GEOMETRY HIERARCHY','Geometry is the base class. It is an abstract class. The instantiable\nsubclasses of Geometry are restricted to zero-, one-, and\ntwo-dimensional geometric objects that exist in two-dimensional\ncoordinate space. All instantiable geometry classes are defined so that\nvalid instances of a geometry class are topologically closed (that is,\nall defined geometries include their boundary).\n\nThe base Geometry class has subclasses for Point, Curve, Surface, and\nGeometryCollection:\n\no Point represents zero-dimensional objects.\n\no Curve represents one-dimensional objects, and has subclass\n LineString, with sub-subclasses Line and LinearRing.\n\no Surface is designed for two-dimensional objects and has subclass\n Polygon.\n\no GeometryCollection has specialized zero-, one-, and two-dimensional\n collection classes named MultiPoint, MultiLineString, and\n MultiPolygon for modeling geometries corresponding to collections of\n Points, LineStrings, and Polygons, respectively. MultiCurve and\n MultiSurface are introduced as abstract superclasses that generalize\n the collection interfaces to handle Curves and Surfaces.\n\nGeometry, Curve, Surface, MultiCurve, and MultiSurface are defined as\nnoninstantiable classes. They define a common set of methods for their\nsubclasses and are included for extensibility.\n\nPoint, LineString, Polygon, GeometryCollection, MultiPoint,\nMultiLineString, and MultiPolygon are instantiable classes.\n\nURL: https://mariadb.com/kb/en/geometry-hierarchy/\n\n','','https://mariadb.com/kb/en/geometry-hierarchy/'); -insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (14,37,'CHAR FUNCTION','Syntax:\nCHAR(N,... [USING charset_name])\n\nCHAR() interprets each argument N as an integer and returns a string\nconsisting of the characters given by the code values of those\nintegers. NULL values are skipped.\nBy default, CHAR() returns a binary string. To produce a string in a\ngiven character set, use the optional USING clause:\n\nMariaDB> SELECT CHARSET(CHAR(0x65)), CHARSET(CHAR(0x65 USING utf8));\n+---------------------+--------------------------------+\n| CHARSET(CHAR(0x65)) | CHARSET(CHAR(0x65 USING utf8)) |\n+---------------------+--------------------------------+\n| binary | utf8 |\n+---------------------+--------------------------------+\n\nIf USING is given and the result string is illegal for the given\ncharacter set, a warning is issued. Also, if strict SQL mode is\nenabled, the result from CHAR() becomes NULL.\n\nURL: https://mariadb.com/kb/en/char-function/\n\n','MariaDB> SELECT CHAR(77,121,83,81,\'76\');\n -> \'MySQL\'\nMariaDB> SELECT CHAR(77,77.3,\'77.3\');\n -> \'MMM\'\n','https://mariadb.com/kb/en/char-function/'); -insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (15,22,'DATETIME','DATETIME\n\nA date and time combination. The supported range is \'1000-01-01\n00:00:00\' to \'9999-12-31 23:59:59\'. MySQL displays DATETIME values in\n\'YYYY-MM-DD HH:MM:SS\' format, but permits assignment of values to\nDATETIME columns using either strings or numbers.\n\nURL: https://mariadb.com/kb/en/datetime/\n\n','','https://mariadb.com/kb/en/datetime/'); -insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (16,26,'SHOW CREATE TRIGGER','Syntax:\nSHOW CREATE TRIGGER trigger_name\n\nThis statement shows a CREATE TRIGGER statement that creates the given\ntrigger.\n\nURL: https://mariadb.com/kb/en/show-create-trigger/\n\n','','https://mariadb.com/kb/en/show-create-trigger/'); -insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (17,26,'SHOW CREATE PROCEDURE','Syntax:\nSHOW CREATE PROCEDURE proc_name\n\nThis statement is a MySQL extension. It returns the exact string that\ncan be used to re-create the named stored procedure. A similar\nstatement, SHOW CREATE FUNCTION, displays information about stored\nfunctions (see [HELP SHOW CREATE FUNCTION]).\n\nBoth statements require that you be the owner of the routine or have\nSELECT access to the mysql.proc table. If you do not have privileges\nfor the routine itself, the value displayed for the Create Procedure or\nCreate Function field will be NULL.\n\nURL: https://mariadb.com/kb/en/show-create-procedure/\n\n','MariaDB> SHOW CREATE PROCEDURE test.simpleproc\\G\n*************************** 1. row ***************************\n Procedure: simpleproc\n sql_mode:\n Create Procedure: CREATE PROCEDURE `simpleproc`(OUT param1 INT)\n BEGIN\n SELECT COUNT(*) INTO param1 FROM t;\n END\ncharacter_set_client: latin1\ncollation_connection: latin1_swedish_ci\n Database Collation: latin1_swedish_ci\n\nMariaDB> SHOW CREATE FUNCTION test.hello\\G\n*************************** 1. row ***************************\n Function: hello\n sql_mode:\n Create Function: CREATE FUNCTION `hello`(s CHAR(20))\n RETURNS CHAR(50)\n RETURN CONCAT(\'Hello, \',s,\'!\')\ncharacter_set_client: latin1\ncollation_connection: latin1_swedish_ci\n Database Collation: latin1_swedish_ci\n','https://mariadb.com/kb/en/show-create-procedure/'); -insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (18,23,'OPEN','Syntax:\nOPEN cursor_name\n\nThis statement opens a previously declared cursor. For an example, see\nhttps://mariadb.com/kb/en/cursor-overview/.\n\nURL: https://mariadb.com/kb/en/open/\n\n','','https://mariadb.com/kb/en/open/'); -insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (19,22,'INTEGER','INTEGER[(M)] [UNSIGNED] [ZEROFILL]\n\nThis type is a synonym for INT.\n\nURL: https://mariadb.com/kb/en/sql_language-data_types-int\n\n','','https://mariadb.com/kb/en/sql_language-data_types-int'); -insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (20,37,'LOWER','Syntax:\nLOWER(str)\n\nReturns the string str with all characters changed to lowercase\naccording to the current character set mapping. The default is latin1\n(cp1252 West European).\n\nMariaDB> SELECT LOWER(\'QUADRATICALLY\');\n -> \'quadratically\'\n\nLOWER() (and UPPER()) are ineffective when applied to binary strings\n(BINARY, VARBINARY, BLOB). To perform lettercase conversion, convert\nthe string to a nonbinary string:\n\nMariaDB> SET @str = BINARY \'New York\';\nMariaDB> SELECT LOWER(@str), LOWER(CONVERT(@str USING latin1));\n+-------------+-----------------------------------+\n| LOWER(@str) | LOWER(CONVERT(@str USING latin1)) |\n+-------------+-----------------------------------+\n| New York | new york |\n+-------------+-----------------------------------+\n\nURL: https://mariadb.com/kb/en/lower/\n\n','','https://mariadb.com/kb/en/lower/'); -insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (21,26,'SHOW COLUMNS','Syntax:\nSHOW [FULL] COLUMNS {FROM | IN} tbl_name [{FROM | IN} db_name]\n [LIKE \'pattern\' | WHERE expr]\n\nSHOW COLUMNS displays information about the columns in a given table.\nIt also works for views. The LIKE clause, if present, indicates which\ncolumn names to match. The WHERE clause can be given to select rows\nusing more general conditions, as discussed in\nhttps://mariadb.com/kb/en/extended-show/.\n\nSHOW COLUMNS displays information only for those columns for which you\nhave some privilege.\n\nMariaDB> SHOW COLUMNS FROM City;\n+------------+----------+------+-----+---------+----------------+\n| Field | Type | Null | Key | Default | Extra |\n+------------+----------+------+-----+---------+----------------+\n| Id | int(11) | NO | PRI | NULL | auto_increment |\n| Name | char(35) | NO | | | |\n| Country | char(3) | NO | UNI | | |\n| District | char(20) | YES | MUL | | |\n| Population | int(11) | NO | | 0 | |\n+------------+----------+------+-----+---------+----------------+\n5 rows in set (0.00 sec)\n\nIf the data types differ from what you expect them to be based on a\nCREATE TABLE statement, note that MySQL sometimes changes data types\nwhen you create or alter a table. The conditions under which this\noccurs are described in\nhttps://mariadb.com/kb/en/silent-column-changes/.\n\nThe FULL keyword causes the output to include the column collation and\ncomments, as well as the privileges you have for each column.\n\nYou can use db_name.tbl_name as an alternative to the tbl_name FROM\ndb_name syntax. In other words, these two statements are equivalent:\n\nMariaDB> SHOW COLUMNS FROM mytable FROM mydb;\nMariaDB> SHOW COLUMNS FROM mydb.mytable;\n\nSHOW COLUMNS displays the following values for each table column:\n\nField indicates the column name.\n\nType indicates the column data type.\n\nCollation indicates the collation for nonbinary string columns, or NULL\nfor other columns. This value is displayed only if you use the FULL\nkeyword.\n\nThe Null field contains YES if NULL values can be stored in the column,\nNO if not.\n\nThe Key field indicates whether the column is indexed:\n\no If Key is empty, the column either is not indexed or is indexed only\n as a secondary column in a multiple-column, nonunique index.\n\no If Key is PRI, the column is a PRIMARY KEY or is one of the columns\n in a multiple-column PRIMARY KEY.\n\no If Key is UNI, the column is the first column of a UNIQUE index. (A\n UNIQUE index permits multiple NULL values, but you can tell whether\n the column permits NULL by checking the Null field.)\n\no If Key is MUL, the column is the first column of a nonunique index in\n which multiple occurrences of a given value are permitted within the\n column.\n\nIf more than one of the Key values applies to a given column of a\ntable, Key displays the one with the highest priority, in the order\nPRI, UNI, MUL.\n\nA UNIQUE index may be displayed as PRI if it cannot contain NULL values\nand there is no PRIMARY KEY in the table. A UNIQUE index may display as\nMUL if several columns form a composite UNIQUE index; although the\ncombination of the columns is unique, each column can still hold\nmultiple occurrences of a given value.\n\nThe Default field indicates the default value that is assigned to the\ncolumn. This is NULL if the column has an explicit default of NULL, or\nif the column definition has no DEFAULT clause.\n\nThe Extra field contains any additional information that is available\nabout a given column. The value is nonempty in these cases:\nauto_increment for columns that have the AUTO_INCREMENT attribute; on\nupdate CURRENT_TIMESTAMP for TIMESTAMP columns that have the ON UPDATE\nCURRENT_TIMESTAMP attribute.\n\nPrivileges indicates the privileges you have for the column. This value\nis displayed only if you use the FULL keyword.\n\nComment indicates any comment the column has. This value is displayed\nonly if you use the FULL keyword.\n\nSHOW FIELDS is a synonym for SHOW COLUMNS. You can also list a table\'s\ncolumns with the mysqlshow db_name tbl_name command.\n\nThe DESCRIBE statement provides information similar to SHOW COLUMNS.\nSee [HELP DESCRIBE].\n\nThe SHOW CREATE TABLE, SHOW TABLE STATUS, and SHOW INDEX statements\nalso provide information about tables. See [HELP SHOW].\n\nURL: https://mariadb.com/kb/en/show-columns/\n\n','','https://mariadb.com/kb/en/show-columns/'); -insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (22,39,'CREATE TRIGGER','Syntax:\nCREATE\n [DEFINER = { user | CURRENT_USER }]\n TRIGGER trigger_name trigger_time trigger_event\n ON tbl_name FOR EACH ROW trigger_body\n\nThis statement creates a new trigger. A trigger is a named database\nobject that is associated with a table, and that activates when a\nparticular event occurs for the table. The trigger becomes associated\nwith the table named tbl_name, which must refer to a permanent table.\nYou cannot associate a trigger with a TEMPORARY table or a view.\n\nCREATE TRIGGER requires the TRIGGER privilege for the table associated\nwith the trigger. The statement might also require the SUPER privilege,\ndepending on the DEFINER value, as described later in this section. If\nbinary logging is enabled, CREATE TRIGGER might require the SUPER\nprivilege, as described in\nhttps://mariadb.com/kb/en/binary-logging-of-stored-routines/.\n\nThe DEFINER clause determines the security context to be used when\nchecking access privileges at trigger activation time. See later in\nthis section for more information.\n\ntrigger_time is the trigger action time. It can be BEFORE or AFTER to\nindicate that the trigger activates before or after each row to be\nmodified.\n\ntrigger_event indicates the kind of statement that activates the\ntrigger. The trigger_event can be one of the following:\n\no INSERT: The trigger is activated whenever a new row is inserted into\n the table; for example, through INSERT, LOAD DATA, and REPLACE\n statements.\n\no UPDATE: The trigger is activated whenever a row is modified; for\n example, through UPDATE statements.\n\no DELETE: The trigger is activated whenever a row is deleted from the\n table; for example, through DELETE and REPLACE statements. However,\n DROP TABLE and TRUNCATE TABLE statements on the table do not activate\n this trigger, because they do not use DELETE. Dropping a partition\n does not activate DELETE triggers, either. See [HELP TRUNCATE TABLE].\n\nURL: https://mariadb.com/kb/en/create-trigger/\n\n','','https://mariadb.com/kb/en/create-trigger/'); -insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (23,31,'MONTH','Syntax:\nMONTH(date)\n\nReturns the month for date, in the range 1 to 12 for January to\nDecember, or 0 for dates such as \'0000-00-00\' or \'2008-00-00\' that have\na zero month part.\n\nURL: https://mariadb.com/kb/en/month/\n\n','MariaDB> SELECT MONTH(\'2008-02-03\');\n -> 2\n','https://mariadb.com/kb/en/month/'); -insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (24,22,'TINYINT','TINYINT[(M)] [UNSIGNED] [ZEROFILL]\n\nA very small integer. The signed range is -128 to 127. The unsigned\nrange is 0 to 255.\n\nURL: https://mariadb.com/kb/en/tinyint/\n\n','','https://mariadb.com/kb/en/tinyint/'); -insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (25,26,'SHOW TRIGGERS','Syntax:\nSHOW TRIGGERS [{FROM | IN} db_name]\n [LIKE \'pattern\' | WHERE expr]\n\nSHOW TRIGGERS lists the triggers currently defined for tables in a\ndatabase (the default database unless a FROM clause is given). This\nstatement returns results only for databases and tables for which you\nhave the TRIGGER privilege. The LIKE clause, if present, indicates\nwhich table names to match and causes the statement to display triggers\nfor those tables. The WHERE clause can be given to select rows using\nmore general conditions, as discussed in\nhttps://mariadb.com/kb/en/extended-show/.\n\nFor the trigger ins_sum as defined in\nhttps://mariadb.com/kb/en/triggers/, the output of\nthis statement is as shown here:\n\nMariaDB> SHOW TRIGGERS LIKE \'acc%\'\\G\n*************************** 1. row ***************************\n Trigger: ins_sum\n Event: INSERT\n Table: account\n Statement: SET @sum = @sum + NEW.amount\n Timing: BEFORE\n Created: NULL\n sql_mode:\n Definer: myname@localhost\ncharacter_set_client: latin1\ncollation_connection: latin1_swedish_ci\n Database Collation: latin1_swedish_ci\n\ncharacter_set_client is the session value of the character_set_client\nsystem variable when the trigger was created. collation_connection is\nthe session value of the collation_connection system variable when the\ntrigger was created. Database Collation is the collation of the\ndatabase with which the trigger is associated.\n\nURL: https://mariadb.com/kb/en/show-triggers/\n\n','','https://mariadb.com/kb/en/show-triggers/'); -insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (26,14,'MASTER_POS_WAIT','Syntax:\nMASTER_POS_WAIT(log_name,log_pos[,timeout])\n\nThis function is useful for control of master/slave synchronization. It\nblocks until the slave has read and applied all updates up to the\nspecified position in the master log. The return value is the number of\nlog events the slave had to wait for to advance to the specified\nposition. The function returns NULL if the slave SQL thread is not\nstarted, the slave\'s master information is not initialized, the\narguments are incorrect, or an error occurs. It returns -1 if the\ntimeout has been exceeded. If the slave SQL thread stops while\nMASTER_POS_WAIT() is waiting, the function returns NULL. If the slave\nis past the specified position, the function returns immediately.\n\nIf a timeout value is specified, MASTER_POS_WAIT() stops waiting when\ntimeout seconds have elapsed. timeout must be greater than 0; a zero or\nnegative timeout means no timeout.\n\nURL: https://mariadb.com/kb/en/master_pos_wait/\n\n','','https://mariadb.com/kb/en/master_pos_wait/'); -insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (27,37,'REGEXP','Syntax:\nexpr REGEXP pat, expr RLIKE pat\n\nPerforms a pattern match of a string expression expr against a pattern\npat. The pattern can be an extended regular expression. The syntax for\nregular expressions is discussed in\nhttps://mariadb.com/kb/en/regexp/. Returns 1 if expr\nmatches pat; otherwise it returns 0. If either expr or pat is NULL, the\nresult is NULL. RLIKE is a synonym for REGEXP, provided for mSQL\ncompatibility.\n\nThe pattern need not be a literal string. For example, it can be\nspecified as a string expression or table column.\n\n*Note*: Because MySQL uses the C escape syntax in strings (for example,\n"\\n" to represent the newline character), you must double any "\\" that\nyou use in your REGEXP strings.\n\nREGEXP is not case sensitive, except when used with binary strings.\n\nURL: https://mariadb.com/kb/en/regexp/\n\n','MariaDB> SELECT \'Monty!\' REGEXP \'.*\';\n -> 1\nMariaDB> SELECT \'new*\\n*line\' REGEXP \'new\\\\*.\\\\*line\';\n -> 1\nMariaDB> SELECT \'a\' REGEXP \'A\', \'a\' REGEXP BINARY \'A\';\n -> 1 0\nMariaDB> SELECT \'a\' REGEXP \'^[a-d]\';\n -> 1\n','https://mariadb.com/kb/en/regexp/'); -insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (28,23,'IF STATEMENT','Syntax:\nIF search_condition THEN statement_list\n [ELSEIF search_condition THEN statement_list] ...\n [ELSE statement_list]\nEND IF\n\nThe IF statement for stored programs implements a basic conditional\nconstruct.\n\n*Note*: There is also an IF() function, which differs from the IF\nstatement described here. See\nhttps://mariadb.com/kb/en/if-function/. The\nIF statement can have THEN, ELSE, and ELSEIF clauses, and it is\nterminated with END IF.\n\nIf the search_condition evaluates to true, the corresponding THEN or\nELSEIF clause statement_list executes. If no search_condition matches,\nthe ELSE clause statement_list executes.\n\nEach statement_list consists of one or more SQL statements; an empty\nstatement_list is not permitted.\n\nURL: https://mariadb.com/kb/en/if-statement/\n\n','','https://mariadb.com/kb/en/if-statement/'); -insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (29,19,'^','Syntax:\n^\n\nBitwise XOR:\n\nURL: https://mariadb.com/kb/en/bitwise-xor/\n\n','MariaDB> SELECT 1 ^ 1;\n -> 0\nMariaDB> SELECT 1 ^ 0;\n -> 1\nMariaDB> SELECT 11 ^ 3;\n -> 8\n','https://mariadb.com/kb/en/bitwise-xor/'); -insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (30,39,'DROP VIEW','Syntax:\nDROP VIEW [IF EXISTS]\n view_name [, view_name] ...\n [RESTRICT | CASCADE]\n\nDROP VIEW removes one or more views. You must have the DROP privilege\nfor each view. If any of the views named in the argument list do not\nexist, MySQL returns an error indicating by name which nonexisting\nviews it was unable to drop, but it also drops all of the views in the\nlist that do exist.\n\nThe IF EXISTS clause prevents an error from occurring for views that\ndon\'t exist. When this clause is given, a NOTE is generated for each\nnonexistent view. See [HELP SHOW WARNINGS].\n\nRESTRICT and CASCADE, if given, are parsed and ignored.\n\nURL: https://mariadb.com/kb/en/drop-view/\n\n','','https://mariadb.com/kb/en/drop-view/'); -insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (31,30,'WITHIN','Within(g1,g2)\n\nReturns 1 or 0 to indicate whether g1 is spatially within g2. This\ntests the opposite relationship as Contains().\n\nURL: https://mariadb.com/kb/en/within/\n\n','','https://mariadb.com/kb/en/within/'); -insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (32,31,'WEEK','Syntax:\nWEEK(date[,mode])\n\nThis function returns the week number for date. The two-argument form\nof WEEK() enables you to specify whether the week starts on Sunday or\nMonday and whether the return value should be in the range from 0 to 53\nor from 1 to 53. If the mode argument is omitted, the value of the\ndefault_week_format system variable is used. See\nhttps://mariadb.com/kb/en/server-system-variables/.\n\nURL: https://mariadb.com/kb/en/week/\n\n','MariaDB> SELECT WEEK(\'2008-02-20\');\n -> 7\nMariaDB> SELECT WEEK(\'2008-02-20\',0);\n -> 7\nMariaDB> SELECT WEEK(\'2008-02-20\',1);\n -> 8\nMariaDB> SELECT WEEK(\'2008-12-31\',1);\n -> 53\n','https://mariadb.com/kb/en/week/'); -insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (33,26,'SHOW PLUGINS','Syntax:\nSHOW PLUGINS\n\nSHOW PLUGINS displays information about server plugins. Plugin\ninformation is also available in the INFORMATION_SCHEMA.PLUGINS table.\nSee https://mariadb.com/kb/en/information_schemaplugins-table/.\n\nExample of SHOW PLUGINS output:\n\nMariaDB> SHOW PLUGINS\\G\n*************************** 1. row ***************************\n Name: binlog\n Status: ACTIVE\n Type: STORAGE ENGINE\nLibrary: NULL\nLicense: GPL\n*************************** 2. row ***************************\n Name: CSV\n Status: ACTIVE\n Type: STORAGE ENGINE\nLibrary: NULL\nLicense: GPL\n*************************** 3. row ***************************\n Name: MEMORY\n Status: ACTIVE\n Type: STORAGE ENGINE\nLibrary: NULL\nLicense: GPL\n*************************** 4. row ***************************\n Name: MyISAM\n Status: ACTIVE\n Type: STORAGE ENGINE\nLibrary: NULL\nLicense: GPL\n...\n\nURL: https://mariadb.com/kb/en/show-plugins/\n\n','','https://mariadb.com/kb/en/show-plugins/'); -insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (34,21,'DROP FUNCTION UDF','Syntax:\nDROP FUNCTION function_name\n\nThis statement drops the user-defined function (UDF) named\nfunction_name.\n\nTo drop a function, you must have the DELETE privilege for the mysql\ndatabase. This is because DROP FUNCTION removes a row from the\nmysql.func system table that records the function\'s name, type, and\nshared library name.\n\nURL: https://mariadb.com/kb/en/drop-function-udf/\n\n','','https://mariadb.com/kb/en/drop-function-udf/'); -insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (35,8,'PREPARE','Syntax:\nPREPARE stmt_name FROM preparable_stmt\n\nThe PREPARE statement prepares a statement and assigns it a name,\nstmt_name, by which to refer to the statement later. Statement names\nare not case sensitive. preparable_stmt is either a string literal or a\nuser variable that contains the text of the statement. The text must\nrepresent a single SQL statement, not multiple statements. Within the\nstatement, "?" characters can be used as parameter markers to indicate\nwhere data values are to be bound to the query later when you execute\nit. The "?" characters should not be enclosed within quotation marks,\neven if you intend to bind them to string values. Parameter markers can\nbe used only where data values should appear, not for SQL keywords,\nidentifiers, and so forth.\n\nIf a prepared statement with the given name already exists, it is\ndeallocated implicitly before the new statement is prepared. This means\nthat if the new statement contains an error and cannot be prepared, an\nerror is returned and no statement with the given name exists.\n\nA prepared statement is executed with EXECUTE and released with\nDEALLOCATE PREPARE.\n\nThe scope of a prepared statement is the session within which it is\ncreated. Other sessions cannot see it.\n\nURL: https://mariadb.com/kb/en/prepare-statement/\n\n','','https://mariadb.com/kb/en/prepare-statement/'); -insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (36,8,'LOCK','Syntax:\nLOCK TABLES\n tbl_name [[AS] alias] lock_type\n [, tbl_name [[AS] alias] lock_type] ...\n\nlock_type:\n READ [LOCAL]\n | [LOW_PRIORITY] WRITE\n\nUNLOCK TABLES\n\nMySQL enables client sessions to acquire table locks explicitly for the\npurpose of cooperating with other sessions for access to tables, or to\nprevent other sessions from modifying tables during periods when a\nsession requires exclusive access to them. A session can acquire or\nrelease locks only for itself. One session cannot acquire locks for\nanother session or release locks held by another session.\n\nLocks may be used to emulate transactions or to get more speed when\nupdating tables. This is explained in more detail later in this\nsection.\n\nLOCK TABLES explicitly acquires table locks for the current client\nsession. Table locks can be acquired for base tables or views. You must\nhave the LOCK TABLES privilege, and the SELECT privilege for each\nobject to be locked.\n\nFor view locking, LOCK TABLES adds all base tables used in the view to\nthe set of tables to be locked and locks them automatically. If you\nlock a table explicitly with LOCK TABLES, any tables used in triggers\nare also locked implicitly, as described in\nhttps://mariadb.com/kb/en/triggers-and-implicit-locks/.\n\nUNLOCK TABLES explicitly releases any table locks held by the current\nsession. LOCK TABLES implicitly releases any table locks held by the\ncurrent session before acquiring new locks.\n\nAnother use for UNLOCK TABLES is to release the global read lock\nacquired with the FLUSH TABLES WITH READ LOCK statement, which enables\nyou to lock all tables in all databases. See [HELP FLUSH]. (This is a\nvery convenient way to get backups if you have a file system such as\nVeritas that can take snapshots in time.)\n\nURL: https://mariadb.com/kb/en/transactions-lock/\n\n','','https://mariadb.com/kb/en/transactions-lock/'); -insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (37,37,'UPDATEXML','Syntax:\nUpdateXML(xml_target, xpath_expr, new_xml)\n\nThis function replaces a single portion of a given fragment of XML\nmarkup xml_target with a new XML fragment new_xml, and then returns the\nchanged XML. The portion of xml_target that is replaced matches an\nXPath expression xpath_expr supplied by the user. In MySQL 5.5, the\nXPath expression can contain at most 127 characters. (This limitation\nis lifted in MySQL 5.6.)\n\nIf no expression matching xpath_expr is found, or if multiple matches\nare found, the function returns the original xml_target XML fragment.\nAll three arguments should be strings.\n\nURL: https://mariadb.com/kb/en/updatexml/\n\n','MariaDB> SELECT\n -> UpdateXML(\'ccc\', \'/a\', \'fff\') AS val1,\n -> UpdateXML(\'ccc\', \'/b\', \'fff\') AS val2,\n -> UpdateXML(\'ccc\', \'//b\', \'fff\') AS val3,\n -> UpdateXML(\'ccc\', \'/a/d\', \'fff\') AS val4,\n -> UpdateXML(\'ccc\', \'/a/d\', \'fff\') AS val5\n -> \\G\n\n*************************** 1. row ***************************\nval1: fff\nval2: ccc\nval3: fff\nval4: cccfff\nval5: ccc\n','https://mariadb.com/kb/en/updatexml/'); -insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (38,8,'RESET SLAVE','Syntax:\nRESET SLAVE [ALL]\n\nRESET SLAVE makes the slave forget its replication position in the\nmaster\'s binary log. This statement is meant to be used for a clean\nstart: It deletes the master.info and relay-log.info files, all the\nrelay log files, and starts a new relay log file. To use RESET SLAVE,\nthe slave replication threads must be stopped (use STOP SLAVE if\nnecessary).\n\n*Note*: All relay log files are deleted, even if they have not been\ncompletely executed by the slave SQL thread. (This is a condition\nlikely to exist on a replication slave if you have issued a STOP SLAVE\nstatement or if the slave is highly loaded.)\n\nIn MySQL 5.5 (unlike the case in MySQL 5.1 and earlier), RESET SLAVE\ndoes not change any replication connection parameters such as master\nhost, master port, master user, or master password, which are retained\nin memory. This means that START SLAVE can be issued without requiring\na CHANGE MASTER TO statement following RESET SLAVE.\n\nIn MySQL 5.5.16 and later, you can use RESET SLAVE ALL to reset these\nconnection parameters (Bug #11809016). Connection parameters are also\nreset if the slave mysqld is shut down.\n\nIf the slave SQL thread was in the middle of replicating temporary\ntables when it was stopped, and RESET SLAVE is issued, these replicated\ntemporary tables are deleted on the slave.\n\nURL: https://mariadb.com/kb/en/reset-slave-connection_name/\n\n','','https://mariadb.com/kb/en/reset-slave-connection_name/'); -insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (39,26,'SHOW BINARY LOGS','Syntax:\nSHOW BINARY LOGS\nSHOW MASTER LOGS\n\nLists the binary log files on the server. This statement is used as\npart of the procedure described in [HELP PURGE BINARY LOGS], that shows\nhow to determine which logs can be purged.\n\nMariaDB> SHOW BINARY LOGS;\n+---------------+-----------+\n| Log_name | File_size |\n+---------------+-----------+\n| binlog.000015 | 724935 |\n| binlog.000016 | 733481 |\n+---------------+-----------+\n\nURL: https://mariadb.com/kb/en/show-binary-logs/\n\n','','https://mariadb.com/kb/en/show-binary-logs/'); -insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (40,24,'POLYGON','Polygon(ls1,ls2,...)\n\nConstructs a Polygon value from a number of LineString or WKB\nLineString arguments. If any argument does not represent a LinearRing\n(that is, not a closed and simple LineString), the return value is\nNULL.\n\nURL: https://mariadb.com/kb/en/polygon/\n\n','','https://mariadb.com/kb/en/polygon/'); -insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (41,31,'MINUTE','Syntax:\nMINUTE(time)\n\nReturns the minute for time, in the range 0 to 59.\n\nURL: https://mariadb.com/kb/en/minute/\n\n','MariaDB> SELECT MINUTE(\'2008-02-03 10:05:03\');\n -> 5\n','https://mariadb.com/kb/en/minute/'); -insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (42,31,'DAY','Syntax:\nDAY(date)\n\nDAY() is a synonym for DAYOFMONTH().\n\nURL: https://mariadb.com/kb/en/day/\n\n','','https://mariadb.com/kb/en/day/'); -insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (43,37,'MID','Syntax:\nMID(str,pos,len)\n\nMID(str,pos,len) is a synonym for SUBSTRING(str,pos,len).\n\nURL: https://mariadb.com/kb/en/mid/\n\n','','https://mariadb.com/kb/en/mid/'); -insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (44,14,'UUID','Syntax:\nUUID()\n\nReturns a Universal Unique Identifier (UUID) generated according to\n"DCE 1.1: Remote Procedure Call" (Appendix A) CAE (Common Applications\nEnvironment) Specifications published by The Open Group in October 1997\n(Document Number C706,\nhttp://www.opengroup.org/public/pubs/catalog/c706.htm).\n\nA UUID is designed as a number that is globally unique in space and\ntime. Two calls to UUID() are expected to generate two different\nvalues, even if these calls are performed on two separate computers\nthat are not connected to each other.\n\nA UUID is a 128-bit number represented by a utf8 string of five\nhexadecimal numbers in aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee format:\n\no The first three numbers are generated from a timestamp.\n\no The fourth number preserves temporal uniqueness in case the timestamp\n value loses monotonicity (for example, due to daylight saving time).\n\no The fifth number is an IEEE 802 node number that provides spatial\n uniqueness. A random number is substituted if the latter is not\n available (for example, because the host computer has no Ethernet\n card, or we do not know how to find the hardware address of an\n interface on your operating system). In this case, spatial uniqueness\n cannot be guaranteed. Nevertheless, a collision should have very low\n probability.\n\n Currently, the MAC address of an interface is taken into account only\n on FreeBSD and Linux. On other operating systems, MySQL uses a\n randomly generated 48-bit number.\n\nURL: https://mariadb.com/kb/en/uuid/\n\n','MariaDB> SELECT UUID();\n -> \'6ccd780c-baba-1026-9564-0040f4311e29\'\n','https://mariadb.com/kb/en/uuid/'); -insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (45,24,'LINESTRING','LineString(pt1,pt2,...)\n\nConstructs a LineString value from a number of Point or WKB Point\narguments. If the number of arguments is less than two, the return\nvalue is NULL.\n\nURL: https://mariadb.com/kb/en/linestring/\n\n','','https://mariadb.com/kb/en/linestring/'); -insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (46,14,'SLEEP','Syntax:\nSLEEP(duration)\n\nSleeps (pauses) for the number of seconds given by the duration\nargument, then returns 0. If SLEEP() is interrupted, it returns 1. The\nduration may have a fractional part given in microseconds.\n\nURL: https://mariadb.com/kb/en/sleep/\n\n','','https://mariadb.com/kb/en/sleep/'); -insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (47,17,'CONNECTION_ID','Syntax:\nCONNECTION_ID()\n\nReturns the connection ID (thread ID) for the connection. Every\nconnection has an ID that is unique among the set of currently\nconnected clients.\n\nURL: https://mariadb.com/kb/en/connection_id/\n\n','MariaDB> SELECT CONNECTION_ID();\n -> 23786\n','https://mariadb.com/kb/en/connection_id/'); -insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (48,27,'DELETE','Syntax:\nSingle-table syntax:\n\nDELETE [LOW_PRIORITY] [QUICK] [IGNORE] FROM tbl_name\n [WHERE where_condition]\n [ORDER BY ...]\n [LIMIT row_count]\n\nMultiple-table syntax:\n\nDELETE [LOW_PRIORITY] [QUICK] [IGNORE]\n tbl_name[.*] [, tbl_name[.*]] ...\n FROM table_references\n [WHERE where_condition]\n\nOr:\n\nDELETE [LOW_PRIORITY] [QUICK] [IGNORE]\n FROM tbl_name[.*] [, tbl_name[.*]] ...\n USING table_references\n [WHERE where_condition]\n\nFor the single-table syntax, the DELETE statement deletes rows from\ntbl_name and returns a count of the number of deleted rows. This count\ncan be obtained by calling the ROW_COUNT() function (see\nhttps://mariadb.com/kb/en/information-functions-row_count/). The\nWHERE clause, if given, specifies the conditions that identify which\nrows to delete. With no WHERE clause, all rows are deleted. If the\nORDER BY clause is specified, the rows are deleted in the order that is\nspecified. The LIMIT clause places a limit on the number of rows that\ncan be deleted.\n\nFor the multiple-table syntax, DELETE deletes from each tbl_name the\nrows that satisfy the conditions. In this case, ORDER BY and LIMIT\ncannot be used.\n\nwhere_condition is an expression that evaluates to true for each row to\nbe deleted. It is specified as described in\nhttps://mariadb.com/kb/en/select/.\n\nCurrently, you cannot delete from a table and select from the same\ntable in a subquery.\n\nYou need the DELETE privilege on a table to delete rows from it. You\nneed only the SELECT privilege for any columns that are only read, such\nas those named in the WHERE clause.\n\nAs stated, a DELETE statement with no WHERE clause deletes all rows. A\nfaster way to do this, when you do not need to know the number of\ndeleted rows, is to use TRUNCATE TABLE. However, within a transaction\nor if you have a lock on the table, TRUNCATE TABLE cannot be used\nwhereas DELETE can. See [HELP TRUNCATE TABLE], and [HELP LOCK].\n\nURL: https://mariadb.com/kb/en/delete/\n\n','','https://mariadb.com/kb/en/delete/'); -insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (49,4,'ROUND','Syntax:\nROUND(X), ROUND(X,D)\n\nRounds the argument X to D decimal places. The rounding algorithm\ndepends on the data type of X. D defaults to 0 if not specified. D can\nbe negative to cause D digits left of the decimal point of the value X\nto become zero.\n\nURL: https://mariadb.com/kb/en/round/\n\n','MariaDB> SELECT ROUND(-1.23);\n -> -1\nMariaDB> SELECT ROUND(-1.58);\n -> -2\nMariaDB> SELECT ROUND(1.58);\n -> 2\nMariaDB> SELECT ROUND(1.298, 1);\n -> 1.3\nMariaDB> SELECT ROUND(1.298, 0);\n -> 1\nMariaDB> SELECT ROUND(23.298, -1);\n -> 20\n','https://mariadb.com/kb/en/round/'); -insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (50,7,'NULLIF','Syntax:\nNULLIF(expr1,expr2)\n\nReturns NULL if expr1 = expr2 is true, otherwise returns expr1. This is\nthe same as CASE WHEN expr1 = expr2 THEN NULL ELSE expr1 END.\n\nURL: https://mariadb.com/kb/en/nullif/\n\n','MariaDB> SELECT NULLIF(1,1);\n -> NULL\nMariaDB> SELECT NULLIF(1,2);\n -> 1\n','https://mariadb.com/kb/en/nullif/'); -insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (51,23,'CLOSE','Syntax:\nCLOSE cursor_name\n\nThis statement closes a previously opened cursor. For an example, see\nhttps://mariadb.com/kb/en/cursor-overview/.\n\nAn error occurs if the cursor is not open.\n\nIf not closed explicitly, a cursor is closed at the end of the BEGIN\n... END block in which it was declared.\n\nURL: https://mariadb.com/kb/en/close/\n\n','','https://mariadb.com/kb/en/close/'); -insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (52,8,'STOP SLAVE','Syntax:\nSTOP SLAVE [thread_types]\n\nthread_types:\n [thread_type [, thread_type] ... ]\n\nthread_type: IO_THREAD | SQL_THREAD\n\nStops the slave threads. STOP SLAVE requires the SUPER privilege.\nRecommended best practice is to execute STOP SLAVE on the slave before\nstopping the slave server (see\nhttp://dev.mysql.com/doc/refman/5.5/en/server-shutdown.html, for more\ninformation).\n\nWhen using the row-based logging format: You should execute STOP SLAVE\non the slave prior to shutting down the slave server if you are\nreplicating any tables that use a nontransactional storage engine (see\nthe Note later in this section). In MySQL 5.5.9 and later, you can also\nuse STOP SLAVE SQL_THREAD for this purpose.\n\nLike START SLAVE, this statement may be used with the IO_THREAD and\nSQL_THREAD options to name the thread or threads to be stopped.\n\n*Note*: In MySQL 5.5, STOP SLAVE waits until the current replication\nevent group affecting one or more non-transactional tables has finished\nexecuting (if there is any such replication group), or until the user\nissues a KILL QUERY or KILL CONNECTION statement. (Bug #319, Bug\n#38205)\n\nURL: https://mariadb.com/kb/en/stop-slave/\n\n','','https://mariadb.com/kb/en/stop-slave/'); -insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (53,31,'TIMEDIFF','Syntax:\nTIMEDIFF(expr1,expr2)\n\nTIMEDIFF() returns expr1 - expr2 expressed as a time value. expr1 and\nexpr2 are time or date-and-time expressions, but both must be of the\nsame type.\n\nThe result returned by TIMEDIFF() is limited to the range allowed for\nTIME values. Alternatively, you can use either of the functions\nTIMESTAMPDIFF() and UNIX_TIMESTAMP(), both of which return integers.\n\nURL: https://mariadb.com/kb/en/timediff/\n\n','MariaDB> SELECT TIMEDIFF(\'2000:01:01 00:00:00\',\n -> \'2000:01:01 00:00:00.000001\');\n -> \'-00:00:00.000001\'\nMariaDB> SELECT TIMEDIFF(\'2008-12-31 23:59:59.000001\',\n -> \'2008-12-30 01:01:01.000002\');\n -> \'46:58:57.999999\'\n','https://mariadb.com/kb/en/timediff/'); -insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (54,37,'REPLACE FUNCTION','Syntax:\nREPLACE(str,from_str,to_str)\n\nReturns the string str with all occurrences of the string from_str\nreplaced by the string to_str. REPLACE() performs a case-sensitive\nmatch when searching for from_str.\n\nURL: https://mariadb.com/kb/en/replace-function/\n\n','MariaDB> SELECT REPLACE(\'www.mariadb.org\', \'w\', \'Ww\');\n -> \'WwWwWw.mariadb.org\'\n','https://mariadb.com/kb/en/replace-function/'); -insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (55,28,'USE','Syntax:\nUSE db_name\n\nThe USE db_name statement tells MySQL to use the db_name database as\nthe default (current) database for subsequent statements. The database\nremains the default until the end of the session or another USE\nstatement is issued:\n\nUSE db1;\nSELECT COUNT(*) FROM mytable; # selects from db1.mytable\nUSE db2;\nSELECT COUNT(*) FROM mytable; # selects from db2.mytable\n\nURL: https://mariadb.com/kb/en/use/\n\n','','https://mariadb.com/kb/en/use/'); -insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (56,3,'LINEFROMTEXT','LineFromText(wkt[,srid]), LineStringFromText(wkt[,srid])\n\nConstructs a LINESTRING value using its WKT representation and SRID.\n\nURL: https://mariadb.com/kb/en/linefromtext/\n\n','','https://mariadb.com/kb/en/linefromtext/'); -insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (57,7,'CASE OPERATOR','Syntax:\nCASE value WHEN [compare_value] THEN result [WHEN [compare_value] THEN\nresult ...] [ELSE result] END\n\nCASE WHEN [condition] THEN result [WHEN [condition] THEN result ...]\n[ELSE result] END\n\nThe first version returns the result where value=compare_value. The\nsecond version returns the result for the first condition that is true.\nIf there was no matching result value, the result after ELSE is\nreturned, or NULL if there is no ELSE part.\n\nURL: https://mariadb.com/kb/en/case-operator/\n\n','MariaDB> SELECT CASE 1 WHEN 1 THEN \'one\'\n -> WHEN 2 THEN \'two\' ELSE \'more\' END;\n -> \'one\'\nMariaDB> SELECT CASE WHEN 1>0 THEN \'true\' ELSE \'false\' END;\n -> \'true\'\nMariaDB> SELECT CASE BINARY \'B\'\n -> WHEN \'a\' THEN 1 WHEN \'b\' THEN 2 END;\n -> NULL\n','https://mariadb.com/kb/en/case-operator/'); -insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (58,26,'SHOW MASTER STATUS','Syntax:\nSHOW MASTER STATUS\n\nThis statement provides status information about the binary log files\nof the master. It requires either the SUPER or REPLICATION CLIENT\nprivilege.\n\nExample:\n\nMariaDB> SHOW MASTER STATUS;\n+---------------+----------+--------------+------------------+\n| File | Position | Binlog_Do_DB | Binlog_Ignore_DB |\n+---------------+----------+--------------+------------------+\n| mysql-bin.003 | 73 | test | manual,mysql |\n+---------------+----------+--------------+------------------+\n\nURL: https://mariadb.com/kb/en/show-master-status/\n\n','','https://mariadb.com/kb/en/show-master-status/'); -insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (59,31,'ADDTIME','Syntax:\nADDTIME(expr1,expr2)\n\nADDTIME() adds expr2 to expr1 and returns the result. expr1 is a time\nor datetime expression, and expr2 is a time expression.\n\nURL: https://mariadb.com/kb/en/addtime/\n\n','MariaDB> SELECT ADDTIME(\'2007-12-31 23:59:59.999999\', \'1 1:1:1.000002\');\n -> \'2008-01-02 01:01:01.000001\'\nMariaDB> SELECT ADDTIME(\'01:00:00.999999\', \'02:00:00.999998\');\n -> \'03:00:01.999997\'\n','https://mariadb.com/kb/en/addtime/'); -insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (60,34,'SPATIAL','For MyISAM tables, MySQL can create spatial indexes using syntax\nsimilar to that for creating regular indexes, but extended with the\nSPATIAL keyword. Currently, columns in spatial indexes must be declared\nNOT NULL. The following examples demonstrate how to create spatial\nindexes:\n\no With CREATE TABLE:\n\nCREATE TABLE geom (g GEOMETRY NOT NULL, SPATIAL INDEX(g)) ENGINE=MyISAM;\n\no With ALTER TABLE:\n\nALTER TABLE geom ADD SPATIAL INDEX(g);\n\no With CREATE INDEX:\n\nCREATE SPATIAL INDEX sp_index ON geom (g);\n\nFor MyISAM tables, SPATIAL INDEX creates an R-tree index. For storage\nengines that support nonspatial indexing of spatial columns, the engine\ncreates a B-tree index. A B-tree index on spatial values will be useful\nfor exact-value lookups, but not for range scans.\n\nFor more information on indexing spatial columns, see [HELP CREATE\nINDEX].\n\nTo drop spatial indexes, use ALTER TABLE or DROP INDEX:\n\no With ALTER TABLE:\n\nALTER TABLE geom DROP INDEX g;\n\no With DROP INDEX:\n\nDROP INDEX sp_index ON geom;\n\nExample: Suppose that a table geom contains more than 32,000\ngeometries, which are stored in the column g of type GEOMETRY. The\ntable also has an AUTO_INCREMENT column fid for storing object ID\nvalues.\n\nURL: https://mariadb.com/kb/en/spatial/\n\n','','https://mariadb.com/kb/en/spatial/'); -insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (61,31,'TO_SECONDS','Syntax:\nTO_SECONDS(expr)\n\nGiven a date or datetime expr, returns a the number of seconds since\nthe year 0. If expr is not a valid date or datetime value, returns\nNULL.\n\nURL: https://mariadb.com/kb/en/to_seconds/\n\n','MariaDB> SELECT TO_SECONDS(950501);\n -> 62966505600\nMariaDB> SELECT TO_SECONDS(\'2009-11-29\');\n -> 63426672000\nMariaDB> SELECT TO_SECONDS(\'2009-11-29 13:43:32\');\n -> 63426721412\nMariaDB> SELECT TO_SECONDS( NOW() );\n -> 63426721458\n','https://mariadb.com/kb/en/to_seconds/'); -insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (62,31,'TIMESTAMPDIFF','Syntax:\nTIMESTAMPDIFF(unit,datetime_expr1,datetime_expr2)\n\nReturns datetime_expr2 - datetime_expr1, where datetime_expr1 and\ndatetime_expr2 are date or datetime expressions. One expression may be\na date and the other a datetime; a date value is treated as a datetime\nhaving the time part \'00:00:00\' where necessary. The unit for the\nresult (an integer) is given by the unit argument. The legal values for\nunit are the same as those listed in the description of the\nTIMESTAMPADD() function.\n\nURL: https://mariadb.com/kb/en/timestampdiff/\n\n','MariaDB> SELECT TIMESTAMPDIFF(MONTH,\'2003-02-01\',\'2003-05-01\');\n -> 3\nMariaDB> SELECT TIMESTAMPDIFF(YEAR,\'2002-05-01\',\'2001-01-01\');\n -> -1\nMariaDB> SELECT TIMESTAMPDIFF(MINUTE,\'2003-02-01\',\'2003-05-01 12:05:55\');\n -> 128885\n','https://mariadb.com/kb/en/timestampdiff/'); -insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (63,37,'UPPER','Syntax:\nUPPER(str)\n\nReturns the string str with all characters changed to uppercase\naccording to the current character set mapping. The default is latin1\n(cp1252 West European).\n\nMariaDB> SELECT UPPER(\'Hej\');\n -> \'HEJ\'\n\nSee the description of LOWER() for information that also applies to\nUPPER(), such as information about how to perform lettercase conversion\nof binary strings (BINARY, VARBINARY, BLOB) for which these functions\nare ineffective.\n\nURL: https://mariadb.com/kb/en/upper/\n\n','','https://mariadb.com/kb/en/upper/'); -insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (64,31,'FROM_UNIXTIME','Syntax:\nFROM_UNIXTIME(unix_timestamp), FROM_UNIXTIME(unix_timestamp,format)\n\nReturns a representation of the unix_timestamp argument as a value in\n\'YYYY-MM-DD HH:MM:SS\' or YYYYMMDDHHMMSS.uuuuuu format, depending on\nwhether the function is used in a string or numeric context. The value\nis expressed in the current time zone. unix_timestamp is an internal\ntimestamp value such as is produced by the UNIX_TIMESTAMP() function.\n\nIf format is given, the result is formatted according to the format\nstring, which is used the same way as listed in the entry for the\nDATE_FORMAT() function.\n\nURL: https://mariadb.com/kb/en/from_unixtime/\n\n','MariaDB> SELECT FROM_UNIXTIME(1196440219);\n -> \'2007-11-30 10:30:19\'\nMariaDB> SELECT FROM_UNIXTIME(1196440219) + 0;\n -> 20071130103019.000000\nMariaDB> SELECT FROM_UNIXTIME(UNIX_TIMESTAMP(),\n -> \'%Y %D %M %h:%i:%s %x\');\n -> \'2007 30th November 10:30:59 2007\'\n','https://mariadb.com/kb/en/from_unixtime/'); -insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (65,22,'MEDIUMBLOB','MEDIUMBLOB\n\nA BLOB column with a maximum length of 16,777,215 (224 - 1) bytes. Each\nMEDIUMBLOB value is stored using a 3-byte length prefix that indicates\nthe number of bytes in the value.\n\nURL: https://mariadb.com/kb/en/mediumblob/\n\n','','https://mariadb.com/kb/en/mediumblob/'); -insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (66,12,'SHA2','Syntax:\nSHA2(str, hash_length)\n\nCalculates the SHA-2 family of hash functions (SHA-224, SHA-256,\nSHA-384, and SHA-512). The first argument is the cleartext string to be\nhashed. The second argument indicates the desired bit length of the\nresult, which must have a value of 224, 256, 384, 512, or 0 (which is\nequivalent to 256). If either argument is NULL or the hash length is\nnot one of the permitted values, the return value is NULL. Otherwise,\nthe function result is a hash value containing the desired number of\nbits. See the notes at the beginning of this section about storing hash\nvalues efficiently.\n\nAs of MySQL 5.5.6, the return value is a nonbinary string in the\nconnection character set. Before 5.5.6, the return value is a binary\nstring; see the notes at the beginning of this section about using the\nvalue as a nonbinary string.\n\nURL: https://mariadb.com/kb/en/sha2/\n\n','MariaDB> SELECT SHA2(\'abc\', 224);\n -> \'23097d223405d8228642a477bda255b32aadbce4bda0b3f7e36c9da7\'\n','https://mariadb.com/kb/en/sha2/'); -insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (67,7,'IFNULL','Syntax:\nIFNULL(expr1,expr2)\n\nIf expr1 is not NULL, IFNULL() returns expr1; otherwise it returns\nexpr2. IFNULL() returns a numeric or string value, depending on the\ncontext in which it is used.\n\nURL: https://mariadb.com/kb/en/ifnull/\n\n','MariaDB> SELECT IFNULL(1,0);\n -> 1\nMariaDB> SELECT IFNULL(NULL,10);\n -> 10\nMariaDB> SELECT IFNULL(1/0,10);\n -> 10\nMariaDB> SELECT IFNULL(1/0,\'yes\');\n -> \'yes\'\n','https://mariadb.com/kb/en/ifnull/'); -insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (68,26,'SHOW FUNCTION CODE','Syntax:\nSHOW FUNCTION CODE func_name\n\nThis statement is similar to SHOW PROCEDURE CODE but for stored\nfunctions. See [HELP SHOW PROCEDURE CODE].\n\nURL: https://mariadb.com/kb/en/show-function-code/\n\n','','https://mariadb.com/kb/en/show-function-code/'); -insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (69,26,'SHOW ERRORS','Syntax:\nSHOW ERRORS [LIMIT [offset,] row_count]\nSHOW COUNT(*) ERRORS\n\nThis statement is similar to SHOW WARNINGS, except that it displays\ninformation only for errors, rather than for errors, warnings, and\nnotes.\n\nThe LIMIT clause has the same syntax as for the SELECT statement. See\nhttps://mariadb.com/kb/en/select/.\n\nThe SHOW COUNT(*) ERRORS statement displays the number of errors. You\ncan also retrieve this number from the error_count variable:\n\nSHOW COUNT(*) ERRORS;\nSELECT @@error_count;\n\nSHOW ERRORS and error_count apply only to errors, not warnings or\nnotes. In other respects, they are similar to SHOW WARNINGS and\nwarning_count. In particular, SHOW ERRORS cannot display information\nfor more than max_error_count messages, and error_count can exceed the\nvalue of max_error_count if the number of errors exceeds\nmax_error_count.\n\nURL: https://mariadb.com/kb/en/show-errors/\n\n','','https://mariadb.com/kb/en/show-errors/'); -insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (70,18,'LEAST','Syntax:\nLEAST(value1,value2,...)\n\nWith two or more arguments, returns the smallest (minimum-valued)\nargument. The arguments are compared using the following rules:\n\no If any argument is NULL, the result is NULL. No comparison is needed.\n\no If the return value is used in an INTEGER context or all arguments\n are integer-valued, they are compared as integers.\n\no If the return value is used in a REAL context or all arguments are\n real-valued, they are compared as reals.\n\no If the arguments comprise a mix of numbers and strings, they are\n compared as numbers.\n\no If any argument is a nonbinary (character) string, the arguments are\n compared as nonbinary strings.\n\no In all other cases, the arguments are compared as binary strings.\n\nURL: https://mariadb.com/kb/en/least/\n\n','MariaDB> SELECT LEAST(2,0);\n -> 0\nMariaDB> SELECT LEAST(34.0,3.0,5.0,767.0);\n -> 3.0\nMariaDB> SELECT LEAST(\'B\',\'A\',\'C\');\n -> \'A\'\n','https://mariadb.com/kb/en/least/'); -insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (71,18,'=','=\n\nEqual:\n\nURL: https://mariadb.com/kb/en/equal/\n\n','MariaDB> SELECT 1 = 0;\n -> 0\nMariaDB> SELECT \'0\' = 0;\n -> 1\nMariaDB> SELECT \'0.0\' = 0;\n -> 1\nMariaDB> SELECT \'0.01\' = 0;\n -> 0\nMariaDB> SELECT \'.01\' = 0.01;\n -> 1\n','https://mariadb.com/kb/en/equal/'); -insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (72,37,'REVERSE','Syntax:\nREVERSE(str)\n\nReturns the string str with the order of the characters reversed.\n\nURL: https://mariadb.com/kb/en/reverse/\n\n','MariaDB> SELECT REVERSE(\'abc\');\n -> \'cba\'\n','https://mariadb.com/kb/en/reverse/'); -insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (73,18,'ISNULL','Syntax:\nISNULL(expr)\n\nIf expr is NULL, ISNULL() returns 1, otherwise it returns 0.\n\nURL: https://mariadb.com/kb/en/isnull/\n\n','MariaDB> SELECT ISNULL(1+1);\n -> 0\nMariaDB> SELECT ISNULL(1/0);\n -> 1\n','https://mariadb.com/kb/en/isnull/'); -insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (74,22,'BINARY','BINARY(M)\n\nThe BINARY type is similar to the CHAR type, but stores binary byte\nstrings rather than nonbinary character strings. M represents the\ncolumn length in bytes.\n\nURL: https://mariadb.com/kb/en/binary/\n\n','','https://mariadb.com/kb/en/binary/'); -insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (75,22,'BLOB DATA TYPE','A BLOB is a binary large object that can hold a variable amount of\ndata. The four BLOB types are TINYBLOB, BLOB, MEDIUMBLOB, and LONGBLOB.\nThese differ only in the maximum length of the values they can hold.\nThe four TEXT types are TINYTEXT, TEXT, MEDIUMTEXT, and LONGTEXT. These\ncorrespond to the four BLOB types and have the same maximum lengths and\nstorage requirements. See\nhttps://mariadb.com/kb/en/data-type-storage-requirements/.\n\nURL: https://mariadb.com/kb/en/sql_language-data_types-blob/\n\n','','https://mariadb.com/kb/en/sql_language-data_types-blob/'); -insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (76,36,'BOUNDARY','Boundary(g)\n\nReturns a geometry that is the closure of the combinatorial boundary of\nthe geometry value g.\n\nURL: https://mariadb.com/kb/en/boundary/\n\n','','https://mariadb.com/kb/en/boundary/'); -insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (77,10,'CREATE USER','Syntax:\nCREATE USER user_specification\n [, user_specification] ...\n\nuser_specification:\n user\n [\n IDENTIFIED BY [PASSWORD] \'password\'\n | IDENTIFIED WITH auth_plugin [AS \'auth_string\']\n ]\n\nThe CREATE USER statement creates new MySQL accounts. To use it, you\nmust have the global CREATE USER privilege or the INSERT privilege for\nthe mysql database. For each account, CREATE USER creates a new row in\nthe mysql.user table and assigns the account no privileges. An error\noccurs if the account already exists.\n\nEach account name uses the format described in\nhttps://mariadb.com/kb/en/create-user#account-names. For example:\n\nCREATE USER \'jeffrey\'@\'localhost\' IDENTIFIED BY \'mypass\';\n\nIf you specify only the user name part of the account name, a host name\npart of \'%\' is used.\n\nThe user specification may indicate how the user should authenticate\nwhen connecting to the server:\n\no To enable the user to connect with no password (which is insecure),\n include no IDENTIFIED BY clause:\n\nCREATE USER \'jeffrey\'@\'localhost\';\n\n In this case, the account uses built-in authentication and clients\n must provide no password.\n\no To assign a password, use IDENTIFIED BY with the literal plaintext\n password value:\n\nCREATE USER \'jeffrey\'@\'localhost\' IDENTIFIED BY \'mypass\';\n\n The account uses built-in authentication and clients must match the\n given password.\n\no To avoid specifying the plaintext password if you know its hash value\n (the value that PASSWORD() would return for the password), specify\n the hash value preceded by the keyword PASSWORD:\n\nCREATE USER \'jeffrey\'@\'localhost\'\nIDENTIFIED BY PASSWORD \'*90E462C37378CED12064BB3388827D2BA3A9B689\';\n\n The account uses built-in authentication and clients must match the\n given password.\n\no To authenticate the account using a specific authentication plugin,\n use IDENTIFIED WITH, where auth_plugin is the plugin name. It can be\n an unquoted name or a quoted string literal. \'auth_string\' is an\n optional quoted string literal to pass to the plugin. The plugin\n interprets the meaning of the string, so its format is plugin\n specific. Consult the documentation for a given plugin for\n information about the authentication string values it accepts.\n\nCREATE USER \'jeffrey\'@\'localhost\'\nIDENTIFIED WITH my_auth_plugin;\n\n For connections that use this account, the server invokes the named\n plugin and clients must provide credentials as required for the\n authentication method that the plugin implements. If the server\n cannot find the plugin, either at account-creation time or connect\n time, an error occurs. IDENTIFIED WITH can be used as of MySQL 5.5.7.\n\nThe IDENTIFIED BY and IDENTIFIED WITH clauses are mutually exclusive,\nso at most one of them can be specified for a given user.\n\nFor additional information about setting passwords, see\nhttps://mariadb.com/kb/en/create-user/.\n\nURL: https://mariadb.com/kb/en/create-user/\n\n','','https://mariadb.com/kb/en/create-user/'); -insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (78,24,'POINT','Point(x,y)\n\nConstructs a Point using its coordinates.\n\nURL: https://mariadb.com/kb/en/point/\n\n','','https://mariadb.com/kb/en/point/'); -insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (79,17,'CURRENT_USER','Syntax:\nCURRENT_USER, CURRENT_USER()\n\nReturns the user name and host name combination for the MySQL account\nthat the server used to authenticate the current client. This account\ndetermines your access privileges. The return value is a string in the\nutf8 character set.\n\nThe value of CURRENT_USER() can differ from the value of USER().\n\nURL: https://mariadb.com/kb/en/current_user/\n\n','MariaDB> SELECT USER();\n -> \'davida@localhost\'\nMariaDB> SELECT * FROM mysql.user;\nERROR 1044: Access denied for user \'\'@\'localhost\' to\ndatabase \'mysql\'\nMariaDB> SELECT CURRENT_USER();\n -> \'@localhost\'\n','https://mariadb.com/kb/en/current_user/'); -insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (80,37,'LCASE','Syntax:\nLCASE(str)\n\nLCASE() is a synonym for LOWER().\n\nURL: https://mariadb.com/kb/en/lcase/\n\n','','https://mariadb.com/kb/en/lcase/'); -insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (81,18,'<=','Syntax:\n<=\n\nLess than or equal:\n\nURL: https://mariadb.com/kb/en/less-than-or-equal/\n\n','MariaDB> SELECT 0.1 <= 2;\n -> 1\n','https://mariadb.com/kb/en/less-than-or-equal/'); -insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (82,26,'SHOW PROFILES','Syntax:\nSHOW PROFILES\n\nThe SHOW PROFILES statement, together with SHOW PROFILE, displays\nprofiling information that indicates resource usage for statements\nexecuted during the course of the current session. For more\ninformation, see [HELP SHOW PROFILE].\n\nURL: https://mariadb.com/kb/en/show-profiles/\n\n','','https://mariadb.com/kb/en/show-profiles/'); -insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (83,27,'UPDATE','Syntax:\nSingle-table syntax:\n\nUPDATE [LOW_PRIORITY] [IGNORE] table_reference\n SET col_name1={expr1|DEFAULT} [, col_name2={expr2|DEFAULT}] ...\n [WHERE where_condition]\n [ORDER BY ...]\n [LIMIT row_count]\n\nMultiple-table syntax:\n\nUPDATE [LOW_PRIORITY] [IGNORE] table_references\n SET col_name1={expr1|DEFAULT} [, col_name2={expr2|DEFAULT}] ...\n [WHERE where_condition]\n\nFor the single-table syntax, the UPDATE statement updates columns of\nexisting rows in the named table with new values. The SET clause\nindicates which columns to modify and the values they should be given.\nEach value can be given as an expression, or the keyword DEFAULT to set\na column explicitly to its default value. The WHERE clause, if given,\nspecifies the conditions that identify which rows to update. With no\nWHERE clause, all rows are updated. If the ORDER BY clause is\nspecified, the rows are updated in the order that is specified. The\nLIMIT clause places a limit on the number of rows that can be updated.\n\nFor the multiple-table syntax, UPDATE updates rows in each table named\nin table_references that satisfy the conditions. In this case, ORDER BY\nand LIMIT cannot be used.\n\nwhere_condition is an expression that evaluates to true for each row to\nbe updated. For expression syntax, see\nhttp://dev.mysql.com/doc/refman/5.5/en/expressions.html.\n\ntable_references and where_condition are is specified as described in\nhttps://mariadb.com/kb/en/select/.\n\nYou need the UPDATE privilege only for columns referenced in an UPDATE\nthat are actually updated. You need only the SELECT privilege for any\ncolumns that are read but not modified.\n\nThe UPDATE statement supports the following modifiers:\n\no With the LOW_PRIORITY keyword, execution of the UPDATE is delayed\n until no other clients are reading from the table. This affects only\n storage engines that use only table-level locking (such as MyISAM,\n MEMORY, and MERGE).\n\no With the IGNORE keyword, the update statement does not abort even if\n errors occur during the update. Rows for which duplicate-key\n conflicts occur are not updated. Rows for which columns are updated\n to values that would cause data conversion errors are updated to the\n closest valid values instead.\n\nURL: https://mariadb.com/kb/en/update/\n\n','','https://mariadb.com/kb/en/update/'); -insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (84,18,'IS NOT NULL','Syntax:\nIS NOT NULL\n\nTests whether a value is not NULL.\n\nURL: https://mariadb.com/kb/en/is-not-null/\n\n','MariaDB> SELECT 1 IS NOT NULL, 0 IS NOT NULL, NULL IS NOT NULL;\n -> 1, 1, 0\n','https://mariadb.com/kb/en/is-not-null/'); -insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (85,23,'CASE STATEMENT','Syntax:\nCASE case_value\n WHEN when_value THEN statement_list\n [WHEN when_value THEN statement_list] ...\n [ELSE statement_list]\nEND CASE\n\nOr:\n\nCASE\n WHEN search_condition THEN statement_list\n [WHEN search_condition THEN statement_list] ...\n [ELSE statement_list]\nEND CASE\n\nThe CASE statement for stored programs implements a complex conditional\nconstruct.\n\n*Note*: There is also a CASE expression, which differs from the CASE\nstatement described here. See\nhttps://mariadb.com/kb/en/case-operator/. The\nCASE statement cannot have an ELSE NULL clause, and it is terminated\nwith END CASE instead of END.\n\nFor the first syntax, case_value is an expression. This value is\ncompared to the when_value expression in each WHEN clause until one of\nthem is equal. When an equal when_value is found, the corresponding\nTHEN clause statement_list executes. If no when_value is equal, the\nELSE clause statement_list executes, if there is one.\n\nThis syntax cannot be used to test for equality with NULL because NULL\n= NULL is false. See\nhttps://mariadb.com/kb/en/null-values/.\n\nFor the second syntax, each WHEN clause search_condition expression is\nevaluated until one is true, at which point its corresponding THEN\nclause statement_list executes. If no search_condition is equal, the\nELSE clause statement_list executes, if there is one.\n\nIf no when_value or search_condition matches the value tested and the\nCASE statement contains no ELSE clause, a Case not found for CASE\nstatement error results.\n\nEach statement_list consists of one or more SQL statements; an empty\nstatement_list is not permitted.\n\nTo handle situations where no value is matched by any WHEN clause, use\nan ELSE containing an empty BEGIN ... END block, as shown in this\nexample. (The indentation used here in the ELSE clause is for purposes\nof clarity only, and is not otherwise significant.)\n\nDELIMITER |\n\nCREATE PROCEDURE p()\n BEGIN\n DECLARE v INT DEFAULT 1;\n\n CASE v\n WHEN 2 THEN SELECT v;\n WHEN 3 THEN SELECT 0;\n ELSE\n BEGIN\n END;\n END CASE;\n END;\n |\n\nURL: https://mariadb.com/kb/en/case-statement/\n\n','','https://mariadb.com/kb/en/case-statement/'); -insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (86,8,'EXECUTE STATEMENT','Syntax:\nEXECUTE stmt_name\n [USING @var_name [, @var_name] ...]\n\nAfter preparing a statement with PREPARE, you execute it with an\nEXECUTE statement that refers to the prepared statement name. If the\nprepared statement contains any parameter markers, you must supply a\nUSING clause that lists user variables containing the values to be\nbound to the parameters. Parameter values can be supplied only by user\nvariables, and the USING clause must name exactly as many variables as\nthe number of parameter markers in the statement.\n\nYou can execute a given prepared statement multiple times, passing\ndifferent variables to it or setting the variables to different values\nbefore each execution.\n\nURL: https://mariadb.com/kb/en/execute-statement/\n\n','','https://mariadb.com/kb/en/execute-statement/'); -insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (87,39,'DROP INDEX','Syntax:\nDROP [ONLINE|OFFLINE] INDEX index_name ON tbl_name\n\nDROP INDEX drops the index named index_name from the table tbl_name.\nThis statement is mapped to an ALTER TABLE statement to drop the index.\nSee [HELP ALTER TABLE].\n\nTo drop a primary key, the index name is always PRIMARY, which must be\nspecified as a quoted identifier because PRIMARY is a reserved word:\n\nDROP INDEX `PRIMARY` ON t;\n\nURL: https://mariadb.com/kb/en/drop-index/\n\n','','https://mariadb.com/kb/en/drop-index/'); -insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (88,37,'MATCH AGAINST','Syntax:\nMATCH (col1,col2,...) AGAINST (expr [search_modifier])\n\nMySQL has support for full-text indexing and searching:\n\no A full-text index in MySQL is an index of type FULLTEXT.\n\no Full-text indexes can be used only with MyISAM tables, and can be\n created only for CHAR, VARCHAR, or TEXT columns.\n\no A FULLTEXT index definition can be given in the CREATE TABLE\n statement when a table is created, or added later using ALTER TABLE\n or CREATE INDEX.\n\no For large data sets, it is much faster to load your data into a table\n that has no FULLTEXT index and then create the index after that, than\n to load data into a table that has an existing FULLTEXT index.\n\nFull-text searching is performed using MATCH() ... AGAINST syntax.\nMATCH() takes a comma-separated list that names the columns to be\nsearched. AGAINST takes a string to search for, and an optional\nmodifier that indicates what type of search to perform. The search\nstring must be a literal string, not a variable or a column name. There\nare three types of full-text searches:\n\no A natural language search interprets the search string as a phrase in\n natural human language (a phrase in free text). There are no special\n operators. The stopword list applies. In addition, words that are\n present in 50% or more of the rows are considered common and do not\n match.\n\n Full-text searches are natural language searches if the IN NATURAL\n LANGUAGE MODE modifier is given or if no modifier is given. For more\n information, see\n https://mariadb.com/kb/en/fulltext-index-overview#in-natural-language-mode\n .\n\no A boolean search interprets the search string using the rules of a\n special query language. The string contains the words to search for.\n It can also contain operators that specify requirements such that a\n word must be present or absent in matching rows, or that it should be\n weighted higher or lower than usual. Common words such as "some" or\n "then" are stopwords and do not match if present in the search\n string. The IN BOOLEAN MODE modifier specifies a boolean search. For\n more information, see\n https://mariadb.com/kb/en/fulltext-index-overview#in-boolean-mode.\n\no A query expansion search is a modification of a natural language\n search. The search string is used to perform a natural language\n search. Then words from the most relevant rows returned by the search\n are added to the search string and the search is done again. The\n query returns the rows from the second search. The IN NATURAL\n LANGUAGE MODE WITH QUERY EXPANSION or WITH QUERY EXPANSION modifier\n specifies a query expansion search. For more information, see\n https://mariadb.com/kb/en/fulltext-index-overview#with-query-expansion.\n\nURL: https://mariadb.com/kb/en/match-against/\n\n','MariaDB> SELECT id, body, MATCH (title,body) AGAINST\n -> (\'Security implications of running MySQL as root\'\n -> IN NATURAL LANGUAGE MODE) AS score\n -> FROM articles WHERE MATCH (title,body) AGAINST\n -> (\'Security implications of running MySQL as root\'\n -> IN NATURAL LANGUAGE MODE);\n+----+-------------------------------------+-----------------+\n| id | body | score |\n+----+-------------------------------------+-----------------+\n| 4 | 1. Never run mysqld as root. 2. ... | 1.5219271183014 |\n| 6 | When configured properly, MySQL ... | 1.3114095926285 |\n+----+-------------------------------------+-----------------+\n2 rows in set (0.00 sec)\n','https://mariadb.com/kb/en/match-against/'); -insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (89,39,'CREATE EVENT','Syntax:\nCREATE\n [DEFINER = { user | CURRENT_USER }]\n EVENT\n [IF NOT EXISTS]\n event_name\n ON SCHEDULE schedule\n [ON COMPLETION [NOT] PRESERVE]\n [ENABLE | DISABLE | DISABLE ON SLAVE]\n [COMMENT \'comment\']\n DO event_body;\n\nschedule:\n AT timestamp [+ INTERVAL interval] ...\n | EVERY interval\n [STARTS timestamp [+ INTERVAL interval] ...]\n [ENDS timestamp [+ INTERVAL interval] ...]\n\ninterval:\n quantity {YEAR | QUARTER | MONTH | DAY | HOUR | MINUTE |\n WEEK | SECOND | YEAR_MONTH | DAY_HOUR | DAY_MINUTE |\n DAY_SECOND | HOUR_MINUTE | HOUR_SECOND | MINUTE_SECOND}\n\nThis statement creates and schedules a new event. The event will not\nrun unless the Event Scheduler is enabled. For information about\nchecking Event Scheduler status and enabling it if necessary, see\nhttps://mariadb.com/kb/en/events/.\n\nCREATE EVENT requires the EVENT privilege for the schema in which the\nevent is to be created. It might also require the SUPER privilege,\ndepending on the DEFINER value, as described later in this section.\n\nThe minimum requirements for a valid CREATE EVENT statement are as\nfollows:\n\no The keywords CREATE EVENT plus an event name, which uniquely\n identifies the event in a database schema.\n\no An ON SCHEDULE clause, which determines when and how often the event\n executes.\n\no A DO clause, which contains the SQL statement to be executed by an\n event.\n\nThis is an example of a minimal CREATE EVENT statement:\n\nCREATE EVENT myevent\n ON SCHEDULE AT CURRENT_TIMESTAMP + INTERVAL 1 HOUR\n DO\n UPDATE myschema.mytable SET mycol = mycol + 1;\n\nThe previous statement creates an event named myevent. This event\nexecutes once---one hour following its creation---by running an SQL\nstatement that increments the value of the myschema.mytable table\'s\nmycol column by 1.\n\nThe event_name must be a valid MySQL identifier with a maximum length\nof 64 characters. Event names are not case sensitive, so you cannot\nhave two events named myevent and MyEvent in the same schema. In\ngeneral, the rules governing event names are the same as those for\nnames of stored routines. See\nhttps://mariadb.com/kb/en/identifier-names/.\n\nAn event is associated with a schema. If no schema is indicated as part\nof event_name, the default (current) schema is assumed. To create an\nevent in a specific schema, qualify the event name with a schema using\nschema_name.event_name syntax.\n\nURL: https://mariadb.com/kb/en/create-event/\n\n','','https://mariadb.com/kb/en/create-event/'); -insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (90,4,'ABS','Syntax:\nABS(X)\n\nReturns the absolute value of X.\n\nURL: https://mariadb.com/kb/en/abs/\n\n','MariaDB> SELECT ABS(2);\n -> 2\nMariaDB> SELECT ABS(-32);\n -> 32\n','https://mariadb.com/kb/en/abs/'); -insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (91,32,'POLYFROMWKB','PolyFromWKB(wkb[,srid]), PolygonFromWKB(wkb[,srid])\n\nConstructs a POLYGON value using its WKB representation and SRID.\n\nURL: https://mariadb.com/kb/en/polyfromwkb/\n\n','','https://mariadb.com/kb/en/polyfromwkb/'); -insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (92,37,'NOT LIKE','Syntax:\nexpr NOT LIKE pat [ESCAPE \'escape_char\']\n\nThis is the same as NOT (expr LIKE pat [ESCAPE \'escape_char\']).\n\nURL: https://mariadb.com/kb/en/not-like/\n\n','','https://mariadb.com/kb/en/not-like/'); -insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (93,37,'SPACE','Syntax:\nSPACE(N)\n\nReturns a string consisting of N space characters.\n\nURL: https://mariadb.com/kb/en/space/\n\n','MariaDB> SELECT SPACE(6);\n -> \' \'\n','https://mariadb.com/kb/en/space/'); -insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (94,6,'MBR DEFINITION','Its MBR (Minimum Bounding Rectangle), or Envelope. This is the bounding\ngeometry, formed by the minimum and maximum (X,Y) coordinates:\n\nURL: https://mariadb.com/kb/en/mbr-definition/\n\n','((MINX MINY, MAXX MINY, MAXX MAXY, MINX MAXY, MINX MINY))\n','https://mariadb.com/kb/en/mbr-definition/'); -insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (95,24,'GEOMETRYCOLLECTION','GeometryCollection(g1,g2,...)\n\nConstructs a GeometryCollection.\n\nURL: https://mariadb.com/kb/en/geometrycollection/\n\n','','https://mariadb.com/kb/en/geometrycollection/'); -insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (96,16,'MAX','Syntax:\nMAX([DISTINCT] expr)\n\nReturns the maximum value of expr. MAX() may take a string argument; in\nsuch cases, it returns the maximum string value. See\nhttps://mariadb.com/kb/en/max/. The DISTINCT\nkeyword can be used to find the maximum of the distinct values of expr,\nhowever, this produces the same result as omitting DISTINCT.\n\nMAX() returns NULL if there were no matching rows.\n\nURL: https://mariadb.com/kb/en/max/\n\n','MariaDB> SELECT student_name, MIN(test_score), MAX(test_score)\n -> FROM student\n -> GROUP BY student_name;\n','https://mariadb.com/kb/en/max/'); -insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (97,21,'CREATE FUNCTION UDF','Syntax:\nCREATE [AGGREGATE] FUNCTION function_name RETURNS {STRING|INTEGER|REAL|DECIMAL}\n SONAME shared_library_name\n\nA user-defined function (UDF) is a way to extend MySQL with a new\nfunction that works like a native (built-in) MySQL function such as\nABS() or CONCAT().\n\nfunction_name is the name that should be used in SQL statements to\ninvoke the function. The RETURNS clause indicates the type of the\nfunction\'s return value. DECIMAL is a legal value after RETURNS, but\ncurrently DECIMAL functions return string values and should be written\nlike STRING functions.\n\nshared_library_name is the basename of the shared object file that\ncontains the code that implements the function. The file must be\nlocated in the plugin directory. This directory is given by the value\nof the plugin_dir system variable. For more information, see\nhttp://dev.mysql.com/doc/refman/5.5/en/udf-compiling.html.\n\nTo create a function, you must have the INSERT privilege for the mysql\ndatabase. This is necessary because CREATE FUNCTION adds a row to the\nmysql.func system table that records the function\'s name, type, and\nshared library name. If you do not have this table, you should run the\nmysql_upgrade command to create it. See\nhttps://mariadb.com/kb/en/mysql_upgrade/.\n\nURL: https://mariadb.com/kb/en/create-function-udf/\n\n','','https://mariadb.com/kb/en/create-function-udf/'); -insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (98,4,'*','Syntax:\n*\n\nMultiplication:\n\nURL: https://mariadb.com/kb/en/multiplication-operator/\n\n','MariaDB> SELECT 3*5;\n -> 15\nMariaDB> SELECT 18014398509481984*18014398509481984.0;\n -> 324518553658426726783156020576256.0\nMariaDB> SELECT 18014398509481984*18014398509481984;\n -> 0\n','https://mariadb.com/kb/en/multiplication-operator/'); -insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (99,22,'TIMESTAMP','TIMESTAMP\n\nA timestamp. The range is \'1970-01-01 00:00:01\' UTC to \'2038-01-19\n03:14:07\' UTC. TIMESTAMP values are stored as the number of seconds\nsince the epoch (\'1970-01-01 00:00:00\' UTC). A TIMESTAMP cannot\nrepresent the value \'1970-01-01 00:00:00\' because that is equivalent to\n0 seconds from the epoch and the value 0 is reserved for representing\n\'0000-00-00 00:00:00\', the "zero" TIMESTAMP value.\n\nUnless specified otherwise, the first TIMESTAMP column in a table is\ndefined to be automatically set to the date and time of the most recent\nmodification if not explicitly assigned a value. This makes TIMESTAMP\nuseful for recording the timestamp of an INSERT or UPDATE operation.\nYou can also set any TIMESTAMP column to the current date and time by\nassigning it a NULL value, unless it has been defined with the NULL\nattribute to permit NULL values. The automatic initialization and\nupdating to the current date and time can be specified using DEFAULT\nCURRENT_TIMESTAMP and ON UPDATE CURRENT_TIMESTAMP clauses, as described\nin\nhttps://mariadb.com/kb/en/timestamp/.\n\n*Note*: The TIMESTAMP format that was used prior to MySQL 4.1 is not\nsupported in MySQL 5.5; see MySQL 3.23, 4.0, 4.1 Reference Manual for\ninformation regarding the old format.\n\nURL: https://mariadb.com/kb/en/timestamp/\n\n','','https://mariadb.com/kb/en/timestamp/'); -insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (100,12,'DES_DECRYPT','Syntax:\nDES_DECRYPT(crypt_str[,key_str])\n\nDecrypts a string encrypted with DES_ENCRYPT(). If an error occurs,\nthis function returns NULL.\n\nThis function works only if MySQL has been configured with SSL support.\nSee https://mariadb.com/kb/en/ssl-connections/.\n\nIf no key_str argument is given, DES_DECRYPT() examines the first byte\nof the encrypted string to determine the DES key number that was used\nto encrypt the original string, and then reads the key from the DES key\nfile to decrypt the message. For this to work, the user must have the\nSUPER privilege. The key file can be specified with the --des-key-file\nserver option.\n\nIf you pass this function a key_str argument, that string is used as\nthe key for decrypting the message.\n\nIf the crypt_str argument does not appear to be an encrypted string,\nMySQL returns the given crypt_str.\n\nURL: https://mariadb.com/kb/en/des_decrypt/\n\n','','https://mariadb.com/kb/en/des_decrypt/'); -insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (101,26,'CACHE INDEX','Syntax:\nCACHE INDEX\n tbl_index_list [, tbl_index_list] ...\n [PARTITION (partition_list | ALL)]\n IN key_cache_name\n\ntbl_index_list:\n tbl_name [[INDEX|KEY] (index_name[, index_name] ...)]\n\npartition_list:\n partition_name[, partition_name][, ...]\n\nThe CACHE INDEX statement assigns table indexes to a specific key\ncache. It is used only for MyISAM tables. After the indexes have been\nassigned, they can be preloaded into the cache if desired with LOAD\nINDEX INTO CACHE.\n\nThe following statement assigns indexes from the tables t1, t2, and t3\nto the key cache named hot_cache:\n\nMariaDB> CACHE INDEX t1, t2, t3 IN hot_cache;\n+---------+--------------------+----------+----------+\n| Table | Op | Msg_type | Msg_text |\n+---------+--------------------+----------+----------+\n| test.t1 | assign_to_keycache | status | OK |\n| test.t2 | assign_to_keycache | status | OK |\n| test.t3 | assign_to_keycache | status | OK |\n+---------+--------------------+----------+----------+\n\nURL: https://mariadb.com/kb/en/cache-index/\n\n','','https://mariadb.com/kb/en/cache-index/'); -insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (102,13,'ENDPOINT','EndPoint(ls)\n\nReturns the Point that is the endpoint of the LineString value ls.\n\nURL: https://mariadb.com/kb/en/endpoint/\n\n','MariaDB> SET @ls = \'LineString(1 1,2 2,3 3)\';\nMariaDB> SELECT AsText(EndPoint(GeomFromText(@ls)));\n+-------------------------------------+\n| AsText(EndPoint(GeomFromText(@ls))) |\n+-------------------------------------+\n| POINT(3 3) |\n+-------------------------------------+\n','https://mariadb.com/kb/en/endpoint/'); -insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (103,12,'COMPRESS','Syntax:\nCOMPRESS(string_to_compress)\n\nCompresses a string and returns the result as a binary string. This\nfunction requires MySQL to have been compiled with a compression\nlibrary such as zlib. Otherwise, the return value is always NULL. The\ncompressed string can be uncompressed with UNCOMPRESS().\n\nURL: https://mariadb.com/kb/en/compress/\n\n','MariaDB> SELECT LENGTH(COMPRESS(REPEAT(\'a\',1000)));\n -> 21\nMariaDB> SELECT LENGTH(COMPRESS(\'\'));\n -> 0\nMariaDB> SELECT LENGTH(COMPRESS(\'a\'));\n -> 13\nMariaDB> SELECT LENGTH(COMPRESS(REPEAT(\'a\',16)));\n -> 15\n','https://mariadb.com/kb/en/compress/'); -insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (104,27,'INSERT','Syntax:\nINSERT [LOW_PRIORITY | DELAYED | HIGH_PRIORITY] [IGNORE]\n [INTO] tbl_name [(col_name,...)]\n {VALUES | VALUE} ({expr | DEFAULT},...),(...),...\n [ ON DUPLICATE KEY UPDATE\n col_name=expr\n [, col_name=expr] ... ]\n\nOr:\n\nINSERT [LOW_PRIORITY | DELAYED | HIGH_PRIORITY] [IGNORE]\n [INTO] tbl_name\n SET col_name={expr | DEFAULT}, ...\n [ ON DUPLICATE KEY UPDATE\n col_name=expr\n [, col_name=expr] ... ]\n\nOr:\n\nINSERT [LOW_PRIORITY | HIGH_PRIORITY] [IGNORE]\n [INTO] tbl_name [(col_name,...)]\n SELECT ...\n [ ON DUPLICATE KEY UPDATE\n col_name=expr\n [, col_name=expr] ... ]\n\nINSERT inserts new rows into an existing table. The INSERT ... VALUES\nand INSERT ... SET forms of the statement insert rows based on\nexplicitly specified values. The INSERT ... SELECT form inserts rows\nselected from another table or tables. INSERT ... SELECT is discussed\nfurther in [HELP INSERT SELECT].\n\nURL: https://mariadb.com/kb/en/insert/\n\n','','https://mariadb.com/kb/en/insert/'); -insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (105,16,'COUNT','Syntax:\nCOUNT(expr)\n\nReturns a count of the number of non-NULL values of expr in the rows\nretrieved by a SELECT statement. The result is a BIGINT value.\n\nCOUNT() returns 0 if there were no matching rows.\n\nURL: https://mariadb.com/kb/en/count/\n\n','MariaDB> SELECT student.student_name,COUNT(*)\n -> FROM student,course\n -> WHERE student.student_id=course.student_id\n -> GROUP BY student_name;\n','https://mariadb.com/kb/en/count/'); -insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (106,27,'HANDLER','Syntax:\nHANDLER tbl_name OPEN [ [AS] alias]\n\nHANDLER tbl_name READ index_name { = | <= | >= | < | > } (value1,value2,...)\n [ WHERE where_condition ] [LIMIT ... ]\nHANDLER tbl_name READ index_name { FIRST | NEXT | PREV | LAST }\n [ WHERE where_condition ] [LIMIT ... ]\nHANDLER tbl_name READ { FIRST | NEXT }\n [ WHERE where_condition ] [LIMIT ... ]\n\nHANDLER tbl_name CLOSE\n\nThe HANDLER statement provides direct access to table storage engine\ninterfaces. It is available for MyISAM and InnoDB tables.\n\nURL: https://mariadb.com/kb/en/handler-commands/\n\n','','https://mariadb.com/kb/en/handler-commands/'); -insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (107,3,'MLINEFROMTEXT','MLineFromText(wkt[,srid]), MultiLineStringFromText(wkt[,srid])\n\nConstructs a MULTILINESTRING value using its WKT representation and\nSRID.\n\nURL: https://mariadb.com/kb/en/mlinefromtext/\n\n','','https://mariadb.com/kb/en/mlinefromtext/'); -insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (108,32,'GEOMCOLLFROMWKB','GeomCollFromWKB(wkb[,srid]), GeometryCollectionFromWKB(wkb[,srid])\n\nConstructs a GEOMETRYCOLLECTION value using its WKB representation and\nSRID.\n\nURL: https://mariadb.com/kb/en/geomcollfromwkb/\n\n','','https://mariadb.com/kb/en/geomcollfromwkb/'); -insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (109,9,'HELP_DATE','This help information was generated from the MySQL 5.5 Reference Manual\non: 2012-08-25\n','',''); -insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (110,39,'RENAME TABLE','Syntax:\nRENAME TABLE tbl_name TO new_tbl_name\n [, tbl_name2 TO new_tbl_name2] ...\n\nThis statement renames one or more tables.\n\nThe rename operation is done atomically, which means that no other\nsession can access any of the tables while the rename is running. For\nexample, if you have an existing table old_table, you can create\nanother table new_table that has the same structure but is empty, and\nthen replace the existing table with the empty one as follows (assuming\nthat backup_table does not already exist):\n\nURL: https://mariadb.com/kb/en/rename-table/\n\n','CREATE TABLE new_table (...);\nRENAME TABLE old_table TO backup_table, new_table TO old_table;\n','https://mariadb.com/kb/en/rename-table/'); -insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (111,22,'BOOLEAN','BOOL, BOOLEAN\n\nThese types are synonyms for TINYINT(1). A value of zero is considered\nfalse. Nonzero values are considered true:\n\nMariaDB> SELECT IF(0, \'true\', \'false\');\n+------------------------+\n| IF(0, \'true\', \'false\') |\n+------------------------+\n| false |\n+------------------------+\n\nMariaDB> SELECT IF(1, \'true\', \'false\');\n+------------------------+\n| IF(1, \'true\', \'false\') |\n+------------------------+\n| true |\n+------------------------+\n\nMariaDB> SELECT IF(2, \'true\', \'false\');\n+------------------------+\n| IF(2, \'true\', \'false\') |\n+------------------------+\n| true |\n+------------------------+\n\nHowever, the values TRUE and FALSE are merely aliases for 1 and 0,\nrespectively, as shown here:\n\nMariaDB> SELECT IF(0 = FALSE, \'true\', \'false\');\n+--------------------------------+\n| IF(0 = FALSE, \'true\', \'false\') |\n+--------------------------------+\n| true |\n+--------------------------------+\n\nMariaDB> SELECT IF(1 = TRUE, \'true\', \'false\');\n+-------------------------------+\n| IF(1 = TRUE, \'true\', \'false\') |\n+-------------------------------+\n| true |\n+-------------------------------+\n\nMariaDB> SELECT IF(2 = TRUE, \'true\', \'false\');\n+-------------------------------+\n| IF(2 = TRUE, \'true\', \'false\') |\n+-------------------------------+\n| false |\n+-------------------------------+\n\nMariaDB> SELECT IF(2 = FALSE, \'true\', \'false\');\n+--------------------------------+\n| IF(2 = FALSE, \'true\', \'false\') |\n+--------------------------------+\n| false |\n+--------------------------------+\n\nThe last two statements display the results shown because 2 is equal to\nneither 1 nor 0.\n\nURL: https://mariadb.com/kb/en/boolean/\n\n','','https://mariadb.com/kb/en/boolean/'); -insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (112,14,'DEFAULT','Syntax:\nDEFAULT(col_name)\n\nReturns the default value for a table column. An error results if the\ncolumn has no default value.\n\nURL: https://mariadb.com/kb/en/default/\n\n','MariaDB> UPDATE t SET i = DEFAULT(i)+1 WHERE id < 100;\n','https://mariadb.com/kb/en/default/'); -insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (113,4,'MOD','Syntax:\nMOD(N,M), N % M, N MOD M\n\nModulo operation. Returns the remainder of N divided by M.\n\nURL: https://mariadb.com/kb/en/mod/\n\n','MariaDB> SELECT MOD(234, 10);\n -> 4\nMariaDB> SELECT 253 % 7;\n -> 1\nMariaDB> SELECT MOD(29,9);\n -> 2\nMariaDB> SELECT 29 MOD 9;\n -> 2\n','https://mariadb.com/kb/en/mod/'); -insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (114,22,'TINYTEXT','TINYTEXT [CHARACTER SET charset_name] [COLLATE collation_name]\n\nA TEXT column with a maximum length of 255 (28 - 1) characters. The\neffective maximum length is less if the value contains multi-byte\ncharacters. Each TINYTEXT value is stored using a 1-byte length prefix\nthat indicates the number of bytes in the value.\n\nURL: https://mariadb.com/kb/en/tinytext/\n\n','','https://mariadb.com/kb/en/tinytext/'); -insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (115,20,'OPTIMIZE TABLE','Syntax:\nOPTIMIZE [NO_WRITE_TO_BINLOG | LOCAL] TABLE\n tbl_name [, tbl_name] ...\n\nOPTIMIZE TABLE should be used if you have deleted a large part of a\ntable or if you have made many changes to a table with variable-length\nrows (tables that have VARCHAR, VARBINARY, BLOB, or TEXT columns).\nDeleted rows are maintained in a linked list and subsequent INSERT\noperations reuse old row positions. You can use OPTIMIZE TABLE to\nreclaim the unused space and to defragment the data file. After\nextensive changes to a table, this statement may also improve\nperformance of statements that use the table, sometimes significantly.\n\nThis statement requires SELECT and INSERT privileges for the table.\n\nOPTIMIZE TABLE is supported for partitioned tables, and you can use\nALTER TABLE ... OPTIMIZE PARTITION to optimize one or more partitions;\nfor more information, see [HELP ALTER TABLE], and\nhttp://dev.mysql.com/doc/refman/5.5/en/partitioning-maintenance.html.\n\nURL: https://mariadb.com/kb/en/optimize-table/\n\n','','https://mariadb.com/kb/en/optimize-table/'); -insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (116,12,'DECODE','Syntax:\nDECODE(crypt_str,pass_str)\n\nDecrypts the encrypted string crypt_str using pass_str as the password.\ncrypt_str should be a string returned from ENCODE().\n\nURL: https://mariadb.com/kb/en/decode/\n\n','','https://mariadb.com/kb/en/decode/'); -insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (117,18,'<=>','Syntax:\n<=>\n\nNULL-safe equal. This operator performs an equality comparison like the\n= operator, but returns 1 rather than NULL if both operands are NULL,\nand 0 rather than NULL if one operand is NULL.\n\nURL: https://mariadb.com/kb/en/null-safe-equal/\n\n','MariaDB> SELECT 1 <=> 1, NULL <=> NULL, 1 <=> NULL;\n -> 1, 1, 0\nMariaDB> SELECT 1 = 1, NULL = NULL, 1 = NULL;\n -> 1, NULL, NULL\n','https://mariadb.com/kb/en/null-safe-equal/'); -insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (118,28,'HELP STATEMENT','Syntax:\nHELP \'search_string\'\n\nThe HELP statement returns online information from the MySQL Reference\nmanual. Its proper operation requires that the help tables in the mysql\ndatabase be initialized with help topic information.\n\nThe HELP statement searches the help tables for the given search string\nand displays the result of the search. The search string is not case\nsensitive.\n\nURL: https://mariadb.com/kb/en/help-command/\n\n','','https://mariadb.com/kb/en/help-command/'); -insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (119,26,'RESET','Syntax:\nRESET reset_option [, reset_option] ...\n\nThe RESET statement is used to clear the state of various server\noperations. You must have the RELOAD privilege to execute RESET.\n\nRESET acts as a stronger version of the FLUSH statement. See [HELP\nFLUSH].\n\nThe RESET statement causes an implicit commit. See\nhttps://mariadb.com/kb/en/sql-statements-that-cause-an-implicit-commit/.\n\nURL: https://mariadb.com/kb/en/reset/\n\n','','https://mariadb.com/kb/en/reset/'); -insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (120,14,'GET_LOCK','Syntax:\nGET_LOCK(str,timeout)\n\nTries to obtain a lock with a name given by the string str, using a\ntimeout of timeout seconds. Returns 1 if the lock was obtained\nsuccessfully, 0 if the attempt timed out (for example, because another\nclient has previously locked the name), or NULL if an error occurred\n(such as running out of memory or the thread was killed with mysqladmin\nkill). If you have a lock obtained with GET_LOCK(), it is released when\nyou execute RELEASE_LOCK(), execute a new GET_LOCK(), or your\nconnection terminates (either normally or abnormally). Locks obtained\nwith GET_LOCK() do not interact with transactions. That is, committing\na transaction does not release any such locks obtained during the\ntransaction.\n\nThis function can be used to implement application locks or to simulate\nrecord locks. Names are locked on a server-wide basis. If a name has\nbeen locked by one client, GET_LOCK() blocks any request by another\nclient for a lock with the same name. This enables clients that agree\non a given lock name to use the name to perform cooperative advisory\nlocking. But be aware that it also enables a client that is not among\nthe set of cooperating clients to lock a name, either inadvertently or\ndeliberately, and thus prevent any of the cooperating clients from\nlocking that name. One way to reduce the likelihood of this is to use\nlock names that are database-specific or application-specific. For\nexample, use lock names of the form db_name.str or app_name.str.\n\nURL: https://mariadb.com/kb/en/get_lock/\n\n','MariaDB> SELECT GET_LOCK(\'lock1\',10);\n -> 1\nMariaDB> SELECT IS_FREE_LOCK(\'lock2\');\n -> 1\nMariaDB> SELECT GET_LOCK(\'lock2\',10);\n -> 1\nMariaDB> SELECT RELEASE_LOCK(\'lock2\');\n -> 1\nMariaDB> SELECT RELEASE_LOCK(\'lock1\');\n -> NULL\n','https://mariadb.com/kb/en/get_lock/'); -insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (121,37,'UCASE','Syntax:\nUCASE(str)\n\nUCASE() is a synonym for UPPER().\n\nURL: https://mariadb.com/kb/en/ucase/\n\n','','https://mariadb.com/kb/en/ucase/'); -insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (122,26,'SHOW BINLOG EVENTS','Syntax:\nSHOW BINLOG EVENTS\n [IN \'log_name\'] [FROM pos] [LIMIT [offset,] row_count]\n\nShows the events in the binary log. If you do not specify \'log_name\',\nthe first binary log is displayed.\n\nURL: https://mariadb.com/kb/en/show-binlog-events/\n\n','','https://mariadb.com/kb/en/show-binlog-events/'); -insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (123,32,'MPOLYFROMWKB','MPolyFromWKB(wkb[,srid]), MultiPolygonFromWKB(wkb[,srid])\n\nConstructs a MULTIPOLYGON value using its WKB representation and SRID.\n\nURL: https://mariadb.com/kb/en/mpolyfromwkb/\n\n','','https://mariadb.com/kb/en/mpolyfromwkb/'); -insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (124,23,'ITERATE','Syntax:\nITERATE label\n\nITERATE can appear only within LOOP, REPEAT, and WHILE statements.\nITERATE means "start the loop again."\n\nURL: https://mariadb.com/kb/en/iterate/\n\n','','https://mariadb.com/kb/en/iterate/'); -insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (125,27,'DO','Syntax:\nDO expr [, expr] ...\n\nDO executes the expressions but does not return any results. In most\nrespects, DO is shorthand for SELECT expr, ..., but has the advantage\nthat it is slightly faster when you do not care about the result.\n\nDO is useful primarily with functions that have side effects, such as\nRELEASE_LOCK().\n\nURL: https://mariadb.com/kb/en/do/\n\n','','https://mariadb.com/kb/en/do/'); -insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (126,31,'CURTIME','Syntax:\nCURTIME()\n\nReturns the current time as a value in \'HH:MM:SS\' or HHMMSS.uuuuuu\nformat, depending on whether the function is used in a string or\nnumeric context. The value is expressed in the current time zone.\n\nURL: https://mariadb.com/kb/en/curtime/\n\n','MariaDB> SELECT CURTIME();\n -> \'23:50:26\'\nMariaDB> SELECT CURTIME() + 0;\n -> 235026.000000\n','https://mariadb.com/kb/en/curtime/'); -insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (127,37,'CHAR_LENGTH','Syntax:\nCHAR_LENGTH(str)\n\nReturns the length of the string str, measured in characters. A\nmulti-byte character counts as a single character. This means that for\na string containing five 2-byte characters, LENGTH() returns 10,\nwhereas CHAR_LENGTH() returns 5.\n\nURL: https://mariadb.com/kb/en/char_length/\n\n','','https://mariadb.com/kb/en/char_length/'); -insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (128,22,'BIGINT','BIGINT[(M)] [UNSIGNED] [ZEROFILL]\n\nA large integer. The signed range is -9223372036854775808 to\n9223372036854775807. The unsigned range is 0 to 18446744073709551615.\n\nSERIAL is an alias for BIGINT UNSIGNED NOT NULL AUTO_INCREMENT UNIQUE.\n\nURL: https://mariadb.com/kb/en/bigint/\n\n','','https://mariadb.com/kb/en/bigint/'); -insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (129,26,'SET','Syntax:\nSET variable_assignment [, variable_assignment] ...\n\nvariable_assignment:\n user_var_name = expr\n | [GLOBAL | SESSION] system_var_name = expr\n | [@@global. | @@session. | @@]system_var_name = expr\n\nThe SET statement assigns values to different types of variables that\naffect the operation of the server or your client. Older versions of\nMySQL employed SET OPTION, but this syntax is deprecated in favor of\nSET without OPTION.\n\nURL: https://mariadb.com/kb/en/set/\n\n','','https://mariadb.com/kb/en/set/'); -insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (130,27,'LOAD XML','Syntax:\nLOAD XML [LOW_PRIORITY | CONCURRENT] [LOCAL] INFILE \'file_name\'\n [REPLACE | IGNORE]\n INTO TABLE [db_name.]tbl_name\n [CHARACTER SET charset_name]\n [ROWS IDENTIFIED BY \'\']\n [IGNORE number {LINES | ROWS}]\n [(column_or_user_var,...)]\n [SET col_name = expr,...]\n\nThe LOAD XML statement reads data from an XML file into a table. The\nfile_name must be given as a literal string. The tagname in the\noptional ROWS IDENTIFIED BY clause must also be given as a literal\nstring, and must be surrounded by angle brackets (< and >).\n\nLOAD XML acts as the complement of running the mysql client in XML\noutput mode (that is, starting the client with the --xml option). To\nwrite data from a table to an XML file, use a command such as the\nfollowing one from the system shell:\n\nshell> mysql --xml -e \'SELECT * FROM mytable\' > file.xml\n\nTo read the file back into a table, use LOAD XML INFILE. By default,\nthe element is considered to be the equivalent of a database\ntable row; this can be changed using the ROWS IDENTIFIED BY clause.\n\nThis statement supports three different XML formats:\n\no Column names as attributes and column values as attribute values:\n\n\n\no Column names as tags and column values as the content of these tags:\n\n\n value1\n value2\n\n\no Column names are the name attributes of tags, and values are\n the contents of these tags:\n\n\n value1\n value2\n\n\n This is the format used by other MySQL tools, such as mysqldump.\n\nAll 3 formats can be used in the same XML file; the import routine\nautomatically detects the format for each row and interprets it\ncorrectly. Tags are matched based on the tag or attribute name and the\ncolumn name.\n\nThe following clauses work essentially the same way for LOAD XML as\nthey do for LOAD DATA:\n\no LOW_PRIORITY or CONCURRENT\n\no LOCAL\n\no REPLACE or IGNORE\n\no CHARACTER SET\n\no (column_or_user_var,...)\n\no SET\n\nSee [HELP LOAD DATA], for more information about these clauses.\n\nThe IGNORE number LINES or IGNORE number ROWS clause causes the first\nnumber rows in the XML file to be skipped. It is analogous to the LOAD\nDATA statement\'s IGNORE ... LINES clause.\n\nURL: https://mariadb.com/kb/en/load-xml/\n\n','','https://mariadb.com/kb/en/load-xml/'); -insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (131,4,'CONV','Syntax:\nCONV(N,from_base,to_base)\n\nConverts numbers between different number bases. Returns a string\nrepresentation of the number N, converted from base from_base to base\nto_base. Returns NULL if any argument is NULL. The argument N is\ninterpreted as an integer, but may be specified as an integer or a\nstring. The minimum base is 2 and the maximum base is 36. If to_base is\na negative number, N is regarded as a signed number. Otherwise, N is\ntreated as unsigned. CONV() works with 64-bit precision.\n\nURL: https://mariadb.com/kb/en/conv/\n\n','MariaDB> SELECT CONV(\'a\',16,2);\n -> \'1010\'\nMariaDB> SELECT CONV(\'6E\',18,8);\n -> \'172\'\nMariaDB> SELECT CONV(-17,10,-18);\n -> \'-H\'\nMariaDB> SELECT CONV(10+\'10\'+\'10\'+0xa,10,10);\n -> \'40\'\n','https://mariadb.com/kb/en/conv/'); -insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (132,22,'DATE','DATE\n\nA date. The supported range is \'1000-01-01\' to \'9999-12-31\'. MySQL\ndisplays DATE values in \'YYYY-MM-DD\' format, but permits assignment of\nvalues to DATE columns using either strings or numbers.\n\nURL: https://mariadb.com/kb/en/date/\n\n','','https://mariadb.com/kb/en/date/'); -insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (133,15,'ASSIGN-VALUE','Syntax:\n:=\n\nAssignment operator. Causes the user variable on the left hand side of\nthe operator to take on the value to its right. The value on the right\nhand side may be a literal value, another variable storing a value, or\nany legal expression that yields a scalar value, including the result\nof a query (provided that this value is a scalar value). You can\nperform multiple assignments in the same SET statement. You can perform\nmultiple assignments in the same statement-\n\nUnlike =, the := operator is never interpreted as a comparison\noperator. This means you can use := in any valid SQL statement (not\njust in SET statements) to assign a value to a variable.\n\nURL: https://mariadb.com/kb/en/assignment-operator/\n\n','MariaDB> SELECT @var1, @var2;\n -> NULL, NULL\nMariaDB> SELECT @var1 := 1, @var2;\n -> 1, NULL\nMariaDB> SELECT @var1, @var2;\n -> 1, NULL\nMariaDB> SELECT @var1, @var2 := @var1;\n -> 1, 1\nMariaDB> SELECT @var1, @var2;\n -> 1, 1\n\nMariaDB> SELECT @var1:=COUNT(*) FROM t1;\n -> 4\nMariaDB> SELECT @var1;\n -> 4\n','https://mariadb.com/kb/en/assignment-operator/'); -insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (134,26,'SHOW OPEN TABLES','Syntax:\nSHOW OPEN TABLES [{FROM | IN} db_name]\n [LIKE \'pattern\' | WHERE expr]\n\nSHOW OPEN TABLES lists the non-TEMPORARY tables that are currently open\nin the table cache. See\nhttp://dev.mysql.com/doc/refman/5.5/en/table-cache.html. The FROM\nclause, if present, restricts the tables shown to those present in the\ndb_name database. The LIKE clause, if present, indicates which table\nnames to match. The WHERE clause can be given to select rows using more\ngeneral conditions, as discussed in\nhttps://mariadb.com/kb/en/extended-show/.\n\nURL: https://mariadb.com/kb/en/show-open-tables/\n\n','','https://mariadb.com/kb/en/show-open-tables/'); -insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (135,31,'EXTRACT','Syntax:\nEXTRACT(unit FROM date)\n\nThe EXTRACT() function uses the same kinds of unit specifiers as\nDATE_ADD() or DATE_SUB(), but extracts parts from the date rather than\nperforming date arithmetic.\n\nURL: https://mariadb.com/kb/en/extract/\n\n','MariaDB> SELECT EXTRACT(YEAR FROM \'2009-07-02\');\n -> 2009\nMariaDB> SELECT EXTRACT(YEAR_MONTH FROM \'2009-07-02 01:02:03\');\n -> 200907\nMariaDB> SELECT EXTRACT(DAY_MINUTE FROM \'2009-07-02 01:02:03\');\n -> 20102\nMariaDB> SELECT EXTRACT(MICROSECOND\n -> FROM \'2003-01-02 10:30:00.000123\');\n -> 123\n','https://mariadb.com/kb/en/extract/'); -insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (136,12,'ENCRYPT','Syntax:\nENCRYPT(str[,salt])\n\nEncrypts str using the Unix crypt() system call and returns a binary\nstring. The salt argument must be a string with at least two characters\nor the result will be NULL. If no salt argument is given, a random\nvalue is used.\n\nURL: https://mariadb.com/kb/en/encrypt/\n\n','MariaDB> SELECT ENCRYPT(\'hello\');\n -> \'VxuFAJXVARROc\'\n','https://mariadb.com/kb/en/encrypt/'); -insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (137,26,'SHOW STATUS','Syntax:\nSHOW [GLOBAL | SESSION] STATUS\n [LIKE \'pattern\' | WHERE expr]\n\nSHOW STATUS provides server status information. This information also\ncan be obtained using the mysqladmin extended-status command. The LIKE\nclause, if present, indicates which variable names to match. The WHERE\nclause can be given to select rows using more general conditions, as\ndiscussed in https://mariadb.com/kb/en/extended-show/.\nThis statement does not require any privilege. It requires only the\nability to connect to the server.\nWith a LIKE clause, the statement displays only rows for those\nvariables with names that match the pattern:\n\nMariaDB> SHOW STATUS LIKE \'Key%\';\n+--------------------+----------+\n| Variable_name | Value |\n+--------------------+----------+\n| Key_blocks_used | 14955 |\n| Key_read_requests | 96854827 |\n| Key_reads | 162040 |\n| Key_write_requests | 7589728 |\n| Key_writes | 3813196 |\n+--------------------+----------+\n\nWith the GLOBAL modifier, SHOW STATUS displays the status values for\nall connections to MySQL. With SESSION, it displays the status values\nfor the current connection. If no modifier is present, the default is\nSESSION. LOCAL is a synonym for SESSION.\n\nSome status variables have only a global value. For these, you get the\nsame value for both GLOBAL and SESSION. The scope for each status\nvariable is listed at\nhttps://mariadb.com/kb/en/server-status-variables/.\n\nEach invocation of the SHOW STATUS statement uses an internal temporary\ntable and increments the global Created_tmp_tables value.\n\nURL: https://mariadb.com/kb/en/show-status/\n\n','','https://mariadb.com/kb/en/show-status/'); -insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (138,37,'EXTRACTVALUE','Syntax:\nExtractValue(xml_frag, xpath_expr)\n\nExtractValue() takes two string arguments, a fragment of XML markup\nxml_frag and an XPath expression xpath_expr (also known as a locator);\nit returns the text (CDATA) of the first text node which is a child of\nthe elements or elements matched by the XPath expression. In MySQL 5.5,\nthe XPath expression can contain at most 127 characters. (This\nlimitation is lifted in MySQL 5.6.)\n\nUsing this function is the equivalent of performing a match using the\nxpath_expr after appending /text(). In other words,\nExtractValue(\'Sakila\', \'/a/b\') and\nExtractValue(\'Sakila\', \'/a/b/text()\') produce the same\nresult.\n\nIf multiple matches are found, the content of the first child text node\nof each matching element is returned (in the order matched) as a\nsingle, space-delimited string.\n\nIf no matching text node is found for the expression (including the\nimplicit /text())---for whatever reason, as long as xpath_expr is\nvalid, and xml_frag consists of elements which are properly nested and\nclosed---an empty string is returned. No distinction is made between a\nmatch on an empty element and no match at all. This is by design.\n\nIf you need to determine whether no matching element was found in\nxml_frag or such an element was found but contained no child text\nnodes, you should test the result of an expression that uses the XPath\ncount() function. For example, both of these statements return an empty\nstring, as shown here:\n\nMariaDB> SELECT ExtractValue(\'\', \'/a/b\');\n+-------------------------------------+\n| ExtractValue(\'\', \'/a/b\') |\n+-------------------------------------+\n| |\n+-------------------------------------+\n1 row in set (0.00 sec)\n\nMariaDB> SELECT ExtractValue(\'\', \'/a/b\');\n+-------------------------------------+\n| ExtractValue(\'\', \'/a/b\') |\n+-------------------------------------+\n| |\n+-------------------------------------+\n1 row in set (0.00 sec)\n\nHowever, you can determine whether there was actually a matching\nelement using the following:\n\nMariaDB> SELECT ExtractValue(\'\', \'count(/a/b)\');\n+-------------------------------------+\n| ExtractValue(\'\', \'count(/a/b)\') |\n+-------------------------------------+\n| 1 |\n+-------------------------------------+\n1 row in set (0.00 sec)\n\nMariaDB> SELECT ExtractValue(\'\', \'count(/a/b)\');\n+-------------------------------------+\n| ExtractValue(\'\', \'count(/a/b)\') |\n+-------------------------------------+\n| 0 |\n+-------------------------------------+\n1 row in set (0.01 sec)\n\n*Important*: ExtractValue() returns only CDATA, and does not return any\ntags that might be contained within a matching tag, nor any of their\ncontent (see the result returned as val1 in the following example).\n\nURL: https://mariadb.com/kb/en/extractvalue/\n\n','MariaDB> SELECT\n -> ExtractValue(\'cccddd\', \'/a\') AS val1,\n -> ExtractValue(\'cccddd\', \'/a/b\') AS val2,\n -> ExtractValue(\'cccddd\', \'//b\') AS val3,\n -> ExtractValue(\'cccddd\', \'/b\') AS val4,\n -> ExtractValue(\'cccdddeee\', \'//b\') AS val5;\n\n+------+------+------+------+---------+\n| val1 | val2 | val3 | val4 | val5 |\n+------+------+------+------+---------+\n| ccc | ddd | ddd | | ddd eee |\n+------+------+------+------+---------+\n','https://mariadb.com/kb/en/extractvalue/'); -insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (139,12,'OLD_PASSWORD','Syntax:\nOLD_PASSWORD(str)\n\nOLD_PASSWORD() was added when the implementation of PASSWORD() was\nchanged in MySQL 4.1 to improve security. OLD_PASSWORD() returns the\nvalue of the pre-4.1 implementation of PASSWORD() as a string, and is\nintended to permit you to reset passwords for any pre-4.1 clients that\nneed to connect to your version 5.5 MySQL server without locking them\nout. See http://dev.mysql.com/doc/refman/5.1/en/password-hashing.html.\n\nAs of MySQL 5.5.3, the return value is a nonbinary string in the\nconnection character set. Before 5.5.3, the return value is a binary\nstring.\n\nURL: https://mariadb.com/kb/en/old_password/\n\n','','https://mariadb.com/kb/en/old_password/'); -insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (140,37,'FORMAT','Syntax:\nFORMAT(X,D[,locale])\n\nFormats the number X to a format like \'#,###,###.##\', rounded to D\ndecimal places, and returns the result as a string. If D is 0, the\nresult has no decimal point or fractional part.\n\nThe optional third parameter enables a locale to be specified to be\nused for the result number\'s decimal point, thousands separator, and\ngrouping between separators. Permissible locale values are the same as\nthe legal values for the lc_time_names system variable (see\nhttps://mariadb.com/kb/en/server-locale/). If no\nlocale is specified, the default is \'en_US\'.\n\nURL: https://mariadb.com/kb/en/format/\n\n','MariaDB> SELECT FORMAT(12332.123456, 4);\n -> \'12,332.1235\'\nMariaDB> SELECT FORMAT(12332.1,4);\n -> \'12,332.1000\'\nMariaDB> SELECT FORMAT(12332.2,0);\n -> \'12,332\'\nMariaDB> SELECT FORMAT(12332.2,2,\'de_DE\');\n -> \'12.332,20\'\n','https://mariadb.com/kb/en/format/'); -insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (141,15,'||','Syntax:\nOR, ||\n\nLogical OR. When both operands are non-NULL, the result is 1 if any\noperand is nonzero, and 0 otherwise. With a NULL operand, the result is\n1 if the other operand is nonzero, and NULL otherwise. If both operands\nare NULL, the result is NULL.\n\nURL: https://mariadb.com/kb/en/or/\n\n','MariaDB> SELECT 1 || 1;\n -> 1\nMariaDB> SELECT 1 || 0;\n -> 1\nMariaDB> SELECT 0 || 0;\n -> 0\nMariaDB> SELECT 0 || NULL;\n -> NULL\nMariaDB> SELECT 1 || NULL;\n -> 1\n','https://mariadb.com/kb/en/or/'); -insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (142,37,'BIT_LENGTH','Syntax:\nBIT_LENGTH(str)\n\nReturns the length of the string str in bits.\n\nURL: https://mariadb.com/kb/en/bit_length/\n\n','MariaDB> SELECT BIT_LENGTH(\'text\');\n -> 32\n','https://mariadb.com/kb/en/bit_length/'); -insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (143,2,'EXTERIORRING','ExteriorRing(poly)\n\nReturns the exterior ring of the Polygon value poly as a LineString.\n\nURL: https://mariadb.com/kb/en/exteriorring/\n\n','MariaDB> SET @poly =\n -> \'Polygon((0 0,0 3,3 3,3 0,0 0),(1 1,1 2,2 2,2 1,1 1))\';\nMariaDB> SELECT AsText(ExteriorRing(GeomFromText(@poly)));\n+-------------------------------------------+\n| AsText(ExteriorRing(GeomFromText(@poly))) |\n+-------------------------------------------+\n| LINESTRING(0 0,0 3,3 3,3 0,0 0) |\n+-------------------------------------------+\n','https://mariadb.com/kb/en/exteriorring/'); -insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (144,32,'GEOMFROMWKB','GeomFromWKB(wkb[,srid]), GeometryFromWKB(wkb[,srid])\n\nConstructs a geometry value of any type using its WKB representation\nand SRID.\n\nURL: https://mariadb.com/kb/en/geomfromwkb/\n\n','','https://mariadb.com/kb/en/geomfromwkb/'); -insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (145,26,'SHOW SLAVE HOSTS','Syntax:\nSHOW SLAVE HOSTS\n\nDisplays a list of replication slaves currently registered with the\nmaster. (Before MySQL 5.5.3, only slaves started with the\n--report-host=host_name option are visible in this list.)\n\nThe list is displayed on any server (not just the master server). The\noutput looks like this:\n\nMariaDB> SHOW SLAVE HOSTS;\n+------------+-----------+------+-----------+\n| Server_id | Host | Port | Master_id |\n+------------+-----------+------+-----------+\n| 192168010 | iconnect2 | 3306 | 192168011 |\n| 1921680101 | athena | 3306 | 192168011 |\n+------------+-----------+------+-----------+\n\no Server_id: The unique server ID of the slave server, as configured in\n the server\'s option file, or on the command line with\n --server-id=value.\n\no Host: The host name of the slave server, as configured in the\n server\'s option file, or on the command line with\n --report-host=host_name. Note that this can differ from the machine\n name as configured in the operating system.\n\no Port: The port the slave server is listening on.\n\n In MySQL 5.5.23 and later, a zero in this column means that the slave\n port (--report-port) was not set. Prior to MySQL 5.5.23, 3306 was\n used as the default in such cases (Bug #13333431).\n\no Master_id: The unique server ID of the master server that the slave\n server is replicating from.\n\nSome MySQL versions report another variable, Rpl_recovery_rank. This\nvariable was never used, and was removed in MySQL 5.5.3. (Bug #13963)\n\nURL: https://mariadb.com/kb/en/show-slave-hosts/\n\n','','https://mariadb.com/kb/en/show-slave-hosts/'); -insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (146,8,'START TRANSACTION','Syntax:\nSTART TRANSACTION [WITH CONSISTENT SNAPSHOT]\nBEGIN [WORK]\nCOMMIT [WORK] [AND [NO] CHAIN] [[NO] RELEASE]\nROLLBACK [WORK] [AND [NO] CHAIN] [[NO] RELEASE]\nSET autocommit = {0 | 1}\n\nThese statements provide control over use of transactions:\n\no START TRANSACTION or BEGIN start a new transaction.\n\no COMMIT commits the current transaction, making its changes permanent.\n\no ROLLBACK rolls back the current transaction, canceling its changes.\n\no SET autocommit disables or enables the default autocommit mode for\n the current session.\n\nBy default, MySQL runs with autocommit mode enabled. This means that as\nsoon as you execute a statement that updates (modifies) a table, MySQL\nstores the update on disk to make it permanent. The change cannot be\nrolled back.\n\nTo disable autocommit mode implicitly for a single series of\nstatements, use the START TRANSACTION statement:\n\nSTART TRANSACTION;\nSELECT @A:=SUM(salary) FROM table1 WHERE type=1;\nUPDATE table2 SET summary=@A WHERE type=1;\nCOMMIT;\n\nWith START TRANSACTION, autocommit remains disabled until you end the\ntransaction with COMMIT or ROLLBACK. The autocommit mode then reverts\nto its previous state.\n\nYou can also begin a transaction like this:\n\nSTART TRANSACTION WITH CONSISTENT SNAPSHOT;\n\nThe WITH CONSISTENT SNAPSHOT option starts a consistent read for\nstorage engines that are capable of it. This applies only to InnoDB.\nThe effect is the same as issuing a START TRANSACTION followed by a\nSELECT from any InnoDB table. See\nhttp://dev.mysql.com/doc/refman/5.5/en/innodb-consistent-read.html. The\nWITH CONSISTENT SNAPSHOT option does not change the current transaction\nisolation level, so it provides a consistent snapshot only if the\ncurrent isolation level is one that permits consistent read (REPEATABLE\nREAD or SERIALIZABLE).\n\n*Important*: Many APIs used for writing MySQL client applications (such\nas JDBC) provide their own methods for starting transactions that can\n(and sometimes should) be used instead of sending a START TRANSACTION\nstatement from the client. See\nhttp://dev.mysql.com/doc/refman/5.5/en/connectors-apis.html, or the\ndocumentation for your API, for more information.\n\nTo disable autocommit mode explicitly, use the following statement:\n\nSET autocommit=0;\n\nAfter disabling autocommit mode by setting the autocommit variable to\nzero, changes to transaction-safe tables (such as those for InnoDB) are not made permanent immediately. You must use COMMIT to\nstore your changes to disk or ROLLBACK to ignore the changes.\n\nautocommit is a session variable and must be set for each session. To\ndisable autocommit mode for each new connection, see the description of\nthe autocommit system variable at\nhttps://mariadb.com/kb/en/server-system-variables/.\n\nBEGIN and BEGIN WORK are supported as aliases of START TRANSACTION for\ninitiating a transaction. START TRANSACTION is standard SQL syntax and\nis the recommended way to start an ad-hoc transaction.\n\nThe BEGIN statement differs from the use of the BEGIN keyword that\nstarts a BEGIN ... END compound statement. The latter does not begin a\ntransaction. See [HELP BEGIN END].\n\n*Note*: Within all stored programs (stored procedures and functions,\ntriggers, and events), the parser treats BEGIN [WORK] as the beginning\nof a BEGIN ... END block. Begin a transaction in this context with\nSTART TRANSACTION instead.\n\nThe optional WORK keyword is supported for COMMIT and ROLLBACK, as are\nthe CHAIN and RELEASE clauses. CHAIN and RELEASE can be used for\nadditional control over transaction completion. The value of the\ncompletion_type system variable determines the default completion\nbehavior. See\nhttps://mariadb.com/kb/en/server-system-variables/.\n\nThe AND CHAIN clause causes a new transaction to begin as soon as the\ncurrent one ends, and the new transaction has the same isolation level\nas the just-terminated transaction. The RELEASE clause causes the\nserver to disconnect the current client session after terminating the\ncurrent transaction. Including the NO keyword suppresses CHAIN or\nRELEASE completion, which can be useful if the completion_type system\nvariable is set to cause chaining or release completion by default.\n\nURL: https://mariadb.com/kb/en/start-transaction/\n\n','','https://mariadb.com/kb/en/start-transaction/'); -insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (147,18,'BETWEEN AND','Syntax:\nexpr BETWEEN min AND max\n\nIf expr is greater than or equal to min and expr is less than or equal\nto max, BETWEEN returns 1, otherwise it returns 0. This is equivalent\nto the expression (min <= expr AND expr <= max) if all the arguments\nare of the same type. Otherwise type conversion takes place according\nto the rules described in\nhttps://mariadb.com/kb/en/type-conversion/, but\napplied to all the three arguments.\n\nURL: https://mariadb.com/kb/en/between-and/\n\n','MariaDB> SELECT 2 BETWEEN 1 AND 3, 2 BETWEEN 3 and 1;\n -> 1, 0\nMariaDB> SELECT 1 BETWEEN 2 AND 3;\n -> 0\nMariaDB> SELECT \'b\' BETWEEN \'a\' AND \'c\';\n -> 1\nMariaDB> SELECT 2 BETWEEN 2 AND \'3\';\n -> 1\nMariaDB> SELECT 2 BETWEEN 2 AND \'x-3\';\n -> 0\n','https://mariadb.com/kb/en/between-and/'); -insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (148,24,'MULTIPOLYGON','MultiPolygon(poly1,poly2,...)\n\nConstructs a MultiPolygon value from a set of Polygon or WKB Polygon\narguments.\n\nURL: https://mariadb.com/kb/en/multipolygon/\n\n','','https://mariadb.com/kb/en/multipolygon/'); -insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (149,31,'TIME_FORMAT','Syntax:\nTIME_FORMAT(time,format)\n\nThis is used like the DATE_FORMAT() function, but the format string may\ncontain format specifiers only for hours, minutes, seconds, and\nmicroseconds. Other specifiers produce a NULL value or 0.\n\nURL: https://mariadb.com/kb/en/time_format/\n\n','MariaDB> SELECT TIME_FORMAT(\'100:00:00\', \'%H %k %h %I %l\');\n -> \'100 100 04 04 4\'\n','https://mariadb.com/kb/en/time_format/'); -insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (150,37,'LEFT','Syntax:\nLEFT(str,len)\n\nReturns the leftmost len characters from the string str, or NULL if any\nargument is NULL.\n\nURL: https://mariadb.com/kb/en/left/\n\n','MariaDB> SELECT LEFT(\'foobarbar\', 5);\n -> \'fooba\'\n','https://mariadb.com/kb/en/left/'); -insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (151,26,'FLUSH QUERY CACHE','You can defragment the query cache to better utilize its memory with\nthe FLUSH QUERY CACHE statement. The statement does not remove any\nqueries from the cache.\n\nThe RESET QUERY CACHE statement removes all query results from the\nquery cache. The FLUSH TABLES statement also does this.\n\nURL: https://mariadb.com/kb/en/flush-query-cache/\n\n','','https://mariadb.com/kb/en/flush-query-cache/'); -insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (152,22,'SET DATA TYPE','SET(\'value1\',\'value2\',...) [CHARACTER SET charset_name] [COLLATE\ncollation_name]\n\nA set. A string object that can have zero or more values, each of which\nmust be chosen from the list of values \'value1\', \'value2\', ... A SET\ncolumn can have a maximum of 64 members. SET values are represented\ninternally as integers.\n\nURL: https://mariadb.com/kb/en/set-data-type/\n\n','','https://mariadb.com/kb/en/set-data-type/'); -insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (153,4,'RAND','Syntax:\nRAND(), RAND(N)\n\nReturns a random floating-point value v in the range 0 <= v < 1.0. If a\nconstant integer argument N is specified, it is used as the seed value,\nwhich produces a repeatable sequence of column values. In the following\nexample, note that the sequences of values produced by RAND(3) is the\nsame both places where it occurs.\n\nURL: https://mariadb.com/kb/en/rand/\n\n','MariaDB> CREATE TABLE t (i INT);\nQuery OK, 0 rows affected (0.42 sec)\n\nMariaDB> INSERT INTO t VALUES(1),(2),(3);\nQuery OK, 3 rows affected (0.00 sec)\nRecords: 3 Duplicates: 0 Warnings: 0\n\nMariaDB> SELECT i, RAND() FROM t;\n+------+------------------+\n| i | RAND() |\n+------+------------------+\n| 1 | 0.61914388706828 |\n| 2 | 0.93845168309142 |\n| 3 | 0.83482678498591 |\n+------+------------------+\n3 rows in set (0.00 sec)\n\nMariaDB> SELECT i, RAND(3) FROM t;\n+------+------------------+\n| i | RAND(3) |\n+------+------------------+\n| 1 | 0.90576975597606 |\n| 2 | 0.37307905813035 |\n| 3 | 0.14808605345719 |\n+------+------------------+\n3 rows in set (0.00 sec)\n\nMariaDB> SELECT i, RAND() FROM t;\n+------+------------------+\n| i | RAND() |\n+------+------------------+\n| 1 | 0.35877890638893 |\n| 2 | 0.28941420772058 |\n| 3 | 0.37073435016976 |\n+------+------------------+\n3 rows in set (0.00 sec)\n\nMariaDB> SELECT i, RAND(3) FROM t;\n+------+------------------+\n| i | RAND(3) |\n+------+------------------+\n| 1 | 0.90576975597606 |\n| 2 | 0.37307905813035 |\n| 3 | 0.14808605345719 |\n+------+------------------+\n3 rows in set (0.01 sec)\n','https://mariadb.com/kb/en/rand/'); -insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (154,37,'RPAD','Syntax:\nRPAD(str,len,padstr)\n\nReturns the string str, right-padded with the string padstr to a length\nof len characters. If str is longer than len, the return value is\nshortened to len characters.\n\nURL: https://mariadb.com/kb/en/rpad/\n\n','MariaDB> SELECT RPAD(\'hi\',5,\'?\');\n -> \'hi???\'\nMariaDB> SELECT RPAD(\'hi\',1,\'?\');\n -> \'h\'\n','https://mariadb.com/kb/en/rpad/'); -insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (155,39,'CREATE DATABASE','Syntax:\nCREATE {DATABASE | SCHEMA} [IF NOT EXISTS] db_name\n [create_specification] ...\n\ncreate_specification:\n [DEFAULT] CHARACTER SET [=] charset_name\n | [DEFAULT] COLLATE [=] collation_name\n\nCREATE DATABASE creates a database with the given name. To use this\nstatement, you need the CREATE privilege for the database. CREATE\nSCHEMA is a synonym for CREATE DATABASE.\n\nURL: https://mariadb.com/kb/en/create-database/\n\n','','https://mariadb.com/kb/en/create-database/'); -insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (156,22,'DEC','DEC[(M[,D])] [UNSIGNED] [ZEROFILL], NUMERIC[(M[,D])] [UNSIGNED]\n[ZEROFILL], FIXED[(M[,D])] [UNSIGNED] [ZEROFILL]\n\nThese types are synonyms for DECIMAL. The FIXED synonym is available\nfor compatibility with other database systems.\n\nURL: https://mariadb.com/kb/en/dec-numeric-fixed/\n\n','','https://mariadb.com/kb/en/dec-numeric-fixed/'); -insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (157,16,'VAR_POP','Syntax:\nVAR_POP(expr)\n\nReturns the population standard variance of expr. It considers rows as\nthe whole population, not as a sample, so it has the number of rows as\nthe denominator. You can also use VARIANCE(), which is equivalent but\nis not standard SQL.\n\nVAR_POP() returns NULL if there were no matching rows.\n\nURL: https://mariadb.com/kb/en/var_pop/\n\n','','https://mariadb.com/kb/en/var_pop/'); -insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (158,37,'ELT','Syntax:\nELT(N,str1,str2,str3,...)\n\nReturns str1 if N = 1, str2 if N = 2, and so on. Returns NULL if N is\nless than 1 or greater than the number of arguments. ELT() is the\ncomplement of FIELD().\n\nURL: https://mariadb.com/kb/en/elt/.html\n\n','MariaDB> SELECT ELT(1, \'ej\', \'Heja\', \'hej\', \'foo\');\n -> \'ej\'\nMariaDB> SELECT ELT(4, \'ej\', \'Heja\', \'hej\', \'foo\');\n -> \'foo\'\n','https://mariadb.com/kb/en/elt/.html'); -insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (159,39,'ALTER VIEW','Syntax:\nALTER\n [ALGORITHM = {UNDEFINED | MERGE | TEMPTABLE}]\n [DEFINER = { user | CURRENT_USER }]\n [SQL SECURITY { DEFINER | INVOKER }]\n VIEW view_name [(column_list)]\n AS select_statement\n [WITH [CASCADED | LOCAL] CHECK OPTION]\n\nThis statement changes the definition of a view, which must exist. The\nsyntax is similar to that for CREATE VIEW and the effect is the same as\nfor CREATE OR REPLACE VIEW. See [HELP CREATE VIEW]. This statement\nrequires the CREATE VIEW and DROP privileges for the view, and some\nprivilege for each column referred to in the SELECT statement. ALTER\nVIEW is permitted only to the definer or users with the SUPER\nprivilege.\n\nURL: https://mariadb.com/kb/en/alter-view/\n\n','','https://mariadb.com/kb/en/alter-view/'); -insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (160,26,'SHOW DATABASES','Syntax:\nSHOW {DATABASES | SCHEMAS}\n [LIKE \'pattern\' | WHERE expr]\n\nSHOW DATABASES lists the databases on the MySQL server host. SHOW\nSCHEMAS is a synonym for SHOW DATABASES. The LIKE clause, if present,\nindicates which database names to match. The WHERE clause can be given\nto select rows using more general conditions, as discussed in\nhttps://mariadb.com/kb/en/extended-show/.\n\nYou see only those databases for which you have some kind of privilege,\nunless you have the global SHOW DATABASES privilege. You can also get\nthis list using the mysqlshow command.\n\nIf the server was started with the --skip-show-database option, you\ncannot use this statement at all unless you have the SHOW DATABASES\nprivilege.\n\nURL: https://mariadb.com/kb/en/show-databases/\n\n','','https://mariadb.com/kb/en/show-databases/'); -insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (161,19,'~','Syntax:\n~\n\nInvert all bits.\n\nURL: https://mariadb.com/kb/en/3489/\n\n','MariaDB> SELECT 5 & ~1;\n -> 4\n','https://mariadb.com/kb/en/3489/'); -insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (162,22,'TEXT','TEXT[(M)] [CHARACTER SET charset_name] [COLLATE collation_name]\n\nA TEXT column with a maximum length of 65,535 (216 - 1) characters. The\neffective maximum length is less if the value contains multi-byte\ncharacters. Each TEXT value is stored using a 2-byte length prefix that\nindicates the number of bytes in the value.\n\nAn optional length M can be given for this type. If this is done, MySQL\ncreates the column as the smallest TEXT type large enough to hold\nvalues M characters long.\n\nURL: https://mariadb.com/kb/en/text/\n\n','','https://mariadb.com/kb/en/text/'); -insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (163,37,'CONCAT_WS','Syntax:\nCONCAT_WS(separator,str1,str2,...)\n\nCONCAT_WS() stands for Concatenate With Separator and is a special form\nof CONCAT(). The first argument is the separator for the rest of the\narguments. The separator is added between the strings to be\nconcatenated. The separator can be a string, as can the rest of the\narguments. If the separator is NULL, the result is NULL.\n\nURL: https://mariadb.com/kb/en/concat_ws/\n\n','MariaDB> SELECT CONCAT_WS(\',\',\'First name\',\'Second name\',\'Last Name\');\n -> \'First name,Second name,Last Name\'\nMariaDB> SELECT CONCAT_WS(\',\',\'First name\',NULL,\'Last Name\');\n -> \'First name,Last Name\'\n','https://mariadb.com/kb/en/concat_ws/'); -insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (164,17,'ROW_COUNT','Syntax:\nROW_COUNT()\n\nBefore MySQL 5.5.5, ROW_COUNT() returns the number of rows changed,\ndeleted, or inserted by the last statement if it was an UPDATE, DELETE,\nor INSERT. For other statements, the value may not be meaningful.\n\nAs of MySQL 5.5.5, ROW_COUNT() returns a value as follows:\n\no DDL statements: 0. This applies to statements such as CREATE TABLE or\n DROP TABLE.\n\no DML statements other than SELECT: The number of affected rows. This\n applies to statements such as UPDATE, INSERT, or DELETE (as before),\n but now also to statements such as ALTER TABLE and LOAD DATA INFILE.\n\no SELECT: -1 if the statement returns a result set, or the number of\n rows "affected" if it does not. For example, for SELECT * FROM t1,\n ROW_COUNT() returns -1. For SELECT * FROM t1 INTO OUTFILE\n \'file_name\', ROW_COUNT() returns the number of rows written to the\n file.\n\no SIGNAL statements: 0.\n\nFor UPDATE statements, the affected-rows value by default is the number\nof rows actually changed. If you specify the CLIENT_FOUND_ROWS flag to\nmysql_real_connect() when connecting to mysqld, the affected-rows value\nis the number of rows "found"; that is, matched by the WHERE clause.\n\nFor REPLACE statements, the affected-rows value is 2 if the new row\nreplaced an old row, because in this case, one row was inserted after\nthe duplicate was deleted.\n\nFor INSERT ... ON DUPLICATE KEY UPDATE statements, the affected-rows\nvalue is 1 if the row is inserted as a new row and 2 if an existing row\nis updated.\n\nThe ROW_COUNT() value is similar to the value from the\nmysql_affected_rows() C API function and the row count that the mysql\nclient displays following statement execution.\n\nURL: https://mariadb.com/kb/en/information-functions-row_count/\n\n','MariaDB> INSERT INTO t VALUES(1),(2),(3);\nQuery OK, 3 rows affected (0.00 sec)\nRecords: 3 Duplicates: 0 Warnings: 0\n\nMariaDB> SELECT ROW_COUNT();\n+-------------+\n| ROW_COUNT() |\n+-------------+\n| 3 |\n+-------------+\n1 row in set (0.00 sec)\n\nMariaDB> DELETE FROM t WHERE i IN(1,2);\nQuery OK, 2 rows affected (0.00 sec)\n\nMariaDB> SELECT ROW_COUNT();\n+-------------+\n| ROW_COUNT() |\n+-------------+\n| 2 |\n+-------------+\n1 row in set (0.00 sec)\n','https://mariadb.com/kb/en/information-functions-row_count/'); -insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (165,4,'ASIN','Syntax:\nASIN(X)\n\nReturns the arc sine of X, that is, the value whose sine is X. Returns\nNULL if X is not in the range -1 to 1.\n\nURL: https://mariadb.com/kb/en/asin/\n\n','MariaDB> SELECT ASIN(0.2);\n -> 0.20135792079033\nMariaDB> SELECT ASIN(\'foo\');\n\n+-------------+\n| ASIN(\'foo\') |\n+-------------+\n| 0 |\n+-------------+\n1 row in set, 1 warning (0.00 sec)\n\nMariaDB> SHOW WARNINGS;\n+---------+------+-----------------------------------------+\n| Level | Code | Message |\n+---------+------+-----------------------------------------+\n| Warning | 1292 | Truncated incorrect DOUBLE value: \'foo\' |\n+---------+------+-----------------------------------------+\n','https://mariadb.com/kb/en/asin/'); -insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (166,4,'SIGN','Syntax:\nSIGN(X)\n\nReturns the sign of the argument as -1, 0, or 1, depending on whether X\nis negative, zero, or positive.\n\nURL: https://mariadb.com/kb/en/sign/\n\n','MariaDB> SELECT SIGN(-32);\n -> -1\nMariaDB> SELECT SIGN(0);\n -> 0\nMariaDB> SELECT SIGN(234);\n -> 1\n','https://mariadb.com/kb/en/sign/'); -insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (167,31,'SEC_TO_TIME','Syntax:\nSEC_TO_TIME(seconds)\n\nReturns the seconds argument, converted to hours, minutes, and seconds,\nas a TIME value. The range of the result is constrained to that of the\nTIME data type. A warning occurs if the argument corresponds to a value\noutside that range.\n\nURL: https://mariadb.com/kb/en/sec_to_time/\n\n','MariaDB> SELECT SEC_TO_TIME(2378);\n -> \'00:39:38\'\nMariaDB> SELECT SEC_TO_TIME(2378) + 0;\n -> 3938\n','https://mariadb.com/kb/en/sec_to_time/'); -insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (168,22,'FLOAT','FLOAT[(M,D)] [UNSIGNED] [ZEROFILL]\n\nA small (single-precision) floating-point number. Permissible values\nare -3.402823466E+38 to -1.175494351E-38, 0, and 1.175494351E-38 to\n3.402823466E+38. These are the theoretical limits, based on the IEEE\nstandard. The actual range might be slightly smaller depending on your\nhardware or operating system.\n\nM is the total number of digits and D is the number of digits following\nthe decimal point. If M and D are omitted, values are stored to the\nlimits permitted by the hardware. A single-precision floating-point\nnumber is accurate to approximately 7 decimal places.\n\nUNSIGNED, if specified, disallows negative values.\n\nUsing FLOAT might give you some unexpected problems because all\ncalculations in MySQL are done with double precision. See\nhttps://mariadb.com/kb/en/floating-point-accuracy/.\n\nURL: https://mariadb.com/kb/en/float/\n\n','','https://mariadb.com/kb/en/float/'); -insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (169,37,'LOCATE','Syntax:\nLOCATE(substr,str), LOCATE(substr,str,pos)\n\nThe first syntax returns the position of the first occurrence of\nsubstring substr in string str. The second syntax returns the position\nof the first occurrence of substring substr in string str, starting at\nposition pos. Returns 0 if substr is not in str.\n\nURL: https://mariadb.com/kb/en/locate/\n\n','MariaDB> SELECT LOCATE(\'bar\', \'foobarbar\');\n -> 4\nMariaDB> SELECT LOCATE(\'xbar\', \'foobar\');\n -> 0\nMariaDB> SELECT LOCATE(\'bar\', \'foobarbar\', 5);\n -> 7\n','https://mariadb.com/kb/en/locate/'); -insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (170,26,'SHOW EVENTS','Syntax:\nSHOW EVENTS [{FROM | IN} schema_name]\n [LIKE \'pattern\' | WHERE expr]\n\nThis statement displays information about Event Manager events. It\nrequires the EVENT privilege for the database from which the events are\nto be shown.\n\nIn its simplest form, SHOW EVENTS lists all of the events in the\ncurrent schema:\n\nMariaDB> SELECT CURRENT_USER(), SCHEMA();\n+----------------+----------+\n| CURRENT_USER() | SCHEMA() |\n+----------------+----------+\n| jon@ghidora | myschema |\n+----------------+----------+\n1 row in set (0.00 sec)\n\nMariaDB> SHOW EVENTS\\G\n*************************** 1. row ***************************\n Db: myschema\n Name: e_daily\n Definer: jon@ghidora\n Time zone: SYSTEM\n Type: RECURRING\n Execute at: NULL\n Interval value: 10\n Interval field: SECOND\n Starts: 2006-02-09 10:41:23\n Ends: NULL\n Status: ENABLED\n Originator: 0\ncharacter_set_client: latin1\ncollation_connection: latin1_swedish_ci\n Database Collation: latin1_swedish_ci\n\nTo see events for a specific schema, use the FROM clause. For example,\nto see events for the test schema, use the following statement:\n\nSHOW EVENTS FROM test;\n\nThe LIKE clause, if present, indicates which event names to match. The\nWHERE clause can be given to select rows using more general conditions,\nas discussed in\nhttps://mariadb.com/kb/en/extended-show/.\n\nURL: https://mariadb.com/kb/en/show-events/\n\n','','https://mariadb.com/kb/en/show-events/'); -insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (171,17,'CHARSET','Syntax:\nCHARSET(str)\n\nReturns the character set of the string argument.\n\nURL: https://mariadb.com/kb/en/charset/\n\n','MariaDB> SELECT CHARSET(\'abc\');\n -> \'latin1\'\nMariaDB> SELECT CHARSET(CONVERT(\'abc\' USING utf8));\n -> \'utf8\'\nMariaDB> SELECT CHARSET(USER());\n -> \'utf8\'\n','https://mariadb.com/kb/en/charset/'); -insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (172,31,'SUBDATE','Syntax:\nSUBDATE(date,INTERVAL expr unit), SUBDATE(expr,days)\n\nWhen invoked with the INTERVAL form of the second argument, SUBDATE()\nis a synonym for DATE_SUB(). For information on the INTERVAL unit\nargument, see the discussion for DATE_ADD().\n\nMariaDB> SELECT DATE_SUB(\'2008-01-02\', INTERVAL 31 DAY);\n -> \'2007-12-02\'\nMariaDB> SELECT SUBDATE(\'2008-01-02\', INTERVAL 31 DAY);\n -> \'2007-12-02\'\n\nThe second form enables the use of an integer value for days. In such\ncases, it is interpreted as the number of days to be subtracted from\nthe date or datetime expression expr.\n\nMariaDB> SELECT SUBDATE(\'2008-01-02 12:00:00\', 31);\n -> \'2007-12-02 12:00:00\'\n\nURL: https://mariadb.com/kb/en/subdate/\n\n','','https://mariadb.com/kb/en/subdate/'); -insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (173,31,'DAYOFYEAR','Syntax:\nDAYOFYEAR(date)\n\nReturns the day of the year for date, in the range 1 to 366.\n\nURL: https://mariadb.com/kb/en/dayofyear/\n\n','MariaDB> SELECT DAYOFYEAR(\'2007-02-03\');\n -> 34\n','https://mariadb.com/kb/en/dayofyear/'); -insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (174,4,'%','Syntax:\nN % M, N MOD M\n\nModulo operation. Returns the remainder of N divided by M. For more\ninformation, see the description for the MOD() function in\nhttps://mariadb.com/kb/en/mod/.\n\nURL: https://mariadb.com/kb/en/modulo-operator/\n\n','','https://mariadb.com/kb/en/modulo-operator/'); -insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (175,22,'LONGTEXT','LONGTEXT [CHARACTER SET charset_name] [COLLATE collation_name]\n\nA TEXT column with a maximum length of 4,294,967,295 or 4GB (232 - 1)\ncharacters. The effective maximum length is less if the value contains\nmulti-byte characters. The effective maximum length of LONGTEXT columns\nalso depends on the configured maximum packet size in the client/server\nprotocol and available memory. Each LONGTEXT value is stored using a\n4-byte length prefix that indicates the number of bytes in the value.\n\nURL: https://mariadb.com/kb/en/longtext/\n\n','','https://mariadb.com/kb/en/longtext/'); -insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (176,26,'KILL','Syntax:\nKILL [CONNECTION | QUERY] thread_id\n\nEach connection to mysqld runs in a separate thread. You can see which\nthreads are running with the SHOW PROCESSLIST statement and kill a\nthread with the KILL thread_id statement.\n\nKILL permits an optional CONNECTION or QUERY modifier:\n\no KILL CONNECTION is the same as KILL with no modifier: It terminates\n the connection associated with the given thread_id.\n\no KILL QUERY terminates the statement that the connection is currently\n executing, but leaves the connection itself intact.\n\nIf you have the PROCESS privilege, you can see all threads. If you have\nthe SUPER privilege, you can kill all threads and statements.\nOtherwise, you can see and kill only your own threads and statements.\n\nYou can also use the mysqladmin processlist and mysqladmin kill\ncommands to examine and kill threads.\n\n*Note*: You cannot use KILL with the Embedded MySQL Server library\nbecause the embedded server merely runs inside the threads of the host\napplication. It does not create any connection threads of its own.\n\nURL: https://mariadb.com/kb/en/data-manipulation-kill-connection-query/\n\n','','https://mariadb.com/kb/en/data-manipulation-kill-connection-query/'); -insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (177,30,'DISJOINT','Disjoint(g1,g2)\n\nReturns 1 or 0 to indicate whether g1 is spatially disjoint from (does\nnot intersect) g2.\n\nURL: https://mariadb.com/kb/en/disjoint/\n\n','','https://mariadb.com/kb/en/disjoint/'); -insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (178,3,'ASTEXT','AsText(g), AsWKT(g)\n\nConverts a value in internal geometry format to its WKT representation\nand returns the string result.\n\nURL: https://mariadb.com/kb/en/astext/\n\n','MariaDB> SET @g = \'LineString(1 1,2 2,3 3)\';\nMariaDB> SELECT AsText(GeomFromText(@g));\n+--------------------------+\n| AsText(GeomFromText(@g)) |\n+--------------------------+\n| LINESTRING(1 1,2 2,3 3) |\n+--------------------------+\n','https://mariadb.com/kb/en/astext/'); -insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (179,37,'LPAD','Syntax:\nLPAD(str,len,padstr)\n\nReturns the string str, left-padded with the string padstr to a length\nof len characters. If str is longer than len, the return value is\nshortened to len characters.\n\n\nURL: https://mariadb.com/kb/en/lpad/\n\n','MariaDB> SELECT LPAD(\'hi\',4,\'??\');\n -> \'??hi\'\nMariaDB> SELECT LPAD(\'hi\',1,\'??\');\n -> \'h\'\n','https://mariadb.com/kb/en/lpad/'); -insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (180,23,'DECLARE CONDITION','Syntax:\nDECLARE condition_name CONDITION FOR condition_value\n\ncondition_value:\n mysql_error_code\n | SQLSTATE [VALUE] sqlstate_value\n\nThe DECLARE ... CONDITION statement declares a named error condition,\nassociating a name with a condition that needs specific handling. The\nname can be referred to in a subsequent DECLARE ... HANDLER statement\n(see [HELP DECLARE HANDLER]).\n\nCondition declarations must appear before cursor or handler\ndeclarations.\n\nThe condition_value for DECLARE ... CONDITION can be a MySQL error code\n(a number) or an SQLSTATE value (a 5-character string literal). You\nshould not use MySQL error code 0 or SQLSTATE values that begin with\n\'00\', because those indicate success rather than an error condition.\nFor a list of MySQL error codes and SQLSTATE values, see\nhttps://mariadb.com/kb/en/mariadb-error-codes/.\n\nURL: https://mariadb.com/kb/en/declare-condition/\n\n','','https://mariadb.com/kb/en/declare-condition/'); -insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (181,30,'OVERLAPS','Overlaps(g1,g2)\n\nReturns 1 or 0 to indicate whether g1 spatially overlaps g2. The term\nspatially overlaps is used if two geometries intersect and their\nintersection results in a geometry of the same dimension but not equal\nto either of the given geometries.\n\nURL: https://mariadb.com/kb/en/overlaps/\n\n','','https://mariadb.com/kb/en/overlaps/'); -insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (182,8,'SET GLOBAL SQL_SLAVE_SKIP_COUNTER','Syntax:\nSET GLOBAL sql_slave_skip_counter = N\n\nThis statement skips the next N events from the master. This is useful\nfor recovering from replication stops caused by a statement.\n\nThis statement is valid only when the slave threads are not running.\nOtherwise, it produces an error.\n\nURL: https://mariadb.com/kb/en/set-global-sql_slave_skip_counter/\n\n','','https://mariadb.com/kb/en/set-global-sql_slave_skip_counter/'); -insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (183,25,'NUMGEOMETRIES','NumGeometries(gc)\n\nReturns the number of geometries in the GeometryCollection value gc.\n\nURL: https://mariadb.com/kb/en/numgeometries/\n\n','MariaDB> SET @gc = \'GeometryCollection(Point(1 1),LineString(2 2, 3 3))\';\nMariaDB> SELECT NumGeometries(GeomFromText(@gc));\n+----------------------------------+\n| NumGeometries(GeomFromText(@gc)) |\n+----------------------------------+\n| 2 |\n+----------------------------------+\n','https://mariadb.com/kb/en/numgeometries/'); -insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (184,31,'MONTHNAME','Syntax:\nMONTHNAME(date)\n\nReturns the full name of the month for date. The language used for the\nname is controlled by the value of the lc_time_names system variable\n(https://mariadb.com/kb/en/server-locale/).\n\nURL: https://mariadb.com/kb/en/monthname/\n\n','MariaDB> SELECT MONTHNAME(\'2008-02-03\');\n -> \'February\'\n','https://mariadb.com/kb/en/monthname/'); -insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (185,8,'CHANGE MASTER TO','Syntax:\nCHANGE MASTER TO option [, option] ...\n\noption:\n MASTER_BIND = \'interface_name\'\n | MASTER_HOST = \'host_name\'\n | MASTER_USER = \'user_name\'\n | MASTER_PASSWORD = \'password\'\n | MASTER_PORT = port_num\n | MASTER_CONNECT_RETRY = interval\n | MASTER_HEARTBEAT_PERIOD = interval\n | MASTER_LOG_FILE = \'master_log_name\'\n | MASTER_LOG_POS = master_log_pos\n | RELAY_LOG_FILE = \'relay_log_name\'\n | RELAY_LOG_POS = relay_log_pos\n | MASTER_SSL = {0|1}\n | MASTER_SSL_CA = \'ca_file_name\'\n | MASTER_SSL_CAPATH = \'ca_directory_name\'\n | MASTER_SSL_CERT = \'cert_file_name\'\n | MASTER_SSL_KEY = \'key_file_name\'\n | MASTER_SSL_CIPHER = \'cipher_list\'\n | MASTER_SSL_VERIFY_SERVER_CERT = {0|1}\n | IGNORE_SERVER_IDS = (server_id_list)\n\nserver_id_list:\n [server_id [, server_id] ... ]\n\nCHANGE MASTER TO changes the parameters that the slave server uses for\nconnecting to the master server, for reading the master binary log, and\nreading the slave relay log. It also updates the contents of the\nmaster.info and relay-log.info files. To use CHANGE MASTER TO, the\nslave replication threads must be stopped (use STOP SLAVE if\nnecessary).\n\nOptions not specified retain their value, except as indicated in the\nfollowing discussion. Thus, in most cases, there is no need to specify\noptions that do not change. For example, if the password to connect to\nyour MySQL master has changed, you just need to issue these statements\nto tell the slave about the new password:\n\nSTOP SLAVE; -- if replication was running\nCHANGE MASTER TO MASTER_PASSWORD=\'new3cret\';\nSTART SLAVE; -- if you want to restart replication\n\nMASTER_HOST, MASTER_USER, MASTER_PASSWORD, and MASTER_PORT provide\ninformation to the slave about how to connect to its master:\n\no MASTER_HOST and MASTER_PORT are the host name (or IP address) of the\n master host and its TCP/IP port.\n\n *Note*: Replication cannot use Unix socket files. You must be able to\n connect to the master MySQL server using TCP/IP.\n\n If you specify the MASTER_HOST or MASTER_PORT option, the slave\n assumes that the master server is different from before (even if the\n option value is the same as its current value.) In this case, the old\n values for the master binary log file name and position are\n considered no longer applicable, so if you do not specify\n MASTER_LOG_FILE and MASTER_LOG_POS in the statement,\n MASTER_LOG_FILE=\'\' and MASTER_LOG_POS=4 are silently appended to it.\n\n Setting MASTER_HOST=\'\' (that is, setting its value explicitly to an\n empty string) is not the same as not setting MASTER_HOST at all.\n Beginning with MySQL 5.5, trying to set MASTER_HOST to an empty\n string fails with an error. Previously, setting MASTER_HOST to an\n empty string caused START SLAVE subsequently to fail. (Bug #28796)\n\no MASTER_USER and MASTER_PASSWORD are the user name and password of the\n account to use for connecting to the master.\n\n In MySQL 5.5.20 and later, MASTER_USER cannot be made empty; setting\n MASTER_USER = \'\' or leaving it unset when setting a value for for\n MASTER_PASSWORD causes an error (Bug #13427949).\n\n Currently, a password used for a replication slave account is\n effectively limited to 32 characters in length; the password can be\n longer, but any excess characters are truncated. This is not due to\n any limit imposed by the MySQL Server generally, but rather is an\n issue specific to MySQL Replication. (For more information, see Bug\n #43439.)\n\n The text of a running CHANGE MASTER TO statement, including values\n for MASTER_USER and MASTER_PASSWORD, can be seen in the output of a\n concurrent SHOW PROCESSLIST statement.\n\nThe MASTER_SSL_xxx options provide information about using SSL for the\nconnection. They correspond to the --ssl-xxx options described in\nhttps://mariadb.com/kb/en/ssl-server-system-variables/, and\nhttp://dev.mysql.com/doc/refman/5.5/en/replication-solutions-ssl.html.\nThese options can be changed even on slaves that are compiled without\nSSL support. They are saved to the master.info file, but are ignored if\nthe slave does not have SSL support enabled.\n\nMASTER_CONNECT_RETRY specifies how many seconds to wait between connect\nretries. The default is 60. The number of reconnection attempts is\nlimited by the --master-retry-count server option; for more\ninformation, see\nhttps://mariadb.com/kb/en/replication-and-binary-log-server-system-variables/.\n\nMASTER_HEARTBEAT_PERIOD sets the interval in seconds between\nreplication heartbeats. Whenever the master\'s binary log is updated\nwith an event, the waiting period for the next heartbeat is reset.\ninterval is a decimal value having the range 0 to 4294967 seconds and a\nresolution in milliseconds; the smallest nonzero value is 0.001.\nHeartbeats are sent by the master only if there are no unsent events in\nthe binary log file for a period longer than interval.\n\nSetting interval to 0 disables heartbeats altogether. The default value\nfor interval is equal to the value of slave_net_timeout divided by 2.\n\nSetting @@global.slave_net_timeout to a value less than that of the\ncurrent heartbeat interval results in a warning being issued. The\neffect of issuing RESET SLAVE on the heartbeat interval is to reset it\nto the default value.\n\nMASTER_LOG_FILE and MASTER_LOG_POS are the coordinates at which the\nslave I/O thread should begin reading from the master the next time the\nthread starts. RELAY_LOG_FILE and RELAY_LOG_POS are the coordinates at\nwhich the slave SQL thread should begin reading from the relay log the\nnext time the thread starts. If you specify either of MASTER_LOG_FILE\nor MASTER_LOG_POS, you cannot specify RELAY_LOG_FILE or RELAY_LOG_POS.\nIf neither of MASTER_LOG_FILE or MASTER_LOG_POS is specified, the slave\nuses the last coordinates of the slave SQL thread before CHANGE MASTER\nTO was issued. This ensures that there is no discontinuity in\nreplication, even if the slave SQL thread was late compared to the\nslave I/O thread, when you merely want to change, say, the password to\nuse.\n\nCHANGE MASTER TO deletes all relay log files and starts a new one,\nunless you specify RELAY_LOG_FILE or RELAY_LOG_POS. In that case, relay\nlog files are kept; the relay_log_purge global variable is set silently\nto 0.\n\nPrior to MySQL 5.5, RELAY_LOG_FILE required an absolute path. In MySQL\n5.5, the path can be relative, in which case the path is assumed to be\nrelative to the slave\'s data directory. (Bug #12190)\n\nIGNORE_SERVER_IDS was added in MySQL 5.5. This option takes a\ncomma-separated list of 0 or more server IDs. Events originating from\nthe corresponding servers are ignored, with the exception of log\nrotation and deletion events, which are still recorded in the relay\nlog.\n\nIn circular replication, the originating server normally acts as the\nterminator of its own events, so that they are not applied more than\nonce. Thus, this option is useful in circular replication when one of\nthe servers in the circle is removed. Suppose that you have a circular\nreplication setup with 4 servers, having server IDs 1, 2, 3, and 4, and\nserver 3 fails. When bridging the gap by starting replication from\nserver 2 to server 4, you can include IGNORE_SERVER_IDS = (3) in the\nCHANGE MASTER TO statement that you issue on server 4 to tell it to use\nserver 2 as its master instead of server 3. Doing so causes it to\nignore and not to propagate any statements that originated with the\nserver that is no longer in use.\n\nIf a CHANGE MASTER TO statement is issued without any IGNORE_SERVER_IDS\noption, any existing list is preserved; RESET SLAVE also has no effect\non the server ID list. To clear the list of ignored servers, it is\nnecessary to use the option with an empty list:\n\nCHANGE MASTER TO IGNORE_SERVER_IDS = ();\n\nIf IGNORE_SERVER_IDS contains the server\'s own ID and the server was\nstarted with the --replicate-same-server-id option enabled, an error\nresults.\n\nAlso beginning with MySQL 5.5, the master.info file and the output of\nSHOW SLAVE STATUS are extended to provide the list of servers that are\ncurrently ignored. For more information, see\nhttps://mariadb.com/kb/en/show-slave-status/, and\n[HELP SHOW SLAVE STATUS].\n\nBeginning with MySQL 5.5.5, invoking CHANGE MASTER TO causes the\nprevious values for MASTER_HOST, MASTER_PORT, MASTER_LOG_FILE, and\nMASTER_LOG_POS to be written to the error log, along with other\ninformation about the slave\'s state prior to execution.\n\nCHANGE MASTER TO is useful for setting up a slave when you have the\nsnapshot of the master and have recorded the master binary log\ncoordinates corresponding to the time of the snapshot. After loading\nthe snapshot into the slave to synchronize it to the slave, you can run\nCHANGE MASTER TO MASTER_LOG_FILE=\'log_name\', MASTER_LOG_POS=log_pos on\nthe slave to specify the coordinates at which the slave should begin\nreading the master binary log.\n\nThe following example changes the master server the slave uses and\nestablishes the master binary log coordinates from which the slave\nbegins reading. This is used when you want to set up the slave to\nreplicate the master:\n\nCHANGE MASTER TO\n MASTER_HOST=\'master2.mycompany.com\',\n MASTER_USER=\'replication\',\n MASTER_PASSWORD=\'bigs3cret\',\n MASTER_PORT=3306,\n MASTER_LOG_FILE=\'master2-bin.001\',\n MASTER_LOG_POS=4,\n MASTER_CONNECT_RETRY=10;\n\nThe next example shows an operation that is less frequently employed.\nIt is used when the slave has relay log files that you want it to\nexecute again for some reason. To do this, the master need not be\nreachable. You need only use CHANGE MASTER TO and start the SQL thread\n(START SLAVE SQL_THREAD):\n\nCHANGE MASTER TO\n RELAY_LOG_FILE=\'slave-relay-bin.006\',\n RELAY_LOG_POS=4025;\n\nURL: https://mariadb.com/kb/en/change-master-to/\n\n','','https://mariadb.com/kb/en/change-master-to/'); -insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (186,39,'DROP DATABASE','Syntax:\nDROP {DATABASE | SCHEMA} [IF EXISTS] db_name\n\nDROP DATABASE drops all tables in the database and deletes the\ndatabase. Be very careful with this statement! To use DROP DATABASE,\nyou need the DROP privilege on the database. DROP SCHEMA is a synonym\nfor DROP DATABASE.\n\n*Important*: When a database is dropped, user privileges on the\ndatabase are not automatically dropped. See [HELP GRANT].\n\nIF EXISTS is used to prevent an error from occurring if the database\ndoes not exist.\n\nURL: https://mariadb.com/kb/en/drop-database/\n\n','','https://mariadb.com/kb/en/drop-database/'); -insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (187,6,'MBREQUAL','MBREqual(g1,g2)\n\nReturns 1 or 0 to indicate whether the Minimum Bounding Rectangles of\nthe two geometries g1 and g2 are the same.\n\nURL: https://mariadb.com/kb/en/mbrequal/\n\n','','https://mariadb.com/kb/en/mbrequal/'); -insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (188,31,'TIMESTAMP FUNCTION','Syntax:\nTIMESTAMP(expr), TIMESTAMP(expr1,expr2)\n\nWith a single argument, this function returns the date or datetime\nexpression expr as a datetime value. With two arguments, it adds the\ntime expression expr2 to the date or datetime expression expr1 and\nreturns the result as a datetime value.\n\nURL: https://mariadb.com/kb/en/timestamp-function/\n\n','MariaDB> SELECT TIMESTAMP(\'2003-12-31\');\n -> \'2003-12-31 00:00:00\'\nMariaDB> SELECT TIMESTAMP(\'2003-12-31 12:00:00\',\'12:00:00\');\n -> \'2004-01-01 00:00:00\'\n','https://mariadb.com/kb/en/timestamp-function/'); -insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (189,33,'PROCEDURE ANALYSE','Syntax:\nANALYSE([max_elements[,max_memory]])\n\nANALYSE() examines the result from a query and returns an analysis of\nthe results that suggests optimal data types for each column that may\nhelp reduce table sizes. To obtain this analysis, append PROCEDURE\nANALYSE to the end of a SELECT statement:\n\nSELECT ... FROM ... WHERE ... PROCEDURE ANALYSE([max_elements,[max_memory]])\n\nFor example:\n\nSELECT col1, col2 FROM table1 PROCEDURE ANALYSE(10, 2000);\n\nThe results show some statistics for the values returned by the query,\nand propose an optimal data type for the columns. This can be helpful\nfor checking your existing tables, or after importing new data. You may\nneed to try different settings for the arguments so that PROCEDURE\nANALYSE() does not suggest the ENUM data type when it is not\nappropriate.\n\nThe arguments are optional and are used as follows:\n\no max_elements (default 256) is the maximum number of distinct values\n that ANALYSE() notices per column. This is used by ANALYSE() to check\n whether the optimal data type should be of type ENUM; if there are\n more than max_elements distinct values, then ENUM is not a suggested\n type.\n\no max_memory (default 8192) is the maximum amount of memory that\n ANALYSE() should allocate per column while trying to find all\n distinct values.\n\nURL: https://mariadb.com/kb/en/procedure-analyse/\n\n','','https://mariadb.com/kb/en/procedure-analyse/'); -insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (190,9,'HELP_VERSION','This help information was generated from the MySQL 5.5 Reference Manual\non: 2012-08-25 (revision: 31914)\n\nThis information applies to MySQL 5.5 through 5.5.29.\n','',''); -insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (191,37,'CHARACTER_LENGTH','Syntax:\nCHARACTER_LENGTH(str)\n\nCHARACTER_LENGTH() is a synonym for CHAR_LENGTH().\n\nURL: https://mariadb.com/kb/en/character_length/\n\n','','https://mariadb.com/kb/en/character_length/'); -insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (192,26,'SHOW GRANTS','Syntax:\nSHOW GRANTS [FOR user]\n\nThis statement lists the GRANT statement or statements that must be\nissued to duplicate the privileges that are granted to a MySQL user\naccount. The account is named using the same format as for the GRANT\nstatement; for example, \'jeffrey\'@\'localhost\'. If you specify only the\nuser name part of the account name, a host name part of \'%\' is used.\nFor additional information about specifying account names, see [HELP\nGRANT].\n\nMariaDB> SHOW GRANTS FOR \'root\'@\'localhost\';\n+---------------------------------------------------------------------+\n| Grants for root@localhost |\n+---------------------------------------------------------------------+\n| GRANT ALL PRIVILEGES ON *.* TO \'root\'@\'localhost\' WITH GRANT OPTION |\n+---------------------------------------------------------------------+\n\nTo list the privileges granted to the account that you are using to\nconnect to the server, you can use any of the following statements:\n\nSHOW GRANTS;\nSHOW GRANTS FOR CURRENT_USER;\nSHOW GRANTS FOR CURRENT_USER();\n\nIf SHOW GRANTS FOR CURRENT_USER (or any of the equivalent syntaxes) is\nused in DEFINER context, such as within a stored procedure that is\ndefined with SQL SECURITY DEFINER), the grants displayed are those of\nthe definer and not the invoker.\n\nURL: https://mariadb.com/kb/en/show-grants/\n\n','','https://mariadb.com/kb/en/show-grants/'); -insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (193,26,'SHOW PRIVILEGES','Syntax:\nSHOW PRIVILEGES\n\nSHOW PRIVILEGES shows the list of system privileges that the MySQL\nserver supports. The exact list of privileges depends on the version of\nyour server.\n\nURL: https://mariadb.com/kb/en/show-privileges/\n\n','','https://mariadb.com/kb/en/show-privileges/'); -insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (194,39,'CREATE TABLESPACE','Syntax:\nCREATE TABLESPACE tablespace_name\n ADD DATAFILE \'file_name\'\n USE LOGFILE GROUP logfile_group\n [EXTENT_SIZE [=] extent_size]\n [INITIAL_SIZE [=] initial_size]\n [AUTOEXTEND_SIZE [=] autoextend_size]\n [MAX_SIZE [=] max_size]\n [NODEGROUP [=] nodegroup_id]\n [WAIT]\n [COMMENT [=] comment_text]\n ENGINE [=] engine_name\n\nThis statement is used with NDB cluster, which is not supported by MariaDB.','','https://mariadb.com/kb/en/create-tablespace/'); -insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (195,37,'INSERT FUNCTION','Syntax:\nINSERT(str,pos,len,newstr)\n\nReturns the string str, with the substring beginning at position pos\nand len characters long replaced by the string newstr. Returns the\noriginal string if pos is not within the length of the string. Replaces\nthe rest of the string from position pos if len is not within the\nlength of the rest of the string. Returns NULL if any argument is NULL.\n\nURL: https://mariadb.com/kb/en/insert-function/\n\n','MariaDB> SELECT INSERT(\'Quadratic\', 3, 4, \'What\');\n -> \'QuWhattic\'\nMariaDB> SELECT INSERT(\'Quadratic\', -1, 4, \'What\');\n -> \'Quadratic\'\nMariaDB> SELECT INSERT(\'Quadratic\', 3, 100, \'What\');\n -> \'QuWhat\'\n','https://mariadb.com/kb/en/insert-function/'); -insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (196,4,'CRC32','Syntax:\nCRC32(expr)\n\nComputes a cyclic redundancy check value and returns a 32-bit unsigned\nvalue. The result is NULL if the argument is NULL. The argument is\nexpected to be a string and (if possible) is treated as one if it is\nnot.\n\nURL: https://mariadb.com/kb/en/crc32/\n\n','MariaDB> SELECT CRC32(\'MySQL\');\n -> 3259397556\nMariaDB> SELECT CRC32(\'mysql\');\n -> 2501908538\n','https://mariadb.com/kb/en/crc32/'); -insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (197,15,'XOR','Syntax:\nXOR\n\nLogical XOR. Returns NULL if either operand is NULL. For non-NULL\noperands, evaluates to 1 if an odd number of operands is nonzero,\notherwise 0 is returned.\n\nURL: https://mariadb.com/kb/en/xor/\n\n','MariaDB> SELECT 1 XOR 1;\n -> 0\nMariaDB> SELECT 1 XOR 0;\n -> 1\nMariaDB> SELECT 1 XOR NULL;\n -> NULL\nMariaDB> SELECT 1 XOR 1 XOR 1;\n -> 1\n','https://mariadb.com/kb/en/xor/'); -insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (198,13,'STARTPOINT','StartPoint(ls)\n\nReturns the Point that is the start point of the LineString value ls.\n\nURL: https://mariadb.com/kb/en/startpoint/\n\n','MariaDB> SET @ls = \'LineString(1 1,2 2,3 3)\';\nMariaDB> SELECT AsText(StartPoint(GeomFromText(@ls)));\n+---------------------------------------+\n| AsText(StartPoint(GeomFromText(@ls))) |\n+---------------------------------------+\n| POINT(1 1) |\n+---------------------------------------+\n','https://mariadb.com/kb/en/startpoint/'); -insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (199,10,'GRANT','Syntax:\nGRANT\n priv_type [(column_list)]\n [, priv_type [(column_list)]] ...\n ON [object_type] priv_level\n TO user_specification [, user_specification] ...\n [REQUIRE {NONE | ssl_option [[AND] ssl_option] ...}]\n [WITH with_option ...]\n\nGRANT PROXY ON user_specification\n TO user_specification [, user_specification] ...\n [WITH GRANT OPTION]\n\nobject_type:\n TABLE\n | FUNCTION\n | PROCEDURE\n\npriv_level:\n *\n | *.*\n | db_name.*\n | db_name.tbl_name\n | tbl_name\n | db_name.routine_name\n\nuser_specification:\n user\n [\n IDENTIFIED BY [PASSWORD] \'password\'\n | IDENTIFIED WITH auth_plugin [AS \'auth_string\']\n ]\n\nssl_option:\n SSL\n | X509\n | CIPHER \'cipher\'\n | ISSUER \'issuer\'\n | SUBJECT \'subject\'\n\nwith_option:\n GRANT OPTION\n | MAX_QUERIES_PER_HOUR count\n | MAX_UPDATES_PER_HOUR count\n | MAX_CONNECTIONS_PER_HOUR count\n | MAX_USER_CONNECTIONS count\n\nThe GRANT statement grants privileges to MySQL user accounts. GRANT\nalso serves to specify other account characteristics such as use of\nsecure connections and limits on access to server resources. To use\nGRANT, you must have the GRANT OPTION privilege, and you must have the\nprivileges that you are granting.\n\nNormally, a database administrator first uses CREATE USER to create an\naccount, then GRANT to define its privileges and characteristics. For\nexample:\n\nCREATE USER \'jeffrey\'@\'localhost\' IDENTIFIED BY \'mypass\';\nGRANT ALL ON db1.* TO \'jeffrey\'@\'localhost\';\nGRANT SELECT ON db2.invoice TO \'jeffrey\'@\'localhost\';\nGRANT USAGE ON *.* TO \'jeffrey\'@\'localhost\' WITH MAX_QUERIES_PER_HOUR 90;\n\nHowever, if an account named in a GRANT statement does not already\nexist, GRANT may create it under the conditions described later in the\ndiscussion of the NO_AUTO_CREATE_USER SQL mode.\n\nThe REVOKE statement is related to GRANT and enables administrators to\nremove account privileges. See [HELP REVOKE].\n\nWhen successfully executed from the mysql program, GRANT responds with\nQuery OK, 0 rows affected. To determine what privileges result from the\noperation, use SHOW GRANTS. See [HELP SHOW GRANTS].\n\nURL: https://mariadb.com/kb/en/grant/\n\n','','https://mariadb.com/kb/en/grant/'); -insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (200,23,'DECLARE VARIABLE','Syntax:\nDECLARE var_name [, var_name] ... type [DEFAULT value]\n\nThis statement declares local variables within stored programs. To\nprovide a default value for a variable, include a DEFAULT clause. The\nvalue can be specified as an expression; it need not be a constant. If\nthe DEFAULT clause is missing, the initial value is NULL.\n\nLocal variables are treated like stored routine parameters with respect\nto data type and overflow checking. See [HELP CREATE PROCEDURE].\n\nVariable declarations must appear before cursor or handler\ndeclarations.\n\nLocal variable names are not case sensitive. Permissible characters and\nquoting rules are the same as for other identifiers, as described in\nhttps://mariadb.com/kb/en/identifier-names/.\n\nThe scope of a local variable is the BEGIN ... END block within which\nit is declared. The variable can be referred to in blocks nested within\nthe declaring block, except those blocks that declare a variable with\nthe same name.\n\nURL: https://mariadb.com/kb/en/declare-variable/\n\n','','https://mariadb.com/kb/en/declare-variable/'); -insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (201,3,'MPOLYFROMTEXT','MPolyFromText(wkt[,srid]), MultiPolygonFromText(wkt[,srid])\n\nConstructs a MULTIPOLYGON value using its WKT representation and SRID.\n\nURL: https://mariadb.com/kb/en/mpolyfromtext/\n\n','','https://mariadb.com/kb/en/mpolyfromtext/'); -insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (202,6,'MBRINTERSECTS','MBRIntersects(g1,g2)\n\nReturns 1 or 0 to indicate whether the Minimum Bounding Rectangles of\nthe two geometries g1 and g2 intersect.\n\nURL: https://mariadb.com/kb/en/mbrintersects/\n\n','','https://mariadb.com/kb/en/mbrintersects/'); -insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (203,16,'BIT_OR','Syntax:\nBIT_OR(expr)\n\nReturns the bitwise OR of all bits in expr. The calculation is\nperformed with 64-bit (BIGINT) precision.\n\nURL: https://mariadb.com/kb/en/bit_or/\n\n','','https://mariadb.com/kb/en/bit_or/'); -insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (204,31,'YEARWEEK','Syntax:\nYEARWEEK(date), YEARWEEK(date,mode)\n\nReturns year and week for a date. The mode argument works exactly like\nthe mode argument to WEEK(). The year in the result may be different\nfrom the year in the date argument for the first and the last week of\nthe year.\n\nURL: https://mariadb.com/kb/en/yearweek/\n\n','MariaDB> SELECT YEARWEEK(\'1987-01-01\');\n -> 198653\n','https://mariadb.com/kb/en/yearweek/'); -insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (205,18,'NOT BETWEEN','Syntax:\nexpr NOT BETWEEN min AND max\n\nThis is the same as NOT (expr BETWEEN min AND max).\n\nURL: https://mariadb.com/kb/en/not-between/\n\n','','https://mariadb.com/kb/en/not-between/'); -insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (206,18,'IS NOT','Syntax:\nIS NOT boolean_value\n\nTests a value against a boolean value, where boolean_value can be TRUE,\nFALSE, or UNKNOWN.\n\nURL: https://mariadb.com/kb/en/is-not/\n\n','MariaDB> SELECT 1 IS NOT UNKNOWN, 0 IS NOT UNKNOWN, NULL IS NOT UNKNOWN;\n -> 1, 1, 0\n','https://mariadb.com/kb/en/is-not/'); -insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (207,4,'LOG10','Syntax:\nLOG10(X)\n\nReturns the base-10 logarithm of X.\n\nURL: https://mariadb.com/kb/en/log10/\n\n','MariaDB> SELECT LOG10(2);\n -> 0.30102999566398\nMariaDB> SELECT LOG10(100);\n -> 2\nMariaDB> SELECT LOG10(-100);\n -> NULL\n','https://mariadb.com/kb/en/log10/'); -insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (208,4,'SQRT','Syntax:\nSQRT(X)\n\nReturns the square root of a nonnegative number X.\n\nURL: https://mariadb.com/kb/en/sqrt/\n\n','MariaDB> SELECT SQRT(4);\n -> 2\nMariaDB> SELECT SQRT(20);\n -> 4.4721359549996\nMariaDB> SELECT SQRT(-16);\n -> NULL\n','https://mariadb.com/kb/en/sqrt/'); -insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (209,22,'DECIMAL','DECIMAL[(M[,D])] [UNSIGNED] [ZEROFILL]\n\nA packed "exact" fixed-point number. M is the total number of digits\n(the precision) and D is the number of digits after the decimal point\n(the scale). The decimal point and (for negative numbers) the "-" sign\nare not counted in M. If D is 0, values have no decimal point or\nfractional part. The maximum number of digits (M) for DECIMAL is 65.\nThe maximum number of supported decimals (D) is 30. If D is omitted,\nthe default is 0. If M is omitted, the default is 10.\n\nUNSIGNED, if specified, disallows negative values.\n\nAll basic calculations (+, -, *, /) with DECIMAL columns are done with\na precision of 65 digits.\n\nURL: https://mariadb.com/kb/en/decimal/\n\n','','https://mariadb.com/kb/en/decimal/'); -insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (210,39,'CREATE INDEX','Syntax:\nCREATE [ONLINE|OFFLINE] [UNIQUE|FULLTEXT|SPATIAL] INDEX index_name\n [index_type]\n ON tbl_name (index_col_name,...)\n [index_option] ...\n\nindex_col_name:\n col_name [(length)] [ASC | DESC]\n\nindex_type:\n USING {BTREE | HASH}\n\nindex_option:\n KEY_BLOCK_SIZE [=] value\n | index_type\n | WITH PARSER parser_name\n | COMMENT \'string\'\n\nCREATE INDEX is mapped to an ALTER TABLE statement to create indexes.\nSee [HELP ALTER TABLE]. CREATE INDEX cannot be used to create a PRIMARY\nKEY; use ALTER TABLE instead. For more information about indexes, see\nhttps://mariadb.com/kb/en/optimization-and-indexes/.\n\nURL: https://mariadb.com/kb/en/create-index/\n\n','','https://mariadb.com/kb/en/create-index/'); -insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (211,39,'CREATE FUNCTION','The CREATE FUNCTION statement is used to create stored functions and\nuser-defined functions (UDFs):\n\no For information about creating stored functions, see [HELP CREATE\n PROCEDURE].\n\no For information about creating user-defined functions, see [HELP\n CREATE FUNCTION UDF].\n\nURL: https://mariadb.com/kb/en/create-function/\n\n','','https://mariadb.com/kb/en/create-function/'); -insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (212,39,'ALTER DATABASE','Syntax:\nALTER {DATABASE | SCHEMA} [db_name]\n alter_specification ...\nALTER {DATABASE | SCHEMA} db_name\n UPGRADE DATA DIRECTORY NAME\n\nalter_specification:\n [DEFAULT] CHARACTER SET [=] charset_name\n | [DEFAULT] COLLATE [=] collation_name\n\nALTER DATABASE enables you to change the overall characteristics of a\ndatabase. These characteristics are stored in the db.opt file in the\ndatabase directory. To use ALTER DATABASE, you need the ALTER privilege\non the database. ALTER SCHEMA is a synonym for ALTER DATABASE.\n\nThe database name can be omitted from the first syntax, in which case\nthe statement applies to the default database.\n\nNational Language Characteristics\n\nThe CHARACTER SET clause changes the default database character set.\nThe COLLATE clause changes the default database collation.\nhttps://mariadb.com/kb/en/data-types-character-sets-and-collations/, discusses\ncharacter set and collation names.\n\nYou can see what character sets and collations are available using,\nrespectively, the SHOW CHARACTER SET and SHOW COLLATION statements. See\n[HELP SHOW CHARACTER SET], and [HELP SHOW COLLATION], for more\ninformation.\n\nIf you change the default character set or collation for a database,\nstored routines that use the database defaults must be dropped and\nrecreated so that they use the new defaults. (In a stored routine,\nvariables with character data types use the database defaults if the\ncharacter set or collation are not specified explicitly. See [HELP\nCREATE PROCEDURE].)\n\nUpgrading from Versions Older than MySQL 5.1\n\nThe syntax that includes the UPGRADE DATA DIRECTORY NAME clause updates\nthe name of the directory associated with the database to use the\nencoding implemented in MySQL 5.1 for mapping database names to\ndatabase directory names (see\nhttps://mariadb.com/kb/en/identifier-to-file-name-mapping/). This\nclause is for use under these conditions:\n\no It is intended when upgrading MySQL to 5.1 or later from older\n versions.\n\no It is intended to update a database directory name to the current\n encoding format if the name contains special characters that need\n encoding.\n\no The statement is used by mysqlcheck (as invoked by mysql_upgrade).\n\nFor example, if a database in MySQL 5.0 has the name a-b-c, the name\ncontains instances of the - (dash) character. In MySQL 5.0, the\ndatabase directory is also named a-b-c, which is not necessarily safe\nfor all file systems. In MySQL 5.1 and later, the same database name is\nencoded as a@002db@002dc to produce a file system-neutral directory\nname.\n\nWhen a MySQL installation is upgraded to MySQL 5.1 or later from an\nolder version,the server displays a name such as a-b-c (which is in the\nold format) as #mysql50#a-b-c, and you must refer to the name using the\n#mysql50# prefix. Use UPGRADE DATA DIRECTORY NAME in this case to\nexplicitly tell the server to re-encode the database directory name to\nthe current encoding format:\n\nALTER DATABASE `#mysql50#a-b-c` UPGRADE DATA DIRECTORY NAME;\n\nAfter executing this statement, you can refer to the database as a-b-c\nwithout the special #mysql50# prefix.\n\nURL: https://mariadb.com/kb/en/alter-database/\n\n','','https://mariadb.com/kb/en/alter-database/'); -insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (213,25,'GEOMETRYN','GeometryN(gc,N)\n\nReturns the N-th geometry in the GeometryCollection value gc.\nGeometries are numbered beginning with 1.\n\nURL: https://mariadb.com/kb/en/geometryn/\n\n','MariaDB> SET @gc = \'GeometryCollection(Point(1 1),LineString(2 2, 3 3))\';\nMariaDB> SELECT AsText(GeometryN(GeomFromText(@gc),1));\n+----------------------------------------+\n| AsText(GeometryN(GeomFromText(@gc),1)) |\n+----------------------------------------+\n| POINT(1 1) |\n+----------------------------------------+\n','https://mariadb.com/kb/en/geometryn/'); -insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (214,19,'<<','Syntax:\n<<\n\nShifts a longlong (BIGINT) number to the left.\n\nURL: https://mariadb.com/kb/en/shift-left/\n\n','MariaDB> SELECT 1 << 2;\n -> 4\n','https://mariadb.com/kb/en/shift-left/'); -insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (215,26,'SHOW TABLE STATUS','Syntax:\nSHOW TABLE STATUS [{FROM | IN} db_name]\n [LIKE \'pattern\' | WHERE expr]\n\nSHOW TABLE STATUS works likes SHOW TABLES, but provides a lot of\ninformation about each non-TEMPORARY table. You can also get this list\nusing the mysqlshow --status db_name command. The LIKE clause, if\npresent, indicates which table names to match. The WHERE clause can be\ngiven to select rows using more general conditions, as discussed in\nhttps://mariadb.com/kb/en/extended-show/.\n\nURL: https://mariadb.com/kb/en/show-table-status/\n\n','','https://mariadb.com/kb/en/show-table-status/'); -insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (216,12,'MD5','Syntax:\nMD5(str)\n\nCalculates an MD5 128-bit checksum for the string. The value is\nreturned as a string of 32 hex digits, or NULL if the argument was\nNULL. The return value can, for example, be used as a hash key. See the\nnotes at the beginning of this section about storing hash values\nefficiently.\n\nAs of MySQL 5.5.3, the return value is a nonbinary string in the\nconnection character set. Before 5.5.3, the return value is a binary\nstring; see the notes at the beginning of this section about using the\nvalue as a nonbinary string.\n\nURL: https://mariadb.com/kb/en/md5/\n\n','MariaDB> SELECT MD5(\'testing\');\n -> \'ae2b1fca515949e5d54fb22b8ed95575\'\n','https://mariadb.com/kb/en/md5/'); -insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (217,18,'<','Syntax:\n<\n\nLess than:\n\nURL: https://mariadb.com/kb/en/less-than/\n\n','MariaDB> SELECT 2 < 2;\n -> 0\n','https://mariadb.com/kb/en/less-than/'); -insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (218,31,'UNIX_TIMESTAMP','Syntax:\nUNIX_TIMESTAMP(), UNIX_TIMESTAMP(date)\n\nIf called with no argument, returns a Unix timestamp (seconds since\n\'1970-01-01 00:00:00\' UTC) as an unsigned integer. If UNIX_TIMESTAMP()\nis called with a date argument, it returns the value of the argument as\nseconds since \'1970-01-01 00:00:00\' UTC. date may be a DATE string, a\nDATETIME string, a TIMESTAMP, or a number in the format YYMMDD or\nYYYYMMDD. The server interprets date as a value in the current time\nzone and converts it to an internal value in UTC. Clients can set their\ntime zone as described in\nhttps://mariadb.com/kb/en/time-zones/.\n\nURL: https://mariadb.com/kb/en/unix_timestamp/\n\n','MariaDB> SELECT UNIX_TIMESTAMP();\n -> 1196440210\nMariaDB> SELECT UNIX_TIMESTAMP(\'2007-11-30 10:30:19\');\n -> 1196440219\n','https://mariadb.com/kb/en/unix_timestamp/'); -insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (219,31,'DAYOFMONTH','Syntax:\nDAYOFMONTH(date)\n\nReturns the day of the month for date, in the range 1 to 31, or 0 for\ndates such as \'0000-00-00\' or \'2008-00-00\' that have a zero day part.\n\nURL: https://mariadb.com/kb/en/dayofmonth/\n\n','MariaDB> SELECT DAYOFMONTH(\'2007-02-03\');\n -> 3\n','https://mariadb.com/kb/en/dayofmonth/'); -insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (220,37,'ASCII','Syntax:\nASCII(str)\n\nReturns the numeric value of the leftmost character of the string str.\nReturns 0 if str is the empty string. Returns NULL if str is NULL.\nASCII() works for 8-bit characters.\n\nURL: https://mariadb.com/kb/en/ascii/\n\n','MariaDB> SELECT ASCII(\'2\');\n -> 50\nMariaDB> SELECT ASCII(2);\n -> 50\nMariaDB> SELECT ASCII(\'dx\');\n -> 100\n','https://mariadb.com/kb/en/ascii/'); -insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (221,4,'DIV','Syntax:\nDIV\n\nInteger division. Similar to FLOOR(), but is safe with BIGINT values.\n\nAs of MySQL 5.5.3, if either operand has a noninteger type, the\noperands are converted to DECIMAL and divided using DECIMAL arithmetic\nbefore converting the result to BIGINT. If the result exceeds BIGINT\nrange, an error occurs. Before MySQL 5.5.3, incorrect results may occur\nfor noninteger operands that exceed BIGINT range.\n\nURL: https://mariadb.com/kb/en/div/\n\n','MariaDB> SELECT 5 DIV 2;\n -> 2\n','https://mariadb.com/kb/en/div/'); -insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (222,10,'RENAME USER','Syntax:\nRENAME USER old_user TO new_user\n [, old_user TO new_user] ...\n\nThe RENAME USER statement renames existing MySQL accounts. To use it,\nyou must have the global CREATE USER privilege or the UPDATE privilege\nfor the mysql database. An error occurs if any old account does not\nexist or any new account exists. Each account name uses the format\ndescribed in https://mariadb.com/kb/en/create-user/#account-names.\nFor example:\n\nRENAME USER \'jeffrey\'@\'localhost\' TO \'jeff\'@\'127.0.0.1\';\n\nIf you specify only the user name part of the account name, a host name\npart of \'%\' is used.\n\nRENAME USER causes the privileges held by the old user to be those held\nby the new user. However, RENAME USER does not automatically drop or\ninvalidate databases or objects within them that the old user created.\nThis includes stored programs or views for which the DEFINER attribute\nnames the old user. Attempts to access such objects may produce an\nerror if they execute in definer security context. (For information\nabout security context, see\nhttps://mariadb.com/kb/en/stored-routine-privileges/.)\n\nThe privilege changes take effect as indicated in\nhttp://dev.mysql.com/doc/refman/5.5/en/privilege-changes.html.\n\nURL: https://mariadb.com/kb/en/rename-user/\n\n','','https://mariadb.com/kb/en/rename-user/'); -insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (223,26,'SHOW SLAVE STATUS','Syntax:\nSHOW SLAVE STATUS\n\nThis statement provides status information on essential parameters of\nthe slave threads. It requires either the SUPER or REPLICATION CLIENT\nprivilege.\n\nIf you issue this statement using the mysql client, you can use a \\G\nstatement terminator rather than a semicolon to obtain a more readable\nvertical layout:\n\nMariaDB> SHOW SLAVE STATUS\\G\n*************************** 1. row ***************************\n Slave_IO_State: Waiting for master to send event\n Master_Host: localhost\n Master_User: root\n Master_Port: 3306\n Connect_Retry: 3\n Master_Log_File: gbichot-bin.005\n Read_Master_Log_Pos: 79\n Relay_Log_File: gbichot-relay-bin.005\n Relay_Log_Pos: 548\n Relay_Master_Log_File: gbichot-bin.005\n Slave_IO_Running: Yes\n Slave_SQL_Running: Yes\n Replicate_Do_DB:\n Replicate_Ignore_DB:\n Replicate_Do_Table:\n Replicate_Ignore_Table:\n Replicate_Wild_Do_Table:\n Replicate_Wild_Ignore_Table:\n Last_Errno: 0\n Last_Error:\n Skip_Counter: 0\n Exec_Master_Log_Pos: 79\n Relay_Log_Space: 552\n Until_Condition: None\n Until_Log_File:\n Until_Log_Pos: 0\n Master_SSL_Allowed: No\n Master_SSL_CA_File:\n Master_SSL_CA_Path:\n Master_SSL_Cert:\n Master_SSL_Cipher:\n Master_SSL_Key:\n Seconds_Behind_Master: 8\nMaster_SSL_Verify_Server_Cert: No\n Last_IO_Errno: 0\n Last_IO_Error:\n Last_SQL_Errno: 0\n Last_SQL_Error:\n Replicate_Ignore_Server_Ids: 0\n Master_Server_Id: 1\n\nURL: https://mariadb.com/kb/en/show-slave-status/\n\n','','https://mariadb.com/kb/en/show-slave-status/'); -insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (224,34,'GEOMETRY','MySQL provides a standard way of creating spatial columns for geometry\ntypes, for example, with CREATE TABLE or ALTER TABLE. Currently,\nspatial columns are supported for MyISAM, Aria, InnoDB and ARCHIVE\ntables. See also the annotations about spatial indexes under [HELP\nSPATIAL].\n\nURL: https://mariadb.com/kb/en/gis-functionality/\n\n','CREATE TABLE geom (g GEOMETRY);\n','https://mariadb.com/kb/en/gis-functionality/'); -insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (225,13,'NUMPOINTS','NumPoints(ls)\n\nReturns the number of Point objects in the LineString value ls.\n\nURL: https://mariadb.com/kb/en/numpoints/\n\n','MariaDB> SET @ls = \'LineString(1 1,2 2,3 3)\';\nMariaDB> SELECT NumPoints(GeomFromText(@ls));\n+------------------------------+\n| NumPoints(GeomFromText(@ls)) |\n+------------------------------+\n| 3 |\n+------------------------------+\n','https://mariadb.com/kb/en/numpoints/'); -insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (226,39,'ALTER LOGFILE GROUP','Syntax:\nALTER LOGFILE GROUP logfile_group\n ADD UNDOFILE \'file_name\'\n [INITIAL_SIZE [=] size]\n [WAIT]\n ENGINE [=] engine_name\n\nThis statement is used with NDB cluster, which is not supported by MariaDB.\n','','https://mariadb.com/kb/en/alter-logfile-group/'); -insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (227,19,'&','Syntax:\n&\n\nBitwise AND:\n\nURL: https://mariadb.com/kb/en/bitwise_and/\n\n','MariaDB> SELECT 29 & 15;\n -> 13\n','https://mariadb.com/kb/en/bitwise_and/'); -insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (228,31,'LOCALTIMESTAMP','Syntax:\nLOCALTIMESTAMP, LOCALTIMESTAMP()\n\nLOCALTIMESTAMP and LOCALTIMESTAMP() are synonyms for NOW().\n\nURL: https://mariadb.com/kb/en/localtimestamp/\n\n','','https://mariadb.com/kb/en/localtimestamp/'); -insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (229,15,'ASSIGN-EQUAL','Syntax:\n=\n\nThis operator is used to perform value assignments in two cases,\ndescribed in the next two paragraphs.\n\nWithin a SET statement, = is treated as an assignment operator that\ncauses the user variable on the left hand side of the operator to take\non the value to its right. (In other words, when used in a SET\nstatement, = is treated identically to :=.) The value on the right hand\nside may be a literal value, another variable storing a value, or any\nlegal expression that yields a scalar value, including the result of a\nquery (provided that this value is a scalar value). You can perform\nmultiple assignments in the same SET statement.\n\nIn the SET clause of an UPDATE statement, = also acts as an assignment\noperator; in this case, however, it causes the column named on the left\nhand side of the operator to assume the value given to the right,\nprovided any WHERE conditions that are part of the UPDATE are met. You\ncan make multiple assignments in the same SET clause of an UPDATE\nstatement.\n\nIn any other context, = is treated as a comparison operator.\n\nURL: https://mariadb.com/kb/en/assignment-operators-assignment-operator/\n\n','MariaDB> SELECT @var1, @var2;\n -> NULL, NULL\nMariaDB> SELECT @var1 := 1, @var2;\n -> 1, NULL\nMariaDB> SELECT @var1, @var2;\n -> 1, NULL\nMariaDB> SELECT @var1, @var2 := @var1;\n -> 1, 1\nMariaDB> SELECT @var1, @var2;\n -> 1, 1\n','https://mariadb.com/kb/en/assignment-operators-assignment-operator/'); -insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (230,37,'CONVERT','Syntax:\nCONVERT(expr,type), CONVERT(expr USING transcoding_name)\n\nThe CONVERT() and CAST() functions take an expression of any type and\nproduce a result value of a specified type.\n\nThe type for the result can be one of the following values:\n\no BINARY[(N)]\n\no CHAR[(N)]\n\no DATE\n\no DATETIME\n\no DECIMAL[(M[,D])]\n\no SIGNED [INTEGER]\n\no TIME\n\no UNSIGNED [INTEGER]\n\nBINARY produces a string with the BINARY data type. See\nhttps://mariadb.com/kb/en/binary/ for a\ndescription of how this affects comparisons. If the optional length N\nis given, BINARY(N) causes the cast to use no more than N bytes of the\nargument. Values shorter than N bytes are padded with 0x00 bytes to a\nlength of N.\n\nCHAR(N) causes the cast to use no more than N characters of the\nargument.\n\nCAST() and CONVERT(... USING ...) are standard SQL syntax. The\nnon-USING form of CONVERT() is ODBC syntax.\n\nCONVERT() with USING is used to convert data between different\ncharacter sets. In MySQL, transcoding names are the same as the\ncorresponding character set names. For example, this statement converts\nthe string \'abc\' in the default character set to the corresponding\nstring in the utf8 character set:\n\nSELECT CONVERT(\'abc\' USING utf8);\n\nURL: https://mariadb.com/kb/en/convert/\n\n','SELECT enum_col FROM tbl_name ORDER BY CAST(enum_col AS CHAR);\n','https://mariadb.com/kb/en/convert/'); -insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (231,31,'ADDDATE','Syntax:\nADDDATE(date,INTERVAL expr unit), ADDDATE(expr,days)\n\nWhen invoked with the INTERVAL form of the second argument, ADDDATE()\nis a synonym for DATE_ADD(). The related function SUBDATE() is a\nsynonym for DATE_SUB(). For information on the INTERVAL unit argument,\nsee the discussion for DATE_ADD().\n\nMariaDB> SELECT DATE_ADD(\'2008-01-02\', INTERVAL 31 DAY);\n -> \'2008-02-02\'\nMariaDB> SELECT ADDDATE(\'2008-01-02\', INTERVAL 31 DAY);\n -> \'2008-02-02\'\n\nWhen invoked with the days form of the second argument, MySQL treats it\nas an integer number of days to be added to expr.\n\nURL: https://mariadb.com/kb/en/adddate/\n\n','MariaDB> SELECT ADDDATE(\'2008-01-02\', 31);\n -> \'2008-02-02\'\n','https://mariadb.com/kb/en/adddate/'); -insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (232,23,'REPEAT LOOP','Syntax:\n[begin_label:] REPEAT\n statement_list\nUNTIL search_condition\nEND REPEAT [end_label]\n\nThe statement list within a REPEAT statement is repeated until the\nsearch_condition expression is true. Thus, a REPEAT always enters the\nloop at least once. statement_list consists of one or more statements,\neach terminated by a semicolon (;) statement delimiter.\n\nA REPEAT statement can be labeled. For the rules regarding label use,\nsee [HELP labels].\n\nURL: https://mariadb.com/kb/en/repeat-loop/\n\n','MariaDB> delimiter //\n\nMariaDB> CREATE PROCEDURE dorepeat(p1 INT)\n -> BEGIN\n -> SET @x = 0;\n -> REPEAT\n -> SET @x = @x + 1;\n -> UNTIL @x > p1 END REPEAT;\n -> END\n -> //\nQuery OK, 0 rows affected (0.00 sec)\n\nMariaDB> CALL dorepeat(1000)//\nQuery OK, 0 rows affected (0.00 sec)\n\nMariaDB> SELECT @x//\n+------+\n| @x |\n+------+\n| 1001 |\n+------+\n1 row in set (0.00 sec)\n','https://mariadb.com/kb/en/repeat-loop/'); -insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (233,39,'ALTER FUNCTION','Syntax:\nALTER FUNCTION func_name [characteristic ...]\n\ncharacteristic:\n COMMENT \'string\'\n | LANGUAGE SQL\n | { CONTAINS SQL | NO SQL | READS SQL DATA | MODIFIES SQL DATA }\n | SQL SECURITY { DEFINER | INVOKER }\n\nThis statement can be used to change the characteristics of a stored\nfunction. More than one change may be specified in an ALTER FUNCTION\nstatement. However, you cannot change the parameters or body of a\nstored function using this statement; to make such changes, you must\ndrop and re-create the function using DROP FUNCTION and CREATE\nFUNCTION.\n\nYou must have the ALTER ROUTINE privilege for the function. (That\nprivilege is granted automatically to the function creator.) If binary\nlogging is enabled, the ALTER FUNCTION statement might also require the\nSUPER privilege, as described in\nhttps://mariadb.com/kb/en/binary-logging-of-stored-routines/.\n\nURL: https://mariadb.com/kb/en/alter-function/\n\n','','https://mariadb.com/kb/en/alter-function/'); -insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (234,22,'SMALLINT','SMALLINT[(M)] [UNSIGNED] [ZEROFILL]\n\nA small integer. The signed range is -32768 to 32767. The unsigned\nrange is 0 to 65535.\n\nURL: https://mariadb.com/kb/en/smallint/\n\n','','https://mariadb.com/kb/en/smallint/'); -insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (235,22,'DOUBLE PRECISION','DOUBLE PRECISION[(M,D)] [UNSIGNED] [ZEROFILL], REAL[(M,D)] [UNSIGNED]\n[ZEROFILL]\n\nThese types are synonyms for DOUBLE. Exception: If the REAL_AS_FLOAT\nSQL mode is enabled, REAL is a synonym for FLOAT rather than DOUBLE.\n\nURL: https://mariadb.com/kb/en/double-precision/\n\n','','https://mariadb.com/kb/en/double-precision/'); -insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (236,37,'ORD','Syntax:\nORD(str)\n\nIf the leftmost character of the string str is a multi-byte character,\nreturns the code for that character, calculated from the numeric values\nof its constituent bytes using this formula:\n\n (1st byte code)\n+ (2nd byte code * 256)\n+ (3rd byte code * 2562) ...\n\nIf the leftmost character is not a multi-byte character, ORD() returns\nthe same value as the ASCII() function.\n\nURL: https://mariadb.com/kb/en/ord/\n\n','MariaDB> SELECT ORD(\'2\');\n -> 50\n','https://mariadb.com/kb/en/ord/'); -insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (237,8,'DEALLOCATE PREPARE','Syntax:\n{DEALLOCATE | DROP} PREPARE stmt_name\n\nTo deallocate a prepared statement produced with PREPARE, use a\nDEALLOCATE PREPARE statement that refers to the prepared statement\nname. Attempting to execute a prepared statement after deallocating it\nresults in an error.\n\nURL: https://mariadb.com/kb/en/deallocate-drop-prepared-statement/\n\n','','https://mariadb.com/kb/en/deallocate-drop-prepared-statement/'); -insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (238,36,'ENVELOPE','Envelope(g)\n\nReturns the Minimum Bounding Rectangle (MBR) for the geometry value g.\nThe result is returned as a Polygon value.\n\nThe polygon is defined by the corner points of the bounding box:\n\nPOLYGON((MINX MINY, MAXX MINY, MAXX MAXY, MINX MAXY, MINX MINY))\n\nURL: https://mariadb.com/kb/en/envelope/\n\n','MariaDB> SELECT AsText(Envelope(GeomFromText(\'LineString(1 1,2 2)\')));\n+-------------------------------------------------------+\n| AsText(Envelope(GeomFromText(\'LineString(1 1,2 2)\'))) |\n+-------------------------------------------------------+\n| POLYGON((1 1,2 1,2 2,1 2,1 1)) |\n+-------------------------------------------------------+\n','https://mariadb.com/kb/en/envelope/'); -insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (239,14,'IS_FREE_LOCK','Syntax:\nIS_FREE_LOCK(str)\n\nChecks whether the lock named str is free to use (that is, not locked).\nReturns 1 if the lock is free (no one is using the lock), 0 if the lock\nis in use, and NULL if an error occurs (such as an incorrect argument).\n\nURL: https://mariadb.com/kb/en/is_free_lock/\n\n','','https://mariadb.com/kb/en/is_free_lock/'); -insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (240,30,'TOUCHES','Touches(g1,g2)\n\nReturns 1 or 0 to indicate whether g1 spatially touches g2. Two\ngeometries spatially touch if the interiors of the geometries do not\nintersect, but the boundary of one of the geometries intersects either\nthe boundary or the interior of the other.\n\nURL: https://mariadb.com/kb/en/touches/\n\n','','https://mariadb.com/kb/en/touches/'); -insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (241,14,'INET_ATON','Syntax:\nINET_ATON(expr)\n\nGiven the dotted-quad representation of an IPv4 network address as a\nstring, returns an integer that represents the numeric value of the\naddress in network byte order (big endian). INET_ATON() returns NULL if\nit does not understand its argument.\n\nURL: https://mariadb.com/kb/en/inet_aton/\n\n','MariaDB> SELECT INET_ATON(\'10.0.5.9\');\n -> 167773449\n','https://mariadb.com/kb/en/inet_aton/'); -insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (242,12,'UNCOMPRESS','Syntax:\nUNCOMPRESS(string_to_uncompress)\n\nUncompresses a string compressed by the COMPRESS() function. If the\nargument is not a compressed value, the result is NULL. This function\nrequires MySQL to have been compiled with a compression library such as\nzlib. Otherwise, the return value is always NULL.\n\nURL: https://mariadb.com/kb/en/uncompress/\n\n','MariaDB> SELECT UNCOMPRESS(COMPRESS(\'any string\'));\n -> \'any string\'\nMariaDB> SELECT UNCOMPRESS(\'any string\');\n -> NULL\n','https://mariadb.com/kb/en/uncompress/'); -insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (243,22,'AUTO_INCREMENT','The AUTO_INCREMENT attribute can be used to generate a unique identity\nfor new rows:\n\nURL: https://mariadb.com/kb/en/auto_increment/\n\n','CREATE TABLE animals (\n id MEDIUMINT NOT NULL AUTO_INCREMENT,\n name CHAR(30) NOT NULL,\n PRIMARY KEY (id)\n);\n\nINSERT INTO animals (name) VALUES\n (\'dog\'),(\'cat\'),(\'penguin\'),\n (\'lax\'),(\'whale\'),(\'ostrich\');\n\nSELECT * FROM animals;\n','https://mariadb.com/kb/en/auto_increment/'); -insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (244,36,'ISSIMPLE','IsSimple(g)\n\nCurrently, this function is a placeholder and should not be used. If\nimplemented, its behavior will be as described in the next paragraph.\n\nReturns 1 if the geometry value g has no anomalous geometric points,\nsuch as self-intersection or self-tangency. IsSimple() returns 0 if the\nargument is not simple, and -1 if it is NULL.\n\nThe description of each instantiable geometric class given earlier in\nthe chapter includes the specific conditions that cause an instance of\nthat class to be classified as not simple. (See [HELP Geometry\nhierarchy].)\n\nURL: https://mariadb.com/kb/en/issimple/\n\n','','https://mariadb.com/kb/en/issimple/'); -insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (245,4,'- BINARY','Syntax:\n-\n\nSubtraction:\n\nURL: https://mariadb.com/kb/en/subtraction-operator-/\n\n','MariaDB> SELECT 3-5;\n -> -2\n','https://mariadb.com/kb/en/subtraction-operator-/'); -insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (246,3,'GEOMCOLLFROMTEXT','GeomCollFromText(wkt[,srid]), GeometryCollectionFromText(wkt[,srid])\n\nConstructs a GEOMETRYCOLLECTION value using its WKT representation and\nSRID.\n\nURL: https://mariadb.com/kb/en/geomcollfromtext/\n\n','','https://mariadb.com/kb/en/geomcollfromtext/'); -insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (247,3,'WKT DEFINITION','The Well-Known Text (WKT) representation of Geometry is designed to\nexchange geometry data in ASCII form. For a Backus-Naur grammar that\nspecifies the formal production rules for writing WKT values, see the\nOpenGIS specification document referenced in\nhttps://mariadb.com/kb/en/gis-resources/.\n\nURL: https://mariadb.com/kb/en/wkt-definition/\n\n','','https://mariadb.com/kb/en/wkt-definition/'); -insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (248,31,'CURRENT_TIME','Syntax:\nCURRENT_TIME, CURRENT_TIME()\n\nCURRENT_TIME and CURRENT_TIME() are synonyms for CURTIME().\n\nURL: https://mariadb.com/kb/en/current_time/\n\n','','https://mariadb.com/kb/en/current_time/'); -insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (249,10,'REVOKE','Syntax:\nREVOKE\n priv_type [(column_list)]\n [, priv_type [(column_list)]] ...\n ON [object_type] priv_level\n FROM user [, user] ...\n\nREVOKE ALL PRIVILEGES, GRANT OPTION\n FROM user [, user] ...\n\nREVOKE PROXY ON user\n FROM user [, user] ...\n\nThe REVOKE statement enables system administrators to revoke privileges\nfrom MySQL accounts. Each account name uses the format described in\nhttps://mariadb.com/kb/en/create-user#account-names. For example:\n\nREVOKE INSERT ON *.* FROM \'jeffrey\'@\'localhost\';\n\nIf you specify only the user name part of the account name, a host name\npart of \'%\' is used.\n\nFor details on the levels at which privileges exist, the permissible\npriv_type and priv_level values, and the syntax for specifying users\nand passwords, see [HELP GRANT]\n\nTo use the first REVOKE syntax, you must have the GRANT OPTION\nprivilege, and you must have the privileges that you are revoking.\n\nTo revoke all privileges, use the second syntax, which drops all\nglobal, database, table, column, and routine privileges for the named\nuser or users:\n\nREVOKE ALL PRIVILEGES, GRANT OPTION FROM user [, user] ...\n\nTo use this REVOKE syntax, you must have the global CREATE USER\nprivilege or the UPDATE privilege for the mysql database.\n\nURL: https://mariadb.com/kb/en/revoke/\n\n','','https://mariadb.com/kb/en/revoke/'); -insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (250,17,'LAST_INSERT_ID','Syntax:\nLAST_INSERT_ID(), LAST_INSERT_ID(expr)\n\nLAST_INSERT_ID() (with no argument) returns a BIGINT (64-bit) value\nrepresenting the first automatically generated value successfully\ninserted for an AUTO_INCREMENT column as a result of the most recently\nexecuted INSERT statement. The value of LAST_INSERT_ID() remains\nunchanged if no rows are successfully inserted.\n\nFor example, after inserting a row that generates an AUTO_INCREMENT\nvalue, you can get the value like this:\n\nMariaDB> SELECT LAST_INSERT_ID();\n -> 195\n\nThe currently executing statement does not affect the value of\nLAST_INSERT_ID(). Suppose that you generate an AUTO_INCREMENT value\nwith one statement, and then refer to LAST_INSERT_ID() in a\nmultiple-row INSERT statement that inserts rows into a table with its\nown AUTO_INCREMENT column. The value of LAST_INSERT_ID() will remain\nstable in the second statement; its value for the second and later rows\nis not affected by the earlier row insertions. (However, if you mix\nreferences to LAST_INSERT_ID() and LAST_INSERT_ID(expr), the effect is\nundefined.)\n\nIf the previous statement returned an error, the value of\nLAST_INSERT_ID() is undefined. For transactional tables, if the\nstatement is rolled back due to an error, the value of LAST_INSERT_ID()\nis left undefined. For manual ROLLBACK, the value of LAST_INSERT_ID()\nis not restored to that before the transaction; it remains as it was at\nthe point of the ROLLBACK.\n\nWithin the body of a stored routine (procedure or function) or a\ntrigger, the value of LAST_INSERT_ID() changes the same way as for\nstatements executed outside the body of these kinds of objects. The\neffect of a stored routine or trigger upon the value of\nLAST_INSERT_ID() that is seen by following statements depends on the\nkind of routine:\n\no If a stored procedure executes statements that change the value of\n LAST_INSERT_ID(), the changed value is seen by statements that follow\n the procedure call.\n\no For stored functions and triggers that change the value, the value is\n restored when the function or trigger ends, so following statements\n will not see a changed value.\n\nURL: https://mariadb.com/kb/en/last_insert_id/\n\n','','https://mariadb.com/kb/en/last_insert_id/'); -insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (251,31,'LAST_DAY','Syntax:\nLAST_DAY(date)\n\nTakes a date or datetime value and returns the corresponding value for\nthe last day of the month. Returns NULL if the argument is invalid.\n\nURL: https://mariadb.com/kb/en/last_day/\n\n','MariaDB> SELECT LAST_DAY(\'2003-02-05\');\n -> \'2003-02-28\'\nMariaDB> SELECT LAST_DAY(\'2004-02-05\');\n -> \'2004-02-29\'\nMariaDB> SELECT LAST_DAY(\'2004-01-01 01:01:01\');\n -> \'2004-01-31\'\nMariaDB> SELECT LAST_DAY(\'2003-03-32\');\n -> NULL\n','https://mariadb.com/kb/en/last_day/'); -insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (252,22,'MEDIUMINT','MEDIUMINT[(M)] [UNSIGNED] [ZEROFILL]\n\nA medium-sized integer. The signed range is -8388608 to 8388607. The\nunsigned range is 0 to 16777215.\n\nURL: https://mariadb.com/kb/en/mediumint/\n\n','','https://mariadb.com/kb/en/mediumint/'); -insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (253,4,'FLOOR','Syntax:\nFLOOR(X)\n\nReturns the largest integer value not greater than X.\n\nURL: https://mariadb.com/kb/en/floor/\n\n','MariaDB> SELECT FLOOR(1.23);\n -> 1\nMariaDB> SELECT FLOOR(-1.23);\n -> -2\n','https://mariadb.com/kb/en/floor/'); -insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (254,37,'RTRIM','Syntax:\nRTRIM(str)\n\nReturns the string str with trailing space characters removed.\n\nURL: https://mariadb.com/kb/en/rtrim/\n\n','MariaDB> SELECT RTRIM(\'barbar \');\n -> \'barbar\'\n','https://mariadb.com/kb/en/rtrim/'); -insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (255,28,'EXPLAIN','Syntax:\nEXPLAIN [explain_type] SELECT select_options\n\nexplain_type:\n EXTENDED\n | PARTITIONS\n\nOr:\n\nEXPLAIN tbl_name\n\nThe EXPLAIN statement can be used either as a way to obtain information\nabout how MySQL executes a statement, or as a synonym for DESCRIBE:\n\no When you precede a SELECT statement with the keyword EXPLAIN, MySQL\n displays information from the optimizer about the query execution\n plan. That is, MySQL explains how it would process the statement,\n including information about how tables are joined and in which order.\n EXPLAIN EXTENDED can be used to obtain additional information.\n\n For information about using EXPLAIN and EXPLAIN EXTENDED to obtain\n query execution plan information, see\n https://mariadb.com/kb/en/explain/.\n\no EXPLAIN PARTITIONS is useful only when examining queries involving\n partitioned tables. For details, see\n http://dev.mysql.com/doc/refman/5.5/en/partitioning-info.html.\n\no EXPLAIN tbl_name is synonymous with DESCRIBE tbl_name or SHOW COLUMNS\n FROM tbl_name. For information about DESCRIBE and SHOW COLUMNS, see\n [HELP DESCRIBE], and [HELP SHOW COLUMNS].\n\nURL: https://mariadb.com/kb/en/explain/\n\n','','https://mariadb.com/kb/en/explain/'); -insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (256,4,'DEGREES','Syntax:\nDEGREES(X)\n\nReturns the argument X, converted from radians to degrees.\n\nURL: https://mariadb.com/kb/en/degrees/\n\n','MariaDB> SELECT DEGREES(PI());\n -> 180\nMariaDB> SELECT DEGREES(PI() / 2);\n -> 90\n','https://mariadb.com/kb/en/degrees/'); -insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (257,22,'VARCHAR','[NATIONAL] VARCHAR(M) [CHARACTER SET charset_name] [COLLATE\ncollation_name]\n\nA variable-length string. M represents the maximum column length in\ncharacters. The range of M is 0 to 65,535. The effective maximum length\nof a VARCHAR is subject to the maximum row size (65,535 bytes, which is\nshared among all columns) and the character set used. For example, utf8\ncharacters can require up to three bytes per character, so a VARCHAR\ncolumn that uses the utf8 character set can be declared to be a maximum\nof 21,844 characters. See\nhttp://dev.mysql.com/doc/refman/5.5/en/column-count-limit.html.\n\nMySQL stores VARCHAR values as a 1-byte or 2-byte length prefix plus\ndata. The length prefix indicates the number of bytes in the value. A\nVARCHAR column uses one length byte if values require no more than 255\nbytes, two length bytes if values may require more than 255 bytes.\n\n*Note*: MySQL 5.5 follows the standard SQL specification, and does not\nremove trailing spaces from VARCHAR values.\n\nVARCHAR is shorthand for CHARACTER VARYING. NATIONAL VARCHAR is the\nstandard SQL way to define that a VARCHAR column should use some\npredefined character set. MySQL 4.1 and up uses utf8 as this predefined\ncharacter set.\nhttps://mariadb.com/kb/en/varchar/. NVARCHAR\nis shorthand for NATIONAL VARCHAR.\n\nURL: https://mariadb.com/kb/en/varchar/\n\n','','https://mariadb.com/kb/en/varchar/'); -insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (258,37,'UNHEX','Syntax:\n\nUNHEX(str)\n\nFor a string argument str, UNHEX(str) performs the inverse operation of\nHEX(str). That is, it interprets each pair of characters in the\nargument as a hexadecimal number and converts it to the character\nrepresented by the number. The return value is a binary string.\n\nURL: https://mariadb.com/kb/en/unhex/\n\n','MariaDB> SELECT UNHEX(\'4D7953514C\');\n -> \'MySQL\'\nMariaDB> SELECT 0x4D7953514C;\n -> \'MySQL\'\nMariaDB> SELECT UNHEX(HEX(\'string\'));\n -> \'string\'\nMariaDB> SELECT HEX(UNHEX(\'1267\'));\n -> \'1267\'\n','https://mariadb.com/kb/en/unhex/'); -insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (259,4,'- UNARY','Syntax:\n-\n\nUnary minus. This operator changes the sign of the operand.\n\nURL: https://mariadb.com/kb/en/subtraction-operator-/\n\n','MariaDB> SELECT - 2;\n -> -2\n','https://mariadb.com/kb/en/subtraction-operator-/'); -insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (260,16,'STD','Syntax:\nSTD(expr)\n\nReturns the population standard deviation of expr. This is an extension\nto standard SQL. The standard SQL function STDDEV_POP() can be used\ninstead.\n\nThis function returns NULL if there were no matching rows.\n\nURL: https://mariadb.com/kb/en/std/\n\n','','https://mariadb.com/kb/en/std/'); -insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (261,4,'COS','Syntax:\nCOS(X)\n\nReturns the cosine of X, where X is given in radians.\n\nURL: https://mariadb.com/kb/en/cos/\n\n','MariaDB> SELECT COS(PI());\n -> -1\n','https://mariadb.com/kb/en/cos/'); -insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (262,31,'DATE FUNCTION','Syntax:\nDATE(expr)\n\nExtracts the date part of the date or datetime expression expr.\n\nURL: https://mariadb.com/kb/en/date-function/\n\n','MariaDB> SELECT DATE(\'2003-12-31 01:02:03\');\n -> \'2003-12-31\'\n','https://mariadb.com/kb/en/date-function/'); -insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (263,39,'DROP TRIGGER','Syntax:\nDROP TRIGGER [IF EXISTS] [schema_name.]trigger_name\n\nThis statement drops a trigger. The schema (database) name is optional.\nIf the schema is omitted, the trigger is dropped from the default\nschema. DROP TRIGGER requires the TRIGGER privilege for the table\nassociated with the trigger.\n\nUse IF EXISTS to prevent an error from occurring for a trigger that\ndoes not exist. A NOTE is generated for a nonexistent trigger when\nusing IF EXISTS. See [HELP SHOW WARNINGS].\n\nTriggers for a table are also dropped if you drop the table.\n\nURL: https://mariadb.com/kb/en/drop-trigger/\n\n','','https://mariadb.com/kb/en/drop-trigger/'); -insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (264,8,'RESET MASTER','Syntax:\nRESET MASTER\n\nDeletes all binary log files listed in the index file, resets the\nbinary log index file to be empty, and creates a new binary log file.\nThis statement is intended to be used only when the master is started\nfor the first time.\n\nURL: https://mariadb.com/kb/en/reset-master/\n\n','','https://mariadb.com/kb/en/reset-master/'); -insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (265,4,'TAN','Syntax:\nTAN(X)\n\nReturns the tangent of X, where X is given in radians.\n\nURL: https://mariadb.com/kb/en/tan/\n\n','MariaDB> SELECT TAN(PI());\n -> -1.2246063538224e-16\nMariaDB> SELECT TAN(PI()+1);\n -> 1.5574077246549\n','https://mariadb.com/kb/en/tan/'); -insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (266,4,'PI','Syntax:\nPI()\n\nReturns the value of π (pi). The default number of decimal places\ndisplayed is seven, but MySQL uses the full double-precision value\ninternally.\n\nURL: https://mariadb.com/kb/en/pi/\n\n','MariaDB> SELECT PI();\n -> 3.141593\nMariaDB> SELECT PI()+0.000000000000000000;\n -> 3.141592653589793116\n','https://mariadb.com/kb/en/pi/'); -insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (267,31,'WEEKOFYEAR','Syntax:\nWEEKOFYEAR(date)\n\nReturns the calendar week of the date as a number in the range from 1\nto 53. WEEKOFYEAR() is a compatibility function that is equivalent to\nWEEK(date,3).\n\nURL: https://mariadb.com/kb/en/weekofyear/\n\n','MariaDB> SELECT WEEKOFYEAR(\'2008-02-20\');\n -> 8\n','https://mariadb.com/kb/en/weekofyear/'); -insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (268,4,'/','Syntax:\n/\n\nDivision:\n\nURL: https://mariadb.com/kb/en/division-operator/\n\n','MariaDB> SELECT 3/5;\n -> 0.60\n','https://mariadb.com/kb/en/division-operator/'); -insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (269,8,'PURGE BINARY LOGS','Syntax:\nPURGE { BINARY | MASTER } LOGS\n { TO \'log_name\' | BEFORE datetime_expr }\n\nThe binary log is a set of files that contain information about data\nmodifications made by the MySQL server. The log consists of a set of\nbinary log files, plus an index file (see\nhttps://mariadb.com/kb/en/overview-of-the-binary-log/).\n\nThe PURGE BINARY LOGS statement deletes all the binary log files listed\nin the log index file prior to the specified log file name or date.\nBINARY and MASTER are synonyms. Deleted log files also are removed from\nthe list recorded in the index file, so that the given log file becomes\nthe first in the list.\n\nThis statement has no effect if the server was not started with the\n--log-bin option to enable binary logging.\n\nURL: https://mariadb.com/kb/en/sql-commands-purge-logs/\n\n','PURGE BINARY LOGS TO \'mysql-bin.010\';\nPURGE BINARY LOGS BEFORE \'2008-04-02 22:46:26\';\n','https://mariadb.com/kb/en/sql-commands-purge-logs/'); -insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (270,16,'STDDEV_SAMP','Syntax:\nSTDDEV_SAMP(expr)\n\nReturns the sample standard deviation of expr (the square root of\nVAR_SAMP().\n\nSTDDEV_SAMP() returns NULL if there were no matching rows.\n\nURL: https://mariadb.com/kb/en/stddev_samp/\n\n','','https://mariadb.com/kb/en/stddev_samp/'); -insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (271,17,'SCHEMA','Syntax:\nSCHEMA()\n\nThis function is a synonym for DATABASE().\n\nURL: https://mariadb.com/kb/en/schema/\n\n','','https://mariadb.com/kb/en/schema/'); -insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (272,32,'MLINEFROMWKB','MLineFromWKB(wkb[,srid]), MultiLineStringFromWKB(wkb[,srid])\n\nConstructs a MULTILINESTRING value using its WKB representation and\nSRID.\n\nURL: https://mariadb.com/kb/en/mlinefromwkb/\n\n','','https://mariadb.com/kb/en/mlinefromwkb/'); -insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (273,4,'LOG2','Syntax:\nLOG2(X)\n\nReturns the base-2 logarithm of X.\n\nURL: https://mariadb.com/kb/en/log2/\n\n','MariaDB> SELECT LOG2(65536);\n -> 16\nMariaDB> SELECT LOG2(-100);\n -> NULL\n','https://mariadb.com/kb/en/log2/'); -insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (274,31,'SUBTIME','Syntax:\nSUBTIME(expr1,expr2)\n\nSUBTIME() returns expr1 - expr2 expressed as a value in the same format\nas expr1. expr1 is a time or datetime expression, and expr2 is a time\nexpression.\n\nURL: https://mariadb.com/kb/en/subtime/\n\n','MariaDB> SELECT SUBTIME(\'2007-12-31 23:59:59.999999\',\'1 1:1:1.000002\');\n -> \'2007-12-30 22:58:58.999997\'\nMariaDB> SELECT SUBTIME(\'01:00:00.999999\', \'02:00:00.999998\');\n -> \'-00:59:59.999999\'\n','https://mariadb.com/kb/en/subtime/'); -insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (275,12,'UNCOMPRESSED_LENGTH','Syntax:\nUNCOMPRESSED_LENGTH(compressed_string)\n\nReturns the length that the compressed string had before being\ncompressed.\n\nURL: https://mariadb.com/kb/en/uncompressed_length/\n\n','MariaDB> SELECT UNCOMPRESSED_LENGTH(COMPRESS(REPEAT(\'a\',30)));\n -> 30\n','https://mariadb.com/kb/en/uncompressed_length/'); -insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (276,39,'DROP TABLE','Syntax:\nDROP [TEMPORARY] TABLE [IF EXISTS]\n tbl_name [, tbl_name] ...\n [RESTRICT | CASCADE]\n\nDROP TABLE removes one or more tables. You must have the DROP privilege\nfor each table. All table data and the table definition are removed, so\nbe careful with this statement! If any of the tables named in the\nargument list do not exist, MySQL returns an error indicating by name\nwhich nonexisting tables it was unable to drop, but it also drops all\nof the tables in the list that do exist.\n\n*Important*: When a table is dropped, user privileges on the table are\nnot automatically dropped. See [HELP GRANT].\n\nNote that for a partitioned table, DROP TABLE permanently removes the\ntable definition, all of its partitions, and all of the data which was\nstored in those partitions. It also removes the partitioning definition\n(.par) file associated with the dropped table.\n\nUse IF EXISTS to prevent an error from occurring for tables that do not\nexist. A NOTE is generated for each nonexistent table when using IF\nEXISTS. See [HELP SHOW WARNINGS].\n\nRESTRICT and CASCADE are permitted to make porting easier. In MySQL\n5.5, they do nothing.\n\n*Note*: DROP TABLE automatically commits the current active\ntransaction, unless you use the TEMPORARY keyword.\n\nURL: https://mariadb.com/kb/en/drop-table/\n\n','','https://mariadb.com/kb/en/drop-table/'); -insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (277,4,'POW','Syntax:\nPOW(X,Y)\n\nReturns the value of X raised to the power of Y.\n\nURL: https://mariadb.com/kb/en/pow/\n\n','MariaDB> SELECT POW(2,2);\n -> 4\nMariaDB> SELECT POW(2,-2);\n -> 0.25\n','https://mariadb.com/kb/en/pow/'); -insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (278,26,'SHOW CREATE TABLE','Syntax:\nSHOW CREATE TABLE tbl_name\n\nShows the CREATE TABLE statement that creates the given table. To use\nthis statement, you must have some privilege for the table. This\nstatement also works with views.\nSHOW CREATE TABLE quotes table and column names according to the value\nof the sql_quote_show_create option. See\nhttps://mariadb.com/kb/en/server-system-variables/.\n\nURL: https://mariadb.com/kb/en/show-create-table/\n\n','MariaDB> SHOW CREATE TABLE t\\G\n*************************** 1. row ***************************\n Table: t\nCreate Table: CREATE TABLE t (\n id INT(11) default NULL auto_increment,\n s char(60) default NULL,\n PRIMARY KEY (id)\n) ENGINE=MyISAM\n','https://mariadb.com/kb/en/show-create-table/'); -insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (279,27,'DUAL','You are permitted to specify DUAL as a dummy table name in situations\nwhere no tables are referenced:\n\nMariaDB> SELECT 1 + 1 FROM DUAL;\n -> 2\n\nDUAL is purely for the convenience of people who require that all\nSELECT statements should have FROM and possibly other clauses. MySQL\nmay ignore the clauses. MySQL does not require FROM DUAL if no tables\nare referenced.\n\nURL: https://mariadb.com/kb/en/dual/\n\n','','https://mariadb.com/kb/en/dual/'); -insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (280,37,'INSTR','Syntax:\nINSTR(str,substr)\n\nReturns the position of the first occurrence of substring substr in\nstring str. This is the same as the two-argument form of LOCATE(),\nexcept that the order of the arguments is reversed.\n\nURL: https://mariadb.com/kb/en/instr/\n\n','MariaDB> SELECT INSTR(\'foobarbar\', \'bar\');\n -> 4\nMariaDB> SELECT INSTR(\'xbar\', \'foobar\');\n -> 0\n','https://mariadb.com/kb/en/instr/'); -insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (281,31,'NOW','Syntax:\nNOW()\n\nReturns the current date and time as a value in \'YYYY-MM-DD HH:MM:SS\'\nor YYYYMMDDHHMMSS.uuuuuu format, depending on whether the function is\nused in a string or numeric context. The value is expressed in the\ncurrent time zone.\n\nURL: https://mariadb.com/kb/en/now/\n\n','MariaDB> SELECT NOW();\n -> \'2007-12-15 23:50:26\'\nMariaDB> SELECT NOW() + 0;\n -> 20071215235026.000000\n','https://mariadb.com/kb/en/now/'); -insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (282,26,'SHOW ENGINES','Syntax:\nSHOW [STORAGE] ENGINES\n\nSHOW ENGINES displays status information about the server\'s storage\nengines. This is particularly useful for checking whether a storage\nengine is supported, or to see what the default engine is.\n\nURL: https://mariadb.com/kb/en/show-engines/\n\n','','https://mariadb.com/kb/en/show-engines/'); -insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (283,18,'>=','Syntax:\n>=\n\nGreater than or equal:\n\nURL: https://mariadb.com/kb/en/greater-than-or-equal/\n\n','MariaDB> SELECT 2 >= 2;\n -> 1\n','https://mariadb.com/kb/en/greater-than-or-equal/'); -insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (284,4,'EXP','Syntax:\nEXP(X)\n\nReturns the value of e (the base of natural logarithms) raised to the\npower of X. The inverse of this function is LOG() (using a single\nargument only) or LN().\n\nURL: https://mariadb.com/kb/en/exp/\n\n','MariaDB> SELECT EXP(2);\n -> 7.3890560989307\nMariaDB> SELECT EXP(-2);\n -> 0.13533528323661\nMariaDB> SELECT EXP(0);\n -> 1\n','https://mariadb.com/kb/en/exp/'); -insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (285,22,'LONGBLOB','LONGBLOB\n\nA BLOB column with a maximum length of 4,294,967,295 or 4GB (232 - 1)\nbytes. The effective maximum length of LONGBLOB columns depends on the\nconfigured maximum packet size in the client/server protocol and\navailable memory. Each LONGBLOB value is stored using a 4-byte length\nprefix that indicates the number of bytes in the value.\n\nURL: https://mariadb.com/kb/en/longblob/\n\n','','https://mariadb.com/kb/en/longblob/'); -insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (286,13,'POINTN','PointN(ls,N)\n\nReturns the N-th Point in the Linestring value ls. Points are numbered\nbeginning with 1.\n\nURL: https://mariadb.com/kb/en/pointn/\n\n','MariaDB> SET @ls = \'LineString(1 1,2 2,3 3)\';\nMariaDB> SELECT AsText(PointN(GeomFromText(@ls),2));\n+-------------------------------------+\n| AsText(PointN(GeomFromText(@ls),2)) |\n+-------------------------------------+\n| POINT(2 2) |\n+-------------------------------------+\n','https://mariadb.com/kb/en/pointn/'); -insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (287,22,'YEAR DATA TYPE','YEAR[(2|4)]\n\nA year in two-digit or four-digit format. The default is four-digit\nformat. YEAR(2) or YEAR(4) differ in display format, but have the same\nrange of values. In four-digit format, values display as 1901 to 2155,\nand 0000. In two-digit format, values display as 70 to 69, representing\nyears from 1970 to 2069. MySQL displays YEAR values in YYYY or\nYYformat, but permits assignment of values to YEAR columns using either\nstrings or numbers.\n\n*Note*: The YEAR(2) data type has certain issues that you should\nconsider before choosing to use it. As of MySQL 5.5.27, YEAR(2) is\ndeprecated. For more information, see\nhttp://dev.mysql.com/doc/refman/5.5/en/migrating-to-year4.html.\n\nFor additional information about YEAR display format and inerpretation\nof input values, see https://mariadb.com/kb/en/year-data-type/.\n\nURL: https://mariadb.com/kb/en/year-data-type/\n\n','','https://mariadb.com/kb/en/year-data-type/'); -insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (288,16,'SUM','Syntax:\nSUM([DISTINCT] expr)\n\nReturns the sum of expr. If the return set has no rows, SUM() returns\nNULL. The DISTINCT keyword can be used to sum only the distinct values\nof expr.\n\nSUM() returns NULL if there were no matching rows.\n\nURL: https://mariadb.com/kb/en/sum/\n\n','','https://mariadb.com/kb/en/sum/'); -insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (289,37,'OCT','Syntax:\nOCT(N)\n\nReturns a string representation of the octal value of N, where N is a\nlonglong (BIGINT) number. This is equivalent to CONV(N,10,8). Returns\nNULL if N is NULL.\n\nURL: https://mariadb.com/kb/en/oct/\n\n','MariaDB> SELECT OCT(12);\n -> \'14\'\n','https://mariadb.com/kb/en/oct/'); -insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (290,31,'SYSDATE','Syntax:\nSYSDATE()\n\nReturns the current date and time as a value in \'YYYY-MM-DD HH:MM:SS\'\nor YYYYMMDDHHMMSS.uuuuuu format, depending on whether the function is\nused in a string or numeric context.\n\nSYSDATE() returns the time at which it executes. This differs from the\nbehavior for NOW(), which returns a constant time that indicates the\ntime at which the statement began to execute. (Within a stored function\nor trigger, NOW() returns the time at which the function or triggering\nstatement began to execute.)\n\nMariaDB> SELECT NOW(), SLEEP(2), NOW();\n+---------------------+----------+---------------------+\n| NOW() | SLEEP(2) | NOW() |\n+---------------------+----------+---------------------+\n| 2006-04-12 13:47:36 | 0 | 2006-04-12 13:47:36 |\n+---------------------+----------+---------------------+\n\nMariaDB> SELECT SYSDATE(), SLEEP(2), SYSDATE();\n+---------------------+----------+---------------------+\n| SYSDATE() | SLEEP(2) | SYSDATE() |\n+---------------------+----------+---------------------+\n| 2006-04-12 13:47:44 | 0 | 2006-04-12 13:47:46 |\n+---------------------+----------+---------------------+\n\nIn addition, the SET TIMESTAMP statement affects the value returned by\nNOW() but not by SYSDATE(). This means that timestamp settings in the\nbinary log have no effect on invocations of SYSDATE().\n\nBecause SYSDATE() can return different values even within the same\nstatement, and is not affected by SET TIMESTAMP, it is nondeterministic\nand therefore unsafe for replication if statement-based binary logging\nis used. If that is a problem, you can use row-based logging.\n\nAlternatively, you can use the --sysdate-is-now option to cause\nSYSDATE() to be an alias for NOW(). This works if the option is used on\nboth the master and the slave.\n\nThe nondeterministic nature of SYSDATE() also means that indexes cannot\nbe used for evaluating expressions that refer to it.\n\nURL: https://mariadb.com/kb/en/sysdate/\n\n','','https://mariadb.com/kb/en/sysdate/'); -insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (291,5,'UNINSTALL PLUGIN','Syntax:\nUNINSTALL PLUGIN plugin_name\n\nThis statement removes an installed server plugin. It requires the\nDELETE privilege for the mysql.plugin table.\n\nplugin_name must be the name of some plugin that is listed in the\nmysql.plugin table. The server executes the plugin\'s deinitialization\nfunction and removes the row for the plugin from the mysql.plugin\ntable, so that subsequent server restarts will not load and initialize\nthe plugin. UNINSTALL PLUGIN does not remove the plugin\'s shared\nlibrary file.\n\nURL: https://mariadb.com/kb/en/uninstall-plugin/\n\n','','https://mariadb.com/kb/en/uninstall-plugin/'); -insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (292,32,'ASBINARY','AsBinary(g), AsWKB(g)\n\nConverts a value in internal geometry format to its WKB representation\nand returns the binary result.\n\nURL: https://mariadb.com/kb/en/asbinary/\n\n','SELECT AsBinary(g) FROM geom;\n','https://mariadb.com/kb/en/asbinary/'); -insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (293,37,'REPEAT FUNCTION','Syntax:\nREPEAT(str,count)\n\nReturns a string consisting of the string str repeated count times. If\ncount is less than 1, returns an empty string. Returns NULL if str or\ncount are NULL.\n\nURL: https://mariadb.com/kb/en/repeat-function/\n\n','MariaDB> SELECT REPEAT(\'MySQL\', 3);\n -> \'MySQLMySQLMySQL\'\n','https://mariadb.com/kb/en/repeat-function/'); -insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (294,26,'SHOW TABLES','Syntax:\nSHOW [FULL] TABLES [{FROM | IN} db_name]\n [LIKE \'pattern\' | WHERE expr]\n\nSHOW TABLES lists the non-TEMPORARY tables in a given database. You can\nalso get this list using the mysqlshow db_name command. The LIKE\nclause, if present, indicates which table names to match. The WHERE\nclause can be given to select rows using more general conditions, as\ndiscussed in https://mariadb.com/kb/en/extended-show/.\n\nThis statement also lists any views in the database. The FULL modifier\nis supported such that SHOW FULL TABLES displays a second output\ncolumn. Values for the second column are BASE TABLE for a table and\nVIEW for a view.\n\nIf you have no privileges for a base table or view, it does not show up\nin the output from SHOW TABLES or mysqlshow db_name.\n\nURL: https://mariadb.com/kb/en/show-tables/\n\n','','https://mariadb.com/kb/en/show-tables/'); -insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (295,31,'MAKEDATE','Syntax:\nMAKEDATE(year,dayofyear)\n\nReturns a date, given year and day-of-year values. dayofyear must be\ngreater than 0 or the result is NULL.\n\nURL: https://mariadb.com/kb/en/makedate/\n\n','MariaDB> SELECT MAKEDATE(2011,31), MAKEDATE(2011,32);\n -> \'2011-01-31\', \'2011-02-01\'\nMariaDB> SELECT MAKEDATE(2011,365), MAKEDATE(2014,365);\n -> \'2011-12-31\', \'2014-12-31\'\nMariaDB> SELECT MAKEDATE(2011,0);\n -> NULL\n','https://mariadb.com/kb/en/makedate/'); -insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (296,37,'BINARY OPERATOR','Syntax:\nBINARY\n\nThe BINARY operator casts the string following it to a binary string.\nThis is an easy way to force a column comparison to be done byte by\nbyte rather than character by character. This causes the comparison to\nbe case sensitive even if the column is not defined as BINARY or BLOB.\nBINARY also causes trailing spaces to be significant.\n\nURL: https://mariadb.com/kb/en/binary-operator/\n\n','MariaDB> SELECT \'a\' = \'A\';\n -> 1\nMariaDB> SELECT BINARY \'a\' = \'A\';\n -> 0\nMariaDB> SELECT \'a\' = \'a \';\n -> 1\nMariaDB> SELECT BINARY \'a\' = \'a \';\n -> 0\n','https://mariadb.com/kb/en/binary-operator/'); -insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (297,6,'MBROVERLAPS','MBROverlaps(g1,g2)\n\nReturns 1 or 0 to indicate whether the Minimum Bounding Rectangles of\nthe two geometries g1 and g2 overlap. The term spatially overlaps is\nused if two geometries intersect and their intersection results in a\ngeometry of the same dimension but not equal to either of the given\ngeometries.\n\nURL: https://mariadb.com/kb/en/mbroverlaps/\n\n','','https://mariadb.com/kb/en/mbroverlaps/'); -insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (298,37,'SOUNDEX','Syntax:\nSOUNDEX(str)\n\nReturns a soundex string from str. Two strings that sound almost the\nsame should have identical soundex strings. A standard soundex string\nis four characters long, but the SOUNDEX() function returns an\narbitrarily long string. You can use SUBSTRING() on the result to get a\nstandard soundex string. All nonalphabetic characters in str are\nignored. All international alphabetic characters outside the A-Z range\nare treated as vowels.\n\n*Important*: When using SOUNDEX(), you should be aware of the following\nlimitations:\n\no This function, as currently implemented, is intended to work well\n with strings that are in the English language only. Strings in other\n languages may not produce reliable results.\n\no This function is not guaranteed to provide consistent results with\n strings that use multi-byte character sets, including utf-8.\n\n We hope to remove these limitations in a future release. See Bug\n #22638 for more information.\n\nURL: https://mariadb.com/kb/en/soundex/\n\n','MariaDB> SELECT SOUNDEX(\'Hello\');\n -> \'H400\'\nMariaDB> SELECT SOUNDEX(\'Quadratically\');\n -> \'Q36324\'\n','https://mariadb.com/kb/en/soundex/'); -insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (299,6,'MBRTOUCHES','MBRTouches(g1,g2)\n\nReturns 1 or 0 to indicate whether the Minimum Bounding Rectangles of\nthe two geometries g1 and g2 touch. Two geometries spatially touch if\nthe interiors of the geometries do not intersect, but the boundary of\none of the geometries intersects either the boundary or the interior of\nthe other.\n\nURL: https://mariadb.com/kb/en/mbrtouches/\n\n','','https://mariadb.com/kb/en/mbrtouches/'); -insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (300,39,'DROP EVENT','Syntax:\nDROP EVENT [IF EXISTS] event_name\n\nThis statement drops the event named event_name. The event immediately\nceases being active, and is deleted completely from the server.\n\nIf the event does not exist, the error ERROR 1517 (HY000): Unknown\nevent \'event_name\' results. You can override this and cause the\nstatement to generate a warning for nonexistent events instead using IF\nEXISTS.\n\nThis statement requires the EVENT privilege for the schema to which the\nevent to be dropped belongs.\n\nURL: https://mariadb.com/kb/en/drop-event/\n\n','','https://mariadb.com/kb/en/drop-event/'); -insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (301,27,'INSERT SELECT','Syntax:\nINSERT [LOW_PRIORITY | HIGH_PRIORITY] [IGNORE]\n [INTO] tbl_name [(col_name,...)]\n SELECT ...\n [ ON DUPLICATE KEY UPDATE col_name=expr, ... ]\n\nWith INSERT ... SELECT, you can quickly insert many rows into a table\nfrom one or many tables. For example:\n\nINSERT INTO tbl_temp2 (fld_id)\n SELECT tbl_temp1.fld_order_id\n FROM tbl_temp1 WHERE tbl_temp1.fld_order_id > 100;\n\nURL: https://mariadb.com/kb/en/insert-select/\n\n','','https://mariadb.com/kb/en/insert-select/'); -insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (302,39,'CREATE PROCEDURE','Syntax:\nCREATE\n [DEFINER = { user | CURRENT_USER }]\n PROCEDURE sp_name ([proc_parameter[,...]])\n [characteristic ...] routine_body\n\nCREATE\n [DEFINER = { user | CURRENT_USER }]\n FUNCTION sp_name ([func_parameter[,...]])\n RETURNS type\n [characteristic ...] routine_body\n\nproc_parameter:\n [ IN | OUT | INOUT ] param_name type\n\nfunc_parameter:\n param_name type\n\ntype:\n Any valid MySQL data type\n\ncharacteristic:\n COMMENT \'string\'\n | LANGUAGE SQL\n | [NOT] DETERMINISTIC\n | { CONTAINS SQL | NO SQL | READS SQL DATA | MODIFIES SQL DATA }\n | SQL SECURITY { DEFINER | INVOKER }\n\nroutine_body:\n Valid SQL routine statement\n\nThese statements create stored routines. By default, a routine is\nassociated with the default database. To associate the routine\nexplicitly with a given database, specify the name as db_name.sp_name\nwhen you create it.\n\nThe CREATE FUNCTION statement is also used in MySQL to support UDFs\n(user-defined functions). See\nhttps://mariadb.com/kb/en/create-function-udf/. A UDF can\nbe regarded as an external stored function. Stored functions share\ntheir namespace with UDFs. See\nhttp://dev.mysql.com/doc/refman/5.5/en/function-resolution.html, for\nthe rules describing how the server interprets references to different\nkinds of functions.\n\nTo invoke a stored procedure, use the CALL statement (see [HELP CALL]).\nTo invoke a stored function, refer to it in an expression. The function\nreturns a value during expression evaluation.\n\nCREATE PROCEDURE and CREATE FUNCTION require the CREATE ROUTINE\nprivilege. They might also require the SUPER privilege, depending on\nthe DEFINER value, as described later in this section. If binary\nlogging is enabled, CREATE FUNCTION might require the SUPER privilege,\nas described in\nhttps://mariadb.com/kb/en/binary-logging-of-stored-routines/.\n\nBy default, MySQL automatically grants the ALTER ROUTINE and EXECUTE\nprivileges to the routine creator. This behavior can be changed by\ndisabling the automatic_sp_privileges system variable. See\nhttps://mariadb.com/kb/en/stored-routine-privileges/.\n\nThe DEFINER and SQL SECURITY clauses specify the security context to be\nused when checking access privileges at routine execution time, as\ndescribed later in this section.\n\nIf the routine name is the same as the name of a built-in SQL function,\na syntax error occurs unless you use a space between the name and the\nfollowing parenthesis when defining the routine or invoking it later.\nFor this reason, avoid using the names of existing SQL functions for\nyour own stored routines.\n\nThe IGNORE_SPACE SQL mode applies to built-in functions, not to stored\nroutines. It is always permissible to have spaces after a stored\nroutine name, regardless of whether IGNORE_SPACE is enabled.\n\nThe parameter list enclosed within parentheses must always be present.\nIf there are no parameters, an empty parameter list of () should be\nused. Parameter names are not case sensitive.\n\nEach parameter is an IN parameter by default. To specify otherwise for\na parameter, use the keyword OUT or INOUT before the parameter name.\n\n*Note*: Specifying a parameter as IN, OUT, or INOUT is valid only for a\nPROCEDURE. For a FUNCTION, parameters are always regarded as IN\nparameters.\n\nAn IN parameter passes a value into a procedure. The procedure might\nmodify the value, but the modification is not visible to the caller\nwhen the procedure returns. An OUT parameter passes a value from the\nprocedure back to the caller. Its initial value is NULL within the\nprocedure, and its value is visible to the caller when the procedure\nreturns. An INOUT parameter is initialized by the caller, can be\nmodified by the procedure, and any change made by the procedure is\nvisible to the caller when the procedure returns.\n\nFor each OUT or INOUT parameter, pass a user-defined variable in the\nCALL statement that invokes the procedure so that you can obtain its\nvalue when the procedure returns. If you are calling the procedure from\nwithin another stored procedure or function, you can also pass a\nroutine parameter or local routine variable as an IN or INOUT\nparameter.\n\nThe following example shows a simple stored procedure that uses an OUT\nparameter:\n\nMariaDB> delimiter //\n\nMariaDB> CREATE PROCEDURE simpleproc (OUT param1 INT)\n -> BEGIN\n -> SELECT COUNT(*) INTO param1 FROM t;\n -> END//\nQuery OK, 0 rows affected (0.00 sec)\n\nMariaDB> delimiter ;\n\nMariaDB> CALL simpleproc(@a);\nQuery OK, 0 rows affected (0.00 sec)\n\nMariaDB> SELECT @a;\n+------+\n| @a |\n+------+\n| 3 |\n+------+\n1 row in set (0.00 sec)\n\nThe example uses the mysql client delimiter command to change the\nstatement delimiter from ; to // while the procedure is being defined.\nThis enables the ; delimiter used in the procedure body to be passed\nthrough to the server rather than being interpreted by mysql itself.\nSee\nhttps://mariadb.com/kb/en/stored-procedure-overview/.\n\nThe RETURNS clause may be specified only for a FUNCTION, for which it\nis mandatory. It indicates the return type of the function, and the\nfunction body must contain a RETURN value statement. If the RETURN\nstatement returns a value of a different type, the value is coerced to\nthe proper type. For example, if a function specifies an ENUM or SET\nvalue in the RETURNS clause, but the RETURN statement returns an\ninteger, the value returned from the function is the string for the\ncorresponding ENUM member of set of SET members.\n\nThe following example function takes a parameter, performs an operation\nusing an SQL function, and returns the result. In this case, it is\nunnecessary to use delimiter because the function definition contains\nno internal ; statement delimiters:\n\nMariaDB> CREATE FUNCTION hello (s CHAR(20))\nMariaDB> RETURNS CHAR(50) DETERMINISTIC\n -> RETURN CONCAT(\'Hello, \',s,\'!\');\nQuery OK, 0 rows affected (0.00 sec)\n\nMariaDB> SELECT hello(\'world\');\n+----------------+\n| hello(\'world\') |\n+----------------+\n| Hello, world! |\n+----------------+\n1 row in set (0.00 sec)\n\nParameter types and function return types can be declared to use any\nvalid data type, except that the COLLATE attribute cannot be used prior\nto MySQL 5.5.3. As of 5.5.3, COLLATE can be used if preceded by the\nCHARACTER SET attribute.\n\nThe routine_body consists of a valid SQL routine statement. This can be\na simple statement such as SELECT or INSERT, or a compound statement\nwritten using BEGIN and END. Compound statements can contain\ndeclarations, loops, and other control structure statements. The syntax\nfor these statements is described in\nhttps://mariadb.com/kb/programmatic-and-compound-statements.\n\nMySQL permits routines to contain DDL statements, such as CREATE and\nDROP. MySQL also permits stored procedures (but not stored functions)\nto contain SQL transaction statements such as COMMIT. Stored functions\nmay not contain statements that perform explicit or implicit commit or\nrollback. Support for these statements is not required by the SQL\nstandard, which states that each DBMS vendor may decide whether to\npermit them.\n\nStatements that return a result set can be used within a stored\nprocedure but not within a stored function. This prohibition includes\nSELECT statements that do not have an INTO var_list clause and other\nstatements such as SHOW, EXPLAIN, and CHECK TABLE. For statements that\ncan be determined at function definition time to return a result set, a\nNot allowed to return a result set from a function error occurs\n(ER_SP_NO_RETSET). For statements that can be determined only at\nruntime to return a result set, a PROCEDURE %s can\'t return a result\nset in the given context error occurs (ER_SP_BADSELECT).\n\nUSE statements within stored routines are not permitted. When a routine\nis invoked, an implicit USE db_name is performed (and undone when the\nroutine terminates). The causes the routine to have the given default\ndatabase while it executes. References to objects in databases other\nthan the routine default database should be qualified with the\nappropriate database name.\n\nFor additional information about statements that are not permitted in\nstored routines, see\nhttps://mariadb.com/kb/en/stored-routine-privileges/\n.\n\nFor information about invoking stored procedures from within programs\nwritten in a language that has a MySQL interface, see [HELP CALL].\n\nMySQL stores the sql_mode system variable setting that is in effect at\nthe time a routine is created, and always executes the routine with\nthis setting in force, regardless of the server SQL mode in effect when\nthe routine is invoked.\n\nThe switch from the SQL mode of the invoker to that of the routine\noccurs after evaluation of arguments and assignment of the resulting\nvalues to routine parameters. If you define a routine in strict SQL\nmode but invoke it in nonstrict mode, assignment of arguments to\nroutine parameters does not take place in strict mode. If you require\nthat expressions passed to a routine be assigned in strict SQL mode,\nyou should invoke the routine with strict mode in effect.\n\nURL: https://mariadb.com/kb/en/create-procedure/\n\n','','https://mariadb.com/kb/en/create-procedure/'); -insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (303,22,'VARBINARY','VARBINARY(M)\n\nThe VARBINARY type is similar to the VARCHAR type, but stores binary\nbyte strings rather than nonbinary character strings. M represents the\nmaximum column length in bytes.\n\nURL: https://mariadb.com/kb/en/varbinary/\n\n','','https://mariadb.com/kb/en/varbinary/'); -insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (304,26,'LOAD INDEX','Syntax:\nLOAD INDEX INTO CACHE\n tbl_index_list [, tbl_index_list] ...\n\ntbl_index_list:\n tbl_name\n [PARTITION (partition_list | ALL)]\n [[INDEX|KEY] (index_name[, index_name] ...)]\n [IGNORE LEAVES]\n\npartition_list:\n partition_name[, partition_name][, ...]\n\nThe LOAD INDEX INTO CACHE statement preloads a table index into the key\ncache to which it has been assigned by an explicit CACHE INDEX\nstatement, or into the default key cache otherwise.\n\nLOAD INDEX INTO CACHE is used only for MyISAM tables. In MySQL 5.5, it\nis also supported for partitioned MyISAM tables; in addition, indexes\non partitioned tables can be preloaded for one, several, or all\npartitions.\n\nThe IGNORE LEAVES modifier causes only blocks for the nonleaf nodes of\nthe index to be preloaded.\n\nIGNORE LEAVES is also supported for partitioned MyISAM tables.\n\nURL: https://mariadb.com/kb/en/load-index/\n\n','','https://mariadb.com/kb/en/load-index/'); -insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (305,27,'UNION','Syntax:\nSELECT ...\nUNION [ALL | DISTINCT] SELECT ...\n[UNION [ALL | DISTINCT] SELECT ...]\n\nUNION is used to combine the result from multiple SELECT statements\ninto a single result set.\n\nThe column names from the first SELECT statement are used as the column\nnames for the results returned. Selected columns listed in\ncorresponding positions of each SELECT statement should have the same\ndata type. (For example, the first column selected by the first\nstatement should have the same type as the first column selected by the\nother statements.)\n\nURL: https://mariadb.com/kb/en/union/\n\n','','https://mariadb.com/kb/en/union/'); -insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (306,31,'TO_DAYS','Syntax:\nTO_DAYS(date)\n\nGiven a date date, returns a day number (the number of days since year\n0).\n\nURL: https://mariadb.com/kb/en/to_days/\n\n','MariaDB> SELECT TO_DAYS(950501);\n -> 728779\nMariaDB> SELECT TO_DAYS(\'2007-10-07\');\n -> 733321\n','https://mariadb.com/kb/en/to_days/'); -insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (307,37,'NOT REGEXP','Syntax:\nexpr NOT REGEXP pat, expr NOT RLIKE pat\n\nThis is the same as NOT (expr REGEXP pat).\n\nURL: https://mariadb.com/kb/en/not-regexp/\n\n','','https://mariadb.com/kb/en/not-regexp/'); -insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (308,26,'SHOW INDEX','Syntax:\nSHOW {INDEX | INDEXES | KEYS}\n {FROM | IN} tbl_name\n [{FROM | IN} db_name]\n [WHERE expr]\n\nSHOW INDEX returns table index information. The format resembles that\nof the SQLStatistics call in ODBC. This statement requires some\nprivilege for any column in the table.\nYou can use db_name.tbl_name as an alternative to the tbl_name FROM\ndb_name syntax. These two statements are equivalent:\n\nSHOW INDEX FROM mytable FROM mydb;\nSHOW INDEX FROM mydb.mytable;\n\nThe WHERE clause can be given to select rows using more general\nconditions, as discussed in\nhttps://mariadb.com/kb/en/extended-show/.\n\nYou can also list a table\'s indexes with the mysqlshow -k db_name\ntbl_name command.\n\nURL: https://mariadb.com/kb/en/show-index/\n\n','','https://mariadb.com/kb/en/show-index/'); -insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (309,26,'SHOW CREATE DATABASE','Syntax:\nSHOW CREATE {DATABASE | SCHEMA} [IF NOT EXISTS] db_name\n\nShows the CREATE DATABASE statement that creates the given database. If\nthe SHOW statement includes an IF NOT EXISTS clause, the output too\nincludes such a clause. SHOW CREATE SCHEMA is a synonym for SHOW CREATE\nDATABASE.\n\nURL: https://mariadb.com/kb/en/show-create-database/\n\n','MariaDB> SHOW CREATE DATABASE test\\G\n*************************** 1. row ***************************\n Database: test\nCreate Database: CREATE DATABASE `test`\n /*!40100 DEFAULT CHARACTER SET latin1 */\n\nMariaDB> SHOW CREATE SCHEMA test\\G\n*************************** 1. row ***************************\n Database: test\nCreate Database: CREATE DATABASE `test`\n /*!40100 DEFAULT CHARACTER SET latin1 */\n','https://mariadb.com/kb/en/show-create-database/'); -insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (310,23,'LEAVE','Syntax:\nLEAVE label\n\nThis statement is used to exit the flow control construct that has the\ngiven label. If the label is for the outermost stored program block,\nLEAVE exits the program.\n\nLEAVE can be used within BEGIN ... END or loop constructs (LOOP,\nREPEAT, WHILE).\n\nURL: https://mariadb.com/kb/en/leave/\n\n','','https://mariadb.com/kb/en/leave/'); -insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (311,18,'NOT IN','Syntax:\nexpr NOT IN (value,...)\n\nThis is the same as NOT (expr IN (value,...)).\n\nURL: https://mariadb.com/kb/en/not-in/\n\n','','https://mariadb.com/kb/en/not-in/'); -insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (312,15,'!','Syntax:\nNOT, !\n\nLogical NOT. Evaluates to 1 if the operand is 0, to 0 if the operand is\nnonzero, and NOT NULL returns NULL.\n\nURL: https://mariadb.com/kb/en/not/\n\n','MariaDB> SELECT NOT 10;\n -> 0\nMariaDB> SELECT NOT 0;\n -> 1\nMariaDB> SELECT NOT NULL;\n -> NULL\nMariaDB> SELECT ! (1+1);\n -> 0\nMariaDB> SELECT ! 1+1;\n -> 1\n','https://mariadb.com/kb/en/not/'); -insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (313,23,'DECLARE HANDLER','Syntax:\nDECLARE handler_action HANDLER\n FOR condition_value [, condition_value] ...\n statement\n\nhandler_action:\n CONTINUE\n | EXIT\n | UNDO\n\ncondition_value:\n mysql_error_code\n | SQLSTATE [VALUE] sqlstate_value\n | condition_name\n | SQLWARNING\n | NOT FOUND\n | SQLEXCEPTION\n\nThe DECLARE ... HANDLER statement specifies a handler that deals with\none or more conditions. If one of these conditions occurs, the\nspecified statement executes. statement can be a simple statement such\nas SET var_name = value, or a compound statement written using BEGIN\nand END (see [HELP BEGIN END]).\n\nHandler declarations must appear after variable or condition\ndeclarations.\n\nThe handler_action value indicates what action the handler takes after\nexecution of the handler statement:\n\no CONTINUE: Execution of the current program continues.\n\no EXIT: Execution terminates for the BEGIN ... END compound statement\n in which the handler is declared. This is true even if the condition\n occurs in an inner block.\n\no UNDO: Not supported.\n\nThe condition_value for DECLARE ... HANDLER indicates the specific\ncondition or class of conditions that activates the handler:\n\no A MySQL error code (a number) or an SQLSTATE value (a 5-character\n string literal). You should not use MySQL error code 0 or SQLSTATE\n values that begin with \'00\', because those indicate success rather\n than an error condition. For a list of MySQL error codes and SQLSTATE\n values, see\n https://mariadb.com/kb/en/mariadb-error-codes/.\n\no A condition name previously specified with DECLARE ... CONDITION. A\n condition name can be associated with a MySQL error code or SQLSTATE\n value. See [HELP DECLARE CONDITION].\n\no SQLWARNING is shorthand for the class of SQLSTATE values that begin\n with \'01\'.\n\no NOT FOUND is shorthand for the class of SQLSTATE values that begin\n with \'02\'. This is relevant within the context of cursors and is used\n to control what happens when a cursor reaches the end of a data set.\n If no more rows are available, a No Data condition occurs with\n SQLSTATE value \'02000\'. To detect this condition, you can set up a\n handler for it (or for a NOT FOUND condition). For an example, see\n https://mariadb.com/kb/en/cursor-overview/. This condition\n also occurs for SELECT ... INTO var_list statements that retrieve no\n rows.\n\no SQLEXCEPTION is shorthand for the class of SQLSTATE values that do\n not begin with \'00\', \'01\', or \'02\'.\n\nIf a condition occurs for which no handler has been declared, the\naction taken depends on the condition class:\n\no For SQLEXCEPTION conditions, the stored program terminates at the\n statement that raised the condition, as if there were an EXIT\n handler. If the program was called by another stored program, the\n calling program handles the condition using the handler selection\n rules applied to its own handlers.\n\no For SQLWARNING conditions, the program continues executing, as if\n there were a CONTINUE handler.\n\no For NOT FOUND conditions, if the condition was raised normally, the\n action is CONTINUE. If it was raised by SIGNAL or RESIGNAL, the\n action is EXIT.\n\nURL: https://mariadb.com/kb/en/declare-handler/\n\n','MariaDB> CREATE TABLE test.t (s1 INT, PRIMARY KEY (s1));\nQuery OK, 0 rows affected (0.00 sec)\n\nMariaDB> delimiter //\n\nMariaDB> CREATE PROCEDURE handlerdemo ()\n -> BEGIN\n -> DECLARE CONTINUE HANDLER FOR SQLSTATE \'23000\' SET @x2 = 1;\n -> SET @x = 1;\n -> INSERT INTO test.t VALUES (1);\n -> SET @x = 2;\n -> INSERT INTO test.t VALUES (1);\n -> SET @x = 3;\n -> END;\n -> //\nQuery OK, 0 rows affected (0.00 sec)\n\nMariaDB> CALL handlerdemo()//\nQuery OK, 0 rows affected (0.00 sec)\n\nMariaDB> SELECT @x//\n +------+\n | @x |\n +------+\n | 3 |\n +------+\n 1 row in set (0.00 sec)\n','https://mariadb.com/kb/en/declare-handler/'); -insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (314,22,'DOUBLE','DOUBLE[(M,D)] [UNSIGNED] [ZEROFILL]\n\nA normal-size (double-precision) floating-point number. Permissible\nvalues are -1.7976931348623157E+308 to -2.2250738585072014E-308, 0, and\n2.2250738585072014E-308 to 1.7976931348623157E+308. These are the\ntheoretical limits, based on the IEEE standard. The actual range might\nbe slightly smaller depending on your hardware or operating system.\n\nM is the total number of digits and D is the number of digits following\nthe decimal point. If M and D are omitted, values are stored to the\nlimits permitted by the hardware. A double-precision floating-point\nnumber is accurate to approximately 15 decimal places.\n\nUNSIGNED, if specified, disallows negative values.\n\nURL: https://mariadb.com/kb/en/double/\n\n','','https://mariadb.com/kb/en/double/'); -insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (315,22,'TIME','TIME\n\nA time. The range is \'-838:59:59\' to \'838:59:59\'. MySQL displays TIME\nvalues in \'HH:MM:SS\' format, but permits assignment of values to TIME\ncolumns using either strings or numbers.\n\nURL: https://mariadb.com/kb/en/time/\n\n','','https://mariadb.com/kb/en/time/'); -insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (316,15,'&&','Syntax:\nAND, &&\n\nLogical AND. Evaluates to 1 if all operands are nonzero and not NULL,\nto 0 if one or more operands are 0, otherwise NULL is returned.\n\nURL: https://mariadb.com/kb/en/and/\n\n','MariaDB> SELECT 1 && 1;\n -> 1\nMariaDB> SELECT 1 && 0;\n -> 0\nMariaDB> SELECT 1 && NULL;\n -> NULL\nMariaDB> SELECT 0 && NULL;\n -> 0\nMariaDB> SELECT NULL && 0;\n -> 0\n','https://mariadb.com/kb/en/and/'); -insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (317,11,'X','X(p)\n\nReturns the X-coordinate value for the Point object p as a\ndouble-precision number.\n\nURL: https://mariadb.com/kb/en/x/\n\n','MariaDB> SELECT X(POINT(56.7, 53.34));\n+-----------------------+\n| X(POINT(56.7, 53.34)) |\n+-----------------------+\n| 56.7 |\n+-----------------------+\n','https://mariadb.com/kb/en/x/'); -insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (318,17,'SYSTEM_USER','Syntax:\nSYSTEM_USER()\n\nSYSTEM_USER() is a synonym for USER().\n\nURL: https://mariadb.com/kb/en/system_user/\n\n','','https://mariadb.com/kb/en/system_user/'); -insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (319,17,'FOUND_ROWS','Syntax:\nFOUND_ROWS()\n\nA SELECT statement may include a LIMIT clause to restrict the number of\nrows the server returns to the client. In some cases, it is desirable\nto know how many rows the statement would have returned without the\nLIMIT, but without running the statement again. To obtain this row\ncount, include a SQL_CALC_FOUND_ROWS option in the SELECT statement,\nand then invoke FOUND_ROWS() afterward:\n\nURL: https://mariadb.com/kb/en/found_rows/\n\n','MariaDB> SELECT SQL_CALC_FOUND_ROWS * FROM tbl_name\n -> WHERE id > 100 LIMIT 10;\nMariaDB> SELECT FOUND_ROWS();\n','https://mariadb.com/kb/en/found_rows/'); -insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (320,30,'CROSSES','Crosses(g1,g2)\n\nReturns 1 if g1 spatially crosses g2. Returns NULL if g1 is a Polygon\nor a MultiPolygon, or if g2 is a Point or a MultiPoint. Otherwise,\nreturns 0.\n\nThe term spatially crosses denotes a spatial relation between two given\ngeometries that has the following properties:\n\no The two geometries intersect\n\no Their intersection results in a geometry that has a dimension that is\n one less than the maximum dimension of the two given geometries\n\no Their intersection is not equal to either of the two given geometries\n\nURL: https://mariadb.com/kb/en/crosses/\n\n','','https://mariadb.com/kb/en/crosses/'); -insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (321,39,'TRUNCATE TABLE','Syntax:\nTRUNCATE [TABLE] tbl_name\n\nTRUNCATE TABLE empties a table completely. It requires the DROP\nprivilege.\n\nLogically, TRUNCATE TABLE is similar to a DELETE statement that deletes\nall rows, or a sequence of DROP TABLE and CREATE TABLE statements. To\nachieve high performance, it bypasses the DML method of deleting data.\nThus, it cannot be rolled back, it does not cause ON DELETE triggers to\nfire, and it cannot be performed for InnoDB tables with parent-child\nforeign key relationships.\n\nAlthough TRUNCATE TABLE is similar to DELETE, it is classified as a DDL\nstatement rather than a DML statement. It differs from DELETE in the\nfollowing ways in MySQL 5.5:\n\no Truncate operations drop and re-create the table, which is much\n faster than deleting rows one by one, particularly for large tables.\n\no Truncate operations cause an implicit commit, and so cannot be rolled\n back.\n\no Truncation operations cannot be performed if the session holds an\n active table lock.\n\no TRUNCATE TABLE fails for an InnoDB table if there are any FOREIGN KEY\n constraints from other tables that reference the table. Foreign key\n constraints between columns of the same table are permitted.\n\no Truncation operations do not return a meaningful value for the number\n of deleted rows. The usual result is "0 rows affected," which should\n be interpreted as "no information."\n\no As long as the table format file tbl_name.frm is valid, the table can\n be re-created as an empty table with TRUNCATE TABLE, even if the data\n or index files have become corrupted.\n\no Any AUTO_INCREMENT value is reset to its start value. This is true\n even for MyISAM and InnoDB, which normally do not reuse sequence\n values.\n\no When used with partitioned tables, TRUNCATE TABLE preserves the\n partitioning; that is, the data and index files are dropped and\n re-created, while the partition definitions (.par) file is\n unaffected.\n\no The TRUNCATE TABLE statement does not invoke ON DELETE triggers.\n\nURL: https://mariadb.com/kb/en/truncate-table/\n\n','','https://mariadb.com/kb/en/truncate-table/'); -insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (322,16,'BIT_XOR','Syntax:\nBIT_XOR(expr)\n\nReturns the bitwise XOR of all bits in expr. The calculation is\nperformed with 64-bit (BIGINT) precision.\n\nURL: https://mariadb.com/kb/en/bit_xor/\n\n','','https://mariadb.com/kb/en/bit_xor/'); -insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (323,31,'CURRENT_DATE','Syntax:\nCURRENT_DATE, CURRENT_DATE()\n\nCURRENT_DATE and CURRENT_DATE() are synonyms for CURDATE().\n\nURL: https://mariadb.com/kb/en/current_date/\n\n','','https://mariadb.com/kb/en/current_date/'); -insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (324,8,'START SLAVE','Syntax:\nSTART SLAVE [thread_types]\n\nSTART SLAVE [SQL_THREAD] UNTIL\n MASTER_LOG_FILE = \'log_name\', MASTER_LOG_POS = log_pos\n\nSTART SLAVE [SQL_THREAD] UNTIL\n RELAY_LOG_FILE = \'log_name\', RELAY_LOG_POS = log_pos\n\nthread_types:\n [thread_type [, thread_type] ... ]\n\nthread_type: IO_THREAD | SQL_THREAD\n\nSTART SLAVE with no thread_type options starts both of the slave\nthreads. The I/O thread reads events from the master server and stores\nthem in the relay log. The SQL thread reads events from the relay log\nand executes them. START SLAVE requires the SUPER privilege.\n\nIf START SLAVE succeeds in starting the slave threads, it returns\nwithout any error. However, even in that case, it might be that the\nslave threads start and then later stop (for example, because they do\nnot manage to connect to the master or read its binary log, or some\nother problem). START SLAVE does not warn you about this. You must\ncheck the slave\'s error log for error messages generated by the slave\nthreads, or check that they are running satisfactorily with SHOW SLAVE\nSTATUS.\n\nURL: https://mariadb.com/kb/en/start-slave/\n\n','','https://mariadb.com/kb/en/start-slave/'); -insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (325,2,'AREA','Area(poly)\n\nReturns as a double-precision number the area of the Polygon value\npoly, as measured in its spatial reference system.\n\nURL: https://mariadb.com/kb/en/area/\n\n','MariaDB> SET @poly = \'Polygon((0 0,0 3,3 0,0 0),(1 1,1 2,2 1,1 1))\';\nMariaDB> SELECT Area(GeomFromText(@poly));\n+---------------------------+\n| Area(GeomFromText(@poly)) |\n+---------------------------+\n| 4 |\n+---------------------------+\n','https://mariadb.com/kb/en/area/'); -insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (326,26,'FLUSH','Syntax:\nFLUSH [NO_WRITE_TO_BINLOG | LOCAL]\n flush_option [, flush_option] ...\n\nThe FLUSH statement has several variant forms that clear or reload\nvarious internal caches, flush tables, or acquire locks. To execute\nFLUSH, you must have the RELOAD privilege. Specific flush options might\nrequire additional privileges, as described later.\n\nBy default, the server writes FLUSH statements to the binary log so\nthat they replicate to replication slaves. To suppress logging, use the\noptional NO_WRITE_TO_BINLOG keyword or its alias LOCAL.\n\n*Note*: FLUSH LOGS, FLUSH MASTER, FLUSH SLAVE, and FLUSH TABLES WITH\nREAD LOCK (with or without a table list) are not written to the binary\nlog in any case because they would cause problems if replicated to a\nslave.\n\nThe FLUSH statement causes an implicit commit. See\nhttp://dev.mysql.com/doc/refman/5.5/en/implicit-commit.html.\n\nThe RESET statement is similar to FLUSH. See [HELP RESET], for\ninformation about using the RESET statement with replication.\n\nURL: https://mariadb.com/kb/en/flush/\n\n','','https://mariadb.com/kb/en/flush/'); -insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (327,23,'BEGIN END','Syntax:\n[begin_label:] BEGIN\n [statement_list]\nEND [end_label]\n\nBEGIN ... END syntax is used for writing compound statements, which can\nappear within stored programs (stored procedures and functions,\ntriggers, and events). A compound statement can contain multiple\nstatements, enclosed by the BEGIN and END keywords. statement_list\nrepresents a list of one or more statements, each terminated by a\nsemicolon (;) statement delimiter. The statement_list itself is\noptional, so the empty compound statement (BEGIN END) is legal.\n\nBEGIN ... END blocks can be nested.\n\nUse of multiple statements requires that a client is able to send\nstatement strings containing the ; statement delimiter. In the mysql\ncommand-line client, this is handled with the delimiter command.\nChanging the ; end-of-statement delimiter (for example, to //) permit ;\nto be used in a program body. For an example, see\nhttps://mariadb.com/kb/en/stored-procedure-overview/.\n\nA BEGIN ... END block can be labeled. See [HELP labels].\n\nURL: https://mariadb.com/kb/en/begin-end/\n\n','','https://mariadb.com/kb/en/begin-end/'); -insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (328,26,'SHOW PROCEDURE STATUS','Syntax:\nSHOW PROCEDURE STATUS\n [LIKE \'pattern\' | WHERE expr]\n\nThis statement is a MySQL extension. It returns characteristics of a\nstored procedure, such as the database, name, type, creator, creation\nand modification dates, and character set information. A similar\nstatement, SHOW FUNCTION STATUS, displays information about stored\nfunctions (see [HELP SHOW FUNCTION STATUS]).\n\nThe LIKE clause, if present, indicates which procedure or function\nnames to match. The WHERE clause can be given to select rows using more\ngeneral conditions, as discussed in\nhttps://mariadb.com/kb/en/extended-show/.\n\nURL: https://mariadb.com/kb/en/show-procedure-status/\n\n','MariaDB> SHOW PROCEDURE STATUS LIKE \'sp1\'\\G\n*************************** 1. row ***************************\n Db: test\n Name: sp1\n Type: PROCEDURE\n Definer: testuser@localhost\n Modified: 2004-08-03 15:29:37\n Created: 2004-08-03 15:29:37\n Security_type: DEFINER\n Comment:\ncharacter_set_client: latin1\ncollation_connection: latin1_swedish_ci\n Database Collation: latin1_swedish_ci\n','https://mariadb.com/kb/en/show-procedure-status/'); -insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (329,28,'DESCRIBE','Syntax:\n{DESCRIBE | DESC} tbl_name [col_name | wild]\n\nDESCRIBE provides information about the columns in a table. It is a\nshortcut for SHOW COLUMNS FROM. These statements also display\ninformation for views. (See [HELP SHOW COLUMNS].)\n\ncol_name can be a column name, or a string containing the SQL "%" and\n"_" wildcard characters to obtain output only for the columns with\nnames matching the string. There is no need to enclose the string\nwithin quotation marks unless it contains spaces or other special\ncharacters.\n\nMariaDB> DESCRIBE City;\n+------------+----------+------+-----+---------+----------------+\n| Field | Type | Null | Key | Default | Extra |\n+------------+----------+------+-----+---------+----------------+\n| Id | int(11) | NO | PRI | NULL | auto_increment |\n| Name | char(35) | NO | | | |\n| Country | char(3) | NO | UNI | | |\n| District | char(20) | YES | MUL | | |\n| Population | int(11) | NO | | 0 | |\n+------------+----------+------+-----+---------+----------------+\n5 rows in set (0.00 sec)\n\nThe description for SHOW COLUMNS provides more information about the\noutput columns (see [HELP SHOW COLUMNS]).\n\nURL: https://mariadb.com/kb/en/describe/\n\n','','https://mariadb.com/kb/en/describe/'); -insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (330,26,'SHOW WARNINGS','Syntax:\nSHOW WARNINGS [LIMIT [offset,] row_count]\nSHOW COUNT(*) WARNINGS\n\nSHOW WARNINGS shows information about the conditions (errors, warnings,\nand notes) that resulted from the last statement in the current session\nthat generated messages. It shows nothing if the last statement used a\ntable and generated no messages. (That is, a statement that uses a\ntable but generates no messages clears the message list.) Statements\nthat do not use tables and do not generate messages have no effect on\nthe message list.\n\nWarnings are generated for DML statements such as INSERT, UPDATE, and\nLOAD DATA INFILE as well as DDL statements such as CREATE TABLE and\nALTER TABLE.\n\nSHOW WARNINGS is also used following EXPLAIN EXTENDED, to display the\nextra information generated by EXPLAIN when the EXTENDED keyword is\nused. See https://mariadb.com/kb/en/explain#explain-extended.\n\nThe LIMIT clause has the same syntax as for the SELECT statement. See\nhttps://mariadb.com/kb/en/select/.\n\nA related statement, SHOW ERRORS, shows only the error conditions (it\nexcludes warnings and notes). See [HELP SHOW ERRORS].\n\nThe SHOW COUNT(*) WARNINGS statement displays the total number of\nerrors, warnings, and notes. You can also retrieve this number from the\nwarning_count system variable:\n\nSHOW COUNT(*) WARNINGS;\nSELECT @@warning_count;\n\nURL: https://mariadb.com/kb/en/show-warnings/\n\n','','https://mariadb.com/kb/en/show-warnings/'); -insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (331,10,'DROP USER','Syntax:\nDROP USER user [, user] ...\n\nThe DROP USER statement removes one or more MySQL accounts and their\nprivileges. It removes privilege rows for the account from all grant\ntables. To use this statement, you must have the global CREATE USER\nprivilege or the DELETE privilege for the mysql database. Each account\nname uses the format described in\nhttps://mariadb.com/kb/en/create-user#account-names. For example:\n\nDROP USER \'jeffrey\'@\'localhost\';\n\nIf you specify only the user name part of the account name, a host name\npart of \'%\' is used.\n\nURL: https://mariadb.com/kb/en/drop-user/\n\n','','https://mariadb.com/kb/en/drop-user/'); -insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (332,16,'STDDEV_POP','Syntax:\nSTDDEV_POP(expr)\n\nReturns the population standard deviation of expr (the square root of\nVAR_POP()). You can also use STD() or STDDEV(), which are equivalent\nbut not standard SQL.\n\nSTDDEV_POP() returns NULL if there were no matching rows.\n\nURL: https://mariadb.com/kb/en/stddev_pop/\n\n','','https://mariadb.com/kb/en/stddev_pop/'); -insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (333,26,'SHOW CHARACTER SET','Syntax:\nSHOW CHARACTER SET\n [LIKE \'pattern\' | WHERE expr]\n\nThe SHOW CHARACTER SET statement shows all available character sets.\nThe LIKE clause, if present, indicates which character set names to\nmatch. The WHERE clause can be given to select rows using more general\nconditions, as discussed in\nhttps://mariadb.com/kb/en/extended-show/. For example:\n\nMariaDB> SHOW CHARACTER SET LIKE \'latin%\';\n+---------+-----------------------------+-------------------+--------+\n| Charset | Description | Default collation | Maxlen |\n+---------+-----------------------------+-------------------+--------+\n| latin1 | cp1252 West European | latin1_swedish_ci | 1 |\n| latin2 | ISO 8859-2 Central European | latin2_general_ci | 1 |\n| latin5 | ISO 8859-9 Turkish | latin5_turkish_ci | 1 |\n| latin7 | ISO 8859-13 Baltic | latin7_general_ci | 1 |\n+---------+-----------------------------+-------------------+--------+\n\nURL: https://mariadb.com/kb/en/show-character-set/\n\n','','https://mariadb.com/kb/en/show-character-set/'); -insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (334,37,'SUBSTRING','Syntax:\nSUBSTRING(str,pos), SUBSTRING(str FROM pos), SUBSTRING(str,pos,len),\nSUBSTRING(str FROM pos FOR len)\n\nThe forms without a len argument return a substring from string str\nstarting at position pos. The forms with a len argument return a\nsubstring len characters long from string str, starting at position\npos. The forms that use FROM are standard SQL syntax. It is also\npossible to use a negative value for pos. In this case, the beginning\nof the substring is pos characters from the end of the string, rather\nthan the beginning. A negative value may be used for pos in any of the\nforms of this function.\n\nFor all forms of SUBSTRING(), the position of the first character in\nthe string from which the substring is to be extracted is reckoned as\n1.\n\nURL: https://mariadb.com/kb/en/substring/\n\n','MariaDB> SELECT SUBSTRING(\'Quadratically\',5);\n -> \'ratically\'\nMariaDB> SELECT SUBSTRING(\'foobarbar\' FROM 4);\n -> \'barbar\'\nMariaDB> SELECT SUBSTRING(\'Quadratically\',5,6);\n -> \'ratica\'\nMariaDB> SELECT SUBSTRING(\'Sakila\', -3);\n -> \'ila\'\nMariaDB> SELECT SUBSTRING(\'Sakila\', -5, 3);\n -> \'aki\'\nMariaDB> SELECT SUBSTRING(\'Sakila\' FROM -4 FOR 2);\n -> \'ki\'\n','https://mariadb.com/kb/en/substring/'); -insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (335,36,'ISEMPTY','IsEmpty(g)\n\nReturns 1 if the geometry value g is the empty geometry, 0 if it is not\nempty, and -1 if the argument is NULL. If the geometry is empty, it\nrepresents the empty point set.\n\nURL: https://mariadb.com/kb/en/isempty/\n\n','','https://mariadb.com/kb/en/isempty/'); -insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (336,26,'SHOW FUNCTION STATUS','Syntax:\nSHOW FUNCTION STATUS\n [LIKE \'pattern\' | WHERE expr]\n\nThis statement is similar to SHOW PROCEDURE STATUS but for stored\nfunctions. See [HELP SHOW PROCEDURE STATUS].\n\nURL: https://mariadb.com/kb/en/show-function-status/\n\n','','https://mariadb.com/kb/en/show-function-status/'); -insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (337,37,'LTRIM','Syntax:\nLTRIM(str)\n\nReturns the string str with leading space characters removed.\n\nURL: https://mariadb.com/kb/en/ltrim/\n\n','MariaDB> SELECT LTRIM(\' barbar\');\n -> \'barbar\'\n','https://mariadb.com/kb/en/ltrim/'); -insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (338,30,'INTERSECTS','Intersects(g1,g2)\n\nReturns 1 or 0 to indicate whether g1 spatially intersects g2.\n\nURL: https://mariadb.com/kb/en/intersects/\n\n','','https://mariadb.com/kb/en/intersects/'); -insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (339,27,'CALL','Syntax:\nCALL sp_name([parameter[,...]])\nCALL sp_name[()]\n\nThe CALL statement invokes a stored procedure that was defined\npreviously with CREATE PROCEDURE.\n\nStored procedures that take no arguments can be invoked without\nparentheses. That is, CALL p() and CALL p are equivalent.\n\nCALL can pass back values to its caller using parameters that are\ndeclared as OUT or INOUT parameters. When the procedure returns, a\nclient program can also obtain the number of rows affected for the\nfinal statement executed within the routine: At the SQL level, call the\nROW_COUNT() function; from the C API, call the mysql_affected_rows()\nfunction.\n\nURL: https://mariadb.com/kb/en/call/\n\n','','https://mariadb.com/kb/en/call/'); -insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (340,6,'MBRDISJOINT','MBRDisjoint(g1,g2)\n\nReturns 1 or 0 to indicate whether the Minimum Bounding Rectangles of\nthe two geometries g1 and g2 are disjoint (do not intersect).\n\nURL: https://mariadb.com/kb/en/mbrdisjoint/\n\n','','https://mariadb.com/kb/en/mbrdisjoint/'); -insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (341,14,'VALUES','Syntax:\nVALUES(col_name)\n\nIn an INSERT ... ON DUPLICATE KEY UPDATE statement, you can use the\nVALUES(col_name) function in the UPDATE clause to refer to column\nvalues from the INSERT portion of the statement. In other words,\nVALUES(col_name) in the UPDATE clause refers to the value of col_name\nthat would be inserted, had no duplicate-key conflict occurred. This\nfunction is especially useful in multiple-row inserts. The VALUES()\nfunction is meaningful only in the ON DUPLICATE KEY UPDATE clause of\nINSERT statements and returns NULL otherwise. See\nhttps://mariadb.com/kb/en/insert-on-duplicate-key-update/.\n\nURL: https://mariadb.com/kb/en/values/\n\n','MariaDB> INSERT INTO table (a,b,c) VALUES (1,2,3),(4,5,6)\n -> ON DUPLICATE KEY UPDATE c=VALUES(a)+VALUES(b);\n','https://mariadb.com/kb/en/values/'); -insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (342,37,'SUBSTRING_INDEX','Syntax:\nSUBSTRING_INDEX(str,delim,count)\n\nReturns the substring from string str before count occurrences of the\ndelimiter delim. If count is positive, everything to the left of the\nfinal delimiter (counting from the left) is returned. If count is\nnegative, everything to the right of the final delimiter (counting from\nthe right) is returned. SUBSTRING_INDEX() performs a case-sensitive\nmatch when searching for delim.\n\nURL: https://mariadb.com/kb/en/substring_index/\n\n','MariaDB> SELECT SUBSTRING_INDEX(\'www.mariadb.org\', \'.\', 2);\n -> \'www.mariadb\'\nMariaDB> SELECT SUBSTRING_INDEX(\'www.mariadb.org\', \'.\', -2);\n -> \'mariadb.org\'\n','https://mariadb.com/kb/en/substring_index/'); -insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (343,12,'ENCODE','Syntax:\nENCODE(str,pass_str)\n\nEncrypt str using pass_str as the password. To decrypt the result, use\nDECODE().\n\nThe result is a binary string of the same length as str.\n\nThe strength of the encryption is based on how good the random\ngenerator is. It should suffice for short strings.\n\nURL: https://mariadb.com/kb/en/encode/\n\n','','https://mariadb.com/kb/en/encode/'); -insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (344,23,'LOOP','Syntax:\n[begin_label:] LOOP\n statement_list\nEND LOOP [end_label]\n\nLOOP implements a simple loop construct, enabling repeated execution of\nthe statement list, which consists of one or more statements, each\nterminated by a semicolon (;) statement delimiter. The statements\nwithin the loop are repeated until the loop is terminated. Usually,\nthis is accomplished with a LEAVE statement. Within a stored function,\nRETURN can also be used, which exits the function entirely.\n\nNeglecting to include a loop-termination statement results in an\ninfinite loop.\n\nA LOOP statement can be labeled. For the rules regarding label use, see\n[HELP labels].\n\nURL: https://mariadb.com/kb/en/loop/\n\n','CREATE PROCEDURE doiterate(p1 INT)\nBEGIN\n label1: LOOP\n SET p1 = p1 + 1;\n IF p1 < 10 THEN\n ITERATE label1;\n END IF;\n LEAVE label1;\n END LOOP label1;\n SET @x = p1;\nEND;\n','https://mariadb.com/kb/en/loop/'); -insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (345,4,'TRUNCATE','Syntax:\nTRUNCATE(X,D)\n\nReturns the number X, truncated to D decimal places. If D is 0, the\nresult has no decimal point or fractional part. D can be negative to\ncause D digits left of the decimal point of the value X to become zero.\n\nURL: https://mariadb.com/kb/en/truncate/\n\n','MariaDB> SELECT TRUNCATE(1.223,1);\n -> 1.2\nMariaDB> SELECT TRUNCATE(1.999,1);\n -> 1.9\nMariaDB> SELECT TRUNCATE(1.999,0);\n -> 1\nMariaDB> SELECT TRUNCATE(-1.999,1);\n -> -1.9\nMariaDB> SELECT TRUNCATE(122,-2);\n -> 100\nMariaDB> SELECT TRUNCATE(10.28*100,0);\n -> 1028\n','https://mariadb.com/kb/en/truncate/'); -insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (346,31,'TIMESTAMPADD','Syntax:\nTIMESTAMPADD(unit,interval,datetime_expr)\n\nAdds the integer expression interval to the date or datetime expression\ndatetime_expr. The unit for interval is given by the unit argument,\nwhich should be one of the following values: MICROSECOND\n(microseconds), SECOND, MINUTE, HOUR, DAY, WEEK, MONTH, QUARTER, or\nYEAR.\n\nIt is possible to use FRAC_SECOND in place of MICROSECOND, but\nFRAC_SECOND is deprecated. FRAC_SECOND was removed in MySQL 5.5.3.\n\nThe unit value may be specified using one of keywords as shown, or with\na prefix of SQL_TSI_. For example, DAY and SQL_TSI_DAY both are legal.\n\nURL: https://mariadb.com/kb/en/timestampadd/\n\n','MariaDB> SELECT TIMESTAMPADD(MINUTE,1,\'2003-01-02\');\n -> \'2003-01-02 00:01:00\'\nMariaDB> SELECT TIMESTAMPADD(WEEK,1,\'2003-01-02\');\n -> \'2003-01-09\'\n','https://mariadb.com/kb/en/timestampadd/'); -insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (347,26,'SHOW','SHOW has many forms that provide information about databases, tables,\ncolumns, or status information about the server. This section describes\nthose following:\n\nSHOW AUTHORS\nSHOW {BINARY | MASTER} LOGS\nSHOW BINLOG EVENTS [IN \'log_name\'] [FROM pos] [LIMIT [offset,] row_count]\nSHOW CHARACTER SET [like_or_where]\nSHOW COLLATION [like_or_where]\nSHOW [FULL] COLUMNS FROM tbl_name [FROM db_name] [like_or_where]\nSHOW CONTRIBUTORS\nSHOW CREATE DATABASE db_name\nSHOW CREATE EVENT event_name\nSHOW CREATE FUNCTION func_name\nSHOW CREATE PROCEDURE proc_name\nSHOW CREATE TABLE tbl_name\nSHOW CREATE TRIGGER trigger_name\nSHOW CREATE VIEW view_name\nSHOW DATABASES [like_or_where]\nSHOW ENGINE engine_name {STATUS | MUTEX}\nSHOW [STORAGE] ENGINES\nSHOW ERRORS [LIMIT [offset,] row_count]\nSHOW EVENTS\nSHOW FUNCTION CODE func_name\nSHOW FUNCTION STATUS [like_or_where]\nSHOW GRANTS FOR user\nSHOW INDEX FROM tbl_name [FROM db_name]\nSHOW MASTER STATUS\nSHOW OPEN TABLES [FROM db_name] [like_or_where]\nSHOW PLUGINS\nSHOW PROCEDURE CODE proc_name\nSHOW PROCEDURE STATUS [like_or_where]\nSHOW PRIVILEGES\nSHOW [FULL] PROCESSLIST\nSHOW PROFILE [types] [FOR QUERY n] [OFFSET n] [LIMIT n]\nSHOW PROFILES\nSHOW SLAVE HOSTS\nSHOW SLAVE STATUS\nSHOW [GLOBAL | SESSION] STATUS [like_or_where]\nSHOW TABLE STATUS [FROM db_name] [like_or_where]\nSHOW [FULL] TABLES [FROM db_name] [like_or_where]\nSHOW TRIGGERS [FROM db_name] [like_or_where]\nSHOW [GLOBAL | SESSION] VARIABLES [like_or_where]\nSHOW WARNINGS [LIMIT [offset,] row_count]\n\nlike_or_where:\n LIKE \'pattern\'\n | WHERE expr\n\nIf the syntax for a given SHOW statement includes a LIKE \'pattern\'\npart, \'pattern\' is a string that can contain the SQL "%" and "_"\nwildcard characters. The pattern is useful for restricting statement\noutput to matching values.\n\nSeveral SHOW statements also accept a WHERE clause that provides more\nflexibility in specifying which rows to display. See\nhttps://mariadb.com/kb/en/extended-show/.\n\nURL: https://mariadb.com/kb/en/show/\n\n','','https://mariadb.com/kb/en/show/'); -insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (348,18,'GREATEST','Syntax:\nGREATEST(value1,value2,...)\n\nWith two or more arguments, returns the largest (maximum-valued)\nargument. The arguments are compared using the same rules as for\nLEAST().\n\nURL: https://mariadb.com/kb/en/greatest/\n\n','MariaDB> SELECT GREATEST(2,0);\n -> 2\nMariaDB> SELECT GREATEST(34.0,3.0,5.0,767.0);\n -> 767.0\nMariaDB> SELECT GREATEST(\'B\',\'A\',\'C\');\n -> \'C\'\n','https://mariadb.com/kb/en/greatest/'); -insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (349,26,'SHOW VARIABLES','Syntax:\nSHOW [GLOBAL | SESSION] VARIABLES\n [LIKE \'pattern\' | WHERE expr]\n\nSHOW VARIABLES shows the values of MySQL system variables. This\ninformation also can be obtained using the mysqladmin variables\ncommand. The LIKE clause, if present, indicates which variable names to\nmatch. The WHERE clause can be given to select rows using more general\nconditions, as discussed in\nhttps://mariadb.com/kb/en/extended-show/. This\nstatement does not require any privilege. It requires only the ability\nto connect to the server.\n\nWith the GLOBAL modifier, SHOW VARIABLES displays the values that are\nused for new connections to MySQL. As of MySQL 5.5.3, if a variable has\nno global value, no value is displayed. Before 5.5.3, the session value\nis displayed. With SESSION, SHOW VARIABLES displays the values that are\nin effect for the current connection. If no modifier is present, the\ndefault is SESSION. LOCAL is a synonym for SESSION.\nWith a LIKE clause, the statement displays only rows for those\nvariables with names that match the pattern. To obtain the row for a\nspecific variable, use a LIKE clause as shown:\n\nSHOW VARIABLES LIKE \'max_join_size\';\nSHOW SESSION VARIABLES LIKE \'max_join_size\';\n\nTo get a list of variables whose name match a pattern, use the "%"\nwildcard character in a LIKE clause:\n\nSHOW VARIABLES LIKE \'%size%\';\nSHOW GLOBAL VARIABLES LIKE \'%size%\';\n\nWildcard characters can be used in any position within the pattern to\nbe matched. Strictly speaking, because "_" is a wildcard that matches\nany single character, you should escape it as "\\_" to match it\nliterally. In practice, this is rarely necessary.\n\nURL: https://mariadb.com/kb/en/show-variables/\n\n','','https://mariadb.com/kb/en/show-variables/'); -insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (350,26,'BINLOG','Syntax:\nBINLOG \'str\'\n\nBINLOG is an internal-use statement. It is generated by the mysqlbinlog\nprogram as the printable representation of certain events in binary log\nfiles. (See https://mariadb.com/kb/en/mysqlbinlog/.)\nThe \'str\' value is a base 64-encoded string the that server decodes to\ndetermine the data change indicated by the corresponding event. This\nstatement requires the SUPER privilege.\n\nURL: https://mariadb.com/kb/en/binlog/\n\n','','https://mariadb.com/kb/en/binlog/'); -insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (351,16,'BIT_AND','Syntax:\nBIT_AND(expr)\n\nReturns the bitwise AND of all bits in expr. The calculation is\nperformed with 64-bit (BIGINT) precision.\n\nURL: https://mariadb.com/kb/en/bit_and/\n\n','','https://mariadb.com/kb/en/bit_and/'); -insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (352,31,'SECOND','Syntax:\nSECOND(time)\n\nReturns the second for time, in the range 0 to 59.\n\nURL: https://mariadb.com/kb/en/second/\n\n','MariaDB> SELECT SECOND(\'10:05:03\');\n -> 3\n','https://mariadb.com/kb/en/second/'); -insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (353,4,'ATAN2','Syntax:\nATAN(Y,X), ATAN2(Y,X)\n\nReturns the arc tangent of the two variables X and Y. It is similar to\ncalculating the arc tangent of Y / X, except that the signs of both\narguments are used to determine the quadrant of the result.\n\nURL: https://mariadb.com/kb/en/atan2/\n\n','MariaDB> SELECT ATAN(-2,2);\n -> -0.78539816339745\nMariaDB> SELECT ATAN2(PI(),0);\n -> 1.5707963267949\n','https://mariadb.com/kb/en/atan2/'); -insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (354,6,'MBRCONTAINS','MBRContains(g1,g2)\n\nReturns 1 or 0 to indicate whether the Minimum Bounding Rectangle of g1\ncontains the Minimum Bounding Rectangle of g2. This tests the opposite\nrelationship as MBRWithin().\n\nURL: https://mariadb.com/kb/en/mbrcontains/\n\n','MariaDB> SET @g1 = GeomFromText(\'Polygon((0 0,0 3,3 3,3 0,0 0))\');\nMariaDB> SET @g2 = GeomFromText(\'Point(1 1)\');\nMariaDB> SELECT MBRContains(@g1,@g2), MBRContains(@g2,@g1);\n----------------------+----------------------+\n| MBRContains(@g1,@g2) | MBRContains(@g2,@g1) |\n+----------------------+----------------------+\n| 1 | 0 |\n+----------------------+----------------------+\n','https://mariadb.com/kb/en/mbrcontains/'); -insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (355,31,'HOUR','Syntax:\nHOUR(time)\n\nReturns the hour for time. The range of the return value is 0 to 23 for\ntime-of-day values. However, the range of TIME values actually is much\nlarger, so HOUR can return values greater than 23.\n\nURL: https://mariadb.com/kb/en/hour/\n\n','MariaDB> SELECT HOUR(\'10:05:03\');\n -> 10\nMariaDB> SELECT HOUR(\'272:59:59\');\n -> 272\n','https://mariadb.com/kb/en/hour/'); -insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (356,27,'SELECT','Syntax:\nSELECT\n [ALL | DISTINCT | DISTINCTROW ]\n [HIGH_PRIORITY]\n [STRAIGHT_JOIN]\n [SQL_SMALL_RESULT] [SQL_BIG_RESULT] [SQL_BUFFER_RESULT]\n [SQL_CACHE | SQL_NO_CACHE] [SQL_CALC_FOUND_ROWS]\n select_expr [, select_expr ...]\n [FROM table_references\n [WHERE where_condition]\n [GROUP BY {col_name | expr | position}\n [ASC | DESC], ... [WITH ROLLUP]]\n [HAVING where_condition]\n [ORDER BY {col_name | expr | position}\n [ASC | DESC], ...]\n [LIMIT {[offset,] row_count | row_count OFFSET offset}]\n [PROCEDURE procedure_name(argument_list)]\n [INTO OUTFILE \'file_name\'\n [CHARACTER SET charset_name]\n export_options\n | INTO DUMPFILE \'file_name\'\n | INTO var_name [, var_name]]\n [FOR UPDATE | LOCK IN SHARE MODE]]\n\nSELECT is used to retrieve rows selected from one or more tables, and\ncan include UNION statements and subqueries. See [HELP UNION], and\nhttps://mariadb.com/kb/en/subqueries/.\n\nThe most commonly used clauses of SELECT statements are these:\n\no Each select_expr indicates a column that you want to retrieve. There\n must be at least one select_expr.\n\no table_references indicates the table or tables from which to retrieve\n rows. Its syntax is described in [HELP JOIN].\n\no The WHERE clause, if given, indicates the condition or conditions\n that rows must satisfy to be selected. where_condition is an\n expression that evaluates to true for each row to be selected. The\n statement selects all rows if there is no WHERE clause.\n\n In the WHERE expression, you can use any of the functions and\n operators that MySQL supports, except for aggregate (summary)\n functions. See\n https://mariadb.com/kb/en/select#select-expressions, and\n https://mariadb.com/kb/en/functions-and-operators/.\n\nSELECT can also be used to retrieve rows computed without reference to\nany table.\n\nURL: https://mariadb.com/kb/en/select/\n\n','','https://mariadb.com/kb/en/select/'); -insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (357,4,'COT','Syntax:\nCOT(X)\n\nReturns the cotangent of X.\n\nURL: https://mariadb.com/kb/en/cot/\n\n','MariaDB> SELECT COT(12);\n -> -1.5726734063977\nMariaDB> SELECT COT(0);\n -> NULL\n','https://mariadb.com/kb/en/cot/'); -insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (358,26,'SHOW CREATE EVENT','Syntax:\nSHOW CREATE EVENT event_name\n\nThis statement displays the CREATE EVENT statement needed to re-create\na given event. It requires the EVENT privilege for the database from\nwhich the event is to be shown. For example (using the same event\ne_daily defined and then altered in [HELP SHOW EVENTS]):\n\nURL: https://mariadb.com/kb/en/show-create-event/\n\n','MariaDB> SHOW CREATE EVENT test.e_daily\\G\n*************************** 1. row ***************************\n Event: e_daily\n sql_mode:\n time_zone: SYSTEM\n Create Event: CREATE EVENT `e_daily`\n ON SCHEDULE EVERY 1 DAY\n STARTS CURRENT_TIMESTAMP + INTERVAL 6 HOUR\n ON COMPLETION NOT PRESERVE\n ENABLE\n COMMENT \'Saves total number of sessions then\n clears the table each day\'\n DO BEGIN\n INSERT INTO site_activity.totals (time, total)\n SELECT CURRENT_TIMESTAMP, COUNT(*)\n FROM site_activity.sessions;\n DELETE FROM site_activity.sessions;\n END\ncharacter_set_client: latin1\ncollation_connection: latin1_swedish_ci\n Database Collation: latin1_swedish_ci\n','https://mariadb.com/kb/en/show-create-event/'); -insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (359,37,'LOAD_FILE','Syntax:\nLOAD_FILE(file_name)\n\nReads the file and returns the file contents as a string. To use this\nfunction, the file must be located on the server host, you must specify\nthe full path name to the file, and you must have the FILE privilege.\nThe file must be readable by all and its size less than\nmax_allowed_packet bytes. If the secure_file_priv system variable is\nset to a nonempty directory name, the file to be loaded must be located\nin that directory.\n\nIf the file does not exist or cannot be read because one of the\npreceding conditions is not satisfied, the function returns NULL.\n\nThe character_set_filesystem system variable controls interpretation of\nfile names that are given as literal strings.\n\nURL: https://mariadb.com/kb/en/load_file/\n\n','MariaDB> UPDATE t\n SET blob_col=LOAD_FILE(\'/tmp/picture\')\n WHERE id=1;\n','https://mariadb.com/kb/en/load_file/'); -insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (360,3,'POINTFROMTEXT','PointFromText(wkt[,srid])\n\nConstructs a POINT value using its WKT representation and SRID.\n\nURL: https://mariadb.com/kb/en/pointfromtext/\n\n','','https://mariadb.com/kb/en/pointfromtext/'); -insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (361,16,'GROUP_CONCAT','Syntax:\nGROUP_CONCAT(expr)\n\nThis function returns a string result with the concatenated non-NULL\nvalues from a group. It returns NULL if there are no non-NULL values.\nThe full syntax is as follows:\n\nGROUP_CONCAT([DISTINCT] expr [,expr ...]\n [ORDER BY {unsigned_integer | col_name | expr}\n [ASC | DESC] [,col_name ...]]\n [SEPARATOR str_val])\n\nURL: https://mariadb.com/kb/en/group_concat/\n\n','MariaDB> SELECT student_name,\n -> GROUP_CONCAT(test_score)\n -> FROM student\n -> GROUP BY student_name;\n','https://mariadb.com/kb/en/group_concat/'); -insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (362,31,'DATE_FORMAT','Syntax:\nDATE_FORMAT(date,format)\n\nFormats the date value according to the format string.\n\nURL: https://mariadb.com/kb/en/date_format/\n\n','MariaDB> SELECT DATE_FORMAT(\'2009-10-04 22:23:00\', \'%W %M %Y\');\n -> \'Sunday October 2009\'\nMariaDB> SELECT DATE_FORMAT(\'2007-10-04 22:23:00\', \'%H:%i:%s\');\n -> \'22:23:00\'\nMariaDB> SELECT DATE_FORMAT(\'1900-10-04 22:23:00\',\n -> \'%D %y %a %d %m %b %j\');\n -> \'4th 00 Thu 04 10 Oct 277\'\nMariaDB> SELECT DATE_FORMAT(\'1997-10-04 22:23:00\',\n -> \'%H %k %I %r %T %S %w\');\n -> \'22 22 10 10:23:00 PM 22:23:00 00 6\'\nMariaDB> SELECT DATE_FORMAT(\'1999-01-01\', \'%X %V\');\n -> \'1998 52\'\nMariaDB> SELECT DATE_FORMAT(\'2006-06-00\', \'%d\');\n -> \'00\'\n','https://mariadb.com/kb/en/date_format/'); -insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (363,17,'BENCHMARK','Syntax:\nBENCHMARK(count,expr)\n\nThe BENCHMARK() function executes the expression expr repeatedly count\ntimes. It may be used to time how quickly MySQL processes the\nexpression. The result value is always 0. The intended use is from\nwithin the mysql client, which reports query execution times:\n\nURL: https://mariadb.com/kb/en/benchmark/\n\n','MariaDB> SELECT BENCHMARK(1000000,ENCODE(\'hello\',\'goodbye\'));\n+----------------------------------------------+\n| BENCHMARK(1000000,ENCODE(\'hello\',\'goodbye\')) |\n+----------------------------------------------+\n| 0 |\n+----------------------------------------------+\n1 row in set (4.74 sec)\n','https://mariadb.com/kb/en/benchmark/'); -insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (364,31,'YEAR','Syntax:\nYEAR(date)\n\nReturns the year for date, in the range 1000 to 9999, or 0 for the\n"zero" date.\n\nURL: https://mariadb.com/kb/en/year/\n\n','MariaDB> SELECT YEAR(\'1987-01-01\');\n -> 1987\n','https://mariadb.com/kb/en/year/'); -insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (365,26,'SHOW ENGINE','Syntax:\nSHOW ENGINE engine_name {STATUS | MUTEX}\n\nSHOW ENGINE displays operational information about a storage engine.\nThe following statements currently are supported:\n\nSHOW ENGINE INNODB STATUS\nSHOW ENGINE INNODB MUTEX\nSHOW ENGINE PERFORMANCE_SCHEMA STATUS\n\nSHOW ENGINE INNODB STATUS displays extensive information from the\nstandard InnoDB Monitor about the state of the InnoDB storage engine.\nFor information about the standard monitor and other InnoDB Monitors\nthat provide information about InnoDB processing, see\nhttp://dev.mysql.com/doc/refman/5.5/en/innodb-monitors.html.\n\nSHOW ENGINE INNODB MUTEX displays InnoDB mutex statistics. The\nstatement displays the following fields:\n\no Type\n\n Always InnoDB.\n\no Name\n\n The source file where the mutex is implemented, and the line number\n in the file where the mutex is created. The line number may change\n depending on your version of MySQL.\n\no Status\n\n The mutex status. This field displays several values if UNIV_DEBUG\n was defined at MySQL compilation time (for example, in include/univ.i\n in the InnoDB part of the MySQL source tree). If UNIV_DEBUG was not\n defined, the statement displays only the os_waits value. In the\n latter case (without UNIV_DEBUG), the information on which the output\n is based is insufficient to distinguish regular mutexes and mutexes\n that protect rw-locks (which permit multiple readers or a single\n writer). Consequently, the output may appear to contain multiple rows\n for the same mutex.\n\n o count indicates how many times the mutex was requested.\n\n o spin_waits indicates how many times the spinlock had to run.\n\n o spin_rounds indicates the number of spinlock rounds. (spin_rounds\n divided by spin_waits provides the average round count.)\n\n o os_waits indicates the number of operating system waits. This\n occurs when the spinlock did not work (the mutex was not locked\n during the spinlock and it was necessary to yield to the operating\n system and wait).\n\n o os_yields indicates the number of times a the thread trying to lock\n a mutex gave up its timeslice and yielded to the operating system\n (on the presumption that permitting other threads to run will free\n the mutex so that it can be locked).\n\n o os_wait_times indicates the amount of time (in ms) spent in\n operating system waits, if the timed_mutexes system variable is 1\n (ON). If timed_mutexes is 0 (OFF), timing is disabled, so\n os_wait_times is 0. timed_mutexes is off by default.\n\nInformation from this statement can be used to diagnose system\nproblems. For example, large values of spin_waits and spin_rounds may\nindicate scalability problems.\n\nUse SHOW ENGINE PERFORMANCE_SCHEMA STATUS to inspect the internal\noperation of the Performance Schema code:\n\nMariaDB> SHOW ENGINE PERFORMANCE_SCHEMA STATUS\\G\n...\n*************************** 3. row ***************************\n Type: performance_schema\n Name: events_waits_history.row_size\nStatus: 76\n*************************** 4. row ***************************\n Type: performance_schema\n Name: events_waits_history.row_count\nStatus: 10000\n*************************** 5. row ***************************\n Type: performance_schema\n Name: events_waits_history.memory\nStatus: 760000\n...\n*************************** 57. row ***************************\n Type: performance_schema\n Name: performance_schema.memory\nStatus: 26459600\n...\n\nThe intent of this statement is to help the DBA to understand the\neffects that different options have on memory requirements.\n\nName values consist of two parts, which name an internal buffer and an\nattribute of the buffer, respectively:\n\no Internal buffers that are exposed as a table in the\n performance_schema database are named after the table. Examples:\n events_waits_history.row_size, mutex_instances.row_count.\n\no Internal buffers that are not exposed as a table are named within\n parentheses. Examples: (pfs_cond_class).row_size,\n (pfs_mutex_class).memory.\n\no Values that apply to the Performance Schema as a whole begin with\n performance_schema. Example: performance_schema.memory.\n\nAttributes have these meanings:\n\no row_size cannot be changed. It is the size of the internal record\n used by the implementation.\n\no row_count can be changed depending on the configuration options.\n\no For a table, tbl_name.memory is the product of row_size multiplied by\n row_count. For the Performance Schema as a whole,\n performance_schema.memory is the sum of all the memory used (the sum\n of all other memory values).\n\nIn some cases, there is a direct relationship between a configuration\nparameter and a SHOW ENGINE value. For example,\nevents_waits_history_long.row_count corresponds to\nperformance_schema_events_waits_history_long_size. In other cases, the\nrelationship is more complex. For example,\nevents_waits_history.row_count corresponds to\nperformance_schema_events_waits_history_size (the number of rows per\nthread) multiplied by performance_schema_max_thread_instances ( the\nnumber of threads).\n\nURL: https://mariadb.com/kb/en/show-engine/\n\n','','https://mariadb.com/kb/en/show-engine/'); -insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (366,14,'NAME_CONST','Syntax:\nNAME_CONST(name,value)\n\nReturns the given value. When used to produce a result set column,\nNAME_CONST() causes the column to have the given name. The arguments\nshould be constants.\n\nMariaDB> SELECT NAME_CONST(\'myname\', 14);\n+--------+\n| myname |\n+--------+\n| 14 |\n+--------+\n\nURL: https://mariadb.com/kb/en/name_const/\n\n','','https://mariadb.com/kb/en/name_const/'); -insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (367,14,'RELEASE_LOCK','Syntax:\nRELEASE_LOCK(str)\n\nReleases the lock named by the string str that was obtained with\nGET_LOCK(). Returns 1 if the lock was released, 0 if the lock was not\nestablished by this thread (in which case the lock is not released),\nand NULL if the named lock did not exist. The lock does not exist if it\nwas never obtained by a call to GET_LOCK() or if it has previously been\nreleased.\n\nThe DO statement is convenient to use with RELEASE_LOCK(). See [HELP\nDO].\n\nURL: https://mariadb.com/kb/en/release_lock/\n\n','','https://mariadb.com/kb/en/release_lock/'); -insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (368,18,'IS NULL','Syntax:\nIS NULL\n\nTests whether a value is NULL.\n\nURL: https://mariadb.com/kb/en/is-null/\n\n','MariaDB> SELECT 1 IS NULL, 0 IS NULL, NULL IS NULL;\n -> 0, 0, 1\n','https://mariadb.com/kb/en/is-null/'); -insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (369,31,'CONVERT_TZ','Syntax:\nCONVERT_TZ(dt,from_tz,to_tz)\n\nCONVERT_TZ() converts a datetime value dt from the time zone given by\nfrom_tz to the time zone given by to_tz and returns the resulting\nvalue. Time zones are specified as described in\nhttps://mariadb.com/kb/en/time-zones/. This\nfunction returns NULL if the arguments are invalid.\n\nURL: https://mariadb.com/kb/en/convert_tz/\n\n','MariaDB> SELECT CONVERT_TZ(\'2004-01-01 12:00:00\',\'GMT\',\'MET\');\n -> \'2004-01-01 13:00:00\'\nMariaDB> SELECT CONVERT_TZ(\'2004-01-01 12:00:00\',\'+00:00\',\'+10:00\');\n -> \'2004-01-01 22:00:00\'\n','https://mariadb.com/kb/en/convert_tz/'); -insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (370,31,'TIME_TO_SEC','Syntax:\nTIME_TO_SEC(time)\n\nReturns the time argument, converted to seconds.\n\nURL: https://mariadb.com/kb/en/time_to_sec/\n\n','MariaDB> SELECT TIME_TO_SEC(\'22:23:00\');\n -> 80580\nMariaDB> SELECT TIME_TO_SEC(\'00:39:38\');\n -> 2378\n','https://mariadb.com/kb/en/time_to_sec/'); -insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (371,31,'WEEKDAY','Syntax:\nWEEKDAY(date)\n\nReturns the weekday index for date (0 = Monday, 1 = Tuesday, ... 6 =\nSunday).\n\nURL: https://mariadb.com/kb/en/weekday/\n\n','MariaDB> SELECT WEEKDAY(\'2008-02-03 22:23:00\');\n -> 6\nMariaDB> SELECT WEEKDAY(\'2007-11-06\');\n -> 1\n','https://mariadb.com/kb/en/weekday/'); -insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (372,37,'EXPORT_SET','Syntax:\nEXPORT_SET(bits,on,off[,separator[,number_of_bits]])\n\nReturns a string such that for every bit set in the value bits, you get\nan on string and for every bit not set in the value, you get an off\nstring. Bits in bits are examined from right to left (from low-order to\nhigh-order bits). Strings are added to the result from left to right,\nseparated by the separator string (the default being the comma\ncharacter ","). The number of bits examined is given by number_of_bits,\nwhich has a default of 64 if not specified. number_of_bits is silently\nclipped to 64 if larger than 64. It is treated as an unsigned integer,\nso a value of -1 is effectively the same as 64.\n\nURL: https://mariadb.com/kb/en/export_set/\n\n','MariaDB> SELECT EXPORT_SET(5,\'Y\',\'N\',\',\',4);\n -> \'Y,N,Y,N\'\nMariaDB> SELECT EXPORT_SET(6,\'1\',\'0\',\',\',10);\n -> \'0,1,1,0,0,0,0,0,0,0\'\n','https://mariadb.com/kb/en/export_set/'); -insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (373,39,'ALTER SERVER','Syntax:\nALTER SERVER server_name\n OPTIONS (option [, option] ...)\n\nAlters the server information for server_name, adjusting any of the\noptions permitted in the CREATE SERVER statement. See [HELP CREATE\nSERVER]. The corresponding fields in the mysql.servers table are\nupdated accordingly. This statement requires the SUPER privilege.\n\nURL: https://mariadb.com/kb/en/alter-server/\n\n','ALTER SERVER s OPTIONS (USER \'sally\');\n','https://mariadb.com/kb/en/alter-server/'); -insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (374,23,'RESIGNAL','Syntax:\nRESIGNAL [condition_value]\n [SET signal_information_item\n [, signal_information_item] ...]\n\ncondition_value:\n SQLSTATE [VALUE] sqlstate_value\n | condition_name\n\nsignal_information_item:\n condition_information_item_name = simple_value_specification\n\ncondition_information_item_name:\n CLASS_ORIGIN\n | SUBCLASS_ORIGIN\n | MESSAGE_TEXT\n | MYSQL_ERRNO\n | CONSTRAINT_CATALOG\n | CONSTRAINT_SCHEMA\n | CONSTRAINT_NAME\n | CATALOG_NAME\n | SCHEMA_NAME\n | TABLE_NAME\n | COLUMN_NAME\n | CURSOR_NAME\n\ncondition_name, simple_value_specification:\n (see following discussion)\n\nRESIGNAL passes on the error condition information that is available\nduring execution of a condition handler within a compound statement\ninside a stored procedure or function, trigger, or event. RESIGNAL may\nchange some or all information before passing it on. RESIGNAL is\nrelated to SIGNAL, but instead of originating a condition as SIGNAL\ndoes, RESIGNAL relays existing condition information, possibly after\nmodifying it.\n\nRESIGNAL makes it possible to both handle an error and return the error\ninformation. Otherwise, by executing an SQL statement within the\nhandler, information that caused the handler\'s activation is destroyed.\nRESIGNAL also can make some procedures shorter if a given handler can\nhandle part of a situation, then pass the condition "up the line" to\nanother handler.\n\nNo special privileges are required to execute the RESIGNAL statement.\n\nFor condition_value and signal_information_item, the definitions and\nrules are the same for RESIGNAL as for SIGNAL (see [HELP SIGNAL]).\n\nThe RESIGNAL statement takes condition_value and SET clauses, both of\nwhich are optional. This leads to several possible uses:\n\no RESIGNAL alone:\n\nRESIGNAL;\n\no RESIGNAL with new signal information:\n\nRESIGNAL SET signal_information_item [, signal_information_item] ...;\n\no RESIGNAL with a condition value and possibly new signal information:\n\nRESIGNAL condition_value\n [SET signal_information_item [, signal_information_item] ...];\n\nURL: https://mariadb.com/kb/en/resignal/\n\n','','https://mariadb.com/kb/en/resignal/'); -insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (375,31,'TIME FUNCTION','Syntax:\nTIME(expr)\n\nExtracts the time part of the time or datetime expression expr and\nreturns it as a string.\n\nURL: https://mariadb.com/kb/en/time-function/\n\n','MariaDB> SELECT TIME(\'2003-12-31 01:02:03\');\n -> \'01:02:03\'\nMariaDB> SELECT TIME(\'2003-12-31 01:02:03.000123\');\n -> \'01:02:03.000123\'\n','https://mariadb.com/kb/en/time-function/'); -insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (376,31,'DATE_ADD','Syntax:\nDATE_ADD(date,INTERVAL expr unit), DATE_SUB(date,INTERVAL expr unit)\n\nThese functions perform date arithmetic. The date argument specifies\nthe starting date or datetime value. expr is an expression specifying\nthe interval value to be added or subtracted from the starting date.\nexpr is a string; it may start with a "-" for negative intervals. unit\nis a keyword indicating the units in which the expression should be\ninterpreted.\n\nURL: https://mariadb.com/kb/en/date_add/\n\n','MariaDB> SELECT \'2008-12-31 23:59:59\' + INTERVAL 1 SECOND;\n -> \'2009-01-01 00:00:00\'\nMariaDB> SELECT INTERVAL 1 DAY + \'2008-12-31\';\n -> \'2009-01-01\'\nMariaDB> SELECT \'2005-01-01\' - INTERVAL 1 SECOND;\n -> \'2004-12-31 23:59:59\'\nMariaDB> SELECT DATE_ADD(\'2000-12-31 23:59:59\',\n -> INTERVAL 1 SECOND);\n -> \'2001-01-01 00:00:00\'\nMariaDB> SELECT DATE_ADD(\'2010-12-31 23:59:59\',\n -> INTERVAL 1 DAY);\n -> \'2011-01-01 23:59:59\'\nMariaDB> SELECT DATE_ADD(\'2100-12-31 23:59:59\',\n -> INTERVAL \'1:1\' MINUTE_SECOND);\n -> \'2101-01-01 00:01:00\'\nMariaDB> SELECT DATE_SUB(\'2005-01-01 00:00:00\',\n -> INTERVAL \'1 1:1:1\' DAY_SECOND);\n -> \'2004-12-30 22:58:59\'\nMariaDB> SELECT DATE_ADD(\'1900-01-01 00:00:00\',\n -> INTERVAL \'-1 10\' DAY_HOUR);\n -> \'1899-12-30 14:00:00\'\nMariaDB> SELECT DATE_SUB(\'1998-01-02\', INTERVAL 31 DAY);\n -> \'1997-12-02\'\nMariaDB> SELECT DATE_ADD(\'1992-12-31 23:59:59.000002\',\n -> INTERVAL \'1.999999\' SECOND_MICROSECOND);\n -> \'1993-01-01 00:00:01.000001\'\n','https://mariadb.com/kb/en/date_add/'); -insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (377,37,'CAST','Syntax:\nCAST(expr AS type)\n\nThe CAST() function takes an expression of any type and produces a\nresult value of a specified type, similar to CONVERT(). See the\ndescription of CONVERT() for more information.\n\nURL: https://mariadb.com/kb/en/cast/\n\n','','https://mariadb.com/kb/en/cast/'); -insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (378,37,'SOUNDS LIKE','Syntax:\nexpr1 SOUNDS LIKE expr2\n\nThis is the same as SOUNDEX(expr1) = SOUNDEX(expr2).\n\nURL: https://mariadb.com/kb/en/sounds-like/\n\n','','https://mariadb.com/kb/en/sounds-like/'); -insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (379,31,'PERIOD_DIFF','Syntax:\nPERIOD_DIFF(P1,P2)\n\nReturns the number of months between periods P1 and P2. P1 and P2\nshould be in the format YYMM or YYYYMM. Note that the period arguments\nP1 and P2 are not date values.\n\nURL: https://mariadb.com/kb/en/period_diff/\n\n','MariaDB> SELECT PERIOD_DIFF(200802,200703);\n -> 11\n','https://mariadb.com/kb/en/period_diff/'); -insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (380,37,'LIKE','Syntax:\nexpr LIKE pat [ESCAPE \'escape_char\']\n\nPattern matching using SQL simple regular expression comparison.\nReturns 1 (TRUE) or 0 (FALSE). If either expr or pat is NULL, the\nresult is NULL.\n\nThe pattern need not be a literal string. For example, it can be\nspecified as a string expression or table column.\n\nURL: https://mariadb.com/kb/en/like/\n\n','MariaDB> SELECT \'David!\' LIKE \'David_\';\n -> 1\nMariaDB> SELECT \'David!\' LIKE \'%D%v%\';\n -> 1\n','https://mariadb.com/kb/en/like/'); -insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (381,24,'MULTIPOINT','MultiPoint(pt1,pt2,...)\n\nConstructs a MultiPoint value using Point or WKB Point arguments.\n\nURL: https://mariadb.com/kb/en/multipoint/\n\n','','https://mariadb.com/kb/en/multipoint/'); -insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (382,19,'>>','Syntax:\n>>\n\nShifts a longlong (BIGINT) number to the right.\n\nURL: https://mariadb.com/kb/en/shift-right/\n\n','MariaDB> SELECT 4 >> 2;\n -> 1\n','https://mariadb.com/kb/en/shift-right/'); -insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (383,23,'FETCH','Syntax:\nFETCH [[NEXT] FROM] cursor_name INTO var_name [, var_name] ...\n\nThis statement fetches the next row for the SELECT statement associated\nwith the specified cursor (which must be open), and advances the cursor\npointer. If a row exists, the fetched columns are stored in the named\nvariables. The number of columns retrieved by the SELECT statement must\nmatch the number of output variables specified in the FETCH statement.\n\nIf no more rows are available, a No Data condition occurs with SQLSTATE\nvalue \'02000\'. To detect this condition, you can set up a handler for\nit (or for a NOT FOUND condition). For an example, see\nhttps://mariadb.com/kb/en/cursor-overview/.\n\nURL: https://mariadb.com/kb/en/fetch/\n\n','','https://mariadb.com/kb/en/fetch/'); -insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (384,16,'AVG','Syntax:\nAVG([DISTINCT] expr)\n\nReturns the average value of expr. The DISTINCT option can be used to\nreturn the average of the distinct values of expr.\n\nAVG() returns NULL if there were no matching rows.\n\nURL: https://mariadb.com/kb/en/avg/\n\n','MariaDB> SELECT student_name, AVG(test_score)\n -> FROM student\n -> GROUP BY student_name;\n','https://mariadb.com/kb/en/avg/'); -insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (385,29,'TRUE FALSE','The constants TRUE and FALSE evaluate to 1 and 0, respectively. The\nconstant names can be written in any lettercase.\n\nMariaDB> SELECT TRUE, true, FALSE, false;\n -> 1, 1, 0, 0\n\nURL: https://mariadb.com/kb/en/true-false/\n\n','','https://mariadb.com/kb/en/true-false/'); -insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (386,6,'MBRWITHIN','MBRWithin(g1,g2)\n\nReturns 1 or 0 to indicate whether the Minimum Bounding Rectangle of g1\nis within the Minimum Bounding Rectangle of g2. This tests the opposite\nrelationship as MBRContains().\n\nURL: https://mariadb.com/kb/en/mbrwithin/\n\n','MariaDB> SET @g1 = GeomFromText(\'Polygon((0 0,0 3,3 3,3 0,0 0))\');\nMariaDB> SET @g2 = GeomFromText(\'Polygon((0 0,0 5,5 5,5 0,0 0))\');\nMariaDB> SELECT MBRWithin(@g1,@g2), MBRWithin(@g2,@g1);\n+--------------------+--------------------+\n| MBRWithin(@g1,@g2) | MBRWithin(@g2,@g1) |\n+--------------------+--------------------+\n| 1 | 0 |\n+--------------------+--------------------+\n','https://mariadb.com/kb/en/mbrwithin/'); -insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (387,17,'SESSION_USER','Syntax:\nSESSION_USER()\n\nSESSION_USER() is a synonym for USER().\n\nURL: https://mariadb.com/kb/en/session_user/\n\n','','https://mariadb.com/kb/en/session_user/'); -insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (388,18,'IN','Syntax:\nexpr IN (value,...)\n\nReturns 1 if expr is equal to any of the values in the IN list, else\nreturns 0. If all values are constants, they are evaluated according to\nthe type of expr and sorted. The search for the item then is done using\na binary search. This means IN is very quick if the IN value list\nconsists entirely of constants. Otherwise, type conversion takes place\naccording to the rules described in\nhttps://mariadb.com/kb/en/type-conversion/, but\napplied to all the arguments.\n\nURL: https://mariadb.com/kb/en/in/\n\n','MariaDB> SELECT 2 IN (0,3,5,7);\n -> 0\nMariaDB> SELECT \'wefwf\' IN (\'wee\',\'wefwf\',\'weg\');\n -> 1\n','https://mariadb.com/kb/en/in/'); -insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (389,37,'QUOTE','Syntax:\nQUOTE(str)\n\nQuotes a string to produce a result that can be used as a properly\nescaped data value in an SQL statement. The string is returned enclosed\nby single quotation marks and with each instance of backslash ("\\"),\nsingle quote ("\'"), ASCII NUL, and Control+Z preceded by a backslash.\nIf the argument is NULL, the return value is the word "NULL" without\nenclosing single quotation marks.\n\nURL: https://mariadb.com/kb/en/quote/\n\n','MariaDB> SELECT QUOTE(\'Don\\\'t!\');\n -> \'Don\\\'t!\'\nMariaDB> SELECT QUOTE(NULL);\n -> NULL\n','https://mariadb.com/kb/en/quote/'); -insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (390,26,'HELP COMMAND','Syntax:\nMariaDB> help search_string\n\nIf you provide an argument to the help command, mysql uses it as a\nsearch string to access server-side help from the contents of the MySQL\nReference Manual. The proper operation of this command requires that\nthe help tables in the mysql database be initialized with help topic\ninformation .\n\nIf there is no match for the search string, the search fails:\n\nMariaDB> help me\n\nNothing found\nPlease try to run \'help contents\' for a list of all accessible topics\n\nUse help contents to see a list of the help categories:\n\nMariaDB> help contents\nYou asked for help about help category: "Contents"\nFor more information, type \'help \', where is one of the\nfollowing categories:\n Account Management\n Administration\n Data Definition\n Data Manipulation\n Data Types\n Functions\n Functions and Modifiers for Use with GROUP BY\n Geographic Features\n Language Structure\n Plugins\n Storage Engines\n Stored Routines\n Table Maintenance\n Transactions\n Triggers\n\nIf the search string matches multiple items, mysql shows a list of\nmatching topics:\n\nMariaDB> help logs\nMany help items for your request exist.\nTo make a more specific request, please type \'help \',\nwhere is one of the following topics:\n SHOW\n SHOW BINARY LOGS\n SHOW ENGINE\n SHOW LOGS\n\nUse a topic as the search string to see the help entry for that topic:\n\nMariaDB> help show binary logs\nName: \'SHOW BINARY LOGS\'\nDescription:\nSyntax:\nSHOW BINARY LOGS\nSHOW MASTER LOGS\n\nLists the binary log files on the server. This statement is used as\npart of the procedure described in [purge-binary-logs], that shows how\nto determine which logs can be purged.\n\nMariaDB> SHOW BINARY LOGS;\n+---------------+-----------+\n| Log_name | File_size |\n+---------------+-----------+\n| binlog.000015 | 724935 |\n| binlog.000016 | 733481 |\n+---------------+-----------+\n\nURL: https://mariadb.com/kb/en/help-command/\n\n','','https://mariadb.com/kb/en/help-command/'); -insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (391,31,'QUARTER','Syntax:\nQUARTER(date)\n\nReturns the quarter of the year for date, in the range 1 to 4.\n\nURL: https://mariadb.com/kb/en/quarter/\n\n','MariaDB> SELECT QUARTER(\'2008-04-01\');\n -> 2\n','https://mariadb.com/kb/en/quarter/'); -insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (392,37,'POSITION','Syntax:\nPOSITION(substr IN str)\n\nPOSITION(substr IN str) is a synonym for LOCATE(substr,str).\n\nURL: https://mariadb.com/kb/en/position/\n\n','','https://mariadb.com/kb/en/position/'); -insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (393,26,'SHOW CREATE FUNCTION','Syntax:\nSHOW CREATE FUNCTION func_name\n\nThis statement is similar to SHOW CREATE PROCEDURE but for stored\nfunctions. See [HELP SHOW CREATE PROCEDURE].\n\nURL: https://mariadb.com/kb/en/show-create-function/\n\n','','https://mariadb.com/kb/en/show-create-function/'); -insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (394,14,'IS_USED_LOCK','Syntax:\nIS_USED_LOCK(str)\n\nChecks whether the lock named str is in use (that is, locked). If so,\nit returns the connection identifier of the client that holds the lock.\nOtherwise, it returns NULL.\n\nURL: https://mariadb.com/kb/en/is_used_lock/\n\n','','https://mariadb.com/kb/en/is_used_lock/'); -insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (395,3,'POLYFROMTEXT','PolyFromText(wkt[,srid]), PolygonFromText(wkt[,srid])\n\nConstructs a POLYGON value using its WKT representation and SRID.\n\nURL: https://mariadb.com/kb/en/polyfromtext/\n\n','','https://mariadb.com/kb/en/polyfromtext/'); -insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (396,12,'DES_ENCRYPT','Syntax:\nDES_ENCRYPT(str[,{key_num|key_str}])\n\nEncrypts the string with the given key using the Triple-DES algorithm.\n\nThis function works only if MySQL has been configured with SSL support.\nSee https://mariadb.com/kb/en/ssl-connections/.\n\nThe encryption key to use is chosen based on the second argument to\nDES_ENCRYPT(), if one was given. With no argument, the first key from\nthe DES key file is used. With a key_num argument, the given key number\n(0 to 9) from the DES key file is used. With a key_str argument, the\ngiven key string is used to encrypt str.\n\nThe key file can be specified with the --des-key-file server option.\n\nThe return string is a binary string where the first character is\nCHAR(128 | key_num). If an error occurs, DES_ENCRYPT() returns NULL.\n\nThe 128 is added to make it easier to recognize an encrypted key. If\nyou use a string key, key_num is 127.\n\nThe string length for the result is given by this formula:\n\nnew_len = orig_len + (8 - (orig_len % 8)) + 1\n\nEach line in the DES key file has the following format:\n\nkey_num des_key_str\n\nEach key_num value must be a number in the range from 0 to 9. Lines in\nthe file may be in any order. des_key_str is the string that is used to\nencrypt the message. There should be at least one space between the\nnumber and the key. The first key is the default key that is used if\nyou do not specify any key argument to DES_ENCRYPT().\n\nYou can tell MySQL to read new key values from the key file with the\nFLUSH DES_KEY_FILE statement. This requires the RELOAD privilege.\n\nOne benefit of having a set of default keys is that it gives\napplications a way to check for the existence of encrypted column\nvalues, without giving the end user the right to decrypt those values.\n\nURL: https://mariadb.com/kb/en/des_encrypt/\n\n','MariaDB> SELECT customer_address FROM customer_table \n > WHERE crypted_credit_card = DES_ENCRYPT(\'credit_card_number\');\n','https://mariadb.com/kb/en/des_encrypt/'); -insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (397,4,'CEIL','Syntax:\nCEIL(X)\n\nCEIL() is a synonym for CEILING().\n\nURL: https://mariadb.com/kb/en/ceil/\n\n','','https://mariadb.com/kb/en/ceil/'); -insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (398,37,'LENGTH','Syntax:\nLENGTH(str)\n\nReturns the length of the string str, measured in bytes. A multi-byte\ncharacter counts as multiple bytes. This means that for a string\ncontaining five 2-byte characters, LENGTH() returns 10, whereas\nCHAR_LENGTH() returns 5.\n\nURL: https://mariadb.com/kb/en/length/\n\n','MariaDB> SELECT LENGTH(\'text\');\n -> 4\n','https://mariadb.com/kb/en/length/'); -insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (399,31,'STR_TO_DATE','Syntax:\nSTR_TO_DATE(str,format)\n\nThis is the inverse of the DATE_FORMAT() function. It takes a string\nstr and a format string format. STR_TO_DATE() returns a DATETIME value\nif the format string contains both date and time parts, or a DATE or\nTIME value if the string contains only date or time parts. If the date,\ntime, or datetime value extracted from str is illegal, STR_TO_DATE()\nreturns NULL and produces a warning.\n\nThe server scans str attempting to match format to it. The format\nstring can contain literal characters and format specifiers beginning\nwith %. Literal characters in format must match literally in str.\nFormat specifiers in format must match a date or time part in str. For\nthe specifiers that can be used in format, see the DATE_FORMAT()\nfunction description.\n\nMariaDB> SELECT STR_TO_DATE(\'01,5,2013\',\'%d,%m,%Y\');\n -> \'2013-05-01\'\nMariaDB> SELECT STR_TO_DATE(\'May 1, 2013\',\'%M %d,%Y\');\n -> \'2013-05-01\'\n\nScanning starts at the beginning of str and fails if format is found\nnot to match. Extra characters at the end of str are ignored.\n\nMariaDB> SELECT STR_TO_DATE(\'a09:30:17\',\'a%h:%i:%s\');\n -> \'09:30:17\'\nMariaDB> SELECT STR_TO_DATE(\'a09:30:17\',\'%h:%i:%s\');\n -> NULL\nMariaDB> SELECT STR_TO_DATE(\'09:30:17a\',\'%h:%i:%s\');\n -> \'09:30:17\'\n\nUnspecified date or time parts have a value of 0, so incompletely\nspecified values in str produce a result with some or all parts set to\n0:\n\nMariaDB> SELECT STR_TO_DATE(\'abc\',\'abc\');\n -> \'0000-00-00\'\nMariaDB> SELECT STR_TO_DATE(\'9\',\'%m\');\n -> \'0000-09-00\'\nMariaDB> SELECT STR_TO_DATE(\'9\',\'%s\');\n -> \'00:00:09\'\n\nURL: https://mariadb.com/kb/en/str_to_date/\n\n','','https://mariadb.com/kb/en/str_to_date/'); -insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (400,11,'Y','Y(p)\n\nReturns the Y-coordinate value for the Point object p as a\ndouble-precision number.\n\nURL: https://mariadb.com/kb/en/y/\n\n','MariaDB> SELECT Y(POINT(56.7, 53.34));\n+-----------------------+\n| Y(POINT(56.7, 53.34)) |\n+-----------------------+\n| 53.34 |\n+-----------------------+\n','https://mariadb.com/kb/en/y/'); -insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (401,20,'CHECKSUM TABLE','Syntax:\nCHECKSUM TABLE tbl_name [, tbl_name] ... [ QUICK | EXTENDED ]\n\nCHECKSUM TABLE reports a table checksum. This statement requires the\nSELECT privilege for the table.\n\nWith QUICK, the live table checksum is reported if it is available, or\nNULL otherwise. This is very fast. A live checksum is enabled by\nspecifying the CHECKSUM=1 table option when you create the table;\ncurrently, this is supported only for MyISAM tables. See [HELP CREATE\nTABLE].\n\nWith EXTENDED, the entire table is read row by row and the checksum is\ncalculated. This can be very slow for large tables.\n\nIf neither QUICK nor EXTENDED is specified, MySQL returns a live\nchecksum if the table storage engine supports it and scans the table\notherwise.\n\nFor a nonexistent table, CHECKSUM TABLE returns NULL and generates a\nwarning.\n\nIn MySQL 5.5, CHECKSUM TABLE returns 0 for partitioned tables unless\nyou include the EXTENDED option. This issue is resolved in MySQL 5.6.\n(Bug #11933226, Bug #60681)\n\nThe checksum value depends on the table row format. If the row format\nchanges, the checksum also changes. For example, the storage format for\nVARCHAR changed between MySQL 4.1 and 5.0, so if a 4.1 table is\nupgraded to MySQL 5.0, the checksum value may change.\n\nURL: https://mariadb.com/kb/en/checksum-table/\n\n','','https://mariadb.com/kb/en/checksum-table/'); -insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (402,2,'NUMINTERIORRINGS','NumInteriorRings(poly)\n\nReturns the number of interior rings in the Polygon value poly.\n\nURL: https://mariadb.com/kb/en/numinteriorrings/\n\n','MariaDB> SET @poly =\n -> \'Polygon((0 0,0 3,3 3,3 0,0 0),(1 1,1 2,2 2,2 1,1 1))\';\nMariaDB> SELECT NumInteriorRings(GeomFromText(@poly));\n+---------------------------------------+\n| NumInteriorRings(GeomFromText(@poly)) |\n+---------------------------------------+\n| 1 |\n+---------------------------------------+\n','https://mariadb.com/kb/en/numinteriorrings/'); -insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (403,2,'INTERIORRINGN','InteriorRingN(poly,N)\n\nReturns the N-th interior ring for the Polygon value poly as a\nLineString. Rings are numbered beginning with 1.\n\nURL: https://mariadb.com/kb/en/interiorringn/\n\n','MariaDB> SET @poly =\n -> \'Polygon((0 0,0 3,3 3,3 0,0 0),(1 1,1 2,2 2,2 1,1 1))\';\nMariaDB> SELECT AsText(InteriorRingN(GeomFromText(@poly),1));\n+----------------------------------------------+\n| AsText(InteriorRingN(GeomFromText(@poly),1)) |\n+----------------------------------------------+\n| LINESTRING(1 1,1 2,2 2,2 1,1 1) |\n+----------------------------------------------+\n','https://mariadb.com/kb/en/interiorringn/'); -insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (404,31,'UTC_TIME','Syntax:\nUTC_TIME, UTC_TIME()\n\nReturns the current UTC time as a value in \'HH:MM:SS\' or HHMMSS.uuuuuu\nformat, depending on whether the function is used in a string or\nnumeric context.\n\nURL: https://mariadb.com/kb/en/utc_time/\n\n','MariaDB> SELECT UTC_TIME(), UTC_TIME() + 0;\n -> \'18:07:53\', 180753.000000\n','https://mariadb.com/kb/en/utc_time/'); -insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (405,39,'DROP FUNCTION','The DROP FUNCTION statement is used to drop stored functions and\nuser-defined functions (UDFs):\n\no For information about dropping stored functions, see [HELP DROP\n PROCEDURE].\n\no For information about dropping user-defined functions, see [HELP DROP\n FUNCTION UDF].\n\nURL: https://mariadb.com/kb/en/drop-function/\n\n','','https://mariadb.com/kb/en/drop-function/'); -insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (406,39,'ALTER EVENT','Syntax:\nALTER\n [DEFINER = { user | CURRENT_USER }]\n EVENT event_name\n [ON SCHEDULE schedule]\n [ON COMPLETION [NOT] PRESERVE]\n [RENAME TO new_event_name]\n [ENABLE | DISABLE | DISABLE ON SLAVE]\n [COMMENT \'comment\']\n [DO event_body]\n\nThe ALTER EVENT statement changes one or more of the characteristics of\nan existing event without the need to drop and recreate it. The syntax\nfor each of the DEFINER, ON SCHEDULE, ON COMPLETION, COMMENT, ENABLE /\nDISABLE, and DO clauses is exactly the same as when used with CREATE\nEVENT. (See [HELP CREATE EVENT].)\n\nAny user can alter an event defined on a database for which that user\nhas the EVENT privilege. When a user executes a successful ALTER EVENT\nstatement, that user becomes the definer for the affected event.\n\nALTER EVENT works only with an existing event:\n\nMariaDB> ALTER EVENT no_such_event \n > ON SCHEDULE \n > EVERY \'2:3\' DAY_HOUR;\nERROR 1517 (HY000): Unknown event \'no_such_event\'\n\nURL: https://mariadb.com/kb/en/alter-event/\n\n','','https://mariadb.com/kb/en/alter-event/'); -insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (407,16,'STDDEV','Syntax:\nSTDDEV(expr)\n\nReturns the population standard deviation of expr. This function is\nprovided for compatibility with Oracle. The standard SQL function\nSTDDEV_POP() can be used instead.\n\nThis function returns NULL if there were no matching rows.\n\nURL: https://mariadb.com/kb/en/stddev/\n\n','','https://mariadb.com/kb/en/stddev/'); -insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (408,31,'DATE_SUB','Syntax:\nDATE_SUB(date,INTERVAL expr unit)\n\nSee the description for DATE_ADD().\n\nURL: https://mariadb.com/kb/en/date_sub/\n\n','','https://mariadb.com/kb/en/date_sub/'); -insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (409,31,'PERIOD_ADD','Syntax:\nPERIOD_ADD(P,N)\n\nAdds N months to period P (in the format YYMM or YYYYMM). Returns a\nvalue in the format YYYYMM. Note that the period argument P is not a\ndate value.\n\nURL: https://mariadb.com/kb/en/period_add/\n\n','MariaDB> SELECT PERIOD_ADD(200801,2);\n -> 200803\n','https://mariadb.com/kb/en/period_add/'); -insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (410,19,'|','Syntax:\n|\n\nBitwise OR:\n\nURL: https://mariadb.com/kb/en/bitwise-or/\n\n','MariaDB> SELECT 29 | 15;\n -> 31\n','https://mariadb.com/kb/en/bitwise-or/'); -insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (411,3,'GEOMFROMTEXT','GeomFromText(wkt[,srid]), GeometryFromText(wkt[,srid])\n\nConstructs a geometry value of any type using its WKT representation\nand SRID.\n\nURL: https://mariadb.com/kb/en/geomfromtext/\n\n','','https://mariadb.com/kb/en/geomfromtext/'); -insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (412,14,'UUID_SHORT','Syntax:\nUUID_SHORT()\n\nReturns a "short" universal identifier as a 64-bit unsigned integer\n(rather than a string-form 128-bit identifier as returned by the UUID()\nfunction).\n\nThe value of UUID_SHORT() is guaranteed to be unique if the following\nconditions hold:\n\no The server_id of the current host is unique among your set of master\n and slave servers\n\no server_id is between 0 and 255\n\no You do not set back your system time for your server between mysqld\n restarts\n\no You do not invoke UUID_SHORT() on average more than 16 million times\n per second between mysqld restarts\n\nThe UUID_SHORT() return value is constructed this way:\n\n (server_id & 255) << 56\n+ (server_startup_time_in_seconds << 24)\n+ incremented_variable++;\n\nURL: https://mariadb.com/kb/en/uuid_short/\n\n','MariaDB> SELECT UUID_SHORT();\n -> 92395783831158784\n','https://mariadb.com/kb/en/uuid_short/'); -insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (413,37,'RIGHT','Syntax:\nRIGHT(str,len)\n\nReturns the rightmost len characters from the string str, or NULL if\nany argument is NULL.\n\nURL: https://mariadb.com/kb/en/right/\n\n','MariaDB> SELECT RIGHT(\'foobarbar\', 4);\n -> \'rbar\'\n','https://mariadb.com/kb/en/right/'); -insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (414,31,'DATEDIFF','Syntax:\nDATEDIFF(expr1,expr2)\n\nDATEDIFF() returns expr1 - expr2 expressed as a value in days from one\ndate to the other. expr1 and expr2 are date or date-and-time\nexpressions. Only the date parts of the values are used in the\ncalculation.\n\nURL: https://mariadb.com/kb/en/datediff/\n\n','MariaDB> SELECT DATEDIFF(\'2007-12-31 23:59:59\',\'2007-12-30\');\n -> 1\nMariaDB> SELECT DATEDIFF(\'2010-11-30 23:59:59\',\'2010-12-31\');\n -> -31\n','https://mariadb.com/kb/en/datediff/'); -insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (415,39,'DROP TABLESPACE','Syntax:\nDROP TABLESPACE tablespace_name\n ENGINE [=] engine_name\n\nThis statement is used with NDB cluster, which is not supported by MariaDB.\n\nURL: https://mariadb.com/kb/en/drop-tablespace/\n\n','','https://mariadb.com/kb/en/drop-tablespace/'); -insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (416,39,'DROP PROCEDURE','Syntax:\nDROP {PROCEDURE | FUNCTION} [IF EXISTS] sp_name\n\nThis statement is used to drop a stored procedure or function. That is,\nthe specified routine is removed from the server. You must have the\nALTER ROUTINE privilege for the routine. (If the\nautomatic_sp_privileges system variable is enabled, that privilege and\nEXECUTE are granted automatically to the routine creator when the\nroutine is created and dropped from the creator when the routine is\ndropped. See\nhttps://mariadb.com/kb/en/stored-routine-privileges/.\n)\n\nThe IF EXISTS clause is a MySQL extension. It prevents an error from\noccurring if the procedure or function does not exist. A warning is\nproduced that can be viewed with SHOW WARNINGS.\n\nURL: https://mariadb.com/kb/en/drop-procedure/\n\n','','https://mariadb.com/kb/en/drop-procedure/'); -insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (417,20,'CHECK TABLE','Syntax:\nCHECK TABLE tbl_name [, tbl_name] ... [option] ...\n\noption = {FOR UPGRADE | QUICK | FAST | MEDIUM | EXTENDED | CHANGED}\n\nCHECK TABLE checks a table or tables for errors. CHECK TABLE works for\nInnoDB, MyISAM, ARCHIVE, and CSV tables. For MyISAM tables, the key\nstatistics are updated as well.\n\nTo check a table, you must have some privilege for it.\n\nCHECK TABLE can also check views for problems, such as tables that are\nreferenced in the view definition that no longer exist.\n\nCHECK TABLE is supported for partitioned tables, and you can use ALTER\nTABLE ... CHECK PARTITION to check one or more partitions; for more\ninformation, see [HELP ALTER TABLE].\n\nURL: https://mariadb.com/kb/en/sql-commands-check-table/\n\n','','https://mariadb.com/kb/en/sql-commands-check-table/'); -insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (418,37,'BIN','Syntax:\nBIN(N)\n\nReturns a string representation of the binary value of N, where N is a\nlonglong (BIGINT) number. This is equivalent to CONV(N,10,2). Returns\nNULL if N is NULL.\n\nURL: https://mariadb.com/kb/en/bin/\n\n','MariaDB> SELECT BIN(12);\n -> \'1100\'\n','https://mariadb.com/kb/en/bin/'); -insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (419,5,'INSTALL PLUGIN','Syntax:\nINSTALL PLUGIN plugin_name SONAME \'shared_library_name\'\n\nThis statement installs a server plugin. It requires the INSERT\nprivilege for the mysql.plugin table.\n\nplugin_name is the name of the plugin as defined in the plugin\ndescriptor structure contained in the library file (see\nhttp://dev.mysql.com/doc/refman/5.5/en/plugin-data-structures.html).\nPlugin names are not case sensitive. For maximal compatibility, plugin\nnames should be limited to ASCII letters, digits, and underscore\nbecause they are used in C source files, shell command lines, M4 and\nBourne shell scripts, and SQL environments.\n\nshared_library_name is the name of the shared library that contains the\nplugin code. The name includes the file name extension (for example,\nlibmyplugin.so, libmyplugin.dll, or libmyplugin.dylib).\n\nThe shared library must be located in the plugin directory (the\ndirectory named by the plugin_dir system variable). The library must be\nin the plugin directory itself, not in a subdirectory. By default,\nplugin_dir is the plugin directory under the directory named by the\npkglibdir configuration variable, but it can be changed by setting the\nvalue of plugin_dir at server startup. For example, set its value in a\nmy.cnf file:\n\n[mysqld]\nplugin_dir=/path/to/plugin/directory\n\nIf the value of plugin_dir is a relative path name, it is taken to be\nrelative to the MySQL base directory (the value of the basedir system\nvariable).\n\nINSTALL PLUGIN loads and initializes the plugin code to make the plugin\navailable for use. A plugin is initialized by executing its\ninitialization function, which handles any setup that the plugin must\nperform before it can be used. When the server shuts down, it executes\nthe deinitialization function for each plugin that is loaded so that\nthe plugin has a change to perform any final cleanup.\n\nINSTALL PLUGIN also registers the plugin by adding a line that\nindicates the plugin name and library file name to the mysql.plugin\ntable. At server startup, the server loads and initializes any plugin\nthat is listed in the mysql.plugin table. This means that a plugin is\ninstalled with INSTALL PLUGIN only once, not every time the server\nstarts. Plugin loading at startup does not occur if the server is\nstarted with the --skip-grant-tables option.\n\nA plugin library can contain multiple plugins. For each of them to be\ninstalled, use a separate INSTALL PLUGIN statement. Each statement\nnames a different plugin, but all of them specify the same library\nname.\n\nURL: https://mariadb.com/kb/en/install-plugin/\n\n','','https://mariadb.com/kb/en/install-plugin/'); -insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (420,23,'DECLARE CURSOR','Syntax:\nDECLARE cursor_name CURSOR FOR select_statement\n\nThis statement declares a cursor and associates it with a SELECT\nstatement that retrieves the rows to be traversed by the cursor. To\nfetch the rows later, use a FETCH statement. The number of columns\nretrieved by the SELECT statement must match the number of output\nvariables specified in the FETCH statement.\n\nThe SELECT statement cannot have an INTO clause.\n\nCursor declarations must appear before handler declarations and after\nvariable and condition declarations.\n\nA stored program may contain multiple cursor declarations, but each\ncursor declared in a given block must have a unique name. For an\nexample, see https://mariadb.com/kb/en/programmatic-and-compound-statements-cursors/.\n\nFor information available through SHOW statements, it is possible in\nmany cases to obtain equivalent information by using a cursor with an\nINFORMATION_SCHEMA table.\n\nURL: https://mariadb.com/kb/en/declare-cursor/\n\n','','https://mariadb.com/kb/en/declare-cursor/'); -insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (421,27,'LOAD DATA','Syntax:\nLOAD DATA [LOW_PRIORITY | CONCURRENT] [LOCAL] INFILE \'file_name\'\n [REPLACE | IGNORE]\n INTO TABLE tbl_name\n [CHARACTER SET charset_name]\n [{FIELDS | COLUMNS}\n [TERMINATED BY \'string\']\n [[OPTIONALLY] ENCLOSED BY \'char\']\n [ESCAPED BY \'char\']\n ]\n [LINES\n [STARTING BY \'string\']\n [TERMINATED BY \'string\']\n ]\n [IGNORE number {LINES | ROWS}]\n [(col_name_or_user_var,...)]\n [SET col_name = expr,...]\n\nThe LOAD DATA INFILE statement reads rows from a text file into a table\nat a very high speed. The file name must be given as a literal string.\n\nLOAD DATA INFILE is the complement of SELECT ... INTO OUTFILE. (See\nhttps://mariadb.com/kb/en/select-into/.) To write data\nfrom a table to a file, use SELECT ... INTO OUTFILE. To read the file\nback into a table, use LOAD DATA INFILE. The syntax of the FIELDS and\nLINES clauses is the same for both statements. Both clauses are\noptional, but FIELDS must precede LINES if both are specified.\n\nFor more information about the efficiency of INSERT versus LOAD DATA\nINFILE and speeding up LOAD DATA INFILE, see\nhttp://dev.mysql.com/doc/refman/5.5/en/insert-speed.html.\n\nThe character set indicated by the character_set_database system\nvariable is used to interpret the information in the file. SET NAMES\nand the setting of character_set_client do not affect interpretation of\ninput. If the contents of the input file use a character set that\ndiffers from the default, it is usually preferable to specify the\ncharacter set of the file by using the CHARACTER SET clause. A\ncharacter set of binary specifies "no conversion."\n\nLOAD DATA INFILE interprets all fields in the file as having the same\ncharacter set, regardless of the data types of the columns into which\nfield values are loaded. For proper interpretation of file contents,\nyou must ensure that it was written with the correct character set. For\nexample, if you write a data file with mysqldump -T or by issuing a\nSELECT ... INTO OUTFILE statement in mysql, be sure to use a\n--default-character-set option with mysqldump or mysql so that output\nis written in the character set to be used when the file is loaded with\nLOAD DATA INFILE.\n\n*Note*: It is not possible to load data files that use the ucs2, utf16,\nor utf32 character set.\n\nThe character_set_filesystem system variable controls the\ninterpretation of the file name.\n\nYou can also load data files by using the mysqlimport utility; it\noperates by sending a LOAD DATA INFILE statement to the server. The\n--local option causes mysqlimport to read data files from the client\nhost. You can specify the --compress option to get better performance\nover slow networks if the client and server support the compressed\nprotocol. See https://mariadb.com/kb/en/mysqlimport/.\n\nIf you use LOW_PRIORITY, execution of the LOAD DATA statement is\ndelayed until no other clients are reading from the table. This affects\nonly storage engines that use only table-level locking (such as MyISAM,\nMEMORY, and MERGE).\n\nIf you specify CONCURRENT with a MyISAM table that satisfies the\ncondition for concurrent inserts (that is, it contains no free blocks\nin the middle), other threads can retrieve data from the table while\nLOAD DATA is executing. Using this option affects the performance of\nLOAD DATA a bit, even if no other thread is using the table at the same\ntime.\n\nPrior to MySQL 5.5.1, CONCURRENT was not replicated when using\nstatement-based replication (see Bug #34628). However, it is replicated\nwhen using row-based replication, regardless of the version. See\nhttp://dev.mysql.com/doc/refman/5.5/en/replication-features-load-data.h\ntml, for more information.\n\nThe LOCAL keyword, if specified, is interpreted with respect to the\nclient end of the connection:\n\no If LOCAL is specified, the file is read by the client program on the\n client host and sent to the server. The file can be given as a full\n path name to specify its exact location. If given as a relative path\n name, the name is interpreted relative to the directory in which the\n client program was started.\n\n When using LOCAL with LOAD DATA, a copy of the file is created in the\n server\'s temporary directory. This is not the directory determined by\n the value of tmpdir or slave_load_tmpdir, but rather the operating\n system\'s temporary directory, and is not configurable in the MySQL\n Server. (Typically the system temporary directory is /tmp on Linux\n systems and C:\\WINDOWS\\TEMP on Windows.) Lack of sufficient space for\n the copy in this directory can cause the LOAD DATA LOCAL statement to\n fail.\n\no If LOCAL is not specified, the file must be located on the server\n host and is read directly by the server. The server uses the\n following rules to locate the file:\n\n o If the file name is an absolute path name, the server uses it as\n given.\n\n o If the file name is a relative path name with one or more leading\n components, the server searches for the file relative to the\n server\'s data directory.\n\n o If a file name with no leading components is given, the server\n looks for the file in the database directory of the default\n database.\n\nNote that, in the non-LOCAL case, these rules mean that a file named as\n./myfile.txt is read from the server\'s data directory, whereas the file\nnamed as myfile.txt is read from the database directory of the default\ndatabase. For example, if db1 is the default database, the following\nLOAD DATA statement reads the file data.txt from the database directory\nfor db1, even though the statement explicitly loads the file into a\ntable in the db2 database:\n\nLOAD DATA INFILE \'data.txt\' INTO TABLE db2.my_table;\n\nWindows path names are specified using forward slashes rather than\nbackslashes. If you do use backslashes, you must double them.\n\nFor security reasons, when reading text files located on the server,\nthe files must either reside in the database directory or be readable\nby all. Also, to use LOAD DATA INFILE on server files, you must have\nthe FILE privilege. See\nhttps://mariadb.com/kb/en/grant/. For\nnon-LOCAL load operations, if the secure_file_priv system variable is\nset to a nonempty directory name, the file to be loaded must be located\nin that directory.\n\nURL: https://mariadb.com/kb/en/load-data-infile/\n\n','','https://mariadb.com/kb/en/load-data-infile/'); -insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (422,24,'MULTILINESTRING','MultiLineString(ls1,ls2,...)\n\nConstructs a MultiLineString value using LineString or WKB LineString\narguments.\n\nURL: https://mariadb.com/kb/en/multilinestring/\n\n','','https://mariadb.com/kb/en/multilinestring/'); -insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (423,31,'LOCALTIME','Syntax:\nLOCALTIME, LOCALTIME()\n\nLOCALTIME and LOCALTIME() are synonyms for NOW().\n\nURL: https://mariadb.com/kb/en/localtime/\n\n','','https://mariadb.com/kb/en/localtime/'); -insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (424,26,'SHOW RELAYLOG EVENTS','Syntax:\nSHOW RELAYLOG EVENTS\n [IN \'log_name\'] [FROM pos] [LIMIT [offset,] row_count]\n\nShows the events in the relay log of a replication slave. If you do not\nspecify \'log_name\', the first relay log is displayed. This statement\nhas no effect on the master.\n\nURL: https://mariadb.com/kb/en/show-relaylog-events/\n\n','','https://mariadb.com/kb/en/show-relaylog-events/'); -insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (425,3,'MPOINTFROMTEXT','MPointFromText(wkt[,srid]), MultiPointFromText(wkt[,srid])\n\nConstructs a MULTIPOINT value using its WKT representation and SRID.\n\nURL: https://mariadb.com/kb/en/mpointfromtext/\n\n','','https://mariadb.com/kb/en/mpointfromtext/'); -insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (426,22,'BLOB','BLOB[(M)]\n\nA BLOB column with a maximum length of 65,535 (216 - 1) bytes. Each\nBLOB value is stored using a 2-byte length prefix that indicates the\nnumber of bytes in the value.\n\nAn optional length M can be given for this type. If this is done, MySQL\ncreates the column as the smallest BLOB type large enough to hold\nvalues M bytes long.\n\nURL: https://mariadb.com/kb/en/blob/\n\n','','https://mariadb.com/kb/en/blob/'); -insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (427,12,'SHA1','Syntax:\nSHA1(str), SHA(str)\n\nCalculates an SHA-1 160-bit checksum for the string, as described in\nRFC 3174 (Secure Hash Algorithm). The value is returned as a string of\n40 hex digits, or NULL if the argument was NULL. One of the possible\nuses for this function is as a hash key. See the notes at the beginning\nof this section about storing hash values efficiently. You can also use\nSHA1() as a cryptographic function for storing passwords. SHA() is\nsynonymous with SHA1().\n\nAs of MySQL 5.5.3, the return value is a nonbinary string in the\nconnection character set. Before 5.5.3, the return value is a binary\nstring; see the notes at the beginning of this section about using the\nvalue as a nonbinary string.\n\nURL: https://mariadb.com/kb/en/sha1/\n\n','MariaDB> SELECT SHA1(\'abc\');\n -> \'a9993e364706816aba3e25717850c26c9cd0d89d\'\n','https://mariadb.com/kb/en/sha1/'); -insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (428,37,'SUBSTR','Syntax:\nSUBSTR(str,pos), SUBSTR(str FROM pos), SUBSTR(str,pos,len), SUBSTR(str\nFROM pos FOR len)\n\nSUBSTR() is a synonym for SUBSTRING().\n\nURL: https://mariadb.com/kb/en/substr/\n\n','','https://mariadb.com/kb/en/substr/'); -insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (429,12,'PASSWORD','Syntax:\nPASSWORD(str)\n\nCalculates and returns a hashed password string from the plaintext\npassword str and returns a nonbinary string in the connection character\nset (a binary string before MySQL 5.5.3), or NULL if the argument is\nNULL. This function is the SQL interface to the algorithm used by the\nserver to encrypt MySQL passwords for storage in the mysql.user grant\ntable.\n\nThe password hashing method used by PASSWORD() depends on the value of\nthe old_passwords system variable:\n\nURL: https://mariadb.com/kb/en/password/\n\n','MariaDB> SET old_passwords = 0;\nMariaDB> SELECT PASSWORD(\'mypass\');\n+-------------------------------------------+\n| PASSWORD(\'mypass\') |\n+-------------------------------------------+\n| *6C8989366EAF75BB670AD8EA7A7FC1176A95CEF4 |\n+-------------------------------------------+\n\nMariaDB> SET old_passwords = 1;\nMariaDB> SELECT PASSWORD(\'mypass\');\n+--------------------+\n| PASSWORD(\'mypass\') |\n+--------------------+\n| 6f8c114b58f2ce9e |\n+--------------------+\n','https://mariadb.com/kb/en/password/'); -insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (430,22,'CHAR','[NATIONAL] CHAR[(M)] [CHARACTER SET charset_name] [COLLATE\ncollation_name]\n\nA fixed-length string that is always right-padded with spaces to the\nspecified length when stored. M represents the column length in\ncharacters. The range of M is 0 to 255. If M is omitted, the length is\n1.\n\n*Note*: Trailing spaces are removed when CHAR values are retrieved\nunless the PAD_CHAR_TO_FULL_LENGTH SQL mode is enabled.\n\nURL: https://mariadb.com/kb/en/char/\n\n','','https://mariadb.com/kb/en/char/'); -insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (431,31,'UTC_DATE','Syntax:\nUTC_DATE, UTC_DATE()\n\nReturns the current UTC date as a value in \'YYYY-MM-DD\' or YYYYMMDD\nformat, depending on whether the function is used in a string or\nnumeric context.\n\nURL: https://mariadb.com/kb/en/utc_date/\n\n','MariaDB> SELECT UTC_DATE(), UTC_DATE() + 0;\n -> \'2003-08-14\', 20030814\n','https://mariadb.com/kb/en/utc_date/'); -insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (432,36,'DIMENSION','Dimension(g)\n\nReturns the inherent dimension of the geometry value g. The result can\nbe -1, 0, 1, or 2. The meaning of these values is given in\nhttps://mariadb.com/kb/en/dimension/.\n\nURL: https://mariadb.com/kb/en/dimension/\n\n','MariaDB> SELECT Dimension(GeomFromText(\'LineString(1 1,2 2)\'));\n+------------------------------------------------+\n| Dimension(GeomFromText(\'LineString(1 1,2 2)\')) |\n+------------------------------------------------+\n| 1 |\n+------------------------------------------------+\n','https://mariadb.com/kb/en/dimension/'); -insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (433,16,'COUNT DISTINCT','Syntax:\nCOUNT(DISTINCT expr,[expr...])\n\nReturns a count of the number of rows with different non-NULL expr\nvalues.\n\nCOUNT(DISTINCT) returns 0 if there were no matching rows.\n\nURL: https://mariadb.com/kb/en/count-distinct/\n\n','MariaDB> SELECT COUNT(DISTINCT results) FROM student;\n','https://mariadb.com/kb/en/count-distinct/'); -insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (434,22,'BIT','BIT[(M)]\n\nA bit-field type. M indicates the number of bits per value, from 1 to\n64. The default is 1 if M is omitted.\n\nURL: https://mariadb.com/kb/en/bit/\n\n','','https://mariadb.com/kb/en/bit/'); -insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (435,30,'EQUALS','Equals(g1,g2)\n\nReturns 1 or 0 to indicate whether g1 is spatially equal to g2.\n\nURL: https://mariadb.com/kb/en/equals/\n\n','','https://mariadb.com/kb/en/equals/'); -insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (436,26,'SHOW CREATE VIEW','Syntax:\nSHOW CREATE VIEW view_name\n\nThis statement shows a CREATE VIEW statement that creates the given\nview.\n\nURL: https://mariadb.com/kb/en/show-create-view/\n\n','','https://mariadb.com/kb/en/show-create-view/'); -insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (437,18,'INTERVAL','Syntax:\nINTERVAL(N,N1,N2,N3,...)\n\nReturns 0 if N < N1, 1 if N < N2 and so on or -1 if N is NULL. All\narguments are treated as integers. It is required that N1 < N2 < N3 <\n... < Nn for this function to work correctly. This is because a binary\nsearch is used (very fast).\n\nURL: https://mariadb.com/kb/en/interval/\n\n','MariaDB> SELECT INTERVAL(23, 1, 15, 17, 30, 44, 200);\n -> 3\nMariaDB> SELECT INTERVAL(10, 1, 10, 100, 1000);\n -> 2\nMariaDB> SELECT INTERVAL(22, 23, 30, 44, 200);\n -> 0\n','https://mariadb.com/kb/en/interval/'); -insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (438,31,'FROM_DAYS','Syntax:\nFROM_DAYS(N)\n\nGiven a day number N, returns a DATE value.\n\nURL: https://mariadb.com/kb/en/from_days/\n\n','MariaDB> SELECT FROM_DAYS(730669);\n -> \'2007-07-03\'\n','https://mariadb.com/kb/en/from_days/'); -insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (439,39,'ALTER PROCEDURE','Syntax:\nALTER PROCEDURE proc_name [characteristic ...]\n\ncharacteristic:\n COMMENT \'string\'\n | LANGUAGE SQL\n | { CONTAINS SQL | NO SQL | READS SQL DATA | MODIFIES SQL DATA }\n | SQL SECURITY { DEFINER | INVOKER }\n\nThis statement can be used to change the characteristics of a stored\nprocedure. More than one change may be specified in an ALTER PROCEDURE\nstatement. However, you cannot change the parameters or body of a\nstored procedure using this statement; to make such changes, you must\ndrop and re-create the procedure using DROP PROCEDURE and CREATE\nPROCEDURE.\n\nYou must have the ALTER ROUTINE privilege for the procedure. By\ndefault, that privilege is granted automatically to the procedure\ncreator. This behavior can be changed by disabling the\nautomatic_sp_privileges system variable. See\nhttps://mariadb.com/kb/en/stored-routine-privileges/.\n\nURL: https://mariadb.com/kb/en/alter-procedure/\n\n','','https://mariadb.com/kb/en/alter-procedure/'); -insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (440,19,'BIT_COUNT','Syntax:\nBIT_COUNT(N)\n\nReturns the number of bits that are set in the argument N.\n\nURL: https://mariadb.com/kb/en/bit_count/\n\n','MariaDB> SELECT BIT_COUNT(29), BIT_COUNT(b\'101010\');\n -> 4, 3\n','https://mariadb.com/kb/en/bit_count/'); -insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (441,37,'OCTET_LENGTH','Syntax:\nOCTET_LENGTH(str)\n\nOCTET_LENGTH() is a synonym for LENGTH().\n\nURL: https://mariadb.com/kb/en/octet_length/\n\n','','https://mariadb.com/kb/en/octet_length/'); -insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (442,31,'UTC_TIMESTAMP','Syntax:\nUTC_TIMESTAMP, UTC_TIMESTAMP()\n\nReturns the current UTC date and time as a value in \'YYYY-MM-DD\nHH:MM:SS\' or YYYYMMDDHHMMSS.uuuuuu format, depending on whether the\nfunction is used in a string or numeric context.\n\nURL: https://mariadb.com/kb/en/utc_timestamp/\n\n','MariaDB> SELECT UTC_TIMESTAMP(), UTC_TIMESTAMP() + 0;\n -> \'2003-08-14 18:08:04\', 20030814180804.000000\n','https://mariadb.com/kb/en/utc_timestamp/'); -insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (443,12,'AES_ENCRYPT','Syntax:\nAES_ENCRYPT(str,key_str)\n\nAES_ENCRYPT() and AES_DECRYPT() enable encryption and decryption of\ndata using the official AES (Advanced Encryption Standard) algorithm,\npreviously known as "Rijndael." Encoding with a 128-bit key length is\nused, but you can extend it up to 256 bits by modifying the source. We\nchose 128 bits because it is much faster and it is secure enough for\nmost purposes.\n\nAES_ENCRYPT() encrypts a string and returns a binary string.\nAES_DECRYPT() decrypts the encrypted string and returns the original\nstring. The input arguments may be any length. If either argument is\nNULL, the result of this function is also NULL.\n\nBecause AES is a block-level algorithm, padding is used to encode\nuneven length strings and so the result string length may be calculated\nusing this formula:\n\n16 * (trunc(string_length / 16) + 1)\n\nIf AES_DECRYPT() detects invalid data or incorrect padding, it returns\nNULL. However, it is possible for AES_DECRYPT() to return a non-NULL\nvalue (possibly garbage) if the input data or the key is invalid.\n\nYou can use the AES functions to store data in an encrypted form by\nmodifying your queries:\n\nURL: https://mariadb.com/kb/en/aes_encrypt/\n\n','INSERT INTO t VALUES (1,AES_ENCRYPT(\'text\',\'password\'));\n','https://mariadb.com/kb/en/aes_encrypt/'); -insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (444,4,'+','Syntax:\n+\n\nAddition:\n\nURL: https://mariadb.com/kb/en/addition-operator/\n\n','MariaDB> SELECT 3+5;\n -> 8\n','https://mariadb.com/kb/en/addition-operator/'); -insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (445,14,'INET_NTOA','Syntax:\nINET_NTOA(expr)\n\nGiven a numeric IPv4 network address in network byte order, returns the\ndotted-quad representation of the address as a string. INET_NTOA()\nreturns NULL if it does not understand its argument.\n\nAs of MySQL 5.5.3, the return value is a nonbinary string in the\nconnection character set. Before 5.5.3, the return value is a binary\nstring.\n\nURL: https://mariadb.com/kb/en/inet_ntoa/\n\n','MariaDB> SELECT INET_NTOA(167773449);\n -> \'10.0.5.9\'\n','https://mariadb.com/kb/en/inet_ntoa/'); -insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (446,4,'ACOS','Syntax:\nACOS(X)\n\nReturns the arc cosine of X, that is, the value whose cosine is X.\nReturns NULL if X is not in the range -1 to 1.\n\nURL: https://mariadb.com/kb/en/acos/\n\n','MariaDB> SELECT ACOS(1);\n -> 0\nMariaDB> SELECT ACOS(1.0001);\n -> NULL\nMariaDB> SELECT ACOS(0);\n -> 1.5707963267949\n','https://mariadb.com/kb/en/acos/'); -insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (447,8,'ISOLATION','Syntax:\nSET [GLOBAL | SESSION] TRANSACTION ISOLATION LEVEL\n {\n REPEATABLE READ\n | READ COMMITTED\n | READ UNCOMMITTED\n | SERIALIZABLE\n }\n\nThis statement sets the transaction isolation level, used for\noperations on InnoDB tables.\n\nScope of the Isolation Level\n\nYou can set the isolation level globally, for the current session, or\nfor the next transaction:\n\no With the GLOBAL keyword, the statement sets the default transaction\n level globally for all subsequent sessions. Existing sessions are\n unaffected.\n\no With the SESSION keyword, the statement sets the default transaction\n level for all subsequent transactions performed within the current\n session.\n\no Without any SESSION or GLOBAL keyword, the statement sets the\n isolation level for the next (not started) transaction performed\n within the current session.\n\nA change to the global default isolation level requires the SUPER\nprivilege. Any session is free to change its session isolation level\n(even in the middle of a transaction), or the isolation level for its\nnext transaction.\n\nSET TRANSACTION ISOLATION LEVEL without GLOBAL or SESSION is not\npermitted while there is an active transaction:\n\nMariaDB> START TRANSACTION;\nQuery OK, 0 rows affected (0.02 sec)\n\nMariaDB> SET TRANSACTION ISOLATION LEVEL SERIALIZABLE;\nERROR 1568 (25001): Transaction isolation level can\'t be changed\nwhile a transaction is in progress\n\nTo set the global default isolation level at server startup, use the\n--transaction-isolation=level option to mysqld on the command line or\nin an option file. Values of level for this option use dashes rather\nthan spaces, so the permissible values are READ-UNCOMMITTED,\nREAD-COMMITTED, REPEATABLE-READ, or SERIALIZABLE. For example, to set\nthe default isolation level to REPEATABLE READ, use these lines in the\n[mysqld] section of an option file:\n\n[mysqld]\ntransaction-isolation = REPEATABLE-READ\n\nIt is possible to check or set the global and session transaction\nisolation levels at runtime by using the tx_isolation system variable:\n\nSELECT @@GLOBAL.tx_isolation, @@tx_isolation;\nSET GLOBAL tx_isolation=\'REPEATABLE-READ\';\nSET SESSION tx_isolation=\'SERIALIZABLE\';\n\nDetails and Usage of Isolation Levels\n\nInnoDB supports each of the transaction isolation levels described here\nusing different locking strategies. You can enforce a high degree of\nconsistency with the default REPEATABLE READ level, for operations on\ncrucial data where ACID compliance is important. Or you can relax the\nconsistency rules with READ COMMITTED or even READ UNCOMMITTED, in\nsituations such as bulk reporting where precise consistency and\nrepeatable results are less important than minimizing the amount of\noverhead for locking. SERIALIZABLE enforces even stricter rules than\nREPEATABLE READ, and is used mainly in specialized situations, such as\nwith XA transactions and for troubleshooting issues with concurrency\nand deadlocks.\n\nFor full information about how these isolation levels work with InnoDB\ntransactions, see\nhttp://dev.mysql.com/doc/refman/5.1/en/innodb-transaction-model.html.\nIn particular, for additional information about InnoDB record-level\nlocks and how it uses them to execute various types of statements, see\nhttp://dev.mysql.com/doc/refman/5.5/en/innodb-record-level-locks.html\nand http://dev.mysql.com/doc/refman/5.5/en/innodb-locks-set.html.\n\nThe following list describes how MySQL supports the different\ntransaction levels. The list goes from the most commonly used level to\nthe least used.\n\no REPEATABLE READ\n\n This is the default isolation level for InnoDB. For consistent reads,\n there is an important difference from the READ COMMITTED isolation\n level: All consistent reads within the same transaction read the\n snapshot established by the first read. This convention means that if\n you issue several plain (nonlocking) SELECT statements within the\n same transaction, these SELECT statements are consistent also with\n respect to each other. See\n http://dev.mysql.com/doc/refman/5.5/en/innodb-consistent-read.html.\n\n For locking reads (SELECT with FOR UPDATE or LOCK IN SHARE MODE),\n UPDATE, and DELETE statements, locking depends on whether the\n statement uses a unique index with a unique search condition, or a\n range-type search condition. For a unique index with a unique search\n condition, InnoDB locks only the index record found, not the gap\n before it. For other search conditions, InnoDB locks the index range\n scanned, using gap locks or next-key (gap plus index-record) locks to\n block insertions by other sessions into the gaps covered by the\n range.\n\no READ COMMITTED\n\n A somewhat Oracle-like isolation level with respect to consistent\n (nonlocking) reads: Each consistent read, even within the same\n transaction, sets and reads its own fresh snapshot. See\n http://dev.mysql.com/doc/refman/5.5/en/innodb-consistent-read.html.\n\n For locking reads (SELECT with FOR UPDATE or LOCK IN SHARE MODE),\n InnoDB locks only index records, not the gaps before them, and thus\n permits the free insertion of new records next to locked records. For\n UPDATE and DELETE statements, locking depends on whether the\n statement uses a unique index with a unique search condition (such as\n WHERE id = 100), or a range-type search condition (such as WHERE id >\n 100). For a unique index with a unique search condition, InnoDB locks\n only the index record found, not the gap before it. For range-type\n searches, InnoDB locks the index range scanned, using gap locks or\n next-key (gap plus index-record) locks to block insertions by other\n sessions into the gaps covered by the range. This is necessary\n because "phantom rows" must be blocked for MySQL replication and\n recovery to work.\n\n *Note*: In MySQL 5.5, if the READ COMMITTED isolation level is used\n or the innodb_locks_unsafe_for_binlog system variable is enabled,\n there is no InnoDB gap locking except for foreign-key constraint\n checking and duplicate-key checking. Also, record locks for\n nonmatching rows are released after MySQL has evaluated the WHERE\n condition. If you use READ COMMITTED or enable\n innodb_locks_unsafe_for_binlog, you must use row-based binary\n logging.\n\no READ UNCOMMITTED\n\n SELECT statements are performed in a nonlocking fashion, but a\n possible earlier version of a row might be used. Thus, using this\n isolation level, such reads are not consistent. This is also called a\n "dirty read." Otherwise, this isolation level works like READ\n COMMITTED.\n\no SERIALIZABLE\n\n This level is like REPEATABLE READ, but InnoDB implicitly converts\n all plain SELECT statements to SELECT ... LOCK IN SHARE MODE if\n autocommit is disabled. If autocommit is enabled, the SELECT is its\n own transaction. It therefore is known to be read only and can be\n serialized if performed as a consistent (nonlocking) read and need\n not block for other transactions. (To force a plain SELECT to block\n if other transactions have modified the selected rows, disable\n autocommit.)\n\nURL: https://mariadb.com/kb/en/set-transaction-isolation-level/\n\n','','https://mariadb.com/kb/en/set-transaction-isolation-level/'); -insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (448,4,'CEILING','Syntax:\nCEILING(X)\n\nReturns the smallest integer value not less than X.\n\nURL: https://mariadb.com/kb/en/ceiling/\n\n','MariaDB> SELECT CEILING(1.23);\n -> 2\nMariaDB> SELECT CEILING(-1.23);\n -> -1\n','https://mariadb.com/kb/en/ceiling/'); -insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (449,4,'SIN','Syntax:\nSIN(X)\n\nReturns the sine of X, where X is given in radians.\n\nURL: https://mariadb.com/kb/en/sin/\n\n','MariaDB> SELECT SIN(PI());\n -> 1.2246063538224e-16\nMariaDB> SELECT ROUND(SIN(PI()));\n -> 0\n','https://mariadb.com/kb/en/sin/'); -insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (450,31,'DAYOFWEEK','Syntax:\nDAYOFWEEK(date)\n\nReturns the weekday index for date (1 = Sunday, 2 = Monday, ..., 7 =\nSaturday). These index values correspond to the ODBC standard.\n\nURL: https://mariadb.com/kb/en/dayofweek/\n\n','MariaDB> SELECT DAYOFWEEK(\'2007-02-03\');\n -> 7\n','https://mariadb.com/kb/en/dayofweek/'); -insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (451,26,'SHOW PROCESSLIST','Syntax:\nSHOW [FULL] PROCESSLIST\n\nSHOW PROCESSLIST shows you which threads are running. You can also get\nthis information from the INFORMATION_SCHEMA PROCESSLIST table or the\nmysqladmin processlist command. If you have the PROCESS privilege, you\ncan see all threads. Otherwise, you can see only your own threads (that\nis, threads associated with the MySQL account that you are using). If\nyou do not use the FULL keyword, only the first 100 characters of each\nstatement are shown in the Info field.\n\nURL: https://mariadb.com/kb/en/show-processlist/\n\n','','https://mariadb.com/kb/en/show-processlist/'); -insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (452,32,'LINEFROMWKB','LineFromWKB(wkb[,srid]), LineStringFromWKB(wkb[,srid])\n\nConstructs a LINESTRING value using its WKB representation and SRID.\n\nURL: https://mariadb.com/kb/en/linefromwkb/\n\n','','https://mariadb.com/kb/en/linefromwkb/'); -insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (453,36,'GEOMETRYTYPE','GeometryType(g)\n\nReturns as a binary string the name of the geometry type of which the\ngeometry instance g is a member. The name corresponds to one of the\ninstantiable Geometry subclasses.\n\nURL: https://mariadb.com/kb/en/geometrytype/\n\n','MariaDB> SELECT GeometryType(GeomFromText(\'POINT(1 1)\'));\n+------------------------------------------+\n| GeometryType(GeomFromText(\'POINT(1 1)\')) |\n+------------------------------------------+\n| POINT |\n+------------------------------------------+\n','https://mariadb.com/kb/en/geometrytype/'); -insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (454,39,'CREATE VIEW','Syntax:\nCREATE\n [OR REPLACE]\n [ALGORITHM = {UNDEFINED | MERGE | TEMPTABLE}]\n [DEFINER = { user | CURRENT_USER }]\n [SQL SECURITY { DEFINER | INVOKER }]\n VIEW view_name [(column_list)]\n AS select_statement\n [WITH [CASCADED | LOCAL] CHECK OPTION]\n\nThe CREATE VIEW statement creates a new view, or replaces an existing\none if the OR REPLACE clause is given. If the view does not exist,\nCREATE OR REPLACE VIEW is the same as CREATE VIEW. If the view does\nexist, CREATE OR REPLACE VIEW is the same as ALTER VIEW.\n\nThe select_statement is a SELECT statement that provides the definition\nof the view. (When you select from the view, you select in effect using\nthe SELECT statement.) select_statement can select from base tables or\nother views.\n\nThe view definition is "frozen" at creation time, so changes to the\nunderlying tables afterward do not affect the view definition. For\nexample, if a view is defined as SELECT * on a table, new columns added\nto the table later do not become part of the view.\n\nThe ALGORITHM clause affects how MySQL processes the view. The DEFINER\nand SQL SECURITY clauses specify the security context to be used when\nchecking access privileges at view invocation time. The WITH CHECK\nOPTION clause can be given to constrain inserts or updates to rows in\ntables referenced by the view. These clauses are described later in\nthis section.\n\nThe CREATE VIEW statement requires the CREATE VIEW privilege for the\nview, and some privilege for each column selected by the SELECT\nstatement. For columns used elsewhere in the SELECT statement you must\nhave the SELECT privilege. If the OR REPLACE clause is present, you\nmust also have the DROP privilege for the view. CREATE VIEW might also\nrequire the SUPER privilege, depending on the DEFINER value, as\ndescribed later in this section.\n\nWhen a view is referenced, privilege checking occurs as described later\nin this section.\n\nA view belongs to a database. By default, a new view is created in the\ndefault database. To create the view explicitly in a given database,\nspecify the name as db_name.view_name when you create it:\n\nMariaDB> CREATE VIEW test.v AS SELECT * FROM t;\n\nWithin a database, base tables and views share the same namespace, so a\nbase table and a view cannot have the same name.\n\nColumns retrieved by the SELECT statement can be simple references to\ntable columns. They can also be expressions that use functions,\nconstant values, operators, and so forth.\n\nViews must have unique column names with no duplicates, just like base\ntables. By default, the names of the columns retrieved by the SELECT\nstatement are used for the view column names. To define explicit names\nfor the view columns, the optional column_list clause can be given as a\nlist of comma-separated identifiers. The number of names in column_list\nmust be the same as the number of columns retrieved by the SELECT\nstatement.\n\nUnqualified table or view names in the SELECT statement are interpreted\nwith respect to the default database. A view can refer to tables or\nviews in other databases by qualifying the table or view name with the\nproper database name.\n\nA view can be created from many kinds of SELECT statements. It can\nrefer to base tables or other views. It can use joins, UNION, and\nsubqueries. The SELECT need not even refer to any tables. The following\nexample defines a view that selects two columns from another table, as\nwell as an expression calculated from those columns:\n\nMariaDB> CREATE TABLE t (qty INT, price INT);\nMariaDB> INSERT INTO t VALUES(3, 50);\nMariaDB> CREATE VIEW v AS SELECT qty, price, qty*price AS value FROM t;\nMariaDB> SELECT * FROM v;\n+------+-------+-------+\n| qty | price | value |\n+------+-------+-------+\n| 3 | 50 | 150 |\n+------+-------+-------+\n\nA view definition is subject to the following restrictions:\n\no The SELECT statement cannot contain a subquery in the FROM clause.\n\no The SELECT statement cannot refer to system or user variables.\n\no Within a stored program, the definition cannot refer to program\n parameters or local variables.\n\no The SELECT statement cannot refer to prepared statement parameters.\n\no Any table or view referred to in the definition must exist. However,\n after a view has been created, it is possible to drop a table or view\n that the definition refers to. In this case, use of the view results\n in an error. To check a view definition for problems of this kind,\n use the CHECK TABLE statement.\n\no The definition cannot refer to a TEMPORARY table, and you cannot\n create a TEMPORARY view.\n\no Any tables named in the view definition must exist at definition\n time.\n\no You cannot associate a trigger with a view.\n\no Aliases for column names in the SELECT statement are checked against\n the maximum column length of 64 characters (not the maximum alias\n length of 256 characters).\n\nORDER BY is permitted in a view definition, but it is ignored if you\nselect from a view using a statement that has its own ORDER BY.\n\nFor other options or clauses in the definition, they are added to the\noptions or clauses of the statement that references the view, but the\neffect is undefined. For example, if a view definition includes a LIMIT\nclause, and you select from the view using a statement that has its own\nLIMIT clause, it is undefined which limit applies. This same principle\napplies to options such as ALL, DISTINCT, or SQL_SMALL_RESULT that\nfollow the SELECT keyword, and to clauses such as INTO, FOR UPDATE,\nLOCK IN SHARE MODE, and PROCEDURE.\n\nIf you create a view and then change the query processing environment\nby changing system variables, that may affect the results that you get\nfrom the view:\n\nMariaDB> CREATE VIEW v (mycol) AS SELECT \'abc\';\nQuery OK, 0 rows affected (0.01 sec)\n\nMariaDB> SET sql_mode = \'\';\nQuery OK, 0 rows affected (0.00 sec)\n\nMariaDB> SELECT "mycol" FROM v;\n+-------+\n| mycol |\n+-------+\n| mycol |\n+-------+\n1 row in set (0.01 sec)\n\nMariaDB> SET sql_mode = \'ANSI_QUOTES\';\nQuery OK, 0 rows affected (0.00 sec)\n\nMariaDB> SELECT "mycol" FROM v;\n+-------+\n| mycol |\n+-------+\n| abc |\n+-------+\n1 row in set (0.00 sec)\n\nThe DEFINER and SQL SECURITY clauses determine which MySQL account to\nuse when checking access privileges for the view when a statement is\nexecuted that references the view. The valid SQL SECURITY\ncharacteristic values are DEFINER and INVOKER. These indicate that the\nrequired privileges must be held by the user who defined or invoked the\nview, respectively. The default SQL SECURITY value is DEFINER.\n\nIf a user value is given for the DEFINER clause, it should be a MySQL\naccount specified as \'user_name\'@\'host_name\' (the same format used in\nthe GRANT statement), CURRENT_USER, or CURRENT_USER(). The default\nDEFINER value is the user who executes the CREATE VIEW statement. This\nis the same as specifying DEFINER = CURRENT_USER explicitly.\n\nIf you specify the DEFINER clause, these rules determine the valid\nDEFINER user values:\n\no If you do not have the SUPER privilege, the only valid user value is\n your own account, either specified literally or by using\n CURRENT_USER. You cannot set the definer to some other account.\n\no If you have the SUPER privilege, you can specify any syntactically\n valid account name. If the account does not actually exist, a warning\n is generated.\n\no Although it is possible to create a view with a nonexistent DEFINER\n account, an error occurs when the view is referenced if the SQL\n SECURITY value is DEFINER but the definer account does not exist.\n\nFor more information about view security, see\nhttps://mariadb.com/kb/en/stored-routine-privileges/.\n\nWithin a view definition, CURRENT_USER returns the view\'s DEFINER value\nby default. For views defined with the SQL SECURITY INVOKER\ncharacteristic, CURRENT_USER returns the account for the view\'s\ninvoker. For information about user auditing within views, see\nhttp://dev.mysql.com/doc/refman/5.5/en/account-activity-auditing.html.\n\nWithin a stored routine that is defined with the SQL SECURITY DEFINER\ncharacteristic, CURRENT_USER returns the routine\'s DEFINER value. This\nalso affects a view defined within such a routine, if the view\ndefinition contains a DEFINER value of CURRENT_USER.\n\nView privileges are checked like this:\n\no At view definition time, the view creator must have the privileges\n needed to use the top-level objects accessed by the view. For\n example, if the view definition refers to table columns, the creator\n must have some privilege for each column in the select list of the\n definition, and the SELECT privilege for each column used elsewhere\n in the definition. If the definition refers to a stored function,\n only the privileges needed to invoke the function can be checked. The\n privileges required at function invocation time can be checked only\n as it executes: For different invocations, different execution paths\n within the function might be taken.\n\no The user who references a view must have appropriate privileges to\n access it (SELECT to select from it, INSERT to insert into it, and so\n forth.)\n\no When a view has been referenced, privileges for objects accessed by\n the view are checked against the privileges held by the view DEFINER\n account or invoker, depending on whether the SQL SECURITY\n characteristic is DEFINER or INVOKER, respectively.\n\no If reference to a view causes execution of a stored function,\n privilege checking for statements executed within the function depend\n on whether the function SQL SECURITY characteristic is DEFINER or\n INVOKER. If the security characteristic is DEFINER, the function runs\n with the privileges of the DEFINER account. If the characteristic is\n INVOKER, the function runs with the privileges determined by the\n view\'s SQL SECURITY characteristic.\n\nExample: A view might depend on a stored function, and that function\nmight invoke other stored routines. For example, the following view\ninvokes a stored function f():\n\nCREATE VIEW v AS SELECT * FROM t WHERE t.id = f(t.name);\n\nSuppose that f() contains a statement such as this:\n\nIF name IS NULL then\n CALL p1();\nELSE\n CALL p2();\nEND IF;\n\nThe privileges required for executing statements within f() need to be\nchecked when f() executes. This might mean that privileges are needed\nfor p1() or p2(), depending on the execution path within f(). Those\nprivileges must be checked at runtime, and the user who must possess\nthe privileges is determined by the SQL SECURITY values of the view v\nand the function f().\n\nThe DEFINER and SQL SECURITY clauses for views are extensions to\nstandard SQL. In standard SQL, views are handled using the rules for\nSQL SECURITY DEFINER. The standard says that the definer of the view,\nwhich is the same as the owner of the view\'s schema, gets applicable\nprivileges on the view (for example, SELECT) and may grant them. MySQL\nhas no concept of a schema "owner", so MySQL adds a clause to identify\nthe definer. The DEFINER clause is an extension where the intent is to\nhave what the standard has; that is, a permanent record of who defined\nthe view. This is why the default DEFINER value is the account of the\nview creator.\n\nThe optional ALGORITHM clause is a MySQL extension to standard SQL. It\naffects how MySQL processes the view. ALGORITHM takes three values:\nMERGE, TEMPTABLE, or UNDEFINED. The default algorithm is UNDEFINED if\nno ALGORITHM clause is present. For more information, see\nhttps://mariadb.com/kb/en/view-algorithms/.\n\nSome views are updatable. That is, you can use them in statements such\nas UPDATE, DELETE, or INSERT to update the contents of the underlying\ntable. For a view to be updatable, there must be a one-to-one\nrelationship between the rows in the view and the rows in the\nunderlying table. There are also certain other constructs that make a\nview nonupdatable.\n\nThe WITH CHECK OPTION clause can be given for an updatable view to\nprevent inserts or updates to rows except those for which the WHERE\nclause in the select_statement is true.\n\nIn a WITH CHECK OPTION clause for an updatable view, the LOCAL and\nCASCADED keywords determine the scope of check testing when the view is\ndefined in terms of another view. The LOCAL keyword restricts the CHECK\nOPTION only to the view being defined. CASCADED causes the checks for\nunderlying views to be evaluated as well. When neither keyword is\ngiven, the default is CASCADED.\n\nFor more information about updatable views and the WITH CHECK OPTION\nclause, see\nhttps://mariadb.com/kb/en/inserting-and-updating-with-views/.\n\nURL: https://mariadb.com/kb/en/create-view/\n\n','','https://mariadb.com/kb/en/create-view/'); -insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (455,37,'TRIM','Syntax:\nTRIM([{BOTH | LEADING | TRAILING} [remstr] FROM] str), TRIM([remstr\nFROM] str)\n\nReturns the string str with all remstr prefixes or suffixes removed. If\nnone of the specifiers BOTH, LEADING, or TRAILING is given, BOTH is\nassumed. remstr is optional and, if not specified, spaces are removed.\n\nURL: https://mariadb.com/kb/en/trim/\n\n','MariaDB> SELECT TRIM(\' bar \');\n -> \'bar\'\nMariaDB> SELECT TRIM(LEADING \'x\' FROM \'xxxbarxxx\');\n -> \'barxxx\'\nMariaDB> SELECT TRIM(BOTH \'x\' FROM \'xxxbarxxx\');\n -> \'bar\'\nMariaDB> SELECT TRIM(TRAILING \'xyz\' FROM \'barxxyz\');\n -> \'barx\'\n','https://mariadb.com/kb/en/trim/'); -insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (456,18,'IS','Syntax:\nIS boolean_value\n\nTests a value against a boolean value, where boolean_value can be TRUE,\nFALSE, or UNKNOWN.\n\nURL: https://mariadb.com/kb/en/is/\n\n','MariaDB> SELECT 1 IS TRUE, 0 IS FALSE, NULL IS UNKNOWN;\n -> 1, 1, 1\n','https://mariadb.com/kb/en/is/'); -insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (457,31,'GET_FORMAT','Syntax:\nGET_FORMAT({DATE|TIME|DATETIME}, {\'EUR\'|\'USA\'|\'JIS\'|\'ISO\'|\'INTERNAL\'})\n\nReturns a format string. This function is useful in combination with\nthe DATE_FORMAT() and the STR_TO_DATE() functions.\n\nURL: https://mariadb.com/kb/en/get_format/\n\n','MariaDB> SELECT DATE_FORMAT(\'2003-10-03\',GET_FORMAT(DATE,\'EUR\'));\n -> \'03.10.2003\'\nMariaDB> SELECT STR_TO_DATE(\'10.31.2003\',GET_FORMAT(DATE,\'USA\'));\n -> \'2003-10-31\'\n','https://mariadb.com/kb/en/get_format/'); -insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (458,22,'TINYBLOB','TINYBLOB\n\nA BLOB column with a maximum length of 255 (28 - 1) bytes. Each\nTINYBLOB value is stored using a 1-byte length prefix that indicates\nthe number of bytes in the value.\n\nURL: https://mariadb.com/kb/en/tinyblob/\n\n','','https://mariadb.com/kb/en/tinyblob/'); -insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (459,23,'SIGNAL','Syntax:\nSIGNAL condition_value\n [SET signal_information_item\n [, signal_information_item] ...]\n\ncondition_value:\n SQLSTATE [VALUE] sqlstate_value\n | condition_name\n\nsignal_information_item:\n condition_information_item_name = simple_value_specification\n\ncondition_information_item_name:\n CLASS_ORIGIN\n | SUBCLASS_ORIGIN\n | MESSAGE_TEXT\n | MYSQL_ERRNO\n | CONSTRAINT_CATALOG\n | CONSTRAINT_SCHEMA\n | CONSTRAINT_NAME\n | CATALOG_NAME\n | SCHEMA_NAME\n | TABLE_NAME\n | COLUMN_NAME\n | CURSOR_NAME\n\ncondition_name, simple_value_specification:\n (see following discussion)\n\nSIGNAL is the way to "return" an error. SIGNAL provides error\ninformation to a handler, to an outer portion of the application, or to\nthe client. Also, it provides control over the error\'s characteristics\n(error number, SQLSTATE value, message). Without SIGNAL, it is\nnecessary to resort to workarounds such as deliberately referring to a\nnonexistent table to cause a routine to return an error.\n\nNo special privileges are required to execute the SIGNAL statement.\n\nThe condition_value in a SIGNAL statement indicates the error value to\nbe returned. It can be an SQLSTATE value (a 5-character string literal)\nor a condition_name that refers to a named condition previously defined\nwith DECLARE ... CONDITION (see [HELP DECLARE CONDITION]).\n\nAn SQLSTATE value can indicate errors, warnings, or "not found." The\nfirst two characters of the value indicate its error class, as\ndiscussed in\nhttps://mariadb.com/kb/en/signal/#signal-condition-inf\normation-items. Some signal values cause statement termination; see\nhttps://mariadb.com/kb/en/signal/#signal-effects.\n\nThe SQLSTATE value for a SIGNAL statement should not start with \'00\'\nbecause such values indicate success and are not valid for signaling an\nerror. This is true whether the SQLSTATE value is specified directly in\nthe SIGNAL statement or in a named condition referred to in the\nstatement. If the value is invalid, a Bad SQLSTATE error occurs.\n\nTo signal a generic SQLSTATE value, use \'45000\', which means "unhandled\nuser-defined exception."\n\nThe SIGNAL statement optionally includes a SET clause that contains\nmultiple signal items, in a comma-separated list of\ncondition_information_item_name = simple_value_specification\nassignments.\n\nEach condition_information_item_name may be specified only once in the\nSET clause. Otherwise, a Duplicate condition information item error\noccurs.\n\nValid simple_value_specification designators can be specified using\nstored procedure or function parameters, stored program local variables\ndeclared with DECLARE, user-defined variables, system variables, or\nliterals. A character literal may include a _charset introducer.\n\nFor information about permissible condition_information_item_name\nvalues, see\nhttps://mariadb.com/kb/en/signal/#signal-condition-inf\normation-items.\n\nURL: https://mariadb.com/kb/en/signal/\n\n','CREATE PROCEDURE p (pval INT)\nBEGIN\n DECLARE specialty CONDITION FOR SQLSTATE \'45000\';\n IF pval = 0 THEN\n SIGNAL SQLSTATE \'01000\';\n ELSEIF pval = 1 THEN\n SIGNAL SQLSTATE \'45000\'\n SET MESSAGE_TEXT = \'An error occurred\';\n ELSEIF pval = 2 THEN\n SIGNAL specialty\n SET MESSAGE_TEXT = \'An error occurred\';\n ELSE\n SIGNAL SQLSTATE \'01000\'\n SET MESSAGE_TEXT = \'A warning occurred\', MYSQL_ERRNO = 1000;\n SIGNAL SQLSTATE \'45000\'\n SET MESSAGE_TEXT = \'An error occurred\', MYSQL_ERRNO = 1001;\n END IF;\nEND;\n','https://mariadb.com/kb/en/signal/'); -insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (460,8,'SAVEPOINT','Syntax:\nSAVEPOINT identifier\nROLLBACK [WORK] TO [SAVEPOINT] identifier\nRELEASE SAVEPOINT identifier\n\nInnoDB supports the SQL statements SAVEPOINT, ROLLBACK TO SAVEPOINT,\nRELEASE SAVEPOINT and the optional WORK keyword for ROLLBACK.\n\nURL: https://mariadb.com/kb/en/savepoint/\n\n','','https://mariadb.com/kb/en/savepoint/'); -insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (461,17,'USER','Syntax:\nUSER()\n\nReturns the current MySQL user name and host name as a string in the\nutf8 character set.\n\nURL: https://mariadb.com/kb/en/user/\n\n','MariaDB> SELECT USER();\n -> \'davida@localhost\'\n','https://mariadb.com/kb/en/user/'); -insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (462,23,'LABELS','Syntax:\n[begin_label:] BEGIN\n [statement_list]\nEND [end_label]\n\n[begin_label:] LOOP\n statement_list\nEND LOOP [end_label]\n\n[begin_label:] REPEAT\n statement_list\nUNTIL search_condition\nEND REPEAT [end_label]\n\n[begin_label:] WHILE search_condition DO\n statement_list\nEND WHILE [end_label]\n\nLabels are permitted for BEGIN ... END blocks and for the LOOP, REPEAT,\nand WHILE statements. Label use for those statements follows these\nrules:\n\no begin_label must be followed by a colon.\n\no begin_label can be given without end_label. If end_label is present,\n it must be the same as begin_label.\n\no end_label cannot be given without begin_label.\n\no Labels at the same nesting level must be distinct.\n\no Labels can be up to 16 characters long.\n\nTo refer to a label within the labeled construct, use an ITERATE or\nLEAVE statement. The following example uses those statements to\ncontinue iterating or terminate the loop:\n\nCREATE PROCEDURE doiterate(p1 INT)\nBEGIN\n label1: LOOP\n SET p1 = p1 + 1;\n IF p1 < 10 THEN ITERATE label1; END IF;\n LEAVE label1;\n END LOOP label1;\nEND;\n\nThe scope of a block label does not include the code for handlers\ndeclared within the block. For details, see [HELP DECLARE HANDLER].\n\nURL: https://mariadb.com/kb/en/labels/\n\n','','https://mariadb.com/kb/en/labels/'); -insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (463,39,'ALTER TABLE','Syntax:\nALTER [ONLINE | OFFLINE] [IGNORE] TABLE tbl_name\n [alter_specification [, alter_specification] ...]\n [partition_options]\n\nalter_specification:\n table_options\n | ADD [COLUMN] col_name column_definition\n [FIRST | AFTER col_name ]\n | ADD [COLUMN] (col_name column_definition,...)\n | ADD {INDEX|KEY} [index_name]\n [index_type] (index_col_name,...) [index_option] ...\n | ADD [CONSTRAINT [symbol]] PRIMARY KEY\n [index_type] (index_col_name,...) [index_option] ...\n | ADD [CONSTRAINT [symbol]]\n UNIQUE [INDEX|KEY] [index_name]\n [index_type] (index_col_name,...) [index_option] ...\n | ADD FULLTEXT [INDEX|KEY] [index_name]\n (index_col_name,...) [index_option] ...\n | ADD SPATIAL [INDEX|KEY] [index_name]\n (index_col_name,...) [index_option] ...\n | ADD [CONSTRAINT [symbol]]\n FOREIGN KEY [index_name] (index_col_name,...)\n reference_definition\n | ALTER [COLUMN] col_name {SET DEFAULT literal | DROP DEFAULT}\n | CHANGE [COLUMN] old_col_name new_col_name column_definition\n [FIRST|AFTER col_name]\n | MODIFY [COLUMN] col_name column_definition\n [FIRST | AFTER col_name]\n | DROP [COLUMN] col_name\n | DROP PRIMARY KEY\n | DROP {INDEX|KEY} index_name\n | DROP FOREIGN KEY fk_symbol\n | MAX_ROWS = rows\n | DISABLE KEYS\n | ENABLE KEYS\n | RENAME [TO|AS] new_tbl_name\n | ORDER BY col_name [, col_name] ...\n | CONVERT TO CHARACTER SET charset_name [COLLATE collation_name]\n | [DEFAULT] CHARACTER SET [=] charset_name [COLLATE [=] collation_name]\n | DISCARD TABLESPACE\n | IMPORT TABLESPACE\n | FORCE\n | ADD PARTITION (partition_definition)\n | DROP PARTITION partition_names\n | TRUNCATE PARTITION {partition_names | ALL}\n | COALESCE PARTITION number\n | REORGANIZE PARTITION [partition_names INTO (partition_definitions)]\n | ANALYZE PARTITION {partition_names | ALL}\n | CHECK PARTITION {partition_names | ALL}\n | OPTIMIZE PARTITION {partition_names | ALL}\n | REBUILD PARTITION {partition_names | ALL}\n | REPAIR PARTITION {partition_names | ALL}\n | PARTITION BY partitioning_expression\n | REMOVE PARTITIONING\n\nindex_col_name:\n col_name [(length)] [ASC | DESC]\n\nindex_type:\n USING {BTREE | HASH}\n\nindex_option:\n KEY_BLOCK_SIZE [=] value\n | index_type\n | WITH PARSER parser_name\n | COMMENT \'string\'\n\ntable_options:\n table_option [[,] table_option] ... (see CREATE TABLE options)\n\npartition_options:\n (see CREATE TABLE options)\n\nALTER TABLE changes the structure of a table. For example, you can add\nor delete columns, create or destroy indexes, change the type of\nexisting columns, or rename columns or the table itself. You can also\nchange characteristics such as the storage engine used for the table or\nthe table comment.\n\nPartitioning-related clauses for ALTER TABLE can be used with\npartitioned tables for repartitioning, for adding, dropping, merging,\nand splitting partitions, and for performing partitioning maintenance.\nFor more information, see\nhttp://dev.mysql.com/doc/refman/5.5/en/alter-table-partition-operations\n.html.\n\nFollowing the table name, specify the alterations to be made. If none\nare given, ALTER TABLE does nothing.\n\nURL: https://mariadb.com/kb/en/alter-table/\n\n','','https://mariadb.com/kb/en/alter-table/'); -insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (464,32,'MPOINTFROMWKB','MPointFromWKB(wkb[,srid]), MultiPointFromWKB(wkb[,srid])\n\nConstructs a MULTIPOINT value using its WKB representation and SRID.\n\nURL: https://mariadb.com/kb/en/mpointfromwkb/\n\n','','https://mariadb.com/kb/en/mpointfromwkb/'); -insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (465,22,'CHAR BYTE','The CHAR BYTE data type is an alias for the BINARY data type. This is a\ncompatibility feature.\n\nURL: https://mariadb.com/kb/en/char-byte/\n\n','','https://mariadb.com/kb/en/char-byte/'); -insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (466,20,'REPAIR TABLE','Syntax:\nREPAIR [NO_WRITE_TO_BINLOG | LOCAL] TABLE\n tbl_name [, tbl_name] ...\n [QUICK] [EXTENDED] [USE_FRM]\n\nREPAIR TABLE repairs a possibly corrupted table. By default, it has the\nsame effect as myisamchk --recover tbl_name. REPAIR TABLE works for\nMyISAM, ARCHIVE, and CSV tables. See\nhttps://mariadb.com/kb/en/myisam-storage-engine/, and\nhttps://mariadb.com/kb/en/archive/, and\nhttps://mariadb.com/kb/en/csv/\n\nThis statement requires SELECT and INSERT privileges for the table.\n\nREPAIR TABLE is supported for partitioned tables. However, the USE_FRM\noption cannot be used with this statement on a partitioned table.\n\nYou can use ALTER TABLE ... REPAIR PARTITION to repair one or more\npartitions; for more information, see [HELP ALTER TABLE], and\nhttp://dev.mysql.com/doc/refman/5.5/en/partitioning-maintenance.html.\n\nURL: https://mariadb.com/kb/en/repair-table/\n\n','','https://mariadb.com/kb/en/repair-table/'); -insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (467,39,'MERGE','The MERGE storage engine, also known as the MRG_MyISAM engine, is a\ncollection of identical MyISAM tables that can be used as one.\n"Identical" means that all tables have identical column and index\ninformation. You cannot merge MyISAM tables in which the columns are\nlisted in a different order, do not have exactly the same columns, or\nhave the indexes in different order. However, any or all of the MyISAM\ntables can be compressed with myisampack. See\nhttps://mariadb.com/kb/en/myisampack/. Differences in\ntable options such as AVG_ROW_LENGTH, MAX_ROWS, or PACK_KEYS do not\nmatter.\n\nURL: https://mariadb.com/kb/en/merge/\n\n','MariaDB> CREATE TABLE t1 (\n -> a INT NOT NULL AUTO_INCREMENT PRIMARY KEY,\n -> message CHAR(20)) ENGINE=MyISAM;\nMariaDB> CREATE TABLE t2 (\n -> a INT NOT NULL AUTO_INCREMENT PRIMARY KEY,\n -> message CHAR(20)) ENGINE=MyISAM;\nMariaDB> INSERT INTO t1 (message) VALUES (\'Testing\'),(\'table\'),(\'t1\');\nMariaDB> INSERT INTO t2 (message) VALUES (\'Testing\'),(\'table\'),(\'t2\');\nMariaDB> CREATE TABLE total (\n -> a INT NOT NULL AUTO_INCREMENT,\n -> message CHAR(20), INDEX(a))\n -> ENGINE=MERGE UNION=(t1,t2) INSERT_METHOD=LAST;\n','https://mariadb.com/kb/en/merge/'); -insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (468,39,'CREATE TABLE','Syntax:\nCREATE [TEMPORARY] TABLE [IF NOT EXISTS] tbl_name\n (create_definition,...)\n [table_options]\n [partition_options]\n\nOr:\n\nCREATE [TEMPORARY] TABLE [IF NOT EXISTS] tbl_name\n [(create_definition,...)]\n [table_options]\n [partition_options]\n select_statement\n\nOr:\n\nCREATE [TEMPORARY] TABLE [IF NOT EXISTS] tbl_name\n { LIKE old_tbl_name | (LIKE old_tbl_name) }\n\ncreate_definition:\n col_name column_definition\n | [CONSTRAINT [symbol]] PRIMARY KEY [index_type] (index_col_name,...)\n [index_option] ...\n | {INDEX|KEY} [index_name] [index_type] (index_col_name,...)\n [index_option] ...\n | [CONSTRAINT [symbol]] UNIQUE [INDEX|KEY]\n [index_name] [index_type] (index_col_name,...)\n [index_option] ...\n | {FULLTEXT|SPATIAL} [INDEX|KEY] [index_name] (index_col_name,...)\n [index_option] ...\n | [CONSTRAINT [symbol]] FOREIGN KEY\n [index_name] (index_col_name,...) reference_definition\n | CHECK (expr)\n\ncolumn_definition:\n data_type [NOT NULL | NULL] [DEFAULT default_value]\n [AUTO_INCREMENT] [UNIQUE [KEY] | [PRIMARY] KEY]\n [COMMENT \'string\']\n [COLUMN_FORMAT {FIXED|DYNAMIC|DEFAULT}]\n [STORAGE {DISK|MEMORY|DEFAULT}]\n [reference_definition]\n\ndata_type:\n BIT[(length)]\n | TINYINT[(length)] [UNSIGNED] [ZEROFILL]\n | SMALLINT[(length)] [UNSIGNED] [ZEROFILL]\n | MEDIUMINT[(length)] [UNSIGNED] [ZEROFILL]\n | INT[(length)] [UNSIGNED] [ZEROFILL]\n | INTEGER[(length)] [UNSIGNED] [ZEROFILL]\n | BIGINT[(length)] [UNSIGNED] [ZEROFILL]\n | REAL[(length,decimals)] [UNSIGNED] [ZEROFILL]\n | DOUBLE[(length,decimals)] [UNSIGNED] [ZEROFILL]\n | FLOAT[(length,decimals)] [UNSIGNED] [ZEROFILL]\n | DECIMAL[(length[,decimals])] [UNSIGNED] [ZEROFILL]\n | NUMERIC[(length[,decimals])] [UNSIGNED] [ZEROFILL]\n | DATE\n | TIME\n | TIMESTAMP\n | DATETIME\n | YEAR\n | CHAR[(length)]\n [CHARACTER SET charset_name] [COLLATE collation_name]\n | VARCHAR(length)\n [CHARACTER SET charset_name] [COLLATE collation_name]\n | BINARY[(length)]\n | VARBINARY(length)\n | TINYBLOB\n | BLOB\n | MEDIUMBLOB\n | LONGBLOB\n | TINYTEXT [BINARY]\n [CHARACTER SET charset_name] [COLLATE collation_name]\n | TEXT [BINARY]\n [CHARACTER SET charset_name] [COLLATE collation_name]\n | MEDIUMTEXT [BINARY]\n [CHARACTER SET charset_name] [COLLATE collation_name]\n | LONGTEXT [BINARY]\n [CHARACTER SET charset_name] [COLLATE collation_name]\n | ENUM(value1,value2,value3,...)\n [CHARACTER SET charset_name] [COLLATE collation_name]\n | SET(value1,value2,value3,...)\n [CHARACTER SET charset_name] [COLLATE collation_name]\n | spatial_type\n\nindex_col_name:\n col_name [(length)] [ASC | DESC]\n\nindex_type:\n USING {BTREE | HASH}\n\nindex_option:\n KEY_BLOCK_SIZE [=] value\n | index_type\n | WITH PARSER parser_name\n | COMMENT \'string\'\n\nreference_definition:\n REFERENCES tbl_name (index_col_name,...)\n [MATCH FULL | MATCH PARTIAL | MATCH SIMPLE]\n [ON DELETE reference_option]\n [ON UPDATE reference_option]\n\nreference_option:\n RESTRICT | CASCADE | SET NULL | NO ACTION\n\ntable_options:\n table_option [[,] table_option] ...\n\ntable_option:\n ENGINE [=] engine_name\n | AUTO_INCREMENT [=] value\n | AVG_ROW_LENGTH [=] value\n | [DEFAULT] CHARACTER SET [=] charset_name\n | CHECKSUM [=] {0 | 1}\n | [DEFAULT] COLLATE [=] collation_name\n | COMMENT [=] \'string\'\n | CONNECTION [=] \'connect_string\'\n | DATA DIRECTORY [=] \'absolute path to directory\'\n | DELAY_KEY_WRITE [=] {0 | 1}\n | INDEX DIRECTORY [=] \'absolute path to directory\'\n | INSERT_METHOD [=] { NO | FIRST | LAST }\n | KEY_BLOCK_SIZE [=] value\n | MAX_ROWS [=] value\n | MIN_ROWS [=] value\n | PACK_KEYS [=] {0 | 1 | DEFAULT}\n | PASSWORD [=] \'string\'\n | ROW_FORMAT [=] {DEFAULT|DYNAMIC|FIXED|COMPRESSED|REDUNDANT|COMPACT}\n | TABLESPACE tablespace_name [STORAGE {DISK|MEMORY|DEFAULT}]\n | UNION [=] (tbl_name[,tbl_name]...)\n\npartition_options:\n PARTITION BY\n { [LINEAR] HASH(expr)\n | [LINEAR] KEY(column_list)\n | RANGE{(expr) | COLUMNS(column_list)}\n | LIST{(expr) | COLUMNS(column_list)} }\n [PARTITIONS num]\n [SUBPARTITION BY\n { [LINEAR] HASH(expr)\n | [LINEAR] KEY(column_list) }\n [SUBPARTITIONS num]\n ]\n [(partition_definition [, partition_definition] ...)]\n\npartition_definition:\n PARTITION partition_name\n [VALUES \n {LESS THAN {(expr | value_list) | MAXVALUE} \n | \n IN (value_list)}]\n [[STORAGE] ENGINE [=] engine_name]\n [COMMENT [=] \'comment_text\' ]\n [DATA DIRECTORY [=] \'data_dir\']\n [INDEX DIRECTORY [=] \'index_dir\']\n [MAX_ROWS [=] max_number_of_rows]\n [MIN_ROWS [=] min_number_of_rows]\n [TABLESPACE [=] tablespace_name]\n [NODEGROUP [=] node_group_id]\n [(subpartition_definition [, subpartition_definition] ...)]\n\nsubpartition_definition:\n SUBPARTITION logical_name\n [[STORAGE] ENGINE [=] engine_name]\n [COMMENT [=] \'comment_text\' ]\n [DATA DIRECTORY [=] \'data_dir\']\n [INDEX DIRECTORY [=] \'index_dir\']\n [MAX_ROWS [=] max_number_of_rows]\n [MIN_ROWS [=] min_number_of_rows]\n [TABLESPACE [=] tablespace_name]\n [NODEGROUP [=] node_group_id]\n\nselect_statement:\n [IGNORE | REPLACE] [AS] SELECT ... (Some valid select statement)\n\nCREATE TABLE creates a table with the given name. You must have the\nCREATE privilege for the table.\n\nRules for permissible table names are given in\nhttps://mariadb.com/kb/en/identifier-names/. By default,\nthe table is created in the default database, using the InnoDB storage\nengine. An error occurs if the table exists, if there is no default\ndatabase, or if the database does not exist.\n\nURL: https://mariadb.com/kb/en/create-table/\n\n','','https://mariadb.com/kb/en/create-table/'); -insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (469,18,'>','Syntax:\n>\n\nGreater than:\n\nURL: https://mariadb.com/kb/en/greater-than/\n\n','MariaDB> SELECT 2 > 2;\n -> 0\n','https://mariadb.com/kb/en/greater-than/'); -insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (470,20,'ANALYZE TABLE','Syntax:\nANALYZE [NO_WRITE_TO_BINLOG | LOCAL] TABLE\n tbl_name [, tbl_name] ...\n\nANALYZE TABLE analyzes and stores the key distribution for a table.\nDuring the analysis, the table is locked with a read lock for InnoDB\nand MyISAM. This statement works with InnoDB, Aria and MyISAM tables.\nFor MyISAM tables, this statement is equivalent to using myisamchk\n--analyze.\n\nFor more information on how the analysis works within InnoDB, see\nhttp://dev.mysql.com/doc/refman/5.5/en/innodb-restrictions.html.\n\nMySQL uses the stored key distribution to decide the order in which\ntables should be joined when you perform a join on something other than\na constant. In addition, key distributions can be used when deciding\nwhich indexes to use for a specific table within a query.\n\nThis statement requires SELECT and INSERT privileges for the table.\n\nANALYZE TABLE is supported for partitioned tables, and you can use\nALTER TABLE ... ANALYZE PARTITION to analyze one or more partitions;\nfor more information, see [HELP ALTER TABLE], and\nhttp://dev.mysql.com/doc/refman/5.5/en/partitioning-maintenance.html.\n\nURL: https://mariadb.com/kb/en/analyze-table/\n\n','','https://mariadb.com/kb/en/analyze-table/'); -insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (471,31,'MICROSECOND','Syntax:\nMICROSECOND(expr)\n\nReturns the microseconds from the time or datetime expression expr as a\nnumber in the range from 0 to 999999.\n\nURL: https://mariadb.com/kb/en/microsecond/\n\n','MariaDB> SELECT MICROSECOND(\'12:00:00.123456\');\n -> 123456\nMariaDB> SELECT MICROSECOND(\'2009-12-31 23:59:59.000010\');\n -> 10\n','https://mariadb.com/kb/en/microsecond/'); -insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (472,39,'CONSTRAINT','InnoDB supports foreign keys, which let you cross-reference related\ndata across tables, and foreign key constraints, which help keep this\nspread-out data consistent. The syntax for an InnoDB foreign key\nconstraint definition in the CREATE TABLE or ALTER TABLE statement\nlooks like this:\n\n[CONSTRAINT [symbol]] FOREIGN KEY\n [index_name] (index_col_name, ...)\n REFERENCES tbl_name (index_col_name,...)\n [ON DELETE reference_option]\n [ON UPDATE reference_option]\n\nreference_option:\n RESTRICT | CASCADE | SET NULL | NO ACTION\n\nURL: https://mariadb.com/kb/en/constraint/\n\n','CREATE TABLE product (category INT NOT NULL, id INT NOT NULL,\n price DECIMAL,\n PRIMARY KEY(category, id)) ENGINE=INNODB;\nCREATE TABLE customer (id INT NOT NULL,\n PRIMARY KEY (id)) ENGINE=INNODB;\nCREATE TABLE product_order (no INT NOT NULL AUTO_INCREMENT,\n product_category INT NOT NULL,\n product_id INT NOT NULL,\n customer_id INT NOT NULL,\n PRIMARY KEY(no),\n INDEX (product_category, product_id),\n FOREIGN KEY (product_category, product_id)\n REFERENCES product(category, id)\n ON UPDATE CASCADE ON DELETE RESTRICT,\n INDEX (customer_id),\n FOREIGN KEY (customer_id)\n REFERENCES customer(id)) ENGINE=INNODB;\n','https://mariadb.com/kb/en/constraint/'); -insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (473,39,'CREATE SERVER','Syntax:\nCREATE SERVER server_name\n FOREIGN DATA WRAPPER wrapper_name\n OPTIONS (option [, option] ...)\n\noption:\n { HOST character-literal\n | DATABASE character-literal\n | USER character-literal\n | PASSWORD character-literal\n | SOCKET character-literal\n | OWNER character-literal\n | PORT numeric-literal }\n\nThis statement creates the definition of a server for use with the\nFEDERATED storage engine. The CREATE SERVER statement creates a new row\nwithin the servers table within the mysql database. This statement\nrequires the SUPER privilege.\n\nThe server_name should be a unique reference to the server. Server\ndefinitions are global within the scope of the server, it is not\npossible to qualify the server definition to a specific database.\nserver_name has a maximum length of 64 characters (names longer than 64\ncharacters are silently truncated), and is case insensitive. You may\nspecify the name as a quoted string.\n\nThe wrapper_name should be mysql, and may be quoted with single\nquotation marks. Other values for wrapper_name are not currently\nsupported.\n\nFor each option you must specify either a character literal or numeric\nliteral. Character literals are UTF-8, support a maximum length of 64\ncharacters and default to a blank (empty) string. String literals are\nsilently truncated to 64 characters. Numeric literals must be a number\nbetween 0 and 9999, default value is 0.\n\n*Note*: Note that the OWNER option is currently not applied, and has no\neffect on the ownership or operation of the server connection that is\ncreated.\n\nThe CREATE SERVER statement creates an entry in the mysql.servers table\nthat can later be used with the CREATE TABLE statement when creating a\nFEDERATED table. The options that you specify will be used to populate\nthe columns in the mysql.servers table. The table columns are\nServer_name, Host, Db, Username, Password, Port and Socket.\n\nURL: https://mariadb.com/kb/en/create-server/\n\n','CREATE SERVER s\nFOREIGN DATA WRAPPER mysql\nOPTIONS (USER \'Remote\', HOST \'192.168.1.106\', DATABASE \'test\');\n','https://mariadb.com/kb/en/create-server/'); -insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (474,37,'FIELD','Syntax:\nFIELD(str,str1,str2,str3,...)\n\nReturns the index (position) of str in the str1, str2, str3, ... list.\nReturns 0 if str is not found.\n\nIf all arguments to FIELD() are strings, all arguments are compared as\nstrings. If all arguments are numbers, they are compared as numbers.\nOtherwise, the arguments are compared as double.\n\nIf str is NULL, the return value is 0 because NULL fails equality\ncomparison with any value. FIELD() is the complement of ELT().\n\nURL: https://mariadb.com/kb/en/field/\n\n','MariaDB> SELECT FIELD(\'ej\', \'Hej\', \'ej\', \'Heja\', \'hej\', \'foo\');\n -> 2\nMariaDB> SELECT FIELD(\'fo\', \'Hej\', \'ej\', \'Heja\', \'hej\', \'foo\');\n -> 0\n','https://mariadb.com/kb/en/field/'); -insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (475,31,'MAKETIME','Syntax:\nMAKETIME(hour,minute,second)\n\nReturns a time value calculated from the hour, minute, and second\narguments.\n\nURL: https://mariadb.com/kb/en/maketime/\n\n','MariaDB> SELECT MAKETIME(12,15,30);\n -> \'12:15:30\'\n','https://mariadb.com/kb/en/maketime/'); -insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (476,31,'CURDATE','Syntax:\nCURDATE()\n\nReturns the current date as a value in \'YYYY-MM-DD\' or YYYYMMDD format,\ndepending on whether the function is used in a string or numeric\ncontext.\n\nURL: https://mariadb.com/kb/en/curdate/\n\n','MariaDB> SELECT CURDATE();\n -> \'2008-06-13\'\nMariaDB> SELECT CURDATE() + 0;\n -> 20080613\n','https://mariadb.com/kb/en/curdate/'); -insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (477,10,'SET PASSWORD','Syntax:\nSET PASSWORD [FOR user] =\n {\n PASSWORD(\'cleartext password\')\n | OLD_PASSWORD(\'cleartext password\')\n | \'encrypted password\'\n }\n\nThe SET PASSWORD statement assigns a password to an existing MySQL user\naccount. When the read_only system variable is enabled, the SUPER\nprivilege is required to use SET PASSWORD, in addition to whatever\nother privileges might be required.\n\nIf the password is specified using the PASSWORD() or OLD_PASSWORD()\nfunction, the cleartext (unencrypted) password should be given as the\nargument to the function, which hashes the password and returns the\nencrypted password string. If the password is specified without using\neither function, it should be the already encrypted password value as a\nliteral string. In all cases, the encrypted password string must be in\nthe format required by the authentication method used for the account.\n\nThe old_passwords system variable value determines the hashing method\nused by PASSWORD(). If you specify the password using that function and\nSET PASSWORD rejects the password as not being in the correct format,\nit may be necessary to set old_passwords to change the hashing method.\nFor descriptions of the permitted values, see\nhttps://mariadb.com/kb/en/server-system-variables#old_passwords.\n\nWith no FOR user clause, this statement sets the password for the\ncurrent user. (To see which account the server authenticated you as,\ninvoke the CURRENT_USER() function.) Any client who successfully\nconnects to the server using a nonanonymous account can change the\npassword for that account.\n\nWith a FOR user clause, this statement sets the password for the named\nuser. You must have the UPDATE privilege for the mysql database to do\nthis. The user account name uses the format described in\nhttps://mariadb.com/kb/en/create-user#account-names. The user\nvalue should be given as \'user_name\'@\'host_name\', where \'user_name\' and\n\'host_name\' are exactly as listed in the User and Host columns of the\nmysql.user table row. (If you specify only a user name, a host name of\n\'%\' is used.) For example, to set the password for an account with User\nand Host column values of \'bob\' and \'%.example.org\', write the\nstatement like this:\n\nSET PASSWORD FOR \'bob\'@\'%.example.org\' = PASSWORD(\'cleartext password\');\n\nURL: https://mariadb.com/kb/en/set-password/\n\n','','https://mariadb.com/kb/en/set-password/'); -insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (478,39,'ALTER TABLESPACE','Syntax:\nALTER TABLESPACE tablespace_name\n {ADD|DROP} DATAFILE \'file_name\'\n [INITIAL_SIZE [=] size]\n [WAIT]\n ENGINE [=] engine_name\n\nThis statement is used with NDB cluster, which is not supported by MariaDB.\n\nURL: https://mariadb.com/kb/en/alter-tablespace/\n\n','','https://mariadb.com/kb/en/alter-tablespace/'); -insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (479,7,'IF FUNCTION','Syntax:\nIF(expr1,expr2,expr3)\n\nIf expr1 is TRUE (expr1 <> 0 and expr1 <> NULL) then IF() returns\nexpr2; otherwise it returns expr3. IF() returns a numeric or string\nvalue, depending on the context in which it is used.\n\nURL: https://mariadb.com/kb/en/if-function/\n\n','MariaDB> SELECT IF(1>2,2,3);\n -> 3\nMariaDB> SELECT IF(1<2,\'yes\',\'no\');\n -> \'yes\'\nMariaDB> SELECT IF(STRCMP(\'test\',\'test1\'),\'no\',\'yes\');\n -> \'no\'\n','https://mariadb.com/kb/en/if-function/'); -insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (480,22,'ENUM','ENUM(\'value1\',\'value2\',...) [CHARACTER SET charset_name] [COLLATE\ncollation_name]\n\nAn enumeration. A string object that can have only one value, chosen\nfrom the list of values \'value1\', \'value2\', ..., NULL or the special \'\'\nerror value. An ENUM column can have a maximum of 65,535 distinct\nvalues. ENUM values are represented internally as integers.\n\nURL: https://mariadb.com/kb/en/enum/\n\n','','https://mariadb.com/kb/en/enum/'); -insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (481,17,'DATABASE','Syntax:\nDATABASE()\n\nReturns the default (current) database name as a string in the utf8\ncharacter set. If there is no default database, DATABASE() returns\nNULL. Within a stored routine, the default database is the database\nthat the routine is associated with, which is not necessarily the same\nas the database that is the default in the calling context.\n\nURL: https://mariadb.com/kb/en/database/\n\n','MariaDB> SELECT DATABASE();\n -> \'test\'\n','https://mariadb.com/kb/en/database/'); -insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (482,32,'POINTFROMWKB','PointFromWKB(wkb[,srid])\n\nConstructs a POINT value using its WKB representation and SRID.\n\nURL: https://mariadb.com/kb/en/pointfromwkb/\n\n','','https://mariadb.com/kb/en/pointfromwkb/'); -insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (483,4,'POWER','Syntax:\nPOWER(X,Y)\n\nThis is a synonym for POW().\n\nURL: https://mariadb.com/kb/en/power/\n\n','','https://mariadb.com/kb/en/power/'); -insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (484,4,'ATAN','Syntax:\nATAN(X)\n\nReturns the arc tangent of X, that is, the value whose tangent is X.\n\nURL: https://mariadb.com/kb/en/atan/\n\n','MariaDB> SELECT ATAN(2);\n -> 1.1071487177941\nMariaDB> SELECT ATAN(-2);\n -> -1.1071487177941\n','https://mariadb.com/kb/en/atan/'); -insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (485,37,'STRCMP','Syntax:\nSTRCMP(expr1,expr2)\n\nSTRCMP() returns 0 if the strings are the same, -1 if the first\nargument is smaller than the second according to the current sort\norder, and 1 otherwise.\n\nURL: https://mariadb.com/kb/en/strcmp/\n\n','MariaDB> SELECT STRCMP(\'text\', \'text2\');\n -> -1\nMariaDB> SELECT STRCMP(\'text2\', \'text\');\n -> 1\nMariaDB> SELECT STRCMP(\'text\', \'text\');\n -> 0\n','https://mariadb.com/kb/en/strcmp/'); -insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (486,27,'INSERT DELAYED','Syntax:\nINSERT DELAYED ...\n\nThe DELAYED option for the INSERT statement is a MySQL extension to\nstandard SQL that is very useful if you have clients that cannot or\nneed not wait for the INSERT to complete. This is a common situation\nwhen you use MySQL for logging and you also periodically run SELECT and\nUPDATE statements that take a long time to complete.\n\nWhen a client uses INSERT DELAYED, it gets an okay from the server at\nonce, and the row is queued to be inserted when the table is not in use\nby any other thread.\n\nAnother major benefit of using INSERT DELAYED is that inserts from many\nclients are bundled together and written in one block. This is much\nfaster than performing many separate inserts.\n\nNote that INSERT DELAYED is slower than a normal INSERT if the table is\nnot otherwise in use. There is also the additional overhead for the\nserver to handle a separate thread for each table for which there are\ndelayed rows. This means that you should use INSERT DELAYED only when\nyou are really sure that you need it.\n\nThe queued rows are held only in memory until they are inserted into\nthe table. This means that if you terminate mysqld forcibly (for\nexample, with kill -9) or if mysqld dies unexpectedly, any queued rows\nthat have not been written to disk are lost.\n\nThere are some constraints on the use of DELAYED:\n\no INSERT DELAYED works only with MyISAM, MEMORY, ARCHIVE, and BLACKHOLE\n tables. For engines that do not support DELAYED, an error occurs.\n\no An error occurs for INSERT DELAYED if used with a table that has been\n locked with LOCK TABLES because the insert must be handled by a\n separate thread, not by the session that holds the lock.\n\no For MyISAM tables, if there are no free blocks in the middle of the\n data file, concurrent SELECT and INSERT statements are supported.\n Under these circumstances, you very seldom need to use INSERT DELAYED\n with MyISAM.\n\no INSERT DELAYED should be used only for INSERT statements that specify\n value lists. The server ignores DELAYED for INSERT ... SELECT or\n INSERT ... ON DUPLICATE KEY UPDATE statements.\n\no Because the INSERT DELAYED statement returns immediately, before the\n rows are inserted, you cannot use LAST_INSERT_ID() to get the\n AUTO_INCREMENT value that the statement might generate.\n\no DELAYED rows are not visible to SELECT statements until they actually\n have been inserted.\n\no Prior to MySQL 5.5.7, INSERT DELAYED was treated as a normal INSERT\n if the statement inserted multiple rows, binary logging was enabled,\n and the global logging format was statement-based (that is, whenever\n binlog_format was set to STATEMENT). Beginning with MySQL 5.5.7,\n INSERT DELAYED is always handled as a simple INSERT (that is, without\n the DELAYED option) whenever the value of binlog_format is STATEMENT\n or MIXED. (In the latter case, the statement no longer triggers a\n switch to row-based logging, and so is logged using the\n statement-based format.)\n\n This does not apply when using row-based binary logging mode\n (binlog_format set to ROW), in which INSERT DELAYED statements are\n always executed using the DELAYED option as specified, and logged as\n row-update events.\n\no DELAYED is ignored on slave replication servers, so that INSERT\n DELAYED is treated as a normal INSERT on slaves. This is because\n DELAYED could cause the slave to have different data than the master.\n\no Pending INSERT DELAYED statements are lost if a table is write locked\n and ALTER TABLE is used to modify the table structure.\n\no INSERT DELAYED is not supported for views.\n\no INSERT DELAYED is not supported for partitioned tables.\n\nURL: https://mariadb.com/kb/en/insert-delayed/\n\n','','https://mariadb.com/kb/en/insert-delayed/'); -insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (487,26,'SHOW PROFILE','Syntax:\nSHOW PROFILE [type [, type] ... ]\n [FOR QUERY n]\n [LIMIT row_count [OFFSET offset]]\n\ntype:\n ALL\n | BLOCK IO\n | CONTEXT SWITCHES\n | CPU\n | IPC\n | MEMORY\n | PAGE FAULTS\n | SOURCE\n | SWAPS\n\nThe SHOW PROFILE and SHOW PROFILES statements display profiling\ninformation that indicates resource usage for statements executed\nduring the course of the current session.\n\nProfiling is controlled by the profiling session variable, which has a\ndefault value of 0 (OFF). Profiling is enabled by setting profiling to\n1 or ON:\n\nMariaDB> SET profiling = 1;\n\nSHOW PROFILES displays a list of the most recent statements sent to the\nserver. The size of the list is controlled by the\nprofiling_history_size session variable, which has a default value of\n15. The maximum value is 100. Setting the value to 0 has the practical\neffect of disabling profiling.\n\nAll statements are profiled except SHOW PROFILE and SHOW PROFILES, so\nyou will find neither of those statements in the profile list.\nMalformed statements are profiled. For example, SHOW PROFILING is an\nillegal statement, and a syntax error occurs if you try to execute it,\nbut it will show up in the profiling list.\n\nSHOW PROFILE displays detailed information about a single statement.\nWithout the FOR QUERY n clause, the output pertains to the most\nrecently executed statement. If FOR QUERY n is included, SHOW PROFILE\ndisplays information for statement n. The values of n correspond to the\nQuery_ID values displayed by SHOW PROFILES.\n\nThe LIMIT row_count clause may be given to limit the output to\nrow_count rows. If LIMIT is given, OFFSET offset may be added to begin\nthe output offset rows into the full set of rows.\n\nBy default, SHOW PROFILE displays Status and Duration columns. The\nStatus values are like the State values displayed by SHOW PROCESSLIST,\nalthough there might be some minor differences in interpretion for the\ntwo statements for some status values (see\nhttp://dev.mysql.com/doc/refman/5.5/en/thread-information.html).\n\nOptional type values may be specified to display specific additional\ntypes of information:\n\no ALL displays all information\n\no BLOCK IO displays counts for block input and output operations\n\no CONTEXT SWITCHES displays counts for voluntary and involuntary\n context switches\n\no CPU displays user and system CPU usage times\n\no IPC displays counts for messages sent and received\n\no MEMORY is not currently implemented\n\no PAGE FAULTS displays counts for major and minor page faults\n\no SOURCE displays the names of functions from the source code, together\n with the name and line number of the file in which the function\n occurs\n\no SWAPS displays swap counts\n\nProfiling is enabled per session. When a session ends, its profiling\ninformation is lost.\n\nURL: https://mariadb.com/kb/en/show-profile/\n\n','MariaDB> SELECT @@profiling;\n+-------------+\n| @@profiling |\n+-------------+\n| 0 |\n+-------------+\n1 row in set (0.00 sec)\n\nMariaDB> SET profiling = 1;\nQuery OK, 0 rows affected (0.00 sec)\n\nMariaDB> DROP TABLE IF EXISTS t1;\nQuery OK, 0 rows affected, 1 warning (0.00 sec)\n\nMariaDB> CREATE TABLE T1 (id INT);\nQuery OK, 0 rows affected (0.01 sec)\n\nMariaDB> SHOW PROFILES;\n+----------+----------+--------------------------+\n| Query_ID | Duration | Query |\n+----------+----------+--------------------------+\n| 0 | 0.000088 | SET PROFILING = 1 |\n| 1 | 0.000136 | DROP TABLE IF EXISTS t1 |\n| 2 | 0.011947 | CREATE TABLE t1 (id INT) |\n+----------+----------+--------------------------+\n3 rows in set (0.00 sec)\n\nMariaDB> SHOW PROFILE;\n+----------------------+----------+\n| Status | Duration |\n+----------------------+----------+\n| checking permissions | 0.000040 |\n| creating table | 0.000056 |\n| After create | 0.011363 |\n| query end | 0.000375 |\n| freeing items | 0.000089 |\n| logging slow query | 0.000019 |\n| cleaning up | 0.000005 |\n+----------------------+----------+\n7 rows in set (0.00 sec)\n\nMariaDB> SHOW PROFILE FOR QUERY 1;\n+--------------------+----------+\n| Status | Duration |\n+--------------------+----------+\n| query end | 0.000107 |\n| freeing items | 0.000008 |\n| logging slow query | 0.000015 |\n| cleaning up | 0.000006 |\n+--------------------+----------+\n4 rows in set (0.00 sec)\n\nMariaDB> SHOW PROFILE CPU FOR QUERY 2;\n+----------------------+----------+----------+------------+\n| Status | Duration | CPU_user | CPU_system |\n+----------------------+----------+----------+------------+\n| checking permissions | 0.000040 | 0.000038 | 0.000002 |\n| creating table | 0.000056 | 0.000028 | 0.000028 |\n| After create | 0.011363 | 0.000217 | 0.001571 |\n| query end | 0.000375 | 0.000013 | 0.000028 |\n| freeing items | 0.000089 | 0.000010 | 0.000014 |\n| logging slow query | 0.000019 | 0.000009 | 0.000010 |\n| cleaning up | 0.000005 | 0.000003 | 0.000002 |\n+----------------------+----------+----------+------------+\n7 rows in set (0.00 sec)\n','https://mariadb.com/kb/en/show-profile/'); -insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (488,26,'SHOW PROCEDURE CODE','Syntax:\nSHOW PROCEDURE CODE proc_name\n\nThis statement is a MySQL extension that is available only for servers\nthat have been built with debugging support. It displays a\nrepresentation of the internal implementation of the named stored\nprocedure. A similar statement, SHOW FUNCTION CODE, displays\ninformation about stored functions (see [HELP SHOW FUNCTION CODE]).\n\nBoth statements require that you be the owner of the routine or have\nSELECT access to the mysql.proc table.\n\nIf the named routine is available, each statement produces a result\nset. Each row in the result set corresponds to one "instruction" in the\nroutine. The first column is Pos, which is an ordinal number beginning\nwith 0. The second column is Instruction, which contains an SQL\nstatement (usually changed from the original source), or a directive\nwhich has meaning only to the stored-routine handler.\n\nURL: https://mariadb.com/kb/en/show-procedure-code/\n\n','MariaDB> DELIMITER //\nMariaDB> CREATE PROCEDURE p1 ()\n -> BEGIN\n -> DECLARE fanta INT DEFAULT 55;\n -> DROP TABLE t2;\n -> LOOP\n -> INSERT INTO t3 VALUES (fanta);\n -> END LOOP;\n -> END//\nQuery OK, 0 rows affected (0.00 sec)\n\nMariaDB> SHOW PROCEDURE CODE p1//\n+-----+----------------------------------------+\n| Pos | Instruction |\n+-----+----------------------------------------+\n| 0 | set fanta@0 55 |\n| 1 | stmt 9 "DROP TABLE t2" |\n| 2 | stmt 5 "INSERT INTO t3 VALUES (fanta)" |\n| 3 | jump 2 |\n+-----+----------------------------------------+\n4 rows in set (0.00 sec)\n','https://mariadb.com/kb/en/show-procedure-code/'); -insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (489,22,'MEDIUMTEXT','MEDIUMTEXT [CHARACTER SET charset_name] [COLLATE collation_name]\n\nA TEXT column with a maximum length of 16,777,215 (224 - 1) characters.\nThe effective maximum length is less if the value contains multi-byte\ncharacters. Each MEDIUMTEXT value is stored using a 3-byte length\nprefix that indicates the number of bytes in the value.\n\nURL: https://mariadb.com/kb/en/mediumtext/\n\n','','https://mariadb.com/kb/en/mediumtext/'); -insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (490,4,'LN','Syntax:\nLN(X)\n\nReturns the natural logarithm of X; that is, the base-e logarithm of X.\nIf X is less than or equal to 0, then NULL is returned.\n\nURL: https://mariadb.com/kb/en/ln/\n\n','MariaDB> SELECT LN(2);\n -> 0.69314718055995\nMariaDB> SELECT LN(-2);\n -> NULL\n','https://mariadb.com/kb/en/ln/'); -insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (491,23,'RETURN','Syntax:\nRETURN expr\n\nThe RETURN statement terminates execution of a stored function and\nreturns the value expr to the function caller. There must be at least\none RETURN statement in a stored function. There may be more than one\nif the function has multiple exit points.\n\nThis statement is not used in stored procedures, triggers, or events.\nThe LEAVE statement can be used to exit a stored program of those\ntypes.\n\nURL: https://mariadb.com/kb/en/return/\n\n','','https://mariadb.com/kb/en/return/'); -insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (492,26,'SHOW COLLATION','Syntax:\nSHOW COLLATION\n [LIKE \'pattern\' | WHERE expr]\n\nThis statement lists collations supported by the server. By default,\nthe output from SHOW COLLATION includes all available collations. The\nLIKE clause, if present, indicates which collation names to match. The\nWHERE clause can be given to select rows using more general conditions,\nas discussed in\nhttps://mariadb.com/kb/en/extended-show/. For example:\n\nMariaDB> SHOW COLLATION LIKE \'latin1%\';\n+-------------------+---------+----+---------+----------+---------+\n| Collation | Charset | Id | Default | Compiled | Sortlen |\n+-------------------+---------+----+---------+----------+---------+\n| latin1_german1_ci | latin1 | 5 | | | 0 |\n| latin1_swedish_ci | latin1 | 8 | Yes | Yes | 0 |\n| latin1_danish_ci | latin1 | 15 | | | 0 |\n| latin1_german2_ci | latin1 | 31 | | Yes | 2 |\n| latin1_bin | latin1 | 47 | | Yes | 0 |\n| latin1_general_ci | latin1 | 48 | | | 0 |\n| latin1_general_cs | latin1 | 49 | | | 0 |\n| latin1_spanish_ci | latin1 | 94 | | | 0 |\n+-------------------+---------+----+---------+----------+---------+\n\nURL: https://mariadb.com/kb/en/show-collation/\n\n','','https://mariadb.com/kb/en/show-collation/'); -insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (493,4,'LOG','Syntax:\nLOG(X), LOG(B,X)\n\nIf called with one parameter, this function returns the natural\nlogarithm of X. If X is less than or equal to 0, then NULL is returned.\n\nThe inverse of this function (when called with a single argument) is\nthe EXP() function.\n\nURL: https://mariadb.com/kb/en/log/\n\n','MariaDB> SELECT LOG(2);\n -> 0.69314718055995\nMariaDB> SELECT LOG(-2);\n -> NULL\n','https://mariadb.com/kb/en/log/'); -insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (494,8,'SET SQL_LOG_BIN','Syntax:\nSET sql_log_bin = {0|1}\n\nThe sql_log_bin variable controls whether logging to the binary log is\ndone. The default value is 1 (do logging). To change logging for the\ncurrent session, change the session value of this variable. The session\nuser must have the SUPER privilege to set this variable.\n\nBeginning with MySQL 5.5.5, it is no longer possible to set\n@@session.sql_log_bin within a transaction or subquery. (Bug #53437)\n\nURL: https://mariadb.com/kb/en/set-sql_log_bin/\n\n','','https://mariadb.com/kb/en/set-sql_log_bin/'); -insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (495,18,'!=','Syntax:\n<>, !=\n\nNot equal:\n\nURL: https://mariadb.com/kb/en/not-equal/\n\n','MariaDB> SELECT \'.01\' <> \'0.01\';\n -> 1\nMariaDB> SELECT .01 <> \'0.01\';\n -> 0\nMariaDB> SELECT \'zapp\' <> \'zappp\';\n -> 1\n','https://mariadb.com/kb/en/not-equal/'); -insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (496,23,'WHILE','Syntax:\n[begin_label:] WHILE search_condition DO\n statement_list\nEND WHILE [end_label]\n\nThe statement list within a WHILE statement is repeated as long as the\nsearch_condition expression is true. statement_list consists of one or\nmore SQL statements, each terminated by a semicolon (;) statement\ndelimiter.\n\nA WHILE statement can be labeled. For the rules regarding label use,\nsee [HELP labels].\n\nURL: https://mariadb.com/kb/en/while/\n\n','CREATE PROCEDURE dowhile()\nBEGIN\n DECLARE v1 INT DEFAULT 5;\n\n WHILE v1 > 0 DO\n ...\n SET v1 = v1 - 1;\n END WHILE;\nEND;\n','https://mariadb.com/kb/en/while/'); -insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (497,12,'AES_DECRYPT','Syntax:\nAES_DECRYPT(crypt_str,key_str)\n\nThis function decrypts data using the official AES (Advanced Encryption\nStandard) algorithm. For more information, see the description of\nAES_ENCRYPT().\n\nURL: https://mariadb.com/kb/en/aes_decrypt/\n\n','','https://mariadb.com/kb/en/aes_decrypt/'); -insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (498,31,'DAYNAME','Syntax:\nDAYNAME(date)\n\nReturns the name of the weekday for date. The language used for the\nname is controlled by the value of the lc_time_names system variable\n(https://mariadb.com/kb/en/server-system-variables#lc_time_names).\n\nURL: https://mariadb.com/kb/en/dayname/\n\n','MariaDB> SELECT DAYNAME(\'2007-02-03\');\n -> \'Saturday\'\n','https://mariadb.com/kb/en/dayname/'); -insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (499,17,'COERCIBILITY','Syntax:\nCOERCIBILITY(str)\n\nReturns the collation coercibility value of the string argument.\n\nURL: https://mariadb.com/kb/en/coercibility/\n\n','MariaDB> SELECT COERCIBILITY(\'abc\' COLLATE latin1_swedish_ci);\n -> 0\nMariaDB> SELECT COERCIBILITY(USER());\n -> 3\nMariaDB> SELECT COERCIBILITY(\'abc\');\n -> 4\n','https://mariadb.com/kb/en/coercibility/'); -insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (500,22,'INT','INT[(M)] [UNSIGNED] [ZEROFILL]\n\nA normal-size integer. The signed range is -2147483648 to 2147483647.\nThe unsigned range is 0 to 4294967295.\n\nURL: https://mariadb.com/kb/en/int/\n\n','','https://mariadb.com/kb/en/int/'); -insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (501,13,'GLENGTH','GLength(ls)\n\nReturns as a double-precision number the length of the LineString value\nls in its associated spatial reference.\n\nURL: https://mariadb.com/kb/en/glength/\n\n','MariaDB> SET @ls = \'LineString(1 1,2 2,3 3)\';\nMariaDB> SELECT GLength(GeomFromText(@ls));\n+----------------------------+\n| GLength(GeomFromText(@ls)) |\n+----------------------------+\n| 2.8284271247462 |\n+----------------------------+\n','https://mariadb.com/kb/en/glength/'); -insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (502,4,'RADIANS','Syntax:\nRADIANS(X)\n\nReturns the argument X, converted from degrees to radians. (Note that\nπ radians equals 180 degrees.)\n\nURL: https://mariadb.com/kb/en/radians/\n\n','MariaDB> SELECT RADIANS(90);\n -> 1.5707963267949\n','https://mariadb.com/kb/en/radians/'); -insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (503,17,'COLLATION','Syntax:\nCOLLATION(str)\n\nReturns the collation of the string argument.\n\nURL: https://mariadb.com/kb/en/collation/\n\n','MariaDB> SELECT COLLATION(\'abc\');\n -> \'latin1_swedish_ci\'\nMariaDB> SELECT COLLATION(_utf8\'abc\');\n -> \'utf8_general_ci\'\n','https://mariadb.com/kb/en/collation/'); -insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (504,18,'COALESCE','Syntax:\nCOALESCE(value,...)\n\nReturns the first non-NULL value in the list, or NULL if there are no\nnon-NULL values.\n\nURL: https://mariadb.com/kb/en/coalesce/\n\n','MariaDB> SELECT COALESCE(NULL,1);\n -> 1\nMariaDB> SELECT COALESCE(NULL,NULL,NULL);\n -> NULL\n','https://mariadb.com/kb/en/coalesce/'); -insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (505,17,'VERSION','Syntax:\nVERSION()\n\nReturns a string that indicates the MySQL server version. The string\nuses the utf8 character set. The value might have a suffix in addition\nto the version number. See the description of the version system\nvariable in\nhttps://mariadb.com/kb/en/server-system-variables#version.\n\nURL: https://mariadb.com/kb/en/version/\n\n','MariaDB> SELECT VERSION();\n -> \'5.5.29-standard\'\n','https://mariadb.com/kb/en/version/'); -insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (506,37,'MAKE_SET','Syntax:\nMAKE_SET(bits,str1,str2,...)\n\nReturns a set value (a string containing substrings separated by ","\ncharacters) consisting of the strings that have the corresponding bit\nin bits set. str1 corresponds to bit 0, str2 to bit 1, and so on. NULL\nvalues in str1, str2, ... are not appended to the result.\n\nURL: https://mariadb.com/kb/en/make_set/\n\n','MariaDB> SELECT MAKE_SET(1,\'a\',\'b\',\'c\');\n -> \'a\'\nMariaDB> SELECT MAKE_SET(1 | 4,\'hello\',\'nice\',\'world\');\n -> \'hello,world\'\nMariaDB> SELECT MAKE_SET(1 | 4,\'hello\',\'nice\',NULL,\'world\');\n -> \'hello\'\nMariaDB> SELECT MAKE_SET(0,\'a\',\'b\',\'c\');\n -> \'\'\n','https://mariadb.com/kb/en/make_set/'); -insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (507,37,'FIND_IN_SET','Syntax:\nFIND_IN_SET(str,strlist)\n\nReturns a value in the range of 1 to N if the string str is in the\nstring list strlist consisting of N substrings. A string list is a\nstring composed of substrings separated by "," characters. If the first\nargument is a constant string and the second is a column of type SET,\nthe FIND_IN_SET() function is optimized to use bit arithmetic. Returns\n0 if str is not in strlist or if strlist is the empty string. Returns\nNULL if either argument is NULL. This function does not work properly\nif the first argument contains a comma (",") character.\n\nURL: https://mariadb.com/kb/en/find_in_set/\n\n','MariaDB> SELECT FIND_IN_SET(\'b\',\'a,b,c,d\');\n -> 2\n','https://mariadb.com/kb/en/find_in_set/'); - -insert into help_keyword (help_keyword_id,name) values (0,'JOIN'); -insert into help_keyword (help_keyword_id,name) values (1,'HOST'); -insert into help_keyword (help_keyword_id,name) values (2,'REPEAT'); -insert into help_keyword (help_keyword_id,name) values (3,'SERIALIZABLE'); -insert into help_keyword (help_keyword_id,name) values (4,'REPLACE'); -insert into help_keyword (help_keyword_id,name) values (5,'AT'); -insert into help_keyword (help_keyword_id,name) values (6,'SCHEDULE'); -insert into help_keyword (help_keyword_id,name) values (7,'RETURNS'); -insert into help_keyword (help_keyword_id,name) values (8,'STARTS'); -insert into help_keyword (help_keyword_id,name) values (9,'MASTER_SSL_CA'); -insert into help_keyword (help_keyword_id,name) values (10,'NCHAR'); -insert into help_keyword (help_keyword_id,name) values (11,'COLUMNS'); -insert into help_keyword (help_keyword_id,name) values (12,'COMPLETION'); -insert into help_keyword (help_keyword_id,name) values (13,'WORK'); -insert into help_keyword (help_keyword_id,name) values (14,'DATETIME'); -insert into help_keyword (help_keyword_id,name) values (15,'MODE'); -insert into help_keyword (help_keyword_id,name) values (16,'OPEN'); -insert into help_keyword (help_keyword_id,name) values (17,'INTEGER'); -insert into help_keyword (help_keyword_id,name) values (18,'ESCAPE'); -insert into help_keyword (help_keyword_id,name) values (19,'VALUE'); -insert into help_keyword (help_keyword_id,name) values (20,'MASTER_SSL_VERIFY_SERVER_CERT'); -insert into help_keyword (help_keyword_id,name) values (21,'SQL_BIG_RESULT'); -insert into help_keyword (help_keyword_id,name) values (22,'DROP'); -insert into help_keyword (help_keyword_id,name) values (23,'GEOMETRYCOLLECTIONFROMWKB'); -insert into help_keyword (help_keyword_id,name) values (24,'EVENTS'); -insert into help_keyword (help_keyword_id,name) values (25,'MONTH'); -insert into help_keyword (help_keyword_id,name) values (26,'PROFILES'); -insert into help_keyword (help_keyword_id,name) values (27,'DUPLICATE'); -insert into help_keyword (help_keyword_id,name) values (28,'REPLICATION'); -insert into help_keyword (help_keyword_id,name) values (29,'UNLOCK'); -insert into help_keyword (help_keyword_id,name) values (30,'INNODB'); -insert into help_keyword (help_keyword_id,name) values (31,'YEAR_MONTH'); -insert into help_keyword (help_keyword_id,name) values (32,'SUBJECT'); -insert into help_keyword (help_keyword_id,name) values (33,'PREPARE'); -insert into help_keyword (help_keyword_id,name) values (34,'LOCK'); -insert into help_keyword (help_keyword_id,name) values (35,'NDB'); -insert into help_keyword (help_keyword_id,name) values (36,'CHECK'); -insert into help_keyword (help_keyword_id,name) values (37,'FULL'); -insert into help_keyword (help_keyword_id,name) values (38,'INT4'); -insert into help_keyword (help_keyword_id,name) values (39,'BY'); -insert into help_keyword (help_keyword_id,name) values (40,'NO'); -insert into help_keyword (help_keyword_id,name) values (41,'MINUTE'); -insert into help_keyword (help_keyword_id,name) values (42,'PARTITION'); -insert into help_keyword (help_keyword_id,name) values (43,'DATA'); -insert into help_keyword (help_keyword_id,name) values (44,'DAY'); -insert into help_keyword (help_keyword_id,name) values (45,'SHARE'); -insert into help_keyword (help_keyword_id,name) values (46,'REAL'); -insert into help_keyword (help_keyword_id,name) values (47,'SEPARATOR'); -insert into help_keyword (help_keyword_id,name) values (48,'MESSAGE_TEXT'); -insert into help_keyword (help_keyword_id,name) values (49,'MASTER_HEARTBEAT_PERIOD'); -insert into help_keyword (help_keyword_id,name) values (50,'DELETE'); -insert into help_keyword (help_keyword_id,name) values (51,'ON'); -insert into help_keyword (help_keyword_id,name) values (52,'COLUMN_NAME'); -insert into help_keyword (help_keyword_id,name) values (53,'CONNECTION'); -insert into help_keyword (help_keyword_id,name) values (54,'CLOSE'); -insert into help_keyword (help_keyword_id,name) values (55,'X509'); -insert into help_keyword (help_keyword_id,name) values (56,'USE'); -insert into help_keyword (help_keyword_id,name) values (57,'SUBCLASS_ORIGIN'); -insert into help_keyword (help_keyword_id,name) values (58,'WHERE'); -insert into help_keyword (help_keyword_id,name) values (59,'PRIVILEGES'); -insert into help_keyword (help_keyword_id,name) values (60,'SPATIAL'); -insert into help_keyword (help_keyword_id,name) values (61,'EVENT'); -insert into help_keyword (help_keyword_id,name) values (62,'SUPER'); -insert into help_keyword (help_keyword_id,name) values (63,'SQL_BUFFER_RESULT'); -insert into help_keyword (help_keyword_id,name) values (64,'IGNORE'); -insert into help_keyword (help_keyword_id,name) values (65,'SHA2'); -insert into help_keyword (help_keyword_id,name) values (66,'QUICK'); -insert into help_keyword (help_keyword_id,name) values (67,'SIGNED'); -insert into help_keyword (help_keyword_id,name) values (68,'OFFLINE'); -insert into help_keyword (help_keyword_id,name) values (69,'SECURITY'); -insert into help_keyword (help_keyword_id,name) values (70,'AUTOEXTEND_SIZE'); -insert into help_keyword (help_keyword_id,name) values (71,'NDBCLUSTER'); -insert into help_keyword (help_keyword_id,name) values (72,'POLYGONFROMWKB'); -insert into help_keyword (help_keyword_id,name) values (73,'FALSE'); -insert into help_keyword (help_keyword_id,name) values (74,'LEVEL'); -insert into help_keyword (help_keyword_id,name) values (75,'FORCE'); -insert into help_keyword (help_keyword_id,name) values (76,'BINARY'); -insert into help_keyword (help_keyword_id,name) values (77,'TO'); -insert into help_keyword (help_keyword_id,name) values (78,'CHANGE'); -insert into help_keyword (help_keyword_id,name) values (79,'CURRENT_USER'); -insert into help_keyword (help_keyword_id,name) values (80,'HOUR_MINUTE'); -insert into help_keyword (help_keyword_id,name) values (81,'UPDATE'); -insert into help_keyword (help_keyword_id,name) values (82,'PRESERVE'); -insert into help_keyword (help_keyword_id,name) values (83,'TABLE_NAME'); -insert into help_keyword (help_keyword_id,name) values (84,'INTO'); -insert into help_keyword (help_keyword_id,name) values (85,'FEDERATED'); -insert into help_keyword (help_keyword_id,name) values (86,'VARYING'); -insert into help_keyword (help_keyword_id,name) values (87,'MAX_SIZE'); -insert into help_keyword (help_keyword_id,name) values (88,'HOUR_SECOND'); -insert into help_keyword (help_keyword_id,name) values (89,'VARIABLE'); -insert into help_keyword (help_keyword_id,name) values (90,'ROLLBACK'); -insert into help_keyword (help_keyword_id,name) values (91,'PROCEDURE'); -insert into help_keyword (help_keyword_id,name) values (92,'TIMESTAMP'); -insert into help_keyword (help_keyword_id,name) values (93,'IMPORT'); -insert into help_keyword (help_keyword_id,name) values (94,'AGAINST'); -insert into help_keyword (help_keyword_id,name) values (95,'CHECKSUM'); -insert into help_keyword (help_keyword_id,name) values (96,'COUNT'); -insert into help_keyword (help_keyword_id,name) values (97,'LONGBINARY'); -insert into help_keyword (help_keyword_id,name) values (98,'THEN'); -insert into help_keyword (help_keyword_id,name) values (99,'INSERT'); -insert into help_keyword (help_keyword_id,name) values (100,'ENGINES'); -insert into help_keyword (help_keyword_id,name) values (101,'HANDLER'); -insert into help_keyword (help_keyword_id,name) values (102,'PORT'); -insert into help_keyword (help_keyword_id,name) values (103,'DAY_SECOND'); -insert into help_keyword (help_keyword_id,name) values (104,'EXISTS'); -insert into help_keyword (help_keyword_id,name) values (105,'MUTEX'); -insert into help_keyword (help_keyword_id,name) values (106,'HELP_DATE'); -insert into help_keyword (help_keyword_id,name) values (107,'RELEASE'); -insert into help_keyword (help_keyword_id,name) values (108,'BOOLEAN'); -insert into help_keyword (help_keyword_id,name) values (109,'MOD'); -insert into help_keyword (help_keyword_id,name) values (110,'DEFAULT'); -insert into help_keyword (help_keyword_id,name) values (111,'TYPE'); -insert into help_keyword (help_keyword_id,name) values (112,'NO_WRITE_TO_BINLOG'); -insert into help_keyword (help_keyword_id,name) values (113,'OPTIMIZE'); -insert into help_keyword (help_keyword_id,name) values (114,'SQLSTATE'); -insert into help_keyword (help_keyword_id,name) values (115,'RESET'); -insert into help_keyword (help_keyword_id,name) values (116,'CLASS_ORIGIN'); -insert into help_keyword (help_keyword_id,name) values (117,'INSTALL'); -insert into help_keyword (help_keyword_id,name) values (118,'ITERATE'); -insert into help_keyword (help_keyword_id,name) values (119,'DO'); -insert into help_keyword (help_keyword_id,name) values (120,'BIGINT'); -insert into help_keyword (help_keyword_id,name) values (121,'SET'); -insert into help_keyword (help_keyword_id,name) values (122,'ISSUER'); -insert into help_keyword (help_keyword_id,name) values (123,'DATE'); -insert into help_keyword (help_keyword_id,name) values (124,'STATUS'); -insert into help_keyword (help_keyword_id,name) values (125,'FULLTEXT'); -insert into help_keyword (help_keyword_id,name) values (126,'COMMENT'); -insert into help_keyword (help_keyword_id,name) values (127,'MASTER_CONNECT_RETRY'); -insert into help_keyword (help_keyword_id,name) values (128,'INNER'); -insert into help_keyword (help_keyword_id,name) values (129,'RELAYLOG'); -insert into help_keyword (help_keyword_id,name) values (130,'STOP'); -insert into help_keyword (help_keyword_id,name) values (131,'MASTER_LOG_FILE'); -insert into help_keyword (help_keyword_id,name) values (132,'MRG_MYISAM'); -insert into help_keyword (help_keyword_id,name) values (133,'PRECISION'); -insert into help_keyword (help_keyword_id,name) values (134,'REQUIRE'); -insert into help_keyword (help_keyword_id,name) values (135,'TRAILING'); -insert into help_keyword (help_keyword_id,name) values (136,'PARTITIONS'); -insert into help_keyword (help_keyword_id,name) values (137,'LONG'); -insert into help_keyword (help_keyword_id,name) values (138,'OPTION'); -insert into help_keyword (help_keyword_id,name) values (139,'REORGANIZE'); -insert into help_keyword (help_keyword_id,name) values (140,'ELSE'); -insert into help_keyword (help_keyword_id,name) values (141,'DEALLOCATE'); -insert into help_keyword (help_keyword_id,name) values (142,'IO_THREAD'); -insert into help_keyword (help_keyword_id,name) values (143,'CASE'); -insert into help_keyword (help_keyword_id,name) values (144,'CIPHER'); -insert into help_keyword (help_keyword_id,name) values (145,'CONTINUE'); -insert into help_keyword (help_keyword_id,name) values (146,'FROM'); -insert into help_keyword (help_keyword_id,name) values (147,'READ'); -insert into help_keyword (help_keyword_id,name) values (148,'LEFT'); -insert into help_keyword (help_keyword_id,name) values (149,'ELSEIF'); -insert into help_keyword (help_keyword_id,name) values (150,'MINUTE_SECOND'); -insert into help_keyword (help_keyword_id,name) values (151,'COMPACT'); -insert into help_keyword (help_keyword_id,name) values (152,'DEC'); -insert into help_keyword (help_keyword_id,name) values (153,'FOR'); -insert into help_keyword (help_keyword_id,name) values (154,'WARNINGS'); -insert into help_keyword (help_keyword_id,name) values (155,'MIN_ROWS'); -insert into help_keyword (help_keyword_id,name) values (156,'STRING'); -insert into help_keyword (help_keyword_id,name) values (157,'CONDITION'); -insert into help_keyword (help_keyword_id,name) values (158,'ENCLOSED'); -insert into help_keyword (help_keyword_id,name) values (159,'FUNCTION'); -insert into help_keyword (help_keyword_id,name) values (160,'AGGREGATE'); -insert into help_keyword (help_keyword_id,name) values (161,'FIELDS'); -insert into help_keyword (help_keyword_id,name) values (162,'INT3'); -insert into help_keyword (help_keyword_id,name) values (163,'ARCHIVE'); -insert into help_keyword (help_keyword_id,name) values (164,'AVG_ROW_LENGTH'); -insert into help_keyword (help_keyword_id,name) values (165,'ADD'); -insert into help_keyword (help_keyword_id,name) values (166,'KILL'); -insert into help_keyword (help_keyword_id,name) values (167,'FLOAT4'); -insert into help_keyword (help_keyword_id,name) values (168,'TABLESPACE'); -insert into help_keyword (help_keyword_id,name) values (169,'VIEW'); -insert into help_keyword (help_keyword_id,name) values (170,'REPEATABLE'); -insert into help_keyword (help_keyword_id,name) values (171,'INFILE'); -insert into help_keyword (help_keyword_id,name) values (172,'HELP_VERSION'); -insert into help_keyword (help_keyword_id,name) values (173,'ORDER'); -insert into help_keyword (help_keyword_id,name) values (174,'USING'); -insert into help_keyword (help_keyword_id,name) values (175,'CONSTRAINT_CATALOG'); -insert into help_keyword (help_keyword_id,name) values (176,'MIDDLEINT'); -insert into help_keyword (help_keyword_id,name) values (177,'GRANT'); -insert into help_keyword (help_keyword_id,name) values (178,'UNSIGNED'); -insert into help_keyword (help_keyword_id,name) values (179,'DECIMAL'); -insert into help_keyword (help_keyword_id,name) values (180,'GEOMETRYFROMTEXT'); -insert into help_keyword (help_keyword_id,name) values (181,'INDEXES'); -insert into help_keyword (help_keyword_id,name) values (182,'FOREIGN'); -insert into help_keyword (help_keyword_id,name) values (183,'CACHE'); -insert into help_keyword (help_keyword_id,name) values (184,'HOSTS'); -insert into help_keyword (help_keyword_id,name) values (185,'MYSQL_ERRNO'); -insert into help_keyword (help_keyword_id,name) values (186,'COMMIT'); -insert into help_keyword (help_keyword_id,name) values (187,'SCHEMAS'); -insert into help_keyword (help_keyword_id,name) values (188,'LEADING'); -insert into help_keyword (help_keyword_id,name) values (189,'SNAPSHOT'); -insert into help_keyword (help_keyword_id,name) values (190,'CONSTRAINT_NAME'); -insert into help_keyword (help_keyword_id,name) values (191,'DECLARE'); -insert into help_keyword (help_keyword_id,name) values (192,'LOAD'); -insert into help_keyword (help_keyword_id,name) values (193,'SQL_CACHE'); -insert into help_keyword (help_keyword_id,name) values (194,'CONVERT'); -insert into help_keyword (help_keyword_id,name) values (195,'DYNAMIC'); -insert into help_keyword (help_keyword_id,name) values (196,'COLLATE'); -insert into help_keyword (help_keyword_id,name) values (197,'POLYGONFROMTEXT'); -insert into help_keyword (help_keyword_id,name) values (198,'BYTE'); -insert into help_keyword (help_keyword_id,name) values (199,'GLOBAL'); -insert into help_keyword (help_keyword_id,name) values (200,'LINESTRINGFROMWKB'); -insert into help_keyword (help_keyword_id,name) values (201,'WHEN'); -insert into help_keyword (help_keyword_id,name) values (202,'HAVING'); -insert into help_keyword (help_keyword_id,name) values (203,'AS'); -insert into help_keyword (help_keyword_id,name) values (204,'STARTING'); -insert into help_keyword (help_keyword_id,name) values (205,'RELOAD'); -insert into help_keyword (help_keyword_id,name) values (206,'AUTOCOMMIT'); -insert into help_keyword (help_keyword_id,name) values (207,'REVOKE'); -insert into help_keyword (help_keyword_id,name) values (208,'GRANTS'); -insert into help_keyword (help_keyword_id,name) values (209,'OUTER'); -insert into help_keyword (help_keyword_id,name) values (210,'CURSOR_NAME'); -insert into help_keyword (help_keyword_id,name) values (211,'FLOOR'); -insert into help_keyword (help_keyword_id,name) values (212,'EXPLAIN'); -insert into help_keyword (help_keyword_id,name) values (213,'WITH'); -insert into help_keyword (help_keyword_id,name) values (214,'AFTER'); -insert into help_keyword (help_keyword_id,name) values (215,'STD'); -insert into help_keyword (help_keyword_id,name) values (216,'CSV'); -insert into help_keyword (help_keyword_id,name) values (217,'DISABLE'); -insert into help_keyword (help_keyword_id,name) values (218,'UNINSTALL'); -insert into help_keyword (help_keyword_id,name) values (219,'OUTFILE'); -insert into help_keyword (help_keyword_id,name) values (220,'LOW_PRIORITY'); -insert into help_keyword (help_keyword_id,name) values (221,'FILE'); -insert into help_keyword (help_keyword_id,name) values (222,'NODEGROUP'); -insert into help_keyword (help_keyword_id,name) values (223,'SCHEMA'); -insert into help_keyword (help_keyword_id,name) values (224,'SONAME'); -insert into help_keyword (help_keyword_id,name) values (225,'POW'); -insert into help_keyword (help_keyword_id,name) values (226,'DUAL'); -insert into help_keyword (help_keyword_id,name) values (227,'MULTIPOINTFROMWKB'); -insert into help_keyword (help_keyword_id,name) values (228,'INDEX'); -insert into help_keyword (help_keyword_id,name) values (229,'MULTIPOINTFROMTEXT'); -insert into help_keyword (help_keyword_id,name) values (230,'DEFINER'); -insert into help_keyword (help_keyword_id,name) values (231,'MASTER_BIND'); -insert into help_keyword (help_keyword_id,name) values (232,'REMOVE'); -insert into help_keyword (help_keyword_id,name) values (233,'EXTENDED'); -insert into help_keyword (help_keyword_id,name) values (234,'MULTILINESTRINGFROMWKB'); -insert into help_keyword (help_keyword_id,name) values (235,'CROSS'); -insert into help_keyword (help_keyword_id,name) values (236,'CONTRIBUTORS'); -insert into help_keyword (help_keyword_id,name) values (237,'NATIONAL'); -insert into help_keyword (help_keyword_id,name) values (238,'GROUP'); -insert into help_keyword (help_keyword_id,name) values (239,'SHA'); -insert into help_keyword (help_keyword_id,name) values (240,'ONLINE'); -insert into help_keyword (help_keyword_id,name) values (241,'UNDO'); -insert into help_keyword (help_keyword_id,name) values (242,'IGNORE_SERVER_IDS'); -insert into help_keyword (help_keyword_id,name) values (243,'ZEROFILL'); -insert into help_keyword (help_keyword_id,name) values (244,'CLIENT'); -insert into help_keyword (help_keyword_id,name) values (245,'MASTER_PASSWORD'); -insert into help_keyword (help_keyword_id,name) values (246,'OWNER'); -insert into help_keyword (help_keyword_id,name) values (247,'RELAY_LOG_FILE'); -insert into help_keyword (help_keyword_id,name) values (248,'TRUE'); -insert into help_keyword (help_keyword_id,name) values (249,'CHARACTER'); -insert into help_keyword (help_keyword_id,name) values (250,'MASTER_USER'); -insert into help_keyword (help_keyword_id,name) values (251,'SCHEMA_NAME'); -insert into help_keyword (help_keyword_id,name) values (252,'TABLE'); -insert into help_keyword (help_keyword_id,name) values (253,'ENGINE'); -insert into help_keyword (help_keyword_id,name) values (254,'INSERT_METHOD'); -insert into help_keyword (help_keyword_id,name) values (255,'CASCADE'); -insert into help_keyword (help_keyword_id,name) values (256,'RELAY_LOG_POS'); -insert into help_keyword (help_keyword_id,name) values (257,'SQL_CALC_FOUND_ROWS'); -insert into help_keyword (help_keyword_id,name) values (258,'UNION'); -insert into help_keyword (help_keyword_id,name) values (259,'MYISAM'); -insert into help_keyword (help_keyword_id,name) values (260,'LEAVE'); -insert into help_keyword (help_keyword_id,name) values (261,'MODIFY'); -insert into help_keyword (help_keyword_id,name) values (262,'MATCH'); -insert into help_keyword (help_keyword_id,name) values (263,'MASTER_LOG_POS'); -insert into help_keyword (help_keyword_id,name) values (264,'DISTINCTROW'); -insert into help_keyword (help_keyword_id,name) values (265,'DESC'); -insert into help_keyword (help_keyword_id,name) values (266,'TIME'); -insert into help_keyword (help_keyword_id,name) values (267,'NUMERIC'); -insert into help_keyword (help_keyword_id,name) values (268,'EXPANSION'); -insert into help_keyword (help_keyword_id,name) values (269,'CODE'); -insert into help_keyword (help_keyword_id,name) values (270,'CURSOR'); -insert into help_keyword (help_keyword_id,name) values (271,'GEOMETRYCOLLECTIONFROMTEXT'); -insert into help_keyword (help_keyword_id,name) values (272,'CHAIN'); -insert into help_keyword (help_keyword_id,name) values (273,'LOGFILE'); -insert into help_keyword (help_keyword_id,name) values (274,'FLUSH'); -insert into help_keyword (help_keyword_id,name) values (275,'CREATE'); -insert into help_keyword (help_keyword_id,name) values (276,'DESCRIBE'); -insert into help_keyword (help_keyword_id,name) values (277,'EXTENT_SIZE'); -insert into help_keyword (help_keyword_id,name) values (278,'MAX_UPDATES_PER_HOUR'); -insert into help_keyword (help_keyword_id,name) values (279,'INT2'); -insert into help_keyword (help_keyword_id,name) values (280,'PROCESSLIST'); -insert into help_keyword (help_keyword_id,name) values (281,'ENDS'); -insert into help_keyword (help_keyword_id,name) values (282,'LOGS'); -insert into help_keyword (help_keyword_id,name) values (283,'DISCARD'); -insert into help_keyword (help_keyword_id,name) values (284,'HEAP'); -insert into help_keyword (help_keyword_id,name) values (285,'SOUNDS'); -insert into help_keyword (help_keyword_id,name) values (286,'BETWEEN'); -insert into help_keyword (help_keyword_id,name) values (287,'MULTILINESTRINGFROMTEXT'); -insert into help_keyword (help_keyword_id,name) values (288,'REPAIR'); -insert into help_keyword (help_keyword_id,name) values (289,'PACK_KEYS'); -insert into help_keyword (help_keyword_id,name) values (290,'FAST'); -insert into help_keyword (help_keyword_id,name) values (291,'VALUES'); -insert into help_keyword (help_keyword_id,name) values (292,'CALL'); -insert into help_keyword (help_keyword_id,name) values (293,'LOOP'); -insert into help_keyword (help_keyword_id,name) values (294,'VARCHARACTER'); -insert into help_keyword (help_keyword_id,name) values (295,'BEFORE'); -insert into help_keyword (help_keyword_id,name) values (296,'TRUNCATE'); -insert into help_keyword (help_keyword_id,name) values (297,'SHOW'); -insert into help_keyword (help_keyword_id,name) values (298,'ALL'); -insert into help_keyword (help_keyword_id,name) values (299,'REDUNDANT'); -insert into help_keyword (help_keyword_id,name) values (300,'USER_RESOURCES'); -insert into help_keyword (help_keyword_id,name) values (301,'PARTIAL'); -insert into help_keyword (help_keyword_id,name) values (302,'BINLOG'); -insert into help_keyword (help_keyword_id,name) values (303,'END'); -insert into help_keyword (help_keyword_id,name) values (304,'SECOND'); -insert into help_keyword (help_keyword_id,name) values (305,'AND'); -insert into help_keyword (help_keyword_id,name) values (306,'FLOAT8'); -insert into help_keyword (help_keyword_id,name) values (307,'PREV'); -insert into help_keyword (help_keyword_id,name) values (308,'HOUR'); -insert into help_keyword (help_keyword_id,name) values (309,'SELECT'); -insert into help_keyword (help_keyword_id,name) values (310,'DATABASES'); -insert into help_keyword (help_keyword_id,name) values (311,'OR'); -insert into help_keyword (help_keyword_id,name) values (312,'IDENTIFIED'); -insert into help_keyword (help_keyword_id,name) values (313,'WRAPPER'); -insert into help_keyword (help_keyword_id,name) values (314,'MASTER_SSL_CIPHER'); -insert into help_keyword (help_keyword_id,name) values (315,'SQL_SLAVE_SKIP_COUNTER'); -insert into help_keyword (help_keyword_id,name) values (316,'BOTH'); -insert into help_keyword (help_keyword_id,name) values (317,'BOOL'); -insert into help_keyword (help_keyword_id,name) values (318,'YEAR'); -insert into help_keyword (help_keyword_id,name) values (319,'MASTER_PORT'); -insert into help_keyword (help_keyword_id,name) values (320,'CONCURRENT'); -insert into help_keyword (help_keyword_id,name) values (321,'HELP'); -insert into help_keyword (help_keyword_id,name) values (322,'UNIQUE'); -insert into help_keyword (help_keyword_id,name) values (323,'TRIGGERS'); -insert into help_keyword (help_keyword_id,name) values (324,'PROCESS'); -insert into help_keyword (help_keyword_id,name) values (325,'OPTIONS'); -insert into help_keyword (help_keyword_id,name) values (326,'RESIGNAL'); -insert into help_keyword (help_keyword_id,name) values (327,'CONSISTENT'); -insert into help_keyword (help_keyword_id,name) values (328,'MASTER_SSL'); -insert into help_keyword (help_keyword_id,name) values (329,'DATE_ADD'); -insert into help_keyword (help_keyword_id,name) values (330,'MAX_CONNECTIONS_PER_HOUR'); -insert into help_keyword (help_keyword_id,name) values (331,'LIKE'); -insert into help_keyword (help_keyword_id,name) values (332,'PLUGIN'); -insert into help_keyword (help_keyword_id,name) values (333,'FETCH'); -insert into help_keyword (help_keyword_id,name) values (334,'IN'); -insert into help_keyword (help_keyword_id,name) values (335,'COLUMN'); -insert into help_keyword (help_keyword_id,name) values (336,'DUMPFILE'); -insert into help_keyword (help_keyword_id,name) values (337,'USAGE'); -insert into help_keyword (help_keyword_id,name) values (338,'EXECUTE'); -insert into help_keyword (help_keyword_id,name) values (339,'MEMORY'); -insert into help_keyword (help_keyword_id,name) values (340,'CEIL'); -insert into help_keyword (help_keyword_id,name) values (341,'QUERY'); -insert into help_keyword (help_keyword_id,name) values (342,'MASTER_HOST'); -insert into help_keyword (help_keyword_id,name) values (343,'LINES'); -insert into help_keyword (help_keyword_id,name) values (344,'SQL_THREAD'); -insert into help_keyword (help_keyword_id,name) values (345,'SERVER'); -insert into help_keyword (help_keyword_id,name) values (346,'MAX_QUERIES_PER_HOUR'); -insert into help_keyword (help_keyword_id,name) values (347,'MASTER_SSL_CERT'); -insert into help_keyword (help_keyword_id,name) values (348,'MULTIPOLYGONFROMWKB'); -insert into help_keyword (help_keyword_id,name) values (349,'TRANSACTION'); -insert into help_keyword (help_keyword_id,name) values (350,'DAY_MINUTE'); -insert into help_keyword (help_keyword_id,name) values (351,'STDDEV'); -insert into help_keyword (help_keyword_id,name) values (352,'DATE_SUB'); -insert into help_keyword (help_keyword_id,name) values (353,'REBUILD'); -insert into help_keyword (help_keyword_id,name) values (354,'GEOMETRYFROMWKB'); -insert into help_keyword (help_keyword_id,name) values (355,'INT1'); -insert into help_keyword (help_keyword_id,name) values (356,'RENAME'); -insert into help_keyword (help_keyword_id,name) values (357,'PARSER'); -insert into help_keyword (help_keyword_id,name) values (358,'RIGHT'); -insert into help_keyword (help_keyword_id,name) values (359,'ALTER'); -insert into help_keyword (help_keyword_id,name) values (360,'MAX_ROWS'); -insert into help_keyword (help_keyword_id,name) values (361,'SOCKET'); -insert into help_keyword (help_keyword_id,name) values (362,'STRAIGHT_JOIN'); -insert into help_keyword (help_keyword_id,name) values (363,'NATURAL'); -insert into help_keyword (help_keyword_id,name) values (364,'VARIABLES'); -insert into help_keyword (help_keyword_id,name) values (365,'ESCAPED'); -insert into help_keyword (help_keyword_id,name) values (366,'SHA1'); -insert into help_keyword (help_keyword_id,name) values (367,'KEY_BLOCK_SIZE'); -insert into help_keyword (help_keyword_id,name) values (368,'PASSWORD'); -insert into help_keyword (help_keyword_id,name) values (369,'OFFSET'); -insert into help_keyword (help_keyword_id,name) values (370,'CHAR'); -insert into help_keyword (help_keyword_id,name) values (371,'NEXT'); -insert into help_keyword (help_keyword_id,name) values (372,'ERRORS'); -insert into help_keyword (help_keyword_id,name) values (373,'SQL_LOG_BIN'); -insert into help_keyword (help_keyword_id,name) values (374,'TEMPORARY'); -insert into help_keyword (help_keyword_id,name) values (375,'COMMITTED'); -insert into help_keyword (help_keyword_id,name) values (376,'SQL_SMALL_RESULT'); -insert into help_keyword (help_keyword_id,name) values (377,'UPGRADE'); -insert into help_keyword (help_keyword_id,name) values (378,'BEGIN'); -insert into help_keyword (help_keyword_id,name) values (379,'DELAY_KEY_WRITE'); -insert into help_keyword (help_keyword_id,name) values (380,'PROFILE'); -insert into help_keyword (help_keyword_id,name) values (381,'MEDIUM'); -insert into help_keyword (help_keyword_id,name) values (382,'INTERVAL'); -insert into help_keyword (help_keyword_id,name) values (383,'SSL'); -insert into help_keyword (help_keyword_id,name) values (384,'DAY_HOUR'); -insert into help_keyword (help_keyword_id,name) values (385,'NAME'); -insert into help_keyword (help_keyword_id,name) values (386,'REFERENCES'); -insert into help_keyword (help_keyword_id,name) values (387,'AES_ENCRYPT'); -insert into help_keyword (help_keyword_id,name) values (388,'STORAGE'); -insert into help_keyword (help_keyword_id,name) values (389,'ISOLATION'); -insert into help_keyword (help_keyword_id,name) values (390,'CEILING'); -insert into help_keyword (help_keyword_id,name) values (391,'EVERY'); -insert into help_keyword (help_keyword_id,name) values (392,'INT8'); -insert into help_keyword (help_keyword_id,name) values (393,'AUTHORS'); -insert into help_keyword (help_keyword_id,name) values (394,'RESTRICT'); -insert into help_keyword (help_keyword_id,name) values (395,'UNCOMMITTED'); -insert into help_keyword (help_keyword_id,name) values (396,'LINESTRINGFROMTEXT'); -insert into help_keyword (help_keyword_id,name) values (397,'IS'); -insert into help_keyword (help_keyword_id,name) values (398,'NOT'); -insert into help_keyword (help_keyword_id,name) values (399,'ANALYSE'); -insert into help_keyword (help_keyword_id,name) values (400,'DATAFILE'); -insert into help_keyword (help_keyword_id,name) values (401,'DES_KEY_FILE'); -insert into help_keyword (help_keyword_id,name) values (402,'SIGNAL'); -insert into help_keyword (help_keyword_id,name) values (403,'COMPRESSED'); -insert into help_keyword (help_keyword_id,name) values (404,'START'); -insert into help_keyword (help_keyword_id,name) values (405,'PLUGINS'); -insert into help_keyword (help_keyword_id,name) values (406,'SAVEPOINT'); -insert into help_keyword (help_keyword_id,name) values (407,'IF'); -insert into help_keyword (help_keyword_id,name) values (408,'ROWS'); -insert into help_keyword (help_keyword_id,name) values (409,'PRIMARY'); -insert into help_keyword (help_keyword_id,name) values (410,'PURGE'); -insert into help_keyword (help_keyword_id,name) values (411,'LAST'); -insert into help_keyword (help_keyword_id,name) values (412,'USER'); -insert into help_keyword (help_keyword_id,name) values (413,'EXIT'); -insert into help_keyword (help_keyword_id,name) values (414,'KEYS'); -insert into help_keyword (help_keyword_id,name) values (415,'LIMIT'); -insert into help_keyword (help_keyword_id,name) values (416,'KEY'); -insert into help_keyword (help_keyword_id,name) values (417,'MERGE'); -insert into help_keyword (help_keyword_id,name) values (418,'UNTIL'); -insert into help_keyword (help_keyword_id,name) values (419,'SQL_NO_CACHE'); -insert into help_keyword (help_keyword_id,name) values (420,'DELAYED'); -insert into help_keyword (help_keyword_id,name) values (421,'CONSTRAINT_SCHEMA'); -insert into help_keyword (help_keyword_id,name) values (422,'ANALYZE'); -insert into help_keyword (help_keyword_id,name) values (423,'CONSTRAINT'); -insert into help_keyword (help_keyword_id,name) values (424,'SERIAL'); -insert into help_keyword (help_keyword_id,name) values (425,'ACTION'); -insert into help_keyword (help_keyword_id,name) values (426,'WRITE'); -insert into help_keyword (help_keyword_id,name) values (427,'INITIAL_SIZE'); -insert into help_keyword (help_keyword_id,name) values (428,'SESSION'); -insert into help_keyword (help_keyword_id,name) values (429,'DATABASE'); -insert into help_keyword (help_keyword_id,name) values (430,'NULL'); -insert into help_keyword (help_keyword_id,name) values (431,'POWER'); -insert into help_keyword (help_keyword_id,name) values (432,'USE_FRM'); -insert into help_keyword (help_keyword_id,name) values (433,'TERMINATED'); -insert into help_keyword (help_keyword_id,name) values (434,'SLAVE'); -insert into help_keyword (help_keyword_id,name) values (435,'NVARCHAR'); -insert into help_keyword (help_keyword_id,name) values (436,'ASC'); -insert into help_keyword (help_keyword_id,name) values (437,'RETURN'); -insert into help_keyword (help_keyword_id,name) values (438,'OPTIONALLY'); -insert into help_keyword (help_keyword_id,name) values (439,'ENABLE'); -insert into help_keyword (help_keyword_id,name) values (440,'DIRECTORY'); -insert into help_keyword (help_keyword_id,name) values (441,'MAX_USER_CONNECTIONS'); -insert into help_keyword (help_keyword_id,name) values (442,'WHILE'); -insert into help_keyword (help_keyword_id,name) values (443,'LOCAL'); -insert into help_keyword (help_keyword_id,name) values (444,'DISTINCT'); -insert into help_keyword (help_keyword_id,name) values (445,'AES_DECRYPT'); -insert into help_keyword (help_keyword_id,name) values (446,'MASTER_SSL_KEY'); -insert into help_keyword (help_keyword_id,name) values (447,'NONE'); -insert into help_keyword (help_keyword_id,name) values (448,'TABLES'); -insert into help_keyword (help_keyword_id,name) values (449,'<>'); -insert into help_keyword (help_keyword_id,name) values (450,'RLIKE'); -insert into help_keyword (help_keyword_id,name) values (451,'TRIGGER'); -insert into help_keyword (help_keyword_id,name) values (452,'COLLATION'); -insert into help_keyword (help_keyword_id,name) values (453,'SHUTDOWN'); -insert into help_keyword (help_keyword_id,name) values (454,'HIGH_PRIORITY'); -insert into help_keyword (help_keyword_id,name) values (455,'BTREE'); -insert into help_keyword (help_keyword_id,name) values (456,'FIRST'); -insert into help_keyword (help_keyword_id,name) values (457,'COALESCE'); -insert into help_keyword (help_keyword_id,name) values (458,'WAIT'); -insert into help_keyword (help_keyword_id,name) values (459,'CATALOG_NAME'); -insert into help_keyword (help_keyword_id,name) values (460,'MASTER'); -insert into help_keyword (help_keyword_id,name) values (461,'FIXED'); -insert into help_keyword (help_keyword_id,name) values (462,'MULTIPOLYGONFROMTEXT'); -insert into help_keyword (help_keyword_id,name) values (463,'ROW_FORMAT'); - -insert into help_relation (help_topic_id,help_keyword_id) values (1,0); -insert into help_relation (help_topic_id,help_keyword_id) values (356,0); -insert into help_relation (help_topic_id,help_keyword_id) values (473,1); -insert into help_relation (help_topic_id,help_keyword_id) values (232,2); -insert into help_relation (help_topic_id,help_keyword_id) values (447,3); -insert into help_relation (help_topic_id,help_keyword_id) values (3,4); -insert into help_relation (help_topic_id,help_keyword_id) values (130,4); -insert into help_relation (help_topic_id,help_keyword_id) values (421,4); -insert into help_relation (help_topic_id,help_keyword_id) values (89,5); -insert into help_relation (help_topic_id,help_keyword_id) values (406,6); -insert into help_relation (help_topic_id,help_keyword_id) values (89,6); -insert into help_relation (help_topic_id,help_keyword_id) values (97,7); -insert into help_relation (help_topic_id,help_keyword_id) values (89,8); -insert into help_relation (help_topic_id,help_keyword_id) values (185,9); -insert into help_relation (help_topic_id,help_keyword_id) values (430,10); -insert into help_relation (help_topic_id,help_keyword_id) values (347,11); -insert into help_relation (help_topic_id,help_keyword_id) values (21,11); -insert into help_relation (help_topic_id,help_keyword_id) values (468,11); -insert into help_relation (help_topic_id,help_keyword_id) values (421,11); -insert into help_relation (help_topic_id,help_keyword_id) values (463,11); -insert into help_relation (help_topic_id,help_keyword_id) values (406,12); -insert into help_relation (help_topic_id,help_keyword_id) values (89,12); -insert into help_relation (help_topic_id,help_keyword_id) values (146,13); -insert into help_relation (help_topic_id,help_keyword_id) values (230,14); -insert into help_relation (help_topic_id,help_keyword_id) values (88,15); -insert into help_relation (help_topic_id,help_keyword_id) values (356,15); -insert into help_relation (help_topic_id,help_keyword_id) values (18,16); -insert into help_relation (help_topic_id,help_keyword_id) values (134,16); -insert into help_relation (help_topic_id,help_keyword_id) values (347,16); -insert into help_relation (help_topic_id,help_keyword_id) values (106,16); -insert into help_relation (help_topic_id,help_keyword_id) values (500,17); -insert into help_relation (help_topic_id,help_keyword_id) values (97,17); -insert into help_relation (help_topic_id,help_keyword_id) values (380,18); -insert into help_relation (help_topic_id,help_keyword_id) values (459,19); -insert into help_relation (help_topic_id,help_keyword_id) values (3,19); -insert into help_relation (help_topic_id,help_keyword_id) values (374,19); -insert into help_relation (help_topic_id,help_keyword_id) values (104,19); -insert into help_relation (help_topic_id,help_keyword_id) values (243,19); -insert into help_relation (help_topic_id,help_keyword_id) values (185,20); -insert into help_relation (help_topic_id,help_keyword_id) values (356,21); -insert into help_relation (help_topic_id,help_keyword_id) values (478,22); -insert into help_relation (help_topic_id,help_keyword_id) values (34,22); -insert into help_relation (help_topic_id,help_keyword_id) values (237,22); -insert into help_relation (help_topic_id,help_keyword_id) values (300,22); -insert into help_relation (help_topic_id,help_keyword_id) values (9,22); -insert into help_relation (help_topic_id,help_keyword_id) values (415,22); -insert into help_relation (help_topic_id,help_keyword_id) values (276,22); -insert into help_relation (help_topic_id,help_keyword_id) values (416,22); -insert into help_relation (help_topic_id,help_keyword_id) values (30,22); -insert into help_relation (help_topic_id,help_keyword_id) values (87,22); -insert into help_relation (help_topic_id,help_keyword_id) values (263,22); -insert into help_relation (help_topic_id,help_keyword_id) values (186,22); -insert into help_relation (help_topic_id,help_keyword_id) values (405,22); -insert into help_relation (help_topic_id,help_keyword_id) values (331,22); -insert into help_relation (help_topic_id,help_keyword_id) values (463,22); -insert into help_relation (help_topic_id,help_keyword_id) values (108,23); -insert into help_relation (help_topic_id,help_keyword_id) values (424,24); -insert into help_relation (help_topic_id,help_keyword_id) values (122,24); -insert into help_relation (help_topic_id,help_keyword_id) values (170,24); -insert into help_relation (help_topic_id,help_keyword_id) values (376,25); -insert into help_relation (help_topic_id,help_keyword_id) values (82,26); -insert into help_relation (help_topic_id,help_keyword_id) values (104,27); -insert into help_relation (help_topic_id,help_keyword_id) values (199,28); -insert into help_relation (help_topic_id,help_keyword_id) values (36,29); -insert into help_relation (help_topic_id,help_keyword_id) values (347,30); -insert into help_relation (help_topic_id,help_keyword_id) values (468,30); -insert into help_relation (help_topic_id,help_keyword_id) values (376,31); -insert into help_relation (help_topic_id,help_keyword_id) values (199,32); -insert into help_relation (help_topic_id,help_keyword_id) values (35,33); -insert into help_relation (help_topic_id,help_keyword_id) values (237,33); -insert into help_relation (help_topic_id,help_keyword_id) values (36,34); -insert into help_relation (help_topic_id,help_keyword_id) values (356,34); -insert into help_relation (help_topic_id,help_keyword_id) values (468,35); -insert into help_relation (help_topic_id,help_keyword_id) values (417,36); -insert into help_relation (help_topic_id,help_keyword_id) values (468,36); -insert into help_relation (help_topic_id,help_keyword_id) values (463,36); -insert into help_relation (help_topic_id,help_keyword_id) values (347,37); -insert into help_relation (help_topic_id,help_keyword_id) values (21,37); -insert into help_relation (help_topic_id,help_keyword_id) values (294,37); -insert into help_relation (help_topic_id,help_keyword_id) values (468,37); -insert into help_relation (help_topic_id,help_keyword_id) values (451,37); -insert into help_relation (help_topic_id,help_keyword_id) values (500,38); -insert into help_relation (help_topic_id,help_keyword_id) values (130,39); -insert into help_relation (help_topic_id,help_keyword_id) values (48,39); -insert into help_relation (help_topic_id,help_keyword_id) values (468,39); -insert into help_relation (help_topic_id,help_keyword_id) values (83,39); -insert into help_relation (help_topic_id,help_keyword_id) values (199,39); -insert into help_relation (help_topic_id,help_keyword_id) values (356,39); -insert into help_relation (help_topic_id,help_keyword_id) values (421,39); -insert into help_relation (help_topic_id,help_keyword_id) values (77,39); -insert into help_relation (help_topic_id,help_keyword_id) values (361,39); -insert into help_relation (help_topic_id,help_keyword_id) values (463,39); -insert into help_relation (help_topic_id,help_keyword_id) values (472,40); -insert into help_relation (help_topic_id,help_keyword_id) values (468,40); -insert into help_relation (help_topic_id,help_keyword_id) values (376,41); -insert into help_relation (help_topic_id,help_keyword_id) values (468,42); -insert into help_relation (help_topic_id,help_keyword_id) values (463,42); -insert into help_relation (help_topic_id,help_keyword_id) values (473,43); -insert into help_relation (help_topic_id,help_keyword_id) values (468,43); -insert into help_relation (help_topic_id,help_keyword_id) values (212,43); -insert into help_relation (help_topic_id,help_keyword_id) values (421,43); -insert into help_relation (help_topic_id,help_keyword_id) values (376,44); -insert into help_relation (help_topic_id,help_keyword_id) values (356,45); -insert into help_relation (help_topic_id,help_keyword_id) values (314,46); -insert into help_relation (help_topic_id,help_keyword_id) values (97,46); -insert into help_relation (help_topic_id,help_keyword_id) values (361,47); -insert into help_relation (help_topic_id,help_keyword_id) values (459,48); -insert into help_relation (help_topic_id,help_keyword_id) values (374,48); -insert into help_relation (help_topic_id,help_keyword_id) values (185,49); -insert into help_relation (help_topic_id,help_keyword_id) values (472,50); -insert into help_relation (help_topic_id,help_keyword_id) values (48,50); -insert into help_relation (help_topic_id,help_keyword_id) values (468,50); -insert into help_relation (help_topic_id,help_keyword_id) values (406,51); -insert into help_relation (help_topic_id,help_keyword_id) values (472,51); -insert into help_relation (help_topic_id,help_keyword_id) values (1,51); -insert into help_relation (help_topic_id,help_keyword_id) values (89,51); -insert into help_relation (help_topic_id,help_keyword_id) values (459,52); -insert into help_relation (help_topic_id,help_keyword_id) values (374,52); -insert into help_relation (help_topic_id,help_keyword_id) values (176,53); -insert into help_relation (help_topic_id,help_keyword_id) values (468,53); -insert into help_relation (help_topic_id,help_keyword_id) values (51,54); -insert into help_relation (help_topic_id,help_keyword_id) values (106,54); -insert into help_relation (help_topic_id,help_keyword_id) values (199,55); -insert into help_relation (help_topic_id,help_keyword_id) values (194,56); -insert into help_relation (help_topic_id,help_keyword_id) values (55,56); -insert into help_relation (help_topic_id,help_keyword_id) values (1,56); -insert into help_relation (help_topic_id,help_keyword_id) values (459,57); -insert into help_relation (help_topic_id,help_keyword_id) values (374,57); -insert into help_relation (help_topic_id,help_keyword_id) values (48,58); -insert into help_relation (help_topic_id,help_keyword_id) values (83,58); -insert into help_relation (help_topic_id,help_keyword_id) values (106,58); -insert into help_relation (help_topic_id,help_keyword_id) values (193,59); -insert into help_relation (help_topic_id,help_keyword_id) values (249,59); -insert into help_relation (help_topic_id,help_keyword_id) values (199,59); -insert into help_relation (help_topic_id,help_keyword_id) values (210,60); -insert into help_relation (help_topic_id,help_keyword_id) values (463,60); -insert into help_relation (help_topic_id,help_keyword_id) values (406,61); -insert into help_relation (help_topic_id,help_keyword_id) values (89,61); -insert into help_relation (help_topic_id,help_keyword_id) values (300,61); -insert into help_relation (help_topic_id,help_keyword_id) values (358,61); -insert into help_relation (help_topic_id,help_keyword_id) values (199,62); -insert into help_relation (help_topic_id,help_keyword_id) values (356,63); -insert into help_relation (help_topic_id,help_keyword_id) values (1,64); -insert into help_relation (help_topic_id,help_keyword_id) values (130,64); -insert into help_relation (help_topic_id,help_keyword_id) values (356,64); -insert into help_relation (help_topic_id,help_keyword_id) values (104,64); -insert into help_relation (help_topic_id,help_keyword_id) values (83,64); -insert into help_relation (help_topic_id,help_keyword_id) values (421,64); -insert into help_relation (help_topic_id,help_keyword_id) values (463,64); -insert into help_relation (help_topic_id,help_keyword_id) values (66,65); -insert into help_relation (help_topic_id,help_keyword_id) values (466,66); -insert into help_relation (help_topic_id,help_keyword_id) values (417,66); -insert into help_relation (help_topic_id,help_keyword_id) values (48,66); -insert into help_relation (help_topic_id,help_keyword_id) values (230,67); -insert into help_relation (help_topic_id,help_keyword_id) values (87,68); -insert into help_relation (help_topic_id,help_keyword_id) values (210,68); -insert into help_relation (help_topic_id,help_keyword_id) values (463,68); -insert into help_relation (help_topic_id,help_keyword_id) values (199,69); -insert into help_relation (help_topic_id,help_keyword_id) values (194,70); -insert into help_relation (help_topic_id,help_keyword_id) values (468,71); -insert into help_relation (help_topic_id,help_keyword_id) values (91,72); -insert into help_relation (help_topic_id,help_keyword_id) values (482,72); -insert into help_relation (help_topic_id,help_keyword_id) values (385,73); -insert into help_relation (help_topic_id,help_keyword_id) values (447,74); -insert into help_relation (help_topic_id,help_keyword_id) values (1,75); -insert into help_relation (help_topic_id,help_keyword_id) values (39,76); -insert into help_relation (help_topic_id,help_keyword_id) values (269,76); -insert into help_relation (help_topic_id,help_keyword_id) values (230,76); -insert into help_relation (help_topic_id,help_keyword_id) values (269,77); -insert into help_relation (help_topic_id,help_keyword_id) values (460,77); -insert into help_relation (help_topic_id,help_keyword_id) values (185,77); -insert into help_relation (help_topic_id,help_keyword_id) values (185,78); -insert into help_relation (help_topic_id,help_keyword_id) values (463,78); -insert into help_relation (help_topic_id,help_keyword_id) values (406,79); -insert into help_relation (help_topic_id,help_keyword_id) values (89,79); -insert into help_relation (help_topic_id,help_keyword_id) values (376,80); -insert into help_relation (help_topic_id,help_keyword_id) values (472,81); -insert into help_relation (help_topic_id,help_keyword_id) values (356,81); -insert into help_relation (help_topic_id,help_keyword_id) values (104,81); -insert into help_relation (help_topic_id,help_keyword_id) values (83,81); -insert into help_relation (help_topic_id,help_keyword_id) values (406,82); -insert into help_relation (help_topic_id,help_keyword_id) values (89,82); -insert into help_relation (help_topic_id,help_keyword_id) values (459,83); -insert into help_relation (help_topic_id,help_keyword_id) values (374,83); -insert into help_relation (help_topic_id,help_keyword_id) values (304,84); -insert into help_relation (help_topic_id,help_keyword_id) values (3,84); -insert into help_relation (help_topic_id,help_keyword_id) values (356,84); -insert into help_relation (help_topic_id,help_keyword_id) values (104,84); -insert into help_relation (help_topic_id,help_keyword_id) values (468,85); -insert into help_relation (help_topic_id,help_keyword_id) values (257,86); -insert into help_relation (help_topic_id,help_keyword_id) values (194,87); -insert into help_relation (help_topic_id,help_keyword_id) values (376,88); -insert into help_relation (help_topic_id,help_keyword_id) values (129,89); -insert into help_relation (help_topic_id,help_keyword_id) values (146,90); -insert into help_relation (help_topic_id,help_keyword_id) values (460,90); -insert into help_relation (help_topic_id,help_keyword_id) values (17,91); -insert into help_relation (help_topic_id,help_keyword_id) values (416,91); -insert into help_relation (help_topic_id,help_keyword_id) values (347,91); -insert into help_relation (help_topic_id,help_keyword_id) values (439,91); -insert into help_relation (help_topic_id,help_keyword_id) values (328,91); -insert into help_relation (help_topic_id,help_keyword_id) values (356,91); -insert into help_relation (help_topic_id,help_keyword_id) values (189,91); -insert into help_relation (help_topic_id,help_keyword_id) values (302,91); -insert into help_relation (help_topic_id,help_keyword_id) values (488,91); -insert into help_relation (help_topic_id,help_keyword_id) values (188,92); -insert into help_relation (help_topic_id,help_keyword_id) values (99,92); -insert into help_relation (help_topic_id,help_keyword_id) values (421,93); -insert into help_relation (help_topic_id,help_keyword_id) values (463,93); -insert into help_relation (help_topic_id,help_keyword_id) values (88,94); -insert into help_relation (help_topic_id,help_keyword_id) values (401,95); -insert into help_relation (help_topic_id,help_keyword_id) values (468,95); -insert into help_relation (help_topic_id,help_keyword_id) values (69,96); -insert into help_relation (help_topic_id,help_keyword_id) values (433,96); -insert into help_relation (help_topic_id,help_keyword_id) values (330,96); -insert into help_relation (help_topic_id,help_keyword_id) values (285,97); -insert into help_relation (help_topic_id,help_keyword_id) values (85,98); -insert into help_relation (help_topic_id,help_keyword_id) values (57,98); -insert into help_relation (help_topic_id,help_keyword_id) values (28,98); -insert into help_relation (help_topic_id,help_keyword_id) values (195,99); -insert into help_relation (help_topic_id,help_keyword_id) values (104,99); -insert into help_relation (help_topic_id,help_keyword_id) values (486,99); -insert into help_relation (help_topic_id,help_keyword_id) values (301,99); -insert into help_relation (help_topic_id,help_keyword_id) values (347,100); -insert into help_relation (help_topic_id,help_keyword_id) values (282,100); -insert into help_relation (help_topic_id,help_keyword_id) values (313,101); -insert into help_relation (help_topic_id,help_keyword_id) values (106,101); -insert into help_relation (help_topic_id,help_keyword_id) values (473,102); -insert into help_relation (help_topic_id,help_keyword_id) values (376,103); -insert into help_relation (help_topic_id,help_keyword_id) values (155,104); -insert into help_relation (help_topic_id,help_keyword_id) values (30,104); -insert into help_relation (help_topic_id,help_keyword_id) values (89,104); -insert into help_relation (help_topic_id,help_keyword_id) values (300,104); -insert into help_relation (help_topic_id,help_keyword_id) values (186,104); -insert into help_relation (help_topic_id,help_keyword_id) values (9,104); -insert into help_relation (help_topic_id,help_keyword_id) values (276,104); -insert into help_relation (help_topic_id,help_keyword_id) values (347,105); -insert into help_relation (help_topic_id,help_keyword_id) values (365,105); -insert into help_relation (help_topic_id,help_keyword_id) values (109,106); -insert into help_relation (help_topic_id,help_keyword_id) values (146,107); -insert into help_relation (help_topic_id,help_keyword_id) values (460,107); -insert into help_relation (help_topic_id,help_keyword_id) values (88,108); -insert into help_relation (help_topic_id,help_keyword_id) values (24,108); -insert into help_relation (help_topic_id,help_keyword_id) values (113,109); -insert into help_relation (help_topic_id,help_keyword_id) values (174,109); -insert into help_relation (help_topic_id,help_keyword_id) values (3,110); -insert into help_relation (help_topic_id,help_keyword_id) values (155,110); -insert into help_relation (help_topic_id,help_keyword_id) values (468,110); -insert into help_relation (help_topic_id,help_keyword_id) values (200,110); -insert into help_relation (help_topic_id,help_keyword_id) values (212,110); -insert into help_relation (help_topic_id,help_keyword_id) values (104,110); -insert into help_relation (help_topic_id,help_keyword_id) values (243,110); -insert into help_relation (help_topic_id,help_keyword_id) values (463,110); -insert into help_relation (help_topic_id,help_keyword_id) values (463,111); -insert into help_relation (help_topic_id,help_keyword_id) values (466,112); -insert into help_relation (help_topic_id,help_keyword_id) values (326,112); -insert into help_relation (help_topic_id,help_keyword_id) values (115,112); -insert into help_relation (help_topic_id,help_keyword_id) values (470,112); -insert into help_relation (help_topic_id,help_keyword_id) values (115,113); -insert into help_relation (help_topic_id,help_keyword_id) values (463,113); -insert into help_relation (help_topic_id,help_keyword_id) values (459,114); -insert into help_relation (help_topic_id,help_keyword_id) values (374,114); -insert into help_relation (help_topic_id,help_keyword_id) values (38,115); -insert into help_relation (help_topic_id,help_keyword_id) values (119,115); -insert into help_relation (help_topic_id,help_keyword_id) values (264,115); -insert into help_relation (help_topic_id,help_keyword_id) values (151,115); -insert into help_relation (help_topic_id,help_keyword_id) values (459,116); -insert into help_relation (help_topic_id,help_keyword_id) values (374,116); -insert into help_relation (help_topic_id,help_keyword_id) values (419,117); -insert into help_relation (help_topic_id,help_keyword_id) values (124,118); -insert into help_relation (help_topic_id,help_keyword_id) values (406,119); -insert into help_relation (help_topic_id,help_keyword_id) values (89,119); -insert into help_relation (help_topic_id,help_keyword_id) values (125,119); -insert into help_relation (help_topic_id,help_keyword_id) values (496,119); -insert into help_relation (help_topic_id,help_keyword_id) values (221,120); -insert into help_relation (help_topic_id,help_keyword_id) values (333,121); -insert into help_relation (help_topic_id,help_keyword_id) values (129,121); -insert into help_relation (help_topic_id,help_keyword_id) values (3,121); -insert into help_relation (help_topic_id,help_keyword_id) values (155,121); -insert into help_relation (help_topic_id,help_keyword_id) values (130,121); -insert into help_relation (help_topic_id,help_keyword_id) values (459,121); -insert into help_relation (help_topic_id,help_keyword_id) values (374,121); -insert into help_relation (help_topic_id,help_keyword_id) values (494,121); -insert into help_relation (help_topic_id,help_keyword_id) values (212,121); -insert into help_relation (help_topic_id,help_keyword_id) values (104,121); -insert into help_relation (help_topic_id,help_keyword_id) values (463,121); -insert into help_relation (help_topic_id,help_keyword_id) values (347,121); -insert into help_relation (help_topic_id,help_keyword_id) values (468,121); -insert into help_relation (help_topic_id,help_keyword_id) values (83,121); -insert into help_relation (help_topic_id,help_keyword_id) values (146,121); -insert into help_relation (help_topic_id,help_keyword_id) values (472,121); -insert into help_relation (help_topic_id,help_keyword_id) values (182,121); -insert into help_relation (help_topic_id,help_keyword_id) values (356,121); -insert into help_relation (help_topic_id,help_keyword_id) values (421,121); -insert into help_relation (help_topic_id,help_keyword_id) values (477,121); -insert into help_relation (help_topic_id,help_keyword_id) values (199,122); -insert into help_relation (help_topic_id,help_keyword_id) values (262,123); -insert into help_relation (help_topic_id,help_keyword_id) values (132,123); -insert into help_relation (help_topic_id,help_keyword_id) values (230,123); -insert into help_relation (help_topic_id,help_keyword_id) values (376,123); -insert into help_relation (help_topic_id,help_keyword_id) values (347,124); -insert into help_relation (help_topic_id,help_keyword_id) values (336,124); -insert into help_relation (help_topic_id,help_keyword_id) values (365,124); -insert into help_relation (help_topic_id,help_keyword_id) values (223,124); -insert into help_relation (help_topic_id,help_keyword_id) values (58,124); -insert into help_relation (help_topic_id,help_keyword_id) values (328,124); -insert into help_relation (help_topic_id,help_keyword_id) values (137,124); -insert into help_relation (help_topic_id,help_keyword_id) values (215,124); -insert into help_relation (help_topic_id,help_keyword_id) values (468,125); -insert into help_relation (help_topic_id,help_keyword_id) values (210,125); -insert into help_relation (help_topic_id,help_keyword_id) values (463,125); -insert into help_relation (help_topic_id,help_keyword_id) values (194,126); -insert into help_relation (help_topic_id,help_keyword_id) values (406,126); -insert into help_relation (help_topic_id,help_keyword_id) values (89,126); -insert into help_relation (help_topic_id,help_keyword_id) values (468,126); -insert into help_relation (help_topic_id,help_keyword_id) values (210,126); -insert into help_relation (help_topic_id,help_keyword_id) values (185,127); -insert into help_relation (help_topic_id,help_keyword_id) values (1,128); -insert into help_relation (help_topic_id,help_keyword_id) values (424,129); -insert into help_relation (help_topic_id,help_keyword_id) values (52,130); -insert into help_relation (help_topic_id,help_keyword_id) values (185,131); -insert into help_relation (help_topic_id,help_keyword_id) values (468,132); -insert into help_relation (help_topic_id,help_keyword_id) values (314,133); -insert into help_relation (help_topic_id,help_keyword_id) values (199,134); -insert into help_relation (help_topic_id,help_keyword_id) values (455,135); -insert into help_relation (help_topic_id,help_keyword_id) values (255,136); -insert into help_relation (help_topic_id,help_keyword_id) values (285,137); -insert into help_relation (help_topic_id,help_keyword_id) values (249,138); -insert into help_relation (help_topic_id,help_keyword_id) values (199,138); -insert into help_relation (help_topic_id,help_keyword_id) values (463,139); -insert into help_relation (help_topic_id,help_keyword_id) values (85,140); -insert into help_relation (help_topic_id,help_keyword_id) values (57,140); -insert into help_relation (help_topic_id,help_keyword_id) values (237,141); -insert into help_relation (help_topic_id,help_keyword_id) values (52,142); -insert into help_relation (help_topic_id,help_keyword_id) values (324,142); -insert into help_relation (help_topic_id,help_keyword_id) values (85,143); -insert into help_relation (help_topic_id,help_keyword_id) values (57,143); -insert into help_relation (help_topic_id,help_keyword_id) values (199,144); -insert into help_relation (help_topic_id,help_keyword_id) values (313,145); -insert into help_relation (help_topic_id,help_keyword_id) values (424,146); -insert into help_relation (help_topic_id,help_keyword_id) values (347,146); -insert into help_relation (help_topic_id,help_keyword_id) values (455,146); -insert into help_relation (help_topic_id,help_keyword_id) values (48,146); -insert into help_relation (help_topic_id,help_keyword_id) values (122,146); -insert into help_relation (help_topic_id,help_keyword_id) values (356,146); -insert into help_relation (help_topic_id,help_keyword_id) values (447,147); -insert into help_relation (help_topic_id,help_keyword_id) values (36,147); -insert into help_relation (help_topic_id,help_keyword_id) values (106,147); -insert into help_relation (help_topic_id,help_keyword_id) values (1,148); -insert into help_relation (help_topic_id,help_keyword_id) values (28,149); -insert into help_relation (help_topic_id,help_keyword_id) values (376,150); -insert into help_relation (help_topic_id,help_keyword_id) values (468,151); -insert into help_relation (help_topic_id,help_keyword_id) values (209,152); -insert into help_relation (help_topic_id,help_keyword_id) values (347,153); -insert into help_relation (help_topic_id,help_keyword_id) values (313,153); -insert into help_relation (help_topic_id,help_keyword_id) values (180,153); -insert into help_relation (help_topic_id,help_keyword_id) values (356,153); -insert into help_relation (help_topic_id,help_keyword_id) values (420,153); -insert into help_relation (help_topic_id,help_keyword_id) values (347,154); -insert into help_relation (help_topic_id,help_keyword_id) values (330,154); -insert into help_relation (help_topic_id,help_keyword_id) values (468,155); -insert into help_relation (help_topic_id,help_keyword_id) values (97,156); -insert into help_relation (help_topic_id,help_keyword_id) values (180,157); -insert into help_relation (help_topic_id,help_keyword_id) values (421,158); -insert into help_relation (help_topic_id,help_keyword_id) values (68,159); -insert into help_relation (help_topic_id,help_keyword_id) values (347,159); -insert into help_relation (help_topic_id,help_keyword_id) values (336,159); -insert into help_relation (help_topic_id,help_keyword_id) values (34,159); -insert into help_relation (help_topic_id,help_keyword_id) values (97,159); -insert into help_relation (help_topic_id,help_keyword_id) values (302,159); -insert into help_relation (help_topic_id,help_keyword_id) values (416,159); -insert into help_relation (help_topic_id,help_keyword_id) values (393,159); -insert into help_relation (help_topic_id,help_keyword_id) values (211,159); -insert into help_relation (help_topic_id,help_keyword_id) values (405,159); -insert into help_relation (help_topic_id,help_keyword_id) values (233,159); -insert into help_relation (help_topic_id,help_keyword_id) values (97,160); -insert into help_relation (help_topic_id,help_keyword_id) values (347,161); -insert into help_relation (help_topic_id,help_keyword_id) values (421,161); -insert into help_relation (help_topic_id,help_keyword_id) values (252,162); -insert into help_relation (help_topic_id,help_keyword_id) values (468,163); -insert into help_relation (help_topic_id,help_keyword_id) values (468,164); -insert into help_relation (help_topic_id,help_keyword_id) values (463,164); -insert into help_relation (help_topic_id,help_keyword_id) values (194,165); -insert into help_relation (help_topic_id,help_keyword_id) values (478,165); -insert into help_relation (help_topic_id,help_keyword_id) values (60,165); -insert into help_relation (help_topic_id,help_keyword_id) values (463,165); -insert into help_relation (help_topic_id,help_keyword_id) values (176,166); -insert into help_relation (help_topic_id,help_keyword_id) values (168,167); -insert into help_relation (help_topic_id,help_keyword_id) values (194,168); -insert into help_relation (help_topic_id,help_keyword_id) values (478,168); -insert into help_relation (help_topic_id,help_keyword_id) values (415,168); -insert into help_relation (help_topic_id,help_keyword_id) values (463,168); -insert into help_relation (help_topic_id,help_keyword_id) values (454,169); -insert into help_relation (help_topic_id,help_keyword_id) values (30,169); -insert into help_relation (help_topic_id,help_keyword_id) values (159,169); -insert into help_relation (help_topic_id,help_keyword_id) values (447,170); -insert into help_relation (help_topic_id,help_keyword_id) values (130,171); -insert into help_relation (help_topic_id,help_keyword_id) values (421,171); -insert into help_relation (help_topic_id,help_keyword_id) values (190,172); -insert into help_relation (help_topic_id,help_keyword_id) values (48,173); -insert into help_relation (help_topic_id,help_keyword_id) values (356,173); -insert into help_relation (help_topic_id,help_keyword_id) values (83,173); -insert into help_relation (help_topic_id,help_keyword_id) values (463,173); -insert into help_relation (help_topic_id,help_keyword_id) values (361,173); -insert into help_relation (help_topic_id,help_keyword_id) values (1,174); -insert into help_relation (help_topic_id,help_keyword_id) values (86,174); -insert into help_relation (help_topic_id,help_keyword_id) values (48,174); -insert into help_relation (help_topic_id,help_keyword_id) values (459,175); -insert into help_relation (help_topic_id,help_keyword_id) values (374,175); -insert into help_relation (help_topic_id,help_keyword_id) values (252,176); -insert into help_relation (help_topic_id,help_keyword_id) values (249,177); -insert into help_relation (help_topic_id,help_keyword_id) values (199,177); -insert into help_relation (help_topic_id,help_keyword_id) values (314,178); -insert into help_relation (help_topic_id,help_keyword_id) values (500,178); -insert into help_relation (help_topic_id,help_keyword_id) values (209,178); -insert into help_relation (help_topic_id,help_keyword_id) values (230,178); -insert into help_relation (help_topic_id,help_keyword_id) values (24,178); -insert into help_relation (help_topic_id,help_keyword_id) values (168,178); -insert into help_relation (help_topic_id,help_keyword_id) values (128,178); -insert into help_relation (help_topic_id,help_keyword_id) values (156,179); -insert into help_relation (help_topic_id,help_keyword_id) values (97,179); -insert into help_relation (help_topic_id,help_keyword_id) values (230,179); -insert into help_relation (help_topic_id,help_keyword_id) values (411,180); -insert into help_relation (help_topic_id,help_keyword_id) values (347,181); -insert into help_relation (help_topic_id,help_keyword_id) values (472,182); -insert into help_relation (help_topic_id,help_keyword_id) values (473,182); -insert into help_relation (help_topic_id,help_keyword_id) values (468,182); -insert into help_relation (help_topic_id,help_keyword_id) values (463,182); -insert into help_relation (help_topic_id,help_keyword_id) values (304,183); -insert into help_relation (help_topic_id,help_keyword_id) values (101,183); -insert into help_relation (help_topic_id,help_keyword_id) values (151,183); -insert into help_relation (help_topic_id,help_keyword_id) values (145,184); -insert into help_relation (help_topic_id,help_keyword_id) values (347,184); -insert into help_relation (help_topic_id,help_keyword_id) values (459,185); -insert into help_relation (help_topic_id,help_keyword_id) values (374,185); -insert into help_relation (help_topic_id,help_keyword_id) values (146,186); -insert into help_relation (help_topic_id,help_keyword_id) values (347,187); -insert into help_relation (help_topic_id,help_keyword_id) values (160,187); -insert into help_relation (help_topic_id,help_keyword_id) values (455,188); -insert into help_relation (help_topic_id,help_keyword_id) values (146,189); -insert into help_relation (help_topic_id,help_keyword_id) values (459,190); -insert into help_relation (help_topic_id,help_keyword_id) values (374,190); -insert into help_relation (help_topic_id,help_keyword_id) values (313,191); -insert into help_relation (help_topic_id,help_keyword_id) values (180,191); -insert into help_relation (help_topic_id,help_keyword_id) values (420,191); -insert into help_relation (help_topic_id,help_keyword_id) values (200,191); -insert into help_relation (help_topic_id,help_keyword_id) values (304,192); -insert into help_relation (help_topic_id,help_keyword_id) values (421,192); -insert into help_relation (help_topic_id,help_keyword_id) values (356,193); -insert into help_relation (help_topic_id,help_keyword_id) values (230,194); -insert into help_relation (help_topic_id,help_keyword_id) values (377,194); -insert into help_relation (help_topic_id,help_keyword_id) values (468,195); -insert into help_relation (help_topic_id,help_keyword_id) values (155,196); -insert into help_relation (help_topic_id,help_keyword_id) values (468,196); -insert into help_relation (help_topic_id,help_keyword_id) values (212,196); -insert into help_relation (help_topic_id,help_keyword_id) values (395,197); -insert into help_relation (help_topic_id,help_keyword_id) values (465,198); -insert into help_relation (help_topic_id,help_keyword_id) values (129,199); -insert into help_relation (help_topic_id,help_keyword_id) values (447,199); -insert into help_relation (help_topic_id,help_keyword_id) values (182,199); -insert into help_relation (help_topic_id,help_keyword_id) values (349,199); -insert into help_relation (help_topic_id,help_keyword_id) values (137,199); -insert into help_relation (help_topic_id,help_keyword_id) values (452,200); -insert into help_relation (help_topic_id,help_keyword_id) values (85,201); -insert into help_relation (help_topic_id,help_keyword_id) values (57,201); -insert into help_relation (help_topic_id,help_keyword_id) values (356,202); -insert into help_relation (help_topic_id,help_keyword_id) values (1,203); -insert into help_relation (help_topic_id,help_keyword_id) values (36,203); -insert into help_relation (help_topic_id,help_keyword_id) values (356,203); -insert into help_relation (help_topic_id,help_keyword_id) values (421,204); -insert into help_relation (help_topic_id,help_keyword_id) values (199,205); -insert into help_relation (help_topic_id,help_keyword_id) values (146,206); -insert into help_relation (help_topic_id,help_keyword_id) values (249,207); -insert into help_relation (help_topic_id,help_keyword_id) values (347,208); -insert into help_relation (help_topic_id,help_keyword_id) values (192,208); -insert into help_relation (help_topic_id,help_keyword_id) values (1,209); -insert into help_relation (help_topic_id,help_keyword_id) values (459,210); -insert into help_relation (help_topic_id,help_keyword_id) values (374,210); -insert into help_relation (help_topic_id,help_keyword_id) values (221,211); -insert into help_relation (help_topic_id,help_keyword_id) values (255,212); -insert into help_relation (help_topic_id,help_keyword_id) values (88,213); -insert into help_relation (help_topic_id,help_keyword_id) values (468,213); -insert into help_relation (help_topic_id,help_keyword_id) values (210,213); -insert into help_relation (help_topic_id,help_keyword_id) values (199,213); -insert into help_relation (help_topic_id,help_keyword_id) values (463,213); -insert into help_relation (help_topic_id,help_keyword_id) values (463,214); -insert into help_relation (help_topic_id,help_keyword_id) values (260,215); -insert into help_relation (help_topic_id,help_keyword_id) values (468,216); -insert into help_relation (help_topic_id,help_keyword_id) values (421,216); -insert into help_relation (help_topic_id,help_keyword_id) values (406,217); -insert into help_relation (help_topic_id,help_keyword_id) values (89,217); -insert into help_relation (help_topic_id,help_keyword_id) values (463,217); -insert into help_relation (help_topic_id,help_keyword_id) values (291,218); -insert into help_relation (help_topic_id,help_keyword_id) values (356,219); -insert into help_relation (help_topic_id,help_keyword_id) values (3,220); -insert into help_relation (help_topic_id,help_keyword_id) values (36,220); -insert into help_relation (help_topic_id,help_keyword_id) values (130,220); -insert into help_relation (help_topic_id,help_keyword_id) values (48,220); -insert into help_relation (help_topic_id,help_keyword_id) values (104,220); -insert into help_relation (help_topic_id,help_keyword_id) values (83,220); -insert into help_relation (help_topic_id,help_keyword_id) values (421,220); -insert into help_relation (help_topic_id,help_keyword_id) values (199,221); -insert into help_relation (help_topic_id,help_keyword_id) values (194,222); -insert into help_relation (help_topic_id,help_keyword_id) values (347,223); -insert into help_relation (help_topic_id,help_keyword_id) values (155,223); -insert into help_relation (help_topic_id,help_keyword_id) values (309,223); -insert into help_relation (help_topic_id,help_keyword_id) values (186,223); -insert into help_relation (help_topic_id,help_keyword_id) values (212,223); -insert into help_relation (help_topic_id,help_keyword_id) values (97,224); -insert into help_relation (help_topic_id,help_keyword_id) values (277,225); -insert into help_relation (help_topic_id,help_keyword_id) values (279,226); -insert into help_relation (help_topic_id,help_keyword_id) values (464,227); -insert into help_relation (help_topic_id,help_keyword_id) values (347,228); -insert into help_relation (help_topic_id,help_keyword_id) values (1,228); -insert into help_relation (help_topic_id,help_keyword_id) values (468,228); -insert into help_relation (help_topic_id,help_keyword_id) values (304,228); -insert into help_relation (help_topic_id,help_keyword_id) values (87,228); -insert into help_relation (help_topic_id,help_keyword_id) values (101,228); -insert into help_relation (help_topic_id,help_keyword_id) values (60,228); -insert into help_relation (help_topic_id,help_keyword_id) values (308,228); -insert into help_relation (help_topic_id,help_keyword_id) values (210,228); -insert into help_relation (help_topic_id,help_keyword_id) values (463,228); -insert into help_relation (help_topic_id,help_keyword_id) values (425,229); -insert into help_relation (help_topic_id,help_keyword_id) values (406,230); -insert into help_relation (help_topic_id,help_keyword_id) values (89,230); -insert into help_relation (help_topic_id,help_keyword_id) values (185,231); -insert into help_relation (help_topic_id,help_keyword_id) values (463,232); -insert into help_relation (help_topic_id,help_keyword_id) values (466,233); -insert into help_relation (help_topic_id,help_keyword_id) values (255,233); -insert into help_relation (help_topic_id,help_keyword_id) values (272,234); -insert into help_relation (help_topic_id,help_keyword_id) values (1,235); -insert into help_relation (help_topic_id,help_keyword_id) values (347,236); -insert into help_relation (help_topic_id,help_keyword_id) values (7,236); -insert into help_relation (help_topic_id,help_keyword_id) values (257,237); -insert into help_relation (help_topic_id,help_keyword_id) values (430,237); -insert into help_relation (help_topic_id,help_keyword_id) values (194,238); -insert into help_relation (help_topic_id,help_keyword_id) values (226,238); -insert into help_relation (help_topic_id,help_keyword_id) values (356,238); -insert into help_relation (help_topic_id,help_keyword_id) values (427,239); -insert into help_relation (help_topic_id,help_keyword_id) values (87,240); -insert into help_relation (help_topic_id,help_keyword_id) values (210,240); -insert into help_relation (help_topic_id,help_keyword_id) values (463,240); -insert into help_relation (help_topic_id,help_keyword_id) values (313,241); -insert into help_relation (help_topic_id,help_keyword_id) values (185,242); -insert into help_relation (help_topic_id,help_keyword_id) values (314,243); -insert into help_relation (help_topic_id,help_keyword_id) values (500,243); -insert into help_relation (help_topic_id,help_keyword_id) values (209,243); -insert into help_relation (help_topic_id,help_keyword_id) values (24,243); -insert into help_relation (help_topic_id,help_keyword_id) values (168,243); -insert into help_relation (help_topic_id,help_keyword_id) values (128,243); -insert into help_relation (help_topic_id,help_keyword_id) values (199,244); -insert into help_relation (help_topic_id,help_keyword_id) values (185,245); -insert into help_relation (help_topic_id,help_keyword_id) values (473,246); -insert into help_relation (help_topic_id,help_keyword_id) values (185,247); -insert into help_relation (help_topic_id,help_keyword_id) values (385,248); -insert into help_relation (help_topic_id,help_keyword_id) values (333,249); -insert into help_relation (help_topic_id,help_keyword_id) values (347,249); -insert into help_relation (help_topic_id,help_keyword_id) values (155,249); -insert into help_relation (help_topic_id,help_keyword_id) values (430,249); -insert into help_relation (help_topic_id,help_keyword_id) values (130,249); -insert into help_relation (help_topic_id,help_keyword_id) values (468,249); -insert into help_relation (help_topic_id,help_keyword_id) values (257,249); -insert into help_relation (help_topic_id,help_keyword_id) values (212,249); -insert into help_relation (help_topic_id,help_keyword_id) values (356,249); -insert into help_relation (help_topic_id,help_keyword_id) values (421,249); -insert into help_relation (help_topic_id,help_keyword_id) values (185,250); -insert into help_relation (help_topic_id,help_keyword_id) values (459,251); -insert into help_relation (help_topic_id,help_keyword_id) values (374,251); -insert into help_relation (help_topic_id,help_keyword_id) values (347,252); -insert into help_relation (help_topic_id,help_keyword_id) values (466,252); -insert into help_relation (help_topic_id,help_keyword_id) values (110,252); -insert into help_relation (help_topic_id,help_keyword_id) values (468,252); -insert into help_relation (help_topic_id,help_keyword_id) values (115,252); -insert into help_relation (help_topic_id,help_keyword_id) values (321,252); -insert into help_relation (help_topic_id,help_keyword_id) values (470,252); -insert into help_relation (help_topic_id,help_keyword_id) values (276,252); -insert into help_relation (help_topic_id,help_keyword_id) values (278,252); -insert into help_relation (help_topic_id,help_keyword_id) values (417,252); -insert into help_relation (help_topic_id,help_keyword_id) values (401,252); -insert into help_relation (help_topic_id,help_keyword_id) values (60,252); -insert into help_relation (help_topic_id,help_keyword_id) values (215,252); -insert into help_relation (help_topic_id,help_keyword_id) values (463,252); -insert into help_relation (help_topic_id,help_keyword_id) values (194,253); -insert into help_relation (help_topic_id,help_keyword_id) values (478,253); -insert into help_relation (help_topic_id,help_keyword_id) values (347,253); -insert into help_relation (help_topic_id,help_keyword_id) values (365,253); -insert into help_relation (help_topic_id,help_keyword_id) values (468,253); -insert into help_relation (help_topic_id,help_keyword_id) values (415,253); -insert into help_relation (help_topic_id,help_keyword_id) values (463,253); -insert into help_relation (help_topic_id,help_keyword_id) values (468,254); -insert into help_relation (help_topic_id,help_keyword_id) values (472,255); -insert into help_relation (help_topic_id,help_keyword_id) values (30,255); -insert into help_relation (help_topic_id,help_keyword_id) values (468,255); -insert into help_relation (help_topic_id,help_keyword_id) values (276,255); -insert into help_relation (help_topic_id,help_keyword_id) values (185,256); -insert into help_relation (help_topic_id,help_keyword_id) values (356,257); -insert into help_relation (help_topic_id,help_keyword_id) values (305,258); -insert into help_relation (help_topic_id,help_keyword_id) values (468,259); -insert into help_relation (help_topic_id,help_keyword_id) values (310,260); -insert into help_relation (help_topic_id,help_keyword_id) values (463,261); -insert into help_relation (help_topic_id,help_keyword_id) values (88,262); -insert into help_relation (help_topic_id,help_keyword_id) values (185,263); -insert into help_relation (help_topic_id,help_keyword_id) values (356,264); -insert into help_relation (help_topic_id,help_keyword_id) values (329,265); -insert into help_relation (help_topic_id,help_keyword_id) values (356,265); -insert into help_relation (help_topic_id,help_keyword_id) values (361,265); -insert into help_relation (help_topic_id,help_keyword_id) values (315,266); -insert into help_relation (help_topic_id,help_keyword_id) values (375,266); -insert into help_relation (help_topic_id,help_keyword_id) values (230,266); -insert into help_relation (help_topic_id,help_keyword_id) values (209,267); -insert into help_relation (help_topic_id,help_keyword_id) values (88,268); -insert into help_relation (help_topic_id,help_keyword_id) values (68,269); -insert into help_relation (help_topic_id,help_keyword_id) values (488,269); -insert into help_relation (help_topic_id,help_keyword_id) values (420,270); -insert into help_relation (help_topic_id,help_keyword_id) values (246,271); -insert into help_relation (help_topic_id,help_keyword_id) values (146,272); -insert into help_relation (help_topic_id,help_keyword_id) values (194,273); -insert into help_relation (help_topic_id,help_keyword_id) values (226,273); -insert into help_relation (help_topic_id,help_keyword_id) values (326,274); -insert into help_relation (help_topic_id,help_keyword_id) values (151,274); -insert into help_relation (help_topic_id,help_keyword_id) values (454,275); -insert into help_relation (help_topic_id,help_keyword_id) values (194,275); -insert into help_relation (help_topic_id,help_keyword_id) values (155,275); -insert into help_relation (help_topic_id,help_keyword_id) values (97,275); -insert into help_relation (help_topic_id,help_keyword_id) values (302,275); -insert into help_relation (help_topic_id,help_keyword_id) values (278,275); -insert into help_relation (help_topic_id,help_keyword_id) values (309,275); -insert into help_relation (help_topic_id,help_keyword_id) values (211,275); -insert into help_relation (help_topic_id,help_keyword_id) values (210,275); -insert into help_relation (help_topic_id,help_keyword_id) values (77,275); -insert into help_relation (help_topic_id,help_keyword_id) values (17,275); -insert into help_relation (help_topic_id,help_keyword_id) values (347,275); -insert into help_relation (help_topic_id,help_keyword_id) values (22,275); -insert into help_relation (help_topic_id,help_keyword_id) values (468,275); -insert into help_relation (help_topic_id,help_keyword_id) values (473,275); -insert into help_relation (help_topic_id,help_keyword_id) values (393,275); -insert into help_relation (help_topic_id,help_keyword_id) values (89,275); -insert into help_relation (help_topic_id,help_keyword_id) values (60,275); -insert into help_relation (help_topic_id,help_keyword_id) values (358,275); -insert into help_relation (help_topic_id,help_keyword_id) values (329,276); -insert into help_relation (help_topic_id,help_keyword_id) values (194,277); -insert into help_relation (help_topic_id,help_keyword_id) values (199,278); -insert into help_relation (help_topic_id,help_keyword_id) values (234,279); -insert into help_relation (help_topic_id,help_keyword_id) values (347,280); -insert into help_relation (help_topic_id,help_keyword_id) values (451,280); -insert into help_relation (help_topic_id,help_keyword_id) values (89,281); -insert into help_relation (help_topic_id,help_keyword_id) values (39,282); -insert into help_relation (help_topic_id,help_keyword_id) values (347,282); -insert into help_relation (help_topic_id,help_keyword_id) values (269,282); -insert into help_relation (help_topic_id,help_keyword_id) values (463,283); -insert into help_relation (help_topic_id,help_keyword_id) values (468,284); -insert into help_relation (help_topic_id,help_keyword_id) values (378,285); -insert into help_relation (help_topic_id,help_keyword_id) values (147,286); -insert into help_relation (help_topic_id,help_keyword_id) values (107,287); -insert into help_relation (help_topic_id,help_keyword_id) values (466,288); -insert into help_relation (help_topic_id,help_keyword_id) values (463,288); -insert into help_relation (help_topic_id,help_keyword_id) values (468,289); -insert into help_relation (help_topic_id,help_keyword_id) values (417,290); -insert into help_relation (help_topic_id,help_keyword_id) values (3,291); -insert into help_relation (help_topic_id,help_keyword_id) values (104,291); -insert into help_relation (help_topic_id,help_keyword_id) values (339,292); -insert into help_relation (help_topic_id,help_keyword_id) values (344,293); -insert into help_relation (help_topic_id,help_keyword_id) values (257,294); -insert into help_relation (help_topic_id,help_keyword_id) values (269,295); -insert into help_relation (help_topic_id,help_keyword_id) values (321,296); -insert into help_relation (help_topic_id,help_keyword_id) values (463,296); -insert into help_relation (help_topic_id,help_keyword_id) values (193,297); -insert into help_relation (help_topic_id,help_keyword_id) values (68,297); -insert into help_relation (help_topic_id,help_keyword_id) values (333,297); -insert into help_relation (help_topic_id,help_keyword_id) values (69,297); -insert into help_relation (help_topic_id,help_keyword_id) values (336,297); -insert into help_relation (help_topic_id,help_keyword_id) values (7,297); -insert into help_relation (help_topic_id,help_keyword_id) values (134,297); -insert into help_relation (help_topic_id,help_keyword_id) values (278,297); -insert into help_relation (help_topic_id,help_keyword_id) values (10,297); -insert into help_relation (help_topic_id,help_keyword_id) values (282,297); -insert into help_relation (help_topic_id,help_keyword_id) values (137,297); -insert into help_relation (help_topic_id,help_keyword_id) values (215,297); -insert into help_relation (help_topic_id,help_keyword_id) values (17,297); -insert into help_relation (help_topic_id,help_keyword_id) values (347,297); -insert into help_relation (help_topic_id,help_keyword_id) values (21,297); -insert into help_relation (help_topic_id,help_keyword_id) values (349,297); -insert into help_relation (help_topic_id,help_keyword_id) values (82,297); -insert into help_relation (help_topic_id,help_keyword_id) values (223,297); -insert into help_relation (help_topic_id,help_keyword_id) values (25,297); -insert into help_relation (help_topic_id,help_keyword_id) values (145,297); -insert into help_relation (help_topic_id,help_keyword_id) values (294,297); -insert into help_relation (help_topic_id,help_keyword_id) values (358,297); -insert into help_relation (help_topic_id,help_keyword_id) values (424,297); -insert into help_relation (help_topic_id,help_keyword_id) values (33,297); -insert into help_relation (help_topic_id,help_keyword_id) values (365,297); -insert into help_relation (help_topic_id,help_keyword_id) values (160,297); -insert into help_relation (help_topic_id,help_keyword_id) values (488,297); -insert into help_relation (help_topic_id,help_keyword_id) values (487,297); -insert into help_relation (help_topic_id,help_keyword_id) values (39,297); -insert into help_relation (help_topic_id,help_keyword_id) values (309,297); -insert into help_relation (help_topic_id,help_keyword_id) values (492,297); -insert into help_relation (help_topic_id,help_keyword_id) values (308,297); -insert into help_relation (help_topic_id,help_keyword_id) values (170,297); -insert into help_relation (help_topic_id,help_keyword_id) values (58,297); -insert into help_relation (help_topic_id,help_keyword_id) values (393,297); -insert into help_relation (help_topic_id,help_keyword_id) values (328,297); -insert into help_relation (help_topic_id,help_keyword_id) values (330,297); -insert into help_relation (help_topic_id,help_keyword_id) values (122,297); -insert into help_relation (help_topic_id,help_keyword_id) values (192,297); -insert into help_relation (help_topic_id,help_keyword_id) values (451,297); -insert into help_relation (help_topic_id,help_keyword_id) values (38,298); -insert into help_relation (help_topic_id,help_keyword_id) values (305,298); -insert into help_relation (help_topic_id,help_keyword_id) values (249,298); -insert into help_relation (help_topic_id,help_keyword_id) values (356,298); -insert into help_relation (help_topic_id,help_keyword_id) values (199,298); -insert into help_relation (help_topic_id,help_keyword_id) values (468,299); -insert into help_relation (help_topic_id,help_keyword_id) values (326,300); -insert into help_relation (help_topic_id,help_keyword_id) values (468,301); -insert into help_relation (help_topic_id,help_keyword_id) values (122,302); -insert into help_relation (help_topic_id,help_keyword_id) values (350,302); -insert into help_relation (help_topic_id,help_keyword_id) values (85,303); -insert into help_relation (help_topic_id,help_keyword_id) values (57,303); -insert into help_relation (help_topic_id,help_keyword_id) values (28,303); -insert into help_relation (help_topic_id,help_keyword_id) values (327,303); -insert into help_relation (help_topic_id,help_keyword_id) values (344,303); -insert into help_relation (help_topic_id,help_keyword_id) values (496,303); -insert into help_relation (help_topic_id,help_keyword_id) values (232,303); -insert into help_relation (help_topic_id,help_keyword_id) values (376,304); -insert into help_relation (help_topic_id,help_keyword_id) values (147,305); -insert into help_relation (help_topic_id,help_keyword_id) values (316,305); -insert into help_relation (help_topic_id,help_keyword_id) values (314,306); -insert into help_relation (help_topic_id,help_keyword_id) values (106,307); -insert into help_relation (help_topic_id,help_keyword_id) values (376,308); -insert into help_relation (help_topic_id,help_keyword_id) values (3,309); -insert into help_relation (help_topic_id,help_keyword_id) values (356,309); -insert into help_relation (help_topic_id,help_keyword_id) values (104,309); -insert into help_relation (help_topic_id,help_keyword_id) values (301,309); -insert into help_relation (help_topic_id,help_keyword_id) values (255,309); -insert into help_relation (help_topic_id,help_keyword_id) values (347,310); -insert into help_relation (help_topic_id,help_keyword_id) values (160,310); -insert into help_relation (help_topic_id,help_keyword_id) values (141,311); -insert into help_relation (help_topic_id,help_keyword_id) values (130,312); -insert into help_relation (help_topic_id,help_keyword_id) values (199,312); -insert into help_relation (help_topic_id,help_keyword_id) values (77,312); -insert into help_relation (help_topic_id,help_keyword_id) values (473,313); -insert into help_relation (help_topic_id,help_keyword_id) values (185,314); -insert into help_relation (help_topic_id,help_keyword_id) values (182,315); -insert into help_relation (help_topic_id,help_keyword_id) values (455,316); -insert into help_relation (help_topic_id,help_keyword_id) values (111,317); -insert into help_relation (help_topic_id,help_keyword_id) values (24,317); -insert into help_relation (help_topic_id,help_keyword_id) values (376,318); -insert into help_relation (help_topic_id,help_keyword_id) values (185,319); -insert into help_relation (help_topic_id,help_keyword_id) values (130,320); -insert into help_relation (help_topic_id,help_keyword_id) values (421,320); -insert into help_relation (help_topic_id,help_keyword_id) values (390,321); -insert into help_relation (help_topic_id,help_keyword_id) values (118,321); -insert into help_relation (help_topic_id,help_keyword_id) values (463,322); -insert into help_relation (help_topic_id,help_keyword_id) values (25,323); -insert into help_relation (help_topic_id,help_keyword_id) values (347,323); -insert into help_relation (help_topic_id,help_keyword_id) values (199,324); -insert into help_relation (help_topic_id,help_keyword_id) values (373,325); -insert into help_relation (help_topic_id,help_keyword_id) values (473,325); -insert into help_relation (help_topic_id,help_keyword_id) values (374,326); -insert into help_relation (help_topic_id,help_keyword_id) values (146,327); -insert into help_relation (help_topic_id,help_keyword_id) values (185,328); -insert into help_relation (help_topic_id,help_keyword_id) values (376,329); -insert into help_relation (help_topic_id,help_keyword_id) values (199,330); -insert into help_relation (help_topic_id,help_keyword_id) values (347,331); -insert into help_relation (help_topic_id,help_keyword_id) values (378,331); -insert into help_relation (help_topic_id,help_keyword_id) values (347,332); -insert into help_relation (help_topic_id,help_keyword_id) values (291,332); -insert into help_relation (help_topic_id,help_keyword_id) values (419,332); -insert into help_relation (help_topic_id,help_keyword_id) values (383,333); -insert into help_relation (help_topic_id,help_keyword_id) values (424,334); -insert into help_relation (help_topic_id,help_keyword_id) values (88,334); -insert into help_relation (help_topic_id,help_keyword_id) values (122,334); -insert into help_relation (help_topic_id,help_keyword_id) values (356,334); -insert into help_relation (help_topic_id,help_keyword_id) values (463,335); -insert into help_relation (help_topic_id,help_keyword_id) values (356,336); -insert into help_relation (help_topic_id,help_keyword_id) values (199,337); -insert into help_relation (help_topic_id,help_keyword_id) values (86,338); -insert into help_relation (help_topic_id,help_keyword_id) values (199,338); -insert into help_relation (help_topic_id,help_keyword_id) values (356,339); -insert into help_relation (help_topic_id,help_keyword_id) values (397,340); -insert into help_relation (help_topic_id,help_keyword_id) values (88,341); -insert into help_relation (help_topic_id,help_keyword_id) values (176,341); -insert into help_relation (help_topic_id,help_keyword_id) values (151,341); -insert into help_relation (help_topic_id,help_keyword_id) values (185,342); -insert into help_relation (help_topic_id,help_keyword_id) values (130,343); -insert into help_relation (help_topic_id,help_keyword_id) values (421,343); -insert into help_relation (help_topic_id,help_keyword_id) values (52,344); -insert into help_relation (help_topic_id,help_keyword_id) values (324,344); -insert into help_relation (help_topic_id,help_keyword_id) values (373,345); -insert into help_relation (help_topic_id,help_keyword_id) values (473,345); -insert into help_relation (help_topic_id,help_keyword_id) values (9,345); -insert into help_relation (help_topic_id,help_keyword_id) values (199,346); -insert into help_relation (help_topic_id,help_keyword_id) values (185,347); -insert into help_relation (help_topic_id,help_keyword_id) values (123,348); -insert into help_relation (help_topic_id,help_keyword_id) values (146,349); -insert into help_relation (help_topic_id,help_keyword_id) values (447,349); -insert into help_relation (help_topic_id,help_keyword_id) values (376,350); -insert into help_relation (help_topic_id,help_keyword_id) values (407,351); -insert into help_relation (help_topic_id,help_keyword_id) values (376,352); -insert into help_relation (help_topic_id,help_keyword_id) values (463,353); -insert into help_relation (help_topic_id,help_keyword_id) values (144,354); -insert into help_relation (help_topic_id,help_keyword_id) values (24,355); -insert into help_relation (help_topic_id,help_keyword_id) values (406,356); -insert into help_relation (help_topic_id,help_keyword_id) values (110,356); -insert into help_relation (help_topic_id,help_keyword_id) values (222,356); -insert into help_relation (help_topic_id,help_keyword_id) values (463,356); -insert into help_relation (help_topic_id,help_keyword_id) values (468,357); -insert into help_relation (help_topic_id,help_keyword_id) values (210,357); -insert into help_relation (help_topic_id,help_keyword_id) values (463,357); -insert into help_relation (help_topic_id,help_keyword_id) values (1,358); -insert into help_relation (help_topic_id,help_keyword_id) values (478,359); -insert into help_relation (help_topic_id,help_keyword_id) values (406,359); -insert into help_relation (help_topic_id,help_keyword_id) values (439,359); -insert into help_relation (help_topic_id,help_keyword_id) values (159,359); -insert into help_relation (help_topic_id,help_keyword_id) values (199,359); -insert into help_relation (help_topic_id,help_keyword_id) values (373,359); -insert into help_relation (help_topic_id,help_keyword_id) values (226,359); -insert into help_relation (help_topic_id,help_keyword_id) values (60,359); -insert into help_relation (help_topic_id,help_keyword_id) values (212,359); -insert into help_relation (help_topic_id,help_keyword_id) values (233,359); -insert into help_relation (help_topic_id,help_keyword_id) values (463,359); -insert into help_relation (help_topic_id,help_keyword_id) values (468,360); -insert into help_relation (help_topic_id,help_keyword_id) values (463,360); -insert into help_relation (help_topic_id,help_keyword_id) values (473,361); -insert into help_relation (help_topic_id,help_keyword_id) values (1,362); -insert into help_relation (help_topic_id,help_keyword_id) values (356,362); -insert into help_relation (help_topic_id,help_keyword_id) values (1,363); -insert into help_relation (help_topic_id,help_keyword_id) values (347,364); -insert into help_relation (help_topic_id,help_keyword_id) values (349,364); -insert into help_relation (help_topic_id,help_keyword_id) values (421,365); -insert into help_relation (help_topic_id,help_keyword_id) values (427,366); -insert into help_relation (help_topic_id,help_keyword_id) values (468,367); -insert into help_relation (help_topic_id,help_keyword_id) values (473,368); -insert into help_relation (help_topic_id,help_keyword_id) values (477,368); -insert into help_relation (help_topic_id,help_keyword_id) values (199,368); -insert into help_relation (help_topic_id,help_keyword_id) values (77,368); -insert into help_relation (help_topic_id,help_keyword_id) values (356,369); -insert into help_relation (help_topic_id,help_keyword_id) values (465,370); -insert into help_relation (help_topic_id,help_keyword_id) values (230,370); -insert into help_relation (help_topic_id,help_keyword_id) values (106,371); -insert into help_relation (help_topic_id,help_keyword_id) values (69,372); -insert into help_relation (help_topic_id,help_keyword_id) values (347,372); -insert into help_relation (help_topic_id,help_keyword_id) values (494,373); -insert into help_relation (help_topic_id,help_keyword_id) values (276,374); -insert into help_relation (help_topic_id,help_keyword_id) values (447,375); -insert into help_relation (help_topic_id,help_keyword_id) values (356,376); -insert into help_relation (help_topic_id,help_keyword_id) values (417,377); -insert into help_relation (help_topic_id,help_keyword_id) values (212,377); -insert into help_relation (help_topic_id,help_keyword_id) values (146,378); -insert into help_relation (help_topic_id,help_keyword_id) values (327,378); -insert into help_relation (help_topic_id,help_keyword_id) values (468,379); -insert into help_relation (help_topic_id,help_keyword_id) values (487,380); -insert into help_relation (help_topic_id,help_keyword_id) values (417,381); -insert into help_relation (help_topic_id,help_keyword_id) values (89,382); -insert into help_relation (help_topic_id,help_keyword_id) values (376,382); -insert into help_relation (help_topic_id,help_keyword_id) values (199,383); -insert into help_relation (help_topic_id,help_keyword_id) values (376,384); -insert into help_relation (help_topic_id,help_keyword_id) values (212,385); -insert into help_relation (help_topic_id,help_keyword_id) values (472,386); -insert into help_relation (help_topic_id,help_keyword_id) values (468,386); -insert into help_relation (help_topic_id,help_keyword_id) values (199,386); -insert into help_relation (help_topic_id,help_keyword_id) values (443,387); -insert into help_relation (help_topic_id,help_keyword_id) values (282,388); -insert into help_relation (help_topic_id,help_keyword_id) values (447,389); -insert into help_relation (help_topic_id,help_keyword_id) values (448,390); -insert into help_relation (help_topic_id,help_keyword_id) values (89,391); -insert into help_relation (help_topic_id,help_keyword_id) values (128,392); -insert into help_relation (help_topic_id,help_keyword_id) values (10,393); -insert into help_relation (help_topic_id,help_keyword_id) values (347,393); -insert into help_relation (help_topic_id,help_keyword_id) values (472,394); -insert into help_relation (help_topic_id,help_keyword_id) values (30,394); -insert into help_relation (help_topic_id,help_keyword_id) values (276,394); -insert into help_relation (help_topic_id,help_keyword_id) values (447,395); -insert into help_relation (help_topic_id,help_keyword_id) values (56,396); -insert into help_relation (help_topic_id,help_keyword_id) values (84,397); -insert into help_relation (help_topic_id,help_keyword_id) values (206,397); -insert into help_relation (help_topic_id,help_keyword_id) values (456,397); -insert into help_relation (help_topic_id,help_keyword_id) values (368,397); -insert into help_relation (help_topic_id,help_keyword_id) values (84,398); -insert into help_relation (help_topic_id,help_keyword_id) values (206,398); -insert into help_relation (help_topic_id,help_keyword_id) values (155,398); -insert into help_relation (help_topic_id,help_keyword_id) values (89,398); -insert into help_relation (help_topic_id,help_keyword_id) values (312,398); -insert into help_relation (help_topic_id,help_keyword_id) values (189,399); -insert into help_relation (help_topic_id,help_keyword_id) values (194,400); -insert into help_relation (help_topic_id,help_keyword_id) values (478,400); -insert into help_relation (help_topic_id,help_keyword_id) values (326,401); -insert into help_relation (help_topic_id,help_keyword_id) values (459,402); -insert into help_relation (help_topic_id,help_keyword_id) values (468,403); -insert into help_relation (help_topic_id,help_keyword_id) values (146,404); -insert into help_relation (help_topic_id,help_keyword_id) values (324,404); -insert into help_relation (help_topic_id,help_keyword_id) values (33,405); -insert into help_relation (help_topic_id,help_keyword_id) values (460,406); -insert into help_relation (help_topic_id,help_keyword_id) values (479,407); -insert into help_relation (help_topic_id,help_keyword_id) values (155,407); -insert into help_relation (help_topic_id,help_keyword_id) values (300,407); -insert into help_relation (help_topic_id,help_keyword_id) values (9,407); -insert into help_relation (help_topic_id,help_keyword_id) values (276,407); -insert into help_relation (help_topic_id,help_keyword_id) values (28,407); -insert into help_relation (help_topic_id,help_keyword_id) values (30,407); -insert into help_relation (help_topic_id,help_keyword_id) values (89,407); -insert into help_relation (help_topic_id,help_keyword_id) values (186,407); -insert into help_relation (help_topic_id,help_keyword_id) values (130,408); -insert into help_relation (help_topic_id,help_keyword_id) values (463,409); -insert into help_relation (help_topic_id,help_keyword_id) values (269,410); -insert into help_relation (help_topic_id,help_keyword_id) values (106,411); -insert into help_relation (help_topic_id,help_keyword_id) values (473,412); -insert into help_relation (help_topic_id,help_keyword_id) values (222,412); -insert into help_relation (help_topic_id,help_keyword_id) values (331,412); -insert into help_relation (help_topic_id,help_keyword_id) values (77,412); -insert into help_relation (help_topic_id,help_keyword_id) values (313,413); -insert into help_relation (help_topic_id,help_keyword_id) values (347,414); -insert into help_relation (help_topic_id,help_keyword_id) values (308,414); -insert into help_relation (help_topic_id,help_keyword_id) values (463,414); -insert into help_relation (help_topic_id,help_keyword_id) values (424,415); -insert into help_relation (help_topic_id,help_keyword_id) values (48,415); -insert into help_relation (help_topic_id,help_keyword_id) values (122,415); -insert into help_relation (help_topic_id,help_keyword_id) values (356,415); -insert into help_relation (help_topic_id,help_keyword_id) values (83,415); -insert into help_relation (help_topic_id,help_keyword_id) values (106,415); -insert into help_relation (help_topic_id,help_keyword_id) values (472,416); -insert into help_relation (help_topic_id,help_keyword_id) values (60,416); -insert into help_relation (help_topic_id,help_keyword_id) values (104,416); -insert into help_relation (help_topic_id,help_keyword_id) values (468,416); -insert into help_relation (help_topic_id,help_keyword_id) values (463,416); -insert into help_relation (help_topic_id,help_keyword_id) values (468,417); -insert into help_relation (help_topic_id,help_keyword_id) values (232,418); -insert into help_relation (help_topic_id,help_keyword_id) values (356,419); -insert into help_relation (help_topic_id,help_keyword_id) values (3,420); -insert into help_relation (help_topic_id,help_keyword_id) values (104,420); -insert into help_relation (help_topic_id,help_keyword_id) values (486,420); -insert into help_relation (help_topic_id,help_keyword_id) values (459,421); -insert into help_relation (help_topic_id,help_keyword_id) values (374,421); -insert into help_relation (help_topic_id,help_keyword_id) values (470,422); -insert into help_relation (help_topic_id,help_keyword_id) values (463,422); -insert into help_relation (help_topic_id,help_keyword_id) values (468,423); -insert into help_relation (help_topic_id,help_keyword_id) values (463,423); -insert into help_relation (help_topic_id,help_keyword_id) values (468,424); -insert into help_relation (help_topic_id,help_keyword_id) values (243,424); -insert into help_relation (help_topic_id,help_keyword_id) values (472,425); -insert into help_relation (help_topic_id,help_keyword_id) values (468,425); -insert into help_relation (help_topic_id,help_keyword_id) values (36,426); -insert into help_relation (help_topic_id,help_keyword_id) values (194,427); -insert into help_relation (help_topic_id,help_keyword_id) values (478,427); -insert into help_relation (help_topic_id,help_keyword_id) values (129,428); -insert into help_relation (help_topic_id,help_keyword_id) values (447,428); -insert into help_relation (help_topic_id,help_keyword_id) values (349,428); -insert into help_relation (help_topic_id,help_keyword_id) values (137,428); -insert into help_relation (help_topic_id,help_keyword_id) values (347,429); -insert into help_relation (help_topic_id,help_keyword_id) values (473,429); -insert into help_relation (help_topic_id,help_keyword_id) values (155,429); -insert into help_relation (help_topic_id,help_keyword_id) values (309,429); -insert into help_relation (help_topic_id,help_keyword_id) values (186,429); -insert into help_relation (help_topic_id,help_keyword_id) values (212,429); -insert into help_relation (help_topic_id,help_keyword_id) values (84,430); -insert into help_relation (help_topic_id,help_keyword_id) values (472,430); -insert into help_relation (help_topic_id,help_keyword_id) values (368,430); -insert into help_relation (help_topic_id,help_keyword_id) values (483,431); -insert into help_relation (help_topic_id,help_keyword_id) values (466,432); -insert into help_relation (help_topic_id,help_keyword_id) values (421,433); -insert into help_relation (help_topic_id,help_keyword_id) values (145,434); -insert into help_relation (help_topic_id,help_keyword_id) values (38,434); -insert into help_relation (help_topic_id,help_keyword_id) values (406,434); -insert into help_relation (help_topic_id,help_keyword_id) values (89,434); -insert into help_relation (help_topic_id,help_keyword_id) values (223,434); -insert into help_relation (help_topic_id,help_keyword_id) values (52,434); -insert into help_relation (help_topic_id,help_keyword_id) values (324,434); -insert into help_relation (help_topic_id,help_keyword_id) values (257,435); -insert into help_relation (help_topic_id,help_keyword_id) values (356,436); -insert into help_relation (help_topic_id,help_keyword_id) values (361,436); -insert into help_relation (help_topic_id,help_keyword_id) values (491,437); -insert into help_relation (help_topic_id,help_keyword_id) values (421,438); -insert into help_relation (help_topic_id,help_keyword_id) values (406,439); -insert into help_relation (help_topic_id,help_keyword_id) values (89,439); -insert into help_relation (help_topic_id,help_keyword_id) values (463,439); -insert into help_relation (help_topic_id,help_keyword_id) values (468,440); -insert into help_relation (help_topic_id,help_keyword_id) values (212,440); -insert into help_relation (help_topic_id,help_keyword_id) values (199,441); -insert into help_relation (help_topic_id,help_keyword_id) values (496,442); -insert into help_relation (help_topic_id,help_keyword_id) values (466,443); -insert into help_relation (help_topic_id,help_keyword_id) values (326,443); -insert into help_relation (help_topic_id,help_keyword_id) values (36,443); -insert into help_relation (help_topic_id,help_keyword_id) values (130,443); -insert into help_relation (help_topic_id,help_keyword_id) values (115,443); -insert into help_relation (help_topic_id,help_keyword_id) values (421,443); -insert into help_relation (help_topic_id,help_keyword_id) values (470,443); -insert into help_relation (help_topic_id,help_keyword_id) values (0,444); -insert into help_relation (help_topic_id,help_keyword_id) values (96,444); -insert into help_relation (help_topic_id,help_keyword_id) values (384,444); -insert into help_relation (help_topic_id,help_keyword_id) values (288,444); -insert into help_relation (help_topic_id,help_keyword_id) values (433,444); -insert into help_relation (help_topic_id,help_keyword_id) values (305,444); -insert into help_relation (help_topic_id,help_keyword_id) values (356,444); -insert into help_relation (help_topic_id,help_keyword_id) values (361,444); -insert into help_relation (help_topic_id,help_keyword_id) values (497,445); -insert into help_relation (help_topic_id,help_keyword_id) values (185,446); -insert into help_relation (help_topic_id,help_keyword_id) values (199,447); -insert into help_relation (help_topic_id,help_keyword_id) values (134,448); -insert into help_relation (help_topic_id,help_keyword_id) values (347,448); -insert into help_relation (help_topic_id,help_keyword_id) values (294,448); -insert into help_relation (help_topic_id,help_keyword_id) values (36,448); -insert into help_relation (help_topic_id,help_keyword_id) values (495,449); -insert into help_relation (help_topic_id,help_keyword_id) values (27,450); -insert into help_relation (help_topic_id,help_keyword_id) values (347,451); -insert into help_relation (help_topic_id,help_keyword_id) values (22,451); -insert into help_relation (help_topic_id,help_keyword_id) values (263,451); -insert into help_relation (help_topic_id,help_keyword_id) values (347,452); -insert into help_relation (help_topic_id,help_keyword_id) values (492,452); -insert into help_relation (help_topic_id,help_keyword_id) values (199,453); -insert into help_relation (help_topic_id,help_keyword_id) values (356,454); -insert into help_relation (help_topic_id,help_keyword_id) values (104,454); -insert into help_relation (help_topic_id,help_keyword_id) values (210,455); -insert into help_relation (help_topic_id,help_keyword_id) values (468,456); -insert into help_relation (help_topic_id,help_keyword_id) values (106,456); -insert into help_relation (help_topic_id,help_keyword_id) values (463,456); -insert into help_relation (help_topic_id,help_keyword_id) values (463,457); -insert into help_relation (help_topic_id,help_keyword_id) values (194,458); -insert into help_relation (help_topic_id,help_keyword_id) values (478,458); -insert into help_relation (help_topic_id,help_keyword_id) values (459,459); -insert into help_relation (help_topic_id,help_keyword_id) values (374,459); -insert into help_relation (help_topic_id,help_keyword_id) values (39,460); -insert into help_relation (help_topic_id,help_keyword_id) values (58,460); -insert into help_relation (help_topic_id,help_keyword_id) values (269,460); -insert into help_relation (help_topic_id,help_keyword_id) values (185,460); -insert into help_relation (help_topic_id,help_keyword_id) values (264,460); -insert into help_relation (help_topic_id,help_keyword_id) values (209,461); -insert into help_relation (help_topic_id,help_keyword_id) values (468,461); -insert into help_relation (help_topic_id,help_keyword_id) values (201,462); -insert into help_relation (help_topic_id,help_keyword_id) values (468,463); +insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (1,9,'HELP_DATE','Help Contents generated from the MariaDB Knowledge Base on 22 October 2022.','',''); +insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (2,9,'HELP_VERSION','Help Contents generated for MariaDB 10.3 from the MariaDB Knowledge Base on 22 October 2022.','',''); +insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (3,2,'AREA','A synonym for ST_AREA.\n\nURL: https://mariadb.com/kb/en/polygon-properties-area/','','https://mariadb.com/kb/en/polygon-properties-area/'); +insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (4,2,'CENTROID','A synonym for ST_CENTROID.\n\nURL: https://mariadb.com/kb/en/centroid/','','https://mariadb.com/kb/en/centroid/'); +insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (5,2,'ExteriorRing','A synonym for ST_ExteriorRing.\n\nURL: https://mariadb.com/kb/en/polygon-properties-exteriorring/','','https://mariadb.com/kb/en/polygon-properties-exteriorring/'); +insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (6,2,'InteriorRingN','A synonym for ST_InteriorRingN.\n\nURL: https://mariadb.com/kb/en/polygon-properties-interiorringn/','','https://mariadb.com/kb/en/polygon-properties-interiorringn/'); +insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (7,2,'NumInteriorRings','A synonym for ST_NumInteriorRings.\n\nURL: https://mariadb.com/kb/en/polygon-properties-numinteriorrings/','','https://mariadb.com/kb/en/polygon-properties-numinteriorrings/'); +insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (8,2,'ST_AREA','Syntax\n------\n\nST_Area(poly)\nArea(poly)\n\nDescription\n-----------\n\nReturns as a double-precision number the area of the Polygon value poly, as\nmeasured in its spatial reference system.\n\nST_Area() and Area() are synonyms.\n\nExamples\n--------\n\nSET @poly = \'Polygon((0 0,0 3,3 0,0 0),(1 1,1 2,2 1,1 1))\';\n\nSELECT Area(GeomFromText(@poly));\n+---------------------------+\n| Area(GeomFromText(@poly)) |\n+---------------------------+\n| 4 |\n+---------------------------+\n\nURL: https://mariadb.com/kb/en/st_area/','','https://mariadb.com/kb/en/st_area/'); +insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (9,2,'ST_CENTROID','Syntax\n------\n\nST_Centroid(mpoly)\nCentroid(mpoly)\n\nDescription\n-----------\n\nReturns a point reflecting the mathematical centroid (geometric center) for\nthe MultiPolygon mpoly. The resulting point will not necessarily be on the\nMultiPolygon.\n\nST_Centroid() and Centroid() are synonyms.\n\nExamples\n--------\n\nSET @poly = ST_GeomFromText(\'POLYGON((0 0,20 0,20 20,0 20,0 0))\');\nSELECT ST_AsText(ST_Centroid(@poly)) AS center;\n+--------------+\n| center |\n+--------------+\n| POINT(10 10) |\n+--------------+\n\nURL: https://mariadb.com/kb/en/st_centroid/','','https://mariadb.com/kb/en/st_centroid/'); +insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (10,2,'ST_ExteriorRing','Syntax\n------\n\nST_ExteriorRing(poly)\nExteriorRing(poly)\n\nDescription\n-----------\n\nReturns the exterior ring of the Polygon value poly as a LineString.\n\nST_ExteriorRing() and ExteriorRing() are synonyms.\n\nExamples\n--------\n\nSET @poly = \'Polygon((0 0,0 3,3 3,3 0,0 0),(1 1,1 2,2 2,2 1,1 1))\';\n\nSELECT AsText(ExteriorRing(GeomFromText(@poly)));\n+-------------------------------------------+\n| AsText(ExteriorRing(GeomFromText(@poly))) |\n+-------------------------------------------+\n| LINESTRING(0 0,0 3,3 3,3 0,0 0) |\n+-------------------------------------------+\n\nURL: https://mariadb.com/kb/en/st_exteriorring/','','https://mariadb.com/kb/en/st_exteriorring/'); +insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (11,2,'ST_InteriorRingN','Syntax\n------\n\nST_InteriorRingN(poly,N)\nInteriorRingN(poly,N)\n\nDescription\n-----------\n\nReturns the N-th interior ring for the Polygon value poly as a LineString.\nRings are numbered beginning with 1.\n\nST_InteriorRingN() and InteriorRingN() are synonyms.\n\nExamples\n--------\n\nSET @poly = \'Polygon((0 0,0 3,3 3,3 0,0 0),(1 1,1 2,2 2,2 1,1 1))\';\n\nSELECT AsText(InteriorRingN(GeomFromText(@poly),1));\n+----------------------------------------------+\n| AsText(InteriorRingN(GeomFromText(@poly),1)) |\n+----------------------------------------------+\n| LINESTRING(1 1,1 2,2 2,2 1,1 1) |\n+----------------------------------------------+\n\nURL: https://mariadb.com/kb/en/st_interiorringn/','','https://mariadb.com/kb/en/st_interiorringn/'); +insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (12,2,'ST_NumInteriorRings','Syntax\n------\n\nST_NumInteriorRings(poly)\nNumInteriorRings(poly)\n\nDescription\n-----------\n\nReturns an integer containing the number of interior rings in the Polygon\nvalue poly.\n\nNote that according the the OpenGIS standard, a POLYGON should have exactly\none ExteriorRing and all other rings should lie within that ExteriorRing and\nthus be the InteriorRings. Practically, however, some systems, including\nMariaDB\'s, permit polygons to have several \'ExteriorRings\'. In the case of\nthere being multiple, non-overlapping exterior rings ST_NumInteriorRings()\nwill return 1.\n\nST_NumInteriorRings() and NumInteriorRings() are synonyms.\n\nExamples\n--------\n\nSET @poly = \'Polygon((0 0,0 3,3 3,3 0,0 0),(1 1,1 2,2 2,2 1,1 1))\';\n\nSELECT NumInteriorRings(GeomFromText(@poly));\n+---------------------------------------+\n| NumInteriorRings(GeomFromText(@poly)) |\n+---------------------------------------+\n| 1 |\n+---------------------------------------+\n\nNon-overlapping \'polygon\':\n\nSELECT ST_NumInteriorRings(ST_PolyFromText(\'POLYGON((0 0,10 0,10 10,0 10,0 0),\n (-1 -1,-5 -1,-5 -5,-1 -5,-1 -1))\')) AS NumInteriorRings;\n+------------------+\n| NumInteriorRings |\n+------------------+\n| 1 |\n+------------------+\n\nURL: https://mariadb.com/kb/en/st_numinteriorrings/','','https://mariadb.com/kb/en/st_numinteriorrings/'); +insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (13,3,'WKT Definition','Description\n-----------\n\nThe Well-Known Text (WKT) representation of Geometry is designed to exchange\ngeometry data in ASCII form. Examples of the basic geometry types include:\n\n+-----------------------------------------------------------------------------+\n| Geometry Types |\n+-----------------------------------------------------------------------------+\n| POINT |\n+-----------------------------------------------------------------------------+\n| LINESTRING |\n+-----------------------------------------------------------------------------+\n| POLYGON |\n+-----------------------------------------------------------------------------+\n| MULTIPOINT |\n+-----------------------------------------------------------------------------+\n| MULTILINESTRING |\n+-----------------------------------------------------------------------------+\n| MULTIPOLYGON |\n+-----------------------------------------------------------------------------+\n| GEOMETRYCOLLECTION |\n+-----------------------------------------------------------------------------+\n| GEOMETRY |\n+-----------------------------------------------------------------------------+\n\nURL: https://mariadb.com/kb/en/wkt-definition/','','https://mariadb.com/kb/en/wkt-definition/'); +insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (14,3,'AsText','A synonym for ST_AsText().\n\nURL: https://mariadb.com/kb/en/wkt-astext/','','https://mariadb.com/kb/en/wkt-astext/'); +insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (15,3,'AsWKT','A synonym for ST_AsText().\n\nURL: https://mariadb.com/kb/en/wkt-aswkt/','','https://mariadb.com/kb/en/wkt-aswkt/'); +insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (16,3,'GeomCollFromText','A synonym for ST_GeomCollFromText.\n\nURL: https://mariadb.com/kb/en/wkt-geomcollfromtext/','','https://mariadb.com/kb/en/wkt-geomcollfromtext/'); +insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (17,3,'GeometryCollectionFromText','A synonym for ST_GeomCollFromText.\n\nURL: https://mariadb.com/kb/en/geometrycollectionfromtext/','','https://mariadb.com/kb/en/geometrycollectionfromtext/'); +insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (18,3,'GeometryFromText','A synonym for ST_GeomFromText.\n\nURL: https://mariadb.com/kb/en/geometryfromtext/','','https://mariadb.com/kb/en/geometryfromtext/'); +insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (19,3,'GeomFromText','A synonym for ST_GeomFromText.\n\nURL: https://mariadb.com/kb/en/wkt-geomfromtext/','','https://mariadb.com/kb/en/wkt-geomfromtext/'); +insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (20,3,'LineFromText','A synonym for ST_LineFromText.\n\nURL: https://mariadb.com/kb/en/wkt-linefromtext/','','https://mariadb.com/kb/en/wkt-linefromtext/'); +insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (21,3,'LineStringFromText','A synonym for ST_LineFromText.\n\nURL: https://mariadb.com/kb/en/linestringfromtext/','','https://mariadb.com/kb/en/linestringfromtext/'); +insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (22,3,'MLineFromText','Syntax\n------\n\nMLineFromText(wkt[,srid])\nMultiLineStringFromText(wkt[,srid])\n\nDescription\n-----------\n\nConstructs a MULTILINESTRING value using its WKT representation and SRID.\n\nMLineFromText() and MultiLineStringFromText() are synonyms.\n\nExamples\n--------\n\nCREATE TABLE gis_multi_line (g MULTILINESTRING);\nSHOW FIELDS FROM gis_multi_line;\nINSERT INTO gis_multi_line VALUES\n (MultiLineStringFromText(\'MULTILINESTRING((10 48,10 21,10 0),(16 0,16\n23,16 48))\')),\n (MLineFromText(\'MULTILINESTRING((10 48,10 21,10 0))\')),\n (MLineFromWKB(AsWKB(MultiLineString(\n LineString(Point(1, 2), Point(3, 5)),\n LineString(Point(2, 5), Point(5, 8), Point(21, 7))))));\n\nURL: https://mariadb.com/kb/en/mlinefromtext/','','https://mariadb.com/kb/en/mlinefromtext/'); +insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (23,3,'MPointFromText','Syntax\n------\n\nMPointFromText(wkt[,srid])\nMultiPointFromText(wkt[,srid])\n\nDescription\n-----------\n\nConstructs a MULTIPOINT value using its WKT representation and SRID.\n\nMPointFromText() and MultiPointFromText() are synonyms.\n\nExamples\n--------\n\nCREATE TABLE gis_multi_point (g MULTIPOINT);\nSHOW FIELDS FROM gis_multi_point;\nINSERT INTO gis_multi_point VALUES\n (MultiPointFromText(\'MULTIPOINT(0 0,10 10,10 20,20 20)\')),\n (MPointFromText(\'MULTIPOINT(1 1,11 11,11 21,21 21)\')),\n (MPointFromWKB(AsWKB(MultiPoint(Point(3, 6), Point(4, 10)))));\n\nURL: https://mariadb.com/kb/en/mpointfromtext/','','https://mariadb.com/kb/en/mpointfromtext/'); +insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (24,3,'MPolyFromText','Syntax\n------\n\nMPolyFromText(wkt[,srid])\nMultiPolygonFromText(wkt[,srid])\n\nDescription\n-----------\n\nConstructs a MULTIPOLYGON value using its WKT representation and SRID.\n\nMPolyFromText() and MultiPolygonFromText() are synonyms.\n\nExamples\n--------\n\nCREATE TABLE gis_multi_polygon (g MULTIPOLYGON);\nSHOW FIELDS FROM gis_multi_polygon;\nINSERT INTO gis_multi_polygon VALUES\n (MultiPolygonFromText(\'MULTIPOLYGON(\n ((28 26,28 0,84 0,84 42,28 26),(52 18,66 23,73 9,48 6,52 18)),\n ((59 18,67 18,67 13,59 13,59 18)))\')),\n (MPolyFromText(\'MULTIPOLYGON(\n ((28 26,28 0,84 0,84 42,28 26),(52 18,66 23,73 9,48 6,52 18)),\n ((59 18,67 18,67 13,59 13,59 18)))\')),\n (MPolyFromWKB(AsWKB(MultiPolygon(Polygon(\n LineString(Point(0, 3), Point(3, 3), Point(3, 0), Point(0, 3)))))));\n\nURL: https://mariadb.com/kb/en/mpolyfromtext/','','https://mariadb.com/kb/en/mpolyfromtext/'); +insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (25,3,'MultiLineStringFromText','A synonym for MLineFromText.\n\nURL: https://mariadb.com/kb/en/multilinestringfromtext/','','https://mariadb.com/kb/en/multilinestringfromtext/'); +insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (26,3,'MultiPointFromText','A synonym for MPointFromText.\n\nURL: https://mariadb.com/kb/en/multipointfromtext/','','https://mariadb.com/kb/en/multipointfromtext/'); +insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (27,3,'MultiPolygonFromText','A synonym for MPolyFromText.\n\nURL: https://mariadb.com/kb/en/multipolygonfromtext/','','https://mariadb.com/kb/en/multipolygonfromtext/'); +insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (28,3,'PointFromText','A synonym for ST_PointFromText.\n\nURL: https://mariadb.com/kb/en/wkt-pointfromtext/','','https://mariadb.com/kb/en/wkt-pointfromtext/'); +insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (29,3,'PolyFromText','A synonym for ST_PolyFromText.\n\nURL: https://mariadb.com/kb/en/wkt-polyfromtext/','','https://mariadb.com/kb/en/wkt-polyfromtext/'); +insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (30,3,'PolygonFromText','A synonym for ST_PolyFromText.\n\nURL: https://mariadb.com/kb/en/polygonfromtext/','','https://mariadb.com/kb/en/polygonfromtext/'); +insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (31,3,'ST_AsText','Syntax\n------\n\nST_AsText(g)\nAsText(g)\nST_AsWKT(g)\nAsWKT(g)\n\nDescription\n-----------\n\nConverts a value in internal geometry format to its WKT representation and\nreturns the string result.\n\nST_AsText(), AsText(), ST_AsWKT() and AsWKT() are all synonyms.\n\nExamples\n--------\n\nSET @g = \'LineString(1 1,4 4,6 6)\';\n\nSELECT ST_AsText(ST_GeomFromText(@g));\n+--------------------------------+\n| ST_AsText(ST_GeomFromText(@g)) |\n+--------------------------------+\n| LINESTRING(1 1,4 4,6 6) |\n+--------------------------------+\n\nURL: https://mariadb.com/kb/en/st_astext/','','https://mariadb.com/kb/en/st_astext/'); +insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (32,3,'ST_ASWKT','A synonym for ST_ASTEXT().\n\nURL: https://mariadb.com/kb/en/st_aswkt/','','https://mariadb.com/kb/en/st_aswkt/'); +insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (33,3,'ST_GeomCollFromText','Syntax\n------\n\nST_GeomCollFromText(wkt[,srid])\nST_GeometryCollectionFromText(wkt[,srid])\nGeomCollFromText(wkt[,srid])\nGeometryCollectionFromText(wkt[,srid])\n\nDescription\n-----------\n\nConstructs a GEOMETRYCOLLECTION value using its WKT representation and SRID.\n\nST_GeomCollFromText(), ST_GeometryCollectionFromText(), GeomCollFromText() and\nGeometryCollectionFromText() are all synonyms.\n\nExample\n-------\n\nCREATE TABLE gis_geometrycollection (g GEOMETRYCOLLECTION);\nSHOW FIELDS FROM gis_geometrycollection;\nINSERT INTO gis_geometrycollection VALUES\n (GeomCollFromText(\'GEOMETRYCOLLECTION(POINT(0 0), LINESTRING(0 0,10\n10))\')),\n (GeometryFromWKB(AsWKB(GeometryCollection(Point(44, 6),\nLineString(Point(3, 6), Point(7, 9)))))),\n (GeomFromText(\'GeometryCollection()\')),\n (GeomFromText(\'GeometryCollection EMPTY\'));\n\nURL: https://mariadb.com/kb/en/st_geomcollfromtext/','','https://mariadb.com/kb/en/st_geomcollfromtext/'); +insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (34,3,'ST_GeometryCollectionFromText','A synonym for ST_GeomCollFromText.\n\nURL: https://mariadb.com/kb/en/st_geometrycollectionfromtext/','','https://mariadb.com/kb/en/st_geometrycollectionfromtext/'); +insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (35,3,'ST_GeometryFromText','A synonym for ST_GeomFromText.\n\nURL: https://mariadb.com/kb/en/st_geometryfromtext/','','https://mariadb.com/kb/en/st_geometryfromtext/'); +insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (36,3,'ST_GeomFromText','Syntax\n------\n\nST_GeomFromText(wkt[,srid])\nST_GeometryFromText(wkt[,srid])\nGeomFromText(wkt[,srid])\nGeometryFromText(wkt[,srid])\n\nDescription\n-----------\n\nConstructs a geometry value of any type using its WKT representation and SRID.\n\nGeomFromText(), GeometryFromText(), ST_GeomFromText() and\nST_GeometryFromText() are all synonyms.\n\nExample\n-------\n\nSET @g = ST_GEOMFROMTEXT(\'POLYGON((1 1,1 5,4 9,6 9,9 3,7 2,1 1))\');\n\nURL: https://mariadb.com/kb/en/st_geomfromtext/','','https://mariadb.com/kb/en/st_geomfromtext/'); +insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (37,3,'ST_LineFromText','Syntax\n------\n\nST_LineFromText(wkt[,srid])\nST_LineStringFromText(wkt[,srid])\nLineFromText(wkt[,srid])\nLineStringFromText(wkt[,srid])\n\nDescription\n-----------\n\nConstructs a LINESTRING value using its WKT representation and SRID.\n\nST_LineFromText(), ST_LineStringFromText(), ST_LineFromText() and\nST_LineStringFromText() are all synonyms.\n\nExamples\n--------\n\nCREATE TABLE gis_line (g LINESTRING);\nSHOW FIELDS FROM gis_line;\nINSERT INTO gis_line VALUES\n (LineFromText(\'LINESTRING(0 0,0 10,10 0)\')),\n (LineStringFromText(\'LINESTRING(10 10,20 10,20 20,10 20,10 10)\')),\n (LineStringFromWKB(AsWKB(LineString(Point(10, 10), Point(40, 10)))));\n\nURL: https://mariadb.com/kb/en/st_linefromtext/','','https://mariadb.com/kb/en/st_linefromtext/'); +insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (38,3,'ST_LineStringFromText','A synonym for ST_LineFromText.\n\nURL: https://mariadb.com/kb/en/st_linestringfromtext/','','https://mariadb.com/kb/en/st_linestringfromtext/'); +insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (39,3,'ST_PointFromText','Syntax\n------\n\nST_PointFromText(wkt[,srid])\nPointFromText(wkt[,srid])\n\nDescription\n-----------\n\nConstructs a POINT value using its WKT representation and SRID.\n\nST_PointFromText() and PointFromText() are synonyms.\n\nExamples\n--------\n\nCREATE TABLE gis_point (g POINT);\nSHOW FIELDS FROM gis_point;\nINSERT INTO gis_point VALUES\n (PointFromText(\'POINT(10 10)\')),\n (PointFromText(\'POINT(20 10)\')),\n (PointFromText(\'POINT(20 20)\')),\n (PointFromWKB(AsWKB(PointFromText(\'POINT(10 20)\'))));\n\nURL: https://mariadb.com/kb/en/st_pointfromtext/','','https://mariadb.com/kb/en/st_pointfromtext/'); +insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (40,3,'ST_PolyFromText','Syntax\n------\n\nST_PolyFromText(wkt[,srid])\nST_PolygonFromText(wkt[,srid])\nPolyFromText(wkt[,srid])\nPolygonFromText(wkt[,srid])\n\nDescription\n-----------\n\nConstructs a POLYGON value using its WKT representation and SRID.\n\nST_PolyFromText(), ST_PolygonFromText(), PolyFromText() and\nST_PolygonFromText() are all synonyms.\n\nExamples\n--------\n\nCREATE TABLE gis_polygon (g POLYGON);\nINSERT INTO gis_polygon VALUES\n (PolygonFromText(\'POLYGON((10 10,20 10,20 20,10 20,10 10))\')),\n (PolyFromText(\'POLYGON((0 0,50 0,50 50,0 50,0 0), (10 10,20 10,20 20,10\n20,10 10))\'));\n\nURL: https://mariadb.com/kb/en/st_polyfromtext/','','https://mariadb.com/kb/en/st_polyfromtext/'); +insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (41,3,'ST_PolygonFromText','A synonym for ST_PolyFromText.\n\nURL: https://mariadb.com/kb/en/st_polygonfromtext/','','https://mariadb.com/kb/en/st_polygonfromtext/'); +insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (42,4,'DIV','Syntax\n------\n\nDIV\n\nDescription\n-----------\n\nInteger division. Similar to FLOOR(), but is safe with BIGINT values.\nIncorrect results may occur for non-integer operands that exceed BIGINT range.\n\nIf the ERROR_ON_DIVISION_BY_ZERO SQL_MODE is used, a division by zero produces\nan error. Otherwise, it returns NULL.\n\nThe remainder of a division can be obtained using the MOD operator.\n\nExamples\n--------\n\nSELECT 300 DIV 7;\n+-----------+\n| 300 DIV 7 |\n+-----------+\n| 42 |\n+-----------+\n\nSELECT 300 DIV 0;\n+-----------+\n| 300 DIV 0 |\n+-----------+\n| NULL |\n+-----------+\n\nURL: https://mariadb.com/kb/en/div/','','https://mariadb.com/kb/en/div/'); +insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (43,4,'ABS','Syntax\n------\n\nABS(X)\n\nDescription\n-----------\n\nReturns the absolute (non-negative) value of X. If X is not a number, it is\nconverted to a numeric type.\n\nExamples\n--------\n\nSELECT ABS(42);\n+---------+\n| ABS(42) |\n+---------+\n| 42 |\n+---------+\n\nSELECT ABS(-42);\n+----------+\n| ABS(-42) |\n+----------+\n| 42 |\n+----------+\n\nSELECT ABS(DATE \'1994-01-01\');\n+------------------------+\n| ABS(DATE \'1994-01-01\') |\n+------------------------+\n| 19940101 |\n+------------------------+\n\nURL: https://mariadb.com/kb/en/abs/','','https://mariadb.com/kb/en/abs/'); +insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (44,4,'ACOS','Syntax\n------\n\nACOS(X)\n\nDescription\n-----------\n\nReturns the arc cosine of X, that is, the value whose cosine is X. Returns\nNULL if X is not in the range -1 to 1.\n\nExamples\n--------\n\nSELECT ACOS(1);\n+---------+\n| ACOS(1) |\n+---------+\n| 0 |\n+---------+\n\nSELECT ACOS(1.0001);\n+--------------+\n| ACOS(1.0001) |\n+--------------+\n| NULL |\n+--------------+\n\nSELECT ACOS(0);\n+-----------------+\n| ACOS(0) |\n+-----------------+\n| 1.5707963267949 |\n+-----------------+\n\nSELECT ACOS(0.234);\n+------------------+\n| ACOS(0.234) |\n+------------------+\n| 1.33460644244679 |\n+------------------+\n\nURL: https://mariadb.com/kb/en/acos/','','https://mariadb.com/kb/en/acos/'); +insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (45,4,'ASIN','Syntax\n------\n\nASIN(X)\n\nDescription\n-----------\n\nReturns the arc sine of X, that is, the value whose sine is X. Returns NULL if\nX is not in the range -1 to 1.\n\nExamples\n--------\n\nSELECT ASIN(0.2);\n+--------------------+\n| ASIN(0.2) |\n+--------------------+\n| 0.2013579207903308 |\n+--------------------+\n\nSELECT ASIN(\'foo\');\n+-------------+\n| ASIN(\'foo\') |\n+-------------+\n| 0 |\n+-------------+\n\nSHOW WARNINGS;\n+---------+------+-----------------------------------------+\n| Level | Code | Message |\n+---------+------+-----------------------------------------+\n| Warning | 1292 | Truncated incorrect DOUBLE value: \'foo\' |\n+---------+------+-----------------------------------------+\n\nURL: https://mariadb.com/kb/en/asin/','','https://mariadb.com/kb/en/asin/'); +insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (46,4,'ATAN','Syntax\n------\n\nATAN(X)\n\nDescription\n-----------\n\nReturns the arc tangent of X, that is, the value whose tangent is X.\n\nExamples\n--------\n\nSELECT ATAN(2);\n+--------------------+\n| ATAN(2) |\n+--------------------+\n| 1.1071487177940904 |\n+--------------------+\n\nSELECT ATAN(-2);\n+---------------------+\n| ATAN(-2) |\n+---------------------+\n| -1.1071487177940904 |\n+---------------------+\n\nURL: https://mariadb.com/kb/en/atan/','','https://mariadb.com/kb/en/atan/'); +insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (47,4,'ATAN2','Syntax\n------\n\nATAN(Y,X), ATAN2(Y,X)\n\nDescription\n-----------\n\nReturns the arc tangent of the two variables X and Y. It is similar to\ncalculating the arc tangent of Y / X, except that the signs of both arguments\nare used to determine the quadrant of the result.\n\nExamples\n--------\n\nSELECT ATAN(-2,2);\n+---------------------+\n| ATAN(-2,2) |\n+---------------------+\n| -0.7853981633974483 |\n+---------------------+\n\nSELECT ATAN2(PI(),0);\n+--------------------+\n| ATAN2(PI(),0) |\n+--------------------+\n| 1.5707963267948966 |\n+--------------------+\n\nURL: https://mariadb.com/kb/en/atan2/','','https://mariadb.com/kb/en/atan2/'); +insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (48,4,'CEIL','Syntax\n------\n\nCEIL(X)\n\nDescription\n-----------\n\nCEIL() is a synonym for CEILING().\n\nURL: https://mariadb.com/kb/en/ceil/','','https://mariadb.com/kb/en/ceil/'); +insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (49,4,'CEILING','Syntax\n------\n\nCEILING(X)\n\nDescription\n-----------\n\nReturns the smallest integer value not less than X.\n\nExamples\n--------\n\nSELECT CEILING(1.23);\n+---------------+\n| CEILING(1.23) |\n+---------------+\n| 2 |\n+---------------+\n\nSELECT CEILING(-1.23);\n+----------------+\n| CEILING(-1.23) |\n+----------------+\n| -1 |\n+----------------+\n\nURL: https://mariadb.com/kb/en/ceiling/','','https://mariadb.com/kb/en/ceiling/'); +insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (50,4,'CONV','Syntax\n------\n\nCONV(N,from_base,to_base)\n\nDescription\n-----------\n\nConverts numbers between different number bases. Returns a string\nrepresentation of the number N, converted from base from_base to base to_base.\n\nReturns NULL if any argument is NULL, or if the second or third argument are\nnot in the allowed range.\n\nThe argument N is interpreted as an integer, but may be specified as an\ninteger or a string. The minimum base is 2 and the maximum base is 36. If\nto_base is a negative number, N is regarded as a signed number. Otherwise, N\nis treated as unsigned. CONV() works with 64-bit precision.\n\nSome shortcuts for this function are also available: BIN(), OCT(), HEX(),\nUNHEX(). Also, MariaDB allows binary literal values and hexadecimal literal\nvalues.\n\nExamples\n--------\n\nSELECT CONV(\'a\',16,2);\n+----------------+\n| CONV(\'a\',16,2) |\n+----------------+\n| 1010 |\n+----------------+\n\nSELECT CONV(\'6E\',18,8);\n+-----------------+\n| CONV(\'6E\',18,8) |\n+-----------------+\n| 172 |\n+-----------------+\n\nSELECT CONV(-17,10,-18);\n+------------------+\n| CONV(-17,10,-18) |\n+------------------+\n| -H |\n+------------------+\n\nSELECT CONV(12+\'10\'+\'10\'+0xa,10,10);\n+------------------------------+\n| CONV(12+\'10\'+\'10\'+0xa,10,10) |\n+------------------------------+\n| 42 |\n+------------------------------+\n\nURL: https://mariadb.com/kb/en/conv/','','https://mariadb.com/kb/en/conv/'); +insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (51,4,'COS','Syntax\n------\n\nCOS(X)\n\nDescription\n-----------\n\nReturns the cosine of X, where X is given in radians.\n\nExamples\n--------\n\nSELECT COS(PI());\n+-----------+\n| COS(PI()) |\n+-----------+\n| -1 |\n+-----------+\n\nURL: https://mariadb.com/kb/en/cos/','','https://mariadb.com/kb/en/cos/'); +insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (52,4,'COT','Syntax\n------\n\nCOT(X)\n\nDescription\n-----------\n\nReturns the cotangent of X.\n\nExamples\n--------\n\nSELECT COT(42);\n+--------------------+\n| COT(42) |\n+--------------------+\n| 0.4364167060752729 |\n+--------------------+\n\nSELECT COT(12);\n+---------------------+\n| COT(12) |\n+---------------------+\n| -1.5726734063976893 |\n+---------------------+\n\nSELECT COT(0);\nERROR 1690 (22003): DOUBLE value is out of range in \'cot(0)\'\n\nURL: https://mariadb.com/kb/en/cot/','','https://mariadb.com/kb/en/cot/'); +insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (53,4,'CRC32','Syntax\n------\n\n<= MariaDB 10.7\n\nCRC32(expr)\n\nFrom MariaDB 10.8\n\nCRC32([par,]expr)\n\nDescription\n-----------\n\nComputes a cyclic redundancy check (CRC) value and returns a 32-bit unsigned\nvalue. The result is NULL if the argument is NULL. The argument is expected to\nbe a string and (if possible) is treated as one if it is not.\n\nUses the ISO 3309 polynomial that used by zlib and many others. MariaDB 10.8\nintroduced the CRC32C() function, which uses the alternate Castagnoli\npolynomia.\n\nMariaDB starting with 10.8\n--------------------------\nOften, CRC is computed in pieces. To facilitate this, MariaDB 10.8.0\nintroduced an optional parameter: CRC32(\'MariaDB\')=CRC32(CRC32(\'Maria\'),\'DB\').\n\nExamples\n--------\n\nSELECT CRC32(\'MariaDB\');\n+------------------+\n| CRC32(\'MariaDB\') |\n+------------------+\n| 4227209140 |\n+------------------+\n\nSELECT CRC32(\'mariadb\');\n+------------------+\n| CRC32(\'mariadb\') |\n+------------------+\n| 2594253378 |\n+------------------+\n\nFrom MariaDB 10.8.0\n\nSELECT CRC32(CRC32(\'Maria\'),\'DB\');\n+----------------------------+\n| CRC32(CRC32(\'Maria\'),\'DB\') |\n+----------------------------+\n| 4227209140 |\n+----------------------------+\n\nURL: https://mariadb.com/kb/en/crc32/','','https://mariadb.com/kb/en/crc32/'); +insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (54,4,'DEGREES','Syntax\n------\n\nDEGREES(X)\n\nDescription\n-----------\n\nReturns the argument X, converted from radians to degrees.\n\nThis is the converse of the RADIANS() function.\n\nExamples\n--------\n\nSELECT DEGREES(PI());\n+---------------+\n| DEGREES(PI()) |\n+---------------+\n| 180 |\n+---------------+\n\nSELECT DEGREES(PI() / 2);\n+-------------------+\n| DEGREES(PI() / 2) |\n+-------------------+\n| 90 |\n+-------------------+\n\nSELECT DEGREES(45);\n+-----------------+\n| DEGREES(45) |\n+-----------------+\n| 2578.3100780887 |\n+-----------------+\n\nURL: https://mariadb.com/kb/en/degrees/','','https://mariadb.com/kb/en/degrees/'); +insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (55,4,'EXP','Syntax\n------\n\nEXP(X)\n\nDescription\n-----------\n\nReturns the value of e (the base of natural logarithms) raised to the power of\nX. The inverse of this function is LOG() (using a single argument only) or\nLN().\n\nIf X is NULL, this function returns NULL.\n\nExamples\n--------\n\nSELECT EXP(2);\n+------------------+\n| EXP(2) |\n+------------------+\n| 7.38905609893065 |\n+------------------+\n\nSELECT EXP(-2);\n+--------------------+\n| EXP(-2) |\n+--------------------+\n| 0.1353352832366127 |\n+--------------------+\n\nSELECT EXP(0);\n+--------+\n| EXP(0) |\n+--------+\n| 1 |\n+--------+\n\nSELECT EXP(NULL);\n+-----------+\n| EXP(NULL) |\n+-----------+\n| NULL |\n+-----------+\n\nURL: https://mariadb.com/kb/en/exp/','','https://mariadb.com/kb/en/exp/'); +insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (56,4,'FLOOR','Syntax\n------\n\nFLOOR(X)\n\nDescription\n-----------\n\nReturns the largest integer value not greater than X.\n\nExamples\n--------\n\nSELECT FLOOR(1.23);\n+-------------+\n| FLOOR(1.23) |\n+-------------+\n| 1 |\n+-------------+\n\nSELECT FLOOR(-1.23);\n+--------------+\n| FLOOR(-1.23) |\n+--------------+\n| -2 |\n+--------------+\n\nURL: https://mariadb.com/kb/en/floor/','','https://mariadb.com/kb/en/floor/'); +insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (57,4,'LN','Syntax\n------\n\nLN(X)\n\nDescription\n-----------\n\nReturns the natural logarithm of X; that is, the base-e logarithm of X. If X\nis less than or equal to 0, or NULL, then NULL is returned.\n\nThe inverse of this function is EXP().\n\nExamples\n--------\n\nSELECT LN(2);\n+-------------------+\n| LN(2) |\n+-------------------+\n| 0.693147180559945 |\n+-------------------+\n\nSELECT LN(-2);\n+--------+\n| LN(-2) |\n+--------+\n| NULL |\n+--------+\n\nURL: https://mariadb.com/kb/en/ln/','','https://mariadb.com/kb/en/ln/'); +insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (58,4,'LOG','Syntax\n------\n\nLOG(X), LOG(B,X)\n\nDescription\n-----------\n\nIf called with one parameter, this function returns the natural logarithm of\nX. If X is less than or equal to 0, then NULL is returned.\n\nIf called with two parameters, it returns the logarithm of X to the base B. If\nB is <= 1 or X <= 0, the function returns NULL.\n\nIf any argument is NULL, the function returns NULL.\n\nThe inverse of this function (when called with a single argument) is the EXP()\nfunction.\n\nExamples\n--------\n\nLOG(X):\n\nSELECT LOG(2);\n+-------------------+\n| LOG(2) |\n+-------------------+\n| 0.693147180559945 |\n+-------------------+\n\nSELECT LOG(-2);\n+---------+\n| LOG(-2) |\n+---------+\n| NULL |\n+---------+\n\nLOG(B,X)\n\nSELECT LOG(2,16);\n+-----------+\n| LOG(2,16) |\n+-----------+\n| 4 |\n+-----------+\n\nSELECT LOG(3,27);\n+-----------+\n| LOG(3,27) |\n+-----------+\n| 3 |\n+-----------+\n\nSELECT LOG(3,1);\n+----------+\n| LOG(3,1) |\n+----------+\n| 0 |\n+----------+\n\nSELECT LOG(3,0);\n+----------+\n| LOG(3,0) |\n+----------+\n| NULL |\n+----------+\n\nURL: https://mariadb.com/kb/en/log/','','https://mariadb.com/kb/en/log/'); +insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (59,4,'LOG10','Syntax\n------\n\nLOG10(X)\n\nDescription\n-----------\n\nReturns the base-10 logarithm of X.\n\nExamples\n--------\n\nSELECT LOG10(2);\n+-------------------+\n| LOG10(2) |\n+-------------------+\n| 0.301029995663981 |\n+-------------------+\n\nSELECT LOG10(100);\n+------------+\n| LOG10(100) |\n+------------+\n| 2 |\n+------------+\n\nSELECT LOG10(-100);\n+-------------+\n| LOG10(-100) |\n+-------------+\n| NULL |\n+-------------+\n\nURL: https://mariadb.com/kb/en/log10/','','https://mariadb.com/kb/en/log10/'); +insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (60,4,'LOG2','Syntax\n------\n\nLOG2(X)\n\nDescription\n-----------\n\nReturns the base-2 logarithm of X.\n\nExamples\n--------\n\nSELECT LOG2(4398046511104);\n+---------------------+\n| LOG2(4398046511104) |\n+---------------------+\n| 42 |\n+---------------------+\n\nSELECT LOG2(65536);\n+-------------+\n| LOG2(65536) |\n+-------------+\n| 16 |\n+-------------+\n\nSELECT LOG2(-100);\n+------------+\n| LOG2(-100) |\n+------------+\n| NULL |\n+------------+\n\nURL: https://mariadb.com/kb/en/log2/','','https://mariadb.com/kb/en/log2/'); +insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (61,4,'MOD','Syntax\n------\n\nMOD(N,M), N % M, N MOD M\n\nDescription\n-----------\n\nModulo operation. Returns the remainder of N divided by M. See also Modulo\nOperator.\n\nIf the ERROR_ON_DIVISION_BY_ZERO SQL_MODE is used, any number modulus zero\nproduces an error. Otherwise, it returns NULL.\n\nThe integer part of a division can be obtained using DIV.\n\nExamples\n--------\n\nSELECT 1042 % 50;\n+-----------+\n| 1042 % 50 |\n+-----------+\n| 42 |\n+-----------+\n\nSELECT MOD(234, 10);\n+--------------+\n| MOD(234, 10) |\n+--------------+\n| 4 |\n+--------------+\n\nSELECT 253 % 7;\n+---------+\n| 253 % 7 |\n+---------+\n| 1 |\n+---------+\n\nSELECT MOD(29,9);\n+-----------+\n| MOD(29,9) |\n+-----------+\n| 2 |\n+-----------+\n\nSELECT 29 MOD 9;\n+----------+\n| 29 MOD 9 |\n+----------+\n| 2 |\n+----------+\n\nURL: https://mariadb.com/kb/en/mod/','','https://mariadb.com/kb/en/mod/'); +insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (62,4,'OCT','Syntax\n------\n\nOCT(N)\n\nDescription\n-----------\n\nReturns a string representation of the octal value of N, where N is a longlong\n(BIGINT) number. This is equivalent to CONV(N,10,8). Returns NULL if N is NULL.\n\nExamples\n--------\n\nSELECT OCT(34);\n+---------+\n| OCT(34) |\n+---------+\n| 42 |\n+---------+\n\nSELECT OCT(12);\n+---------+\n| OCT(12) |\n+---------+\n| 14 |\n+---------+\n\nURL: https://mariadb.com/kb/en/oct/','','https://mariadb.com/kb/en/oct/'); +insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (63,4,'PI','Syntax\n------\n\nPI()\n\nDescription\n-----------\n\nReturns the value of π (pi). The default number of decimal places displayed is\nsix, but MariaDB uses the full double-precision value internally.\n\nExamples\n--------\n\nSELECT PI();\n+----------+\n| PI() |\n+----------+\n| 3.141593 |\n+----------+\n\nSELECT PI()+0.0000000000000000000000;\n+-------------------------------+\n| PI()+0.0000000000000000000000 |\n+-------------------------------+\n| 3.1415926535897931159980 |\n+-------------------------------+\n\nURL: https://mariadb.com/kb/en/pi/','','https://mariadb.com/kb/en/pi/'); +insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (64,4,'POW','Syntax\n------\n\nPOW(X,Y)\n\nDescription\n-----------\n\nReturns the value of X raised to the power of Y.\n\nPOWER() is a synonym.\n\nExamples\n--------\n\nSELECT POW(2,3);\n+----------+\n| POW(2,3) |\n+----------+\n| 8 |\n+----------+\n\nSELECT POW(2,-2);\n+-----------+\n| POW(2,-2) |\n+-----------+\n| 0.25 |\n+-----------+\n\nURL: https://mariadb.com/kb/en/pow/','','https://mariadb.com/kb/en/pow/'); +insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (65,4,'POWER','Syntax\n------\n\nPOWER(X,Y)\n\nDescription\n-----------\n\nThis is a synonym for POW(), which returns the value of X raised to the power\nof Y.\n\nURL: https://mariadb.com/kb/en/power/','','https://mariadb.com/kb/en/power/'); +insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (66,4,'RADIANS','Syntax\n------\n\nRADIANS(X)\n\nDescription\n-----------\n\nReturns the argument X, converted from degrees to radians. Note that π radians\nequals 180 degrees.\n\nThis is the converse of the DEGREES() function.\n\nExamples\n--------\n\nSELECT RADIANS(45);\n+-------------------+\n| RADIANS(45) |\n+-------------------+\n| 0.785398163397448 |\n+-------------------+\n\nSELECT RADIANS(90);\n+-----------------+\n| RADIANS(90) |\n+-----------------+\n| 1.5707963267949 |\n+-----------------+\n\nSELECT RADIANS(PI());\n+--------------------+\n| RADIANS(PI()) |\n+--------------------+\n| 0.0548311355616075 |\n+--------------------+\n\nSELECT RADIANS(180);\n+------------------+\n| RADIANS(180) |\n+------------------+\n| 3.14159265358979 |\n+------------------+\n\nURL: https://mariadb.com/kb/en/radians/','','https://mariadb.com/kb/en/radians/'); +insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (67,4,'RAND','Syntax\n------\n\nRAND(), RAND(N)\n\nDescription\n-----------\n\nReturns a random DOUBLE precision floating point value v in the range 0 <= v <\n1.0. If a constant integer argument N is specified, it is used as the seed\nvalue, which produces a repeatable sequence of column values. In the example\nbelow, note that the sequences of values produced by RAND(3) is the same both\nplaces where it occurs.\n\nIn a WHERE clause, RAND() is evaluated each time the WHERE is executed.\n\nStatements using the RAND() function are not safe for statement-based\nreplication.\n\nPractical uses\n--------------\n\nThe expression to get a random integer from a given range is the following:\n\nFLOOR(min_value + RAND() * (max_value - min_value +1))\n\nRAND() is often used to read random rows from a table, as follows:\n\nSELECT * FROM my_table ORDER BY RAND() LIMIT 10;\n\nNote, however, that this technique should never be used on a large table as it\nwill be extremely slow. MariaDB will read all rows in the table, generate a\nrandom value for each of them, order them, and finally will apply the LIMIT\nclause.\n\nExamples\n--------\n\nCREATE TABLE t (i INT);\n\nINSERT INTO t VALUES(1),(2),(3);\n\nSELECT i, RAND() FROM t;\n+------+-------------------+\n| i | RAND() |\n+------+-------------------+\n| 1 | 0.255651095188829 |\n| 2 | 0.833920199269355 |\n| 3 | 0.40264774151393 |\n+------+-------------------+\n\nSELECT i, RAND(3) FROM t;\n+------+-------------------+\n| i | RAND(3) |\n+------+-------------------+\n| 1 | 0.90576975597606 |\n| 2 | 0.373079058130345 |\n| 3 | 0.148086053457191 |\n+------+-------------------+\n\nSELECT i, RAND() FROM t;\n+------+-------------------+\n| i | RAND() |\n+------+-------------------+\n| 1 | 0.511478140495232 |\n| 2 | 0.349447508668012 |\n| 3 | 0.212803152588013 |\n+------+-------------------+\n\nUsing the same seed, the same sequence will be returned:\n\nSELECT i, RAND(3) FROM t;\n+------+-------------------+\n| i | RAND(3) |\n+------+-------------------+\n| 1 | 0.90576975597606 |\n| 2 | 0.373079058130345 |\n| 3 | 0.148086053457191 |\n+------+-------------------+\n\nGenerating a random number from 5 to 15:\n\nSELECT FLOOR(5 + (RAND() * 11));\n\nURL: https://mariadb.com/kb/en/rand/','','https://mariadb.com/kb/en/rand/'); +insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (68,4,'ROUND','Syntax\n------\n\nROUND(X), ROUND(X,D)\n\nDescription\n-----------\n\nRounds the argument X to D decimal places. The rounding algorithm depends on\nthe data type of X. D defaults to 0 if not specified. D can be negative to\ncause D digits left of the decimal point of the value X to become zero.\n\nExamples\n--------\n\nSELECT ROUND(-1.23);\n+--------------+\n| ROUND(-1.23) |\n+--------------+\n| -1 |\n+--------------+\n\nSELECT ROUND(-1.58);\n+--------------+\n| ROUND(-1.58) |\n+--------------+\n| -2 |\n+--------------+\n\nSELECT ROUND(1.58); \n+-------------+\n| ROUND(1.58) |\n+-------------+\n| 2 |\n+-------------+\n\nSELECT ROUND(1.298, 1);\n+-----------------+\n| ROUND(1.298, 1) |\n+-----------------+\n| 1.3 |\n+-----------------+\n\nSELECT ROUND(1.298, 0);\n+-----------------+\n| ROUND(1.298, 0) |\n+-----------------+\n| 1 |\n+-----------------+\n\nSELECT ROUND(23.298, -1);\n+-------------------+\n| ROUND(23.298, -1) |\n+-------------------+\n| 20 |\n+-------------------+\n\nURL: https://mariadb.com/kb/en/round/','','https://mariadb.com/kb/en/round/'); +insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (69,4,'SIGN','Syntax\n------\n\nSIGN(X)\n\nDescription\n-----------\n\nReturns the sign of the argument as -1, 0, or 1, depending on whether X is\nnegative, zero, or positive.\n\nExamples\n--------\n\nSELECT SIGN(-32);\n+-----------+\n| SIGN(-32) |\n+-----------+\n| -1 |\n+-----------+\n\nSELECT SIGN(0);\n+---------+\n| SIGN(0) |\n+---------+\n| 0 |\n+---------+\n\nSELECT SIGN(234);\n+-----------+\n| SIGN(234) |\n+-----------+\n| 1 |\n+-----------+\n\nURL: https://mariadb.com/kb/en/sign/','','https://mariadb.com/kb/en/sign/'); +insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (70,4,'SIN','Syntax\n------\n\nSIN(X)\n\nDescription\n-----------\n\nReturns the sine of X, where X is given in radians.\n\nExamples\n--------\n\nSELECT SIN(1.5707963267948966);\n+-------------------------+\n| SIN(1.5707963267948966) |\n+-------------------------+\n| 1 |\n+-------------------------+\n\nSELECT SIN(PI());\n+----------------------+\n| SIN(PI()) |\n+----------------------+\n| 1.22460635382238e-16 |\n+----------------------+\n\nSELECT ROUND(SIN(PI()));\n+------------------+\n| ROUND(SIN(PI())) |\n+------------------+\n| 0 |\n+------------------+\n\nURL: https://mariadb.com/kb/en/sin/','','https://mariadb.com/kb/en/sin/'); +insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (71,4,'SQRT','Syntax\n------\n\nSQRT(X)\n\nDescription\n-----------\n\nReturns the square root of X. If X is negative, NULL is returned.\n\nExamples\n--------\n\nSELECT SQRT(4);\n+---------+\n| SQRT(4) |\n+---------+\n| 2 |\n+---------+\n\nSELECT SQRT(20);\n+------------------+\n| SQRT(20) |\n+------------------+\n| 4.47213595499958 |\n+------------------+\n\nSELECT SQRT(-16);\n+-----------+\n| SQRT(-16) |\n+-----------+\n| NULL |\n+-----------+\n\nSELECT SQRT(1764);\n+------------+\n| SQRT(1764) |\n+------------+\n| 42 |\n+------------+\n\nURL: https://mariadb.com/kb/en/sqrt/','','https://mariadb.com/kb/en/sqrt/'); +insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (72,4,'TAN','Syntax\n------\n\nTAN(X)\n\nDescription\n-----------\n\nReturns the tangent of X, where X is given in radians.\n\nExamples\n--------\n\nSELECT TAN(0.7853981633974483);\n+-------------------------+\n| TAN(0.7853981633974483) |\n+-------------------------+\n| 0.9999999999999999 |\n+-------------------------+\n\nSELECT TAN(PI());\n+-----------------------+\n| TAN(PI()) |\n+-----------------------+\n| -1.22460635382238e-16 |\n+-----------------------+\n\nSELECT TAN(PI()+1);\n+-----------------+\n| TAN(PI()+1) |\n+-----------------+\n| 1.5574077246549 |\n+-----------------+\n\nSELECT TAN(RADIANS(PI()));\n+--------------------+\n| TAN(RADIANS(PI())) |\n+--------------------+\n| 0.0548861508080033 |\n+--------------------+\n\nURL: https://mariadb.com/kb/en/tan/','','https://mariadb.com/kb/en/tan/'); +insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (73,4,'TRUNCATE','This page documents the TRUNCATE function. See TRUNCATE TABLE for the DDL\nstatement.\n\nSyntax\n------\n\nTRUNCATE(X,D)\n\nDescription\n-----------\n\nReturns the number X, truncated to D decimal places. If D is 0, the result has\nno decimal point or fractional part. D can be negative to cause D digits left\nof the decimal point of the value X to become zero.\n\nExamples\n--------\n\nSELECT TRUNCATE(1.223,1);\n+-------------------+\n| TRUNCATE(1.223,1) |\n+-------------------+\n| 1.2 |\n+-------------------+\n\nSELECT TRUNCATE(1.999,1);\n+-------------------+\n| TRUNCATE(1.999,1) |\n+-------------------+\n| 1.9 |\n+-------------------+\n\nSELECT TRUNCATE(1.999,0); \n+-------------------+\n| TRUNCATE(1.999,0) |\n+-------------------+\n| 1 |\n+-------------------+\n\nSELECT TRUNCATE(-1.999,1);\n+--------------------+\n| TRUNCATE(-1.999,1) |\n+--------------------+\n| -1.9 |\n+--------------------+\n\nSELECT TRUNCATE(122,-2);\n+------------------+\n| TRUNCATE(122,-2) |\n+------------------+\n| 100 |\n+------------------+\n\nSELECT TRUNCATE(10.28*100,0);\n+-----------------------+\n| TRUNCATE(10.28*100,0) |\n+-----------------------+\n| 1028 |\n+-----------------------+\n\nURL: https://mariadb.com/kb/en/truncate/','','https://mariadb.com/kb/en/truncate/'); +insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (74,5,'INSTALL PLUGIN','Syntax\n------\n\nINSTALL PLUGIN [IF NOT EXISTS] plugin_name SONAME \'plugin_library\'\n\nDescription\n-----------\n\nThis statement installs an individual plugin from the specified library. To\ninstall the whole library (which could be required), use INSTALL SONAME. See\nalso Installing a Plugin.\n\nplugin_name is the name of the plugin as defined in the plugin declaration\nstructure contained in the library file. Plugin names are not case sensitive.\nFor maximal compatibility, plugin names should be limited to ASCII letters,\ndigits, and underscore, because they are used in C source files, shell command\nlines, M4 and Bourne shell scripts, and SQL environments.\n\nplugin_library is the name of the shared library that contains the plugin\ncode. The file name extension can be omitted (which makes the statement look\nthe same on all architectures).\n\nThe shared library must be located in the plugin directory (that is, the\ndirectory named by the plugin_dir system variable). The library must be in the\nplugin directory itself, not in a subdirectory. By default, plugin_dir is\nplugin directory under the directory named by the pkglibdir configuration\nvariable, but it can be changed by setting the value of plugin_dir at server\nstartup. For example, set its value in a my.cnf file:\n\n[mysqld]\nplugin_dir=/path/to/plugin/directory\nIf the value of plugin_dir is a relative path name, it is taken to be relative\nto the MySQL base directory (the value of the basedir system variable).\n\nINSTALL PLUGIN adds a line to the mysql.plugin table that describes the\nplugin. This table contains the plugin name and library file name.\n\nINSTALL PLUGIN causes the server to read option (my.cnf) files just as during\nserver startup. This enables the plugin to pick up any relevant options from\nthose files. It is possible to add plugin options to an option file even\nbefore loading a plugin (if the loose prefix is used). It is also possible to\nuninstall a plugin, edit my.cnf, and install the plugin again. Restarting the\nplugin this way enables it to the new option values without a server restart.\n\nINSTALL PLUGIN also loads and initializes the plugin code to make the plugin\navailable for use. A plugin is initialized by executing its initialization\nfunction, which handles any setup that the plugin must perform before it can\nbe used.\n\nTo use INSTALL PLUGIN, you must have the INSERT privilege for the mysql.plugin\ntable.\n\nAt server startup, the server loads and initializes any plugin that is listed\nin the mysql.plugin table. This means that a plugin is installed with INSTALL\nPLUGIN only once, not every time the server starts. Plugin loading at startup\ndoes not occur if the server is started with the --skip-grant-tables option.\n\nWhen the server shuts down, it executes the de-initialization function for\neach plugin that is loaded so that the plugin has a chance to perform any\nfinal cleanup.\n\nIf you need to load plugins for a single server startup when the\n--skip-grant-tables option is given (which tells the server not to read system\ntables), use the --plugin-load mysqld option.\n\nMariaDB starting with 10.4.0\n----------------------------\n\nIF NOT EXISTS\n-------------\n\nWhen the IF NOT EXISTS clause is used, MariaDB will return a note instead of\nan error if the specified plugin already exists. See SHOW WARNINGS.\n\nExamples\n--------\n\nINSTALL PLUGIN sphinx SONAME \'ha_sphinx.so\';\n\nThe extension can also be omitted:\n\nINSTALL PLUGIN innodb SONAME \'ha_xtradb\';\n\nFrom MariaDB 10.4.0:\n\nINSTALL PLUGIN IF NOT EXISTS example SONAME \'ha_example\';\nQuery OK, 0 rows affected (0.104 sec)\n\nINSTALL PLUGIN IF NOT EXISTS example SONAME \'ha_example\';\nQuery OK, 0 rows affected, 1 warning (0.000 sec)\n\nSHOW WARNINGS;\n+-------+------+------------------------------------+\n| Level | Code | Message |\n+-------+------+------------------------------------+\n| Note | 1968 | Plugin \'example\' already installed |\n+-------+------+------------------------------------+\n\nURL: https://mariadb.com/kb/en/install-plugin/','','https://mariadb.com/kb/en/install-plugin/'); +insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (75,5,'UNINSTALL PLUGIN','Syntax\n------\n\nUNINSTALL PLUGIN [IF EXISTS] plugin_name\n\nDescription\n-----------\n\nThis statement removes a single installed plugin. To uninstall the whole\nlibrary which contains the plugin, use UNINSTALL SONAME. You cannot uninstall\na plugin if any table that uses it is open.\n\nplugin_name must be the name of some plugin that is listed in the mysql.plugin\ntable. The server executes the plugin\'s deinitialization function and removes\nthe row for the plugin from the mysql.plugin table, so that subsequent server\nrestarts will not load and initialize the plugin. UNINSTALL PLUGIN does not\nremove the plugin\'s shared library file.\n\nTo use UNINSTALL PLUGIN, you must have the DELETE privilege for the\nmysql.plugin table.\n\nMariaDB starting with 10.4.0\n----------------------------\n\nIF EXISTS\n---------\n\nIf the IF EXISTS clause is used, MariaDB will return a note instead of an\nerror if the plugin does not exist. See SHOW WARNINGS.\n\nExamples\n--------\n\nUNINSTALL PLUGIN example;\n\nFrom MariaDB 10.4.0:\n\nUNINSTALL PLUGIN IF EXISTS example;\nQuery OK, 0 rows affected (0.099 sec)\n\nUNINSTALL PLUGIN IF EXISTS example;\nQuery OK, 0 rows affected, 1 warning (0.000 sec)\n\nSHOW WARNINGS;\n+-------+------+-------------------------------+\n| Level | Code | Message |\n+-------+------+-------------------------------+\n| Note | 1305 | PLUGIN example does not exist |\n+-------+------+-------------------------------+\n\nURL: https://mariadb.com/kb/en/uninstall-plugin/','','https://mariadb.com/kb/en/uninstall-plugin/'); +insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (76,5,'INSTALL SONAME','Syntax\n------\n\nINSTALL SONAME \'plugin_library\'\n\nDescription\n-----------\n\nThis statement is a variant of INSTALL PLUGIN. It installs all plugins from a\ngiven plugin_library. See INSTALL PLUGIN for details.\n\nplugin_library is the name of the shared library that contains the plugin\ncode. The file name extension (for example, libmyplugin.so or libmyplugin.dll)\ncan be omitted (which makes the statement look the same on all architectures).\n\nThe shared library must be located in the plugin directory (that is, the\ndirectory named by the plugin_dir system variable). The library must be in the\nplugin directory itself, not in a subdirectory. By default, plugin_dir is\nplugin directory under the directory named by the pkglibdir configuration\nvariable, but it can be changed by setting the value of plugin_dir at server\nstartup. For example, set its value in a my.cnf file:\n\n[mysqld]\nplugin_dir=/path/to/plugin/directory\nIf the value of plugin_dir is a relative path name, it is taken to be relative\nto the MySQL base directory (the value of the basedir system variable).\n\nINSTALL SONAME adds one or more lines to the mysql.plugin table that describes\nthe plugin. This table contains the plugin name and library file name.\n\nINSTALL SONAME causes the server to read option (my.cnf) files just as during\nserver startup. This enables the plugin to pick up any relevant options from\nthose files. It is possible to add plugin options to an option file even\nbefore loading a plugin (if the loose prefix is used). It is also possible to\nuninstall a plugin, edit my.cnf, and install the plugin again. Restarting the\nplugin this way enables it to the new option values without a server restart.\n\nINSTALL SONAME also loads and initializes the plugin code to make the plugin\navailable for use. A plugin is initialized by executing its initialization\nfunction, which handles any setup that the plugin must perform before it can\nbe used.\n\nTo use INSTALL SONAME, you must have the INSERT privilege for the mysql.plugin\ntable.\n\nAt server startup, the server loads and initializes any plugin that is listed\nin the mysql.plugin table. This means that a plugin is installed with INSTALL\nSONAME only once, not every time the server starts. Plugin loading at startup\ndoes not occur if the server is started with the --skip-grant-tables option.\n\nWhen the server shuts down, it executes the de-initialization function for\neach plugin that is loaded so that the plugin has a chance to perform any\nfinal cleanup.\n\nIf you need to load plugins for a single server startup when the\n--skip-grant-tables option is given (which tells the server not to read system\ntables), use the --plugin-load mysqld option.\n\nIf you need to install only one plugin from a library, use the INSTALL PLUGIN\nstatement.\n\nExamples\n--------\n\nTo load the XtraDB storage engine and all of its information_schema tables\nwith one statement, use\n\nINSTALL SONAME \'ha_xtradb\';\n\nThis statement can be used instead of INSTALL PLUGIN even when the library\ncontains only one plugin:\n\nINSTALL SONAME \'ha_sequence\';\n\nURL: https://mariadb.com/kb/en/install-soname/','','https://mariadb.com/kb/en/install-soname/'); +insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (77,5,'UNINSTALL SONAME','Syntax\n------\n\nUNINSTALL SONAME [IF EXISTS] \'plugin_library\'\n\nDescription\n-----------\n\nThis statement is a variant of UNINSTALL PLUGIN statement, that removes all\nplugins belonging to a specified plugin_library. See UNINSTALL PLUGIN for\ndetails.\n\nplugin_library is the name of the shared library that contains the plugin\ncode. The file name extension (for example, libmyplugin.so or libmyplugin.dll)\ncan be omitted (which makes the statement look the same on all architectures).\n\nTo use UNINSTALL SONAME, you must have the DELETE privilege for the\nmysql.plugin table.\n\nMariaDB starting with 10.4.0\n----------------------------\n\nIF EXISTS\n---------\n\nIf the IF EXISTS clause is used, MariaDB will return a note instead of an\nerror if the plugin library does not exist. See SHOW WARNINGS.\n\nExamples\n--------\n\nTo uninstall the XtraDB plugin and all of its information_schema tables with\none statement, use\n\nUNINSTALL SONAME \'ha_xtradb\';\n\nFrom MariaDB 10.4.0:\n\nUNINSTALL SONAME IF EXISTS \'ha_example\';\nQuery OK, 0 rows affected (0.099 sec)\n\nUNINSTALL SONAME IF EXISTS \'ha_example\';\nQuery OK, 0 rows affected, 1 warning (0.000 sec)\n\nSHOW WARNINGS;\n+-------+------+-------------------------------------+\n| Level | Code | Message |\n+-------+------+-------------------------------------+\n| Note | 1305 | SONAME ha_example.so does not exist |\n+-------+------+-------------------------------------+\n\nURL: https://mariadb.com/kb/en/uninstall-soname/','','https://mariadb.com/kb/en/uninstall-soname/'); +insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (78,5,'Plugin Overview','Plugins are server components that enhance MariaDB in some way. These can be\nanything from new storage engines, plugins for enhancing full-text parsing, or\neven small enhancements, such as a plugin to get a timestamp as an integer.\n\nQuerying Plugin Information\n---------------------------\n\nThere are a number of ways to see which plugins are currently active.\n\nA server almost always has a large number of active plugins, because the\nserver contains a large number of built-in plugins, which are active by\ndefault and cannot be uninstalled.\n\nQuerying Plugin Information with SHOW PLUGINS\n---------------------------------------------\n\nThe SHOW PLUGINS statement can be used to query information about all active\nplugins.\n\nFor example:\n\nSHOW PLUGINS\\G;\n********************** 1. row **********************\n Name: binlog\n Status: ACTIVE\n Type: STORAGE ENGINE\nLibrary: NULL\nLicense: GPL\n********************** 2. row **********************\n Name: mysql_native_password\n Status: ACTIVE\n Type: AUTHENTICATION\nLibrary: NULL\nLicense: GPL\n********************** 3. row **********************\n Name: mysql_old_password\n Status: ACTIVE\n Type: AUTHENTICATION\nLibrary: NULL\nLicense: GPL\n...\n\nIf a plugin\'s Library column has a NULL value, then the plugin is built-in,\nand it cannot be uninstalled.\n\nQuerying Plugin Information with information_schema.PLUGINS\n-----------------------------------------------------------\n\nThe information_schema.PLUGINS table can be queried to get more detailed\ninformation about plugins.\n\nFor example:\n\nSELECT * FROM information_schema.PLUGINS\\G\n...\n*************************** 6. row ***************************\n PLUGIN_NAME: CSV\n PLUGIN_VERSION: 1.0\n PLUGIN_STATUS: ACTIVE\n PLUGIN_TYPE: STORAGE ENGINE\n PLUGIN_TYPE_VERSION: 100003.0\n PLUGIN_LIBRARY: NULL\nPLUGIN_LIBRARY_VERSION: NULL\n PLUGIN_AUTHOR: Brian Aker, MySQL AB\n PLUGIN_DESCRIPTION: CSV storage engine\n PLUGIN_LICENSE: GPL\n LOAD_OPTION: FORCE\n PLUGIN_MATURITY: Stable\n PLUGIN_AUTH_VERSION: 1.0\n*************************** 7. row ***************************\n PLUGIN_NAME: MEMORY\n PLUGIN_VERSION: 1.0\n PLUGIN_STATUS: ACTIVE\n PLUGIN_TYPE: STORAGE ENGINE\n PLUGIN_TYPE_VERSION: 100003.0\n PLUGIN_LIBRARY: NULL\nPLUGIN_LIBRARY_VERSION: NULL\n PLUGIN_AUTHOR: MySQL AB\n PLUGIN_DESCRIPTION: Hash based, stored in memory, useful for temporary\ntables\n PLUGIN_LICENSE: GPL\n LOAD_OPTION: FORCE\n PLUGIN_MATURITY: Stable\n PLUGIN_AUTH_VERSION: 1.0\n...\n\nIf a plugin\'s PLUGIN_LIBRARY column has the NULL value, then the plugin is\nbuilt-in, and it cannot be uninstalled.\n\nQuerying Plugin Information with mysql.plugin\n---------------------------------------------\n\nThe mysql.plugin table can be queried to get information about installed\nplugins.\n\nThis table only contains information about plugins that have been installed\nvia the following methods:\n\n* The INSTALL SONAME statement.\n* The INSTALL PLUGIN statement.\n* The mysql_plugin utility.\n\nThis table does not contain information about:\n\n* Built-in plugins.\n* Plugins loaded with the --plugin-load-add option.\n* Plugins loaded with the --plugin-load option.\n\nThis table only contains enough information to reload the plugin when the\nserver is restarted, which means it only contains the plugin name and the\nplugin library.\n\nFor example:\n\nSELECT * FROM mysql.plugin;\n\n+------+------------+\n| name | dl |\n+------+------------+\n| PBXT | libpbxt.so |\n+------+------------+\n\nInstalling a Plugin\n-------------------\n\nThere are three primary ways to install a plugin:\n\n* A plugin can be installed dynamically with an SQL statement.\n* A plugin can be installed with a mysqld option, but it requires a server\nrestart.\n* A plugin can be installed with the mysql_plugin utility, while the server is\ncompletely offline.\n\nWhen you are installing a plugin, you also have to ensure that:\n\n* The server\'s plugin directory is properly configured, and the plugin\'s\nlibrary is in the plugin directory.\n* The server\'s minimum plugin maturity is properly configured, and the plugin\nis mature enough to be installed.\n\nInstalling a Plugin Dynamically\n-------------------------------\n\nA plugin can be installed dynamically by executing either the INSTALL SONAME\nor the INSTALL PLUGIN statement.\n\nIf a plugin is installed with one of these statements, then a record will be\nadded to the mysql.plugins table for the plugin. This means that the plugin\nwill automatically be loaded every time the server restarts, unless\nspecifically uninstalled or deactivated.\n\nInstalling a Plugin with INSTALL SONAME\n---------------------------------------\n\nYou can install a plugin dynamically by executing the INSTALL SONAME\nstatement. INSTALL SONAME installs all plugins from the given plugin library.\nThis could be required for some plugin libraries.\n\nFor example, to install all plugins in the server_audit plugin library (which\nis currently only the server_audit audit plugin), you could execute the\nfollowing:\n\nINSTALL SONAME \'server_audit\';\n\nInstalling a Plugin with INSTALL PLUGIN\n---------------------------------------\n\nYou can install a plugin dynamically by executing the INSTALL PLUGIN\nstatement. INSTALL PLUGIN installs a single plugin from the given plugin\nlibrary.\n\nFor example, to install the server_audit audit plugin from the server_audit\nplugin library, you could execute the following:\n\nINSTALL PLUGIN server_audit SONAME \'server_audit\';\n','','https://mariadb.com/kb/en/plugin-overview/'); +update help_topic set description = CONCAT(description, '\nInstalling a Plugin with Plugin Load Options\n--------------------------------------------\n\nA plugin can be installed with a mysqld option by providing either the\n--plugin-load-add or the --plugin-load option.\n\nIf a plugin is installed with one of these options, then a record will not be\nadded to the mysql.plugins table for the plugin. This means that if the server\nis restarted without the same option set, then the plugin will not\nautomatically be loaded.\n\nInstalling a Plugin with --plugin-load-add\n------------------------------------------\n\nYou can install a plugin with the --plugin-load-add option by specifying the\noption as a command-line argument to mysqld or by specifying the option in a\nrelevant server option group in an option file.\n\nThe --plugin-load-add option uses the following format:\n\n* Plugins can be specified in the format name=library, where name is the\nplugin name and library is the plugin library. This format installs a single\nplugin from the given plugin library.\n* Plugins can also be specified in the format library, where library is the\nplugin library. This format installs all plugins from the given plugin library.\n* Multiple plugins can be specified by separating them with semicolons.\n\nFor example, to install all plugins in the server_audit plugin library (which\nis currently only the server_audit audit plugin) and also the ed25519\nauthentication plugin from the auth_ed25519 plugin library, you could set the\noption to the following values on the command-line:\n\n$ mysqld --user=mysql --plugin-load-add=\'server_audit\'\n--plugin-load-add=\'ed25519=auth_ed25519\'\n\nYou could also set the option to the same values in an option file:\n\n[mariadb]\n...\nplugin_load_add = server_audit\nplugin_load_add = ed25519=auth_ed25519\n\nSpecial care must be taken when specifying both the --plugin-load option and\nthe --plugin-load-add option together. The --plugin-load option resets the\nplugin load list, and this can cause unexpected problems if you are not aware.\nThe --plugin-load-add option does not reset the plugin load list, so it is\nmuch safer to use. See Specifying Multiple Plugin Load Options for more\ninformation.\n\nInstalling a Plugin with --plugin-load\n--------------------------------------\n\nYou can install a plugin with the --plugin-load option by specifying the\noption as a command-line argument to mysqld or by specifying the option in a\nrelevant server option group in an option file.\n\nThe --plugin-load option uses the following format:\n\n* Plugins can be specified in the format name=library, where name is the\nplugin name and library is the plugin library. This format installs a single\nplugin from the given plugin library.\n* Plugins can also be specified in the format library, where library is the\nplugin library. This format installs all plugins from the given plugin library.\n* Multiple plugins can be specified by separating them with semicolons.\n\nFor example, to install all plugins in the server_audit plugin library (which\nis currently only the server_audit audit plugin) and also the ed25519\nauthentication plugin from the auth_ed25519 plugin library, you could set the\noption to the following values on the command-line:\n\n$ mysqld --user=mysql --plugin-load=\'server_audit;ed25519=auth_ed25519\'\n\nYou could also set the option to the same values in an option file:\n\n[mariadb]\n...\nplugin_load = server_audit;ed25519=auth_ed25519\n\nSpecial care must be taken when specifying the --plugin-load option multiple\ntimes, or when specifying both the --plugin-load option and the\n--plugin-load-add option together. The --plugin-load option resets the plugin\nload list, and this can cause unexpected problems if you are not aware. The\n--plugin-load-add option does not reset the plugin load list, so it is much\nsafer to use. See Specifying Multiple Plugin Load Options for more information.\n\nSpecifying Multiple Plugin Load Options\n---------------------------------------\n\nSpecial care must be taken when specifying the --plugin-load option multiple\ntimes, or when specifying both the --plugin-load option and the\n--plugin-load-add option. The --plugin-load option resets the plugin load\nlist, and this can cause unexpected problems if you are not aware. The\n--plugin-load-add option does not reset the plugin load list, so it is much\nsafer to use.\n\nThis can have the following consequences:\n\n* If the --plugin-load option is specified multiple times, then only the last\ninstance will have any effect. For example, in the following case, the first\ninstance of the option is reset:\n\n[mariadb]\n...\nplugin_load = server_audit\nplugin_load = ed25519=auth_ed25519\n\n* If the --plugin-load option is specified after the --plugin-load-add option,\nthen it will also reset the changes made by that option. For example, in the\nfollowing case, the --plugin-load-add option does not do anything, because the\nsubsequent --plugin-load option resets the plugin load list:\n\n[mariadb]\n...\nplugin_load_add = server_audit\nplugin_load = ed25519=auth_ed25519\n\n* In contrast, if the --plugin-load option is specified before the\n--plugin-load-add option, then it will work fine, because the\n--plugin-load-add option does not reset the plugin load list. For example, in\nthe following case, both plugins are properly loaded:\n\n[mariadb]\n...\nplugin_load = server_audit\nplugin_load_add = ed25519=auth_ed25519\n\nInstalling a Plugin with mysql_plugin\n-------------------------------------\n') WHERE help_topic_id = 78; +update help_topic set description = CONCAT(description, '\nA plugin can be installed with the mysql_plugin utility if the server is\ncompletely offline.\n\nThe syntax is:\n\nmysql_plugin [options] ENABLE|DISABLE\n\nFor example, to install the server_audit audit plugin, you could execute the\nfollowing:\n\nmysql_plugin server_audit ENABLE\n\nIf a plugin is installed with this utility, then a record will be added to the\nmysql.plugins table for the plugin. This means that the plugin will\nautomatically be loaded every time the server restarts, unless specifically\nuninstalled or deactivated.\n\nConfiguring the Plugin Directory\n--------------------------------\n\nWhen a plugin is being installed, the server looks for the plugin\'s library in\nthe server\'s plugin directory. This directory is configured by the plugin_dir\nsystem variable. This can be specified as a command-line argument to mysqld or\nit can be specified in a relevant server option group in an option file. For\nexample:\n\n[mariadb]\n...\nplugin_dir = /usr/lib64/mysql/plugin\n\nConfiguring the Minimum Plugin Maturity\n---------------------------------------\n\nWhen a plugin is being installed, the server compares the plugin\'s maturity\nlevel against the server\'s minimum allowed plugin maturity. This can help\nprevent users from using unstable plugins on production servers. This minimum\nplugin maturity is configured by the plugin_maturity system variable. This can\nbe specified as a command-line argument to mysqld or it can be specified in a\nrelevant server option group in an option file. For example:\n\n[mariadb]\n...\nplugin_maturity = stable\n\nConfiguring Plugin Activation at Server Startup\n-----------------------------------------------\n\nA plugin will be loaded by default when the server starts if:\n\n* The plugin was installed with the INSTALL SONAME statement.\n* The plugin was installed with the INSTALL PLUGIN statement.\n* The plugin was installed with the mysql_plugin utility.\n* The server is configured to load the plugin with the --plugin-load-add\noption.\n* The server is configured to load the plugin with the --plugin-load option.\n\nThis behavior can be changed with special options that take the form\n--plugin-name. For example, for the server_audit audit plugin, the special\noption is called --server-audit.\n\nThe possible values for these special options are:\n\n+---------------------------------------+------------------------------------+\n| Option Value | Description |\n+---------------------------------------+------------------------------------+\n| OFF | Disables the plugin without |\n| | removing it from the |\n| | mysql.plugins table. |\n+---------------------------------------+------------------------------------+\n| ON | Enables the plugin. If the plugin |\n| | cannot be initialized, then the |\n| | server will still continue |\n| | starting up, but the plugin will |\n| | be disabled. |\n+---------------------------------------+------------------------------------+\n| FORCE | Enables the plugin. If the plugin |\n| | cannot be initialized, then the |\n| | server will fail to start with an |\n| | error. |\n+---------------------------------------+------------------------------------+\n| FORCE_PLUS_PERMANENT | Enables the plugin. If the plugin |\n| | cannot be initialized, then the |\n| | server will fail to start with an |\n| | error. In addition, the plugin |\n| | cannot be uninstalled with |\n| | UNINSTALL SONAME or UNINSTALL |\n| | PLUGIN while the server is |\n| | running. |\n+---------------------------------------+------------------------------------+\n\nA plugin\'s status can be found by looking at the PLUGIN_STATUS column of the\ninformation_schema.PLUGINS table.\n\nUninstalling Plugins\n--------------------\n\nPlugins that are found in the mysql.plugin table, that is those that were\ninstalled with INSTALL SONAME, INSTALL PLUGIN or mysql_plugin can be\nuninstalled in one of two ways:\n\n* The UNINSTALL SONAME or the UNINSTALL PLUGIN statement while the server is\nrunning\n* With mysql_plugin while the server is offline.\n\nPlugins that were enabled as a --plugin-load option do not need to be\nuninstalled. If --plugin-load is omitted the next time the server starts, or\nthe plugin is not listed as one of the --plugin-load entries, the plugin will\nnot be loaded.\n\nUNINSTALL PLUGIN uninstalls a single installed plugin, while UNINSTALL SONAME\nuninstalls all plugins belonging to a given library.\n\nURL: https://mariadb.com/kb/en/plugin-overview/') WHERE help_topic_id = 78; +insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (79,6,'MBR Definition','Description\n-----------\n\nThe MBR (Minimum Bounding Rectangle), or Envelope is the bounding geometry,\nformed by the minimum and maximum (X,Y) coordinates:\n\nExamples\n--------\n\n((MINX MINY, MAXX MINY, MAXX MAXY, MINX MAXY, MINX MINY))\n\nURL: https://mariadb.com/kb/en/mbr-definition/','','https://mariadb.com/kb/en/mbr-definition/'); +insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (80,6,'MBRContains','Syntax\n------\n\nMBRContains(g1,g2)\n\nDescription\n-----------\n\nReturns 1 or 0 to indicate whether the Minimum Bounding Rectangle of g1\ncontains the Minimum Bounding Rectangle of g2. This tests the opposite\nrelationship as MBRWithin().\n\nExamples\n--------\n\nSET @g1 = GeomFromText(\'Polygon((0 0,0 3,3 3,3 0,0 0))\');\n\nSET @g2 = GeomFromText(\'Point(1 1)\');\n\nSELECT MBRContains(@g1,@g2), MBRContains(@g2,@g1);\n+----------------------+----------------------+\n| MBRContains(@g1,@g2) | MBRContains(@g2,@g1) |\n+----------------------+----------------------+\n| 1 | 0 |\n+----------------------+----------------------+\n\nURL: https://mariadb.com/kb/en/mbrcontains/','','https://mariadb.com/kb/en/mbrcontains/'); +insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (81,6,'MBRDisjoint','Syntax\n------\n\nMBRDisjoint(g1,g2)\n\nDescription\n-----------\n\nReturns 1 or 0 to indicate whether the Minimum Bounding Rectangles of the two\ngeometries g1 and g2 are disjoint. Two geometries are disjoint if they do not\nintersect, that is touch or overlap.\n\nExamples\n--------\n\nSET @g1 = GeomFromText(\'Polygon((0 0,0 3,3 3,3 0,0 0))\');\nSET @g2 = GeomFromText(\'Polygon((4 4,4 7,7 7,7 4,4 4))\');\nSELECTmbrdisjoint(@g1,@g2);\n+----------------------+\n| mbrdisjoint(@g1,@g2) |\n+----------------------+\n| 1 |\n+----------------------+\n\nSET @g1 = GeomFromText(\'Polygon((0 0,0 3,3 3,3 0,0 0))\');\nSET @g2 = GeomFromText(\'Polygon((3 3,3 6,6 6,6 3,3 3))\');\nSELECT mbrdisjoint(@g1,@g2);\n+----------------------+\n| mbrdisjoint(@g1,@g2) |\n+----------------------+\n| 0 |\n+----------------------+\n\nURL: https://mariadb.com/kb/en/mbrdisjoint/','','https://mariadb.com/kb/en/mbrdisjoint/'); +insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (82,6,'MBREqual','Syntax\n------\n\nMBREqual(g1,g2)\n\nDescription\n-----------\n\nReturns 1 or 0 to indicate whether the Minimum Bounding Rectangles of the two\ngeometries g1 and g2 are the same.\n\nExamples\n--------\n\nSET @g1=GEOMFROMTEXT(\'LINESTRING(0 0, 1 2)\');\nSET @g2=GEOMFROMTEXT(\'POLYGON((0 0, 0 2, 1 2, 1 0, 0 0))\');\nSELECT MbrEqual(@g1,@g2);\n+-------------------+\n| MbrEqual(@g1,@g2) |\n+-------------------+\n| 1 |\n+-------------------+\n\nSET @g1=GEOMFROMTEXT(\'LINESTRING(0 0, 1 3)\');\nSET @g2=GEOMFROMTEXT(\'POLYGON((0 0, 0 2, 1 4, 1 0, 0 0))\');\nSELECT MbrEqual(@g1,@g2);\n+-------------------+\n| MbrEqual(@g1,@g2) |\n+-------------------+\n| 0 |\n+-------------------+\n\nURL: https://mariadb.com/kb/en/mbrequal/','','https://mariadb.com/kb/en/mbrequal/'); +insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (83,6,'MBRIntersects','Syntax\n------\n\nMBRIntersects(g1,g2)\n\nDescription\n-----------\n\nReturns 1 or 0 to indicate whether the Minimum Bounding Rectangles of the two\ngeometries g1 and g2 intersect.\n\nExamples\n--------\n\nSET @g1 = GeomFromText(\'Polygon((0 0,0 3,3 3,3 0,0 0))\');\nSET @g2 = GeomFromText(\'Polygon((3 3,3 6,6 6,6 3,3 3))\');\nSELECT mbrintersects(@g1,@g2);\n+------------------------+\n| mbrintersects(@g1,@g2) |\n+------------------------+\n| 1 |\n+------------------------+\n\nSET @g1 = GeomFromText(\'Polygon((0 0,0 3,3 3,3 0,0 0))\');\nSET @g2 = GeomFromText(\'Polygon((4 4,4 7,7 7,7 4,4 4))\');\nSELECT mbrintersects(@g1,@g2);\n+------------------------+\n| mbrintersects(@g1,@g2) |\n+------------------------+\n| 0 |\n+------------------------+\n\nURL: https://mariadb.com/kb/en/mbrintersects/','','https://mariadb.com/kb/en/mbrintersects/'); +insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (84,6,'MBROverlaps','Syntax\n------\n\nMBROverlaps(g1,g2)\n\nDescription\n-----------\n\nReturns 1 or 0 to indicate whether the Minimum Bounding Rectangles of the two\ngeometries g1 and g2 overlap. The term spatially overlaps is used if two\ngeometries intersect and their intersection results in a geometry of the same\ndimension but not equal to either of the given geometries.\n\nExamples\n--------\n\nSET @g1 = GeomFromText(\'Polygon((0 0,0 3,3 3,3 0,0 0))\');\nSET @g2 = GeomFromText(\'Polygon((4 4,4 7,7 7,7 4,4 4))\');\nSELECT mbroverlaps(@g1,@g2);\n+----------------------+\n| mbroverlaps(@g1,@g2) |\n+----------------------+\n| 0 |\n+----------------------+\n\nSET @g1 = GeomFromText(\'Polygon((0 0,0 3,3 3,3 0,0 0))\');\nSET @g2 = GeomFromText(\'Polygon((3 3,3 6,6 6,6 3,3 3))\');\nSELECT mbroverlaps(@g1,@g2);\n+----------------------+\n| mbroverlaps(@g1,@g2) |\n+----------------------+\n| 0 |\n+----------------------+\n\nSET @g1 = GeomFromText(\'Polygon((0 0,0 4,4 4,4 0,0 0))\');\nSET @g2 = GeomFromText(\'Polygon((3 3,3 6,6 6,6 3,3 3))\');\nSELECT mbroverlaps(@g1,@g2);\n+----------------------+\n| mbroverlaps(@g1,@g2) |\n+----------------------+\n| 1 |\n+----------------------+\n\nURL: https://mariadb.com/kb/en/mbroverlaps/','','https://mariadb.com/kb/en/mbroverlaps/'); +insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (85,6,'MBRTouches','Syntax\n------\n\nMBRTouches(g1,g2)\n\nDescription\n-----------\n\nReturns 1 or 0 to indicate whether the Minimum Bounding Rectangles of the two\ngeometries g1 and g2 touch. Two geometries spatially touch if the interiors of\nthe geometries do not intersect, but the boundary of one of the geometries\nintersects either the boundary or the interior of the other.\n\nExamples\n--------\n\nSET @g1 = GeomFromText(\'Polygon((0 0,0 3,3 3,3 0,0 0))\');\nSET @g2 = GeomFromText(\'Polygon((4 4,4 7,7 7,7 4,4 4))\');\nSELECT mbrtouches(@g1,@g2);\n+---------------------+\n| mbrtouches(@g1,@g2) |\n+---------------------+\n| 0 |\n+---------------------+\n\nSET @g1 = GeomFromText(\'Polygon((0 0,0 3,3 3,3 0,0 0))\');\nSET @g2 = GeomFromText(\'Polygon((3 3,3 6,6 6,6 3,3 3))\');\nSELECT mbrtouches(@g1,@g2);\n+---------------------+\n| mbrtouches(@g1,@g2) |\n+---------------------+\n| 1 |\n+---------------------+\n\nSET @g1 = GeomFromText(\'Polygon((0 0,0 4,4 4,4 0,0 0))\');\nSET @g2 = GeomFromText(\'Polygon((3 3,3 6,6 6,6 3,3 3))\');\nSELECT mbrtouches(@g1,@g2);\n+---------------------+\n| mbrtouches(@g1,@g2) |\n+---------------------+\n| 0 |\n+---------------------+\n\nURL: https://mariadb.com/kb/en/mbrtouches/','','https://mariadb.com/kb/en/mbrtouches/'); +insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (86,6,'MBRWithin','Syntax\n------\n\nMBRWithin(g1,g2)\n\nDescription\n-----------\n\nReturns 1 or 0 to indicate whether the Minimum Bounding Rectangle of g1 is\nwithin the Minimum Bounding Rectangle of g2. This tests the opposite\nrelationship as MBRContains().\n\nExamples\n--------\n\nSET @g1 = GeomFromText(\'Polygon((0 0,0 3,3 3,3 0,0 0))\');\nSET @g2 = GeomFromText(\'Polygon((0 0,0 5,5 5,5 0,0 0))\');\nSELECT MBRWithin(@g1,@g2), MBRWithin(@g2,@g1);\n+--------------------+--------------------+\n| MBRWithin(@g1,@g2) | MBRWithin(@g2,@g1) |\n+--------------------+--------------------+\n| 1 | 0 |\n+--------------------+--------------------+\n\nURL: https://mariadb.com/kb/en/mbrwithin/','','https://mariadb.com/kb/en/mbrwithin/'); +insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (87,7,'CASE OPERATOR','Syntax\n------\n\nCASE value WHEN [compare_value] THEN result [WHEN [compare_value] THEN\nresult ...] [ELSE result] END\n\nCASE WHEN [condition] THEN result [WHEN [condition] THEN result ...]\n[ELSE result] END\n\nDescription\n-----------\n\nThe first version returns the result where value=compare_value. The second\nversion returns the result for the first condition that is true. If there was\nno matching result value, the result after ELSE is returned, or NULL if there\nis no ELSE part.\n\nThere is also a CASE statement, which differs from the CASE operator described\nhere.\n\nExamples\n--------\n\nSELECT CASE 1 WHEN 1 THEN \'one\' WHEN 2 THEN \'two\' ELSE \'more\' END;\n+------------------------------------------------------------+\n| CASE 1 WHEN 1 THEN \'one\' WHEN 2 THEN \'two\' ELSE \'more\' END |\n+------------------------------------------------------------+\n| one |\n+------------------------------------------------------------+\n\nSELECT CASE WHEN 1>0 THEN \'true\' ELSE \'false\' END;\n+--------------------------------------------+\n| CASE WHEN 1>0 THEN \'true\' ELSE \'false\' END |\n+--------------------------------------------+\n| true |\n+--------------------------------------------+\n\nSELECT CASE BINARY \'B\' WHEN \'a\' THEN 1 WHEN \'b\' THEN 2 END;\n+-----------------------------------------------------+\n| CASE BINARY \'B\' WHEN \'a\' THEN 1 WHEN \'b\' THEN 2 END |\n+-----------------------------------------------------+\n| NULL |\n+-----------------------------------------------------+\n\nURL: https://mariadb.com/kb/en/case-operator/','','https://mariadb.com/kb/en/case-operator/'); +insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (88,7,'IF Function','Syntax\n------\n\nIF(expr1,expr2,expr3)\n\nDescription\n-----------\n\nIf expr1 is TRUE (expr1 <> 0 and expr1 <> NULL) then IF() returns expr2;\notherwise it returns expr3. IF() returns a numeric or string value, depending\non the context in which it is used.\n\nNote: There is also an IF statement which differs from the IF() function\ndescribed here.\n\nExamples\n--------\n\nSELECT IF(1>2,2,3);\n+-------------+\n| IF(1>2,2,3) |\n+-------------+\n| 3 |\n+-------------+\n\nSELECT IF(1<2,\'yes\',\'no\');\n+--------------------+\n| IF(1<2,\'yes\',\'no\') |\n+--------------------+\n| yes |\n+--------------------+\n\nSELECT IF(STRCMP(\'test\',\'test1\'),\'no\',\'yes\');\n+---------------------------------------+\n| IF(STRCMP(\'test\',\'test1\'),\'no\',\'yes\') |\n+---------------------------------------+\n| no |\n+---------------------------------------+\n\nURL: https://mariadb.com/kb/en/if-function/','','https://mariadb.com/kb/en/if-function/'); +insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (89,7,'IFNULL','Syntax\n------\n\nIFNULL(expr1,expr2)\nNVL(expr1,expr2)\n\nDescription\n-----------\n\nIf expr1 is not NULL, IFNULL() returns expr1; otherwise it returns expr2.\nIFNULL() returns a numeric or string value, depending on the context in which\nit is used.\n\nFrom MariaDB 10.3, NVL() is an alias for IFNULL().\n\nExamples\n--------\n\nSELECT IFNULL(1,0); \n+-------------+\n| IFNULL(1,0) |\n+-------------+\n| 1 |\n+-------------+\n\nSELECT IFNULL(NULL,10);\n+-----------------+\n| IFNULL(NULL,10) |\n+-----------------+\n| 10 |\n+-----------------+\n\nSELECT IFNULL(1/0,10);\n+----------------+\n| IFNULL(1/0,10) |\n+----------------+\n| 10.0000 |\n+----------------+\n\nSELECT IFNULL(1/0,\'yes\');\n+-------------------+\n| IFNULL(1/0,\'yes\') |\n+-------------------+\n| yes |\n+-------------------+\n\nURL: https://mariadb.com/kb/en/ifnull/','','https://mariadb.com/kb/en/ifnull/'); +insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (90,7,'NULLIF','Syntax\n------\n\nNULLIF(expr1,expr2)\n\nDescription\n-----------\n\nReturns NULL if expr1 = expr2 is true, otherwise returns expr1. This is the\nsame as CASE WHEN expr1 = expr2 THEN NULL ELSE expr1 END.\n\nExamples\n--------\n\nSELECT NULLIF(1,1);\n+-------------+\n| NULLIF(1,1) |\n+-------------+\n| NULL |\n+-------------+\n\nSELECT NULLIF(1,2);\n+-------------+\n| NULLIF(1,2) |\n+-------------+\n| 1 |\n+-------------+\n\nURL: https://mariadb.com/kb/en/nullif/','','https://mariadb.com/kb/en/nullif/'); +insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (91,7,'NVL','MariaDB starting with 10.3\n--------------------------\nFrom MariaDB 10.3, NVL is a synonym for IFNULL.\n\nURL: https://mariadb.com/kb/en/nvl/','','https://mariadb.com/kb/en/nvl/'); +insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (92,7,'NVL2','MariaDB starting with 10.3\n--------------------------\nThe NLV2 function was introduced in MariaDB 10.3.0.\n\nSyntax\n------\n\nNVL2(expr1,expr2,expr3)\n\nDescription\n-----------\n\nThe NVL2 function returns a value based on whether a specified expression is\nNULL or not. If expr1 is not NULL, then NVL2 returns expr2. If expr1 is NULL,\nthen NVL2 returns expr3.\n\nExamples\n--------\n\nSELECT NVL2(NULL,1,2);\n+----------------+\n| NVL2(NULL,1,2) |\n+----------------+\n| 2 |\n+----------------+\n\nSELECT NVL2(\'x\',1,2);\n+---------------+\n| NVL2(\'x\',1,2) |\n+---------------+\n| 1 |\n+---------------+\n\nURL: https://mariadb.com/kb/en/nvl2/','','https://mariadb.com/kb/en/nvl2/'); +insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (93,8,'SET TRANSACTION','Syntax\n------\n\nSET [GLOBAL | SESSION] TRANSACTION\n transaction_property [, transaction_property] ...\n\ntransaction_property:\n ISOLATION LEVEL level\n | READ WRITE\n | READ ONLY\n\nlevel:\n REPEATABLE READ\n | READ COMMITTED\n | READ UNCOMMITTED\n | SERIALIZABLE\n\nDescription\n-----------\n\nThis statement sets the transaction isolation level or the transaction access\nmode globally, for the current session, or for the next transaction:\n\n* With the GLOBAL keyword, the statement sets the default\n transaction level globally for all subsequent sessions. Existing sessions are\n unaffected.\n* With the SESSION keyword, the statement sets the default\n transaction level for all subsequent transactions performed within the\n current session.\n* Without any SESSION or GLOBAL keyword,\n the statement sets the isolation level for the next (not started) transaction\n performed within the current session.\n\nA change to the global default isolation level requires the SUPER privilege.\nAny session is free to change its session isolation level (even in the middle\nof a transaction), or the isolation level for its next transaction.\n\nIsolation Level\n---------------\n\nTo set the global default isolation level at server startup, use the\n--transaction-isolation=level option on the command line or in an option file.\nValues of level for this option use dashes rather than spaces, so the\nallowable values are READ-UNCOMMITTED, READ-COMMITTED, REPEATABLE-READ, or\nSERIALIZABLE. For example, to set the default isolation level to REPEATABLE\nREAD, use these lines in the [mysqld] section of an option file:\n\n[mysqld]\ntransaction-isolation = REPEATABLE-READ\nTo determine the global and session transaction isolation levels at runtime,\ncheck the value of the tx_isolation system variable:\n\nSELECT @@GLOBAL.tx_isolation, @@tx_isolation;\n\nInnoDB supports each of the translation isolation levels described here using\ndifferent locking strategies. The default level is REPEATABLE READ. For\nadditional information about InnoDB record-level locks and how it uses them to\nexecute various types of statements, see InnoDB Lock Modes, and\nhttp://dev.mysql.com/doc/refman/en/innodb-locks-set.html.\n\nIsolation Levels\n----------------\n\nThe following sections describe how MariaDB supports the different transaction\nlevels.\n\nREAD UNCOMMITTED\n----------------\n\nSELECT statements are performed in a non-locking fashion, but a possible\nearlier version of a row might be used. Thus, using this isolation level, such\nreads are not consistent. This is also called a \"dirty read.\" Otherwise, this\nisolation level works like READ COMMITTED.\n\nREAD COMMITTED\n--------------\n\nA somewhat Oracle-like isolation level with respect to consistent\n(non-locking) reads: Each consistent read, even within the same transaction,\nsets and reads its own fresh snapshot. See\nhttp://dev.mysql.com/doc/refman/en/innodb-consistent-read.html.\n\nFor locking reads (SELECT with FOR UPDATE or LOCK IN SHARE MODE), InnoDB locks\nonly index records, not the gaps before them, and thus allows the free\ninsertion of new records next to locked records. For UPDATE and DELETE\nstatements, locking depends on whether the statement uses a unique index with\na unique search condition (such as WHERE id = 100), or a range-type search\ncondition (such as WHERE id > 100). For a unique index with a unique search\ncondition, InnoDB locks only the index record found, not the gap before it.\nFor range-type searches, InnoDB locks the index range scanned, using gap locks\nor next-key (gap plus index-record) locks to block insertions by other\nsessions into the gaps covered by the range. This is necessary because\n\"phantom rows\" must be blocked for MySQL replication and recovery to work.\n\nNote: If the READ COMMITTED isolation level is used or the\ninnodb_locks_unsafe_for_binlog system variable is enabled, there is no InnoDB\ngap locking except for foreign-key constraint checking and duplicate-key\nchecking. Also, record locks for non-matching rows are released after MariaDB\nhas evaluated the WHERE condition.If you use READ COMMITTED or enable\ninnodb_locks_unsafe_for_binlog, you must use row-based binary logging.\n\nREPEATABLE READ\n---------------\n\nThis is the default isolation level for InnoDB. For consistent reads, there is\nan important difference from the READ COMMITTED isolation level: All\nconsistent reads within the same transaction read the snapshot established by\nthe first read. This convention means that if you issue several plain\n(non-locking) SELECT statements within the same transaction, these SELECT\nstatements are consistent also with respect to each other. See\nhttp://dev.mysql.com/doc/refman/en/innodb-consistent-read.html.\n\nFor locking reads (SELECT with FOR UPDATE or LOCK IN SHARE MODE), UPDATE, and\nDELETE statements, locking depends on whether the statement uses a unique\nindex with a unique search condition, or a range-type search condition. For a\nunique index with a unique search condition, InnoDB locks only the index\nrecord found, not the gap before it. For other search conditions, InnoDB locks\nthe index range scanned, using gap locks or next-key (gap plus index-record)\nlocks to block insertions by other sessions into the gaps covered by the range.\n\nThis is the minimum isolation level for non-distributed XA transactions.\n\nSERIALIZABLE\n------------\n\nThis level is like REPEATABLE READ, but InnoDB implicitly converts all plain\nSELECT statements to SELECT ... LOCK IN SHARE MODE if autocommit is disabled.','','https://mariadb.com/kb/en/set-transaction/'); +update help_topic set description = CONCAT(description, '\nIf autocommit is enabled, the SELECT is its own transaction. It therefore is\nknown to be read only and can be serialized if performed as a consistent\n(non-locking) read and need not block for other transactions. (This means that\nto force a plain SELECT to block if other transactions have modified the\nselected rows, you should disable autocommit.)\n\nDistributed XA transactions should always use this isolation level.\n\nAccess Mode\n-----------\n\nThe access mode specifies whether the transaction is allowed to write data or\nnot. By default, transactions are in READ WRITE mode (see the tx_read_only\nsystem variable). READ ONLY mode allows the storage engine to apply\noptimizations that cannot be used for transactions which write data. The only\nexception to this rule is that read only transactions can perform DDL\nstatements on temporary tables.\n\nIt is not permitted to specify both READ WRITE and READ ONLY in the same\nstatement.\n\nREAD WRITE and READ ONLY can also be specified in the START TRANSACTION\nstatement, in which case the specified mode is only valid for one transaction.\n\nExamples\n--------\n\nSET GLOBAL TRANSACTION ISOLATION LEVEL SERIALIZABLE;\n\nAttempting to set the isolation level within an existing transaction without\nspecifying GLOBAL or SESSION.\n\nSTART TRANSACTION;\n\nSET TRANSACTION ISOLATION LEVEL SERIALIZABLE;\nERROR 1568 (25001): Transaction characteristics can\'t be changed while a\ntransaction is in progress\n\nURL: https://mariadb.com/kb/en/set-transaction/') WHERE help_topic_id = 93; +insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (94,8,'START TRANSACTION','Syntax\n------\n\nSTART TRANSACTION [transaction_property [, transaction_property] ...] | BEGIN\n[WORK]\nCOMMIT [WORK] [AND [NO] CHAIN] [[NO] RELEASE]\nROLLBACK [WORK] [AND [NO] CHAIN] [[NO] RELEASE]\nSET autocommit = {0 | 1}\n\ntransaction_property:\n WITH CONSISTENT SNAPSHOT\n | READ WRITE\n | READ ONLY\n\nDescription\n-----------\n\nThe START TRANSACTION or BEGIN statement begins a new transaction. COMMIT\ncommits the current transaction, making its changes permanent. ROLLBACK rolls\nback the current transaction, canceling its changes. The SET autocommit\nstatement disables or enables the default autocommit mode for the current\nsession.\n\nSTART TRANSACTION and SET autocommit = 1 implicitly commit the current\ntransaction, if any.\n\nThe optional WORK keyword is supported for COMMIT and ROLLBACK, as are the\nCHAIN and RELEASE clauses. CHAIN and RELEASE can be used for additional\ncontrol over transaction completion. The value of the completion_type system\nvariable determines the default completion behavior.\n\nThe AND CHAIN clause causes a new transaction to begin as soon as the current\none ends, and the new transaction has the same isolation level as the\njust-terminated transaction. The RELEASE clause causes the server to\ndisconnect the current client session after terminating the current\ntransaction. Including the NO keyword suppresses CHAIN or RELEASE completion,\nwhich can be useful if the completion_type system variable is set to cause\nchaining or release completion by default.\n\nAccess Mode\n-----------\n\nThe access mode specifies whether the transaction is allowed to write data or\nnot. By default, transactions are in READ WRITE mode (see the tx_read_only\nsystem variable). READ ONLY mode allows the storage engine to apply\noptimizations that cannot be used for transactions which write data. The only\nexception to this rule is that read only transactions can perform DDL\nstatements on temporary tables.\n\nIt is not permitted to specify both READ WRITE and READ ONLY in the same\nstatement.\n\nREAD WRITE and READ ONLY can also be specified in the SET TRANSACTION\nstatement, in which case the specified mode is valid for all sessions, or for\nall subsequent transaction used by the current session.\n\nautocommit\n----------\n\nBy default, MariaDB runs with autocommit mode enabled. This means that as soon\nas you execute a statement that updates (modifies) a table, MariaDB stores the\nupdate on disk to make it permanent. To disable autocommit mode, use the\nfollowing statement:\n\nSET autocommit=0;\n\nAfter disabling autocommit mode by setting the autocommit variable to zero,\nchanges to transaction-safe tables (such as those for InnoDB or NDBCLUSTER)\nare not made permanent immediately. You must use COMMIT to store your changes\nto disk or ROLLBACK to ignore the changes.\n\nTo disable autocommit mode for a single series of statements, use the START\nTRANSACTION statement.\n\nDDL Statements\n--------------\n\nDDL statements (CREATE, ALTER, DROP) and administrative statements (FLUSH,\nRESET, OPTIMIZE, ANALYZE, CHECK, REPAIR, CACHE INDEX), transaction management\nstatements (BEGIN, START TRANSACTION) and LOAD DATA INFILE, cause an implicit\nCOMMIT and start a new transaction. An exception to this rule are the DDL that\noperate on temporary tables: you can CREATE, ALTER and DROP them without\ncausing any COMMIT, but those actions cannot be rolled back. This means that\nif you call ROLLBACK, the temporary tables you created in the transaction will\nremain, while the rest of the transaction will be rolled back.\n\nTransactions cannot be used in Stored Functions or Triggers. In Stored\nProcedures and Events BEGIN is not allowed, so you should use START\nTRANSACTION instead.\n\nA transaction acquires a metadata lock on every table it accesses to prevent\nother connections from altering their structure. The lock is released at the\nend of the transaction. This happens even with non-transactional storage\nengines (like MEMORY or CONNECT), so it makes sense to use transactions with\nnon-transactional tables.\n\nin_transaction\n--------------\n\nThe in_transaction system variable is a session-only, read-only variable that\nreturns 1 inside a transaction, and 0 if not in a transaction.\n\nWITH CONSISTENT SNAPSHOT\n------------------------\n\nThe WITH CONSISTENT SNAPSHOT option starts a consistent read for storage\nengines such as InnoDB that can do so, the same as if a START TRANSACTION\nfollowed by a SELECT from any InnoDB table was issued.\n\nSee Enhancements for START TRANSACTION WITH CONSISTENT SNAPSHOT.\n\nExamples\n--------\n\nSTART TRANSACTION;\nSELECT @A:=SUM(salary) FROM table1 WHERE type=1;\nUPDATE table2 SET summary=@A WHERE type=1;\nCOMMIT;\n\nURL: https://mariadb.com/kb/en/start-transaction/','','https://mariadb.com/kb/en/start-transaction/'); +insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (95,8,'COMMIT','The COMMIT statement ends a transaction, saving any changes to the data so\nthat they become visible to subsequent transactions. Also, unlocks metadata\nchanged by current transaction. If autocommit is set to 1, an implicit commit\nis performed after each statement. Otherwise, all transactions which don\'t end\nwith an explicit COMMIT are implicitly rollbacked and the changes are lost.\nThe ROLLBACK statement can be used to do this explicitly.\n\nThe required syntax for the COMMIT statement is as follows:\n\nCOMMIT [WORK] [AND [NO] CHAIN] [[NO] RELEASE]\n\nCOMMIT is the more important transaction terminator, as well as the more\ninteresting one. The basic form of the COMMIT statement is simply the keyword\nCOMMIT (the keyword WORK is simply noise and can be omitted without changing\nthe effect).\n\nThe optional AND CHAIN clause is a convenience for initiating a new\ntransaction as soon as the old transaction terminates. If AND CHAIN is\nspecified, then there is effectively nothing between the old and new\ntransactions, although they remain separate. The characteristics of the new\ntransaction will be the same as the characteristics of the old one — that is,\nthe new transaction will have the same access mode, isolation level and\ndiagnostics area size (we\'ll discuss all of these shortly) as the transaction\njust terminated.\n\nRELEASE tells the server to disconnect the client immediately after the\ncurrent transaction.\n\nThere are NO RELEASE and AND NO CHAIN options. By default, commits do not\nRELEASE or CHAIN, but it\'s possible to change this default behavior with the\ncompletion_type server system variable. In this case, the AND NO CHAIN and NO\nRELEASE options override the server default.\n\nURL: https://mariadb.com/kb/en/commit/','','https://mariadb.com/kb/en/commit/'); +insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (96,8,'ROLLBACK','The ROLLBACK statement rolls back (ends) a transaction, destroying any changes\nto SQL-data so that they never become visible to subsequent transactions. The\nrequired syntax for the ROLLBACK statement is as follows.\n\nROLLBACK [ WORK ] [ AND [ NO ] CHAIN ] \n[ TO [ SAVEPOINT ] { | } ]\n\nThe ROLLBACK statement will either end a transaction, destroying all data\nchanges that happened during any of the transaction, or it will just destroy\nany data changes that happened since you established a savepoint. The basic\nform of the ROLLBACK statement is just the keyword ROLLBACK (the keyword WORK\nis simply noise and can be omitted without changing the effect).\n\nThe optional AND CHAIN clause is a convenience for initiating a new\ntransaction as soon as the old transaction terminates. If AND CHAIN is\nspecified, then there is effectively nothing between the old and new\ntransactions, although they remain separate. The characteristics of the new\ntransaction will be the same as the characteristics of the old one — that is,\nthe new transaction will have the same access mode, isolation level and\ndiagnostics area size (we\'ll discuss all of these shortly) as the transaction\njust terminated. The AND NO CHAIN option just tells your DBMS to end the\ntransaction — that is, these four SQL statements are equivalent:\n\nROLLBACK; \nROLLBACK WORK; \nROLLBACK AND NO CHAIN; \nROLLBACK WORK AND NO CHAIN;\n\nAll of them end a transaction without saving any transaction characteristics.\nThe only other options, the equivalent statements:\n\nROLLBACK AND CHAIN;\nROLLBACK WORK AND CHAIN;\n\nboth tell your DBMS to end a transaction, but to save that transaction\'s\ncharacteristics for the next transaction.\n\nROLLBACK is much simpler than COMMIT: it may involve no more than a few\ndeletions (of Cursors, locks, prepared SQL statements and log-file entries).\nIt\'s usually assumed that ROLLBACK can\'t fail, although such a thing is\nconceivable (for example, an encompassing transaction might reject an attempt\nto ROLLBACK because it\'s lining up for a COMMIT).\n\nROLLBACK cancels all effects of a transaction. It does not cancel effects on\nobjects outside the DBMS\'s control (for example the values in host program\nvariables or the settings made by some SQL/CLI function calls). But in\ngeneral, it is a convenient statement for those situations when you say \"oops,\nthis isn\'t working\" or when you simply don\'t care whether your temporary work\nbecomes permanent or not.\n\nHere is a moot question. If all you\'ve been doing is SELECTs, so that there\nhave been no data changes, should you end the transaction with ROLLBACK or\nCOMMIT? It shouldn\'t really matter because both ROLLBACK and COMMIT do the\nsame transaction-terminating job. However, the popular conception is that\nROLLBACK implies failure, so after a successful series of SELECT statements\nthe convention is to end the transaction with COMMIT rather than ROLLBACK.\n\nMariaDB (and most other DBMSs) supports rollback of SQL-data change\nstatements, but not of SQL-Schema statements. This means that if you use any\nof CREATE, ALTER, DROP, GRANT, REVOKE, you are implicitly committing at\nexecution time.\n\nINSERT INTO Table_2 VALUES(5); \nDROP TABLE Table_3 CASCADE; \nROLLBACK;\n\nThe result will be that both the INSERT and the DROP will go through as\nseparate transactions so the ROLLBACK will have no effect.\n\nURL: https://mariadb.com/kb/en/rollback/','','https://mariadb.com/kb/en/rollback/'); +insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (97,8,'LOCK TABLES','Syntax\n------\n\nLOCK TABLE[S]\n tbl_name [[AS] alias] lock_type\n [, tbl_name [[AS] alias] lock_type] ...\n [WAIT n|NOWAIT]\n\nlock_type:\n READ [LOCAL]\n | [LOW_PRIORITY] WRITE\n | WRITE CONCURRENT\n\nUNLOCK TABLES\n\nDescription\n-----------\n\nThe lock_type can be one of:\n\n+---------------------------+------------------------------------------------+\n| Option | Description |\n+---------------------------+------------------------------------------------+\n| READ | Read lock, no writes allowed |\n+---------------------------+------------------------------------------------+\n| READ LOCAL | Read lock, but allow concurrent inserts |\n+---------------------------+------------------------------------------------+\n| WRITE | Exclusive write lock. No other connections |\n| | can read or write to this table |\n+---------------------------+------------------------------------------------+\n| LOW_PRIORITY WRITE | Exclusive write lock, but allow new read |\n| | locks on the table until we get the write |\n| | lock. |\n+---------------------------+------------------------------------------------+\n| WRITE CONCURRENT | Exclusive write lock, but allow READ LOCAL |\n| | locks to the table. |\n+---------------------------+------------------------------------------------+\n\nMariaDB enables client sessions to acquire table locks explicitly for the\npurpose of cooperating with other sessions for access to tables, or to prevent\nother sessions from modifying tables during periods when a session requires\nexclusive access to them. A session can acquire or release locks only for\nitself. One session cannot acquire locks for another session or release locks\nheld by another session.\n\nLocks may be used to emulate transactions or to get more speed when updating\ntables.\n\nLOCK TABLES explicitly acquires table locks for the current client session.\nTable locks can be acquired for base tables or views. To use LOCK TABLES, you\nmust have the LOCK TABLES privilege, and the SELECT privilege for each object\nto be locked. See GRANT\n\nFor view locking, LOCK TABLES adds all base tables used in the view to the set\nof tables to be locked and locks them automatically. If you lock a table\nexplicitly with LOCK TABLES, any tables used in triggers are also locked\nimplicitly, as described in Triggers and Implicit Locks.\n\nUNLOCK TABLES explicitly releases any table locks held by the current session.\n\nMariaDB starting with 10.3.0\n----------------------------\n\nWAIT/NOWAIT\n-----------\n\nSet the lock wait timeout. See WAIT and NOWAIT.\n\nLimitations\n-----------\n\n* LOCK TABLES doesn\'t work when using Galera cluster. You may experience\ncrashes or locks when used with Galera.\n* LOCK TABLES works on XtraDB/InnoDB tables only if the innodb_table_locks\nsystem variable is set to 1 (the default) and autocommit is set to 0 (1 is\ndefault). Please note that no error message will be returned on LOCK TABLES\nwith innodb_table_locks = 0.\n* LOCK TABLES implicitly commits the active transaction, if any. Also,\nstarting a transaction always releases all table locks acquired with LOCK\nTABLES. This means that there is no way to have table locks and an active\ntransaction at the same time. The only exceptions are the transactions in\nautocommit mode. To preserve the data integrity between transactional and\nnon-transactional tables, the GET_LOCK() function can be used.\n* When using LOCK TABLES on a TEMPORARY table, it will always be locked with a\nWRITE lock.\n* While a connection holds an explicit read lock on a table, it cannot modify\nit. If you try, the following error will be produced:\n\nERROR 1099 (HY000): Table \'tab_name\' was locked with a READ lock and can\'t be\nupdated\n\n* While a connection holds an explicit lock on a table, it cannot access a\nnon-locked table. If you try, the following error will be produced:\n\nERROR 1100 (HY000): Table \'tab_name\' was not locked with LOCK TABLES\n\n* While a connection holds an explicit lock on a table, it cannot issue the\nfollowing: INSERT DELAYED, CREATE TABLE, CREATE TABLE ... LIKE, and DDL\nstatements involving stored programs and views (except for triggers). If you\ntry, the following error will be produced:\n\nERROR 1192 (HY000): Can\'t execute the given command because you have active\nlocked tables or an active transaction\n\n* LOCK TABLES can not be used in stored routines - if you try, the following\nerror will be produced on creation. This restriction was removed in MariaDB\n10.6.2:\n\nERROR 1314 (0A000): LOCK is not allowed in stored procedures\n\nURL: https://mariadb.com/kb/en/lock-tables/','','https://mariadb.com/kb/en/lock-tables/'); +insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (98,8,'SAVEPOINT','Syntax\n------\n\nSAVEPOINT identifier\nROLLBACK [WORK] TO [SAVEPOINT] identifier\nRELEASE SAVEPOINT identifier\n\nDescription\n-----------\n\nInnoDB supports the SQL statements SAVEPOINT, ROLLBACK TO SAVEPOINT, RELEASE\nSAVEPOINT and the optional WORK keyword for ROLLBACK.\n\nEach savepoint must have a legal MariaDB identifier. A savepoint is a named\nsub-transaction.\n\nNormally ROLLBACK undoes the changes performed by the whole transaction. When\nused with the TO clause, it undoes the changes performed after the specified\nsavepoint, and erases all subsequent savepoints. However, all locks that have\nbeen acquired after the save point will survive. RELEASE SAVEPOINT does not\nrollback or commit any changes, but removes the specified savepoint.\n\nWhen the execution of a trigger or a stored function begins, it is not\npossible to use statements which reference a savepoint which was defined from\nout of that stored program.\n\nWhen a COMMIT (including implicit commits) or a ROLLBACK statement (with no TO\nclause) is performed, they act on the whole transaction, and all savepoints\nare removed.\n\nErrors\n------\n\nIf COMMIT or ROLLBACK is issued and no transaction was started, no error is\nreported.\n\nIf SAVEPOINT is issued and no transaction was started, no error is reported\nbut no savepoint is created. When ROLLBACK TO SAVEPOINT or RELEASE SAVEPOINT\nis called for a savepoint that does not exist, an error like this is issued:\n\nERROR 1305 (42000): SAVEPOINT svp_name does not exist\n\nURL: https://mariadb.com/kb/en/savepoint/','','https://mariadb.com/kb/en/savepoint/'); +insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (99,8,'Metadata Locking','MariaDB supports metadata locking. This means that when a transaction\n(including XA transactions) uses a table, it locks its metadata until the end\nof transaction. Non-transactional tables are also locked, as well as views and\nobjects which are related to locked tables/views (stored functions, triggers,\netc). When a connection tries to use a DDL statement (like an ALTER TABLE)\nwhich modifies a table that is locked, that connection is queued, and has to\nwait until it\'s unlocked. Using savepoints and performing a partial rollback\ndoes not release metadata locks.\n\nLOCK TABLES ... WRITE are also queued. Some wrong statements which produce an\nerror may not need to wait for the lock to be freed.\n\nThe metadata lock\'s timeout is determined by the value of the\nlock_wait_timeout server system variable (in seconds). However, note that its\ndefault value is 31536000 (1 year, MariaDB <= 10.2.3), or 86400 (1 day,\nMariaDB >= 10.2.4). If this timeout is exceeded, the following error is\nreturned:\n\nERROR 1205 (HY000): Lock wait timeout exceeded; try restarting transaction\n\nIf the metadata_lock_info plugin is installed, the Information Schema\nmetadata_lock_info table stores information about existing metadata locks.\n\nMariaDB starting with 10.5.2\n----------------------------\nFrom MariaDB 10.5, the Performance Schema metadata_locks table contains\nmetadata lock information.\n\nExample\n-------\n\nLet\'s use the following MEMORY (non-transactional) table:\n\nCREATE TABLE t (a INT) ENGINE = MEMORY;\n\nConnection 1 starts a transaction, and INSERTs a row into t:\n\nSTART TRANSACTION;\n\nINSERT INTO t SET a=1;\n\nt\'s metadata is now locked by connection 1. Connection 2 tries to alter t, but\nhas to wait:\n\nALTER TABLE t ADD COLUMN b INT;\n\nConnection 2\'s prompt is blocked now.\n\nNow connection 1 ends the transaction:\n\nCOMMIT;\n\n...and connection 2 finally gets the output of its command:\n\nQuery OK, 1 row affected (35.23 sec)\nRecords: 1 Duplicates: 0 Warnings: 0\n\nURL: https://mariadb.com/kb/en/metadata-locking/','','https://mariadb.com/kb/en/metadata-locking/'); +insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (100,8,'Transaction Timeouts','MariaDB has always had the wait_timeout and interactive_timeout settings,\nwhich close connections after a certain period of inactivity.\n\nHowever, these are by default set to a long wait period. In situations where\ntransactions may be started, but not committed or rolled back, more granular\ncontrol and a shorter timeout may be desirable so as to avoid locks being held\nfor too long.\n\nMariaDB 10.3 introduced three new variables to handle this situation.\n\n* idle_transaction_timeout (all transactions)\n* idle_write_transaction_timeout (write transactions - called\nidle_readwrite_transaction_timeout until MariaDB 10.3.2)\n* idle_readonly_transaction_timeout (read transactions)\n\nThese accept a time in seconds to time out, by closing the connection,\ntransactions that are idle for longer than this period. By default all are set\nto zero, or no timeout.\n\nidle_transaction_timeout affects all transactions,\nidle_write_transaction_timeout affects write transactions only and\nidle_readonly_transaction_timeout affects read transactions only. The latter\ntwo variables work independently. However, if either is set along with\nidle_transaction_timeout, the settings for idle_write_transaction_timeout or\nidle_readonly_transaction_timeout will take precedence.\n\nExamples\n--------\n\nSET SESSION idle_transaction_timeout=2;\nBEGIN;\nSELECT * FROM t;\nEmpty set (0.000 sec)\n## wait 3 seconds\nSELECT * FROM t;\nERROR 2006 (HY000): MySQL server has gone away\n\nSET SESSION idle_write_transaction_timeout=2;\nBEGIN;\nSELECT * FROM t;\nEmpty set (0.000 sec)\n## wait 3 seconds\nSELECT * FROM t;\nEmpty set (0.000 sec)\nINSERT INTO t VALUES(1);\n## wait 3 seconds\nSELECT * FROM t;\nERROR 2006 (HY000): MySQL server has gone away\n\nSET SESSION idle_transaction_timeout=2, SESSION\nidle_readonly_transaction_timeout=10;\nBEGIN;\nSELECT * FROM t;\nEmpty set (0.000 sec)\n ## wait 3 seconds\nSELECT * FROM t;\nEmpty set (0.000 sec)\n## wait 11 seconds\nSELECT * FROM t;\nERROR 2006 (HY000): MySQL server has gone away\n\nURL: https://mariadb.com/kb/en/transaction-timeouts/','','https://mariadb.com/kb/en/transaction-timeouts/'); +insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (101,8,'UNLOCK TABLES','Syntax\n------\n\nUNLOCK TABLES\n\nDescription\n-----------\n\nUNLOCK TABLES explicitly releases any table locks held by the current session.\nSee LOCK TABLES for more information.\n\nIn addition to releasing table locks acquired by the LOCK TABLES statement,\nthe UNLOCK TABLES statement also releases the global read lock acquired by the\nFLUSH TABLES WITH READ LOCK statement. The FLUSH TABLES WITH READ LOCK\nstatement is very useful for performing backups. See FLUSH for more\ninformation about FLUSH TABLES WITH READ LOCK.\n\nURL: https://mariadb.com/kb/en/transactions-unlock-tables/','','https://mariadb.com/kb/en/transactions-unlock-tables/'); +insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (102,8,'WAIT and NOWAIT','MariaDB starting with 10.3.0\n----------------------------\nMariaDB 10.3.0 introduced extended syntax so that it is possible to set\ninnodb_lock_wait_timeout and lock_wait_timeout for the following statements:\n\nSyntax\n------\n\nALTER TABLE tbl_name [WAIT n|NOWAIT] ...\nCREATE ... INDEX ON tbl_name (index_col_name, ...) [WAIT n|NOWAIT] ...\nDROP INDEX ... [WAIT n|NOWAIT]\nDROP TABLE tbl_name [WAIT n|NOWAIT] ...\nLOCK TABLE ... [WAIT n|NOWAIT]\nOPTIMIZE TABLE tbl_name [WAIT n|NOWAIT]\nRENAME TABLE tbl_name [WAIT n|NOWAIT] ...\nSELECT ... FOR UPDATE [WAIT n|NOWAIT]\nSELECT ... LOCK IN SHARE MODE [WAIT n|NOWAIT]\nTRUNCATE TABLE tbl_name [WAIT n|NOWAIT]\n\nDescription\n-----------\n\nThe lock wait timeout can be explicitly set in the statement by using either\nWAIT n (to set the wait in seconds) or NOWAIT, in which case the statement\nwill immediately fail if the lock cannot be obtained. WAIT 0 is equivalent to\nNOWAIT.\n\nURL: https://mariadb.com/kb/en/wait-and-nowait/','','https://mariadb.com/kb/en/wait-and-nowait/'); +insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (103,8,'XA Transactions','Overview\n--------\n\nThe MariaDB XA implementation is based on the X/Open CAE document Distributed\nTransaction Processing: The XA Specification. This document is published by\nThe Open Group and available at\nhttp://www.opengroup.org/public/pubs/catalog/c193.htm.\n\nXA transactions are designed to allow distributed transactions, where a\ntransaction manager (the application) controls a transaction which involves\nmultiple resources. Such resources are usually DBMSs, but could be resources\nof any type. The whole set of required transactional operations is called a\nglobal transaction. Each subset of operations which involve a single resource\nis called a local transaction. XA used a 2-phases commit (2PC). With the first\ncommit, the transaction manager tells each resource to prepare an effective\ncommit, and waits for a confirm message. The changes are not still made\neffective at this point. If any of the resources encountered an error, the\ntransaction manager will rollback the global transaction. If all resources\ncommunicate that the first commit is successful, the transaction manager can\nrequire a second commit, which makes the changes effective.\n\nIn MariaDB, XA transactions can only be used with storage engines that support\nthem. At least InnoDB, TokuDB, SPIDER and MyRocks support them. For InnoDB,\nuntil MariaDB 10.2, XA transactions can be disabled by setting the\ninnodb_support_xa server system variable to 0. From MariaDB 10.3, XA\ntransactions are always supported.\n\nLike regular transactions, XA transactions create metadata locks on accessed\ntables.\n\nXA transactions require REPEATABLE READ as a minimum isolation level. However,\ndistributed transactions should always use SERIALIZABLE.\n\nTrying to start more than one XA transaction at the same time produces a 1400\nerror (SQLSTATE \'XAE09\'). The same error is produced when attempting to start\nan XA transaction while a regular transaction is in effect. Trying to start a\nregular transaction while an XA transaction is in effect produces a 1399 error\n(SQLSTATE \'XAE07\').\n\nThe statements that cause an implicit COMMIT for regular transactions produce\na 1400 error (SQLSTATE \'XAE09\') if a XA transaction is in effect.\n\nInternal XA vs External XA\n--------------------------\n\nXA transactions are an overloaded term in MariaDB. If a storage engine is\nXA-capable, it can mean one or both of these:\n\n* It supports MariaDB\'s internal two-phase commit API. This is transparent to\nthe user. Sometimes this is called \"internal XA\", since MariaDB\'s internal\ntransaction coordinator log can handle coordinating these transactions.\n\n* It supports XA transactions, with the XA START, XA PREPARE, XA COMMIT, etc.\nstatements. Sometimes this is called \"external XA\", since it requires the use\nof an external transaction coordinator to use this feature properly.\n\nTransaction Coordinator Log\n---------------------------\n\nIf you have two or more XA-capable storage engines enabled, then a transaction\ncoordinator log must be available.\n\nThere are currently two implementations of the transaction coordinator log:\n\n* Binary log-based transaction coordinator log\n* Memory-mapped file-based transaction coordinator log\n\nIf the binary log is enabled on a server, then the server will use the binary\nlog-based transaction coordinator log. Otherwise, it will use the\nmemory-mapped file-based transaction coordinator log.\n\nSee Transaction Coordinator Log for more information.\n\nSyntax\n------\n\nXA {START|BEGIN} xid [JOIN|RESUME]\n\nXA END xid [SUSPEND [FOR MIGRATE]]\n\nXA PREPARE xid\n\nXA COMMIT xid [ONE PHASE]\n\nXA ROLLBACK xid\n\nXA RECOVER [FORMAT=[\'RAW\'|\'SQL\']]\n\nxid: gtrid [, bqual [, formatID ]]\n\nThe interface to XA transactions is a set of SQL statements starting with XA.\nEach statement changes a transaction\'s state, determining which actions it can\nperform. A transaction which does not exist is in the NON-EXISTING state.\n\nXA START (or BEGIN) starts a transaction and defines its xid (a transaction\nidentifier). The JOIN or RESUME keywords have no effect. The new transaction\nwill be in ACTIVE state.\n\nThe xid can have 3 components, though only the first one is mandatory. gtrid\nis a quoted string representing a global transaction identifier. bqual is a\nquoted string representing a local transaction identifier. formatID is an\nunsigned integer indicating the format used for the first two components; if\nnot specified, defaults to 1. MariaDB does not interpret in any way these\ncomponents, and only uses them to identify a transaction. xids of transactions\nin effect must be unique.\n\nXA END declares that the specified ACTIVE transaction is finished and it\nchanges its state to IDLE. SUSPEND [FOR MIGRATE] has no effect.\n\nXA PREPARE prepares an IDLE transaction for commit, changing its state to\nPREPARED. This is the first commit.\n\nXA COMMIT definitely commits and terminates a transaction which has already\nbeen PREPARED. If the ONE PHASE clause is specified, this statements performs\na 1-phase commit on an IDLE transaction.\n\nXA ROLLBACK rolls back and terminates an IDLE or PREPARED transaction.\n\nXA RECOVER shows information about all PREPARED transactions.\n\nWhen trying to execute an operation which is not allowed for the transaction\'s\ncurrent state, an error is produced:\n\nXA COMMIT \'test\' ONE PHASE;\nERROR 1399 (XAE07): XAER_RMFAIL: The command cannot be executed when global\ntransaction is in the ACTIVE state\n\nXA COMMIT \'test2\';','','https://mariadb.com/kb/en/xa-transactions/'); +update help_topic set description = CONCAT(description, '\nERROR 1399 (XAE07): XAER_RMFAIL: The command cannot be executed when global\ntransaction is in the NON-EXISTING state\n\nXA RECOVER\n----------\n\nThe XA RECOVER statement shows information about all transactions which are in\nthe PREPARED state. It does not matter which connection created the\ntransaction: if it has been PREPARED, it appears. But this does not mean that\na connection can commit or rollback a transaction which was started by another\nconnection. Note that transactions using a 1-phase commit are never in the\nPREPARED state, so they cannot be shown by XA RECOVER.\n\nXA RECOVER produces four columns:\n\nXA RECOVER;\n+----------+--------------+--------------+------+\n| formatID | gtrid_length | bqual_length | data |\n+----------+--------------+--------------+------+\n| 1 | 4 | 0 | test |\n+----------+--------------+--------------+------+\n\nMariaDB starting with 10.3.3\n----------------------------\nYou can use XA RECOVER FORMAT=\'SQL\' to get the data in a human readable form\nthat can be directly copy-pasted into XA COMMIT or XA ROLLBACK. This is\nparticularly useful for binary xid generated by some transaction coordinators.\n\nformatID is the formatID part of xid.\n\ndata are the gtrid and bqual parts of xid, concatenated.\n\ngtrid_length and bqual_length are the lengths of gtrid and bqual, respectevely.\n\nExamples\n--------\n\n2-phases commit:\n\nXA START \'test\';\n\nINSERT INTO t VALUES (1,2);\n\nXA END \'test\';\n\nXA PREPARE \'test\';\n\nXA COMMIT \'test\';\n\n1-phase commit:\n\nXA START \'test\';\n\nINSERT INTO t VALUES (1,2);\n\nXA END \'test\';\n\nXA COMMIT \'test\' ONE PHASE;\n\nHuman-readable:\n\nxa start \'12\\r34\\t67\\v78\', \'abc\\ndef\', 3;\n\ninsert t1 values (40);\n\nxa end \'12\\r34\\t67\\v78\', \'abc\\ndef\', 3;\n\nxa prepare \'12\\r34\\t67\\v78\', \'abc\\ndef\', 3;\n\nxa recover format=\'RAW\';\n+----------+--------------+--------------+--------------------+\n| formatID | gtrid_length | bqual_length | data |\n+----------+--------------+--------------+--------------------+\n34 67v78abc 11 | 7 | 12\ndef |\n+----------+--------------+--------------+--------------------+\n\nxa recover format=\'SQL\';\n+----------+--------------+--------------+-------------------------------------\n---------+\n| formatID | gtrid_length | bqual_length | data \n |\n+----------+--------------+--------------+-------------------------------------\n---------+\n| 3 | 11 | 7 |\nX\'31320d3334093637763738\',X\'6162630a646566\',3 |\n+----------+--------------+--------------+-------------------------------------\n---------+\n\nxa rollback X\'31320d3334093637763738\',X\'6162630a646566\',3;\n\nKnown Issues\n------------\n\nMariaDB Galera Cluster\n----------------------\n\nMariaDB Galera Cluster does not support XA transactions.\n\nHowever, MariaDB Galera Cluster builds include a built-in plugin called wsrep.\nPrior to MariaDB 10.4.3, this plugin was internally considered an XA-capable\nstorage engine. Consequently, these MariaDB Galera Cluster builds have\nmultiple XA-capable storage engines by default, even if the only \"real\"\nstorage engine that supports external XA transactions enabled on these builds\nby default is InnoDB. Therefore, when using one these builds MariaDB would be\nforced to use a transaction coordinator log by default, which could have\nperformance implications.\n\nSee Transaction Coordinator Log Overview: MariaDB Galera Cluster for more\ninformation.\n\nURL: https://mariadb.com/kb/en/xa-transactions/') WHERE help_topic_id = 103; +insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (104,10,'CREATE USER','Syntax\n------\n\nCREATE [OR REPLACE] USER [IF NOT EXISTS] \n user_specification [,user_specification ...] \n [REQUIRE {NONE | tls_option [[AND] tls_option ...] }]\n [WITH resource_option [resource_option ...] ]\n [lock_option] [password_option]\n\nuser_specification:\n username [authentication_option]\n\nauthentication_option:\n IDENTIFIED BY \'password\'\n | IDENTIFIED BY PASSWORD \'password_hash\'\n | IDENTIFIED {VIA|WITH} authentication_rule [OR authentication_rule ...]\n\nauthentication_rule:\n authentication_plugin\n | authentication_plugin {USING|AS} \'authentication_string\'\n | authentication_plugin {USING|AS} PASSWORD(\'password\')\n\ntls_option:\n SSL\n | X509\n | CIPHER \'cipher\'\n | ISSUER \'issuer\'\n | SUBJECT \'subject\'\n\nresource_option:\n MAX_QUERIES_PER_HOUR count\n | MAX_UPDATES_PER_HOUR count\n | MAX_CONNECTIONS_PER_HOUR count\n | MAX_USER_CONNECTIONS count\n | MAX_STATEMENT_TIME time\n\npassword_option:\n PASSWORD EXPIRE\n | PASSWORD EXPIRE DEFAULT\n | PASSWORD EXPIRE NEVER\n | PASSWORD EXPIRE INTERVAL N DAY\n\nlock_option:\n ACCOUNT LOCK\n | ACCOUNT UNLOCK\n}\n\nDescription\n-----------\n\nThe CREATE USER statement creates new MariaDB accounts. To use it, you must\nhave the global CREATE USER privilege or the INSERT privilege for the mysql\ndatabase. For each account, CREATE USER creates a new row in mysql.user (until\nMariaDB 10.3 this is a table, from MariaDB 10.4 it\'s a view) or\nmysql.global_priv_table (from MariaDB 10.4) that has no privileges.\n\nIf any of the specified accounts, or any permissions for the specified\naccounts, already exist, then the server returns ERROR 1396 (HY000). If an\nerror occurs, CREATE USER will still create the accounts that do not result in\nan error. Only one error is produced for all users which have not been created:\n\nERROR 1396 (HY000): \n Operation CREATE USER failed for \'u1\'@\'%\',\'u2\'@\'%\'\n\nCREATE USER, DROP USER, CREATE ROLE, and DROP ROLE all produce the same error\ncode when they fail.\n\nSee Account Names below for details on how account names are specified.\n\nOR REPLACE\n----------\n\nIf the optional OR REPLACE clause is used, it is basically a shortcut for:\n\nDROP USER IF EXISTS name;\nCREATE USER name ...;\n\nFor example:\n\nCREATE USER foo2@test IDENTIFIED BY \'password\';\nERROR 1396 (HY000): Operation CREATE USER failed for \'foo2\'@\'test\'\n\nCREATE OR REPLACE USER foo2@test IDENTIFIED BY \'password\';\nQuery OK, 0 rows affected (0.00 sec)\n\nIF NOT EXISTS\n-------------\n\nWhen the IF NOT EXISTS clause is used, MariaDB will return a warning instead\nof an error if the specified user already exists.\n\nFor example:\n\nCREATE USER foo2@test IDENTIFIED BY \'password\';\nERROR 1396 (HY000): Operation CREATE USER failed for \'foo2\'@\'test\'\n\nCREATE USER IF NOT EXISTS foo2@test IDENTIFIED BY \'password\';\nQuery OK, 0 rows affected, 1 warning (0.00 sec)\n\nSHOW WARNINGS;\n+-------+------+----------------------------------------------------+\n| Level | Code | Message |\n+-------+------+----------------------------------------------------+\n| Note | 1973 | Can\'t create user \'foo2\'@\'test\'; it already exists |\n+-------+------+----------------------------------------------------+\n\nAuthentication Options\n----------------------\n\nIDENTIFIED BY \'password\'\n------------------------\n\nThe optional IDENTIFIED BY clause can be used to provide an account with a\npassword. The password should be specified in plain text. It will be hashed by\nthe PASSWORD function prior to being stored in the\nmysql.user/mysql.global_priv_table table.\n\nFor example, if our password is mariadb, then we can create the user with:\n\nCREATE USER foo2@test IDENTIFIED BY \'mariadb\';\n\nIf you do not specify a password with the IDENTIFIED BY clause, the user will\nbe able to connect without a password. A blank password is not a wildcard to\nmatch any password. The user must connect without providing a password if no\npassword is set.\n\nThe only authentication plugins that this clause supports are\nmysql_native_password and mysql_old_password.\n\nIDENTIFIED BY PASSWORD \'password_hash\'\n--------------------------------------\n\nThe optional IDENTIFIED BY PASSWORD clause can be used to provide an account\nwith a password that has already been hashed. The password should be specified\nas a hash that was provided by the PASSWORD function. It will be stored in the\nmysql.user/mysql.global_priv_table table as-is.\n\nFor example, if our password is mariadb, then we can find the hash with:\n\nSELECT PASSWORD(\'mariadb\');\n+-------------------------------------------+\n| PASSWORD(\'mariadb\') |\n+-------------------------------------------+\n| *54958E764CE10E50764C2EECBB71D01F08549980 |\n+-------------------------------------------+\n1 row in set (0.00 sec)\n\nAnd then we can create a user with the hash:\n\nCREATE USER foo2@test IDENTIFIED BY PASSWORD\n\'*54958E764CE10E50764C2EECBB71D01F08549980\';\n\nIf you do not specify a password with the IDENTIFIED BY clause, the user will\nbe able to connect without a password. A blank password is not a wildcard to\nmatch any password. The user must connect without providing a password if no\npassword is set.\n\nThe only authentication plugins that this clause supports are\nmysql_native_password and mysql_old_password.\n\nIDENTIFIED {VIA|WITH} authentication_plugin\n-------------------------------------------\n\nThe optional IDENTIFIED VIA authentication_plugin allows you to specify that','','https://mariadb.com/kb/en/create-user/'); +update help_topic set description = CONCAT(description, '\nthe account should be authenticated by a specific authentication plugin. The\nplugin name must be an active authentication plugin as per SHOW PLUGINS. If it\ndoesn\'t show up in that output, then you will need to install it with INSTALL\nPLUGIN or INSTALL SONAME.\n\nFor example, this could be used with the PAM authentication plugin:\n\nCREATE USER foo2@test IDENTIFIED VIA pam;\n\nSome authentication plugins allow additional arguments to be specified after a\nUSING or AS keyword. For example, the PAM authentication plugin accepts a\nservice name:\n\nCREATE USER foo2@test IDENTIFIED VIA pam USING \'mariadb\';\n\nThe exact meaning of the additional argument would depend on the specific\nauthentication plugin.\n\nMariaDB starting with 10.4.0\n----------------------------\nThe USING or AS keyword can also be used to provide a plain-text password to a\nplugin if it\'s provided as an argument to the PASSWORD() function. This is\nonly valid for authentication plugins that have implemented a hook for the\nPASSWORD() function. For example, the ed25519 authentication plugin supports\nthis:\n\nCREATE USER safe@\'%\' IDENTIFIED VIA ed25519 USING PASSWORD(\'secret\');\n\nMariaDB starting with 10.4.3\n----------------------------\nOne can specify many authentication plugins, they all work as alternatives\nways of authenticating a user:\n\nCREATE USER safe@\'%\' IDENTIFIED VIA ed25519 USING PASSWORD(\'secret\') OR\nunix_socket;\n\nBy default, when you create a user without specifying an authentication\nplugin, MariaDB uses the mysql_native_password plugin.\n\nTLS Options\n-----------\n\nBy default, MariaDB transmits data between the server and clients without\nencrypting it. This is generally acceptable when the server and client run on\nthe same host or in networks where security is guaranteed through other means.\nHowever, in cases where the server and client exist on separate networks or\nthey are in a high-risk network, the lack of encryption does introduce\nsecurity concerns as a malicious actor could potentially eavesdrop on the\ntraffic as it is sent over the network between them.\n\nTo mitigate this concern, MariaDB allows you to encrypt data in transit\nbetween the server and clients using the Transport Layer Security (TLS)\nprotocol. TLS was formerly known as Secure Socket Layer (SSL), but strictly\nspeaking the SSL protocol is a predecessor to TLS and, that version of the\nprotocol is now considered insecure. The documentation still uses the term SSL\noften and for compatibility reasons TLS-related server system and status\nvariables still use the prefix ssl_, but internally, MariaDB only supports its\nsecure successors.\n\nSee Secure Connections Overview for more information about how to determine\nwhether your MariaDB server has TLS support.\n\nYou can set certain TLS-related restrictions for specific user accounts. For\ninstance, you might use this with user accounts that require access to\nsensitive data while sending it across networks that you do not control. These\nrestrictions can be enabled for a user account with the CREATE USER, ALTER\nUSER, or GRANT statements. The following options are available:\n\n+---------------------------+------------------------------------------------+\n| Option | Description |\n+---------------------------+------------------------------------------------+\n| REQUIRE NONE | TLS is not required for this account, but can |\n| | still be used. |\n+---------------------------+------------------------------------------------+\n| REQUIRE SSL | The account must use TLS, but no valid X509 |\n| | certificate is required. This option cannot |\n| | be combined with other TLS options. |\n+---------------------------+------------------------------------------------+\n| REQUIRE X509 | The account must use TLS and must have a |\n| | valid X509 certificate. This option implies |\n| | REQUIRE SSL. This option cannot be combined |\n| | with other TLS options. |\n+---------------------------+------------------------------------------------+\n| REQUIRE ISSUER \'issuer\' | The account must use TLS and must have a |\n| | valid X509 certificate. Also, the Certificate |\n| | Authority must be the one specified via the |\n| | string issuer. This option implies REQUIRE |\n| | X509. This option can be combined with the |\n| | SUBJECT, and CIPHER options in any order. |\n+---------------------------+------------------------------------------------+\n| REQUIRE SUBJECT \'subject\' | The account must use TLS and must have a |\n| | valid X509 certificate. Also, the |\n| | certificate\'s Subject must be the one |\n| | specified via the string subject. This option |\n| | implies REQUIRE X509. This option can be |\n| | combined with the ISSUER, and CIPHER options |\n| | in any order. |\n+---------------------------+------------------------------------------------+') WHERE help_topic_id = 104; +update help_topic set description = CONCAT(description, '\n| REQUIRE CIPHER \'cipher\' | The account must use TLS, but no valid X509 |\n| | certificate is required. Also, the encryption |\n| | used for the connection must use a specific |\n| | cipher method specified in the string cipher. |\n| | This option implies REQUIRE SSL. This option |\n| | can be combined with the ISSUER, and SUBJECT |\n| | options in any order. |\n+---------------------------+------------------------------------------------+\n\nThe REQUIRE keyword must be used only once for all specified options, and the\nAND keyword can be used to separate individual options, but it is not required.\n\nFor example, you can create a user account that requires these TLS options\nwith the following:\n\nCREATE USER \'alice\'@\'%\'\n REQUIRE SUBJECT \'/CN=alice/O=My Dom, Inc./C=US/ST=Oregon/L=Portland\'\n AND ISSUER \'/C=FI/ST=Somewhere/L=City/ O=Some Company/CN=Peter\nParker/emailAddress=p.parker@marvel.com\'\n AND CIPHER \'SHA-DES-CBC3-EDH-RSA\';\n\nIf any of these options are set for a specific user account, then any client\nwho tries to connect with that user account will have to be configured to\nconnect with TLS.\n\nSee Securing Connections for Client and Server for information on how to\nenable TLS on the client and server.\n\nResource Limit Options\n----------------------\n\nIt is possible to set per-account limits for certain server resources. The\nfollowing table shows the values that can be set per account:\n\n+--------------------------------------+--------------------------------------+\n| Limit Type | Decription |\n+--------------------------------------+--------------------------------------+\n| MAX_QUERIES_PER_HOUR | Number of statements that the |\n| | account can issue per hour |\n| | (including updates) |\n+--------------------------------------+--------------------------------------+\n| MAX_UPDATES_PER_HOUR | Number of updates (not queries) |\n| | that the account can issue per hour |\n+--------------------------------------+--------------------------------------+\n| MAX_CONNECTIONS_PER_HOUR | Number of connections that the |\n| | account can start per hour |\n+--------------------------------------+--------------------------------------+\n| MAX_USER_CONNECTIONS | Number of simultaneous connections |\n| | that can be accepted from the same |\n| | account; if it is 0, |\n| | max_connections will be used |\n| | instead; if max_connections is 0, |\n| | there is no limit for this |\n| | account\'s simultaneous connections. |\n+--------------------------------------+--------------------------------------+\n| MAX_STATEMENT_TIME | Timeout, in seconds, for statements |\n| | executed by the user. See also |\n| | Aborting Statements that Exceed a |\n| | Certain Time to Execute. |\n+--------------------------------------+--------------------------------------+\n\nIf any of these limits are set to 0, then there is no limit for that resource\nfor that user.\n\nHere is an example showing how to create a user with resource limits:\n\nCREATE USER \'someone\'@\'localhost\' WITH\n MAX_USER_CONNECTIONS 10\n MAX_QUERIES_PER_HOUR 200;\n\nThe resources are tracked per account, which means \'user\'@\'server\'; not per\nuser name or per connection.\n\nThe count can be reset for all users using FLUSH USER_RESOURCES, FLUSH\nPRIVILEGES or mysqladmin reload.\n\nPer account resource limits are stored in the user table, in the mysql\ndatabase. Columns used for resources limits are named max_questions,\nmax_updates, max_connections (for MAX_CONNECTIONS_PER_HOUR), and\nmax_user_connections (for MAX_USER_CONNECTIONS).\n\nAccount Names\n-------------\n\nAccount names have both a user name component and a host name component, and\nare specified as \'user_name\'@\'host_name\'.\n\nThe user name and host name may be unquoted, quoted as strings using double\nquotes (\") or single quotes (\'), or quoted as identifiers using backticks (`).\nYou must use quotes when using special characters (such as a hyphen) or\nwildcard characters. If you quote, you must quote the user name and host name\nseparately (for example \'user_name\'@\'host_name\').\n\nHost Name Component\n-------------------\n\nIf the host name is not provided, it is assumed to be \'%\'.\n\nHost names may contain the wildcard characters % and _. They are matched as if\nby the LIKE clause. If you need to use a wildcard character literally (for\nexample, to match a domain name with an underscore), prefix the character with\na backslash. See LIKE for more information on escaping wildcard characters.\n\nHost name matches are case-insensitive. Host names can match either domain') WHERE help_topic_id = 104; +update help_topic set description = CONCAT(description, '\nnames or IP addresses. Use \'localhost\' as the host name to allow only local\nclient connections.\n\nYou can use a netmask to match a range of IP addresses using \'base_ip/netmask\'\nas the host name. A user with an IP address ip_addr will be allowed to connect\nif the following condition is true:\n\nip_addr & netmask = base_ip\n\nFor example, given a user:\n\nCREATE USER \'maria\'@\'247.150.130.0/255.255.255.0\';\n\nthe IP addresses satisfying this condition range from 247.150.130.0 to\n247.150.130.255.\n\nUsing 255.255.255.255 is equivalent to not using a netmask at all. Netmasks\ncannot be used for IPv6 addresses.\n\nNote that the credentials added when creating a user with the \'%\' wildcard\nhost will not grant access in all cases. For example, some systems come with\nan anonymous localhost user, and when connecting from localhost this will take\nprecedence.\n\nBefore MariaDB 10.6, the host name component could be up to 60 characters in\nlength. Starting from MariaDB 10.6, it can be up to 255 characters.\n\nUser Name Component\n-------------------\n\nUser names must match exactly, including case. A user name that is empty is\nknown as an anonymous account and is allowed to match a login attempt with any\nuser name component. These are described more in the next section.\n\nFor valid identifiers to use as user names, see Identifier Names.\n\nIt is possible for more than one account to match when a user connects.\nMariaDB selects the first matching account after sorting according to the\nfollowing criteria:\n\n* Accounts with an exact host name are sorted before accounts using a wildcard\nin the\nhost name. Host names using a netmask are considered to be exact for sorting.\n* Accounts with a wildcard in the host name are sorted according to the\nposition of\nthe first wildcard character. Those with a wildcard character later in the\nhost name\nsort before those with a wildcard character earlier in the host name.\n* Accounts with a non-empty user name sort before accounts with an empty user\nname.\n* Accounts with an empty user name are sorted last. As mentioned previously,\nthese are known as anonymous accounts. These are described more in the next\nsection.\n\nThe following table shows a list of example account as sorted by these\ncriteria:\n\n+---------+-------------+\n| User | Host |\n+---------+-------------+\n| joffrey | 192.168.0.3 |\n| | 192.168.0.% |\n| joffrey | 192.168.% |\n| | 192.168.% |\n+---------+-------------+\n\nOnce connected, you only have the privileges granted to the account that\nmatched, not all accounts that could have matched. For example, consider the\nfollowing commands:\n\nCREATE USER \'joffrey\'@\'192.168.0.3\';\nCREATE USER \'joffrey\'@\'%\';\nGRANT SELECT ON test.t1 to \'joffrey\'@\'192.168.0.3\';\nGRANT SELECT ON test.t2 to \'joffrey\'@\'%\';\n\nIf you connect as joffrey from 192.168.0.3, you will have the SELECT privilege\non the table test.t1, but not on the table test.t2. If you connect as joffrey\nfrom any other IP address, you will have the SELECT privilege on the table\ntest.t2, but not on the table test.t1.\n\nUsernames can be up to 80 characters long before 10.6 and starting from 10.6\nit can be 128 characters long.\n\nAnonymous Accounts\n------------------\n\nAnonymous accounts are accounts where the user name portion of the account\nname is empty. These accounts act as special catch-all accounts. If a user\nattempts to log into the system from a host, and an anonymous account exists\nwith a host name portion that matches the user\'s host, then the user will log\nin as the anonymous account if there is no more specific account match for the\nuser name that the user entered.\n\nFor example, here are some anonymous accounts:\n\nCREATE USER \'\'@\'localhost\';\nCREATE USER \'\'@\'192.168.0.3\';\n\nFixing a Legacy Default Anonymous Account\n-----------------------------------------\n\nOn some systems, the mysql.db table has some entries for the \'\'@\'%\' anonymous\naccount by default. Unfortunately, there is no matching entry in the\nmysql.user/mysql.global_priv_table table, which means that this anonymous\naccount doesn\'t exactly exist, but it does have privileges--usually on the\ndefault test database created by mysql_install_db. These account-less\nprivileges are a legacy that is leftover from a time when MySQL\'s privilege\nsystem was less advanced.\n\nThis situation means that you will run into errors if you try to create a\n\'\'@\'%\' account. For example:\n\nCREATE USER \'\'@\'%\';\nERROR 1396 (HY000): Operation CREATE USER failed for \'\'@\'%\'\n\nThe fix is to DELETE the row in the mysql.db table and then execute FLUSH\nPRIVILEGES:\n\nDELETE FROM mysql.db WHERE User=\'\' AND Host=\'%\';\nFLUSH PRIVILEGES;\n\nAnd then the account can be created:\n\nCREATE USER \'\'@\'%\';\nQuery OK, 0 rows affected (0.01 sec)\n\nSee MDEV-13486 for more information.\n\nPassword Expiry\n---------------\n\nMariaDB starting with 10.4.3\n----------------------------\nBesides automatic password expiry, as determined by default_password_lifetime,\npassword expiry times can be set on an individual user basis, overriding the\nglobal setting, for example:\n\nCREATE USER \'monty\'@\'localhost\' PASSWORD EXPIRE INTERVAL 120 DAY;\n\nSee User Password Expiry for more details.\n\nAccount Locking\n---------------\n\nMariaDB starting with 10.4.2\n----------------------------\nAccount locking permits privileged administrators to lock/unlock user\naccounts. No new client connections will be permitted if an account is locked') WHERE help_topic_id = 104; +update help_topic set description = CONCAT(description, '\n(existing connections are not affected). For example:\n\nCREATE USER \'marijn\'@\'localhost\' ACCOUNT LOCK;\n\nSee Account Locking for more details.\n\nFrom MariaDB 10.4.7 and MariaDB 10.5.8, the lock_option and password_option\nclauses can occur in either order.\n\nURL: https://mariadb.com/kb/en/create-user/') WHERE help_topic_id = 104; +insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (105,10,'ALTER USER','Syntax\n------\n\nALTER USER [IF EXISTS] \n user_specification [,user_specification] ...\n [REQUIRE {NONE | tls_option [[AND] tls_option] ...}]\n [WITH resource_option [resource_option] ...]\n [lock_option] [password_option]\n\nuser_specification:\n username [authentication_option]\n\nauthentication_option:\n IDENTIFIED BY \'password\'\n | IDENTIFIED BY PASSWORD \'password_hash\'\n | IDENTIFIED {VIA|WITH} authentication_rule [OR authentication_rule] ...\n\nauthentication_rule:\n authentication_plugin\n | authentication_plugin {USING|AS} \'authentication_string\'\n | authentication_plugin {USING|AS} PASSWORD(\'password\')\n\ntls_option\n SSL\n | X509\n | CIPHER \'cipher\'\n | ISSUER \'issuer\'\n | SUBJECT \'subject\'\n\nresource_option\n MAX_QUERIES_PER_HOUR count\n | MAX_UPDATES_PER_HOUR count\n | MAX_CONNECTIONS_PER_HOUR count\n | MAX_USER_CONNECTIONS count\n | MAX_STATEMENT_TIME time\n\npassword_option:\n PASSWORD EXPIRE\n | PASSWORD EXPIRE DEFAULT\n | PASSWORD EXPIRE NEVER\n | PASSWORD EXPIRE INTERVAL N DAY\n\nlock_option:\n ACCOUNT LOCK\n | ACCOUNT UNLOCK\n}\n\nDescription\n-----------\n\nThe ALTER USER statement modifies existing MariaDB accounts. To use it, you\nmust have the global CREATE USER privilege or the UPDATE privilege for the\nmysql database. The global SUPER privilege is also required if the read_only\nsystem variable is enabled.\n\nIf any of the specified user accounts do not yet exist, an error results. If\nan error occurs, ALTER USER will still modify the accounts that do not result\nin an error. Only one error is produced for all users which have not been\nmodified.\n\nIF EXISTS\n---------\n\nWhen the IF EXISTS clause is used, MariaDB will return a warning instead of an\nerror for each specified user that does not exist.\n\nAccount Names\n-------------\n\nFor ALTER USER statements, account names are specified as the username\nargument in the same way as they are for CREATE USER statements. See account\nnames from the CREATE USER page for details on how account names are specified.\n\nCURRENT_USER or CURRENT_USER() can also be used to alter the account logged\ninto the current session. For example, to change the current user\'s password\nto mariadb:\n\nALTER USER CURRENT_USER() IDENTIFIED BY \'mariadb\';\n\nAuthentication Options\n----------------------\n\nMariaDB starting with 10.4\n--------------------------\nFrom MariaDB 10.4, it is possible to use more than one authentication plugin\nfor each user account. For example, this can be useful to slowly migrate users\nto the more secure ed25519 authentication plugin over time, while allowing the\nold mysql_native_password authentication plugin as an alternative for the\ntransitional period. See Authentication from MariaDB 10.4 for more.\n\nWhen running ALTER USER, not specifying an authentication option in the\nIDENTIFIED VIA clause will remove that authentication method. (However this\nwas not the case before MariaDB 10.4.13, see MDEV-21928)\n\nFor example, a user is created with the ability to authenticate via both a\npassword and unix_socket:\n\nCREATE USER \'bob\'@\'localhost\' \n IDENTIFIED VIA mysql_native_password USING PASSWORD(\'pwd\')\n OR unix_socket;\n\nSHOW CREATE USER \'bob\'@\'localhost\'\\G\n*************************** 1. row ***************************\nCREATE USER for bob@localhost: CREATE USER `bob`@`localhost` \n IDENTIFIED VIA mysql_native_password\n USING \'*975B2CD4FF9AE554FE8AD33168FBFC326D2021DD\'\n OR unix_socket\n\nIf the user\'s password is updated, but unix_socket authentication is not\nspecified in the IDENTIFIED VIA clause, unix_socket authentication will no\nlonger be permitted.\n\nALTER USER \'bob\'@\'localhost\' IDENTIFIED VIA mysql_native_password \n USING PASSWORD(\'pwd2\');\n\nSHOW CREATE USER \'bob\'@\'localhost\'\\G\n*************************** 1. row ***************************\nCREATE USER for bob@localhost: CREATE USER `bob`@`localhost` \n IDENTIFIED BY PASSWORD \'*38366FDA01695B6A5A9DD4E428D9FB8F7EB75512\'\n\nIDENTIFIED BY \'password\'\n------------------------\n\nThe optional IDENTIFIED BY clause can be used to provide an account with a\npassword. The password should be specified in plain text. It will be hashed by\nthe PASSWORD function prior to being stored to the mysql.user table.\n\nFor example, if our password is mariadb, then we can set the account\'s\npassword with:\n\nALTER USER foo2@test IDENTIFIED BY \'mariadb\';\n\nIf you do not specify a password with the IDENTIFIED BY clause, the user will\nbe able to connect without a password. A blank password is not a wildcard to\nmatch any password. The user must connect without providing a password if no\npassword is set.\n\nThe only authentication plugins that this clause supports are\nmysql_native_password and mysql_old_password.\n\nIDENTIFIED BY PASSWORD \'password_hash\'\n--------------------------------------\n\nThe optional IDENTIFIED BY PASSWORD clause can be used to provide an account\nwith a password that has already been hashed. The password should be specified\nas a hash that was provided by the PASSWORD#function. It will be stored to the\nmysql.user table as-is.\n\nFor example, if our password is mariadb, then we can find the hash with:\n\nSELECT PASSWORD(\'mariadb\');\n+-------------------------------------------+\n| PASSWORD(\'mariadb\') |\n+-------------------------------------------+\n| *54958E764CE10E50764C2EECBB71D01F08549980 |\n+-------------------------------------------+\n\nAnd then we can set an account\'s password with the hash:\n\nALTER USER foo2@test ','','https://mariadb.com/kb/en/alter-user/'); +update help_topic set description = CONCAT(description, '\n IDENTIFIED BY PASSWORD \'*54958E764CE10E50764C2EECBB71D01F08549980\';\n\nIf you do not specify a password with the IDENTIFIED BY clause, the user will\nbe able to connect without a password. A blank password is not a wildcard to\nmatch any password. The user must connect without providing a password if no\npassword is set.\n\nThe only authentication plugins that this clause supports are\nmysql_native_password and mysql_old_password.\n\nIDENTIFIED {VIA|WITH} authentication_plugin\n-------------------------------------------\n\nThe optional IDENTIFIED VIA authentication_plugin allows you to specify that\nthe account should be authenticated by a specific authentication plugin. The\nplugin name must be an active authentication plugin as per SHOW PLUGINS. If it\ndoesn\'t show up in that output, then you will need to install it with INSTALL\nPLUGIN or INSTALL SONAME.\n\nFor example, this could be used with the PAM authentication plugin:\n\nALTER USER foo2@test IDENTIFIED VIA pam;\n\nSome authentication plugins allow additional arguments to be specified after a\nUSING or AS keyword. For example, the PAM authentication plugin accepts a\nservice name:\n\nALTER USER foo2@test IDENTIFIED VIA pam USING \'mariadb\';\n\nThe exact meaning of the additional argument would depend on the specific\nauthentication plugin.\n\nIn MariaDB 10.4 and later, the USING or AS keyword can also be used to provide\na plain-text password to a plugin if it\'s provided as an argument to the\nPASSWORD() function. This is only valid for authentication plugins that have\nimplemented a hook for the PASSWORD() function. For example, the ed25519\nauthentication plugin supports this:\n\nALTER USER safe@\'%\' IDENTIFIED VIA ed25519 USING PASSWORD(\'secret\');\n\nTLS Options\n-----------\n\nBy default, MariaDB transmits data between the server and clients without\nencrypting it. This is generally acceptable when the server and client run on\nthe same host or in networks where security is guaranteed through other means.\nHowever, in cases where the server and client exist on separate networks or\nthey are in a high-risk network, the lack of encryption does introduce\nsecurity concerns as a malicious actor could potentially eavesdrop on the\ntraffic as it is sent over the network between them.\n\nTo mitigate this concern, MariaDB allows you to encrypt data in transit\nbetween the server and clients using the Transport Layer Security (TLS)\nprotocol. TLS was formerly known as Secure Socket Layer (SSL), but strictly\nspeaking the SSL protocol is a predecessor to TLS and, that version of the\nprotocol is now considered insecure. The documentation still uses the term SSL\noften and for compatibility reasons TLS-related server system and status\nvariables still use the prefix ssl_, but internally, MariaDB only supports its\nsecure successors.\n\nSee Secure Connections Overview for more information about how to determine\nwhether your MariaDB server has TLS support.\n\nYou can set certain TLS-related restrictions for specific user accounts. For\ninstance, you might use this with user accounts that require access to\nsensitive data while sending it across networks that you do not control. These\nrestrictions can be enabled for a user account with the CREATE USER, ALTER\nUSER, or GRANT statements. The following options are available:\n\n+---------------------------+------------------------------------------------+\n| Option | Description |\n+---------------------------+------------------------------------------------+\n| REQUIRE NONE | TLS is not required for this account, but can |\n| | still be used. |\n+---------------------------+------------------------------------------------+\n| REQUIRE SSL | The account must use TLS, but no valid X509 |\n| | certificate is required. This option cannot |\n| | be combined with other TLS options. |\n+---------------------------+------------------------------------------------+\n| REQUIRE X509 | The account must use TLS and must have a |\n| | valid X509 certificate. This option implies |\n| | REQUIRE SSL. This option cannot be combined |\n| | with other TLS options. |\n+---------------------------+------------------------------------------------+\n| REQUIRE ISSUER \'issuer\' | The account must use TLS and must have a |\n| | valid X509 certificate. Also, the Certificate |\n| | Authority must be the one specified via the |\n| | string issuer. This option implies REQUIRE |\n| | X509. This option can be combined with the |\n| | SUBJECT, and CIPHER options in any order. |\n+---------------------------+------------------------------------------------+\n| REQUIRE SUBJECT \'subject\' | The account must use TLS and must have a |\n| | valid X509 certificate. Also, the |\n| | certificate\'s Subject must be the one |\n| | specified via the string subject. This option |\n| | implies REQUIRE X509. This option can be |\n| | combined with the ISSUER, and CIPHER options |') WHERE help_topic_id = 105; +update help_topic set description = CONCAT(description, '\n| | in any order. |\n+---------------------------+------------------------------------------------+\n| REQUIRE CIPHER \'cipher\' | The account must use TLS, but no valid X509 |\n| | certificate is required. Also, the encryption |\n| | used for the connection must use a specific |\n| | cipher method specified in the string cipher. |\n| | This option implies REQUIRE SSL. This option |\n| | can be combined with the ISSUER, and SUBJECT |\n| | options in any order. |\n+---------------------------+------------------------------------------------+\n\nThe REQUIRE keyword must be used only once for all specified options, and the\nAND keyword can be used to separate individual options, but it is not required.\n\nFor example, you can alter a user account to require these TLS options with\nthe following:\n\nALTER USER \'alice\'@\'%\'\n REQUIRE SUBJECT \'/CN=alice/O=My Dom, Inc./C=US/ST=Oregon/L=Portland\' AND\n ISSUER \'/C=FI/ST=Somewhere/L=City/ O=Some Company/CN=Peter\nParker/emailAddress=p.parker@marvel.com\'\n AND CIPHER \'SHA-DES-CBC3-EDH-RSA\';\n\nIf any of these options are set for a specific user account, then any client\nwho tries to connect with that user account will have to be configured to\nconnect with TLS.\n\nSee Securing Connections for Client and Server for information on how to\nenable TLS on the client and server.\n\nResource Limit Options\n----------------------\n\nIt is possible to set per-account limits for certain server resources. The\nfollowing table shows the values that can be set per account:\n\n+------------------------------------+---------------------------------------+\n| Limit Type | Description |\n+------------------------------------+---------------------------------------+\n| MAX_QUERIES_PER_HOUR | Number of statements that the |\n| | account can issue per hour |\n| | (including updates) |\n+------------------------------------+---------------------------------------+\n| MAX_UPDATES_PER_HOUR | Number of updates (not queries) that |\n| | the account can issue per hour |\n+------------------------------------+---------------------------------------+\n| MAX_CONNECTIONS_PER_HOUR | Number of connections that the |\n| | account can start per hour |\n+------------------------------------+---------------------------------------+\n| MAX_USER_CONNECTIONS | Number of simultaneous connections |\n| | that can be accepted from the same |\n| | account; if it is 0, max_connections |\n| | will be used instead; if |\n| | max_connections is 0, there is no |\n| | limit for this account\'s |\n| | simultaneous connections. |\n+------------------------------------+---------------------------------------+\n| MAX_STATEMENT_TIME | Timeout, in seconds, for statements |\n| | executed by the user. See also |\n| | Aborting Statements that Exceed a |\n| | Certain Time to Execute. |\n+------------------------------------+---------------------------------------+\n\nIf any of these limits are set to 0, then there is no limit for that resource\nfor that user.\n\nHere is an example showing how to set an account\'s resource limits:\n\nALTER USER \'someone\'@\'localhost\' WITH\n MAX_USER_CONNECTIONS 10\n MAX_QUERIES_PER_HOUR 200;\n\nThe resources are tracked per account, which means \'user\'@\'server\'; not per\nuser name or per connection.\n\nThe count can be reset for all users using FLUSH USER_RESOURCES, FLUSH\nPRIVILEGES or mysqladmin reload.\n\nPer account resource limits are stored in the user table, in the mysql\ndatabase. Columns used for resources limits are named max_questions,\nmax_updates, max_connections (for MAX_CONNECTIONS_PER_HOUR), and\nmax_user_connections (for MAX_USER_CONNECTIONS).\n\nPassword Expiry\n---------------\n\nMariaDB starting with 10.4.3\n----------------------------\nBesides automatic password expiry, as determined by default_password_lifetime,\npassword expiry times can be set on an individual user basis, overriding the\nglobal setting, for example:\n\nALTER USER \'monty\'@\'localhost\' PASSWORD EXPIRE INTERVAL 120 DAY;\nALTER USER \'monty\'@\'localhost\' PASSWORD EXPIRE NEVER;\nALTER USER \'monty\'@\'localhost\' PASSWORD EXPIRE DEFAULT;\n\nSee User Password Expiry for more details.\n\nAccount Locking\n---------------\n\nMariaDB starting with 10.4.2\n----------------------------\nAccount locking permits privileged administrators to lock/unlock user\naccounts. No new client connections will be permitted if an account is locked\n(existing connections are not affected). For example:\n\nALTER USER \'marijn\'@\'localhost\' ACCOUNT LOCK;\n\nSee Account Locking for more details.\n') WHERE help_topic_id = 105; +update help_topic set description = CONCAT(description, '\nFrom MariaDB 10.4.7 and MariaDB 10.5.8, the lock_option and password_option\nclauses can occur in either order.\n\nURL: https://mariadb.com/kb/en/alter-user/') WHERE help_topic_id = 105; +insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (106,10,'DROP USER','Syntax\n------\n\nDROP USER [IF EXISTS] user_name [, user_name] ...\n\nDescription\n-----------\n\nThe DROP USER statement removes one or more MariaDB accounts. It removes\nprivilege rows for the account from all grant tables. To use this statement,\nyou must have the global CREATE USER privilege or the DELETE privilege for the\nmysql database. Each account is named using the same format as for the CREATE\nUSER statement; for example, \'jeffrey\'@\'localhost\'. If you specify only the\nuser name part of the account name, a host name part of \'%\' is used. For\nadditional information about specifying account names, see CREATE USER.\n\nNote that, if you specify an account that is currently connected, it will not\nbe deleted until the connection is closed. The connection will not be\nautomatically closed.\n\nIf any of the specified user accounts do not exist, ERROR 1396 (HY000)\nresults. If an error occurs, DROP USER will still drop the accounts that do\nnot result in an error. Only one error is produced for all users which have\nnot been dropped:\n\nERROR 1396 (HY000): Operation DROP USER failed for \'u1\'@\'%\',\'u2\'@\'%\'\n\nFailed CREATE or DROP operations, for both users and roles, produce the same\nerror code.\n\nIF EXISTS\n---------\n\nIf the IF EXISTS clause is used, MariaDB will return a note instead of an\nerror if the user does not exist.\n\nExamples\n--------\n\nDROP USER bob;\n\nIF EXISTS:\n\nDROP USER bob;\nERROR 1396 (HY000): Operation DROP USER failed for \'bob\'@\'%\'\n\nDROP USER IF EXISTS bob;\nQuery OK, 0 rows affected, 1 warning (0.00 sec)\n\nSHOW WARNINGS;\n+-------+------+---------------------------------------------+\n| Level | Code | Message |\n+-------+------+---------------------------------------------+\n| Note | 1974 | Can\'t drop user \'bob\'@\'%\'; it doesn\'t exist |\n+-------+------+---------------------------------------------+\n\nURL: https://mariadb.com/kb/en/drop-user/','','https://mariadb.com/kb/en/drop-user/'); +insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (107,10,'GRANT','Syntax\n------\n\nGRANT\n priv_type [(column_list)]\n [, priv_type [(column_list)]] ...\n ON [object_type] priv_level\n TO user_specification [ user_options ...]\n\nuser_specification:\n username [authentication_option]\n | PUBLIC\nauthentication_option:\n IDENTIFIED BY \'password\'\n | IDENTIFIED BY PASSWORD \'password_hash\'\n | IDENTIFIED {VIA|WITH} authentication_rule [OR authentication_rule ...]\n\nauthentication_rule:\n authentication_plugin\n | authentication_plugin {USING|AS} \'authentication_string\'\n | authentication_plugin {USING|AS} PASSWORD(\'password\')\n\nGRANT PROXY ON username\n TO user_specification [, user_specification ...]\n [WITH GRANT OPTION]\n\nGRANT rolename TO grantee [, grantee ...]\n [WITH ADMIN OPTION]\n\ngrantee:\n rolename\n username [authentication_option]\n\nuser_options:\n [REQUIRE {NONE | tls_option [[AND] tls_option] ...}]\n [WITH with_option [with_option] ...]\n\nobject_type:\n TABLE\n | FUNCTION\n | PROCEDURE\n | PACKAGE\n\npriv_level:\n *\n | *.*\n | db_name.*\n | db_name.tbl_name\n | tbl_name\n | db_name.routine_name\n\nwith_option:\n GRANT OPTION\n | resource_option\n\nresource_option:\n MAX_QUERIES_PER_HOUR count\n | MAX_UPDATES_PER_HOUR count\n | MAX_CONNECTIONS_PER_HOUR count\n | MAX_USER_CONNECTIONS count\n | MAX_STATEMENT_TIME time\n\ntls_option:\n SSL\n | X509\n | CIPHER \'cipher\'\n | ISSUER \'issuer\'\n | SUBJECT \'subject\'\n\nDescription\n-----------\n\nThe GRANT statement allows you to grant privileges or roles to accounts. To\nuse GRANT, you must have the GRANT OPTION privilege, and you must have the\nprivileges that you are granting.\n\nUse the REVOKE statement to revoke privileges granted with the GRANT statement.\n\nUse the SHOW GRANTS statement to determine what privileges an account has.\n\nAccount Names\n-------------\n\nFor GRANT statements, account names are specified as the username argument in\nthe same way as they are for CREATE USER statements. See account names from\nthe CREATE USER page for details on how account names are specified.\n\nImplicit Account Creation\n-------------------------\n\nThe GRANT statement also allows you to implicitly create accounts in some\ncases.\n\nIf the account does not yet exist, then GRANT can implicitly create it. To\nimplicitly create an account with GRANT, a user is required to have the same\nprivileges that would be required to explicitly create the account with the\nCREATE USER statement.\n\nIf the NO_AUTO_CREATE_USER SQL_MODE is set, then accounts can only be created\nif authentication information is specified, or with a CREATE USER statement.\nIf no authentication information is provided, GRANT will produce an error when\nthe specified account does not exist, for example:\n\nshow variables like \'%sql_mode%\' ;\n+---------------+--------------------------------------------+\n| Variable_name | Value |\n+---------------+--------------------------------------------+\n| sql_mode | NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION |\n+---------------+--------------------------------------------+\n\nGRANT USAGE ON *.* TO \'user123\'@\'%\' IDENTIFIED BY \'\';\nERROR 1133 (28000): Can\'t find any matching row in the user table\n\nGRANT USAGE ON *.* TO \'user123\'@\'%\' \n IDENTIFIED VIA PAM using \'mariadb\' require ssl ;\nQuery OK, 0 rows affected (0.00 sec)\n\nselect host, user from mysql.user where user=\'user123\' ;\n\n+------+----------+\n| host | user |\n+------+----------+\n| % | user123 |\n+------+----------+\n\nPrivilege Levels\n----------------\n\nPrivileges can be set globally, for an entire database, for a table or\nroutine, or for individual columns in a table. Certain privileges can only be\nset at certain levels.\n\n* Global privileges priv_type are granted using *.* for\npriv_level. Global privileges include privileges to administer the database\nand manage user accounts, as well as privileges for all tables, functions, and\nprocedures. Global privileges are stored in the mysql.user table prior to\nMariaDB 10.4, and in mysql.global_priv table afterwards.\n* Database privileges priv_type are granted using db_name.*\nfor priv_level, or using just * to use default database. Database\nprivileges include privileges to create tables and functions, as well as\nprivileges for all tables, functions, and procedures in the database. Database\nprivileges are stored in the mysql.db table.\n* Table privileges priv_type are granted using db_name.tbl_name\nfor priv_level, or using just tbl_name to specify a table in the default\ndatabase. The TABLE keyword is optional. Table privileges include the\nability to select and change data in the table. Certain table privileges can\nbe granted for individual columns.\n* Column privileges priv_type are granted by specifying a table for\npriv_level and providing a column list after the privilege type. They allow\nyou to control exactly which columns in a table users can select and change.\n* Function privileges priv_type are granted using FUNCTION db_name.routine_name\nfor priv_level, or using just FUNCTION routine_name to specify a function\nin the default database.\n* Procedure privileges priv_type are granted using PROCEDURE\ndb_name.routine_name\nfor priv_level, or using just PROCEDURE routine_name to specify a procedure\nin the default database.\n\nThe USAGE Privilege\n-------------------\n\nThe USAGE privilege grants no real privileges. The SHOW GRANTS statement will\nshow a global USAGE privilege for a newly-created user. You can use USAGE with','','https://mariadb.com/kb/en/grant/'); +update help_topic set description = CONCAT(description, '\nthe GRANT statement to change options like GRANT OPTION and\nMAX_USER_CONNECTIONS without changing any account privileges.\n\nThe ALL PRIVILEGES Privilege\n----------------------------\n\nThe ALL PRIVILEGES privilege grants all available privileges. Granting all\nprivileges only affects the given privilege level. For example, granting all\nprivileges on a table does not grant any privileges on the database or\nglobally.\n\nUsing ALL PRIVILEGES does not grant the special GRANT OPTION privilege.\n\nYou can use ALL instead of ALL PRIVILEGES.\n\nThe GRANT OPTION Privilege\n--------------------------\n\nUse the WITH GRANT OPTION clause to give users the ability to grant privileges\nto other users at the given privilege level. Users with the GRANT OPTION\nprivilege can only grant privileges they have. They cannot grant privileges at\na higher privilege level than they have the GRANT OPTION privilege.\n\nThe GRANT OPTION privilege cannot be set for individual columns. If you use\nWITH GRANT OPTION when specifying column privileges, the GRANT OPTION\nprivilege will be granted for the entire table.\n\nUsing the WITH GRANT OPTION clause is equivalent to listing GRANT OPTION as a\nprivilege.\n\nGlobal Privileges\n-----------------\n\nThe following table lists the privileges that can be granted globally. You can\nalso grant all database, table, and function privileges globally. When granted\nglobally, these privileges apply to all databases, tables, or functions,\nincluding those created later.\n\nTo set a global privilege, use *.* for priv_level.\n\nBINLOG ADMIN\n------------\n\nEnables administration of the binary log, including the PURGE BINARY LOGS\nstatement and setting the system variables:\n\n* binlog_annotate_row_events\n* binlog_cache_size\n* binlog_commit_wait_count\n* binlog_commit_wait_usec\n* binlog_direct_non_transactional_updates\n* binlog_expire_logs_seconds\n* binlog_file_cache_size\n* binlog_format\n* binlog_row_image\n* binlog_row_metadata\n* binlog_stmt_cache_size\n* expire_logs_days\n* log_bin_compress\n* log_bin_compress_min_len\n* log_bin_trust_function_creators\n* max_binlog_cache_size\n* max_binlog_size\n* max_binlog_stmt_cache_size\n* sql_log_bin and\n* sync_binlog.\n\nAdded in MariaDB 10.5.2.\n\nBINLOG MONITOR\n--------------\n\nNew name for REPLICATION CLIENT from MariaDB 10.5.2, (REPLICATION CLIENT still\nsupported as an alias for compatibility purposes). Permits running SHOW\ncommands related to the binary log, in particular the SHOW BINLOG STATUS and\nSHOW BINARY LOGS statements. Unlike REPLICATION CLIENT prior to MariaDB 10.5,\nSHOW REPLICA STATUS isn\'t included in this privilege, and REPLICA MONITOR is\nrequired.\n\nBINLOG REPLAY\n-------------\n\nEnables replaying the binary log with the BINLOG statement (generated by\nmariadb-binlog), executing SET timestamp when secure_timestamp is set to\nreplication, and setting the session values of system variables usually\nincluded in BINLOG output, in particular:\n\n* gtid_domain_id\n* gtid_seq_no\n* pseudo_thread_id\n* server_id.\n\nAdded in MariaDB 10.5.2\n\nCONNECTION ADMIN\n----------------\n\nEnables administering connection resource limit options. This includes\nignoring the limits specified by:\n\n* max_connections\n* max_user_connections and\n* max_password_errors.\n\nThe statements specified in init_connect are not executed, killing connections\nand queries owned by other users is permitted. The following\nconnection-related system variables can be changed:\n\n* connect_timeout\n* disconnect_on_expired_password\n* extra_max_connections\n* init_connect\n* max_connections\n* max_connect_errors\n* max_password_errors\n* proxy_protocol_networks\n* secure_auth\n* slow_launch_time\n* thread_pool_exact_stats\n* thread_pool_dedicated_listener\n* thread_pool_idle_timeout\n* thread_pool_max_threads\n* thread_pool_min_threads\n* thread_pool_oversubscribe\n* thread_pool_prio_kickup_timer\n* thread_pool_priority\n* thread_pool_size, and\n* thread_pool_stall_limit.\n\nAdded in MariaDB 10.5.2.\n\nCREATE USER\n-----------\n\nCreate a user using the CREATE USER statement, or implicitly create a user\nwith the GRANT statement.\n\nFEDERATED ADMIN\n---------------\n\nExecute CREATE SERVER, ALTER SERVER, and DROP SERVER statements. Added in\nMariaDB 10.5.2.\n\nFILE\n----\n\nRead and write files on the server, using statements like LOAD DATA INFILE or\nfunctions like LOAD_FILE(). Also needed to create CONNECT outward tables.\nMariaDB server must have the permissions to access those files.\n\nGRANT OPTION\n------------\n\nGrant global privileges. You can only grant privileges that you have.\n\nPROCESS\n-------\n\nShow information about the active processes, for example via SHOW PROCESSLIST\nor mysqladmin processlist. If you have the PROCESS privilege, you can see all\nthreads. Otherwise, you can see only your own threads (that is, threads\nassociated with the MariaDB account that you are using).\n\nREAD_ONLY ADMIN\n---------------\n\nUser can set the read_only system variable and allows the user to perform\nwrite operations, even when the read_only option is active. Added in MariaDB\n10.5.2.\n\nFrom MariaDB 10.11.0, the READ_ONLY ADMIN privilege has been removed from\nSUPER. The benefit of this is that one can remove the READ_ONLY ADMIN\nprivilege from all users and ensure that no one can make any changes on any\nnon-temporary tables. This is useful on replicas when one wants to ensure that\nthe replica is kept identical to the primary.\n\nRELOAD\n------\n\nExecute FLUSH statements or equivalent mariadb-admin/mysqladmin commands.\n') WHERE help_topic_id = 107; +update help_topic set description = CONCAT(description, '\nREPLICATION CLIENT\n------------------\n\nExecute SHOW MASTER STATUS and SHOW BINARY LOGS informative statements.\nRenamed to BINLOG MONITOR in MariaDB 10.5.2 (but still supported as an alias\nfor compatibility reasons). SHOW SLAVE STATUS was part of REPLICATION CLIENT\nprior to MariaDB 10.5.\n\nREPLICATION MASTER ADMIN\n------------------------\n\nPermits administration of primary servers, including the SHOW REPLICA HOSTS\nstatement, and setting the gtid_binlog_state, gtid_domain_id,\nmaster_verify_checksum and server_id system variables. Added in MariaDB 10.5.2.\n\nREPLICA MONITOR\n---------------\n\nPermit SHOW REPLICA STATUS and SHOW RELAYLOG EVENTS. From MariaDB 10.5.9.\n\nWhen a user would upgrade from an older major release to a MariaDB 10.5 minor\nrelease prior to MariaDB 10.5.9, certain user accounts would lose\ncapabilities. For example, a user account that had the REPLICATION CLIENT\nprivilege in older major releases could run SHOW REPLICA STATUS, but after\nupgrading to a MariaDB 10.5 minor release prior to MariaDB 10.5.9, they could\nno longer run SHOW REPLICA STATUS, because that statement was changed to\nrequire the REPLICATION REPLICA ADMIN privilege.\n\nThis issue is fixed in MariaDB 10.5.9 with this new privilege, which now\ngrants the user the ability to execute SHOW [ALL] (SLAVE | REPLICA) STATUS.\n\nWhen a database is upgraded from an older major release to MariaDB Server\n10.5.9 or later, any user accounts with the REPLICATION CLIENT or REPLICATION\nSLAVE privileges will automatically be granted the new REPLICA MONITOR\nprivilege. The privilege fix occurs when the server is started up, not when\nmariadb-upgrade is performed.\n\nHowever, when a database is upgraded from an early 10.5 minor release to\n10.5.9 and later, the user will have to fix any user account privileges\nmanually.\n\nREPLICATION REPLICA\n-------------------\n\nSynonym for REPLICATION SLAVE. From MariaDB 10.5.1.\n\nREPLICATION SLAVE\n-----------------\n\nAccounts used by replica servers on the primary need this privilege. This is\nneeded to get the updates made on the master. From MariaDB 10.5.1, REPLICATION\nREPLICA is an alias for REPLICATION SLAVE.\n\nREPLICATION SLAVE ADMIN\n-----------------------\n\nPermits administering replica servers, including START REPLICA/SLAVE, STOP\nREPLICA/SLAVE, CHANGE MASTER, SHOW REPLICA/SLAVE STATUS, SHOW RELAYLOG EVENTS\nstatements, replaying the binary log with the BINLOG statement (generated by\nmariadb-binlog), and setting the system variables:\n\n* gtid_cleanup_batch_size\n* gtid_ignore_duplicates\n* gtid_pos_auto_engines\n* gtid_slave_pos\n* gtid_strict_mode\n* init_slave\n* read_binlog_speed_limit\n* relay_log_purge\n* relay_log_recovery\n* replicate_do_db\n* replicate_do_table\n* replicate_events_marked_for_skip\n* replicate_ignore_db\n* replicate_ignore_table\n* replicate_wild_do_table\n* replicate_wild_ignore_table\n* slave_compressed_protocol\n* slave_ddl_exec_mode\n* slave_domain_parallel_threads\n* slave_exec_mode\n* slave_max_allowed_packet\n* slave_net_timeout\n* slave_parallel_max_queued\n* slave_parallel_mode\n* slave_parallel_threads\n* slave_parallel_workers\n* slave_run_triggers_for_rbr\n* slave_sql_verify_checksum\n* slave_transaction_retry_interval\n* slave_type_conversions\n* sync_master_info\n* sync_relay_log, and\n* sync_relay_log_info.\n\nAdded in MariaDB 10.5.2.\n\nSET USER\n--------\n\nEnables setting the DEFINER when creating triggers, views, stored functions\nand stored procedures. Added in MariaDB 10.5.2.\n\nSHOW DATABASES\n--------------\n\nList all databases using the SHOW DATABASES statement. Without the SHOW\nDATABASES privilege, you can still issue the SHOW DATABASES statement, but it\nwill only list databases containing tables on which you have privileges.\n\nSHUTDOWN\n--------\n\nShut down the server using SHUTDOWN or the mysqladmin shutdown command.\n\nSUPER\n-----\n\nExecute superuser statements: CHANGE MASTER TO, KILL (users who do not have\nthis privilege can only KILL their own threads), PURGE LOGS, SET global system\nvariables, or the mysqladmin debug command. Also, this permission allows the\nuser to write data even if the read_only startup option is set, enable or\ndisable logging, enable or disable replication on replica, specify a DEFINER\nfor statements that support that clause, connect once reaching the\nMAX_CONNECTIONS. If a statement has been specified for the init-connect mysqld\noption, that command will not be executed when a user with SUPER privileges\nconnects to the server.\n\nThe SUPER privilege has been split into multiple smaller privileges from\nMariaDB 10.5.2 to allow for more fine-grained privileges, although it remains\nan alias for these smaller privileges.\n\nFrom MariaDB 10.11.0, the READ_ONLY ADMIN privilege has been removed from\nSUPER. The benefit of this is that one can remove the READ_ONLY ADMIN\nprivilege from all users and ensure that no one can make any changes on any\nnon-temporary tables. This is useful on replicas when one wants to ensure that\nthe replica is kept identical to the primary.\n\nDatabase Privileges\n-------------------\n\nThe following table lists the privileges that can be granted at the database\nlevel. You can also grant all table and function privileges at the database\nlevel. Table and function privileges on a database apply to all tables or\nfunctions in that database, including those created later.\n\nTo set a privilege for a database, specify the database using db_name.* for\npriv_level, or just use * to specify the default database.\n') WHERE help_topic_id = 107; +update help_topic set description = CONCAT(description, '\n+----------------------------------+-----------------------------------------+\n| Privilege | Description |\n+----------------------------------+-----------------------------------------+\n| CREATE | Create a database using the CREATE |\n| | DATABASE statement, when the privilege |\n| | is granted for a database. You can |\n| | grant the CREATE privilege on |\n| | databases that do not yet exist. This |\n| | also grants the CREATE privilege on |\n| | all tables in the database. |\n+----------------------------------+-----------------------------------------+\n| CREATE ROUTINE | Create Stored Programs using the |\n| | CREATE PROCEDURE and CREATE FUNCTION |\n| | statements. |\n+----------------------------------+-----------------------------------------+\n| CREATE TEMPORARY TABLES | Create temporary tables with the |\n| | CREATE TEMPORARY TABLE statement. This |\n| | privilege enable writing and dropping |\n| | those temporary tables |\n+----------------------------------+-----------------------------------------+\n| DROP | Drop a database using the DROP |\n| | DATABASE statement, when the privilege |\n| | is granted for a database. This also |\n| | grants the DROP privilege on all |\n| | tables in the database. |\n+----------------------------------+-----------------------------------------+\n| EVENT | Create, drop and alter EVENTs. |\n+----------------------------------+-----------------------------------------+\n| GRANT OPTION | Grant database privileges. You can |\n| | only grant privileges that you have. |\n+----------------------------------+-----------------------------------------+\n| LOCK TABLES | Acquire explicit locks using the LOCK |\n| | TABLES statement; you also need to |\n| | have the SELECT privilege on a table, |\n| | in order to lock it. |\n+----------------------------------+-----------------------------------------+\n\nTable Privileges\n----------------\n\n+----------------------------------+-----------------------------------------+\n| Privilege | Description |\n+----------------------------------+-----------------------------------------+\n| ALTER | Change the structure of an existing |\n| | table using the ALTER TABLE statement. |\n+----------------------------------+-----------------------------------------+\n| CREATE | Create a table using the CREATE TABLE |\n| | statement. You can grant the CREATE |\n| | privilege on tables that do not yet |\n| | exist. |\n+----------------------------------+-----------------------------------------+\n| CREATE VIEW | Create a view using the CREATE_VIEW |\n| | statement. |\n+----------------------------------+-----------------------------------------+\n| DELETE | Remove rows from a table using the |\n| | DELETE statement. |\n+----------------------------------+-----------------------------------------+\n| DELETE HISTORY | Remove historical rows from a table |\n| | using the DELETE HISTORY statement. |\n| | Displays as DELETE VERSIONING ROWS |\n| | when running SHOW GRANTS until MariaDB |\n| | 10.3.15 and until MariaDB 10.4.5 |\n| | (MDEV-17655), or when running SHOW |\n| | PRIVILEGES until MariaDB 10.5.2, |\n| | MariaDB 10.4.13 and MariaDB 10.3.23 |\n| | (MDEV-20382). From MariaDB 10.3.4. |\n| | From MariaDB 10.3.5, if a user has the |\n| | SUPER privilege but not this |\n| | privilege, running mysql_upgrade will |\n| | grant this privilege as well. |\n+----------------------------------+-----------------------------------------+\n| DROP | Drop a table using the DROP TABLE |\n| | statement or a view using the DROP |') WHERE help_topic_id = 107; +update help_topic set description = CONCAT(description, '\n| | VIEW statement. Also required to |\n| | execute the TRUNCATE TABLE statement. |\n+----------------------------------+-----------------------------------------+\n| GRANT OPTION | Grant table privileges. You can only |\n| | grant privileges that you have. |\n+----------------------------------+-----------------------------------------+\n| INDEX | Create an index on a table using the |\n| | CREATE INDEX statement. Without the |\n| | INDEX privilege, you can still create |\n| | indexes when creating a table using |\n| | the CREATE TABLE statement if the you |\n| | have the CREATE privilege, and you can |\n| | create indexes using the ALTER TABLE |\n| | statement if you have the ALTER |\n| | privilege. |\n+----------------------------------+-----------------------------------------+\n| INSERT | Add rows to a table using the INSERT |\n| | statement. The INSERT privilege can |\n| | also be set on individual columns; see |\n| | Column Privileges below for details. |\n+----------------------------------+-----------------------------------------+\n| REFERENCES | Unused. |\n+----------------------------------+-----------------------------------------+\n| SELECT | Read data from a table using the |\n| | SELECT statement. The SELECT privilege |\n| | can also be set on individual columns; |\n| | see Column Privileges below for |\n| | details. |\n+----------------------------------+-----------------------------------------+\n| SHOW VIEW | Show the CREATE VIEW statement to |\n| | create a view using the SHOW CREATE |\n| | VIEW statement. |\n+----------------------------------+-----------------------------------------+\n| TRIGGER | Execute triggers associated to tables |\n| | you update, execute the CREATE TRIGGER |\n| | and DROP TRIGGER statements. You will |\n| | still be able to see triggers. |\n+----------------------------------+-----------------------------------------+\n| UPDATE | Update existing rows in a table using |\n| | the UPDATE statement. UPDATE |\n| | statements usually include a WHERE |\n| | clause to update only certain rows. |\n| | You must have SELECT privileges on the |\n| | table or the appropriate columns for |\n| | the WHERE clause. The UPDATE privilege |\n| | can also be set on individual columns; |\n| | see Column Privileges below for |\n| | details. |\n+----------------------------------+-----------------------------------------+\n\nColumn Privileges\n-----------------\n\nSome table privileges can be set for individual columns of a table. To use\ncolumn privileges, specify the table explicitly and provide a list of column\nnames after the privilege type. For example, the following statement would\nallow the user to read the names and positions of employees, but not other\ninformation from the same table, such as salaries.\n\nGRANT SELECT (name, position) on Employee to \'jeffrey\'@\'localhost\';\n\n+----------------------------------+-----------------------------------------+\n| Privilege | Description |\n+----------------------------------+-----------------------------------------+\n| INSERT (column_list) | Add rows specifying values in columns |\n| | using the INSERT statement. If you |\n| | only have column-level INSERT |\n| | privileges, you must specify the |\n| | columns you are setting in the INSERT |\n| | statement. All other columns will be |\n| | set to their default values, or NULL. |\n+----------------------------------+-----------------------------------------+\n| REFERENCES (column_list) | Unused. |\n+----------------------------------+-----------------------------------------+\n| SELECT (column_list) | Read values in columns using the |\n| | SELECT statement. You cannot access or |') WHERE help_topic_id = 107; +update help_topic set description = CONCAT(description, '\n| | query any columns for which you do not |\n| | have SELECT privileges, including in |\n| | WHERE, ON, GROUP BY, and ORDER BY |\n| | clauses. |\n+----------------------------------+-----------------------------------------+\n| UPDATE (column_list) | Update values in columns of existing |\n| | rows using the UPDATE statement. |\n| | UPDATE statements usually include a |\n| | WHERE clause to update only certain |\n| | rows. You must have SELECT privileges |\n| | on the table or the appropriate |\n| | columns for the WHERE clause. |\n+----------------------------------+-----------------------------------------+\n\nFunction Privileges\n-------------------\n\n+----------------------------------+-----------------------------------------+\n| Privilege | Description |\n+----------------------------------+-----------------------------------------+\n| ALTER ROUTINE | Change the characteristics of a stored |\n| | function using the ALTER FUNCTION |\n| | statement. |\n+----------------------------------+-----------------------------------------+\n| EXECUTE | Use a stored function. You need SELECT |\n| | privileges for any tables or columns |\n| | accessed by the function. |\n+----------------------------------+-----------------------------------------+\n| GRANT OPTION | Grant function privileges. You can |\n| | only grant privileges that you have. |\n+----------------------------------+-----------------------------------------+\n\nProcedure Privileges\n--------------------\n\n+----------------------------------+-----------------------------------------+\n| Privilege | Description |\n+----------------------------------+-----------------------------------------+\n| ALTER ROUTINE | Change the characteristics of a stored |\n| | procedure using the ALTER PROCEDURE |\n| | statement. |\n+----------------------------------+-----------------------------------------+\n| EXECUTE | Execute a stored procedure using the |\n| | CALL statement. The privilege to call |\n| | a procedure may allow you to perform |\n| | actions you wouldn\'t otherwise be able |\n| | to do, such as insert rows into a |\n| | table. |\n+----------------------------------+-----------------------------------------+\n| GRANT OPTION | Grant procedure privileges. You can |\n| | only grant privileges that you have. |\n+----------------------------------+-----------------------------------------+\n\nGRANT EXECUTE ON PROCEDURE mysql.create_db TO maintainer;\n\nProxy Privileges\n----------------\n\n+----------------------------------+-----------------------------------------+\n| Privilege | Description |\n+----------------------------------+-----------------------------------------+\n| PROXY | Permits one user to be a proxy for |\n| | another. |\n+----------------------------------+-----------------------------------------+\n\nThe PROXY privilege allows one user to proxy as another user, which means\ntheir privileges change to that of the proxy user, and the CURRENT_USER()\nfunction returns the user name of the proxy user.\n\nThe PROXY privilege only works with authentication plugins that support it.\nThe default mysql_native_password authentication plugin does not support proxy\nusers.\n\nThe pam authentication plugin is the only plugin included with MariaDB that\ncurrently supports proxy users. The PROXY privilege is commonly used with the\npam authentication plugin to enable user and group mapping with PAM.\n\nFor example, to grant the PROXY privilege to an anonymous account that\nauthenticates with the pam authentication plugin, you could execute the\nfollowing:\n\nCREATE USER \'dba\'@\'%\' IDENTIFIED BY \'strongpassword\';\nGRANT ALL PRIVILEGES ON *.* TO \'dba\'@\'%\' ;\n\nCREATE USER \'\'@\'%\' IDENTIFIED VIA pam USING \'mariadb\';\nGRANT PROXY ON \'dba\'@\'%\' TO \'\'@\'%\';\n\nA user account can only grant the PROXY privilege for a specific user account\nif the granter also has the PROXY privilege for that specific user account,\nand if that privilege is defined WITH GRANT OPTION. For example, the following\nexample fails because the granter does not have the PROXY privilege for that\nspecific user account at all:\n\nSELECT USER(), CURRENT_USER();\n+-----------------+-----------------+') WHERE help_topic_id = 107; +update help_topic set description = CONCAT(description, '\n| USER() | CURRENT_USER() |\n+-----------------+-----------------+\n| alice@localhost | alice@localhost |\n+-----------------+-----------------+\n\nSHOW GRANTS;\n+------------------------------------------------------------------------------\n----------------------------------------+\n| Grants for alice@localhost \n |\n+------------------------------------------------------------------------------\n----------------------------------------+\n| GRANT ALL PRIVILEGES ON *.* TO \'alice\'@\'localhost\' IDENTIFIED BY PASSWORD\n\'*2470C0C06DEE42FD1618BB99005ADCA2EC9D1E19\' |\n+------------------------------------------------------------------------------\n----------------------------------------+\n\nGRANT PROXY ON \'dba\'@\'localhost\' TO \'bob\'@\'localhost\';\nERROR 1698 (28000): Access denied for user \'alice\'@\'localhost\'\n\nAnd the following example fails because the granter does have the PROXY\nprivilege for that specific user account, but it is not defined WITH GRANT\nOPTION:\n\nSELECT USER(), CURRENT_USER();\n+-----------------+-----------------+\n| USER() | CURRENT_USER() |\n+-----------------+-----------------+\n| alice@localhost | alice@localhost |\n+-----------------+-----------------+\n\nSHOW GRANTS;\n+------------------------------------------------------------------------------\n----------------------------------------+\n| Grants for alice@localhost \n |\n+------------------------------------------------------------------------------\n----------------------------------------+\n| GRANT ALL PRIVILEGES ON *.* TO \'alice\'@\'localhost\' IDENTIFIED BY PASSWORD\n\'*2470C0C06DEE42FD1618BB99005ADCA2EC9D1E19\' |\n| GRANT PROXY ON \'dba\'@\'localhost\' TO \'alice\'@\'localhost\' \n |\n+------------------------------------------------------------------------------\n----------------------------------------+\n\nGRANT PROXY ON \'dba\'@\'localhost\' TO \'bob\'@\'localhost\';\nERROR 1698 (28000): Access denied for user \'alice\'@\'localhost\'\n\nBut the following example succeeds because the granter does have the PROXY\nprivilege for that specific user account, and it is defined WITH GRANT OPTION:\n\nSELECT USER(), CURRENT_USER();\n+-----------------+-----------------+\n| USER() | CURRENT_USER() |\n+-----------------+-----------------+\n| alice@localhost | alice@localhost |\n+-----------------+-----------------+\n\nSHOW GRANTS;\n+------------------------------------------------------------------------------\n----------------------------------------------------------+\n| Grants for alice@localhost \n |\n+------------------------------------------------------------------------------\n----------------------------------------------------------+\n| GRANT ALL PRIVILEGES ON *.* TO \'alice\'@\'localhost\' IDENTIFIED BY PASSWORD\n\'*2470C0C06DEE42FD1618BB99005ADCA2EC9D1E19\' WITH GRANT OPTION |\n| GRANT PROXY ON \'dba\'@\'localhost\' TO \'alice\'@\'localhost\' WITH GRANT OPTION \n |\n+------------------------------------------------------------------------------\n----------------------------------------------------------+\n\nGRANT PROXY ON \'dba\'@\'localhost\' TO \'bob\'@\'localhost\';\n\nA user account can grant the PROXY privilege for any other user account if the\ngranter has the PROXY privilege for the \'\'@\'%\' anonymous user account, like\nthis:\n\nGRANT PROXY ON \'\'@\'%\' TO \'dba\'@\'localhost\' WITH GRANT OPTION;\n\nFor example, the following example succeeds because the user can grant the\nPROXY privilege for any other user account:\n\nSELECT USER(), CURRENT_USER();\n+-----------------+-----------------+\n| USER() | CURRENT_USER() |\n+-----------------+-----------------+\n| alice@localhost | alice@localhost |\n+-----------------+-----------------+\n\nSHOW GRANTS;\n+------------------------------------------------------------------------------\n----------------------------------------------------------+\n| Grants for alice@localhost \n |\n+------------------------------------------------------------------------------\n----------------------------------------------------------+\n| GRANT ALL PRIVILEGES ON *.* TO \'alice\'@\'localhost\' IDENTIFIED BY PASSWORD\n\'*2470C0C06DEE42FD1618BB99005ADCA2EC9D1E19\' WITH GRANT OPTION |\n| GRANT PROXY ON \'\'@\'%\' TO \'alice\'@\'localhost\' WITH GRANT OPTION \n |\n+------------------------------------------------------------------------------\n----------------------------------------------------------+\n\nGRANT PROXY ON \'app1_dba\'@\'localhost\' TO \'bob\'@\'localhost\';\nQuery OK, 0 rows affected (0.004 sec)\n\nGRANT PROXY ON \'app2_dba\'@\'localhost\' TO \'carol\'@\'localhost\';\nQuery OK, 0 rows affected (0.004 sec)\n\nThe default root user accounts created by mysql_install_db have this\nprivilege. For example:\n\nGRANT ALL PRIVILEGES ON *.* TO \'root\'@\'localhost\' WITH GRANT OPTION;\nGRANT PROXY ON \'\'@\'%\' TO \'root\'@\'localhost\' WITH GRANT OPTION;\n\nThis allows the default root user accounts to grant the PROXY privilege for\nany other user account, and it also allows the default root user accounts to\ngrant others the privilege to do the same.\n\nAuthentication Options\n----------------------\n') WHERE help_topic_id = 107; +update help_topic set description = CONCAT(description, '\nThe authentication options for the GRANT statement are the same as those for\nthe CREATE USER statement.\n\nIDENTIFIED BY \'password\'\n------------------------\n\nThe optional IDENTIFIED BY clause can be used to provide an account with a\npassword. The password should be specified in plain text. It will be hashed by\nthe PASSWORD function prior to being stored.\n\nFor example, if our password is mariadb, then we can create the user with:\n\nGRANT USAGE ON *.* TO foo2@test IDENTIFIED BY \'mariadb\';\n\nIf you do not specify a password with the IDENTIFIED BY clause, the user will\nbe able to connect without a password. A blank password is not a wildcard to\nmatch any password. The user must connect without providing a password if no\npassword is set.\n\nIf the user account already exists and if you provide the IDENTIFIED BY\nclause, then the user\'s password will be changed. You must have the privileges\nneeded for the SET PASSWORD statement to change a user\'s password with GRANT.\n\nThe only authentication plugins that this clause supports are\nmysql_native_password and mysql_old_password.\n\nIDENTIFIED BY PASSWORD \'password_hash\'\n--------------------------------------\n\nThe optional IDENTIFIED BY PASSWORD clause can be used to provide an account\nwith a password that has already been hashed. The password should be specified\nas a hash that was provided by the PASSWORD function. It will be stored as-is.\n\nFor example, if our password is mariadb, then we can find the hash with:\n\nSELECT PASSWORD(\'mariadb\');\n+-------------------------------------------+\n| PASSWORD(\'mariadb\') |\n+-------------------------------------------+\n| *54958E764CE10E50764C2EECBB71D01F08549980 |\n+-------------------------------------------+\n1 row in set (0.00 sec)\n\nAnd then we can create a user with the hash:\n\nGRANT USAGE ON *.* TO foo2@test IDENTIFIED BY \n PASSWORD \'*54958E764CE10E50764C2EECBB71D01F08549980\';\n\nIf you do not specify a password with the IDENTIFIED BY clause, the user will\nbe able to connect without a password. A blank password is not a wildcard to\nmatch any password. The user must connect without providing a password if no\npassword is set.\n\nIf the user account already exists and if you provide the IDENTIFIED BY\nclause, then the user\'s password will be changed. You must have the privileges\nneeded for the SET PASSWORD statement to change a user\'s password with GRANT.\n\nThe only authentication plugins that this clause supports are\nmysql_native_password and mysql_old_password.\n\nIDENTIFIED {VIA|WITH} authentication_plugin\n-------------------------------------------\n\nThe optional IDENTIFIED VIA authentication_plugin allows you to specify that\nthe account should be authenticated by a specific authentication plugin. The\nplugin name must be an active authentication plugin as per SHOW PLUGINS. If it\ndoesn\'t show up in that output, then you will need to install it with INSTALL\nPLUGIN or INSTALL SONAME.\n\nFor example, this could be used with the PAM authentication plugin:\n\nGRANT USAGE ON *.* TO foo2@test IDENTIFIED VIA pam;\n\nSome authentication plugins allow additional arguments to be specified after a\nUSING or AS keyword. For example, the PAM authentication plugin accepts a\nservice name:\n\nGRANT USAGE ON *.* TO foo2@test IDENTIFIED VIA pam USING \'mariadb\';\n\nThe exact meaning of the additional argument would depend on the specific\nauthentication plugin.\n\nMariaDB starting with 10.4.0\n----------------------------\nThe USING or AS keyword can also be used to provide a plain-text password to a\nplugin if it\'s provided as an argument to the PASSWORD() function. This is\nonly valid for authentication plugins that have implemented a hook for the\nPASSWORD() function. For example, the ed25519 authentication plugin supports\nthis:\n\nCREATE USER safe@\'%\' IDENTIFIED VIA ed25519 \n USING PASSWORD(\'secret\');\n\nMariaDB starting with 10.4.3\n----------------------------\nOne can specify many authentication plugins, they all work as alternatives\nways of authenticating a user:\n\nCREATE USER safe@\'%\' IDENTIFIED VIA ed25519 \n USING PASSWORD(\'secret\') OR unix_socket;\n\nBy default, when you create a user without specifying an authentication\nplugin, MariaDB uses the mysql_native_password plugin.\n\nResource Limit Options\n----------------------\n\nIt is possible to set per-account limits for certain server resources. The\nfollowing table shows the values that can be set per account:\n\n+--------------------------------------+--------------------------------------+\n| Limit Type | Decription |\n+--------------------------------------+--------------------------------------+\n| MAX_QUERIES_PER_HOUR | Number of statements that the |\n| | account can issue per hour |\n| | (including updates) |\n+--------------------------------------+--------------------------------------+\n| MAX_UPDATES_PER_HOUR | Number of updates (not queries) |\n| | that the account can issue per hour |\n+--------------------------------------+--------------------------------------+\n| MAX_CONNECTIONS_PER_HOUR | Number of connections that the |\n| | account can start per hour |\n+--------------------------------------+--------------------------------------+') WHERE help_topic_id = 107; +update help_topic set description = CONCAT(description, '\n| MAX_USER_CONNECTIONS | Number of simultaneous connections |\n| | that can be accepted from the same |\n| | account; if it is 0, |\n| | max_connections will be used |\n| | instead; if max_connections is 0, |\n| | there is no limit for this |\n| | account\'s simultaneous connections. |\n+--------------------------------------+--------------------------------------+\n| MAX_STATEMENT_TIME | Timeout, in seconds, for statements |\n| | executed by the user. See also |\n| | Aborting Statements that Exceed a |\n| | Certain Time to Execute. |\n+--------------------------------------+--------------------------------------+\n\nIf any of these limits are set to 0, then there is no limit for that resource\nfor that user.\n\nTo set resource limits for an account, if you do not want to change that\naccount\'s privileges, you can issue a GRANT statement with the USAGE\nprivilege, which has no meaning. The statement can name some or all limit\ntypes, in any order.\n\nHere is an example showing how to set resource limits:\n\nGRANT USAGE ON *.* TO \'someone\'@\'localhost\' WITH\n MAX_USER_CONNECTIONS 0\n MAX_QUERIES_PER_HOUR 200;\n\nThe resources are tracked per account, which means \'user\'@\'server\'; not per\nuser name or per connection.\n\nThe count can be reset for all users using FLUSH USER_RESOURCES, FLUSH\nPRIVILEGES or mysqladmin reload.\n\nUsers with the CONNECTION ADMIN privilege (in MariaDB 10.5.2 and later) or the\nSUPER privilege are not restricted by max_user_connections, max_connections,\nor max_password_errors.\n\nPer account resource limits are stored in the user table, in the mysql\ndatabase. Columns used for resources limits are named max_questions,\nmax_updates, max_connections (for MAX_CONNECTIONS_PER_HOUR), and\nmax_user_connections (for MAX_USER_CONNECTIONS).\n\nTLS Options\n-----------\n\nBy default, MariaDB transmits data between the server and clients without\nencrypting it. This is generally acceptable when the server and client run on\nthe same host or in networks where security is guaranteed through other means.\nHowever, in cases where the server and client exist on separate networks or\nthey are in a high-risk network, the lack of encryption does introduce\nsecurity concerns as a malicious actor could potentially eavesdrop on the\ntraffic as it is sent over the network between them.\n\nTo mitigate this concern, MariaDB allows you to encrypt data in transit\nbetween the server and clients using the Transport Layer Security (TLS)\nprotocol. TLS was formerly known as Secure Socket Layer (SSL), but strictly\nspeaking the SSL protocol is a predecessor to TLS and, that version of the\nprotocol is now considered insecure. The documentation still uses the term SSL\noften and for compatibility reasons TLS-related server system and status\nvariables still use the prefix ssl_, but internally, MariaDB only supports its\nsecure successors.\n\nSee Secure Connections Overview for more information about how to determine\nwhether your MariaDB server has TLS support.\n\nYou can set certain TLS-related restrictions for specific user accounts. For\ninstance, you might use this with user accounts that require access to\nsensitive data while sending it across networks that you do not control. These\nrestrictions can be enabled for a user account with the CREATE USER, ALTER\nUSER, or GRANT statements. The following options are available:\n\n+---------------------------+------------------------------------------------+\n| Option | Description |\n+---------------------------+------------------------------------------------+\n| REQUIRE NONE | TLS is not required for this account, but can |\n| | still be used. |\n+---------------------------+------------------------------------------------+\n| REQUIRE SSL | The account must use TLS, but no valid X509 |\n| | certificate is required. This option cannot |\n| | be combined with other TLS options. |\n+---------------------------+------------------------------------------------+\n| REQUIRE X509 | The account must use TLS and must have a |\n| | valid X509 certificate. This option implies |\n| | REQUIRE SSL. This option cannot be combined |\n| | with other TLS options. |\n+---------------------------+------------------------------------------------+\n| REQUIRE ISSUER \'issuer\' | The account must use TLS and must have a |\n| | valid X509 certificate. Also, the Certificate |\n| | Authority must be the one specified via the |\n| | string issuer. This option implies REQUIRE |\n| | X509. This option can be combined with the |\n| | SUBJECT, and CIPHER options in any order. |\n+---------------------------+------------------------------------------------+') WHERE help_topic_id = 107; +update help_topic set description = CONCAT(description, '\n| REQUIRE SUBJECT \'subject\' | The account must use TLS and must have a |\n| | valid X509 certificate. Also, the |\n| | certificate\'s Subject must be the one |\n| | specified via the string subject. This option |\n| | implies REQUIRE X509. This option can be |\n| | combined with the ISSUER, and CIPHER options |\n| | in any order. |\n+---------------------------+------------------------------------------------+\n| REQUIRE CIPHER \'cipher\' | The account must use TLS, but no valid X509 |\n| | certificate is required. Also, the encryption |\n| | used for the connection must use a specific |\n| | cipher method specified in the string cipher. |\n| | This option implies REQUIRE SSL. This option |\n| | can be combined with the ISSUER, and SUBJECT |\n| | options in any order. |\n+---------------------------+------------------------------------------------+\n\nThe REQUIRE keyword must be used only once for all specified options, and the\nAND keyword can be used to separate individual options, but it is not required.\n\nFor example, you can create a user account that requires these TLS options\nwith the following:\n\nGRANT USAGE ON *.* TO \'alice\'@\'%\'\n REQUIRE SUBJECT \'/CN=alice/O=My Dom, Inc./C=US/ST=Oregon/L=Portland\'\n AND ISSUER \'/C=FI/ST=Somewhere/L=City/ O=Some Company/CN=Peter\nParker/emailAddress=p.parker@marvel.com\'\n AND CIPHER \'SHA-DES-CBC3-EDH-RSA\';\n\nIf any of these options are set for a specific user account, then any client\nwho tries to connect with that user account will have to be configured to\nconnect with TLS.\n\nSee Securing Connections for Client and Server for information on how to\nenable TLS on the client and server.\n\nRoles\n-----\n\nSyntax\n------\n\nGRANT role TO grantee [, grantee ... ]\n[ WITH ADMIN OPTION ]\n\ngrantee:\n rolename\n username [authentication_option]\n\nThe GRANT statement is also used to grant the use a role to one or more users\nor other roles. In order to be able to grant a role, the grantor doing so must\nhave permission to do so (see WITH ADMIN in the CREATE ROLE article).\n\nSpecifying the WITH ADMIN OPTION permits the grantee to in turn grant the role\nto another.\n\nFor example, the following commands show how to grant the same role to a\ncouple different users.\n\nGRANT journalist TO hulda;\n\nGRANT journalist TO berengar WITH ADMIN OPTION;\n\nIf a user has been granted a role, they do not automatically obtain all\npermissions associated with that role. These permissions are only in use when\nthe user activates the role with the SET ROLE statement.\n\nTO PUBLIC\n---------\n\nMariaDB starting with 10.11\n---------------------------\n\nSyntax\n------\n\nGRANT ON . TO PUBLIC;\nREVOKE ON . FROM PUBLIC;\n\nGRANT ... TO PUBLIC grants privileges to all users with access to the server.\nThe privileges also apply to users created after the privileges are granted.\nThis can be useful when one only wants to state once that all users need to\nhave a certain set of privileges.\n\nWhen running SHOW GRANTS, a user will also see all privileges inherited from\nPUBLIC. SHOW GRANTS FOR PUBLIC will only show TO PUBLIC grants.\n\nGrant Examples\n--------------\n\nGranting Root-like Privileges\n-----------------------------\n\nYou can create a user that has privileges similar to the default root accounts\nby executing the following:\n\nCREATE USER \'alexander\'@\'localhost\';\nGRANT ALL PRIVILEGES ON *.* to \'alexander\'@\'localhost\' WITH GRANT OPTION;\n\nURL: https://mariadb.com/kb/en/grant/') WHERE help_topic_id = 107; +insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (108,10,'RENAME USER','Syntax\n------\n\nRENAME USER old_user TO new_user\n [, old_user TO new_user] ...\n\nDescription\n-----------\n\nThe RENAME USER statement renames existing MariaDB accounts. To use it, you\nmust have the global CREATE USER privilege or the UPDATE privilege for the\nmysql database. Each account is named using the same format as for the CREATE\nUSER statement; for example, \'jeffrey\'@\'localhost\'. If you specify only the\nuser name part of the account name, a host name part of \'%\' is used.\n\nIf any of the old user accounts do not exist or any of the new user accounts\nalready exist, ERROR 1396 (HY000) results. If an error occurs, RENAME USER\nwill still rename the accounts that do not result in an error.\n\nExamples\n--------\n\nCREATE USER \'donald\', \'mickey\';\nRENAME USER \'donald\' TO \'duck\'@\'localhost\', \'mickey\' TO \'mouse\'@\'localhost\';\n\nURL: https://mariadb.com/kb/en/rename-user/','','https://mariadb.com/kb/en/rename-user/'); +insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (109,10,'REVOKE','Privileges\n----------\n\nSyntax\n------\n\nREVOKE \n priv_type [(column_list)]\n [, priv_type [(column_list)]] ...\n ON [object_type] priv_level\n FROM user [, user] ...\n\nREVOKE ALL PRIVILEGES, GRANT OPTION\n FROM user [, user] ...\n\nDescription\n-----------\n\nThe REVOKE statement enables system administrators to revoke privileges (or\nroles - see section below) from MariaDB accounts. Each account is named using\nthe same format as for the GRANT statement; for example,\n\'jeffrey\'@\'localhost\'. If you specify only the user name part of the account\nname, a host name part of \'%\' is used. For details on the levels at which\nprivileges exist, the allowable priv_type and priv_level values, and the\nsyntax for specifying users and passwords, see GRANT.\n\nTo use the first REVOKE syntax, you must have the GRANT OPTION privilege, and\nyou must have the privileges that you are revoking.\n\nTo revoke all privileges, use the second syntax, which drops all global,\ndatabase, table, column, and routine privileges for the named user or users:\n\nREVOKE ALL PRIVILEGES, GRANT OPTION FROM user [, user] ...\n\nTo use this REVOKE syntax, you must have the global CREATE USER privilege or\nthe UPDATE privilege for the mysql database. See GRANT.\n\nExamples\n--------\n\nREVOKE SUPER ON *.* FROM \'alexander\'@\'localhost\';\n\nRoles\n-----\n\nSyntax\n------\n\nREVOKE role [, role ...]\n FROM grantee [, grantee2 ... ]\n\nREVOKE ADMIN OPTION FOR role FROM grantee [, grantee2]\n\nDescription\n-----------\n\nREVOKE is also used to remove a role from a user or another role that it\'s\npreviously been assigned to. If a role has previously been set as a default\nrole, REVOKE does not remove the record of the default role from the\nmysql.user table. If the role is subsequently granted again, it will again be\nthe user\'s default. Use SET DEFAULT ROLE NONE to explicitly remove this.\n\nBefore MariaDB 10.1.13, the REVOKE role statement was not permitted in\nprepared statements.\n\nExample\n-------\n\nREVOKE journalist FROM hulda\n\nURL: https://mariadb.com/kb/en/revoke/','','https://mariadb.com/kb/en/revoke/'); +insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (110,10,'SET PASSWORD','Syntax\n------\n\nSET PASSWORD [FOR user] =\n {\n PASSWORD(\'some password\')\n | OLD_PASSWORD(\'some password\')\n | \'encrypted password\'\n }\n\nDescription\n-----------\n\nThe SET PASSWORD statement assigns a password to an existing MariaDB user\naccount.\n\nIf the password is specified using the PASSWORD() or OLD_PASSWORD() function,\nthe literal text of the password should be given. If the password is specified\nwithout using either function, the password should be the already-encrypted\npassword value as returned by PASSWORD().\n\nOLD_PASSWORD() should only be used if your MariaDB/MySQL clients are very old\n(< 4.0.0).\n\nWith no FOR clause, this statement sets the password for the current user. Any\nclient that has connected to the server using a non-anonymous account can\nchange the password for that account.\n\nWith a FOR clause, this statement sets the password for a specific account on\nthe current server host. Only clients that have the UPDATE privilege for the\nmysql database can do this. The user value should be given in\nuser_name@host_name format, where user_name and host_name are exactly as they\nare listed in the User and Host columns of the mysql.user table (or view in\nMariaDB-10.4 onwards) entry.\n\nThe argument to PASSWORD() and the password given to MariaDB clients can be of\narbitrary length.\n\nAuthentication Plugin Support\n-----------------------------\n\nMariaDB starting with 10.4\n--------------------------\nIn MariaDB 10.4 and later, SET PASSWORD (with or without PASSWORD()) works for\naccounts authenticated via any authentication plugin that supports passwords\nstored in the mysql.global_priv table.\n\nThe ed25519, mysql_native_password, and mysql_old_password authentication\nplugins store passwords in the mysql.global_priv table.\n\nIf you run SET PASSWORD on an account that authenticates with one of these\nauthentication plugins that stores passwords in the mysql.global_priv table,\nthen the PASSWORD() function is evaluated by the specific authentication\nplugin used by the account. The authentication plugin hashes the password with\na method that is compatible with that specific authentication plugin.\n\nThe unix_socket, named_pipe, gssapi, and pam authentication plugins do not\nstore passwords in the mysql.global_priv table. These authentication plugins\nrely on other methods to authenticate the user.\n\nIf you attempt to run SET PASSWORD on an account that authenticates with one\nof these authentication plugins that doesn\'t store a password in the\nmysql.global_priv table, then MariaDB Server will raise a warning like the\nfollowing:\n\nSET PASSWORD is ignored for users authenticating via unix_socket plugin\n\nSee Authentication from MariaDB 10.4 for an overview of authentication changes\nin MariaDB 10.4.\n\nMariaDB until 10.3\n------------------\nIn MariaDB 10.3 and before, SET PASSWORD (with or without PASSWORD()) only\nworks for accounts authenticated via mysql_native_password or\nmysql_old_password authentication plugins\n\nPasswordless User Accounts\n--------------------------\n\nUser accounts do not always require passwords to login.\n\nThe unix_socket , named_pipe and gssapi authentication plugins do not require\na password to authenticate the user.\n\nThe pam authentication plugin may or may not require a password to\nauthenticate the user, depending on the specific configuration.\n\nThe mysql_native_password and mysql_old_password authentication plugins\nrequire passwords for authentication, but the password can be blank. In that\ncase, no password is required.\n\nIf you provide a password while attempting to log into the server as an\naccount that doesn\'t require a password, then MariaDB server will simply\nignore the password.\n\nMariaDB starting with 10.4\n--------------------------\nIn MariaDB 10.4 and later, a user account can be defined to use multiple\nauthentication plugins in a specific order of preference. This specific\nscenario may be more noticeable in these versions, since an account could be\nassociated with some authentication plugins that require a password, and some\nthat do not.\n\nExample\n-------\n\nFor example, if you had an entry with User and Host column values of \'bob\' and\n\'%.loc.gov\', you would write the statement like this:\n\nSET PASSWORD FOR \'bob\'@\'%.loc.gov\' = PASSWORD(\'newpass\');\n\nIf you want to delete a password for a user, you would do:\n\nSET PASSWORD FOR \'bob\'@localhost = PASSWORD(\"\");\n\nURL: https://mariadb.com/kb/en/set-password/','','https://mariadb.com/kb/en/set-password/'); +insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (111,10,'CREATE ROLE','Syntax\n------\n\nCREATE [OR REPLACE] ROLE [IF NOT EXISTS] role \n [WITH ADMIN\n {CURRENT_USER | CURRENT_ROLE | user | role}]\n\nDescription\n-----------\n\nThe CREATE ROLE statement creates one or more MariaDB roles. To use it, you\nmust have the global CREATE USER privilege or the INSERT privilege for the\nmysql database. For each account, CREATE ROLE creates a new row in the\nmysql.user table that has no privileges, and with the corresponding is_role\nfield set to Y. It also creates a record in the mysql.roles_mapping table.\n\nIf any of the specified roles already exist, ERROR 1396 (HY000) results. If an\nerror occurs, CREATE ROLE will still create the roles that do not result in an\nerror. The maximum length for a role is 128 characters. Role names can be\nquoted, as explained in the Identifier names page. Only one error is produced\nfor all roles which have not been created:\n\nERROR 1396 (HY000): Operation CREATE ROLE failed for \'a\',\'b\',\'c\'\n\nFailed CREATE or DROP operations, for both users and roles, produce the same\nerror code.\n\nPUBLIC and NONE are reserved, and cannot be used as role names. NONE is used\nto unset a role and PUBLIC has a special use in other systems, such as Oracle,\nso is reserved for compatibility purposes.\n\nFor valid identifiers to use as role names, see Identifier Names.\n\nWITH ADMIN\n----------\n\nThe optional WITH ADMIN clause determines whether the current user, the\ncurrent role or another user or role has use of the newly created role. If the\nclause is omitted, WITH ADMIN CURRENT_USER is treated as the default, which\nmeans that the current user will be able to GRANT this role to users.\n\nOR REPLACE\n----------\n\nIf the optional OR REPLACE clause is used, it acts as a shortcut for:\n\nDROP ROLE IF EXISTS name;\nCREATE ROLE name ...;\n\nIF NOT EXISTS\n-------------\n\nWhen the IF NOT EXISTS clause is used, MariaDB will return a warning instead\nof an error if the specified role already exists. Cannot be used together with\nthe OR REPLACE clause.\n\nExamples\n--------\n\nCREATE ROLE journalist;\n\nCREATE ROLE developer WITH ADMIN lorinda@localhost;\n\nGranting the role to another user. Only user lorinda@localhost has permission\nto grant the developer role:\n\nSELECT USER();\n+-------------------+\n| USER() |\n+-------------------+\n| henning@localhost |\n+-------------------+\n...\nGRANT developer TO ian@localhost;\nAccess denied for user \'henning\'@\'localhost\'\n\nSELECT USER();\n+-------------------+\n| USER() |\n+-------------------+\n| lorinda@localhost |\n+-------------------+\n\nGRANT m_role TO ian@localhost;\n\nThe OR REPLACE and IF NOT EXISTS clauses. The journalist role already exists:\n\nCREATE ROLE journalist;\nERROR 1396 (HY000): Operation CREATE ROLE failed for \'journalist\'\n\nCREATE OR REPLACE ROLE journalist;\nQuery OK, 0 rows affected (0.00 sec)\n\nCREATE ROLE IF NOT EXISTS journalist;\nQuery OK, 0 rows affected, 1 warning (0.00 sec)\n\nSHOW WARNINGS;\n+-------+------+---------------------------------------------------+\n| Level | Code | Message |\n+-------+------+---------------------------------------------------+\n| Note | 1975 | Can\'t create role \'journalist\'; it already exists |\n+-------+------+---------------------------------------------------+\n\nURL: https://mariadb.com/kb/en/create-role/','','https://mariadb.com/kb/en/create-role/'); +insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (112,10,'DROP ROLE','Syntax\n------\n\nDROP ROLE [IF EXISTS] role_name [,role_name ...]\n\nDescription\n-----------\n\nThe DROP ROLE statement removes one or more MariaDB roles. To use this\nstatement, you must have the global CREATE USER privilege or the DELETE\nprivilege for the mysql database.\n\nDROP ROLE does not disable roles for connections which selected them with SET\nROLE. If a role has previously been set as a default role, DROP ROLE does not\nremove the record of the default role from the mysql.user table. If the role\nis subsequently recreated and granted, it will again be the user\'s default.\nUse SET DEFAULT ROLE NONE to explicitly remove this.\n\nIf any of the specified user accounts do not exist, ERROR 1396 (HY000)\nresults. If an error occurs, DROP ROLE will still drop the roles that do not\nresult in an error. Only one error is produced for all roles which have not\nbeen dropped:\n\nERROR 1396 (HY000): Operation DROP ROLE failed for \'a\',\'b\',\'c\'\n\nFailed CREATE or DROP operations, for both users and roles, produce the same\nerror code.\n\nIF EXISTS\n---------\n\nIf the IF EXISTS clause is used, MariaDB will return a warning instead of an\nerror if the role does not exist.\n\nExamples\n--------\n\nDROP ROLE journalist;\n\nThe same thing using the optional IF EXISTS clause:\n\nDROP ROLE journalist;\nERROR 1396 (HY000): Operation DROP ROLE failed for \'journalist\'\n\nDROP ROLE IF EXISTS journalist;\nQuery OK, 0 rows affected, 1 warning (0.00 sec)\n\nNote (Code 1975): Can\'t drop role \'journalist\'; it doesn\'t exist\n\nURL: https://mariadb.com/kb/en/drop-role/','','https://mariadb.com/kb/en/drop-role/'); +insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (113,10,'SET ROLE','Syntax\n------\n\nSET ROLE { role | NONE }\n\nDescription\n-----------\n\nThe SET ROLE statement enables a role, along with all of its associated\npermissions, for the current session. To unset a role, use NONE .\n\nIf a role that doesn\'t exist, or to which the user has not been assigned, is\nspecified, an ERROR 1959 (OP000): Invalid role specification error occurs.\n\nAn automatic SET ROLE is implicitly performed when a user connects if that\nuser has been assigned a default role. See SET DEFAULT ROLE.\n\nExample\n-------\n\nSELECT CURRENT_ROLE;\n+--------------+\n| CURRENT_ROLE |\n+--------------+\n| NULL |\n+--------------+\n\nSET ROLE staff;\n\nSELECT CURRENT_ROLE;\n+--------------+\n| CURRENT_ROLE |\n+--------------+\n| staff |\n+--------------+\n\nSET ROLE NONE;\n\nSELECT CURRENT_ROLE();\n+----------------+\n| CURRENT_ROLE() |\n+----------------+\n| NULL |\n+----------------+\n\nURL: https://mariadb.com/kb/en/set-role/','','https://mariadb.com/kb/en/set-role/'); +insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (114,10,'SET DEFAULT ROLE','Syntax\n------\n\nSET DEFAULT ROLE { role | NONE } [ FOR user@host ]\n\nDescription\n-----------\n\nThe SET DEFAULT ROLE statement sets a default role for a specified (or\ncurrent) user. A default role is automatically enabled when a user connects\n(an implicit SET ROLE statement is executed immediately after a connection is\nestablished).\n\nTo be able to set a role as a default, the role must already have been granted\nto that user, and one needs the privileges to enable this role (if you cannot\ndo SET ROLE X, you won\'t be able to do SET DEFAULT ROLE X). To set a default\nrole for another user one needs to have write access to the mysql database.\n\nTo remove a user\'s default role, use SET DEFAULT ROLE NONE [ FOR user@host ].\nThe record of the default role is not removed if the role is dropped or\nrevoked, so if the role is subsequently re-created or granted, it will again\nbe the user\'s default role.\n\nThe default role is stored in the default_role column in the mysql.user\ntable/view, as well as in the Information Schema APPLICABLE_ROLES table, so\nthese can be viewed to see which role has been assigned to a user as the\ndefault.\n\nExamples\n--------\n\nSetting a default role for the current user:\n\nSET DEFAULT ROLE journalist;\n\nRemoving a default role from the current user:\n\nSET DEFAULT ROLE NONE;\n\nSetting a default role for another user. The role has to have been granted to\nthe user before it can be set as default:\n\nCREATE ROLE journalist;\nCREATE USER taniel;\n\nSET DEFAULT ROLE journalist FOR taniel;\nERROR 1959 (OP000): Invalid role specification `journalist`\n\nGRANT journalist TO taniel;\nSET DEFAULT ROLE journalist FOR taniel;\n\nViewing mysql.user:\n\nselect * from mysql.user where user=\'taniel\'\\G\n*************************** 1. row ***************************\n Host: %\n User: taniel\n...\n is_role: N\n default_role: journalist\n...\n\nRemoving a default role for another user\n\nSET DEFAULT ROLE NONE FOR taniel;\n\nURL: https://mariadb.com/kb/en/set-default-role/','','https://mariadb.com/kb/en/set-default-role/'); +insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (115,10,'Roles Overview','Description\n-----------\n\nA role bundles a number of privileges together. It assists larger\norganizations where, typically, a number of users would have the same\nprivileges, and, previously, the only way to change the privileges for a group\nof users was by changing each user\'s privileges individually.\n\nAlternatively, multiple external users could have been assigned the same user,\nand there would have been no way to see which actual user was responsible for\nwhich action.\n\nWith roles, managing this is easy. For example, there could be a number of\nusers assigned to a journalist role, with identical privileges. Changing the\nprivileges for all the journalists is a matter of simply changing the role\'s\nprivileges, while the individual user is still linked with any changes that\ntake place.\n\nRoles are created with the CREATE ROLE statement, and dropped with the DROP\nROLE statement. Roles are then assigned to a user with an extension to the\nGRANT statement, while privileges are assigned to a role in the regular way\nwith GRANT. Similarly, the REVOKE statement can be used to both revoke a role\nfrom a user, or revoke a privilege from a role.\n\nOnce a user has connected, he can obtain all privileges associated with a role\nby setting a role with the SET ROLE statement. The CURRENT_ROLE function\nreturns the currently set role for the session, if any.\n\nOnly roles granted directly to a user can be set, roles granted to other roles\ncannot. Instead the privileges granted to a role, which is, in turn, granted\nto another role (grantee), will be immediately available to any user who sets\nthis second grantee role.\n\nThe SET DEFAULT ROLE statement allows one to set a default role for a user. A\ndefault role is automatically enabled when a user connects (an implicit SET\nROLE statement is executed immediately after a connection is established).\n\nRoles were implemented as a GSoC 2013 project by Vicentiu Ciorbaru.\n\nSystem Tables\n-------------\n\nInformation about roles and who they\'ve been granted to can be found in the\nInformation Schema APPLICABLE_ROLES table as well as the mysql.ROLES_MAPPING\ntable.\n\nThe Information Schema ENABLED_ROLES table shows the enabled roles for the\ncurrent session.\n\nExamples\n--------\n\nCreating a role and granting a privilege:\n\nCREATE ROLE journalist;\n\nGRANT SHOW DATABASES ON *.* TO journalist;\n\nGRANT journalist to hulda;\n\nNote, that hulda has no SHOW DATABASES privilege, even though she was granted\nthe journalist role. She needs to set the role first:\n\nSHOW DATABASES;\n+--------------------+\n| Database |\n+--------------------+\n| information_schema |\n+--------------------+\n\nSELECT CURRENT_ROLE;\n+--------------+\n| CURRENT_ROLE |\n+--------------+\n| NULL |\n+--------------+\n\nSET ROLE journalist;\n\nSELECT CURRENT_ROLE;\n+--------------+\n| CURRENT_ROLE |\n+--------------+\n| journalist |\n+--------------+\n\nSHOW DATABASES;\n+--------------------+\n| Database |\n+--------------------+\n| ... |\n| information_schema |\n| mysql |\n| performance_schema |\n| test |\n| ... |\n+--------------------+\n\nSET ROLE NONE;\n\nRoles can be granted to roles:\n\nCREATE ROLE writer;\n\nGRANT SELECT ON data.* TO writer;\n\nGRANT writer TO journalist;\n\nBut one does not need to set a role granted to a role. For example, hulda will\nautomatically get all writer privileges when she sets the journalist role:\n\nSELECT CURRENT_ROLE;\n+--------------+\n| CURRENT_ROLE |\n+--------------+\n| NULL |\n+--------------+\n\nSHOW TABLES FROM data;\nEmpty set (0.01 sec)\n\nSET ROLE journalist;\n\nSELECT CURRENT_ROLE;\n+--------------+\n| CURRENT_ROLE |\n+--------------+\n| journalist |\n+--------------+\n\nSHOW TABLES FROM data;\n+------------------------------+\n| Tables_in_data |\n+------------------------------+\n| set1 |\n| ... |\n+------------------------------+\n\nRoles and Views (and Stored Routines)\n-------------------------------------\n\nWhen a user sets a role, he, in a sense, has two identities with two\nassociated sets of privileges. But a view (or a stored routine) can have only\none definer. So, when a view (or a stored routine) is created with the SQL\nSECURITY DEFINER, one can specify whether the definer should be CURRENT_USER\n(and the view will have none of the privileges of the user\'s role) or\nCURRENT_ROLE (in this case, the view will use role\'s privileges, but none of\nthe user\'s privileges). As a result, sometimes one can create a view that is\nimpossible to use.\n\nCREATE ROLE r1;\n\nGRANT ALL ON db1.* TO r1;\n\nGRANT r1 TO foo@localhost;\n\nGRANT ALL ON db.* TO foo@localhost;\n\nSELECT CURRENT_USER\n+---------------+\n| current_user |\n+---------------+\n| foo@localhost |\n+---------------+\n\nSET ROLE r1;\n\nCREATE TABLE db1.t1 (i int);\n\nCREATE VIEW db.v1 AS SELECT * FROM db1.t1;\n\nSHOW CREATE VIEW db.v1;\n+------+-----------------------------------------------------------------------\n------------------------------------------------------------------+------------\n---------+----------------------+\n| View | Create View \n |\ncharacter_set_client | collation_connection |\n+------+-----------------------------------------------------------------------\n------------------------------------------------------------------+------------\n---------+----------------------+','','https://mariadb.com/kb/en/roles_overview/'); +update help_topic set description = CONCAT(description, '\n| v1 | CREATE ALGORITHM=UNDEFINED DEFINER=`foo`@`localhost` SQL SECURITY\nDEFINER VIEW `db`.`v1` AS SELECT `db1`.`t1`.`i` AS `i` from `db1`.`t1` | utf8 \n | utf8_general_ci |\n+------+-----------------------------------------------------------------------\n------------------------------------------------------------------+------------\n---------+----------------------+\n\nCREATE DEFINER=CURRENT_ROLE VIEW db.v2 AS SELECT * FROM db1.t1;\n\nSHOW CREATE VIEW db.b2;\n+------+-----------------------------------------------------------------------\n-----------------------------------------------------+----------------------+--\n-------------------+\n| View | Create View \n | character_set_client |\ncollation_connection |\n+------+-----------------------------------------------------------------------\n-----------------------------------------------------+----------------------+--\n-------------------+\n| v2 | CREATE ALGORITHM=UNDEFINED DEFINER=`r1` SQL SECURITY DEFINER VIEW\n`db`.`v2` AS select `db1`.`t1`.`a` AS `a` from `db1`.`t1` | utf8 \n | utf8_general_ci |\n+------+-----------------------------------------------------------------------\n-----------------------------------------------------+----------------------+--\n-------------------+\n\nOther Resources\n---------------\n\n* Roles Review by Peter Gulutzan\n\nURL: https://mariadb.com/kb/en/roles_overview/') WHERE help_topic_id = 115; +insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (116,10,'Account Locking','MariaDB starting with 10.4.2\n----------------------------\nAccount locking was introduced in MariaDB 10.4.2.\n\nDescription\n-----------\n\nAccount locking permits privileged administrators to lock/unlock user\naccounts. No new client connections will be permitted if an account is locked\n(existing connections are not affected).\n\nUser accounts can be locked at creation, with the CREATE USER statement, or\nmodified after creation with the ALTER USER statement. For example:\n\nCREATE USER \'lorin\'@\'localhost\' ACCOUNT LOCK;\n\nor\n\nALTER USER \'marijn\'@\'localhost\' ACCOUNT LOCK;\n\nThe server will return an ER_ACCOUNT_HAS_BEEN_LOCKED error when locked users\nattempt to connect:\n\nmysql -ulorin\n ERROR 4151 (HY000): Access denied, this account is locked\n\nThe ALTER USER statement is also used to unlock a user:\n\nALTER USER \'lorin\'@\'localhost\' ACCOUNT UNLOCK;\n\nThe SHOW CREATE USER statement will show whether the account is locked:\n\nSHOW CREATE USER \'marijn\'@\'localhost\';\n+-----------------------------------------------+\n| CREATE USER for marijn@localhost |\n+-----------------------------------------------+\n| CREATE USER \'marijn\'@\'localhost\' ACCOUNT LOCK |\n+-----------------------------------------------+\n\nas well as querying the mysql.global_priv table:\n\nSELECT CONCAT(user, \'@\', host, \' => \', JSON_DETAILED(priv)) FROM\nmysql.global_priv \n WHERE user=\'marijn\';\n+------------------------------------------------------------------------------\n-------+\n| CONCAT(user, \'@\', host, \' => \', JSON_DETAILED(priv)) \n |\n+------------------------------------------------------------------------------\n-------+\n| marijn@localhost => {\n \"access\": 0,\n \"plugin\": \"mysql_native_password\",\n \"authentication_string\": \"\",\n \"account_locked\": true,\n \"password_last_changed\": 1558017158\n} |\n+------------------------------------------------------------------------------\n-------+\n\nURL: https://mariadb.com/kb/en/account-locking/','','https://mariadb.com/kb/en/account-locking/'); +insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (117,10,'Authentication from MariaDB 10.4','MariaDB starting with 10.4\n--------------------------\nMariaDB 10.4 introduced a number of changes to the authentication process,\nintended to make things easier and more intuitive.\n\nOverview\n--------\n\nThere are four new main features in 10.4 relating to authentication:\n\n* It is possible to use more than one authentication plugin for each user\naccount. For example, this can be useful to slowly migrate users to the more\nsecure ed25519 authentication plugin over time, while allowing the old\nmysql_native_password authentication plugin as an alternative for the\ntransitional period.\n* The root@localhost user account created by mysql_install_db is created with\nthe ability to use two authentication plugins.\nFirst, it is configured to try to use the unix_socket authentication plugin.\nThis allows the root@localhost user to login without a password via the local\nUnix socket file defined by the socket system variable, as long as the login\nis attempted from a process owned by the operating system root user account.\nSecond, if authentication fails with the unix_socket authentication plugin,\nthen it is configured to try to use the mysql_native_password authentication\nplugin. However, an invalid password is initially set, so in order to\nauthenticate this way, a password must be set with SET PASSWORD.\nHowever, just using the unix_socket authentication plugin may be fine for many\nusers, and it is very secure. You may want to try going without password\nauthentication to see how well it works for you. Remember, the best way to\nkeep your password safe is not to have one!\n\n* All user accounts, passwords, and global privileges are now stored in the\nmysql.global_priv table. The mysql.user table still exists and has exactly the\nsame set of columns as before, but it’s now a view that references the\nmysql.global_priv table. Tools that analyze the mysql.user table should\ncontinue to work as before. From MariaDB 10.4.13, the dedicated mariadb.sys\nuser is created as the definer of this view. Previously root was the definer,\nwhich resulted in privilege problems when this username was changed.\n* MariaDB 10.4 adds supports for User Password Expiry, which is not active by\ndefault.\n\nDescription\n-----------\n\nAs a result of the above changes, the open-for-everyone all-powerful root\naccount is finally gone. And installation scripts will no longer demand that\nyou \"PLEASE REMEMBER TO SET A PASSWORD FOR THE MariaDB root USER !\", because\nthe root account is securely created automatically.\n\nTwo all-powerful accounts are created by default — root and the OS user that\nowns the data directory, typically mysql. They are created as:\n\nCREATE USER root@localhost IDENTIFIED VIA unix_socket OR mysql_native_password\nUSING \'invalid\'\nCREATE USER mysql@localhost IDENTIFIED VIA unix_socket OR\nmysql_native_password USING \'invalid\'\n\nUsing unix_socket means that if you are the system root user, you can login as\nroot@locahost without a password. This technique was pioneered by Otto\nKekäläinen in Debian MariaDB packages and has been successfully used in Debian\nsince as early as MariaDB 10.0.\n\nIt is based on a simple fact that asking the system root for a password adds\nno extra security — root has full access to all the data files and all process\nmemory anyway. But not asking for a password means, there is no root password\nto forget (no need for the numerous tutorials on \"how to reset MariaDB root\npassword\"). And if you want to script some tedious database work, there is no\nneed to store the root password in plain text for the script to use (no need\nfor debian-sys-maint user).\n\nStill, some users may wish to log in as MariaDB root without using sudo. Hence\nthe old authentication method — conventional MariaDB password — is still\navailable. By default it is disabled (\"invalid\" is not a valid password hash),\nbut one can set the password with a usual SET PASSWORD statement. And still\nretain the password-less access via sudo.\n\nIf you install MariaDB locally (say from a tarball), you would not want to use\nsudo to be able to login. This is why MariaDB creates a second all-powerful\nuser with the same name as a system user that owns the data directory. In\nlocal (not system-wide) installations, this will be the user who installed\nMariaDB — they automatically get convenient password-less root-like access,\nbecause they can access all the data files anyway.\n\nEven if MariaDB is installed system-wide, you may not want to run your\ndatabase maintenance scripts as system root — now you can run them as system\nmysql user. And you will know that they will never destroy your entire system,\neven if you make a typo in a shell script.\n\nHowever, seasoned MariaDB DBAs who are used to the old ways do need to make\nsome changes. See the examples below for common tasks.\n\nCookbook\n--------\n\nAfter installing MariaDB system-wide the first thing you’ve got used to doing\nis logging in into the unprotected root account and protecting it, that is,\nsetting the root password:\n\n$ sudo dnf install MariaDB-server\n$ mysql -uroot\n...\nMariaDB> set password = password(\"XH4VmT3_jt\");\n\nThis is not only unnecessary now, it will simply not work — there is no\nunprotected root account. To login as root use\n\n$ sudo dnf install MariaDB-server\n$ sudo mysql\n\nNote that it implies you are connecting via the unix socket, not tcp. If you\nhappen to have protocol=tcp in a system-wide /etc/my.cnf file, use sudo mysql\n--protocol=socket.\n','','https://mariadb.com/kb/en/authentication-from-mariadb-104/'); +update help_topic set description = CONCAT(description, '\nAfter installing MariaDB locally you’ve also used to connect to the\nunprotected root account using mysql -uroot. This will not work either, simply\nuse mysql without specifying a username.\n\nIf you\'ve forgotten your root password, no problem — you can still connect\nusing sudo and change the password. And if you\'ve also removed unix_socket\nauthentication, to restore access do as follows:\n\n* restart MariaDB with --skip-grant-tables\n* login into the unprotected server\n* run FLUSH PRIVILEGES (note, before 10.4 this would’ve been the last step,\nnot anymore). This disables --skip-grant-tables and allows you to change the\nstored authentication method\n* run SET PASSWORD FOR root@localhost to change the root password.\n\nTo view inside privilege tables, the old mysql.user table still exists. You\ncan select from it as before, although you cannot update it anymore. It\ndoesn’t show alternative authentication plugins and this was one of the\nreasons for switching to the mysql.global_priv table — complex authentication\nrules did not fit into rigid structure of a relational table. You can select\nfrom the new table, for example:\n\nselect concat(user, \'@\', host, \' => \', json_detailed(priv)) from\nmysql.global_priv;\n\nReverting to the Previous Authentication Method for root@localhost\n------------------------------------------------------------------\n\nIf you don\'t want the root@localhost user account created by mysql_install_db\nto use unix_socket authentication by default, then there are a few ways to\nrevert to the previous mysql_native_password authentication method for this\nuser account.\n\nConfiguring mysql_install_db to Revert to the Previous Authentication Method\n----------------------------------------------------------------------------\n\nOne way to revert to the previous mysql_native_password authentication method\nfor the root@localhost user account is to execute mysql_install_db with a\nspecial option. If mysql_install_db is executed while\n--auth-root-authentication-method=normal is specified, then it will create the\ndefault user accounts using the default behavior of MariaDB 10.3 and before.\n\nThis means that the root@localhost user account will use mysql_native_password\nauthentication by default. There are some other differences as well. See\nmysql_install_db: User Accounts Created by Default for more information.\n\nFor example, the option can be set on the command-line while running\nmysql_install_db:\n\nmysql_install_db --user=mysql --datadir=/var/lib/mysql\n--auth-root-authentication-method=normal\n\nThe option can also be set in an option file in an option group supported by\nmysql_install_db. For example:\n\n[mysql_install_db]\nauth_root_authentication_method=normal\n\nIf the option is set in an option file and if mysql_install_db is executed,\nthen mysql_install_db will read this option from the option file, and it will\nautomatically set this option.\n\nAltering the User Account to Revert to the Previous Authentication Method\n-------------------------------------------------------------------------\n\nIf you have already installed MariaDB, and if the root@localhost user account\nis already using unix_socket authentication, then you can revert to the old\nmysql_native_password authentication method for the user account by executing\nthe following:\n\nALTER USER root@localhost IDENTIFIED VIA mysql_native_password USING\nPASSWORD(\"verysecret\")\n\nURL: https://mariadb.com/kb/en/authentication-from-mariadb-104/') WHERE help_topic_id = 117; +insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (118,10,'User Password Expiry','MariaDB starting with 10.4.3\n----------------------------\nUser password expiry was introduced in MariaDB 10.4.3.\n\nPassword expiry permits administrators to expire user passwords, either\nmanually or automatically.\n\nSystem Variables\n----------------\n\nThere are two system variables which affect password expiry:\ndefault_password_lifetime, which determines the amount of time between\nrequiring the user to change their password. 0, the default, means automatic\npassword expiry is not active.\n\nThe second variable, disconnect_on_expired_password determines whether a\nclient is permitted to connect if their password has expired, or whether they\nare permitted to connect in sandbox mode, able to perform a limited subset of\nqueries related to resetting the password, in particular SET PASSWORD and SET.\n\nSetting a Password Expiry Limit for a User\n------------------------------------------\n\nBesides automatic password expiry, as determined by default_password_lifetime,\npassword expiry times can be set on an individual user basis, overriding the\nglobal using the CREATE USER or ALTER USER statements, for example:\n\nCREATE USER \'monty\'@\'localhost\' PASSWORD EXPIRE INTERVAL 120 DAY;\n\nALTER USER \'monty\'@\'localhost\' PASSWORD EXPIRE INTERVAL 120 DAY;\n\nLimits can be disabled by use of the NEVER keyword, for example:\n\nCREATE USER \'monty\'@\'localhost\' PASSWORD EXPIRE NEVER;\n\nALTER USER \'monty\'@\'localhost\' PASSWORD EXPIRE NEVER;\n\nA manually set limit can be restored the system default by use of DEFAULT, for\nexample:\n\nCREATE USER \'monty\'@\'localhost\' PASSWORD EXPIRE DEFAULT;\n\nALTER USER \'monty\'@\'localhost\' PASSWORD EXPIRE DEFAULT;\n\nSHOW CREATE USER\n----------------\n\nThe SHOW CREATE USER statement will display information about the password\nexpiry status of the user. Unlike MySQL, it will not display if the user is\nunlocked, or if the password expiry is set to default.\n\nCREATE USER \'monty\'@\'localhost\' PASSWORD EXPIRE INTERVAL 120 DAY;\nCREATE USER \'konstantin\'@\'localhost\' PASSWORD EXPIRE NEVER;\nCREATE USER \'amse\'@\'localhost\' PASSWORD EXPIRE DEFAULT;\n\nSHOW CREATE USER \'monty\'@\'localhost\';\n+------------------------------------------------------------------+\n| CREATE USER for monty@localhost |\n+------------------------------------------------------------------+\n| CREATE USER \'monty\'@\'localhost\' PASSWORD EXPIRE INTERVAL 120 DAY |\n+------------------------------------------------------------------+\n\nSHOW CREATE USER \'konstantin\'@\'localhost\';\n+------------------------------------------------------------+\n| CREATE USER for konstantin@localhost |\n+------------------------------------------------------------+\n| CREATE USER \'konstantin\'@\'localhost\' PASSWORD EXPIRE NEVER |\n+------------------------------------------------------------+\n\nSHOW CREATE USER \'amse\'@\'localhost\';\n+--------------------------------+\n| CREATE USER for amse@localhost |\n+--------------------------------+\n| CREATE USER \'amse\'@\'localhost\' |\n+--------------------------------+\n\nChecking When Passwords Expire\n------------------------------\n\nThe following query can be used to check when the current passwords expire for\nall users:\n\nWITH password_expiration_info AS (\n SELECT User, Host,\n IF(\n IFNULL(JSON_EXTRACT(Priv, \'$.password_lifetime\'), -1) = -1,\n @@global.default_password_lifetime,\n JSON_EXTRACT(Priv, \'$.password_lifetime\')\n ) AS password_lifetime,\n JSON_EXTRACT(Priv, \'$.password_last_changed\') AS password_last_changed\n FROM mysql.global_priv\n)\nSELECT pei.User, pei.Host,\n pei.password_lifetime,\n FROM_UNIXTIME(pei.password_last_changed) AS password_last_changed_datetime,\n FROM_UNIXTIME(\n pei.password_last_changed +\n (pei.password_lifetime * 60 * 60 * 24)\n ) AS password_expiration_datetime\n FROM password_expiration_info pei\n WHERE pei.password_lifetime != 0\n AND pei.password_last_changed IS NOT NULL\nUNION\nSELECT pei.User, pei.Host,\n pei.password_lifetime,\n FROM_UNIXTIME(pei.password_last_changed) AS password_last_changed_datetime,\n 0 AS password_expiration_datetime\n FROM password_expiration_info pei\n WHERE pei.password_lifetime = 0\n OR pei.password_last_changed IS NULL;\n\n--connect-expired-password Client Option\n----------------------------------------\n\nThe mysql client --connect-expired-password option notifies the server that\nthe client is prepared to handle expired password sandbox mode (even if the\n--batch option was specified).\n\nURL: https://mariadb.com/kb/en/user-password-expiry/','','https://mariadb.com/kb/en/user-password-expiry/'); +insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (119,11,'ST_X','Syntax\n------\n\nST_X(p)\nX(p)\n\nDescription\n-----------\n\nReturns the X-coordinate value for the point p as a double-precision number.\n\nST_X() and X() are synonyms.\n\nExamples\n--------\n\nSET @pt = \'Point(56.7 53.34)\';\n\nSELECT X(GeomFromText(@pt));\n+----------------------+\n| X(GeomFromText(@pt)) |\n+----------------------+\n| 56.7 |\n+----------------------+\n\nURL: https://mariadb.com/kb/en/st_x/','','https://mariadb.com/kb/en/st_x/'); +insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (120,11,'ST_Y','Syntax\n------\n\nST_Y(p)\nY(p)\n\nDescription\n-----------\n\nReturns the Y-coordinate value for the point p as a double-precision number.\n\nST_Y() and Y() are synonyms.\n\nExamples\n--------\n\nSET @pt = \'Point(56.7 53.34)\';\n\nSELECT Y(GeomFromText(@pt));\n+----------------------+\n| Y(GeomFromText(@pt)) |\n+----------------------+\n| 53.34 |\n+----------------------+\n\nURL: https://mariadb.com/kb/en/st_y/','','https://mariadb.com/kb/en/st_y/'); +insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (121,11,'X','A synonym for ST_X.\n\nURL: https://mariadb.com/kb/en/point-properties-x/','','https://mariadb.com/kb/en/point-properties-x/'); +insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (122,11,'Y','A synonym for ST_Y.\n\nURL: https://mariadb.com/kb/en/point-properties-y/','','https://mariadb.com/kb/en/point-properties-y/'); +insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (123,12,'UNCOMPRESS','Syntax\n------\n\nUNCOMPRESS(string_to_uncompress)\n\nDescription\n-----------\n\nUncompresses a string compressed by the COMPRESS() function. If the argument\nis not a compressed value, the result is NULL. This function requires MariaDB\nto have been compiled with a compression library such as zlib. Otherwise, the\nreturn value is always NULL. The have_compress server system variable\nindicates whether a compression library is present.\n\nExamples\n--------\n\nSELECT UNCOMPRESS(COMPRESS(\'a string\'));\n+----------------------------------+\n| UNCOMPRESS(COMPRESS(\'a string\')) |\n+----------------------------------+\n| a string |\n+----------------------------------+\n\nSELECT UNCOMPRESS(\'a string\');\n+------------------------+\n| UNCOMPRESS(\'a string\') |\n+------------------------+\n| NULL |\n+------------------------+\n\nURL: https://mariadb.com/kb/en/uncompress/','','https://mariadb.com/kb/en/uncompress/'); +insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (124,12,'DECODE','Syntax\n------\n\nDECODE(crypt_str,pass_str)\n\nIn Oracle mode from MariaDB 10.3.2:\n\nDECODE(expr, search_expr, result_expr [, search_expr2, result_expr2 ...]\n[default_expr])\n\nIn all modes from MariaDB 10.3.2:\n\nDECODE_ORACLE(expr, search_expr, result_expr [, search_expr2, result_expr2\n...] [default_expr])\n\nDescription\n-----------\n\nIn the default mode, DECODE decrypts the encrypted string crypt_str using\npass_str as the password. crypt_str should be a string returned from ENCODE().\nThe resulting string will be the original string only if pass_str is the same.\n\nIn Oracle mode from MariaDB 10.3.2, DECODE compares expr to the search\nexpressions, in order. If it finds a match, the corresponding result\nexpression is returned. If no matches are found, the default expression is\nreturned, or NULL if no default is provided.\n\nNULLs are treated as equivalent.\n\nDECODE_ORACLE is a synonym for the Oracle-mode version of the function, and is\navailable in all modes.\n\nExamples\n--------\n\nFrom MariaDB 10.3.2:\n\nSELECT DECODE_ORACLE(2+1,3*1,\'found1\',3*2,\'found2\',\'default\');\n+--------------------------------------------------------+\n| DECODE_ORACLE(2+1,3*1,\'found1\',3*2,\'found2\',\'default\') |\n+--------------------------------------------------------+\n| found1 |\n+--------------------------------------------------------+\n\nSELECT DECODE_ORACLE(2+4,3*1,\'found1\',3*2,\'found2\',\'default\');\n+--------------------------------------------------------+\n| DECODE_ORACLE(2+4,3*1,\'found1\',3*2,\'found2\',\'default\') |\n+--------------------------------------------------------+\n| found2 |\n+--------------------------------------------------------+\n\nSELECT DECODE_ORACLE(2+2,3*1,\'found1\',3*2,\'found2\',\'default\');\n+--------------------------------------------------------+\n| DECODE_ORACLE(2+2,3*1,\'found1\',3*2,\'found2\',\'default\') |\n+--------------------------------------------------------+\n| default |\n+--------------------------------------------------------+\n\nNulls are treated as equivalent:\n\nSELECT DECODE_ORACLE(NULL,NULL,\'Nulls are equivalent\',\'Nulls are not\nequivalent\');\n+----------------------------------------------------------------------------+\n| DECODE_ORACLE(NULL,NULL,\'Nulls are equivalent\',\'Nulls are not equivalent\') |\n+----------------------------------------------------------------------------+\n| Nulls are equivalent |\n+----------------------------------------------------------------------------+\n\nURL: https://mariadb.com/kb/en/decode/','','https://mariadb.com/kb/en/decode/'); +insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (125,12,'DECODE_ORACLE','MariaDB starting with 10.3.2\n----------------------------\nDECODE_ORACLE is a synonym for the Oracle mode version of the DECODE function,\nand is available in all modes.\n\nURL: https://mariadb.com/kb/en/decode_oracle/','','https://mariadb.com/kb/en/decode_oracle/'); +insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (126,12,'AES_DECRYPT','Syntax\n------\n\nAES_DECRYPT(crypt_str,key_str)\n\nDescription\n-----------\n\nThis function allows decryption of data using the official AES (Advanced\nEncryption Standard) algorithm. For more information, see the description of\nAES_ENCRYPT().\n\nURL: https://mariadb.com/kb/en/aes_decrypt/','','https://mariadb.com/kb/en/aes_decrypt/'); +insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (127,12,'AES_ENCRYPT','Syntax\n------\n\nAES_ENCRYPT(str,key_str)\n\nDescription\n-----------\n\nAES_ENCRYPT() and AES_DECRYPT() allow encryption and decryption of data using\nthe official AES (Advanced Encryption Standard) algorithm, previously known as\n\"Rijndael.\" Encoding with a 128-bit key length is used, but you can extend it\nup to 256 bits by modifying the source. We chose 128 bits because it is much\nfaster and it is secure enough for most purposes.\n\nAES_ENCRYPT() encrypts a string str using the key key_str, and returns a\nbinary string.\n\nAES_DECRYPT() decrypts the encrypted string and returns the original string.\n\nThe input arguments may be any length. If either argument is NULL, the result\nof this function is also NULL.\n\nBecause AES is a block-level algorithm, padding is used to encode uneven\nlength strings and so the result string length may be calculated using this\nformula:\n\n16 x (trunc(string_length / 16) + 1)\n\nIf AES_DECRYPT() detects invalid data or incorrect padding, it returns NULL.\nHowever, it is possible for AES_DECRYPT() to return a non-NULL value (possibly\ngarbage) if the input data or the key is invalid.\n\nExamples\n--------\n\nINSERT INTO t VALUES (AES_ENCRYPT(\'text\',SHA2(\'password\',512)));\n\nURL: https://mariadb.com/kb/en/aes_encrypt/','','https://mariadb.com/kb/en/aes_encrypt/'); +insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (128,12,'COMPRESS','Syntax\n------\n\nCOMPRESS(string_to_compress)\n\nDescription\n-----------\n\nCompresses a string and returns the result as a binary string. This function\nrequires MariaDB to have been compiled with a compression library such as\nzlib. Otherwise, the return value is always NULL. The compressed string can be\nuncompressed with UNCOMPRESS().\n\nThe have_compress server system variable indicates whether a compression\nlibrary is present.\n\nExamples\n--------\n\nSELECT LENGTH(COMPRESS(REPEAT(\'a\',1000)));\n+------------------------------------+\n| LENGTH(COMPRESS(REPEAT(\'a\',1000))) |\n+------------------------------------+\n| 21 |\n+------------------------------------+\n\nSELECT LENGTH(COMPRESS(\'\'));\n+----------------------+\n| LENGTH(COMPRESS(\'\')) |\n+----------------------+\n| 0 |\n+----------------------+\n\nSELECT LENGTH(COMPRESS(\'a\'));\n+-----------------------+\n| LENGTH(COMPRESS(\'a\')) |\n+-----------------------+\n| 13 |\n+-----------------------+\n\nSELECT LENGTH(COMPRESS(REPEAT(\'a\',16)));\n+----------------------------------+\n| LENGTH(COMPRESS(REPEAT(\'a\',16))) |\n+----------------------------------+\n| 15 |\n+----------------------------------+\n\nURL: https://mariadb.com/kb/en/compress/','','https://mariadb.com/kb/en/compress/'); +insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (129,12,'DES_DECRYPT','DES_DECRYPT has been deprecated from MariaDB 10.10.0, and will be removed in a\nfuture release.\n\nSyntax\n------\n\nDES_DECRYPT(crypt_str[,key_str])\n\nDescription\n-----------\n\nDecrypts a string encrypted with DES_ENCRYPT(). If an error occurs, this\nfunction returns NULL.\n\nThis function works only if MariaDB has been configured with TLS support.\n\nIf no key_str argument is given, DES_DECRYPT() examines the first byte of the\nencrypted string to determine the DES key number that was used to encrypt the\noriginal string, and then reads the key from the DES key file to decrypt the\nmessage. For this to work, the user must have the SUPER privilege. The key\nfile can be specified with the --des-key-file server option.\n\nIf you pass this function a key_str argument, that string is used as the key\nfor decrypting the message.\n\nIf the crypt_str argument does not appear to be an encrypted string, MariaDB\nreturns the given crypt_str.\n\nURL: https://mariadb.com/kb/en/des_decrypt/','','https://mariadb.com/kb/en/des_decrypt/'); +insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (130,12,'DES_ENCRYPT','DES_ENCRYPT has been deprecated from MariaDB 10.10.0, and will be removed in a\nfuture release.\n\nSyntax\n------\n\nDES_ENCRYPT(str[,{key_num|key_str}])\n\nDescription\n-----------\n\nEncrypts the string with the given key using the Triple-DES algorithm.\n\nThis function works only if MariaDB has been configured with TLS support.\n\nThe encryption key to use is chosen based on the second argument to\nDES_ENCRYPT(), if one was given. With no argument, the first key from the DES\nkey file is used. With a key_num argument, the given key number (0-9) from the\nDES key file is used. With a key_str argument, the given key string is used to\nencrypt str.\n\nThe key file can be specified with the --des-key-file server option.\n\nThe return string is a binary string where the first character is CHAR(128 |\nkey_num). If an error occurs, DES_ENCRYPT() returns NULL.\n\nThe 128 is added to make it easier to recognize an encrypted key. If you use a\nstring key, key_num is 127.\n\nThe string length for the result is given by this formula:\n\nnew_len = orig_len + (8 - (orig_len % 8)) + 1\n\nEach line in the DES key file has the following format:\n\nkey_num des_key_str\n\nEach key_num value must be a number in the range from 0 to 9. Lines in the\nfile may be in any order. des_key_str is the string that is used to encrypt\nthe message. There should be at least one space between the number and the\nkey. The first key is the default key that is used if you do not specify any\nkey argument to DES_ENCRYPT().\n\nYou can tell MariaDB to read new key values from the key file with the FLUSH\nDES_KEY_FILE statement. This requires the RELOAD privilege.\n\nOne benefit of having a set of default keys is that it gives applications a\nway to check for the existence of encrypted column values, without giving the\nend user the right to decrypt those values.\n\nExamples\n--------\n\nSELECT customer_address FROM customer_table \n WHERE crypted_credit_card = DES_ENCRYPT(\'credit_card_number\');\n\nURL: https://mariadb.com/kb/en/des_encrypt/','','https://mariadb.com/kb/en/des_encrypt/'); +insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (131,12,'ENCODE','Syntax\n------\n\nENCODE(str,pass_str)\n\nDescription\n-----------\n\nENCODE is not considered cryptographically secure, and should not be used for\npassword encryption.\n\nEncrypt str using pass_str as the password. To decrypt the result, use\nDECODE().\n\nThe result is a binary string of the same length as str.\n\nThe strength of the encryption is based on how good the random generator is.\n\nIt is not recommended to rely on the encryption performed by the ENCODE\nfunction. Using a salt value (changed when a password is updated) will improve\nmatters somewhat, but for storing passwords, consider a more cryptographically\nsecure function, such as SHA2().\n\nExamples\n--------\n\nENCODE(\'not so secret text\', CONCAT(\'random_salt\',\'password\'))\n\nURL: https://mariadb.com/kb/en/encode/','','https://mariadb.com/kb/en/encode/'); +insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (132,12,'ENCRYPT','Syntax\n------\n\nENCRYPT(str[,salt])\n\nDescription\n-----------\n\nEncrypts a string using the Unix crypt() system call, returning an encrypted\nbinary string. The salt argument should be a string with at least two\ncharacters or the returned result will be NULL. If no salt argument is given,\na random value of sufficient length is used.\n\nIt is not recommended to use ENCRYPT() with utf16, utf32 or ucs2 multi-byte\ncharacter sets because the crypt() system call expects a string terminated\nwith a zero byte.\n\nNote that the underlying crypt() system call may have some limitations, such\nas ignoring all but the first eight characters.\n\nIf the have_crypt system variable is set to NO (because the crypt() system\ncall is not available), the ENCRYPT function will always return NULL.\n\nExamples\n--------\n\nSELECT ENCRYPT(\'encrypt me\');\n+-----------------------+\n| ENCRYPT(\'encrypt me\') |\n+-----------------------+\n| 4I5BsEx0lqTDk |\n+-----------------------+\n\nURL: https://mariadb.com/kb/en/encrypt/','','https://mariadb.com/kb/en/encrypt/'); +insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (133,12,'MD5','Syntax\n------\n\nMD5(str)\n\nDescription\n-----------\n\nCalculates an MD5 128-bit checksum for the string.\n\nThe return value is a 32-hex digit string, and as of MariaDB 5.5, is a\nnonbinary string in the connection character set and collation, determined by\nthe values of the character_set_connection and collation_connection system\nvariables. Before 5.5, the return value was a binary string.\n\nNULL is returned if the argument was NULL.\n\nExamples\n--------\n\nSELECT MD5(\'testing\');\n+----------------------------------+\n| MD5(\'testing\') |\n+----------------------------------+\n| ae2b1fca515949e5d54fb22b8ed95575 |\n+----------------------------------+\n\nURL: https://mariadb.com/kb/en/md5/','','https://mariadb.com/kb/en/md5/'); +insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (134,12,'OLD_PASSWORD','Syntax\n------\n\nOLD_PASSWORD(str)\n\nDescription\n-----------\n\nOLD_PASSWORD() was added to MySQL when the implementation of PASSWORD() was\nchanged to improve security. OLD_PASSWORD() returns the value of the old\n(pre-MySQL 4.1) implementation of PASSWORD() as a string, and is intended to\npermit you to reset passwords for any pre-4.1 clients that need to connect to\na more recent MySQL server version, or any version of MariaDB, without locking\nthem out.\n\nAs of MariaDB 5.5, the return value is a nonbinary string in the connection\ncharacter set and collation, determined by the values of the\ncharacter_set_connection and collation_connection system variables. Before\n5.5, the return value was a binary string.\n\nThe return value is 16 bytes in length, or NULL if the argument was NULL.\n\nURL: https://mariadb.com/kb/en/old_password/','','https://mariadb.com/kb/en/old_password/'); +insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (135,12,'PASSWORD','Syntax\n------\n\nPASSWORD(str)\n\nDescription\n-----------\n\nThe PASSWORD() function is used for hashing passwords for use in\nauthentication by the MariaDB server. It is not intended for use in other\napplications.\n\nCalculates and returns a hashed password string from the plaintext password\nstr. Returns an empty string (>= MariaDB 10.0.4) if the argument was NULL.\n\nThe return value is a nonbinary string in the connection character set and\ncollation, determined by the values of the character_set_connection and\ncollation_connection system variables.\n\nThis is the function that is used for hashing MariaDB passwords for storage in\nthe Password column of the user table (see privileges), usually used with the\nSET PASSWORD statement. It is not intended for use in other applications.\n\nUntil MariaDB 10.3, the return value is 41-bytes in length, and the first\ncharacter is always \'*\'. From MariaDB 10.4, the function takes into account\nthe authentication plugin where applicable (A CREATE USER or SET PASSWORD\nstatement). For example, when used in conjunction with a user authenticated by\nthe ed25519 plugin, the statement will create a longer hash:\n\nCREATE USER edtest@localhost IDENTIFIED VIA ed25519 USING PASSWORD(\'secret\');\n\nCREATE USER edtest2@localhost IDENTIFIED BY \'secret\';\n\nSELECT CONCAT(user, \'@\', host, \' => \', JSON_DETAILED(priv)) FROM\nmysql.global_priv\n WHERE user LIKE \'edtest%\'\\G\n*************************** 1. row ***************************\nCONCAT(user, \'@\', host, \' => \', JSON_DETAILED(priv)): edtest@localhost => {\n...\n \"plugin\": \"ed25519\",\n \"authentication_string\": \"ZIgUREUg5PVgQ6LskhXmO+eZLS0nC8be6HPjYWR4YJY\",\n...\n}\n*************************** 2. row ***************************\nCONCAT(user, \'@\', host, \' => \', JSON_DETAILED(priv)): edtest2@localhost => {\n...\n \"plugin\": \"mysql_native_password\",\n \"authentication_string\": \"*14E65567ABDB5135D0CFD9A70B3032C179A49EE7\",\n...\n}\n\nThe behavior of this function is affected by the value of the old_passwords\nsystem variable. If this is set to 1 (0 is default), MariaDB reverts to using\nthe mysql_old_password authentication plugin by default for newly created\nusers and passwords.\n\nExamples\n--------\n\nSELECT PASSWORD(\'notagoodpwd\');\n+-------------------------------------------+\n| PASSWORD(\'notagoodpwd\') |\n+-------------------------------------------+\n| *3A70EE9FC6594F88CE9E959CD51C5A1C002DC937 |\n+-------------------------------------------+\n\nSET PASSWORD FOR \'bob\'@\'%.loc.gov\' = PASSWORD(\'newpass\');\n\nURL: https://mariadb.com/kb/en/password/','','https://mariadb.com/kb/en/password/'); +insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (136,12,'SHA1','Syntax\n------\n\nSHA1(str), SHA(str)\n\nDescription\n-----------\n\nCalculates an SHA-1 160-bit checksum for the string str, as described in RFC\n3174 (Secure Hash Algorithm).\n\nThe value is returned as a string of 40 hex digits, or NULL if the argument\nwas NULL. As of MariaDB 5.5, the return value is a nonbinary string in the\nconnection character set and collation, determined by the values of the\ncharacter_set_connection and collation_connection system variables. Before\n5.5, the return value was a binary string.\n\nExamples\n--------\n\nSELECT SHA1(\'some boring text\');\n+------------------------------------------+\n| SHA1(\'some boring text\') |\n+------------------------------------------+\n| af969fc2085b1bb6d31e517d5c456def5cdd7093 |\n+------------------------------------------+\n\nURL: https://mariadb.com/kb/en/sha1/','','https://mariadb.com/kb/en/sha1/'); +insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (137,12,'SHA2','Syntax\n------\n\nSHA2(str,hash_len)\n\nDescription\n-----------\n\nGiven a string str, calculates an SHA-2 checksum, which is considered more\ncryptographically secure than its SHA-1 equivalent. The SHA-2 family includes\nSHA-224, SHA-256, SHA-384, and SHA-512, and the hash_len must correspond to\none of these, i.e. 224, 256, 384 or 512. 0 is equivalent to 256.\n\nThe return value is a nonbinary string in the connection character set and\ncollation, determined by the values of the character_set_connection and\ncollation_connection system variables.\n\nNULL is returned if the hash length is not valid, or the string str is NULL.\n\nSHA2 will only work if MariaDB was has been configured with TLS support.\n\nExamples\n--------\n\nSELECT SHA2(\'Maria\',224);\n+----------------------------------------------------------+\n| SHA2(\'Maria\',224) |\n+----------------------------------------------------------+\n| 6cc67add32286412efcab9d0e1675a43a5c2ef3cec8879f81516ff83 |\n+----------------------------------------------------------+\n\nSELECT SHA2(\'Maria\',256);\n+------------------------------------------------------------------+\n| SHA2(\'Maria\',256) |\n+------------------------------------------------------------------+\n| 9ff18ebe7449349f358e3af0b57cf7a032c1c6b2272cb2656ff85eb112232f16 |\n+------------------------------------------------------------------+\n\nSELECT SHA2(\'Maria\',0);\n+------------------------------------------------------------------+\n| SHA2(\'Maria\',0) |\n+------------------------------------------------------------------+\n| 9ff18ebe7449349f358e3af0b57cf7a032c1c6b2272cb2656ff85eb112232f16 |\n+------------------------------------------------------------------+\n\nURL: https://mariadb.com/kb/en/sha2/','','https://mariadb.com/kb/en/sha2/'); +insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (138,13,'ENDPOINT','A synonym for ST_ENDPOINT.\n\nURL: https://mariadb.com/kb/en/linestring-properties-endpoint/','','https://mariadb.com/kb/en/linestring-properties-endpoint/'); +insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (139,13,'GLENGTH','Syntax\n------\n\nGLength(ls)\n\nDescription\n-----------\n\nReturns as a double-precision number the length of the LineString value ls in\nits associated spatial reference.\n\nExamples\n--------\n\nSET @ls = \'LineString(1 1,2 2,3 3)\';\n\nSELECT GLength(GeomFromText(@ls));\n+----------------------------+\n| GLength(GeomFromText(@ls)) |\n+----------------------------+\n| 2.82842712474619 |\n+----------------------------+\n\nURL: https://mariadb.com/kb/en/glength/','','https://mariadb.com/kb/en/glength/'); +insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (140,13,'NumPoints','A synonym for ST_NumPoints.\n\nURL: https://mariadb.com/kb/en/linestring-properties-numpoints/','','https://mariadb.com/kb/en/linestring-properties-numpoints/'); +insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (141,13,'PointN','A synonym for ST_PointN.\n\nURL: https://mariadb.com/kb/en/linestring-properties-pointn/','','https://mariadb.com/kb/en/linestring-properties-pointn/'); +insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (142,13,'STARTPOINT','A synonym for ST_STARTPOINT.\n\nURL: https://mariadb.com/kb/en/linestring-properties-startpoint/','','https://mariadb.com/kb/en/linestring-properties-startpoint/'); +insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (143,13,'ST_ENDPOINT','Syntax\n------\n\nST_EndPoint(ls)\nEndPoint(ls)\n\nDescription\n-----------\n\nReturns the Point that is the endpoint of the LineString value ls.\n\nST_EndPoint() and EndPoint() are synonyms.\n\nExamples\n--------\n\nSET @ls = \'LineString(1 1,2 2,3 3)\';\n\nSELECT AsText(EndPoint(GeomFromText(@ls)));\n+-------------------------------------+\n| AsText(EndPoint(GeomFromText(@ls))) |\n+-------------------------------------+\n| POINT(3 3) |\n+-------------------------------------+\n\nURL: https://mariadb.com/kb/en/st_endpoint/','','https://mariadb.com/kb/en/st_endpoint/'); +insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (144,13,'ST_NUMPOINTS','Syntax\n------\n\nST_NumPoints(ls)\nNumPoints(ls)\n\nDescription\n-----------\n\nReturns the number of Point objects in the LineString value ls.\n\nST_NumPoints() and NumPoints() are synonyms.\n\nExamples\n--------\n\nSET @ls = \'LineString(1 1,2 2,3 3)\';\n\nSELECT NumPoints(GeomFromText(@ls));\n+------------------------------+\n| NumPoints(GeomFromText(@ls)) |\n+------------------------------+\n| 3 |\n+------------------------------+\n\nURL: https://mariadb.com/kb/en/st_numpoints/','','https://mariadb.com/kb/en/st_numpoints/'); +insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (145,13,'ST_POINTN','Syntax\n------\n\nST_PointN(ls,N)\nPointN(ls,N)\n\nDescription\n-----------\n\nReturns the N-th Point in the LineString value ls. Points are numbered\nbeginning with 1.\n\nST_PointN() and PointN() are synonyms.\n\nExamples\n--------\n\nSET @ls = \'LineString(1 1,2 2,3 3)\';\n\nSELECT AsText(PointN(GeomFromText(@ls),2));\n+-------------------------------------+\n| AsText(PointN(GeomFromText(@ls),2)) |\n+-------------------------------------+\n| POINT(2 2) |\n+-------------------------------------+\n\nURL: https://mariadb.com/kb/en/st_pointn/','','https://mariadb.com/kb/en/st_pointn/'); +insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (146,13,'ST_STARTPOINT','Syntax\n------\n\nST_StartPoint(ls)\nStartPoint(ls)\n\nDescription\n-----------\n\nReturns the Point that is the start point of the LineString value ls.\n\nST_StartPoint() and StartPoint() are synonyms.\n\nExamples\n--------\n\nSET @ls = \'LineString(1 1,2 2,3 3)\';\n\nSELECT AsText(StartPoint(GeomFromText(@ls)));\n+---------------------------------------+\n| AsText(StartPoint(GeomFromText(@ls))) |\n+---------------------------------------+\n| POINT(1 1) |\n+---------------------------------------+\n\nURL: https://mariadb.com/kb/en/st_startpoint/','','https://mariadb.com/kb/en/st_startpoint/'); +insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (147,14,'GET_LOCK','Syntax\n------\n\nGET_LOCK(str,timeout)\n\nDescription\n-----------\n\nTries to obtain a lock with a name given by the string str, using a timeout of\ntimeout seconds. Returns 1 if the lock was obtained successfully, 0 if the\nattempt timed out (for example, because another client has previously locked\nthe name), or NULL if an error occurred (such as running out of memory or the\nthread was killed with mysqladmin kill).\n\nA lock is released with RELEASE_LOCK(), when the connection terminates (either\nnormally or abnormally). A connection can hold multiple locks at the same\ntime, so a lock that is no longer needed needs to be explicitly released.\n\nThe IS_FREE_LOCK function returns whether a specified lock a free or not, and\nthe IS_USED_LOCK whether the function is in use or not.\n\nLocks obtained with GET_LOCK() do not interact with transactions. That is,\ncommitting a transaction does not release any such locks obtained during the\ntransaction.\n\nIt is also possible to recursively set the same lock. If a lock with the same\nname is set n times, it needs to be released n times as well.\n\nstr is case insensitive for GET_LOCK() and related functions. If str is an\nempty string or NULL, GET_LOCK() returns NULL and does nothing. From MariaDB\n10.2.2, timeout supports microseconds. Before then, it was rounded to the\nclosest integer.\n\nIf the metadata_lock_info plugin is installed, locks acquired with this\nfunction are visible in the Information Schema METADATA_LOCK_INFO table.\n\nThis function can be used to implement application locks or to simulate record\nlocks. Names are locked on a server-wide basis. If a name has been locked by\none client, GET_LOCK() blocks any request by another client for a lock with\nthe same name. This allows clients that agree on a given lock name to use the\nname to perform cooperative advisory locking. But be aware that it also allows\na client that is not among the set of cooperating clients to lock a name,\neither inadvertently or deliberately, and thus prevent any of the cooperating\nclients from locking that name. One way to reduce the likelihood of this is to\nuse lock names that are database-specific or application-specific. For\nexample, use lock names of the form db_name.str or app_name.str.\n\nStatements using the GET_LOCK function are not safe for statement-based\nreplication.\n\nThe patch to permit multiple locks was contributed by Konstantin \"Kostja\"\nOsipov (MDEV-3917).\n\nExamples\n--------\n\nSELECT GET_LOCK(\'lock1\',10);\n+----------------------+\n| GET_LOCK(\'lock1\',10) |\n+----------------------+\n| 1 |\n+----------------------+\n\nSELECT IS_FREE_LOCK(\'lock1\'), IS_USED_LOCK(\'lock1\');\n+-----------------------+-----------------------+\n| IS_FREE_LOCK(\'lock1\') | IS_USED_LOCK(\'lock1\') |\n+-----------------------+-----------------------+\n| 0 | 46 |\n+-----------------------+-----------------------+\n\nSELECT IS_FREE_LOCK(\'lock2\'), IS_USED_LOCK(\'lock2\');\n+-----------------------+-----------------------+\n| IS_FREE_LOCK(\'lock2\') | IS_USED_LOCK(\'lock2\') |\n+-----------------------+-----------------------+\n| 1 | NULL |\n+-----------------------+-----------------------+\n\nMultiple locks can be held:\n\nSELECT GET_LOCK(\'lock2\',10);\n+----------------------+\n| GET_LOCK(\'lock2\',10) |\n+----------------------+\n| 1 |\n+----------------------+\n\nSELECT IS_FREE_LOCK(\'lock1\'), IS_FREE_LOCK(\'lock2\');\n+-----------------------+-----------------------+\n| IS_FREE_LOCK(\'lock1\') | IS_FREE_LOCK(\'lock2\') |\n+-----------------------+-----------------------+\n| 0 | 0 |\n+-----------------------+-----------------------+\n\nSELECT RELEASE_LOCK(\'lock1\'), RELEASE_LOCK(\'lock2\');\n+-----------------------+-----------------------+\n| RELEASE_LOCK(\'lock1\') | RELEASE_LOCK(\'lock2\') |\n+-----------------------+-----------------------+\n| 1 | 1 |\n+-----------------------+-----------------------+\n\nIt is possible to hold the same lock recursively. This example is viewed using\nthe metadata_lock_info plugin:\n\nSELECT GET_LOCK(\'lock3\',10);\n+----------------------+\n| GET_LOCK(\'lock3\',10) |\n+----------------------+\n| 1 |\n+----------------------+\n\nSELECT GET_LOCK(\'lock3\',10);\n+----------------------+\n| GET_LOCK(\'lock3\',10) |\n+----------------------+\n| 1 |\n+----------------------+\n\nSELECT * FROM INFORMATION_SCHEMA.METADATA_LOCK_INFO;\n+-----------+---------------------+---------------+-----------+--------------+-\n----------+\n| THREAD_ID | LOCK_MODE | LOCK_DURATION | LOCK_TYPE | TABLE_SCHEMA |\nTABLE_NAME |\n+-----------+---------------------+---------------+-----------+--------------+-\n----------+\n| 46 | MDL_SHARED_NO_WRITE | NULL | User lock | lock3 |\n |\n+-----------+---------------------+---------------+-----------+--------------+-\n----------+\n\nSELECT RELEASE_LOCK(\'lock3\');\n+-----------------------+\n| RELEASE_LOCK(\'lock3\') |\n+-----------------------+\n| 1 |\n+-----------------------+\n\nSELECT * FROM INFORMATION_SCHEMA.METADATA_LOCK_INFO;\n+-----------+---------------------+---------------+-----------+--------------+-\n----------+\n| THREAD_ID | LOCK_MODE | LOCK_DURATION | LOCK_TYPE | TABLE_SCHEMA |\nTABLE_NAME |\n+-----------+---------------------+---------------+-----------+--------------+-','','https://mariadb.com/kb/en/get_lock/'); +update help_topic set description = CONCAT(description, '\n----------+\n| 46 | MDL_SHARED_NO_WRITE | NULL | User lock | lock3 |\n |\n+-----------+---------------------+---------------+-----------+--------------+-\n----------+\n\nSELECT RELEASE_LOCK(\'lock3\');\n+-----------------------+\n| RELEASE_LOCK(\'lock3\') |\n+-----------------------+\n| 1 |\n+-----------------------+\n\nSELECT * FROM INFORMATION_SCHEMA.METADATA_LOCK_INFO;\nEmpty set (0.000 sec)\n\nTimeout example: Connection 1:\n\nSELECT GET_LOCK(\'lock4\',10);\n+----------------------+\n| GET_LOCK(\'lock4\',10) |\n+----------------------+\n| 1 |\n+----------------------+\n\nConnection 2:\n\nSELECT GET_LOCK(\'lock4\',10);\n\nAfter 10 seconds...\n\n+----------------------+\n| GET_LOCK(\'lock4\',10) |\n+----------------------+\n| 0 |\n+----------------------+\n\nDeadlocks are automatically detected and resolved. Connection 1:\n\nSELECT GET_LOCK(\'lock5\',10); \n+----------------------+\n| GET_LOCK(\'lock5\',10) |\n+----------------------+\n| 1 |\n+----------------------+\n\nConnection 2:\n\nSELECT GET_LOCK(\'lock6\',10);\n+----------------------+\n| GET_LOCK(\'lock6\',10) |\n+----------------------+\n| 1 |\n+----------------------+\n\nConnection 1:\n\nSELECT GET_LOCK(\'lock6\',10); \n+----------------------+\n| GET_LOCK(\'lock6\',10) |\n+----------------------+\n| 0 |\n+----------------------+\n\nConnection 2:\n\nSELECT GET_LOCK(\'lock5\',10);\nERROR 1213 (40001): Deadlock found when trying to get lock; try restarting\ntransaction\n\nURL: https://mariadb.com/kb/en/get_lock/') WHERE help_topic_id = 147; +insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (148,14,'INET6_ATON','Syntax\n------\n\nINET6_ATON(expr)\n\nDescription\n-----------\n\nGiven an IPv6 or IPv4 network address as a string, returns a binary string\nthat represents the numeric value of the address.\n\nNo trailing zone ID\'s or traling network masks are permitted. For IPv4\naddresses, or IPv6 addresses with IPv4 address parts, no classful addresses or\ntrailing port numbers are permitted and octal numbers are not supported.\n\nThe returned binary string will be VARBINARY(16) or VARBINARY(4) for IPv6 and\nIPv4 addresses respectively.\n\nReturns NULL if the argument is not understood.\n\nMariaDB starting with 10.5.0\n----------------------------\nFrom MariaDB 10.5.0, INET6_ATON can take INET6 as an argument.\n\nExamples\n--------\n\nSELECT HEX(INET6_ATON(\'10.0.1.1\'));\n+-----------------------------+\n| HEX(INET6_ATON(\'10.0.1.1\')) |\n+-----------------------------+\n| 0A000101 |\n+-----------------------------+\n\nSELECT HEX(INET6_ATON(\'48f3::d432:1431:ba23:846f\'));\n+----------------------------------------------+\n| HEX(INET6_ATON(\'48f3::d432:1431:ba23:846f\')) |\n+----------------------------------------------+\n| 48F3000000000000D4321431BA23846F |\n+----------------------------------------------+\n\nURL: https://mariadb.com/kb/en/inet6_aton/','','https://mariadb.com/kb/en/inet6_aton/'); +insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (149,14,'INET6_NTOA','Syntax\n------\n\nINET6_NTOA(expr)\n\nDescription\n-----------\n\nGiven an IPv6 or IPv4 network address as a numeric binary string, returns the\naddress as a nonbinary string in the connection character set.\n\nThe return string is lowercase, and is platform independent, since it does not\nuse functions specific to the operating system. It has a maximum length of 39\ncharacters.\n\nReturns NULL if the argument is not understood.\n\nExamples\n--------\n\nSELECT INET6_NTOA(UNHEX(\'0A000101\'));\n+-------------------------------+\n| INET6_NTOA(UNHEX(\'0A000101\')) |\n+-------------------------------+\n| 10.0.1.1 |\n+-------------------------------+\n\nSELECT INET6_NTOA(UNHEX(\'48F3000000000000D4321431BA23846F\'));\n+-------------------------------------------------------+\n| INET6_NTOA(UNHEX(\'48F3000000000000D4321431BA23846F\')) |\n+-------------------------------------------------------+\n| 48f3::d432:1431:ba23:846f |\n+-------------------------------------------------------+\n\nURL: https://mariadb.com/kb/en/inet6_ntoa/','','https://mariadb.com/kb/en/inet6_ntoa/'); +insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (150,14,'INET_ATON','Syntax\n------\n\nINET_ATON(expr)\n\nDescription\n-----------\n\nGiven the dotted-quad representation of an IPv4 network address as a string,\nreturns an integer that represents the numeric value of the address. Addresses\nmay be 4- or 8-byte addresses.\n\nReturns NULL if the argument is not understood.\n\nExamples\n--------\n\nSELECT INET_ATON(\'192.168.1.1\');\n+--------------------------+\n| INET_ATON(\'192.168.1.1\') |\n+--------------------------+\n| 3232235777 |\n+--------------------------+\n\nThis is calculated as follows: 192 x 2563 + 168 x 256 2 + 1 x 256 + 1\n\nURL: https://mariadb.com/kb/en/inet_aton/','','https://mariadb.com/kb/en/inet_aton/'); +insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (151,14,'INET_NTOA','Syntax\n------\n\nINET_NTOA(expr)\n\nDescription\n-----------\n\nGiven a numeric IPv4 network address in network byte order (4 or 8 byte),\nreturns the dotted-quad representation of the address as a string.\n\nExamples\n--------\n\nSELECT INET_NTOA(3232235777);\n+-----------------------+\n| INET_NTOA(3232235777) |\n+-----------------------+\n| 192.168.1.1 |\n+-----------------------+\n\n192.168.1.1 corresponds to 3232235777 since 192 x 2563 + 168 x 256 2 + 1 x 256\n+ 1 = 3232235777\n\nURL: https://mariadb.com/kb/en/inet_ntoa/','','https://mariadb.com/kb/en/inet_ntoa/'); +insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (152,14,'IS_FREE_LOCK','Syntax\n------\n\nIS_FREE_LOCK(str)\n\nDescription\n-----------\n\nChecks whether the lock named str is free to use (that is, not locked).\nReturns 1 if the lock is free (no one is using the lock), 0 if the lock is in\nuse, and NULL if an error occurs (such as an incorrect argument, like an empty\nstring or NULL). str is case insensitive.\n\nIf the metadata_lock_info plugin is installed, the Information Schema\nmetadata_lock_info table contains information about locks of this kind (as\nwell as metadata locks).\n\nStatements using the IS_FREE_LOCK function are not safe for statement-based\nreplication.\n\nURL: https://mariadb.com/kb/en/is_free_lock/','','https://mariadb.com/kb/en/is_free_lock/'); +insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (153,14,'IS_IPV4','Syntax\n------\n\nIS_IPV4(expr)\n\nDescription\n-----------\n\nIf the expression is a valid IPv4 address, returns 1, otherwise returns 0.\n\nIS_IPV4() is stricter than INET_ATON(), but as strict as INET6_ATON(), in\ndetermining the validity of an IPv4 address. This implies that if IS_IPV4\nreturns 1, the same expression will always return a non-NULL result when\npassed to INET_ATON(), but that the reverse may not apply.\n\nExamples\n--------\n\nSELECT IS_IPV4(\'1110.0.1.1\');\n+-----------------------+\n| IS_IPV4(\'1110.0.1.1\') |\n+-----------------------+\n| 0 |\n+-----------------------+\n\nSELECT IS_IPV4(\'48f3::d432:1431:ba23:846f\');\n+--------------------------------------+\n| IS_IPV4(\'48f3::d432:1431:ba23:846f\') |\n+--------------------------------------+\n| 0 |\n+--------------------------------------+\n\nURL: https://mariadb.com/kb/en/is_ipv4/','','https://mariadb.com/kb/en/is_ipv4/'); +insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (154,14,'IS_IPV4_COMPAT','Syntax\n------\n\nIS_IPV4_COMPAT(expr)\n\nDescription\n-----------\n\nReturns 1 if a given numeric binary string IPv6 address, such as returned by\nINET6_ATON(), is IPv4-compatible, otherwise returns 0.\n\nMariaDB starting with 10.5.0\n----------------------------\nFrom MariaDB 10.5.0, when the argument is not INET6, automatic implicit CAST\nto INET6 is applied. As a consequence, IS_IPV4_COMPAT now understands\narguments in both text representation and binary(16) representation. Before\nMariaDB 10.5.0, the function understood only binary(16) representation.\n\nExamples\n--------\n\nSELECT IS_IPV4_COMPAT(INET6_ATON(\'::10.0.1.1\'));\n+------------------------------------------+\n| IS_IPV4_COMPAT(INET6_ATON(\'::10.0.1.1\')) |\n+------------------------------------------+\n| 1 |\n+------------------------------------------+\n\nSELECT IS_IPV4_COMPAT(INET6_ATON(\'::48f3::d432:1431:ba23:846f\'));\n+-----------------------------------------------------------+\n| IS_IPV4_COMPAT(INET6_ATON(\'::48f3::d432:1431:ba23:846f\')) |\n+-----------------------------------------------------------+\n| 0 |\n+-----------------------------------------------------------+\n\nURL: https://mariadb.com/kb/en/is_ipv4_compat/','','https://mariadb.com/kb/en/is_ipv4_compat/'); +insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (155,14,'IS_IPV4_MAPPED','Syntax\n------\n\nIS_IPV4_MAPPED(expr)\n\nDescription\n-----------\n\nReturns 1 if a given a numeric binary string IPv6 address, such as returned by\nINET6_ATON(), is a valid IPv4-mapped address, otherwise returns 0.\n\nMariaDB starting with 10.5.0\n----------------------------\nFrom MariaDB 10.5.0, when the argument is not INET6, automatic implicit CAST\nto INET6 is applied. As a consequence, IS_IPV4_MAPPED now understands\narguments in both text representation and binary(16) representation. Before\nMariaDB 10.5.0, the function understood only binary(16) representation.\n\nExamples\n--------\n\nSELECT IS_IPV4_MAPPED(INET6_ATON(\'::10.0.1.1\'));\n+------------------------------------------+\n| IS_IPV4_MAPPED(INET6_ATON(\'::10.0.1.1\')) |\n+------------------------------------------+\n| 0 |\n+------------------------------------------+\n\nSELECT IS_IPV4_MAPPED(INET6_ATON(\'::ffff:10.0.1.1\'));\n+-----------------------------------------------+\n| IS_IPV4_MAPPED(INET6_ATON(\'::ffff:10.0.1.1\')) |\n+-----------------------------------------------+\n| 1 |\n+-----------------------------------------------+\n\nURL: https://mariadb.com/kb/en/is_ipv4_mapped/','','https://mariadb.com/kb/en/is_ipv4_mapped/'); +insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (156,14,'IS_IPV6','Syntax\n------\n\nIS_IPV6(expr)\n\nDescription\n-----------\n\nReturns 1 if the expression is a valid IPv6 address specified as a string,\notherwise returns 0. Does not consider IPv4 addresses to be valid IPv6\naddresses.\n\nExamples\n--------\n\nSELECT IS_IPV6(\'48f3::d432:1431:ba23:846f\');\n+--------------------------------------+\n| IS_IPV6(\'48f3::d432:1431:ba23:846f\') |\n+--------------------------------------+\n| 1 |\n+--------------------------------------+\n1 row in set (0.02 sec)\n\nSELECT IS_IPV6(\'10.0.1.1\');\n+---------------------+\n| IS_IPV6(\'10.0.1.1\') |\n+---------------------+\n| 0 |\n+---------------------+\n\nURL: https://mariadb.com/kb/en/is_ipv6/','','https://mariadb.com/kb/en/is_ipv6/'); +insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (157,14,'IS_USED_LOCK','Syntax\n------\n\nIS_USED_LOCK(str)\n\nDescription\n-----------\n\nChecks whether the lock named str is in use (that is, locked). If so, it\nreturns the connection identifier of the client that holds the lock.\nOtherwise, it returns NULL. str is case insensitive.\n\nIf the metadata_lock_info plugin is installed, the Information Schema\nmetadata_lock_info table contains information about locks of this kind (as\nwell as metadata locks).\n\nStatements using the IS_USED_LOCK function are not safe for statement-based\nreplication.\n\nURL: https://mariadb.com/kb/en/is_used_lock/','','https://mariadb.com/kb/en/is_used_lock/'); +insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (158,14,'MASTER_GTID_WAIT','Syntax\n------\n\nMASTER_GTID_WAIT(gtid-list[, timeout)\n\nDescription\n-----------\n\nThis function takes a string containing a comma-separated list of global\ntransaction id\'s (similar to the value of, for example, gtid_binlog_pos). It\nwaits until the value of gtid_slave_pos has the same or higher seq_no within\nall replication domains specified in the gtid-list; in other words, it waits\nuntil the slave has reached the specified GTID position.\n\nAn optional second argument gives a timeout in seconds. If the timeout expires\nbefore the specified GTID position is reached, then the function returns -1.\nPassing NULL or a negative number for the timeout means no timeout, and the\nfunction will wait indefinitely.\n\nIf the wait completes without a timeout, 0 is returned. Passing NULL for the\ngtid-list makes the function return NULL immediately, without waiting.\n\nThe gtid-list may be the empty string, in which case MASTER_GTID_WAIT()\nreturns immediately. If the gtid-list contains fewer domains than\ngtid_slave_pos, then only those domains are waited upon. If gtid-list contains\na domain that is not present in @@gtid_slave_pos, then MASTER_GTID_WAIT() will\nwait until an event containing such domain_id arrives on the slave (or until\ntimed out or killed).\n\nMASTER_GTID_WAIT() can be useful to ensure that a slave has caught up to a\nmaster. Simply take the value of gtid_binlog_pos on the master, and use it in\na MASTER_GTID_WAIT() call on the slave; when the call completes, the slave\nwill have caught up with that master position.\n\nMASTER_GTID_WAIT() can also be used in client applications together with the\nlast_gtid session variable. This is useful in a read-scaleout replication\nsetup, where the application writes to a single master but divides the reads\nout to a number of slaves to distribute the load. In such a setup, there is a\nrisk that an application could first do an update on the master, and then a\nbit later do a read on a slave, and if the slave is not fast enough, the data\nread from the slave might not include the update just made, possibly confusing\nthe application and/or the end-user. One way to avoid this is to request the\nvalue of last_gtid on the master just after the update. Then before doing the\nread on the slave, do a MASTER_GTID_WAIT() on the value obtained from the\nmaster; this will ensure that the read is not performed until the slave has\nreplicated sufficiently far for the update to have become visible.\n\nNote that MASTER_GTID_WAIT() can be used even if the slave is configured not\nto use GTID for connections (CHANGE MASTER TO master_use_gtid=no). This is\nbecause from MariaDB 10, GTIDs are always logged on the master server, and\nalways recorded on the slave servers.\n\nDifferences to MASTER_POS_WAIT()\n--------------------------------\n\n* MASTER_GTID_WAIT() is global; it waits for any master connection to reach\n the specified GTID position. MASTER_POS_WAIT() works only against a\n specific connection. This also means that while MASTER_POS_WAIT() aborts if\n its master connection is terminated with STOP SLAVE or due to an error,\n MASTER_GTID_WAIT() continues to wait while slaves are stopped.\n\n* MASTER_GTID_WAIT() can take its timeout as a floating-point value, so a\n timeout in fractional seconds is supported, eg. MASTER_GTID_WAIT(\"0-1-100\",\n 0.5). (The minimum wait is one microsecond, 0.000001 seconds).\n\n* MASTER_GTID_WAIT() allows one to specify a timeout of zero in order to do a\n non-blocking check to see if the slaves have progressed to a specific GTID\nposition\n (MASTER_POS_WAIT() takes a zero timeout as meaning an infinite wait). To do\n an infinite MASTER_GTID_WAIT(), specify a negative timeout, or omit the\n timeout argument.\n\n* MASTER_GTID_WAIT() does not return the number of events executed since the\n wait started, nor does it return NULL if a slave thread is stopped. It\n always returns either 0 for successful wait completed, or -1 for timeout\n reached (or NULL if the specified gtid-pos is NULL).\n\nSince MASTER_GTID_WAIT() looks only at the seq_no part of the GTIDs, not the\nserver_id, care is needed if a slave becomes diverged from another server so\nthat two different GTIDs with the same seq_no (in the same domain) arrive at\nthe same server. This situation is in any case best avoided; setting\ngtid_strict_mode is recommended, as this will prevent any such out-of-order\nsequence numbers from ever being replicated on a slave.\n\nURL: https://mariadb.com/kb/en/master_gtid_wait/','','https://mariadb.com/kb/en/master_gtid_wait/'); +insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (159,14,'MASTER_POS_WAIT','Syntax\n------\n\nMASTER_POS_WAIT(log_name,log_pos[,timeout,[\"connection_name\"]])\n\nDescription\n-----------\n\nThis function is useful in replication for controlling primary/replica\nsynchronization. It blocks until the replica has read and applied all updates\nup to the specified position (log_name,log_pos) in the primary log. The return\nvalue is the number of log events the replica had to wait for to advance to\nthe specified position. The function returns NULL if the replica SQL thread is\nnot started, the replica\'s primary information is not initialized, the\narguments are incorrect, or an error occurs. It returns -1 if the timeout has\nbeen exceeded. If the replica SQL thread stops while MASTER_POS_WAIT() is\nwaiting, the function returns NULL. If the replica is past the specified\nposition, the function returns immediately.\n\nIf a timeout value is specified, MASTER_POS_WAIT() stops waiting when timeout\nseconds have elapsed. timeout must be greater than 0; a zero or negative\ntimeout means no timeout.\n\nThe connection_name is used when you are using multi-source-replication. If\nyou don\'t specify it, it\'s set to the value of the default_master_connection\nsystem variable.\n\nStatements using the MASTER_POS_WAIT() function are not safe for replication.\n\nURL: https://mariadb.com/kb/en/master_pos_wait/','','https://mariadb.com/kb/en/master_pos_wait/'); +insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (160,14,'NAME_CONST','Syntax\n------\n\nNAME_CONST(name,value)\n\nDescription\n-----------\n\nReturns the given value. When used to produce a result set column,\nNAME_CONST() causes the column to have the given name. The arguments should be\nconstants.\n\nThis function is used internally when replicating stored procedures. It makes\nlittle sense to use it explicitly in SQL statements, and it was not supposed\nto be used like that.\n\nSELECT NAME_CONST(\'myname\', 14);\n+--------+\n| myname |\n+--------+\n| 14 |\n+--------+\n\nURL: https://mariadb.com/kb/en/name_const/','','https://mariadb.com/kb/en/name_const/'); +insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (161,14,'RELEASE_LOCK','Syntax\n------\n\nRELEASE_LOCK(str)\n\nDescription\n-----------\n\nReleases the lock named by the string str that was obtained with GET_LOCK().\nReturns 1 if the lock was released, 0 if the lock was not established by this\nthread (in which case the lock is not released), and NULL if the named lock\ndid not exist. The lock does not exist if it was never obtained by a call to\nGET_LOCK() or if it has previously been released.\n\nstr is case insensitive. If str is an empty string or NULL, RELEASE_LOCK()\nreturns NULL and does nothing.\n\nStatements using the RELEASE_LOCK() function are not safe for replication.\n\nThe DO statement is convenient to use with RELEASE_LOCK().\n\nExamples\n--------\n\nConnection1:\n\nSELECT GET_LOCK(\'lock1\',10);\n+----------------------+\n| GET_LOCK(\'lock1\',10) |\n+----------------------+\n| 1 |\n+----------------------+\n\nConnection 2:\n\nSELECT GET_LOCK(\'lock2\',10);\n+----------------------+\n| GET_LOCK(\'lock2\',10) |\n+----------------------+\n| 1 |\n+----------------------+\n\nConnection 1:\n\nSELECT RELEASE_LOCK(\'lock1\'), RELEASE_LOCK(\'lock2\'), RELEASE_LOCK(\'lock3\');\n+-----------------------+-----------------------+-----------------------+\n| RELEASE_LOCK(\'lock1\') | RELEASE_LOCK(\'lock2\') | RELEASE_LOCK(\'lock3\') |\n+-----------------------+-----------------------+-----------------------+\n| 1 | 0 | NULL |\n+-----------------------+-----------------------+-----------------------+\n\nFrom MariaDB 10.0.2, it is possible to hold the same lock recursively. This\nexample is viewed using the metadata_lock_info plugin:\n\nSELECT GET_LOCK(\'lock3\',10);\n+----------------------+\n| GET_LOCK(\'lock3\',10) |\n+----------------------+\n| 1 |\n+----------------------+\n\nSELECT GET_LOCK(\'lock3\',10);\n+----------------------+\n| GET_LOCK(\'lock3\',10) |\n+----------------------+\n| 1 |\n+----------------------+\n\nSELECT * FROM INFORMATION_SCHEMA.METADATA_LOCK_INFO;\n+-----------+---------------------+---------------+-----------+--------------+-\n----------+\n| THREAD_ID | LOCK_MODE | LOCK_DURATION | LOCK_TYPE | TABLE_SCHEMA |\nTABLE_NAME |\n+-----------+---------------------+---------------+-----------+--------------+-\n----------+\n| 46 | MDL_SHARED_NO_WRITE | NULL | User lock | lock3 |\n |\n+-----------+---------------------+---------------+-----------+--------------+-\n----------+\n\nSELECT RELEASE_LOCK(\'lock3\');\n+-----------------------+\n| RELEASE_LOCK(\'lock3\') |\n+-----------------------+\n| 1 |\n+-----------------------+\n\nSELECT * FROM INFORMATION_SCHEMA.METADATA_LOCK_INFO;\n+-----------+---------------------+---------------+-----------+--------------+-\n----------+\n| THREAD_ID | LOCK_MODE | LOCK_DURATION | LOCK_TYPE | TABLE_SCHEMA |\nTABLE_NAME |\n+-----------+---------------------+---------------+-----------+--------------+-\n----------+\n| 46 | MDL_SHARED_NO_WRITE | NULL | User lock | lock3 |\n |\n+-----------+---------------------+---------------+-----------+--------------+-\n----------+\n\nSELECT RELEASE_LOCK(\'lock3\');\n+-----------------------+\n| RELEASE_LOCK(\'lock3\') |\n+-----------------------+\n| 1 |\n+-----------------------+\n\nSELECT * FROM INFORMATION_SCHEMA.METADATA_LOCK_INFO;\nEmpty set (0.000 sec)\n\nURL: https://mariadb.com/kb/en/release_lock/','','https://mariadb.com/kb/en/release_lock/'); +insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (162,14,'SLEEP','Syntax\n------\n\nSLEEP(duration)\n\nDescription\n-----------\n\nSleeps (pauses) for the number of seconds given by the duration argument, then\nreturns 0. If SLEEP() is interrupted, it returns 1. The duration may have a\nfractional part given in microseconds.\n\nStatements using the SLEEP() function are not safe for replication.\n\nExample\n-------\n\nSELECT SLEEP(5.5);\n+------------+\n| SLEEP(5.5) |\n+------------+\n| 0 |\n+------------+\n1 row in set (5.50 sec)\n\nURL: https://mariadb.com/kb/en/sleep/','','https://mariadb.com/kb/en/sleep/'); +insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (163,14,'UUID','Syntax\n------\n\nUUID()\n\nDescription\n-----------\n\nReturns a Universally Unique Identifier (UUID).\n\nA UUID is designed as a number that is globally unique in space and time. Two\ncalls to UUID() are expected to generate two different values, even if these\ncalls are performed on two separate computers that are not connected to each\nother.\n\nUUID() results are intended to be unique, but cannot always be relied upon to\nunpredictable and unguessable, so should not be relied upon for these purposes.\n\nA UUID is a 128-bit number represented by a utf8 string of five hexadecimal\nnumbers in aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee format:\n\n* The first three numbers are generated from a timestamp.\n* The fourth number preserves temporal uniqueness in case the timestamp value\n loses monotonicity (for example, due to daylight saving time).\n* The fifth number is an IEEE 802 node number that provides spatial uniqueness.\n A random number is substituted if the latter is not available (for example,\n because the host computer has no Ethernet card, or we do not know how to find\n the hardware address of an interface on your operating system). In this case,\n spatial uniqueness cannot be guaranteed. Nevertheless, a collision should\n have very low probability.\n\nCurrently, the MAC address of an interface is taken into account only on\nFreeBSD and Linux. On other operating systems, MariaDB uses a randomly\ngenerated 48-bit number.\n\nStatements using the UUID() function are not safe for replication.\n\nThe results are generated according to the \"DCE 1.1:Remote Procedure Call\"\n(Appendix A) CAE (Common Applications Environment) Specifications published by\nThe Open Group in October 1997 (Document Number C706).\n\nExamples\n--------\n\nSELECT UUID();\n+--------------------------------------+\n| UUID() |\n+--------------------------------------+\n| cd41294a-afb0-11df-bc9b-00241dd75637 |\n+--------------------------------------+\n\nURL: https://mariadb.com/kb/en/uuid/','','https://mariadb.com/kb/en/uuid/'); +insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (164,14,'UUID_SHORT','Syntax\n------\n\nUUID_SHORT()\n\nDescription\n-----------\n\nReturns a \"short\" universally unique identifier as a 64-bit unsigned integer\n(rather than a string-form 128-bit identifier as returned by the UUID()\nfunction).\n\nThe value of UUID_SHORT() is guaranteed to be unique if the following\nconditions hold:\n\n* The server_id of the current host is unique among your set of master and\n slave servers\n* server_id is between 0 and 255\n* You don\'t set back your system time for your server between mysqld restarts\n* You do not invoke UUID_SHORT() on average more than 16\n million times per second between mysqld restarts\n\nThe UUID_SHORT() return value is constructed this way:\n\n(server_id & 255) << 56\n+ (server_startup_time_in_seconds << 24)\n+ incremented_variable++;\n\nStatements using the UUID_SHORT() function are not safe for statement-based\nreplication.\n\nExamples\n--------\n\nSELECT UUID_SHORT();\n+-------------------+\n| UUID_SHORT() |\n+-------------------+\n| 21517162376069120 |\n+-------------------+\n\ncreate table t1 (a bigint unsigned default(uuid_short()) primary key);\ninsert into t1 values(),();\nselect * from t1;\n+-------------------+\n| a |\n+-------------------+\n| 98113699159474176 |\n| 98113699159474177 |\n+-------------------+\n\nURL: https://mariadb.com/kb/en/uuid_short/','','https://mariadb.com/kb/en/uuid_short/'); +insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (165,14,'VALUES / VALUE','Syntax\n------\n\nMariaDB starting with 10.3.3\n----------------------------\n\nVALUE(col_name)\n\nMariaDB until 10.3.2\n--------------------\n\nVALUES(col_name)\n\nDescription\n-----------\n\nIn an INSERT ... ON DUPLICATE KEY UPDATE statement, you can use the\nVALUES(col_name) function in the UPDATE clause to refer to column values from\nthe INSERT portion of the statement. In other words, VALUES(col_name) in the\nUPDATE clause refers to the value of col_name that would be inserted, had no\nduplicate-key conflict occurred. This function is especially useful in\nmultiple-row inserts.\n\nThe VALUES() function is meaningful only in INSERT ... ON DUPLICATE KEY UPDATE\nstatements and returns NULL otherwise.\n\nIn MariaDB 10.3.3 this function was renamed to VALUE(), because it\'s\nincompatible with the standard Table Value Constructors syntax, implemented in\nMariaDB 10.3.3.\n\nThe VALUES() function can still be used even from MariaDB 10.3.3, but only in\nINSERT ... ON DUPLICATE KEY UPDATE statements; it\'s a syntax error otherwise.\n\nExamples\n--------\n\nMariaDB starting with 10.3.3\n----------------------------\n\nINSERT INTO t (a,b,c) VALUES (1,2,3),(4,5,6)\n ON DUPLICATE KEY UPDATE c=VALUE(a)+VALUE(b);\n\nMariaDB until 10.3.2\n--------------------\n\nINSERT INTO t (a,b,c) VALUES (1,2,3),(4,5,6)\n ON DUPLICATE KEY UPDATE c=VALUES(a)+VALUES(b);\n\nURL: https://mariadb.com/kb/en/values-value/','','https://mariadb.com/kb/en/values-value/'); +insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (166,15,'!','Syntax\n------\n\nNOT, !\n\nDescription\n-----------\n\nLogical NOT. Evaluates to 1 if the operand is 0, to 0 if the operand is\nnon-zero, and NOT NULL returns NULL.\n\nBy default, the ! operator has a higher precedence. If the HIGH_NOT_PRECEDENCE\nSQL_MODE flag is set, NOT and ! have the same precedence.\n\nExamples\n--------\n\nSELECT NOT 10;\n+--------+\n| NOT 10 |\n+--------+\n| 0 |\n+--------+\n\nSELECT NOT 0;\n+-------+\n| NOT 0 |\n+-------+\n| 1 |\n+-------+\n\nSELECT NOT NULL;\n+----------+\n| NOT NULL |\n+----------+\n| NULL |\n+----------+\n\nSELECT ! (1+1);\n+---------+\n| ! (1+1) |\n+---------+\n| 0 |\n+---------+\n\nSELECT ! 1+1;\n+-------+\n| ! 1+1 |\n+-------+\n| 1 |\n+-------+\n\nURL: https://mariadb.com/kb/en/not/','','https://mariadb.com/kb/en/not/'); +insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (167,15,'&&','Syntax\n------\n\nAND, &&\n\nDescription\n-----------\n\nLogical AND. Evaluates to 1 if all operands are non-zero and not NULL, to 0 if\none or more operands are 0, otherwise NULL is returned.\n\nFor this operator, short-circuit evaluation can be used.\n\nExamples\n--------\n\nSELECT 1 && 1;\n+--------+\n| 1 && 1 |\n+--------+\n| 1 |\n+--------+\n\nSELECT 1 && 0;\n+--------+\n| 1 && 0 |\n+--------+\n| 0 |\n+--------+\n\nSELECT 1 && NULL;\n+-----------+\n| 1 && NULL |\n+-----------+\n| NULL |\n+-----------+\n\nSELECT 0 && NULL;\n+-----------+\n| 0 && NULL |\n+-----------+\n| 0 |\n+-----------+\n\nSELECT NULL && 0;\n+-----------+\n| NULL && 0 |\n+-----------+\n| 0 |\n+-----------+\n\nURL: https://mariadb.com/kb/en/and/','','https://mariadb.com/kb/en/and/'); +insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (168,15,'XOR','Syntax\n------\n\nXOR\n\nDescription\n-----------\n\nXOR stands for eXclusive OR. Returns NULL if either operand is NULL. For\nnon-NULL operands, evaluates to 1 if an odd number of operands is non-zero,\notherwise 0 is returned.\n\nExamples\n--------\n\nSELECT 1 XOR 1;\n+---------+\n| 1 XOR 1 |\n+---------+\n| 0 |\n+---------+\n\nSELECT 1 XOR 0;\n+---------+\n| 1 XOR 0 |\n+---------+\n| 1 |\n+---------+\n\nSELECT 1 XOR NULL;\n+------------+\n| 1 XOR NULL |\n+------------+\n| NULL |\n+------------+\n\nIn the following example, the right 1 XOR 1 is evaluated first, and returns 0.\nThen, 1 XOR 0 is evaluated, and 1 is returned.\n\nSELECT 1 XOR 1 XOR 1;\n+---------------+\n| 1 XOR 1 XOR 1 |\n+---------------+\n| 1 |\n+---------------+\n\nURL: https://mariadb.com/kb/en/xor/','','https://mariadb.com/kb/en/xor/'); +insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (169,15,'||','Syntax\n------\n\nOR, ||\n\nDescription\n-----------\n\nLogical OR. When both operands are non-NULL, the result is 1 if any operand is\nnon-zero, and 0 otherwise. With a NULL operand, the result is 1 if the other\noperand is non-zero, and NULL otherwise. If both operands are NULL, the result\nis NULL.\n\nFor this operator, short-circuit evaluation can be used.\n\nNote that, if the PIPES_AS_CONCAT SQL_MODE is set, || is used as a string\nconcatenation operator. This means that a || b is the same as CONCAT(a,b). See\nCONCAT() for details.\n\nOracle Mode\n-----------\n\nMariaDB starting with 10.3\n--------------------------\nIn Oracle mode from MariaDB 10.3, || ignores NULL.\n\nExamples\n--------\n\nSELECT 1 || 1;\n+--------+\n| 1 || 1 |\n+--------+\n| 1 |\n+--------+\n\nSELECT 1 || 0;\n+--------+\n| 1 || 0 |\n+--------+\n| 1 |\n+--------+\n\nSELECT 0 || 0;\n+--------+\n| 0 || 0 |\n+--------+\n| 0 |\n+--------+\n\nSELECT 0 || NULL;\n+-----------+\n| 0 || NULL |\n+-----------+\n| NULL |\n+-----------+\n\nSELECT 1 || NULL;\n+-----------+\n| 1 || NULL |\n+-----------+\n| 1 |\n+-----------+\n\nIn Oracle mode, from MariaDB 10.3:\n\nSELECT 0 || NULL;\n+-----------+\n| 0 || NULL |\n+-----------+\n| 0 |\n+-----------+\n\nURL: https://mariadb.com/kb/en/or/','','https://mariadb.com/kb/en/or/'); +insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (170,16,'Stored Aggregate Functions','MariaDB starting with 10.3.3\n----------------------------\nThe ability to create stored aggregate functions was added in MariaDB 10.3.3.\n\nAggregate functions are functions that are computed over a sequence of rows\nand return one result for the sequence of rows.\n\nCreating a custom aggregate function is done using the CREATE FUNCTION\nstatement with two main differences:\n\n* The addition of the AGGREGATE keyword, so CREATE AGGREGATE FUNCTION\n* The FETCH GROUP NEXT ROW instruction inside the loop\n* Oracle PL/SQL compatibility using SQL/PL is provided\n\nStandard Syntax\n---------------\n\nCREATE AGGREGATE FUNCTION function_name (parameters) RETURNS return_type\nBEGIN\n All types of declarations\n DECLARE CONTINUE HANDLER FOR NOT FOUND RETURN return_val;\n LOOP\n FETCH GROUP NEXT ROW; // fetches next row from table\n other instructions\n END LOOP;\nEND\n\nStored aggregate functions were a 2016 Google Summer of Code project by Varun\nGupta.\n\nUsing SQL/PL\n------------\n\nSET sql_mode=Oracle;\nDELIMITER //\n\nCREATE AGGREGATE FUNCTION function_name (parameters) RETURN return_type\n declarations\nBEGIN\n LOOP\n FETCH GROUP NEXT ROW; -- fetches next row from table\n -- other instructions\n\nEND LOOP;\nEXCEPTION\n WHEN NO_DATA_FOUND THEN\n RETURN return_val;\nEND //\n\nDELIMITER ;\n\nExamples\n--------\n\nFirst a simplified example:\n\nCREATE TABLE marks(stud_id INT, grade_count INT);\n\nINSERT INTO marks VALUES (1,6), (2,4), (3,7), (4,5), (5,8);\n\nSELECT * FROM marks;\n+---------+-------------+\n| stud_id | grade_count |\n+---------+-------------+\n| 1 | 6 |\n| 2 | 4 |\n| 3 | 7 |\n| 4 | 5 |\n| 5 | 8 |\n+---------+-------------+\n\nDELIMITER //\nCREATE AGGREGATE FUNCTION IF NOT EXISTS aggregate_count(x INT) RETURNS INT\nBEGIN\n DECLARE count_students INT DEFAULT 0;\n DECLARE CONTINUE HANDLER FOR NOT FOUND\n RETURN count_students;\n LOOP\n FETCH GROUP NEXT ROW;\n IF x THEN\n SET count_students = count_students+1;\n END IF;\n END LOOP;\nEND //\nDELIMITER ;\n\nA non-trivial example that cannot easily be rewritten using existing functions:\n\nDELIMITER //\nCREATE AGGREGATE FUNCTION medi_int(x INT) RETURNS DOUBLE\nBEGIN\n DECLARE CONTINUE HANDLER FOR NOT FOUND\n BEGIN\n DECLARE res DOUBLE;\n DECLARE cnt INT DEFAULT (SELECT COUNT(*) FROM tt);\n DECLARE lim INT DEFAULT (cnt-1) DIV 2;\n IF cnt % 2 = 0 THEN\n SET res = (SELECT AVG(a) FROM (SELECT a FROM tt ORDER BY a LIMIT\nlim,2) ttt);\n ELSE\n SET res = (SELECT a FROM tt ORDER BY a LIMIT lim,1);\n END IF;\n DROP TEMPORARY TABLE tt;\n RETURN res;\n END;\n CREATE TEMPORARY TABLE tt (a INT);\n LOOP\n FETCH GROUP NEXT ROW;\n INSERT INTO tt VALUES (x);\n END LOOP;\nEND //\nDELIMITER ;\n\nSQL/PL Example\n--------------\n\nThis uses the same marks table as created above.\n\nSET sql_mode=Oracle;\nDELIMITER //\n\nCREATE AGGREGATE FUNCTION aggregate_count(x INT) RETURN INT AS count_students\nINT DEFAULT 0;\nBEGIN\n LOOP\n FETCH GROUP NEXT ROW;\n IF x THEN\n SET count_students := count_students+1;\n END IF;\n END LOOP;\nEXCEPTION\n WHEN NO_DATA_FOUND THEN\n RETURN count_students;\nEND aggregate_count //\nDELIMITER ;\n\nSELECT aggregate_count(stud_id) FROM marks;\n\nURL: https://mariadb.com/kb/en/stored-aggregate-functions/','','https://mariadb.com/kb/en/stored-aggregate-functions/'); +insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (171,16,'AVG','Syntax\n------\n\nAVG([DISTINCT] expr)\n\nDescription\n-----------\n\nReturns the average value of expr. The DISTINCT option can be used to return\nthe average of the distinct values of expr. NULL values are ignored. It is an\naggregate function, and so can be used with the GROUP BY clause.\n\nAVG() returns NULL if there were no matching rows.\n\nAVG() can be used as a window function.\n\nExamples\n--------\n\nCREATE TABLE sales (sales_value INT);\n\nINSERT INTO sales VALUES(10),(20),(20),(40);\n\nSELECT AVG(sales_value) FROM sales;\n+------------------+\n| AVG(sales_value) |\n+------------------+\n| 22.5000 |\n+------------------+\n\nSELECT AVG(DISTINCT(sales_value)) FROM sales;\n+----------------------------+\n| AVG(DISTINCT(sales_value)) |\n+----------------------------+\n| 23.3333 |\n+----------------------------+\n\nCommonly, AVG() is used with a GROUP BY clause:\n\nCREATE TABLE student (name CHAR(10), test CHAR(10), score TINYINT);\n\nINSERT INTO student VALUES \n (\'Chun\', \'SQL\', 75), (\'Chun\', \'Tuning\', 73),\n (\'Esben\', \'SQL\', 43), (\'Esben\', \'Tuning\', 31),\n (\'Kaolin\', \'SQL\', 56), (\'Kaolin\', \'Tuning\', 88),\n (\'Tatiana\', \'SQL\', 87), (\'Tatiana\', \'Tuning\', 83);\n\nSELECT name, AVG(score) FROM student GROUP BY name;\n+---------+------------+\n| name | AVG(score) |\n+---------+------------+\n| Chun | 74.0000 |\n| Esben | 37.0000 |\n| Kaolin | 72.0000 |\n| Tatiana | 85.0000 |\n+---------+------------+\n\nBe careful to avoid this common mistake, not grouping correctly and returning\nmismatched data:\n\nSELECT name,test,AVG(score) FROM student;\n+------+------+------------+\n| name | test | MIN(score) |\n+------+------+------------+\n| Chun | SQL | 31 |\n+------+------+------------+\n\nAs a window function:\n\nCREATE TABLE student_test (name CHAR(10), test CHAR(10), score TINYINT);\n\nINSERT INTO student_test VALUES \n (\'Chun\', \'SQL\', 75), (\'Chun\', \'Tuning\', 73),\n (\'Esben\', \'SQL\', 43), (\'Esben\', \'Tuning\', 31),\n (\'Kaolin\', \'SQL\', 56), (\'Kaolin\', \'Tuning\', 88),\n (\'Tatiana\', \'SQL\', 87), (\'Tatiana\', \'Tuning\', 83);\n\nSELECT name, test, score, AVG(score) OVER (PARTITION BY test) \n AS average_by_test FROM student_test;\n+---------+--------+-------+-----------------+\n| name | test | score | average_by_test |\n+---------+--------+-------+-----------------+\n| Chun | SQL | 75 | 65.2500 |\n| Chun | Tuning | 73 | 68.7500 |\n| Esben | SQL | 43 | 65.2500 |\n| Esben | Tuning | 31 | 68.7500 |\n| Kaolin | SQL | 56 | 65.2500 |\n| Kaolin | Tuning | 88 | 68.7500 |\n| Tatiana | SQL | 87 | 65.2500 |\n| Tatiana | Tuning | 83 | 68.7500 |\n+---------+--------+-------+-----------------+\n\nURL: https://mariadb.com/kb/en/avg/','','https://mariadb.com/kb/en/avg/'); +insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (172,16,'BIT_AND','Syntax\n------\n\nBIT_AND(expr) [over_clause]\n\nDescription\n-----------\n\nReturns the bitwise AND of all bits in expr. The calculation is performed with\n64-bit (BIGINT) precision. It is an aggregate function, and so can be used\nwith the GROUP BY clause.\n\nIf no rows match, BIT_AND will return a value with all bits set to 1. NULL\nvalues have no effect on the result unless all results are NULL, which is\ntreated as no match.\n\nBIT_AND can be used as a window function with the addition of the over_clause.\n\nExamples\n--------\n\nCREATE TABLE vals (x INT);\n\nINSERT INTO vals VALUES(111),(110),(100);\n\nSELECT BIT_AND(x), BIT_OR(x), BIT_XOR(x) FROM vals;\n+------------+-----------+------------+\n| BIT_AND(x) | BIT_OR(x) | BIT_XOR(x) |\n+------------+-----------+------------+\n| 100 | 111 | 101 |\n+------------+-----------+------------+\n\nAs an aggregate function:\n\nCREATE TABLE vals2 (category VARCHAR(1), x INT);\n\nINSERT INTO vals2 VALUES\n (\'a\',111),(\'a\',110),(\'a\',100),\n (\'b\',\'000\'),(\'b\',001),(\'b\',011);\n\nSELECT category, BIT_AND(x), BIT_OR(x), BIT_XOR(x) \n FROM vals GROUP BY category;\n+----------+------------+-----------+------------+\n| category | BIT_AND(x) | BIT_OR(x) | BIT_XOR(x) |\n+----------+------------+-----------+------------+\n| a | 100 | 111 | 101 |\n| b | 0 | 11 | 10 |\n+----------+------------+-----------+------------+\n\nNo match:\n\nSELECT BIT_AND(NULL);\n+----------------------+\n| BIT_AND(NULL) |\n+----------------------+\n| 18446744073709551615 |\n+----------------------+\n\nURL: https://mariadb.com/kb/en/bit_and/','','https://mariadb.com/kb/en/bit_and/'); +insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (173,16,'BIT_OR','Syntax\n------\n\nBIT_OR(expr) [over_clause]\n\nDescription\n-----------\n\nReturns the bitwise OR of all bits in expr. The calculation is performed with\n64-bit (BIGINT) precision. It is an aggregate function, and so can be used\nwith the GROUP BY clause.\n\nIf no rows match, BIT_OR will return a value with all bits set to 0. NULL\nvalues have no effect on the result unless all results are NULL, which is\ntreated as no match.\n\nBIT_OR can be used as a window function with the addition of the over_clause.\n\nExamples\n--------\n\nCREATE TABLE vals (x INT);\n\nINSERT INTO vals VALUES(111),(110),(100);\n\nSELECT BIT_AND(x), BIT_OR(x), BIT_XOR(x) FROM vals;\n+------------+-----------+------------+\n| BIT_AND(x) | BIT_OR(x) | BIT_XOR(x) |\n+------------+-----------+------------+\n| 100 | 111 | 101 |\n+------------+-----------+------------+\n\nAs an aggregate function:\n\nCREATE TABLE vals2 (category VARCHAR(1), x INT);\n\nINSERT INTO vals2 VALUES\n (\'a\',111),(\'a\',110),(\'a\',100),\n (\'b\',\'000\'),(\'b\',001),(\'b\',011);\n\nSELECT category, BIT_AND(x), BIT_OR(x), BIT_XOR(x) \n FROM vals GROUP BY category;\n+----------+------------+-----------+------------+\n| category | BIT_AND(x) | BIT_OR(x) | BIT_XOR(x) |\n+----------+------------+-----------+------------+\n| a | 100 | 111 | 101 |\n| b | 0 | 11 | 10 |\n+----------+------------+-----------+------------+\n\nNo match:\n\nSELECT BIT_OR(NULL);\n+--------------+\n| BIT_OR(NULL) |\n+--------------+\n| 0 |\n+--------------+\n\nURL: https://mariadb.com/kb/en/bit_or/','','https://mariadb.com/kb/en/bit_or/'); +insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (174,16,'BIT_XOR','Syntax\n------\n\nBIT_XOR(expr) [over_clause]\n\nDescription\n-----------\n\nReturns the bitwise XOR of all bits in expr. The calculation is performed with\n64-bit (BIGINT) precision. It is an aggregate function, and so can be used\nwith the GROUP BY clause.\n\nIf no rows match, BIT_XOR will return a value with all bits set to 0. NULL\nvalues have no effect on the result unless all results are NULL, which is\ntreated as no match.\n\nBIT_XOR can be used as a window function with the addition of the over_clause.\n\nExamples\n--------\n\nCREATE TABLE vals (x INT);\n\nINSERT INTO vals VALUES(111),(110),(100);\n\nSELECT BIT_AND(x), BIT_OR(x), BIT_XOR(x) FROM vals;\n+------------+-----------+------------+\n| BIT_AND(x) | BIT_OR(x) | BIT_XOR(x) |\n+------------+-----------+------------+\n| 100 | 111 | 101 |\n+------------+-----------+------------+\n\nAs an aggregate function:\n\nCREATE TABLE vals2 (category VARCHAR(1), x INT);\n\nINSERT INTO vals2 VALUES\n (\'a\',111),(\'a\',110),(\'a\',100),\n (\'b\',\'000\'),(\'b\',001),(\'b\',011);\n\nSELECT category, BIT_AND(x), BIT_OR(x), BIT_XOR(x) \n FROM vals GROUP BY category;\n+----------+------------+-----------+------------+\n| category | BIT_AND(x) | BIT_OR(x) | BIT_XOR(x) |\n+----------+------------+-----------+------------+\n| a | 100 | 111 | 101 |\n| b | 0 | 11 | 10 |\n+----------+------------+-----------+------------+\n\nNo match:\n\nSELECT BIT_XOR(NULL);\n+---------------+\n| BIT_XOR(NULL) |\n+---------------+\n| 0 |\n+---------------+\n\nURL: https://mariadb.com/kb/en/bit_xor/','','https://mariadb.com/kb/en/bit_xor/'); +insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (175,16,'COUNT','Syntax\n------\n\nCOUNT(expr)\n\nDescription\n-----------\n\nReturns a count of the number of non-NULL values of expr in the rows retrieved\nby a SELECT statement. The result is a BIGINT value. It is an aggregate\nfunction, and so can be used with the GROUP BY clause.\n\nCOUNT(*) counts the total number of rows in a table.\n\nCOUNT() returns 0 if there were no matching rows.\n\nCOUNT() can be used as a window function.\n\nExamples\n--------\n\nCREATE TABLE student (name CHAR(10), test CHAR(10), score TINYINT);\n\nINSERT INTO student VALUES \n (\'Chun\', \'SQL\', 75), (\'Chun\', \'Tuning\', 73),\n (\'Esben\', \'SQL\', 43), (\'Esben\', \'Tuning\', 31),\n (\'Kaolin\', \'SQL\', 56), (\'Kaolin\', \'Tuning\', 88),\n (\'Tatiana\', \'SQL\', 87), (\'Tatiana\', \'Tuning\', 83);\n\nSELECT COUNT(*) FROM student;\n+----------+\n| COUNT(*) |\n+----------+\n| 8 |\n+----------+\n\nCOUNT(DISTINCT) example:\n\nSELECT COUNT(DISTINCT (name)) FROM student;\n+------------------------+\n| COUNT(DISTINCT (name)) |\n+------------------------+\n| 4 |\n+------------------------+\n\nAs a window function\n\nCREATE OR REPLACE TABLE student_test (name CHAR(10), test CHAR(10), score\nTINYINT);\n\nINSERT INTO student_test VALUES \n (\'Chun\', \'SQL\', 75), (\'Chun\', \'Tuning\', 73),\n (\'Esben\', \'SQL\', 43), (\'Esben\', \'Tuning\', 31),\n (\'Kaolin\', \'SQL\', 56), (\'Kaolin\', \'Tuning\', 88),\n (\'Tatiana\', \'SQL\', 87);\n\nSELECT name, test, score, COUNT(score) OVER (PARTITION BY name) \n AS tests_written FROM student_test;\n+---------+--------+-------+---------------+\n| name | test | score | tests_written |\n+---------+--------+-------+---------------+\n| Chun | SQL | 75 | 2 |\n| Chun | Tuning | 73 | 2 |\n| Esben | SQL | 43 | 2 |\n| Esben | Tuning | 31 | 2 |\n| Kaolin | SQL | 56 | 2 |\n| Kaolin | Tuning | 88 | 2 |\n| Tatiana | SQL | 87 | 1 |\n+---------+--------+-------+---------------+\n\nURL: https://mariadb.com/kb/en/count/','','https://mariadb.com/kb/en/count/'); +insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (176,16,'COUNT DISTINCT','Syntax\n------\n\nCOUNT(DISTINCT expr,[expr...])\n\nDescription\n-----------\n\nReturns a count of the number of different non-NULL values.\n\nCOUNT(DISTINCT) returns 0 if there were no matching rows.\n\nAlthough, from MariaDB 10.2.0, COUNT can be used as a window function, COUNT\nDISTINCT cannot be.\n\nExamples\n--------\n\nCREATE TABLE student (name CHAR(10), test CHAR(10), score TINYINT);\n\nINSERT INTO student VALUES \n (\'Chun\', \'SQL\', 75), (\'Chun\', \'Tuning\', 73),\n (\'Esben\', \'SQL\', 43), (\'Esben\', \'Tuning\', 31),\n (\'Kaolin\', \'SQL\', 56), (\'Kaolin\', \'Tuning\', 88),\n (\'Tatiana\', \'SQL\', 87), (\'Tatiana\', \'Tuning\', 83);\n\nSELECT COUNT(*) FROM student;\n+----------+\n| COUNT(*) |\n+----------+\n| 8 |\n+----------+\n\nSELECT COUNT(DISTINCT (name)) FROM student;\n+------------------------+\n| COUNT(DISTINCT (name)) |\n+------------------------+\n| 4 |\n+------------------------+\n\nURL: https://mariadb.com/kb/en/count-distinct/','','https://mariadb.com/kb/en/count-distinct/'); +insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (177,16,'GROUP_CONCAT','Syntax\n------\n\nGROUP_CONCAT(expr)\n\nDescription\n-----------\n\nThis function returns a string result with the concatenated non-NULL values\nfrom a group. It returns NULL if there are no non-NULL values.\n\nThe maximum returned length in bytes is determined by the group_concat_max_len\nserver system variable, which defaults to 1M (>= MariaDB 10.2.4) or 1K (<=\nMariaDB 10.2.3).\n\nIf group_concat_max_len <= 512, the return type is VARBINARY or VARCHAR;\notherwise, the return type is BLOB or TEXT. The choice between binary or\nnon-binary types depends from the input.\n\nThe full syntax is as follows:\n\nGROUP_CONCAT([DISTINCT] expr [,expr ...]\n [ORDER BY {unsigned_integer | col_name | expr}\n [ASC | DESC] [,col_name ...]]\n [SEPARATOR str_val]\n [LIMIT {[offset,] row_count | row_count OFFSET offset}])\n\nDISTINCT eliminates duplicate values from the output string.\n\nORDER BY determines the order of returned values.\n\nSEPARATOR specifies a separator between the values. The default separator is a\ncomma (,). It is possible to avoid using a separator by specifying an empty\nstring.\n\nLIMIT\n-----\n\nMariaDB starting with 10.3.3\n----------------------------\nUntil MariaDB 10.3.2, it was not possible to use the LIMIT clause with\nGROUP_CONCAT. This restriction was lifted in MariaDB 10.3.3.\n\nExamples\n--------\n\nSELECT student_name,\n GROUP_CONCAT(test_score)\n FROM student\n GROUP BY student_name;\n\nGet a readable list of MariaDB users from the mysql.user table:\n\nSELECT GROUP_CONCAT(DISTINCT User ORDER BY User SEPARATOR \'\\n\')\n FROM mysql.user;\n\nIn the former example, DISTINCT is used because the same user may occur more\nthan once. The new line (\\n) used as a SEPARATOR makes the results easier to\nread.\n\nGet a readable list of hosts from which each user can connect:\n\nSELECT User, GROUP_CONCAT(Host ORDER BY Host SEPARATOR \', \') \n FROM mysql.user GROUP BY User ORDER BY User;\n\nThe former example shows the difference between the GROUP_CONCAT\'s ORDER BY\n(which sorts the concatenated hosts), and the SELECT\'s ORDER BY (which sorts\nthe rows).\n\nFrom MariaDB 10.3.3, LIMIT can be used with GROUP_CONCAT, so, for example,\ngiven the following table:\n\nCREATE TABLE d (dd DATE, cc INT);\n\nINSERT INTO d VALUES (\'2017-01-01\',1);\nINSERT INTO d VALUES (\'2017-01-02\',2);\nINSERT INTO d VALUES (\'2017-01-04\',3);\n\nthe following query:\n\nSELECT SUBSTRING_INDEX(GROUP_CONCAT(CONCAT_WS(\":\",dd,cc) ORDER BY cc\nDESC),\",\",1) FROM d;\n+----------------------------------------------------------------------------+\n| SUBSTRING_INDEX(GROUP_CONCAT(CONCAT_WS(\":\",dd,cc) ORDER BY cc DESC),\",\",1) |\n+----------------------------------------------------------------------------+\n| 2017-01-04:3 |\n+----------------------------------------------------------------------------+\n\ncan be more simply rewritten as:\n\nSELECT GROUP_CONCAT(CONCAT_WS(\":\",dd,cc) ORDER BY cc DESC LIMIT 1) FROM d;\n+-------------------------------------------------------------+\n| GROUP_CONCAT(CONCAT_WS(\":\",dd,cc) ORDER BY cc DESC LIMIT 1) |\n+-------------------------------------------------------------+\n| 2017-01-04:3 |\n+-------------------------------------------------------------+\n\nURL: https://mariadb.com/kb/en/group_concat/','','https://mariadb.com/kb/en/group_concat/'); +insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (178,16,'MAX','Syntax\n------\n\nMAX([DISTINCT] expr)\n\nDescription\n-----------\n\nReturns the largest, or maximum, value of expr. MAX() can also take a string\nargument in which case it returns the maximum string value. The DISTINCT\nkeyword can be used to find the maximum of the distinct values of expr,\nhowever, this produces the same result as omitting DISTINCT.\n\nNote that SET and ENUM fields are currently compared by their string value\nrather than their relative position in the set, so MAX() may produce a\ndifferent highest result than ORDER BY DESC.\n\nIt is an aggregate function, and so can be used with the GROUP BY clause.\n\nMAX() can be used as a window function.\n\nMAX() returns NULL if there were no matching rows.\n\nExamples\n--------\n\nCREATE TABLE student (name CHAR(10), test CHAR(10), score TINYINT);\n\nINSERT INTO student VALUES \n (\'Chun\', \'SQL\', 75), (\'Chun\', \'Tuning\', 73),\n (\'Esben\', \'SQL\', 43), (\'Esben\', \'Tuning\', 31),\n (\'Kaolin\', \'SQL\', 56), (\'Kaolin\', \'Tuning\', 88),\n (\'Tatiana\', \'SQL\', 87), (\'Tatiana\', \'Tuning\', 83);\n\nSELECT name, MAX(score) FROM student GROUP BY name;\n+---------+------------+\n| name | MAX(score) |\n+---------+------------+\n| Chun | 75 |\n| Esben | 43 |\n| Kaolin | 88 |\n| Tatiana | 87 |\n+---------+------------+\n\nMAX string:\n\nSELECT MAX(name) FROM student;\n+-----------+\n| MAX(name) |\n+-----------+\n| Tatiana |\n+-----------+\n\nBe careful to avoid this common mistake, not grouping correctly and returning\nmismatched data:\n\nSELECT name,test,MAX(SCORE) FROM student;\n+------+------+------------+\n| name | test | MAX(SCORE) |\n+------+------+------------+\n| Chun | SQL | 88 |\n+------+------+------------+\n\nDifference between ORDER BY DESC and MAX():\n\nCREATE TABLE student2(name CHAR(10),grade ENUM(\'b\',\'c\',\'a\'));\n\nINSERT INTO student2 VALUES(\'Chun\',\'b\'),(\'Esben\',\'c\'),(\'Kaolin\',\'a\');\n\nSELECT MAX(grade) FROM student2;\n+------------+\n| MAX(grade) |\n+------------+\n| c |\n+------------+\n\nSELECT grade FROM student2 ORDER BY grade DESC LIMIT 1;\n+-------+\n| grade |\n+-------+\n| a |\n+-------+\n\nAs a window function:\n\nCREATE OR REPLACE TABLE student_test (name CHAR(10), test CHAR(10), score\nTINYINT);\nINSERT INTO student_test VALUES \n (\'Chun\', \'SQL\', 75), (\'Chun\', \'Tuning\', 73),\n (\'Esben\', \'SQL\', 43), (\'Esben\', \'Tuning\', 31),\n (\'Kaolin\', \'SQL\', 56), (\'Kaolin\', \'Tuning\', 88),\n (\'Tatiana\', \'SQL\', 87);\n\nSELECT name, test, score, MAX(score) \n OVER (PARTITION BY name) AS highest_score FROM student_test;\n+---------+--------+-------+---------------+\n| name | test | score | highest_score |\n+---------+--------+-------+---------------+\n| Chun | SQL | 75 | 75 |\n| Chun | Tuning | 73 | 75 |\n| Esben | SQL | 43 | 43 |\n| Esben | Tuning | 31 | 43 |\n| Kaolin | SQL | 56 | 88 |\n| Kaolin | Tuning | 88 | 88 |\n| Tatiana | SQL | 87 | 87 |\n+---------+--------+-------+---------------+\n\nURL: https://mariadb.com/kb/en/max/','','https://mariadb.com/kb/en/max/'); +insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (179,16,'MIN','Syntax\n------\n\nMIN([DISTINCT] expr)\n\nDescription\n-----------\n\nReturns the minimum value of expr. MIN() may take a string argument, in which\ncase it returns the minimum string value. The DISTINCT keyword can be used to\nfind the minimum of the distinct values of expr, however, this produces the\nsame result as omitting DISTINCT.\n\nNote that SET and ENUM fields are currently compared by their string value\nrather than their relative position in the set, so MIN() may produce a\ndifferent lowest result than ORDER BY ASC.\n\nIt is an aggregate function, and so can be used with the GROUP BY clause.\n\nMIN() can be used as a window function.\n\nMIN() returns NULL if there were no matching rows.\n\nExamples\n--------\n\nCREATE TABLE student (name CHAR(10), test CHAR(10), score TINYINT);\n\nINSERT INTO student VALUES \n (\'Chun\', \'SQL\', 75), (\'Chun\', \'Tuning\', 73),\n (\'Esben\', \'SQL\', 43), (\'Esben\', \'Tuning\', 31),\n (\'Kaolin\', \'SQL\', 56), (\'Kaolin\', \'Tuning\', 88),\n (\'Tatiana\', \'SQL\', 87), (\'Tatiana\', \'Tuning\', 83);\n\nSELECT name, MIN(score) FROM student GROUP BY name;\n+---------+------------+\n| name | MIN(score) |\n+---------+------------+\n| Chun | 73 |\n| Esben | 31 |\n| Kaolin | 56 |\n| Tatiana | 83 |\n+---------+------------+\n\nMIN() with a string:\n\nSELECT MIN(name) FROM student;\n+-----------+\n| MIN(name) |\n+-----------+\n| Chun |\n+-----------+\n\nBe careful to avoid this common mistake, not grouping correctly and returning\nmismatched data:\n\nSELECT name,test,MIN(score) FROM student;\n+------+------+------------+\n| name | test | MIN(score) |\n+------+------+------------+\n| Chun | SQL | 31 |\n+------+------+------------+\n\nDifference between ORDER BY ASC and MIN():\n\nCREATE TABLE student2(name CHAR(10),grade ENUM(\'b\',\'c\',\'a\'));\n\nINSERT INTO student2 VALUES(\'Chun\',\'b\'),(\'Esben\',\'c\'),(\'Kaolin\',\'a\');\n\nSELECT MIN(grade) FROM student2;\n+------------+\n| MIN(grade) |\n+------------+\n| a |\n+------------+\n\nSELECT grade FROM student2 ORDER BY grade ASC LIMIT 1;\n+-------+\n| grade |\n+-------+\n| b |\n+-------+\n\nAs a window function:\n\nCREATE OR REPLACE TABLE student_test (name CHAR(10), test CHAR(10), score\nTINYINT);\nINSERT INTO student_test VALUES \n (\'Chun\', \'SQL\', 75), (\'Chun\', \'Tuning\', 73),\n (\'Esben\', \'SQL\', 43), (\'Esben\', \'Tuning\', 31),\n (\'Kaolin\', \'SQL\', 56), (\'Kaolin\', \'Tuning\', 88),\n (\'Tatiana\', \'SQL\', 87);\n\nSELECT name, test, score, MIN(score) \n OVER (PARTITION BY name) AS lowest_score FROM student_test;\n+---------+--------+-------+--------------+\n| name | test | score | lowest_score |\n+---------+--------+-------+--------------+\n| Chun | SQL | 75 | 73 |\n| Chun | Tuning | 73 | 73 |\n| Esben | SQL | 43 | 31 |\n| Esben | Tuning | 31 | 31 |\n| Kaolin | SQL | 56 | 56 |\n| Kaolin | Tuning | 88 | 56 |\n| Tatiana | SQL | 87 | 87 |\n+---------+--------+-------+--------------+\n\nURL: https://mariadb.com/kb/en/min/','','https://mariadb.com/kb/en/min/'); +insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (180,16,'STD','Syntax\n------\n\nSTD(expr)\n\nDescription\n-----------\n\nReturns the population standard deviation of expr. This is an extension to\nstandard SQL. The standard SQL function STDDEV_POP() can be used instead.\n\nIt is an aggregate function, and so can be used with the GROUP BY clause.\n\nSTD() can be used as a window function.\n\nThis function returns NULL if there were no matching rows.\n\nExamples\n--------\n\nAs an aggregate function:\n\nCREATE OR REPLACE TABLE stats (category VARCHAR(2), x INT);\n\nINSERT INTO stats VALUES \n (\'a\',1),(\'a\',2),(\'a\',3),\n (\'b\',11),(\'b\',12),(\'b\',20),(\'b\',30),(\'b\',60);\n\nSELECT category, STDDEV_POP(x), STDDEV_SAMP(x), VAR_POP(x) \n FROM stats GROUP BY category;\n+----------+---------------+----------------+------------+\n| category | STDDEV_POP(x) | STDDEV_SAMP(x) | VAR_POP(x) |\n+----------+---------------+----------------+------------+\n| a | 0.8165 | 1.0000 | 0.6667 |\n| b | 18.0400 | 20.1693 | 325.4400 |\n+----------+---------------+----------------+------------+\n\nAs a window function:\n\nCREATE OR REPLACE TABLE student_test (name CHAR(10), test CHAR(10), score\nTINYINT);\n\nINSERT INTO student_test VALUES \n (\'Chun\', \'SQL\', 75), (\'Chun\', \'Tuning\', 73),\n (\'Esben\', \'SQL\', 43), (\'Esben\', \'Tuning\', 31),\n (\'Kaolin\', \'SQL\', 56), (\'Kaolin\', \'Tuning\', 88),\n (\'Tatiana\', \'SQL\', 87);\n\nSELECT name, test, score, STDDEV_POP(score) \n OVER (PARTITION BY test) AS stddev_results FROM student_test;\n+---------+--------+-------+----------------+\n| name | test | score | stddev_results |\n+---------+--------+-------+----------------+\n| Chun | SQL | 75 | 16.9466 |\n| Chun | Tuning | 73 | 24.1247 |\n| Esben | SQL | 43 | 16.9466 |\n| Esben | Tuning | 31 | 24.1247 |\n| Kaolin | SQL | 56 | 16.9466 |\n| Kaolin | Tuning | 88 | 24.1247 |\n| Tatiana | SQL | 87 | 16.9466 |\n+---------+--------+-------+----------------+\n\nURL: https://mariadb.com/kb/en/std/','','https://mariadb.com/kb/en/std/'); +insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (181,16,'STDDEV','Syntax\n------\n\nSTDDEV(expr)\n\nDescription\n-----------\n\nReturns the population standard deviation of expr. This function is provided\nfor compatibility with Oracle. The standard SQL function STDDEV_POP() can be\nused instead.\n\nIt is an aggregate function, and so can be used with the GROUP BY clause.\n\nSTDDEV() can be used as a window function.\n\nThis function returns NULL if there were no matching rows.\n\nExamples\n--------\n\nAs an aggregate function:\n\nCREATE OR REPLACE TABLE stats (category VARCHAR(2), x INT);\n\nINSERT INTO stats VALUES \n (\'a\',1),(\'a\',2),(\'a\',3),\n (\'b\',11),(\'b\',12),(\'b\',20),(\'b\',30),(\'b\',60);\n\nSELECT category, STDDEV_POP(x), STDDEV_SAMP(x), VAR_POP(x) \n FROM stats GROUP BY category;\n+----------+---------------+----------------+------------+\n| category | STDDEV_POP(x) | STDDEV_SAMP(x) | VAR_POP(x) |\n+----------+---------------+----------------+------------+\n| a | 0.8165 | 1.0000 | 0.6667 |\n| b | 18.0400 | 20.1693 | 325.4400 |\n+----------+---------------+----------------+------------+\n\nAs a window function:\n\nCREATE OR REPLACE TABLE student_test (name CHAR(10), test CHAR(10), score\nTINYINT);\n\nINSERT INTO student_test VALUES \n (\'Chun\', \'SQL\', 75), (\'Chun\', \'Tuning\', 73),\n (\'Esben\', \'SQL\', 43), (\'Esben\', \'Tuning\', 31),\n (\'Kaolin\', \'SQL\', 56), (\'Kaolin\', \'Tuning\', 88),\n (\'Tatiana\', \'SQL\', 87);\n\nSELECT name, test, score, STDDEV_POP(score) \n OVER (PARTITION BY test) AS stddev_results FROM student_test;\n+---------+--------+-------+----------------+\n| name | test | score | stddev_results |\n+---------+--------+-------+----------------+\n| Chun | SQL | 75 | 16.9466 |\n| Chun | Tuning | 73 | 24.1247 |\n| Esben | SQL | 43 | 16.9466 |\n| Esben | Tuning | 31 | 24.1247 |\n| Kaolin | SQL | 56 | 16.9466 |\n| Kaolin | Tuning | 88 | 24.1247 |\n| Tatiana | SQL | 87 | 16.9466 |\n+---------+--------+-------+----------------+\n\nURL: https://mariadb.com/kb/en/stddev/','','https://mariadb.com/kb/en/stddev/'); +insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (182,16,'STDDEV_POP','Syntax\n------\n\nSTDDEV_POP(expr)\n\nDescription\n-----------\n\nReturns the population standard deviation of expr (the square root of\nVAR_POP()). You can also use STD() or STDDEV(), which are equivalent but not\nstandard SQL.\n\nIt is an aggregate function, and so can be used with the GROUP BY clause.\n\nSTDDEV_POP() can be used as a window function.\n\nSTDDEV_POP() returns NULL if there were no matching rows.\n\nExamples\n--------\n\nAs an aggregate function:\n\nCREATE OR REPLACE TABLE stats (category VARCHAR(2), x INT);\n\nINSERT INTO stats VALUES \n (\'a\',1),(\'a\',2),(\'a\',3),\n (\'b\',11),(\'b\',12),(\'b\',20),(\'b\',30),(\'b\',60);\n\nSELECT category, STDDEV_POP(x), STDDEV_SAMP(x), VAR_POP(x) \n FROM stats GROUP BY category;\n+----------+---------------+----------------+------------+\n| category | STDDEV_POP(x) | STDDEV_SAMP(x) | VAR_POP(x) |\n+----------+---------------+----------------+------------+\n| a | 0.8165 | 1.0000 | 0.6667 |\n| b | 18.0400 | 20.1693 | 325.4400 |\n+----------+---------------+----------------+------------+\n\nAs a window function:\n\nCREATE OR REPLACE TABLE student_test (name CHAR(10), test CHAR(10), score\nTINYINT);\n\nINSERT INTO student_test VALUES \n (\'Chun\', \'SQL\', 75), (\'Chun\', \'Tuning\', 73),\n (\'Esben\', \'SQL\', 43), (\'Esben\', \'Tuning\', 31),\n (\'Kaolin\', \'SQL\', 56), (\'Kaolin\', \'Tuning\', 88),\n (\'Tatiana\', \'SQL\', 87);\n\nSELECT name, test, score, STDDEV_POP(score) \n OVER (PARTITION BY test) AS stddev_results FROM student_test;\n+---------+--------+-------+----------------+\n| name | test | score | stddev_results |\n+---------+--------+-------+----------------+\n| Chun | SQL | 75 | 16.9466 |\n| Chun | Tuning | 73 | 24.1247 |\n| Esben | SQL | 43 | 16.9466 |\n| Esben | Tuning | 31 | 24.1247 |\n| Kaolin | SQL | 56 | 16.9466 |\n| Kaolin | Tuning | 88 | 24.1247 |\n| Tatiana | SQL | 87 | 16.9466 |\n+---------+--------+-------+----------------+\n\nURL: https://mariadb.com/kb/en/stddev_pop/','','https://mariadb.com/kb/en/stddev_pop/'); +insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (183,16,'STDDEV_SAMP','Syntax\n------\n\nSTDDEV_SAMP(expr)\n\nDescription\n-----------\n\nReturns the sample standard deviation of expr (the square root of VAR_SAMP()).\n\nIt is an aggregate function, and so can be used with the GROUP BY clause.\n\nSTDDEV_SAMP() can be used as a window function.\n\nSTDDEV_SAMP() returns NULL if there were no matching rows.\n\nURL: https://mariadb.com/kb/en/stddev_samp/','','https://mariadb.com/kb/en/stddev_samp/'); +insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (184,16,'SUM','Syntax\n------\n\nSUM([DISTINCT] expr)\n\nDescription\n-----------\n\nReturns the sum of expr. If the return set has no rows, SUM() returns NULL.\nThe DISTINCT keyword can be used to sum only the distinct values of expr.\n\nSUM() can be used as a window function, although not with the DISTINCT\nspecifier.\n\nExamples\n--------\n\nCREATE TABLE sales (sales_value INT);\nINSERT INTO sales VALUES(10),(20),(20),(40);\n\nSELECT SUM(sales_value) FROM sales;\n+------------------+\n| SUM(sales_value) |\n+------------------+\n| 90 |\n+------------------+\n\nSELECT SUM(DISTINCT(sales_value)) FROM sales;\n+----------------------------+\n| SUM(DISTINCT(sales_value)) |\n+----------------------------+\n| 70 |\n+----------------------------+\n\nCommonly, SUM is used with a GROUP BY clause:\n\nCREATE TABLE sales (name CHAR(10), month CHAR(10), units INT);\n\nINSERT INTO sales VALUES \n (\'Chun\', \'Jan\', 75), (\'Chun\', \'Feb\', 73),\n (\'Esben\', \'Jan\', 43), (\'Esben\', \'Feb\', 31),\n (\'Kaolin\', \'Jan\', 56), (\'Kaolin\', \'Feb\', 88),\n (\'Tatiana\', \'Jan\', 87), (\'Tatiana\', \'Feb\', 83);\n\nSELECT name, SUM(units) FROM sales GROUP BY name;\n+---------+------------+\n| name | SUM(units) |\n+---------+------------+\n| Chun | 148 |\n| Esben | 74 |\n| Kaolin | 144 |\n| Tatiana | 170 |\n+---------+------------+\n\nThe GROUP BY clause is required when using an aggregate function along with\nregular column data, otherwise the result will be a mismatch, as in the\nfollowing common type of mistake:\n\nSELECT name,SUM(units) FROM sales\n;+------+------------+\n| name | SUM(units) |\n+------+------------+\n| Chun | 536 |\n+------+------------+\n\nAs a window function:\n\nCREATE OR REPLACE TABLE student_test (name CHAR(10), test CHAR(10), score\nTINYINT);\nINSERT INTO student_test VALUES \n (\'Chun\', \'SQL\', 75), (\'Chun\', \'Tuning\', 73),\n (\'Esben\', \'SQL\', 43), (\'Esben\', \'Tuning\', 31),\n (\'Kaolin\', \'SQL\', 56), (\'Kaolin\', \'Tuning\', 88),\n (\'Tatiana\', \'SQL\', 87);\n\nSELECT name, test, score, SUM(score) OVER (PARTITION BY name) AS total_score\nFROM student_test;\n+---------+--------+-------+-------------+\n| name | test | score | total_score |\n+---------+--------+-------+-------------+\n| Chun | SQL | 75 | 148 |\n| Chun | Tuning | 73 | 148 |\n| Esben | SQL | 43 | 74 |\n| Esben | Tuning | 31 | 74 |\n| Kaolin | SQL | 56 | 144 |\n| Kaolin | Tuning | 88 | 144 |\n| Tatiana | SQL | 87 | 87 |\n+---------+--------+-------+-------------+\n\nURL: https://mariadb.com/kb/en/sum/','','https://mariadb.com/kb/en/sum/'); +insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (185,16,'VARIANCE','Syntax\n------\n\nVARIANCE(expr)\n\nDescription\n-----------\n\nReturns the population standard variance of expr. This is an extension to\nstandard SQL. The standard SQL function VAR_POP() can be used instead.\n\nVariance is calculated by\n\n* working out the mean for the set\n* for each number, subtracting the mean and squaring the result\n* calculate the average of the resulting differences\n\nIt is an aggregate function, and so can be used with the GROUP BY clause.\n\nVARIANCE() can be used as a window function.\n\nVARIANCE() returns NULL if there were no matching rows.\n\nExamples\n--------\n\nCREATE TABLE v(i tinyint);\n\nINSERT INTO v VALUES(101),(99);\n\nSELECT VARIANCE(i) FROM v;\n+-------------+\n| VARIANCE(i) |\n+-------------+\n| 1.0000 |\n+-------------+\n\nINSERT INTO v VALUES(120),(80);\n\nSELECT VARIANCE(i) FROM v;\n+-------------+\n| VARIANCE(i) |\n+-------------+\n| 200.5000 |\n+-------------+\n\nAs an aggregate function:\n\nCREATE OR REPLACE TABLE stats (category VARCHAR(2), x INT);\n\nINSERT INTO stats VALUES \n (\'a\',1),(\'a\',2),(\'a\',3),\n (\'b\',11),(\'b\',12),(\'b\',20),(\'b\',30),(\'b\',60);\n\nSELECT category, STDDEV_POP(x), STDDEV_SAMP(x), VAR_POP(x) \n FROM stats GROUP BY category;\n+----------+---------------+----------------+------------+\n| category | STDDEV_POP(x) | STDDEV_SAMP(x) | VAR_POP(x) |\n+----------+---------------+----------------+------------+\n| a | 0.8165 | 1.0000 | 0.6667 |\n| b | 18.0400 | 20.1693 | 325.4400 |\n+----------+---------------+----------------+------------+\n\nAs a window function:\n\nCREATE OR REPLACE TABLE student_test (name CHAR(10), test CHAR(10), score\nTINYINT);\n\nINSERT INTO student_test VALUES \n (\'Chun\', \'SQL\', 75), (\'Chun\', \'Tuning\', 73),\n (\'Esben\', \'SQL\', 43), (\'Esben\', \'Tuning\', 31),\n (\'Kaolin\', \'SQL\', 56), (\'Kaolin\', \'Tuning\', 88),\n (\'Tatiana\', \'SQL\', 87);\n\nSELECT name, test, score, VAR_POP(score) \n OVER (PARTITION BY test) AS variance_results FROM student_test;\n+---------+--------+-------+------------------+\n| name | test | score | variance_results |\n+---------+--------+-------+------------------+\n| Chun | SQL | 75 | 287.1875 |\n| Chun | Tuning | 73 | 582.0000 |\n| Esben | SQL | 43 | 287.1875 |\n| Esben | Tuning | 31 | 582.0000 |\n| Kaolin | SQL | 56 | 287.1875 |\n| Kaolin | Tuning | 88 | 582.0000 |\n| Tatiana | SQL | 87 | 287.1875 |\n+---------+--------+-------+------------------+\n\nURL: https://mariadb.com/kb/en/variance/','','https://mariadb.com/kb/en/variance/'); +insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (186,16,'VAR_POP','Syntax\n------\n\nVAR_POP(expr)\n\nDescription\n-----------\n\nReturns the population standard variance of expr. It considers rows as the\nwhole population, not as a sample, so it has the number of rows as the\ndenominator. You can also use VARIANCE(), which is equivalent but is not\nstandard SQL.\n\nVariance is calculated by\n\n* working out the mean for the set\n* for each number, subtracting the mean and squaring the result\n* calculate the average of the resulting differences\n\nIt is an aggregate function, and so can be used with the GROUP BY clause.\n\nVAR_POP() can be used as a window function.\n\nVAR_POP() returns NULL if there were no matching rows.\n\nExamples\n--------\n\nCREATE TABLE v(i tinyint);\n\nINSERT INTO v VALUES(101),(99);\n\nSELECT VAR_POP(i) FROM v;\n+------------+\n| VAR_POP(i) |\n+------------+\n| 1.0000 |\n+------------+\n\nINSERT INTO v VALUES(120),(80);\n\nSELECT VAR_POP(i) FROM v;\n+------------+\n| VAR_POP(i) |\n+------------+\n| 200.5000 |\n+------------+\n\nAs an aggregate function:\n\nCREATE OR REPLACE TABLE stats (category VARCHAR(2), x INT);\n\nINSERT INTO stats VALUES \n (\'a\',1),(\'a\',2),(\'a\',3),\n (\'b\',11),(\'b\',12),(\'b\',20),(\'b\',30),(\'b\',60);\n\nSELECT category, STDDEV_POP(x), STDDEV_SAMP(x), VAR_POP(x) \n FROM stats GROUP BY category;\n+----------+---------------+----------------+------------+\n| category | STDDEV_POP(x) | STDDEV_SAMP(x) | VAR_POP(x) |\n+----------+---------------+----------------+------------+\n| a | 0.8165 | 1.0000 | 0.6667 |\n| b | 18.0400 | 20.1693 | 325.4400 |\n+----------+---------------+----------------+------------+\n\nAs a window function:\n\nCREATE OR REPLACE TABLE student_test (name CHAR(10), test CHAR(10), score\nTINYINT);\n\nINSERT INTO student_test VALUES \n (\'Chun\', \'SQL\', 75), (\'Chun\', \'Tuning\', 73),\n (\'Esben\', \'SQL\', 43), (\'Esben\', \'Tuning\', 31),\n (\'Kaolin\', \'SQL\', 56), (\'Kaolin\', \'Tuning\', 88),\n (\'Tatiana\', \'SQL\', 87);\n\nSELECT name, test, score, VAR_POP(score) \n OVER (PARTITION BY test) AS variance_results FROM student_test;\n+---------+--------+-------+------------------+\n| name | test | score | variance_results |\n+---------+--------+-------+------------------+\n| Chun | SQL | 75 | 287.1875 |\n| Esben | SQL | 43 | 287.1875 |\n| Kaolin | SQL | 56 | 287.1875 |\n| Tatiana | SQL | 87 | 287.1875 |\n| Chun | Tuning | 73 | 582.0000 |\n| Esben | Tuning | 31 | 582.0000 |\n| Kaolin | Tuning | 88 | 582.0000 |\n+---------+--------+-------+------------------+\n\nURL: https://mariadb.com/kb/en/var_pop/','','https://mariadb.com/kb/en/var_pop/'); +insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (187,16,'VAR_SAMP','Syntax\n------\n\nVAR_SAMP(expr)\n\nDescription\n-----------\n\nReturns the sample variance of expr. That is, the denominator is the number of\nrows minus one.\n\nIt is an aggregate function, and so can be used with the GROUP BY clause.\n\nVAR_SAMP() can be used as a window function.\n\nVAR_SAMP() returns NULL if there were no matching rows.\n\nExamples\n--------\n\nAs an aggregate function:\n\nCREATE OR REPLACE TABLE stats (category VARCHAR(2), x INT);\n\nINSERT INTO stats VALUES \n (\'a\',1),(\'a\',2),(\'a\',3),\n (\'b\',11),(\'b\',12),(\'b\',20),(\'b\',30),(\'b\',60);\n\nSELECT category, STDDEV_POP(x), STDDEV_SAMP(x), VAR_POP(x) \n FROM stats GROUP BY category;\n+----------+---------------+----------------+------------+\n| category | STDDEV_POP(x) | STDDEV_SAMP(x) | VAR_POP(x) |\n+----------+---------------+----------------+------------+\n| a | 0.8165 | 1.0000 | 0.6667 |\n| b | 18.0400 | 20.1693 | 325.4400 |\n+----------+---------------+----------------+------------+\n\nAs a window function:\n\nCREATE OR REPLACE TABLE student_test (name CHAR(10), test CHAR(10), score\nTINYINT);\n\nINSERT INTO student_test VALUES \n (\'Chun\', \'SQL\', 75), (\'Chun\', \'Tuning\', 73),\n (\'Esben\', \'SQL\', 43), (\'Esben\', \'Tuning\', 31),\n (\'Kaolin\', \'SQL\', 56), (\'Kaolin\', \'Tuning\', 88),\n (\'Tatiana\', \'SQL\', 87);\n\nSELECT name, test, score, VAR_SAMP(score) \n OVER (PARTITION BY test) AS variance_results FROM student_test;\n+---------+--------+-------+------------------+\n| name | test | score | variance_results |\n+---------+--------+-------+------------------+\n| Chun | SQL | 75 | 382.9167 |\n| Chun | Tuning | 73 | 873.0000 |\n| Esben | SQL | 43 | 382.9167 |\n| Esben | Tuning | 31 | 873.0000 |\n| Kaolin | SQL | 56 | 382.9167 |\n| Kaolin | Tuning | 88 | 873.0000 |\n| Tatiana | SQL | 87 | 382.9167 |\n+---------+--------+-------+------------------+\n\nURL: https://mariadb.com/kb/en/var_samp/','','https://mariadb.com/kb/en/var_samp/'); +insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (188,17,'BENCHMARK','Syntax\n------\n\nBENCHMARK(count,expr)\n\nDescription\n-----------\n\nThe BENCHMARK() function executes the expression expr repeatedly count times.\nIt may be used to time how quickly MariaDB processes the expression. The\nresult value is always 0. The intended use is from within the mysql client,\nwhich reports query execution times.\n\nExamples\n--------\n\nSELECT BENCHMARK(1000000,ENCODE(\'hello\',\'goodbye\'));\n+----------------------------------------------+\n| BENCHMARK(1000000,ENCODE(\'hello\',\'goodbye\')) |\n+----------------------------------------------+\n| 0 |\n+----------------------------------------------+\n1 row in set (0.21 sec)\n\nURL: https://mariadb.com/kb/en/benchmark/','','https://mariadb.com/kb/en/benchmark/'); +insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (189,17,'BINLOG_GTID_POS','Syntax\n------\n\nBINLOG_GTID_POS(binlog_filename,binlog_offset)\n\nDescription\n-----------\n\nThe BINLOG_GTID_POS() function takes as input an old-style binary log position\nin the form of a file name and a file offset. It looks up the position in the\ncurrent binlog, and returns a string representation of the corresponding GTID\nposition. If the position is not found in the current binlog, NULL is returned.\n\nExamples\n--------\n\nSELECT BINLOG_GTID_POS(\"master-bin.000001\", 600);\n\nURL: https://mariadb.com/kb/en/binlog_gtid_pos/','','https://mariadb.com/kb/en/binlog_gtid_pos/'); +insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (190,17,'CHARSET','Syntax\n------\n\nCHARSET(str)\n\nDescription\n-----------\n\nReturns the character set of the string argument. If str is not a string, it\nis considered as a binary string (so the function returns \'binary\'). This\napplies to NULL, too. The return value is a string in the utf8 character set.\n\nExamples\n--------\n\nSELECT CHARSET(\'abc\');\n+----------------+\n| CHARSET(\'abc\') |\n+----------------+\n| latin1 |\n+----------------+\n\nSELECT CHARSET(CONVERT(\'abc\' USING utf8));\n+------------------------------------+\n| CHARSET(CONVERT(\'abc\' USING utf8)) |\n+------------------------------------+\n| utf8 |\n+------------------------------------+\n\nSELECT CHARSET(USER());\n+-----------------+\n| CHARSET(USER()) |\n+-----------------+\n| utf8 |\n+-----------------+\n\nURL: https://mariadb.com/kb/en/charset/','','https://mariadb.com/kb/en/charset/'); +insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (191,17,'COERCIBILITY','Syntax\n------\n\nCOERCIBILITY(str)\n\nDescription\n-----------\n\nReturns the collation coercibility value of the string argument. Coercibility\ndefines what will be converted to what in case of collation conflict, with an\nexpression with higher coercibility being converted to the collation of an\nexpression with lower coercibility.\n\n+-----------------------------+---------------------------+------------------+\n| Coercibility | Description | Example |\n+-----------------------------+---------------------------+------------------+\n| 0 | Explicit | Value using a |\n| | | COLLATE clause |\n+-----------------------------+---------------------------+------------------+\n| 1 | No collation | Concatenated |\n| | | strings using |\n| | | different |\n| | | collations |\n+-----------------------------+---------------------------+------------------+\n| 2 | Implicit | Column value |\n+-----------------------------+---------------------------+------------------+\n| 3 | Constant | USER() return |\n| | | value |\n+-----------------------------+---------------------------+------------------+\n| 4 | Coercible | Literal string |\n+-----------------------------+---------------------------+------------------+\n| 5 | Ignorable | NULL or derived |\n| | | from NULL |\n+-----------------------------+---------------------------+------------------+\n\nExamples\n--------\n\nSELECT COERCIBILITY(\'abc\' COLLATE latin1_swedish_ci);\n+-----------------------------------------------+\n| COERCIBILITY(\'abc\' COLLATE latin1_swedish_ci) |\n+-----------------------------------------------+\n| 0 |\n+-----------------------------------------------+\n\nSELECT COERCIBILITY(USER());\n+----------------------+\n| COERCIBILITY(USER()) |\n+----------------------+\n| 3 |\n+----------------------+\n\nSELECT COERCIBILITY(\'abc\');\n+---------------------+\n| COERCIBILITY(\'abc\') |\n+---------------------+\n| 4 |\n+---------------------+\n\nURL: https://mariadb.com/kb/en/coercibility/','','https://mariadb.com/kb/en/coercibility/'); +insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (192,17,'COLLATION','Syntax\n------\n\nCOLLATION(str)\n\nDescription\n-----------\n\nReturns the collation of the string argument. If str is not a string, it is\nconsidered as a binary string (so the function returns \'binary\'). This applies\nto NULL, too. The return value is a string in the utf8 character set.\n\nSee Character Sets and Collations.\n\nExamples\n--------\n\nSELECT COLLATION(\'abc\');\n+-------------------+\n| COLLATION(\'abc\') |\n+-------------------+\n| latin1_swedish_ci |\n+-------------------+\n\nSELECT COLLATION(_utf8\'abc\');\n+-----------------------+\n| COLLATION(_utf8\'abc\') |\n+-----------------------+\n| utf8_general_ci |\n+-----------------------+\n\nURL: https://mariadb.com/kb/en/collation/','','https://mariadb.com/kb/en/collation/'); +insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (193,17,'CONNECTION_ID','Syntax\n------\n\nCONNECTION_ID()\n\nDescription\n-----------\n\nReturns the connection ID for the connection. Every connection (including\nevents) has an ID that is unique among the set of currently connected clients.\n\nUntil MariaDB 10.3.1, returns MYSQL_TYPE_LONGLONG, or bigint(10), in all\ncases. From MariaDB 10.3.1, returns MYSQL_TYPE_LONG, or int(10), when the\nresult would fit within 32-bits.\n\nExamples\n--------\n\nSELECT CONNECTION_ID();\n+-----------------+\n| CONNECTION_ID() |\n+-----------------+\n| 3 |\n+-----------------+\n\nURL: https://mariadb.com/kb/en/connection_id/','','https://mariadb.com/kb/en/connection_id/'); +insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (194,17,'CURRENT_ROLE','Syntax\n------\n\nCURRENT_ROLE, CURRENT_ROLE()\n\nDescription\n-----------\n\nReturns the current role name. This determines your access privileges. The\nreturn value is a string in the utf8 character set.\n\nIf there is no current role, NULL is returned.\n\nThe output of SELECT CURRENT_ROLE is equivalent to the contents of the\nENABLED_ROLES Information Schema table.\n\nUSER() returns the combination of user and host used to login. CURRENT_USER()\nreturns the account used to determine current connection\'s privileges.\n\nExamples\n--------\n\nSELECT CURRENT_ROLE;\n+--------------+\n| CURRENT_ROLE |\n+--------------+\n| NULL |\n+--------------+\n\nSET ROLE staff;\n\nSELECT CURRENT_ROLE;\n+--------------+\n| CURRENT_ROLE |\n+--------------+\n| staff |\n+--------------+\n\nURL: https://mariadb.com/kb/en/current_role/','','https://mariadb.com/kb/en/current_role/'); +insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (195,17,'CURRENT_USER','Syntax\n------\n\nCURRENT_USER, CURRENT_USER()\n\nDescription\n-----------\n\nReturns the user name and host name combination for the MariaDB account that\nthe server used to authenticate the current client. This account determines\nyour access privileges. The return value is a string in the utf8 character set.\n\nThe value of CURRENT_USER() can differ from the value of USER().\nCURRENT_ROLE() returns the current active role.\n\nExamples\n--------\n\nshell> mysql --user=\"anonymous\"\n\nselect user(),current_user();\n+---------------------+----------------+\n| user() | current_user() |\n+---------------------+----------------+\n| anonymous@localhost | @localhost |\n+---------------------+----------------+\n\nWhen calling CURRENT_USER() in a stored procedure, it returns the owner of the\nstored procedure, as defined with DEFINER.\n\nURL: https://mariadb.com/kb/en/current_user/','','https://mariadb.com/kb/en/current_user/'); +insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (196,17,'DATABASE','Syntax\n------\n\nDATABASE()\n\nDescription\n-----------\n\nReturns the default (current) database name as a string in the utf8 character\nset. If there is no default database, DATABASE() returns NULL. Within a stored\nroutine, the default database is the database that the routine is associated\nwith, which is not necessarily the same as the database that is the default in\nthe calling context.\n\nSCHEMA() is a synonym for DATABASE().\n\nTo select a default database, the USE statement can be run. Another way to set\nthe default database is specifying its name at mysql command line client\nstartup.\n\nExamples\n--------\n\nSELECT DATABASE();\n+------------+\n| DATABASE() |\n+------------+\n| NULL |\n+------------+\n\nUSE test;\nDatabase changed\n\nSELECT DATABASE();\n+------------+\n| DATABASE() |\n+------------+\n| test |\n+------------+\n\nURL: https://mariadb.com/kb/en/database/','','https://mariadb.com/kb/en/database/'); +insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (197,17,'DECODE_HISTOGRAM','Syntax\n------\n\nDECODE_HISTOGRAM(hist_type,histogram)\n\nDescription\n-----------\n\nReturns a string of comma separated numeric values corresponding to a\nprobability distribution represented by the histogram of type hist_type\n(SINGLE_PREC_HB or DOUBLE_PREC_HB). The hist_type and histogram would be\ncommonly used from the mysql.column_stats table.\n\nSee Histogram Based Statistics for details.\n\nExamples\n--------\n\nCREATE TABLE origin (\n i INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY,\n v INT UNSIGNED NOT NULL\n);\n\nINSERT INTO origin(v) VALUES \n (1),(2),(3),(4),(5),(10),(20),\n (30),(40),(50),(60),(70),(80),\n (90),(100),(200),(400),(800);\n\nSET histogram_size=10,histogram_type=SINGLE_PREC_HB;\n\nANALYZE TABLE origin PERSISTENT FOR ALL;\n+-------------+---------+----------+-----------------------------------------+\n| Table | Op | Msg_type | Msg_text |\n+-------------+---------+----------+-----------------------------------------+\n| test.origin | analyze | status | Engine-independent statistics collected |\n| test.origin | analyze | status | OK |\n+-------------+---------+----------+-----------------------------------------+\n\nSELECT db_name,table_name,column_name,hist_type,\n hex(histogram),decode_histogram(hist_type,histogram)\n FROM mysql.column_stats WHERE db_name=\'test\' and table_name=\'origin\';\n+---------+------------+-------------+----------------+----------------------+-\n-----------------------------------------------------------------+\n| db_name | table_name | column_name | hist_type | hex(histogram) |\ndecode_histogram(hist_type,histogram) |\n+---------+------------+-------------+----------------+----------------------+-\n-----------------------------------------------------------------+\n| test | origin | i | SINGLE_PREC_HB | 0F2D3C5A7887A5C3D2F0 |\n0.059,0.118,0.059,0.118,0.118,0.059,0.118,0.118,0.059,0.118,0.059 |\n| test | origin | v | SINGLE_PREC_HB | 000001060C0F161C1F7F |\n0.000,0.000,0.004,0.020,0.024,0.012,0.027,0.024,0.012,0.376,0.502 |\n+---------+------------+-------------+----------------+----------------------+-\n-----------------------------------------------------------------+\n\nSET histogram_size=20,histogram_type=DOUBLE_PREC_HB;\n\nANALYZE TABLE origin PERSISTENT FOR ALL;\n+-------------+---------+----------+-----------------------------------------+\n| Table | Op | Msg_type | Msg_text |\n+-------------+---------+----------+-----------------------------------------+\n| test.origin | analyze | status | Engine-independent statistics collected |\n| test.origin | analyze | status | OK |\n+-------------+---------+----------+-----------------------------------------+\n\nSELECT db_name,table_name,column_name,\n hist_type,hex(histogram),decode_histogram(hist_type,histogram)\n FROM mysql.column_stats WHERE db_name=\'test\' and table_name=\'origin\';\n+---------+------------+-------------+----------------+------------------------\n-----------------+-------------------------------------------------------------\n---------------------------+\n| db_name | table_name | column_name | hist_type | hex(histogram) \n | decode_histogram(hist_type,histogram)\n |\n+---------+------------+-------------+----------------+------------------------\n-----------------+-------------------------------------------------------------\n---------------------------+\n| test | origin | i | DOUBLE_PREC_HB |\n0F0F2D2D3C3C5A5A78788787A5A5C3C3D2D2F0F0 |\n0.05882,0.11765,0.05882,0.11765,0.11765,0.05882,0.11765,0.11765,0.05882,0.11765\n0.05882 |\n| test | origin | v | DOUBLE_PREC_HB |\n5200F600480116067E0CB30F1B16831CB81FD67F |\n0.00125,0.00250,0.00125,0.01877,0.02502,0.01253,0.02502,0.02502,0.01253,0.37546\n0.50063 |\n\nURL: https://mariadb.com/kb/en/decode_histogram/','','https://mariadb.com/kb/en/decode_histogram/'); +insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (198,17,'DEFAULT','Syntax\n------\n\nDEFAULT(col_name)\n\nDescription\n-----------\n\nReturns the default value for a table column. If the column has no default\nvalue (and is not NULLABLE - NULLABLE fields have a NULL default), an error is\nreturned.\n\nFor integer columns using AUTO_INCREMENT, 0 is returned.\n\nWhen using DEFAULT as a value to set in an INSERT or UPDATE statement, you can\nuse the bare keyword DEFAULT without the parentheses and argument to refer to\nthe column in context. You can only use DEFAULT as a bare keyword if you are\nusing it alone without a surrounding expression or function.\n\nExamples\n--------\n\nSelect only non-default values for a column:\n\nSELECT i FROM t WHERE i != DEFAULT(i);\n\nUpdate values to be one greater than the default value:\n\nUPDATE t SET i = DEFAULT(i)+1 WHERE i < 100;\n\nWhen referring to the default value exactly in UPDATE or INSERT, you can omit\nthe argument:\n\nINSERT INTO t (i) VALUES (DEFAULT);\nUPDATE t SET i = DEFAULT WHERE i < 100;\n\nCREATE OR REPLACE TABLE t (\n i INT NOT NULL AUTO_INCREMENT,\n j INT NOT NULL,\n k INT DEFAULT 3,\n l INT NOT NULL DEFAULT 4,\n m INT,\n PRIMARY KEY (i)\n);\n\nDESC t;\n+-------+---------+------+-----+---------+----------------+\n| Field | Type | Null | Key | Default | Extra |\n+-------+---------+------+-----+---------+----------------+\n| i | int(11) | NO | PRI | NULL | auto_increment |\n| j | int(11) | NO | | NULL | |\n| k | int(11) | YES | | 3 | |\n| l | int(11) | NO | | 4 | |\n| m | int(11) | YES | | NULL | |\n+-------+---------+------+-----+---------+----------------+\n\nINSERT INTO t (j) VALUES (1);\nINSERT INTO t (j,m) VALUES (2,2);\nINSERT INTO t (j,l,m) VALUES (3,3,3);\n\nSELECT * FROM t;\n+---+---+------+---+------+\n| i | j | k | l | m |\n+---+---+------+---+------+\n| 1 | 1 | 3 | 4 | NULL |\n| 2 | 2 | 3 | 4 | 2 |\n| 3 | 3 | 3 | 3 | 3 |\n+---+---+------+---+------+\n\nSELECT DEFAULT(i), DEFAULT(k), DEFAULT (l), DEFAULT(m) FROM t;\n+------------+------------+-------------+------------+\n| DEFAULT(i) | DEFAULT(k) | DEFAULT (l) | DEFAULT(m) |\n+------------+------------+-------------+------------+\n| 0 | 3 | 4 | NULL |\n| 0 | 3 | 4 | NULL |\n| 0 | 3 | 4 | NULL |\n+------------+------------+-------------+------------+\n\nSELECT DEFAULT(i), DEFAULT(k), DEFAULT (l), DEFAULT(m), DEFAULT(j) FROM t;\nERROR 1364 (HY000): Field \'j\' doesn\'t have a default value\n\nSELECT * FROM t WHERE i = DEFAULT(i);\nEmpty set (0.001 sec)\n\nSELECT * FROM t WHERE j = DEFAULT(j);\nERROR 1364 (HY000): Field \'j\' doesn\'t have a default value\n\nSELECT * FROM t WHERE k = DEFAULT(k);\n+---+---+------+---+------+\n| i | j | k | l | m |\n+---+---+------+---+------+\n| 1 | 1 | 3 | 4 | NULL |\n| 2 | 2 | 3 | 4 | 2 |\n| 3 | 3 | 3 | 3 | 3 |\n+---+---+------+---+------+\n\nSELECT * FROM t WHERE l = DEFAULT(l);\n+---+---+------+---+------+\n| i | j | k | l | m |\n+---+---+------+---+------+\n| 1 | 1 | 3 | 4 | NULL |\n| 2 | 2 | 3 | 4 | 2 |\n+---+---+------+---+------+\n\nSELECT * FROM t WHERE m = DEFAULT(m);\nEmpty set (0.001 sec)\n\nSELECT * FROM t WHERE m <=> DEFAULT(m);\n+---+---+------+---+------+\n| i | j | k | l | m |\n+---+---+------+---+------+\n| 1 | 1 | 3 | 4 | NULL |\n+---+---+------+---+------+\n\nURL: https://mariadb.com/kb/en/default/','','https://mariadb.com/kb/en/default/'); +insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (199,17,'FOUND_ROWS','Syntax\n------\n\nFOUND_ROWS()\n\nDescription\n-----------\n\nA SELECT statement may include a LIMIT clause to restrict the number of rows\nthe server returns to the client. In some cases, it is desirable to know how\nmany rows the statement would have returned without the LIMIT, but without\nrunning the statement again. To obtain this row count, include a\nSQL_CALC_FOUND_ROWS option in the SELECT statement, and then invoke\nFOUND_ROWS() afterwards.\n\nYou can also use FOUND_ROWS() to obtain the number of rows returned by a\nSELECT which does not contain a LIMIT clause. In this case you don\'t need to\nuse the SQL_CALC_FOUND_ROWS option. This can be useful for example in a stored\nprocedure.\n\nAlso, this function works with some other statements which return a resultset,\nincluding SHOW, DESC and HELP. For DELETE ... RETURNING you should use\nROW_COUNT(). It also works as a prepared statement, or after executing a\nprepared statement.\n\nStatements which don\'t return any results don\'t affect FOUND_ROWS() - the\nprevious value will still be returned.\n\nWarning: When used after a CALL statement, this function returns the number of\nrows selected by the last query in the procedure, not by the whole procedure.\n\nStatements using the FOUND_ROWS() function are not safe for replication.\n\nExamples\n--------\n\nSHOW ENGINES\\G\n*************************** 1. row ***************************\n Engine: CSV\n Support: YES\n Comment: Stores tables as CSV files\nTransactions: NO\n XA: NO\n Savepoints: NO\n*************************** 2. row ***************************\n Engine: MRG_MyISAM\n Support: YES\n Comment: Collection of identical MyISAM tables\nTransactions: NO\n XA: NO\n Savepoints: NO\n\n...\n\n*************************** 8. row ***************************\n Engine: PERFORMANCE_SCHEMA\n Support: YES\n Comment: Performance Schema\nTransactions: NO\n XA: NO\n Savepoints: NO\n8 rows in set (0.000 sec)\n\nSELECT FOUND_ROWS();\n+--------------+\n| FOUND_ROWS() |\n+--------------+\n| 8 |\n+--------------+\n\nSELECT SQL_CALC_FOUND_ROWS * FROM tbl_name WHERE id > 100 LIMIT 10;\n\nSELECT FOUND_ROWS();\n+--------------+\n| FOUND_ROWS() |\n+--------------+\n| 23 |\n+--------------+\n\nURL: https://mariadb.com/kb/en/found_rows/','','https://mariadb.com/kb/en/found_rows/'); +insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (200,17,'LAST_INSERT_ID','Syntax\n------\n\nLAST_INSERT_ID(), LAST_INSERT_ID(expr)\n\nDescription\n-----------\n\nLAST_INSERT_ID() (no arguments) returns the first automatically generated\nvalue successfully inserted for an AUTO_INCREMENT column as a result of the\nmost recently executed INSERT statement. The value of LAST_INSERT_ID() remains\nunchanged if no rows are successfully inserted.\n\nIf one gives an argument to LAST_INSERT_ID(), then it will return the value of\nthe expression and the next call to LAST_INSERT_ID() will return the same\nvalue. The value will also be sent to the client and can be accessed by the\nmysql_insert_id function.\n\nFor example, after inserting a row that generates an AUTO_INCREMENT value, you\ncan get the value like this:\n\nSELECT LAST_INSERT_ID();\n+------------------+\n| LAST_INSERT_ID() |\n+------------------+\n| 9 |\n+------------------+\n\nYou can also use LAST_INSERT_ID() to delete the last inserted row:\n\nDELETE FROM product WHERE id = LAST_INSERT_ID();\n\nIf no rows were successfully inserted, LAST_INSERT_ID() returns 0.\n\nThe value of LAST_INSERT_ID() will be consistent across all versions if all\nrows in the INSERT or UPDATE statement were successful.\n\nThe currently executing statement does not affect the value of\nLAST_INSERT_ID(). Suppose that you generate an AUTO_INCREMENT value with one\nstatement, and then refer to LAST_INSERT_ID() in a multiple-row INSERT\nstatement that inserts rows into a table with its own AUTO_INCREMENT column.\nThe value of LAST_INSERT_ID() will remain stable in the second statement; its\nvalue for the second and later rows is not affected by the earlier row\ninsertions. (However, if you mix references to LAST_INSERT_ID() and\nLAST_INSERT_ID(expr), the effect is undefined.)\n\nIf the previous statement returned an error, the value of LAST_INSERT_ID() is\nundefined. For transactional tables, if the statement is rolled back due to an\nerror, the value of LAST_INSERT_ID() is left undefined. For manual ROLLBACK,\nthe value of LAST_INSERT_ID() is not restored to that before the transaction;\nit remains as it was at the point of the ROLLBACK.\n\nWithin the body of a stored routine (procedure or function) or a trigger, the\nvalue of LAST_INSERT_ID() changes the same way as for statements executed\noutside the body of these kinds of objects. The effect of a stored routine or\ntrigger upon the value of LAST_INSERT_ID() that is seen by following\nstatements depends on the kind of routine:\n\n* If a stored procedure executes statements that change the value of\nLAST_INSERT_ID(), the new value will be seen by statements that follow the\nprocedure call.\n\n* For stored functions and triggers that change the value, the value is\nrestored when the function or trigger ends, so following statements will not\nsee a changed value.\n\nExamples\n--------\n\nCREATE TABLE t (\n id INTEGER UNSIGNED AUTO_INCREMENT PRIMARY KEY,\n f VARCHAR(1))\nENGINE = InnoDB;\n\nINSERT INTO t(f) VALUES(\'a\');\n\nSELECT LAST_INSERT_ID();\n+------------------+\n| LAST_INSERT_ID() |\n+------------------+\n| 1 |\n+------------------+\n\nINSERT INTO t(f) VALUES(\'b\');\n\nINSERT INTO t(f) VALUES(\'c\');\n\nSELECT LAST_INSERT_ID();\n+------------------+\n| LAST_INSERT_ID() |\n+------------------+\n| 3 |\n+------------------+\n\nINSERT INTO t(f) VALUES(\'d\'),(\'e\');\n\nSELECT LAST_INSERT_ID();\n+------------------+\n| LAST_INSERT_ID() |\n+------------------+\n| 4 |\n+------------------+\n\nSELECT * FROM t;\n+----+------+\n| id | f |\n+----+------+\n| 1 | a |\n| 2 | b |\n| 3 | c |\n| 4 | d |\n| 5 | e |\n+----+------+\n\nSELECT LAST_INSERT_ID(12);\n+--------------------+\n| LAST_INSERT_ID(12) |\n+--------------------+\n| 12 |\n+--------------------+\n\nSELECT LAST_INSERT_ID();\n+------------------+\n| LAST_INSERT_ID() |\n+------------------+\n| 12 |\n+------------------+\n\nINSERT INTO t(f) VALUES(\'f\');\n\nSELECT LAST_INSERT_ID();\n+------------------+\n| LAST_INSERT_ID() |\n+------------------+\n| 6 |\n+------------------+\n\nSELECT * FROM t;\n+----+------+\n| id | f |\n+----+------+\n| 1 | a |\n| 2 | b |\n| 3 | c |\n| 4 | d |\n| 5 | e |\n| 6 | f |\n+----+------+\n\nSELECT LAST_INSERT_ID(12);\n+--------------------+\n| LAST_INSERT_ID(12) |\n+--------------------+\n| 12 |\n+--------------------+\n\nINSERT INTO t(f) VALUES(\'g\');\n\nSELECT * FROM t;\n+----+------+\n| id | f |\n+----+------+\n| 1 | a |\n| 2 | b |\n| 3 | c |\n| 4 | d |\n| 5 | e |\n| 6 | f |\n| 7 | g |\n+----+------+\n\nURL: https://mariadb.com/kb/en/last_insert_id/','','https://mariadb.com/kb/en/last_insert_id/'); +insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (201,17,'LAST_VALUE','Syntax\n------\n\nLAST_VALUE(expr,[expr,...])\n\nLAST_VALUE(expr) OVER (\n [ PARTITION BY partition_expression ]\n [ ORDER BY order_list ]\n)\n\nDescription\n-----------\n\nLAST_VALUE() evaluates all expressions and returns the last.\n\nThis is useful together with setting user variables to a value with\n@var:=expr, for example when you want to get data of rows updated/deleted\nwithout having to do two queries against the table.\n\nLAST_VALUE can be used as a window function.\n\nReturns NULL if no last value exists.\n\nExamples\n--------\n\nCREATE TABLE t1 (a int, b int);\nINSERT INTO t1 VALUES(1,10),(2,20);\nDELETE FROM t1 WHERE a=1 AND last_value(@a:=a,@b:=b,1);\nSELECT @a,@b;\n+------+------+\n| @a | @b |\n+------+------+\n| 1 | 10 |\n+------+------+\n\nAs a window function:\n\nCREATE TABLE t1 (\n pk int primary key,\n a int,\n b int,\n c char(10),\n d decimal(10, 3),\n e real\n);\n\nINSERT INTO t1 VALUES\n( 1, 0, 1, \'one\', 0.1, 0.001),\n( 2, 0, 2, \'two\', 0.2, 0.002),\n( 3, 0, 3, \'three\', 0.3, 0.003),\n( 4, 1, 2, \'three\', 0.4, 0.004),\n( 5, 1, 1, \'two\', 0.5, 0.005),\n( 6, 1, 1, \'one\', 0.6, 0.006),\n( 7, 2, NULL, \'n_one\', 0.5, 0.007),\n( 8, 2, 1, \'n_two\', NULL, 0.008),\n( 9, 2, 2, NULL, 0.7, 0.009),\n(10, 2, 0, \'n_four\', 0.8, 0.010),\n(11, 2, 10, NULL, 0.9, NULL);\n\nSELECT pk, FIRST_VALUE(pk) OVER (ORDER BY pk) AS first_asc,\n LAST_VALUE(pk) OVER (ORDER BY pk) AS last_asc,\n FIRST_VALUE(pk) OVER (ORDER BY pk DESC) AS first_desc,\n LAST_VALUE(pk) OVER (ORDER BY pk DESC) AS last_desc\nFROM t1\nORDER BY pk DESC;\n\n+----+-----------+----------+------------+-----------+\n| pk | first_asc | last_asc | first_desc | last_desc |\n+----+-----------+----------+------------+-----------+\n| 11 | 1 | 11 | 11 | 11 |\n| 10 | 1 | 10 | 11 | 10 |\n| 9 | 1 | 9 | 11 | 9 |\n| 8 | 1 | 8 | 11 | 8 |\n| 7 | 1 | 7 | 11 | 7 |\n| 6 | 1 | 6 | 11 | 6 |\n| 5 | 1 | 5 | 11 | 5 |\n| 4 | 1 | 4 | 11 | 4 |\n| 3 | 1 | 3 | 11 | 3 |\n| 2 | 1 | 2 | 11 | 2 |\n| 1 | 1 | 1 | 11 | 1 |\n+----+-----------+----------+------------+-----------+\n\nCREATE OR REPLACE TABLE t1 (i int);\nINSERT INTO t1 VALUES (1),(2),(3),(4),(5),(6),(7),(8),(9),(10);\n\nSELECT i,\n FIRST_VALUE(i) OVER (ORDER BY i ROWS BETWEEN CURRENT ROW and 1 FOLLOWING) AS\nf_1f,\n LAST_VALUE(i) OVER (ORDER BY i ROWS BETWEEN CURRENT ROW and 1 FOLLOWING) AS\nl_1f,\n FIRST_VALUE(i) OVER (ORDER BY i ROWS BETWEEN 1 PRECEDING AND 1 FOLLOWING) AS\nf_1p1f,\n LAST_VALUE(i) OVER (ORDER BY i ROWS BETWEEN 1 PRECEDING AND 1 FOLLOWING) AS\nf_1p1f,\n FIRST_VALUE(i) OVER (ORDER BY i ROWS BETWEEN 2 PRECEDING AND 1 PRECEDING) AS\nf_2p1p,\n LAST_VALUE(i) OVER (ORDER BY i ROWS BETWEEN 2 PRECEDING AND 1 PRECEDING) AS\nf_2p1p,\n FIRST_VALUE(i) OVER (ORDER BY i ROWS BETWEEN 1 FOLLOWING AND 2 FOLLOWING) AS\nf_1f2f,\n LAST_VALUE(i) OVER (ORDER BY i ROWS BETWEEN 1 FOLLOWING AND 2 FOLLOWING) AS\nf_1f2f\nFROM t1;\n\n+------+------+------+--------+--------+--------+--------+--------+--------+\n| i | f_1f | l_1f | f_1p1f | f_1p1f | f_2p1p | f_2p1p | f_1f2f | f_1f2f |\n+------+------+------+--------+--------+--------+--------+--------+--------+\n| 1 | 1 | 2 | 1 | 2 | NULL | NULL | 2 | 3 |\n| 2 | 2 | 3 | 1 | 3 | 1 | 1 | 3 | 4 |\n| 3 | 3 | 4 | 2 | 4 | 1 | 2 | 4 | 5 |\n| 4 | 4 | 5 | 3 | 5 | 2 | 3 | 5 | 6 |\n| 5 | 5 | 6 | 4 | 6 | 3 | 4 | 6 | 7 |\n| 6 | 6 | 7 | 5 | 7 | 4 | 5 | 7 | 8 |\n| 7 | 7 | 8 | 6 | 8 | 5 | 6 | 8 | 9 |\n| 8 | 8 | 9 | 7 | 9 | 6 | 7 | 9 | 10 |\n| 9 | 9 | 10 | 8 | 10 | 7 | 8 | 10 | 10 |\n| 10 | 10 | 10 | 9 | 10 | 8 | 9 | NULL | NULL |\n+------+------+------+--------+--------+--------+--------+--------+--------+\n\nURL: https://mariadb.com/kb/en/last_value/','','https://mariadb.com/kb/en/last_value/'); +insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (202,17,'PROCEDURE ANALYSE','Syntax\n------\n\nanalyse([max_elements[,max_memory]])\n\nDescription\n-----------\n\nThis procedure is defined in the sql/sql_analyse.cc file. It examines the\nresult from a query and returns an analysis of the results that suggests\noptimal data types for each column. To obtain this analysis, append PROCEDURE\nANALYSE to the end of a SELECT statement:\n\nSELECT ... FROM ... WHERE ... PROCEDURE ANALYSE([max_elements,[max_memory]])\n\nFor example:\n\nSELECT col1, col2 FROM table1 PROCEDURE ANALYSE(10, 2000);\n\nThe results show some statistics for the values returned by the query, and\npropose an optimal data type for the columns. This can be helpful for checking\nyour existing tables, or after importing new data. You may need to try\ndifferent settings for the arguments so that PROCEDURE ANALYSE() does not\nsuggest the ENUM data type when it is not appropriate.\n\nThe arguments are optional and are used as follows:\n\n* max_elements (default 256) is the maximum number of distinct values that\nanalyse notices per column. This is used by analyse to check whether the\noptimal data type should be of type ENUM; if there are more than max_elements\ndistinct values, then ENUM is not a suggested type.\n* max_memory (default 8192) is the maximum amount of memory that analyse\nshould allocate per column while trying to find all distinct values.\n\nURL: https://mariadb.com/kb/en/procedure-analyse/','','https://mariadb.com/kb/en/procedure-analyse/'); +insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (203,17,'ROW_COUNT','Syntax\n------\n\nROW_COUNT()\n\nDescription\n-----------\n\nROW_COUNT() returns the number of rows updated, inserted or deleted by the\npreceding statement. This is the same as the row count that the mysql client\ndisplays and the value from the mysql_affected_rows() C API function.\n\nGenerally:\n\n* For statements which return a result set (such as SELECT, SHOW, DESC or\nHELP), returns -1, even when the result set is empty. This is also true for\nadministrative statements, such as OPTIMIZE.\n* For DML statements other than SELECT and for ALTER TABLE, returns the number\nof affected rows.\n* For DDL statements (including TRUNCATE) and for other statements which don\'t\nreturn any result set (such as USE, DO, SIGNAL or DEALLOCATE PREPARE), returns\n0.\n\nFor UPDATE, affected rows is by default the number of rows that were actually\nchanged. If the CLIENT_FOUND_ROWS flag to mysql_real_connect() is specified\nwhen connecting to mysqld, affected rows is instead the number of rows matched\nby the WHERE clause.\n\nFor REPLACE, deleted rows are also counted. So, if REPLACE deletes a row and\nadds a new row, ROW_COUNT() returns 2.\n\nFor INSERT ... ON DUPLICATE KEY, updated rows are counted twice. So, if INSERT\nadds a new rows and modifies another row, ROW_COUNT() returns 3.\n\nROW_COUNT() does not take into account rows that are not directly\ndeleted/updated by the last statement. This means that rows deleted by foreign\nkeys or triggers are not counted.\n\nWarning: You can use ROW_COUNT() with prepared statements, but you need to\ncall it after EXECUTE, not after DEALLOCATE PREPARE, because the row count for\nallocate prepare is always 0.\n\nWarning: When used after a CALL statement, this function returns the number of\nrows affected by the last statement in the procedure, not by the whole\nprocedure.\n\nWarning: After INSERT DELAYED, ROW_COUNT() returns the number of the rows you\ntried to insert, not the number of the successful writes.\n\nThis information can also be found in the diagnostics area.\n\nStatements using the ROW_COUNT() function are not safe for replication.\n\nExamples\n--------\n\nCREATE TABLE t (A INT);\n\nINSERT INTO t VALUES(1),(2),(3);\n\nSELECT ROW_COUNT();\n+-------------+\n| ROW_COUNT() |\n+-------------+\n| 3 |\n+-------------+\n\nDELETE FROM t WHERE A IN(1,2);\n\nSELECT ROW_COUNT(); \n+-------------+\n| ROW_COUNT() |\n+-------------+\n| 2 |\n+-------------+\n\nExample with prepared statements:\n\nSET @q = \'INSERT INTO t VALUES(1),(2),(3);\';\n\nPREPARE stmt FROM @q;\n\nEXECUTE stmt;\nQuery OK, 3 rows affected (0.39 sec)\nRecords: 3 Duplicates: 0 Warnings: 0\n\nSELECT ROW_COUNT();\n+-------------+\n| ROW_COUNT() |\n+-------------+\n| 3 |\n+-------------+\n\nURL: https://mariadb.com/kb/en/row_count/','','https://mariadb.com/kb/en/row_count/'); +insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (204,17,'SCHEMA','Syntax\n------\n\nSCHEMA()\n\nDescription\n-----------\n\nThis function is a synonym for DATABASE().\n\nURL: https://mariadb.com/kb/en/schema/','','https://mariadb.com/kb/en/schema/'); +insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (205,17,'SESSION_USER','Syntax\n------\n\nSESSION_USER()\n\nDescription\n-----------\n\nSESSION_USER() is a synonym for USER().\n\nURL: https://mariadb.com/kb/en/session_user/','','https://mariadb.com/kb/en/session_user/'); +insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (206,17,'SYSTEM_USER','Syntax\n------\n\nSYSTEM_USER()\n\nDescription\n-----------\n\nSYSTEM_USER() is a synonym for USER().\n\nURL: https://mariadb.com/kb/en/system_user/','','https://mariadb.com/kb/en/system_user/'); +insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (207,17,'USER','Syntax\n------\n\nUSER()\n\nDescription\n-----------\n\nReturns the current MariaDB user name and host name, given when authenticating\nto MariaDB, as a string in the utf8 character set.\n\nNote that the value of USER() may differ from the value of CURRENT_USER(),\nwhich is the user used to authenticate the current client. CURRENT_ROLE()\nreturns the current active role.\n\nSYSTEM_USER() and SESSION_USER are synonyms for USER().\n\nStatements using the USER() function or one of its synonyms are not safe for\nstatement level replication.\n\nExamples\n--------\n\nshell> mysql --user=\"anonymous\"\n\nSELECT USER(),CURRENT_USER();\n+---------------------+----------------+\n| USER() | CURRENT_USER() |\n+---------------------+----------------+\n| anonymous@localhost | @localhost |\n+---------------------+----------------+\n\nTo select only the IP address, use SUBSTRING_INDEX(),\n\nSELECT SUBSTRING_INDEX(USER(), \'@\', -1);\n+----------------------------------+\n| SUBSTRING_INDEX(USER(), \'@\', -1) |\n+----------------------------------+\n| 192.168.0.101 |\n+----------------------------------+\n\nURL: https://mariadb.com/kb/en/user/','','https://mariadb.com/kb/en/user/'); +insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (208,17,'VERSION','Syntax\n------\n\nVERSION()\n\nDescription\n-----------\n\nReturns a string that indicates the MariaDB server version. The string uses\nthe utf8 character set.\n\nExamples\n--------\n\nSELECT VERSION();\n+----------------+\n| VERSION() |\n+----------------+\n| 10.4.7-MariaDB |\n+----------------+\n\nThe VERSION() string may have one or more of the following suffixes:\n\n+---------------------------+------------------------------------------------+\n| Suffix | Description |\n+---------------------------+------------------------------------------------+\n| -embedded | The server is an embedded server (libmysqld). |\n+---------------------------+------------------------------------------------+\n| -log | General logging, slow logging or binary |\n| | (replication) logging is enabled. |\n+---------------------------+------------------------------------------------+\n| -debug | The server is compiled for debugging. |\n+---------------------------+------------------------------------------------+\n| -valgrind | The server is compiled to be instrumented |\n| | with valgrind. |\n+---------------------------+------------------------------------------------+\n\nChanging the Version String\n---------------------------\n\nSome old legacy code may break because they are parsing the VERSION string and\nexpecting a MySQL string or a simple version string like Joomla til API17, see\nMDEV-7780.\n\nFrom MariaDB 10.2, one can fool these applications by setting the version\nstring from the command line or the my.cnf files with --version=....\n\nURL: https://mariadb.com/kb/en/version/','','https://mariadb.com/kb/en/version/'); +insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (209,18,'Assignment Operator (:=)','Syntax\n------\n\nvar_name := expr\n\nDescription\n-----------\n\nAssignment operator for assigning a value. The value on the right is assigned\nto the variable on left.\n\nUnlike the = operator, := can always be used to assign a value to a variable.\n\nThis operator works with both user-defined variables and local variables.\n\nWhen assigning the same value to several variables, LAST_VALUE() can be useful.\n\nExamples\n--------\n\nSELECT @x := 10;\n+----------+\n| @x := 10 |\n+----------+\n| 10 |\n+----------+\n\nSELECT @x, @y := @x;\n+------+----------+\n| @x | @y := @x |\n+------+----------+\n| 10 | 10 |\n+------+----------+\n\nURL: https://mariadb.com/kb/en/assignment-operator/','','https://mariadb.com/kb/en/assignment-operator/'); +insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (210,18,'Assignment Operator (=)','Syntax\n------\n\nidentifier = expr\n\nDescription\n-----------\n\nThe equal sign is used as both an assignment operator in certain contexts, and\nas a comparison operator. When used as assignment operator, the value on the\nright is assigned to the variable (or column, in some contexts) on the left.\n\nSince its use can be ambiguous, unlike the := assignment operator, the =\nassignment operator cannot be used in all contexts, and is only valid as part\nof a SET statement, or the SET clause of an UPDATE statement\n\nThis operator works with both user-defined variables and local variables.\n\nExamples\n--------\n\nUPDATE table_name SET x = 2 WHERE x > 100;\n\nSET @x = 1, @y := 2;\n\nURL: https://mariadb.com/kb/en/assignment-operators-assignment-operator/','','https://mariadb.com/kb/en/assignment-operators-assignment-operator/'); +insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (211,19,'Not Equal Operator','Syntax\n------\n\n<>, !=\n\nDescription\n-----------\n\nNot equal operator. Evaluates both SQL expressions and returns 1 if they are\nnot equal and 0 if they are equal, or NULL if either expression is NULL. If\nthe expressions return different data types, (for instance, a number and a\nstring), performs type conversion.\n\nWhen used in row comparisons these two queries return the same results:\n\nSELECT (t1.a, t1.b) != (t2.x, t2.y) \nFROM t1 INNER JOIN t2;\n\nSELECT (t1.a != t2.x) OR (t1.b != t2.y)\nFROM t1 INNER JOIN t2;\n\nExamples\n--------\n\nSELECT \'.01\' <> \'0.01\';\n+-----------------+\n| \'.01\' <> \'0.01\' |\n+-----------------+\n| 1 |\n+-----------------+\n\nSELECT .01 <> \'0.01\';\n+---------------+\n| .01 <> \'0.01\' |\n+---------------+\n| 0 |\n+---------------+\n\nSELECT \'zapp\' <> \'zappp\';\n+-------------------+\n| \'zapp\' <> \'zappp\' |\n+-------------------+\n| 1 |\n+-------------------+\n\nURL: https://mariadb.com/kb/en/not-equal/','','https://mariadb.com/kb/en/not-equal/'); +insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (212,19,'<','Syntax\n------\n\n<\n\nDescription\n-----------\n\nLess than operator. Evaluates both SQL expressions and returns 1 if the left\nvalue is less than the right value and 0 if it is not, or NULL if either\nexpression is NULL. If the expressions return different data types, (for\ninstance, a number and a string), performs type conversion.\n\nWhen used in row comparisons these two queries return the same results:\n\nSELECT (t1.a, t1.b) < (t2.x, t2.y) \nFROM t1 INNER JOIN t2;\n\nSELECT (t1.a < t2.x) OR ((t1.a = t2.x) AND (t1.b < t2.y))\nFROM t1 INNER JOIN t2;\n\nExamples\n--------\n\nSELECT 2 < 2;\n+-------+\n| 2 < 2 |\n+-------+\n| 0 |\n+-------+\n\nType conversion:\n\nSELECT 3<\'4\';\n+-------+\n| 3<\'4\' |\n+-------+\n| 1 |\n+-------+\n\nCase insensitivity - see Character Sets and Collations:\n\nSELECT \'a\'<\'A\';\n+---------+\n| \'a\'<\'A\' |\n+---------+\n| 0 |\n+---------+\n\nURL: https://mariadb.com/kb/en/less-than/','','https://mariadb.com/kb/en/less-than/'); +insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (213,19,'<=','Syntax\n------\n\n<=\n\nDescription\n-----------\n\nLess than or equal operator. Evaluates both SQL expressions and returns 1 if\nthe left value is less than or equal to the right value and 0 if it is not, or\nNULL if either expression is NULL. If the expressions return different data\ntypes, (for instance, a number and a string), performs type conversion.\n\nWhen used in row comparisons these two queries return the same results:\n\nSELECT (t1.a, t1.b) <= (t2.x, t2.y) \nFROM t1 INNER JOIN t2;\n\nSELECT (t1.a < t2.x) OR ((t1.a = t2.x) AND (t1.b <= t2.y))\nFROM t1 INNER JOIN t2;\n\nExamples\n--------\n\nSELECT 0.1 <= 2;\n+----------+\n| 0.1 <= 2 |\n+----------+\n| 1 |\n+----------+\n\nSELECT \'a\'<=\'A\';\n+----------+\n| \'a\'<=\'A\' |\n+----------+\n| 1 |\n+----------+\n\nURL: https://mariadb.com/kb/en/less-than-or-equal/','','https://mariadb.com/kb/en/less-than-or-equal/'); +insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (214,19,'<=>','Syntax\n------\n\n<=>\n\nDescription\n-----------\n\nNULL-safe equal operator. It performs an equality comparison like the =\noperator, but returns 1 rather than NULL if both operands are NULL, and 0\nrather than NULL if one operand is NULL.\n\na <=> b is equivalent to a = b OR (a IS NULL AND b IS NULL).\n\nWhen used in row comparisons these two queries return the same results:\n\nSELECT (t1.a, t1.b) <=> (t2.x, t2.y) \nFROM t1 INNER JOIN t2;\n\nSELECT (t1.a <=> t2.x) AND (t1.b <=> t2.y)\nFROM t1 INNER JOIN t2;\n\nSee also NULL Values in MariaDB.\n\nExamples\n--------\n\nSELECT 1 <=> 1, NULL <=> NULL, 1 <=> NULL;\n+---------+---------------+------------+\n| 1 <=> 1 | NULL <=> NULL | 1 <=> NULL |\n+---------+---------------+------------+\n| 1 | 1 | 0 |\n+---------+---------------+------------+\n\nSELECT 1 = 1, NULL = NULL, 1 = NULL;\n+-------+-------------+----------+\n| 1 = 1 | NULL = NULL | 1 = NULL |\n+-------+-------------+----------+\n| 1 | NULL | NULL |\n+-------+-------------+----------+\n\nURL: https://mariadb.com/kb/en/null-safe-equal/','','https://mariadb.com/kb/en/null-safe-equal/'); +insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (215,19,'=','Syntax\n------\n\nleft_expr = right_expr\n\nDescription\n-----------\n\nEqual operator. Evaluates both SQL expressions and returns 1 if they are\nequal, 0 if they are not equal, or NULL if either expression is NULL. If the\nexpressions return different data types (for example, a number and a string),\na type conversion is performed.\n\nWhen used in row comparisons these two queries are synonymous and return the\nsame results:\n\nSELECT (t1.a, t1.b) = (t2.x, t2.y) FROM t1 INNER JOIN t2;\n\nSELECT (t1.a = t2.x) AND (t1.b = t2.y) FROM t1 INNER JOIN t2;\n\nTo perform a NULL-safe comparison, use the <=> operator.\n\n= can also be used as an assignment operator.\n\nExamples\n--------\n\nSELECT 1 = 0;\n+-------+\n| 1 = 0 |\n+-------+\n| 0 |\n+-------+\n\nSELECT \'0\' = 0;\n+---------+\n| \'0\' = 0 |\n+---------+\n| 1 |\n+---------+\n\nSELECT \'0.0\' = 0;\n+-----------+\n| \'0.0\' = 0 |\n+-----------+\n| 1 |\n+-----------+\n\nSELECT \'0.01\' = 0;\n+------------+\n| \'0.01\' = 0 |\n+------------+\n| 0 |\n+------------+\n\nSELECT \'.01\' = 0.01;\n+--------------+\n| \'.01\' = 0.01 |\n+--------------+\n| 1 |\n+--------------+\n\nSELECT (5 * 2) = CONCAT(\'1\', \'0\');\n+----------------------------+\n| (5 * 2) = CONCAT(\'1\', \'0\') |\n+----------------------------+\n| 1 |\n+----------------------------+\n\nSELECT 1 = NULL;\n+----------+\n| 1 = NULL |\n+----------+\n| NULL |\n+----------+\n\nSELECT NULL = NULL;\n+-------------+\n| NULL = NULL |\n+-------------+\n| NULL |\n+-------------+\n\nURL: https://mariadb.com/kb/en/equal/','','https://mariadb.com/kb/en/equal/'); +insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (216,19,'>','Syntax\n------\n\n>\n\nDescription\n-----------\n\nGreater than operator. Evaluates both SQL expressions and returns 1 if the\nleft value is greater than the right value and 0 if it is not, or NULL if\neither expression is NULL. If the expressions return different data types,\n(for instance, a number and a string), performs type conversion.\n\nWhen used in row comparisons these two queries return the same results:\n\nSELECT (t1.a, t1.b) > (t2.x, t2.y) \nFROM t1 INNER JOIN t2;\n\nSELECT (t1.a > t2.x) OR ((t1.a = t2.x) AND (t1.b > t2.y))\nFROM t1 INNER JOIN t2;\n\nExamples\n--------\n\nSELECT 2 > 2;\n+-------+\n| 2 > 2 |\n+-------+\n| 0 |\n+-------+\n\nSELECT \'b\' > \'a\';\n+-----------+\n| \'b\' > \'a\' |\n+-----------+\n| 1 |\n+-----------+\n\nURL: https://mariadb.com/kb/en/greater-than/','','https://mariadb.com/kb/en/greater-than/'); +insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (217,19,'>=','Syntax\n------\n\n>=\n\nDescription\n-----------\n\nGreater than or equal operator. Evaluates both SQL expressions and returns 1\nif the left value is greater than or equal to the right value and 0 if it is\nnot, or NULL if either expression is NULL. If the expressions return different\ndata types, (for instance, a number and a string), performs type conversion.\n\nWhen used in row comparisons these two queries return the same results:\n\nSELECT (t1.a, t1.b) >= (t2.x, t2.y) \nFROM t1 INNER JOIN t2;\n\nSELECT (t1.a > t2.x) OR ((t1.a = t2.x) AND (t1.b >= t2.y))\nFROM t1 INNER JOIN t2;\n\nExamples\n--------\n\nSELECT 2 >= 2;\n+--------+\n| 2 >= 2 |\n+--------+\n| 1 |\n+--------+\n\nSELECT \'A\' >= \'a\';\n+------------+\n| \'A\' >= \'a\' |\n+------------+\n| 1 |\n+------------+\n\nURL: https://mariadb.com/kb/en/greater-than-or-equal/','','https://mariadb.com/kb/en/greater-than-or-equal/'); +insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (218,19,'BETWEEN AND','Syntax\n------\n\nexpr BETWEEN min AND max\n\nDescription\n-----------\n\nIf expr is greater than or equal to min and expr is less than or equal to max,\nBETWEEN returns 1, otherwise it returns 0. This is equivalent to the\nexpression (min <= expr AND expr <= max) if all the arguments are of the same\ntype. Otherwise type conversion takes place according to the rules described\nat Type Conversion, but applied to all the three arguments.\n\nExamples\n--------\n\nSELECT 1 BETWEEN 2 AND 3;\n+-------------------+\n| 1 BETWEEN 2 AND 3 |\n+-------------------+\n| 0 |\n+-------------------+\n\nSELECT \'b\' BETWEEN \'a\' AND \'c\';\n+-------------------------+\n| \'b\' BETWEEN \'a\' AND \'c\' |\n+-------------------------+\n| 1 |\n+-------------------------+\n\nSELECT 2 BETWEEN 2 AND \'3\';\n+---------------------+\n| 2 BETWEEN 2 AND \'3\' |\n+---------------------+\n| 1 |\n+---------------------+\n\nSELECT 2 BETWEEN 2 AND \'x-3\';\n+-----------------------+\n| 2 BETWEEN 2 AND \'x-3\' |\n+-----------------------+\n| 0 |\n+-----------------------+\n1 row in set, 1 warning (0.00 sec)\n\nWarning (Code 1292): Truncated incorrect DOUBLE value: \'x-3\'\n\nNULL:\n\nSELECT 1 BETWEEN 1 AND NULL;\n+----------------------+\n| 1 BETWEEN 1 AND NULL |\n+----------------------+\n| NULL |\n+----------------------+\n\nDATE, DATETIME and TIMESTAMP examples. Omitting the time component compares\nagainst 00:00, so later times on the same date are not returned:\n\nCREATE TABLE `x` (\n a date ,\n b datetime,\n c timestamp\n)\n\nINSERT INTO x VALUES \n (\'2018-11-11\', \'2018-11-11 05:15\', \'2018-11-11 05:15\'), \n (\'2018-11-12\', \'2018-11-12 05:15\', \'2018-11-12 05:15\');\n\nSELECT * FROM x WHERE a BETWEEN \'2018-11-11\' AND \'2018-11-12\';\n+------------+---------------------+---------------------+\n| a | b | c |\n+------------+---------------------+---------------------+\n| 2018-11-11 | 2018-11-11 05:15:00 | 2018-11-11 05:15:00 |\n| 2018-11-12 | 2018-11-12 05:15:00 | 2018-11-12 05:15:00 |\n+------------+---------------------+---------------------+\n\nSELECT * FROM x WHERE b BETWEEN \'2018-11-11\' AND \'2018-11-12\';\n+------------+---------------------+---------------------+\n| a | b | c |\n+------------+---------------------+---------------------+\n| 2018-11-11 | 2018-11-11 05:15:00 | 2018-11-11 05:15:00 |\n+------------+---------------------+---------------------+\n\nSELECT * FROM x WHERE c BETWEEN \'2018-11-11\' AND \'2018-11-12\';\n+------------+---------------------+---------------------+\n| a | b | c |\n+------------+---------------------+---------------------+\n| 2018-11-11 | 2018-11-11 05:15:00 | 2018-11-11 05:15:00 |\n+------------+---------------------+---------------------+\n\nURL: https://mariadb.com/kb/en/between-and/','','https://mariadb.com/kb/en/between-and/'); +insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (219,19,'COALESCE','Syntax\n------\n\nCOALESCE(value,...)\n\nDescription\n-----------\n\nReturns the first non-NULL value in the list, or NULL if there are no non-NULL\nvalues. At least one parameter must be passed.\n\nThe function is useful when substituting a default value for null values when\ndisplaying data.\n\nSee also NULL Values in MariaDB.\n\nExamples\n--------\n\nSELECT COALESCE(NULL,1);\n+------------------+\n| COALESCE(NULL,1) |\n+------------------+\n| 1 |\n+------------------+\n\nSELECT COALESCE(NULL,NULL,NULL);\n+--------------------------+\n| COALESCE(NULL,NULL,NULL) |\n+--------------------------+\n| NULL |\n+--------------------------+\n\nWhen two arguments are given, COALESCE() is the same as IFNULL():\n\nSET @a=NULL, @b=1;\n\nSELECT COALESCE(@a, @b), IFNULL(@a, @b);\n+------------------+----------------+\n| COALESCE(@a, @b) | IFNULL(@a, @b) |\n+------------------+----------------+\n| 1 | 1 |\n+------------------+----------------+\n\nHex type confusion:\n\nCREATE TABLE t1 (a INT, b VARCHAR(10));\nINSERT INTO t1 VALUES (0x31, 0x61),(COALESCE(0x31), COALESCE(0x61));\n\nSELECT * FROM t1;\n+------+------+\n| a | b |\n+------+------+\n| 49 | a |\n| 1 | a |\n+------+------+\n\nThe reason for the differing results above is that when 0x31 is inserted\ndirectly to the column, it\'s treated as a number (see Hexadecimal Literals),\nwhile when 0x31 is passed to COALESCE(), it\'s treated as a string, because:\n\n* HEX values have a string data type by default.\n* COALESCE() has the same data type as the argument.\n\nSubstituting zero for NULL (in this case when the aggregate function returns\nNULL after finding no rows):\n\nSELECT SUM(score) FROM student;\n+------------+\n| SUM(score) |\n+------------+\n| NULL |\n+------------+\n\nSELECT COALESCE(SUM(score),0) FROM student;\n+------------------------+\n| COALESCE(SUM(score),0) |\n+------------------------+\n| 0 |\n+------------------------+\n\nURL: https://mariadb.com/kb/en/coalesce/','','https://mariadb.com/kb/en/coalesce/'); +insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (220,19,'GREATEST','Syntax\n------\n\nGREATEST(value1,value2,...)\n\nDescription\n-----------\n\nWith two or more arguments, returns the largest (maximum-valued) argument. The\narguments are compared using the same rules as for LEAST().\n\nExamples\n--------\n\nSELECT GREATEST(2,0);\n+---------------+\n| GREATEST(2,0) |\n+---------------+\n| 2 |\n+---------------+\n\nSELECT GREATEST(34.0,3.0,5.0,767.0);\n+------------------------------+\n| GREATEST(34.0,3.0,5.0,767.0) |\n+------------------------------+\n| 767.0 |\n+------------------------------+\n\nSELECT GREATEST(\'B\',\'A\',\'C\');\n+-----------------------+\n| GREATEST(\'B\',\'A\',\'C\') |\n+-----------------------+\n| C |\n+-----------------------+\n\nURL: https://mariadb.com/kb/en/greatest/','','https://mariadb.com/kb/en/greatest/'); +insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (221,19,'IN','Syntax\n------\n\nexpr IN (value,...)\n\nDescription\n-----------\n\nReturns 1 if expr is equal to any of the values in the IN list, else returns\n0. If all values are constants, they are evaluated according to the type of\nexpr and sorted. The search for the item then is done using a binary search.\nThis means IN is very quick if the IN value list consists entirely of\nconstants. Otherwise, type conversion takes place according to the rules\ndescribed at Type Conversion, but applied to all the arguments.\n\nIf expr is NULL, IN always returns NULL. If at least one of the values in the\nlist is NULL, and one of the comparisons is true, the result is 1. If at least\none of the values in the list is NULL and none of the comparisons is true, the\nresult is NULL.\n\nExamples\n--------\n\nSELECT 2 IN (0,3,5,7);\n+----------------+\n| 2 IN (0,3,5,7) |\n+----------------+\n| 0 |\n+----------------+\n\nSELECT \'wefwf\' IN (\'wee\',\'wefwf\',\'weg\');\n+----------------------------------+\n| \'wefwf\' IN (\'wee\',\'wefwf\',\'weg\') |\n+----------------------------------+\n| 1 |\n+----------------------------------+\n\nType conversion:\n\nSELECT 1 IN (\'1\', \'2\', \'3\');\n+----------------------+\n| 1 IN (\'1\', \'2\', \'3\') |\n+----------------------+\n| 1 |\n+----------------------+\n\nSELECT NULL IN (1, 2, 3);\n+-------------------+\n| NULL IN (1, 2, 3) |\n+-------------------+\n| NULL |\n+-------------------+\n\nSELECT 1 IN (1, 2, NULL);\n+-------------------+\n| 1 IN (1, 2, NULL) |\n+-------------------+\n| 1 |\n+-------------------+\n\nSELECT 5 IN (1, 2, NULL);\n+-------------------+\n| 5 IN (1, 2, NULL) |\n+-------------------+\n| NULL |\n+-------------------+\n\nURL: https://mariadb.com/kb/en/in/','','https://mariadb.com/kb/en/in/'); +insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (222,19,'INTERVAL','Syntax\n------\n\nINTERVAL(N,N1,N2,N3,...)\n\nDescription\n-----------\n\nReturns the index of the last argument that is less than the first argument or\nis NULL.\n\nReturns 0 if N < N1, 1 if N < N2, 2 if N < N3 and so on or -1 if N is NULL.\nAll arguments are treated as integers. It is required that N1 < N2 < N3 < ...\n< Nn for this function to work correctly. This is because a fast binary search\nis used.\n\nExamples\n--------\n\nSELECT INTERVAL(23, 1, 15, 17, 30, 44, 200);\n+--------------------------------------+\n| INTERVAL(23, 1, 15, 17, 30, 44, 200) |\n+--------------------------------------+\n| 3 |\n+--------------------------------------+\n\nSELECT INTERVAL(10, 1, 10, 100, 1000);\n+--------------------------------+\n| INTERVAL(10, 1, 10, 100, 1000) |\n+--------------------------------+\n| 2 |\n+--------------------------------+\n\nSELECT INTERVAL(22, 23, 30, 44, 200);\n+-------------------------------+\n| INTERVAL(22, 23, 30, 44, 200) |\n+-------------------------------+\n| 0 |\n+-------------------------------+\n\nSELECT INTERVAL(10, 2, NULL);\n+-----------------------+\n| INTERVAL(10, 2, NULL) |\n+-----------------------+\n| 2 |\n+-----------------------+\n\nURL: https://mariadb.com/kb/en/interval/','','https://mariadb.com/kb/en/interval/'); +insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (223,19,'IS','Syntax\n------\n\nIS boolean_value\n\nDescription\n-----------\n\nTests a value against a boolean value, where boolean_value can be TRUE, FALSE,\nor UNKNOWN.\n\nThere is an important difference between using IS TRUE or comparing a value\nwith TRUE using =. When using =, only 1 equals to TRUE. But when using IS\nTRUE, all values which are logically true (like a number > 1) return TRUE.\n\nExamples\n--------\n\nSELECT 1 IS TRUE, 0 IS FALSE, NULL IS UNKNOWN;\n+-----------+------------+-----------------+\n| 1 IS TRUE | 0 IS FALSE | NULL IS UNKNOWN |\n+-----------+------------+-----------------+\n| 1 | 1 | 1 |\n+-----------+------------+-----------------+\n\nDifference between = and IS TRUE:\n\nSELECT 2 = TRUE, 2 IS TRUE;\n+----------+-----------+\n| 2 = TRUE | 2 IS TRUE |\n+----------+-----------+\n| 0 | 1 |\n+----------+-----------+\n\nURL: https://mariadb.com/kb/en/is/','','https://mariadb.com/kb/en/is/'); +insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (224,19,'IS NOT','Syntax\n------\n\nIS NOT boolean_value\n\nDescription\n-----------\n\nTests a value against a boolean value, where boolean_value can be TRUE, FALSE,\nor UNKNOWN.\n\nExamples\n--------\n\nSELECT 1 IS NOT UNKNOWN, 0 IS NOT UNKNOWN, NULL IS NOT UNKNOWN;\n+------------------+------------------+---------------------+\n| 1 IS NOT UNKNOWN | 0 IS NOT UNKNOWN | NULL IS NOT UNKNOWN |\n+------------------+------------------+---------------------+\n| 1 | 1 | 0 |\n+------------------+------------------+---------------------+\n\nSELECT NULL IS NOT TRUE, NULL IS NOT FALSE;\n+------------------+-------------------+\n| NULL IS NOT TRUE | NULL IS NOT FALSE |\n+------------------+-------------------+\n| 1 | 1 |\n+------------------+-------------------+\n\nURL: https://mariadb.com/kb/en/is-not/','','https://mariadb.com/kb/en/is-not/'); +insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (225,19,'IS NOT NULL','Syntax\n------\n\nIS NOT NULL\n\nDescription\n-----------\n\nTests whether a value is not NULL. See also NULL Values in MariaDB.\n\nExamples\n--------\n\nSELECT 1 IS NOT NULL, 0 IS NOT NULL, NULL IS NOT NULL;\n+---------------+---------------+------------------+\n| 1 IS NOT NULL | 0 IS NOT NULL | NULL IS NOT NULL |\n+---------------+---------------+------------------+\n| 1 | 1 | 0 |\n+---------------+---------------+------------------+\n\nURL: https://mariadb.com/kb/en/is-not-null/','','https://mariadb.com/kb/en/is-not-null/'); +insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (226,19,'IS NULL','Syntax\n------\n\nIS NULL\n\nDescription\n-----------\n\nTests whether a value is NULL. See also NULL Values in MariaDB.\n\nExamples\n--------\n\nSELECT 1 IS NULL, 0 IS NULL, NULL IS NULL;\n+-----------+-----------+--------------+\n| 1 IS NULL | 0 IS NULL | NULL IS NULL |\n+-----------+-----------+--------------+\n| 0 | 0 | 1 |\n+-----------+-----------+--------------+\n\nCompatibility\n-------------\n\nSome ODBC applications use the syntax auto_increment_field IS NOT NULL to find\nthe latest row that was inserted with an autogenerated key value. If your\napplications need this, you can set the sql_auto_is_null variable to 1.\n\nSET @@sql_auto_is_null=1;\nCREATE TABLE t1 (auto_increment_column INT NOT NULL AUTO_INCREMENT PRIMARY\nKEY);\nINSERT INTO t1 VALUES (NULL);\nSELECT * FROM t1 WHERE auto_increment_column IS NULL;\n\n+-----------------------+\n| auto_increment_column |\n+-----------------------+\n| 1 |\n+-----------------------+\n\nURL: https://mariadb.com/kb/en/is-null/','','https://mariadb.com/kb/en/is-null/'); +insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (227,19,'ISNULL','Syntax\n------\n\nISNULL(expr)\n\nDescription\n-----------\n\nIf expr is NULL, ISNULL() returns 1, otherwise it returns 0.\n\nSee also NULL Values in MariaDB.\n\nExamples\n--------\n\nSELECT ISNULL(1+1);\n+-------------+\n| ISNULL(1+1) |\n+-------------+\n| 0 |\n+-------------+\n\nSELECT ISNULL(1/0);\n+-------------+\n| ISNULL(1/0) |\n+-------------+\n| 1 |\n+-------------+\n\nURL: https://mariadb.com/kb/en/isnull/','','https://mariadb.com/kb/en/isnull/'); +insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (228,19,'LEAST','Syntax\n------\n\nLEAST(value1,value2,...)\n\nDescription\n-----------\n\nWith two or more arguments, returns the smallest (minimum-valued) argument.\nThe arguments are compared using the following rules:\n\n* If the return value is used in an INTEGER context or all arguments are\ninteger-valued, they are compared as integers.\n* If the return value is used in a REAL context or all arguments are\nreal-valued, they are compared as reals.\n* If any argument is a case-sensitive string, the arguments are compared as\ncase-sensitive strings.\n* In all other cases, the arguments are compared as case-insensitive strings.\n\nLEAST() returns NULL if any argument is NULL.\n\nExamples\n--------\n\nSELECT LEAST(2,0);\n+------------+\n| LEAST(2,0) |\n+------------+\n| 0 |\n+------------+\n\nSELECT LEAST(34.0,3.0,5.0,767.0);\n+---------------------------+\n| LEAST(34.0,3.0,5.0,767.0) |\n+---------------------------+\n| 3.0 |\n+---------------------------+\n\nSELECT LEAST(\'B\',\'A\',\'C\');\n+--------------------+\n| LEAST(\'B\',\'A\',\'C\') |\n+--------------------+\n| A |\n+--------------------+\n\nURL: https://mariadb.com/kb/en/least/','','https://mariadb.com/kb/en/least/'); +insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (229,19,'NOT BETWEEN','Syntax\n------\n\nexpr NOT BETWEEN min AND max\n\nDescription\n-----------\n\nThis is the same as NOT (expr BETWEEN min AND max).\n\nNote that the meaning of the alternative form NOT expr BETWEEN min AND max is\naffected by the HIGH_NOT_PRECEDENCE SQL_MODE flag.\n\nExamples\n--------\n\nSELECT 1 NOT BETWEEN 2 AND 3;\n+-----------------------+\n| 1 NOT BETWEEN 2 AND 3 |\n+-----------------------+\n| 1 |\n+-----------------------+\n\nSELECT \'b\' NOT BETWEEN \'a\' AND \'c\';\n+-----------------------------+\n| \'b\' NOT BETWEEN \'a\' AND \'c\' |\n+-----------------------------+\n| 0 |\n+-----------------------------+\n\nNULL:\n\nSELECT 1 NOT BETWEEN 1 AND NULL;\n+--------------------------+\n| 1 NOT BETWEEN 1 AND NULL |\n+--------------------------+\n| NULL |\n+--------------------------+\n\nURL: https://mariadb.com/kb/en/not-between/','','https://mariadb.com/kb/en/not-between/'); +insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (230,19,'NOT IN','Syntax\n------\n\nexpr NOT IN (value,...)\n\nDescription\n-----------\n\nThis is the same as NOT (expr IN (value,...)).\n\nExamples\n--------\n\nSELECT 2 NOT IN (0,3,5,7);\n+--------------------+\n| 2 NOT IN (0,3,5,7) |\n+--------------------+\n| 1 |\n+--------------------+\n\nSELECT \'wefwf\' NOT IN (\'wee\',\'wefwf\',\'weg\');\n+--------------------------------------+\n| \'wefwf\' NOT IN (\'wee\',\'wefwf\',\'weg\') |\n+--------------------------------------+\n| 0 |\n+--------------------------------------+\n\nSELECT 1 NOT IN (\'1\', \'2\', \'3\');\n+--------------------------+\n| 1 NOT IN (\'1\', \'2\', \'3\') |\n+--------------------------+\n| 0 |\n+--------------------------+\n\nNULL:\n\nSELECT NULL NOT IN (1, 2, 3);\n+-----------------------+\n| NULL NOT IN (1, 2, 3) |\n+-----------------------+\n| NULL |\n+-----------------------+\n\nSELECT 1 NOT IN (1, 2, NULL);\n+-----------------------+\n| 1 NOT IN (1, 2, NULL) |\n+-----------------------+\n| 0 |\n+-----------------------+\n\nSELECT 5 NOT IN (1, 2, NULL);\n+-----------------------+\n| 5 NOT IN (1, 2, NULL) |\n+-----------------------+\n| NULL |\n+-----------------------+\n\nURL: https://mariadb.com/kb/en/not-in/','','https://mariadb.com/kb/en/not-in/'); +insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (231,20,'&','Syntax\n------\n\n&\n\nDescription\n-----------\n\nBitwise AND. Converts the values to binary and compares bits. Only if both the\ncorresponding bits are 1 is the resulting bit also 1.\n\nSee also bitwise OR.\n\nExamples\n--------\n\nSELECT 2&1;\n+-----+\n| 2&1 |\n+-----+\n| 0 |\n+-----+\n\nSELECT 3&1;\n+-----+\n| 3&1 |\n+-----+\n| 1 |\n+-----+\n\nSELECT 29 & 15;\n+---------+\n| 29 & 15 |\n+---------+\n| 13 |\n+---------+\n\nURL: https://mariadb.com/kb/en/bitwise_and/','','https://mariadb.com/kb/en/bitwise_and/'); +insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (232,20,'<<','Syntax\n------\n\nvalue1 << value2\n\nDescription\n-----------\n\nConverts a longlong (BIGINT) number (value1) to binary and shifts value2 units\nto the left.\n\nExamples\n--------\n\nSELECT 1 << 2;\n+--------+\n| 1 << 2 |\n+--------+\n| 4 |\n+--------+\n\nURL: https://mariadb.com/kb/en/shift-left/','','https://mariadb.com/kb/en/shift-left/'); +insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (233,20,'>>','Syntax\n------\n\nvalue1 >> value2\n\nDescription\n-----------\n\nConverts a longlong (BIGINT) number (value1) to binary and shifts value2 units\nto the right.\n\nExamples\n--------\n\nSELECT 4 >> 2;\n+--------+\n| 4 >> 2 |\n+--------+\n| 1 |\n+--------+\n\nURL: https://mariadb.com/kb/en/shift-right/','','https://mariadb.com/kb/en/shift-right/'); +insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (234,20,'BIT_COUNT','Syntax\n------\n\nBIT_COUNT(N)\n\nDescription\n-----------\n\nReturns the number of bits that are set in the argument N.\n\nExamples\n--------\n\nSELECT BIT_COUNT(29), BIT_COUNT(b\'101010\');\n+---------------+----------------------+\n| BIT_COUNT(29) | BIT_COUNT(b\'101010\') |\n+---------------+----------------------+\n| 4 | 3 |\n+---------------+----------------------+\n\nURL: https://mariadb.com/kb/en/bit_count/','','https://mariadb.com/kb/en/bit_count/'); +insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (235,20,'^','Syntax\n------\n\n^\n\nDescription\n-----------\n\nBitwise XOR. Converts the values to binary and compares bits. If one (and only\none) of the corresponding bits is 1 is the resulting bit also 1.\n\nExamples\n--------\n\nSELECT 1 ^ 1;\n+-------+\n| 1 ^ 1 |\n+-------+\n| 0 |\n+-------+\n\nSELECT 1 ^ 0;\n+-------+\n| 1 ^ 0 |\n+-------+\n| 1 |\n+-------+\n\nSELECT 11 ^ 3;\n+--------+\n| 11 ^ 3 |\n+--------+\n| 8 |\n+--------+\n\nURL: https://mariadb.com/kb/en/bitwise-xor/','','https://mariadb.com/kb/en/bitwise-xor/'); +insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (236,20,'|','Syntax\n------\n\n|\n\nDescription\n-----------\n\nBitwise OR. Converts the values to binary and compares bits. If either of the\ncorresponding bits has a value of 1, the resulting bit is also 1.\n\nSee also bitwise AND.\n\nExamples\n--------\n\nSELECT 2|1;\n+-----+\n| 2|1 |\n+-----+\n| 3 |\n+-----+\n\nSELECT 29 | 15;\n+---------+\n| 29 | 15 |\n+---------+\n| 31 |\n+---------+\n\nURL: https://mariadb.com/kb/en/bitwise-or/','','https://mariadb.com/kb/en/bitwise-or/'); +insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (237,20,'~','Syntax\n------\n\n~\n\nDescription\n-----------\n\nBitwise NOT. Converts the value to 4 bytes binary and inverts all bits.\n\nExamples\n--------\n\nSELECT 3 & ~1;\n+--------+\n| 3 & ~1 |\n+--------+\n| 2 |\n+--------+\n\nSELECT 5 & ~1;\n+--------+\n| 5 & ~1 |\n+--------+\n| 4 |\n+--------+\n\nURL: https://mariadb.com/kb/en/bitwise-not/','','https://mariadb.com/kb/en/bitwise-not/'); +insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (238,20,'Parentheses','Parentheses are sometimes called precedence operators - this means that they\ncan be used to change the other operator\'s precedence in an expression. The\nexpressions that are written between parentheses are computed before the\nexpressions that are written outside. Parentheses must always contain an\nexpression (that is, they cannot be empty), and can be nested.\n\nFor example, the following expressions could return different results:\n\n* NOT a OR b\n* NOT (a OR b)\n\nIn the first case, NOT applies to a, so if a is FALSE or b is TRUE, the\nexpression returns TRUE. In the second case, NOT applies to the result of a OR\nb, so if at least one of a or b is TRUE, the expression is TRUE.\n\nWhen the precedence of operators is not intuitive, you can use parentheses to\nmake it immediately clear for whoever reads the statement.\n\nThe precedence of the NOT operator can also be affected by the\nHIGH_NOT_PRECEDENCE SQL_MODE flag.\n\nOther uses\n----------\n\nParentheses must always be used to enclose subqueries.\n\nParentheses can also be used in a JOIN statement between multiple tables to\ndetermine which tables must be joined first.\n\nAlso, parentheses are used to enclose the list of parameters to be passed to\nbuilt-in functions, user-defined functions and stored routines. However, when\nno parameter is passed to a stored procedure, parentheses are optional. For\nbuiltin functions and user-defined functions, spaces are not allowed between\nthe function name and the open parenthesis, unless the IGNORE_SPACE SQL_MODE\nis set. For stored routines (and for functions if IGNORE_SPACE is set) spaces\nare allowed before the open parenthesis, including tab characters and new line\ncharacters.\n\nSyntax errors\n-------------\n\nIf there are more open parentheses than closed parentheses, the error usually\nlooks like this:\n\nERROR 1064 (42000): You have an error in your SQL syntax; check the manual that\ncorresponds to your MariaDB server version for the right syntax to use near \'\'\na\nt line 1\n\nNote the empty string.\n\nIf there are more closed parentheses than open parentheses, the error usually\nlooks like this:\n\nERROR 1064 (42000): You have an error in your SQL syntax; check the manual that\ncorresponds to your MariaDB server version for the right syntax to use near \')\'\nat line 1\n\nNote the quoted closed parenthesis.\n\nURL: https://mariadb.com/kb/en/parentheses/','','https://mariadb.com/kb/en/parentheses/'); +insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (239,20,'TRUE FALSE','Description\n-----------\n\nThe constants TRUE and FALSE evaluate to 1 and 0, respectively. The constant\nnames can be written in any lettercase.\n\nExamples\n--------\n\nSELECT TRUE, true, FALSE, false;\n+------+------+-------+-------+\n| TRUE | TRUE | FALSE | FALSE |\n+------+------+-------+-------+\n| 1 | 1 | 0 | 0 |\n+------+------+-------+-------+\n\nURL: https://mariadb.com/kb/en/true-false/','','https://mariadb.com/kb/en/true-false/'); +insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (240,21,'ANALYZE TABLE','Syntax\n------\n\nANALYZE [NO_WRITE_TO_BINLOG | LOCAL] TABLE tbl_name [,tbl_name ...] \n [PERSISTENT FOR [ALL|COLUMNS ([col_name [,col_name ...]])]\n [INDEXES ([index_name [,index_name ...]])]]\n\nDescription\n-----------\n\nANALYZE TABLE analyzes and stores the key distribution for a table (index\nstatistics). This statement works with MyISAM, Aria and InnoDB tables. During\nthe analysis, InnoDB will allow reads/writes, and MyISAM/Aria reads/inserts.\nFor MyISAM tables, this statement is equivalent to using myisamchk --analyze.\n\nFor more information on how the analysis works within InnoDB, see InnoDB\nLimitations.\n\nMariaDB uses the stored key distribution to decide the order in which tables\nshould be joined when you perform a join on something other than a constant.\nIn addition, key distributions can be used when deciding which indexes to use\nfor a specific table within a query.\n\nThis statement requires SELECT and INSERT privileges for the table.\n\nBy default, ANALYZE TABLE statements are written to the binary log and will be\nreplicated. The NO_WRITE_TO_BINLOG keyword (LOCAL is an alias) will ensure the\nstatement is not written to the binary log.\n\nFrom MariaDB 10.3.19, ANALYZE TABLE statements are not logged to the binary\nlog if read_only is set. See also Read-Only Replicas.\n\nANALYZE TABLE is also supported for partitioned tables. You can use ALTER\nTABLE ... ANALYZE PARTITION to analyze one or more partitions.\n\nThe Aria storage engine supports progress reporting for the ANALYZE TABLE\nstatement.\n\nEngine-Independent Statistics\n-----------------------------\n\nANALYZE TABLE supports engine-independent statistics. See Engine-Independent\nTable Statistics: Collecting Statistics with the ANALYZE TABLE Statement for\nmore information.\n\nURL: https://mariadb.com/kb/en/analyze-table/','','https://mariadb.com/kb/en/analyze-table/'); +insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (241,21,'CHECK TABLE','Syntax\n------\n\nCHECK TABLE tbl_name [, tbl_name] ... [option] ...\n\noption = {FOR UPGRADE | QUICK | FAST | MEDIUM | EXTENDED | CHANGED}\n\nDescription\n-----------\n\nCHECK TABLE checks a table or tables for errors. CHECK TABLE works for\nArchive, Aria, CSV, InnoDB, and MyISAM tables. For Aria and MyISAM tables, the\nkey statistics are updated as well. For CSV, see also Checking and Repairing\nCSV Tables.\n\nAs an alternative, myisamchk is a commandline tool for checking MyISAM tables\nwhen the tables are not being accessed.\n\nFor checking dynamic columns integrity, COLUMN_CHECK() can be used.\n\nCHECK TABLE can also check views for problems, such as tables that are\nreferenced in the view definition that no longer exist.\n\nCHECK TABLE is also supported for partitioned tables. You can use ALTER TABLE\n... CHECK PARTITION to check one or more partitions.\n\nThe meaning of the different options are as follows - note that this can vary\na bit between storage engines:\n\n+-----+----------------------------------------------------------------------+\n| FOR | Do a very quick check if the storage format for the table has |\n| UPG | changed so that one needs to do a REPAIR. This is only needed when |\n| ADE | one upgrades between major versions of MariaDB or MySQL. This is |\n| | usually done by running mysql_upgrade. |\n+-----+----------------------------------------------------------------------+\n| FAS | Only check tables that has not been closed properly or are marked |\n| | as corrupt. Only supported by the MyISAM and Aria engines. For |\n| | other engines the table is checked normally |\n+-----+----------------------------------------------------------------------+\n| CHA | Check only tables that has changed since last REPAIR / CHECK. Only |\n| GED | supported by the MyISAM and Aria engines. For other engines the |\n| | table is checked normally. |\n+-----+----------------------------------------------------------------------+\n| QUI | Do a fast check. For MyISAM and Aria engine this means we skip |\n| K | checking the delete link chain which may take some time. |\n+-----+----------------------------------------------------------------------+\n| MED | Scan also the data files. Checks integrity between data and index |\n| UM | files with checksums. In most cases this should find all possible |\n| | errors. |\n+-----+----------------------------------------------------------------------+\n| EXT | Does a full check to verify every possible error. For MyISAM and |\n| NDE | Aria we verify for each row that all it keys exists and points to |\n| | the row. This may take a long time on big tables! |\n+-----+----------------------------------------------------------------------+\n\nFor most cases running CHECK TABLE without options or MEDIUM should be good\nenough.\n\nThe Aria storage engine supports progress reporting for this statement.\n\nIf you want to know if two tables are identical, take a look at CHECKSUM TABLE.\n\nInnoDB\n------\n\nIf CHECK TABLE finds an error in an InnoDB table, MariaDB might shutdown to\nprevent the error propagation. In this case, the problem will be reported in\nthe error log. Otherwise the table or an index might be marked as corrupted,\nto prevent use. This does not happen with some minor problems, like a wrong\nnumber of entries in a secondary index. Those problems are reported in the\noutput of CHECK TABLE.\n\nEach tablespace contains a header with metadata. This header is not checked by\nthis statement.\n\nDuring the execution of CHECK TABLE, other threads may be blocked.\n\nURL: https://mariadb.com/kb/en/check-table/','','https://mariadb.com/kb/en/check-table/'); +insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (242,21,'CHECK VIEW','Syntax\n------\n\nCHECK VIEW view_name\n\nDescription\n-----------\n\nThe CHECK VIEW statement was introduced in MariaDB 10.0.18 to assist with\nfixing MDEV-6916, an issue introduced in MariaDB 5.2 where the view algorithms\nwere swapped. It checks whether the view algorithm is correct. It is run as\npart of mysql_upgrade, and should not normally be required in regular use.\n\nURL: https://mariadb.com/kb/en/check-view/','','https://mariadb.com/kb/en/check-view/'); +insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (243,21,'CHECKSUM TABLE','Syntax\n------\n\nCHECKSUM TABLE tbl_name [, tbl_name] ... [ QUICK | EXTENDED ]\n\nDescription\n-----------\n\nCHECKSUM TABLE reports a table checksum. This is very useful if you want to\nknow if two tables are the same (for example on a master and slave).\n\nWith QUICK, the live table checksum is reported if it is available, or NULL\notherwise. This is very fast. A live checksum is enabled by specifying the\nCHECKSUM=1 table option when you create the table; currently, this is\nsupported only for Aria and MyISAM tables.\n\nWith EXTENDED, the entire table is read row by row and the checksum is\ncalculated. This can be very slow for large tables.\n\nIf neither QUICK nor EXTENDED is specified, MariaDB returns a live checksum if\nthe table storage engine supports it and scans the table otherwise.\n\nCHECKSUM TABLE requires the SELECT privilege for the table.\n\nFor a nonexistent table, CHECKSUM TABLE returns NULL and generates a warning.\n\nThe table row format affects the checksum value. If the row format changes,\nthe checksum will change. This means that when a table created with a\nMariaDB/MySQL version is upgraded to another version, the checksum value will\nprobably change.\n\nTwo identical tables should always match to the same checksum value; however,\nalso for non-identical tables there is a very slight chance that they will\nreturn the same value as the hashing algorithm is not completely\ncollision-free.\n\nDifferences Between MariaDB and MySQL\n-------------------------------------\n\nCHECKSUM TABLE may give a different result as MariaDB doesn\'t ignore NULLs in\nthe columns as MySQL 5.1 does (Later MySQL versions should calculate checksums\nthe same way as MariaDB). You can get the \'old style\' checksum in MariaDB by\nstarting mysqld with the --old option. Note however that that the MyISAM and\nAria storage engines in MariaDB are using the new checksum internally, so if\nyou are using --old, the CHECKSUM command will be slower as it needs to\ncalculate the checksum row by row. Starting from MariaDB Server 10.9, --old is\ndeprecated and will be removed in a future release. Set --old-mode or OLD_MODE\nto COMPAT_5_1_CHECKSUM to get \'old style\' checksum.\n\nURL: https://mariadb.com/kb/en/checksum-table/','','https://mariadb.com/kb/en/checksum-table/'); +insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (244,21,'OPTIMIZE TABLE','Syntax\n------\n\nOPTIMIZE [NO_WRITE_TO_BINLOG | LOCAL] TABLE\n tbl_name [, tbl_name] ...\n [WAIT n | NOWAIT]\n\nDescription\n-----------\n\nOPTIMIZE TABLE has two main functions. It can either be used to defragment\ntables, or to update the InnoDB fulltext index.\n\nMariaDB starting with 10.3.0\n----------------------------\n\nWAIT/NOWAIT\n-----------\n\nSet the lock wait timeout. See WAIT and NOWAIT.\n\nDefragmenting\n-------------\n\nOPTIMIZE TABLE works for InnoDB (before MariaDB 10.1.1, only if the\ninnodb_file_per_table server system variable is set), Aria, MyISAM and ARCHIVE\ntables, and should be used if you have deleted a large part of a table or if\nyou have made many changes to a table with variable-length rows (tables that\nhave VARCHAR, VARBINARY, BLOB, or TEXT columns). Deleted rows are maintained\nin a linked list and subsequent INSERT operations reuse old row positions.\n\nThis statement requires SELECT and INSERT privileges for the table.\n\nBy default, OPTIMIZE TABLE statements are written to the binary log and will\nbe replicated. The NO_WRITE_TO_BINLOG keyword (LOCAL is an alias) will ensure\nthe statement is not written to the binary log.\n\nFrom MariaDB 10.3.19, OPTIMIZE TABLE statements are not logged to the binary\nlog if read_only is set. See also Read-Only Replicas.\n\nOPTIMIZE TABLE is also supported for partitioned tables. You can use ALTER\nTABLE ... OPTIMIZE PARTITION to optimize one or more partitions.\n\nYou can use OPTIMIZE TABLE to reclaim the unused space and to defragment the\ndata file. With other storage engines, OPTIMIZE TABLE does nothing by default,\nand returns this message: \" The storage engine for the table doesn\'t support\noptimize\". However, if the server has been started with the --skip-new option,\nOPTIMIZE TABLE is linked to ALTER TABLE, and recreates the table. This\noperation frees the unused space and updates index statistics.\n\nThe Aria storage engine supports progress reporting for this statement.\n\nIf a MyISAM table is fragmented, concurrent inserts will not be performed\nuntil an OPTIMIZE TABLE statement is executed on that table, unless the\nconcurrent_insert server system variable is set to ALWAYS.\n\nUpdating an InnoDB fulltext index\n---------------------------------\n\nWhen rows are added or deleted to an InnoDB fulltext index, the index is not\nimmediately re-organized, as this can be an expensive operation. Change\nstatistics are stored in a separate location . The fulltext index is only\nfully re-organized when an OPTIMIZE TABLE statement is run.\n\nBy default, an OPTIMIZE TABLE will defragment a table. In order to use it to\nupdate fulltext index statistics, the innodb_optimize_fulltext_only system\nvariable must be set to 1. This is intended to be a temporary setting, and\nshould be reset to 0 once the fulltext index has been re-organized.\n\nSince fulltext re-organization can take a long time, the\ninnodb_ft_num_word_optimize variable limits the re-organization to a number of\nwords (2000 by default). You can run multiple OPTIMIZE statements to fully\nre-organize the index.\n\nDefragmenting InnoDB tablespaces\n--------------------------------\n\nMariaDB 10.1.1 merged the Facebook/Kakao defragmentation patch, allowing one\nto use OPTIMIZE TABLE to defragment InnoDB tablespaces. For this functionality\nto be enabled, the innodb_defragment system variable must be enabled. No new\ntables are created and there is no need to copy data from old tables to new\ntables. Instead, this feature loads n pages (determined by\ninnodb-defragment-n-pages) and tries to move records so that pages would be\nfull of records and then frees pages that are fully empty after the operation.\nNote that tablespace files (including ibdata1) will not shrink as the result\nof defragmentation, but one will get better memory utilization in the InnoDB\nbuffer pool as there are fewer data pages in use.\n\nSee Defragmenting InnoDB Tablespaces for more details.\n\nURL: https://mariadb.com/kb/en/optimize-table/','','https://mariadb.com/kb/en/optimize-table/'); +insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (245,21,'REPAIR TABLE','Syntax\n------\n\nREPAIR [NO_WRITE_TO_BINLOG | LOCAL] TABLE\n tbl_name [, tbl_name] ...\n [QUICK] [EXTENDED] [USE_FRM]\n\nDescription\n-----------\n\nREPAIR TABLE repairs a possibly corrupted table. By default, it has the same\neffect as\n\nmyisamchk --recover tbl_name\n\nor\n\naria_chk --recover tbl_name\n\nSee aria_chk and myisamchk for more.\n\nREPAIR TABLE works for Archive, Aria, CSV and MyISAM tables. For InnoDB, see\nrecovery modes. For CSV, see also Checking and Repairing CSV Tables. For\nArchive, this statement also improves compression. If the storage engine does\nnot support this statement, a warning is issued.\n\nThis statement requires SELECT and INSERT privileges for the table.\n\nBy default, REPAIR TABLE statements are written to the binary log and will be\nreplicated. The NO_WRITE_TO_BINLOG keyword (LOCAL is an alias) will ensure the\nstatement is not written to the binary log.\n\nFrom MariaDB 10.3.19, REPAIR TABLE statements are not logged to the binary log\nif read_only is set. See also Read-Only Replicas.\n\nWhen an index is recreated, the storage engine may use a configurable buffer\nin the process. Incrementing the buffer speeds up the index creation. Aria and\nMyISAM allocate a buffer whose size is defined by aria_sort_buffer_size or\nmyisam_sort_buffer_size, also used for ALTER TABLE.\n\nREPAIR TABLE is also supported for partitioned tables. However, the USE_FRM\noption cannot be used with this statement on a partitioned table.\n\nALTER TABLE ... REPAIR PARTITION can be used to repair one or more partitions.\n\nThe Aria storage engine supports progress reporting for this statement.\n\nURL: https://mariadb.com/kb/en/repair-table/','','https://mariadb.com/kb/en/repair-table/'); +insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (246,21,'REPAIR VIEW','Syntax\n------\n\nREPAIR [NO_WRITE_TO_BINLOG | LOCAL] VIEW view_name[, view_name] ... [FROM\nMYSQL]\n\nDescription\n-----------\n\nThe REPAIR VIEW statement was introduced to assist with fixing MDEV-6916, an\nissue introduced in MariaDB 5.2 where the view algorithms were swapped\ncompared to their MySQL on disk representation. It checks whether the view\nalgorithm is correct. It is run as part of mysql_upgrade, and should not\nnormally be required in regular use.\n\nBy default it corrects the checksum and if necessary adds the mariadb-version\nfield. If the optional FROM MYSQL clause is used, and no mariadb-version field\nis present, the MERGE and TEMPTABLE algorithms are toggled.\n\nBy default, REPAIR VIEW statements are written to the binary log and will be\nreplicated. The NO_WRITE_TO_BINLOG keyword (LOCAL is an alias) will ensure the\nstatement is not written to the binary log.\n\nURL: https://mariadb.com/kb/en/repair-view/','','https://mariadb.com/kb/en/repair-view/'); +insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (247,22,'mysql.func Table','The mysql.func table stores information about user-defined functions (UDFs)\ncreated with the CREATE FUNCTION UDF statement.\n\nMariaDB starting with 10.4\n--------------------------\nIn MariaDB 10.4 and later, this table uses the Aria storage engine.\n\nMariaDB until 10.3\n------------------\nIn MariaDB 10.3 and before, this table uses the MyISAM storage engine.\n\nThe mysql.func table contains the following fields:\n\n+----------+---------+---------+-------+--------------+---------------------+\n| Field | Type | Null | Key | Default | Description |\n+----------+---------+---------+-------+--------------+---------------------+\n| name | char(64 | NO | PRI | | UDF name |\n| | | | | | |\n+----------+---------+---------+-------+--------------+---------------------+\n| ret | tinyint | NO | | 0 | |\n| | 1) | | | | |\n+----------+---------+---------+-------+--------------+---------------------+\n| dl | char(12 | NO | | | Shared library name |\n| | ) | | | | |\n+----------+---------+---------+-------+--------------+---------------------+\n| type | enum(\'f | NO | | NULL | Type, either |\n| | nction\' | | | | function or |\n| | \'aggreg | | | | aggregate. |\n| | te\') | | | | Aggregate |\n| | | | | | functions are |\n| | | | | | summary functions |\n| | | | | | such as SUM() and |\n| | | | | | AVG(). |\n+----------+---------+---------+-------+--------------+---------------------+\n\nExample\n-------\n\nSELECT * FROM mysql.func;\n+------------------------------+-----+--------------+-----------+\n| name | ret | dl | type |\n+------------------------------+-----+--------------+-----------+\n| spider_direct_sql | 2 | ha_spider.so | function |\n| spider_bg_direct_sql | 2 | ha_spider.so | aggregate |\n| spider_ping_table | 2 | ha_spider.so | function |\n| spider_copy_tables | 2 | ha_spider.so | function |\n| spider_flush_table_mon_cache | 2 | ha_spider.so | function |\n+------------------------------+-----+--------------+-----------+\n\nURL: https://mariadb.com/kb/en/mysqlfunc-table/','','https://mariadb.com/kb/en/mysqlfunc-table/'); +insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (248,22,'CREATE FUNCTION UDF','Syntax\n------\n\nCREATE [OR REPLACE] [AGGREGATE] FUNCTION [IF NOT EXISTS] function_name\n RETURNS {STRING|INTEGER|REAL|DECIMAL}\n SONAME shared_library_name\n\nDescription\n-----------\n\nA user-defined function (UDF) is a way to extend MariaDB with a new function\nthat works like a native (built-in) MariaDB function such as ABS() or CONCAT().\n\nfunction_name is the name that should be used in SQL statements to invoke the\nfunction.\n\nTo create a function, you must have the INSERT privilege for the mysql\ndatabase. This is necessary becauseCREATE FUNCTION adds a row to the\nmysql.func system table that records the function\'s name, type, and shared\nlibrary name. If you do not have this table, you should run the mysql_upgrade\ncommand to create it.\n\nUDFs need to be written in C, C++ or another language that uses C calling\nconventions, MariaDB needs to have been dynamically compiled, and your\noperating system must support dynamic loading.\n\nFor an example, see sql/udf_example.cc in the source tree. For a collection of\nexisting UDFs see http://www.mysqludf.org/.\n\nStatements making use of user-defined functions are not safe for replication.\n\nFor creating a stored function as opposed to a user-defined function, see\nCREATE FUNCTION.\n\nFor valid identifiers to use as function names, see Identifier Names.\n\nRETURNS\n-------\n\nThe RETURNS clause indicates the type of the function\'s return value, and can\nbe one of STRING, INTEGER, REAL or DECIMAL. DECIMAL functions currently return\nstring values and should be written like STRING functions.\n\nshared_library_name\n-------------------\n\nshared_library_name is the basename of the shared object file that contains\nthe code that implements the function. The file must be located in the plugin\ndirectory. This directory is given by the value of the plugin_dir system\nvariable. Note that before MariaDB/MySQL 5.1, the shared object could be\nlocated in any directory that was searched by your system\'s dynamic linker.\n\nAGGREGATE\n---------\n\nAggregate functions are summary functions such as SUM() and AVG().\n\nMariaDB starting with 10.4\n--------------------------\nAggregate UDF functions can be used as window functions.\n\nOR REPLACE\n----------\n\nMariaDB starting with 10.1.3\n----------------------------\nThe OR REPLACE clause was added in MariaDB 10.1.3\n\nIf the optional OR REPLACE clause is used, it acts as a shortcut for:\n\nDROP FUNCTION IF EXISTS function_name;\nCREATE FUNCTION name ...;\n\nIF NOT EXISTS\n-------------\n\nMariaDB starting with 10.1.3\n----------------------------\nThe IF NOT EXISTS clause was added in MariaDB 10.1.3\n\nWhen the IF NOT EXISTS clause is used, MariaDB will return a warning instead\nof an error if the specified function already exists. Cannot be used together\nwith OR REPLACE.\n\nUpgrading a UDF\n---------------\n\nTo upgrade the UDF\'s shared library, first run a DROP FUNCTION statement, then\nupgrade the shared library and finally run the CREATE FUNCTION statement. If\nyou upgrade without following this process, you may crash the server.\n\nExamples\n--------\n\nCREATE FUNCTION jsoncontains_path RETURNS integer SONAME \'ha_connect.so\';\nQuery OK, 0 rows affected (0.00 sec)\n\nOR REPLACE and IF NOT EXISTS:\n\nCREATE FUNCTION jsoncontains_path RETURNS integer SONAME \'ha_connect.so\';\nERROR 1125 (HY000): Function \'jsoncontains_path\' already exists\n\nCREATE OR REPLACE FUNCTION jsoncontains_path RETURNS integer SONAME\n\'ha_connect.so\';\nQuery OK, 0 rows affected (0.00 sec)\n\nCREATE FUNCTION IF NOT EXISTS jsoncontains_path RETURNS integer SONAME\n\'ha_connect.so\';\nQuery OK, 0 rows affected, 1 warning (0.00 sec)\n\nSHOW WARNINGS;\n+-------+------+---------------------------------------------+\n| Level | Code | Message |\n+-------+------+---------------------------------------------+\n| Note | 1125 | Function \'jsoncontains_path\' already exists |\n+-------+------+---------------------------------------------+\n\nURL: https://mariadb.com/kb/en/create-function-udf/','','https://mariadb.com/kb/en/create-function-udf/'); +insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (249,22,'DROP FUNCTION UDF','Syntax\n------\n\nDROP FUNCTION [IF EXISTS] function_name\n\nDescription\n-----------\n\nThis statement drops the user-defined function (UDF) named function_name.\n\nTo drop a function, you must have the DELETE privilege for the mysql database.\nThis is because DROP FUNCTION removes the row from the mysql.func system table\nthat records the function\'s name, type and shared library name.\n\nFor dropping a stored function, see DROP FUNCTION.\n\nUpgrading a UDF\n---------------\n\nTo upgrade the UDF\'s shared library, first run a DROP FUNCTION statement, then\nupgrade the shared library and finally run the CREATE FUNCTION statement. If\nyou upgrade without following this process, you may crash the server.\n\nExamples\n--------\n\nDROP FUNCTION jsoncontains_path;\n\nIF EXISTS:\n\nDROP FUNCTION jsoncontains_path;\nERROR 1305 (42000): FUNCTION test.jsoncontains_path does not exist\n\nDROP FUNCTION IF EXISTS jsoncontains_path;\nQuery OK, 0 rows affected, 1 warning (0.00 sec)\n\nSHOW WARNINGS;\n+-------+------+------------------------------------------------+\n| Level | Code | Message |\n+-------+------+------------------------------------------------+\n| Note | 1305 | FUNCTION test.jsoncontains_path does not exist |\n+-------+------+------------------------------------------------+\n\nURL: https://mariadb.com/kb/en/drop-function-udf/','','https://mariadb.com/kb/en/drop-function-udf/'); +insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (250,22,'Creating User-Defined Functions','User-defined functions allow MariaDB to be extended with a new function that\nworks like a native (built-in) MariaDB function such as ABS() or CONCAT().\nThere are alternative ways to add a new function: writing a native function\n(which requires modifying and compiling the server source code), or writing a\nstored function.\n\nStatements making use of user-defined functions are not safe for replication.\n\nFunctions are written in C or C++, and to make use of them, the operating\nsystem must support dynamic loading.\n\nEach new SQL function requires corresponding functions written in C/C++. In\nthe list below, at least the main function - x() - and one other, are\nrequired. x should be replaced by the name of the function you are creating.\n\nAll functions need to be thread-safe, so not global or static variables that\nchange can be allocated. Memory is allocated in x_init()/ and freed in\nx_deinit().\n\nSimple Functions\n----------------\n\nx()\n---\n\nRequired for all UDFs; this is where the results are calculated.\n\n+------------------------------------------+----------------------------------+\n| C/C++ type | SQL type |\n+------------------------------------------+----------------------------------+\n| char * | STRING |\n+------------------------------------------+----------------------------------+\n| long long | INTEGER |\n+------------------------------------------+----------------------------------+\n| double | REAL |\n+------------------------------------------+----------------------------------+\n\nDECIMAL functions return string values, and so should be written accordingly.\nIt is not possible to create ROW functions.\n\nx_init()\n--------\n\nInitialization function for x(). Can be used for the following:\n\n* Check the number of arguments to X() (the SQL equivalent).\n* Verify the argument types, or to force arguments to be of a particular type\nafter the function is called.\n* Specify whether the result can be NULL.\n* Specify the maximum result length.\n* For REAL functions, specify the maximum number of decimals for the result.\n* Allocate any required memory.\n\nx_deinit()\n----------\n\nDe-initialization function for x(). Used to de-allocate memory that was\nallocated in x_init().\n\nDescription\n-----------\n\nEach time the SQL function X() is called:\n\n* MariaDB will first call the C/C++ initialization function, x_init(),\nassuming it exists. All setup will be performed, and if it returns an error,\nthe SQL statement is aborted and no further functions are called.\n* If there is no x_init() function, or it has been called and did not return\nan error, x() is then called once per row.\n* After all rows have finished processing, x_deinit() is called, if present,\nto clean up by de-allocating any memory that was allocated in x_init().\n* See User-defined Functions Calling Sequences for more details on the\nfunctions.\n\nAggregate Functions\n-------------------\n\nThe following functions are required for aggregate functions, such as AVG()\nand SUM(). When using CREATE FUNCTION, the AGGREGATE keyword is required.\n\nx_clear()\n---------\n\nUsed to reset the current aggregate, but without inserting the argument as the\ninitial aggregate value for the new group.\n\nx_add()\n-------\n\nUsed to add the argument to the current aggregate.\n\nx_remove()\n----------\n\nStarting from MariaDB 10.4, improves the support of window functions (so it is\nnot obligatory to add it) and should remove the argument from the current\naggregate.\n\nDescription\n-----------\n\nEach time the aggregate SQL function X() is called:\n\n* MariaDB will first call the C/C++ initialization function, x_init(),\nassuming it exists. All setup will be performed, and if it returns an error,\nthe SQL statement is aborted and no further functions are called.\n* If there is no x_init() function, or it has been called and did not return\nan error, x() is then called once per row.\n* After all rows have finished processing, x_deinit() is called, if present,\nto clean up by de-allocating any memory that was allocated in x_init().\n\n* MariaDB will first call the C/C++ initialization function, x_init(),\nassuming it exists. All setup will be performed, and if it returns an error,\nthe SQL statement is aborted and no further functions are called.\n* The table is sorted according to the GROUP BY expression.\n* x_clear() is called for the first row of each new group.\n* x_add() is called once per row for each row in the same group.\n* x() is called when the group changes, or after the last row, to get the\naggregate result. \n* The latter three steps are repeated until all rows have been processed.\n* After all rows have finished processing, x_deinit() is called, if present,\nto clean up by de-allocating any memory that was allocated in x_init().\n\nExamples\n--------\n\nFor an example, see sql/udf_example.cc in the source tree. For a collection of\nexisting UDFs see https://github.com/mysqludf.\n\nURL: https://mariadb.com/kb/en/creating-user-defined-functions/','','https://mariadb.com/kb/en/creating-user-defined-functions/'); +insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (251,22,'User-Defined Functions Calling Sequences','The functions described in Creating User-defined Functions are expanded on\nthis page. They are declared as follows:\n\nSimple Functions\n----------------\n\nx()\n---\n\nIf x() returns an integer, it is declared as follows:\n\nlong long x(UDF_INIT *initid, UDF_ARGS *args,\n char *is_null, char *error);\n\nIf x() returns a string (DECIMAL functions also return string values), it is\ndeclared as follows:\n\nchar *x(UDF_INIT *initid, UDF_ARGS *args,\n char *result, unsigned long *length,\n char *is_null, char *error);\n\nIf x() returns a real, it is declared as follows:\n\ndouble x(UDF_INIT *initid, UDF_ARGS *args,\n char *is_null, char *error);\n\nx_init()\n--------\n\nmy_bool x_init(UDF_INIT *initid, UDF_ARGS *args, char *message);\n\nx_deinit()\n----------\n\nvoid x_deinit(UDF_INIT *initid);\n\nDescription\n-----------\n\ninitid is a parameter passed to all three functions that points to a UDF_INIT\nstructure, used for communicating information between the functions. Its\nstructure members are:\n\n* my_bool maybe_null\nmaybe_null should be set to 1 if x_init can return a NULL value, Defaults to 1\nif any arguments are declared maybe_null.\n\n* unsigned int decimals\nNumber of decimals after the decimal point. The default, if an explicit number\nof decimals is passed in the arguments to the main function, is the maximum\nnumber of decimals, so if 9.5, 9.55 and 9.555 are passed to the function, the\ndefault would be three (based on 9.555, the maximum). If there are no\nexplicit number of decimals, the default is set to 31, or one more than the\nmaximum for the DOUBLE, FLOAT and DECIMAL types. This default can be changed\nin the function to suit the actual calculation.\n\n* unsigned int max_length\nMaximum length of the result. For integers, the default is 21. For strings,\nthe length of the longest argument. For reals, the default is 13 plus the\nnumber of decimals indicated by initid->decimals. The length includes any\nsigns or decimal points. Can also be set to 65KB or 16MB in order to return a\nBLOB. The memory remains unallocated, but this is used to decide on the data\ntype to use if the data needs to be temporarily stored.\n\n* char *ptr\nA pointer for use as required by the function. Commonly, initid->ptr is used\nto communicate allocated memory, with x_init() allocating the memory and\nassigning it to this pointer, x() using it, and x_deinit() de-allocating it.\n\n* my_bool const_item\nShould be set to 1 in x_init() if x() always returns the same value, otherwise\n0.\n\nAggregate Functions\n-------------------\n\nx_clear()\n---------\n\nx_clear() is a required function for aggregate functions, and is declared as\nfollows:\n\nvoid x_clear(UDF_INIT *initid, char *is_null, char *error);\n\nIt is called when the summary results need to be reset, that is at the\nbeginning of each new group. but also to reset the values when there were no\nmatching rows.\n\nis_null is set to point to CHAR(0) before calling x_clear().\n\nIn the case of an error, you can store the value to which the error argument\npoints (a single-byte variable, not a string string buffer) in the variable.\n\nx_reset()\n---------\n\nx_reset() is declared as follows:\n\nvoid x_reset(UDF_INIT *initid, UDF_ARGS *args,\n char *is_null, char *error);\n\nIt is called on finding the first row in a new group. Should reset the summary\nvariables, and then use UDF_ARGS as the first value in the group\'s internal\nsummary value. The function is not required if the UDF interface uses\nx_clear().\n\nx_add()\n-------\n\nx_add() is declared as follows:\n\nvoid x_add(UDF_INIT *initid, UDF_ARGS *args,\n char *is_null, char *error);\n\nIt is called for all rows belonging to the same group, and should be used to\nadd the value in UDF_ARGS to the internal summary variable.\n\nx_remove()\n----------\n\nx_remove() was added in MariaDB 10.4 and is declared as follows (same as\nx_add()):\n\nvoid x_remove(UDF_INIT* initid, UDF_ARGS* args,\n char* is_null, char *error );\n\nIt adds more efficient support of aggregate UDFs as window functions.\nx_remove() should \"subtract\" the row (reverse x_add()). In MariaDB 10.4\naggregate UDFs will work as WINDOW functions without x_remove() but it will\nnot be so efficient.\n\nIf x_remove() supported (defined) detected automatically.\n\nURL: https://mariadb.com/kb/en/user-defined-functions-calling-sequences/','','https://mariadb.com/kb/en/user-defined-functions-calling-sequences/'); +insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (252,22,'User-Defined Functions Security','The MariaDB server imposes a number of limitations on user-defined functions\nfor security purposes.\n\n* The INSERT privilege for the mysql database is required to run CREATE\nFUNCTION, as a record will be added to the mysql.func-table.\n* The DELETE privilege for the mysql database is required to run DROP FUNCTION\nas the corresponding record will be removed from the mysql.func-table.\n* UDF object files can only be placed in the plugin directory, as specified by\nthe value of the plugin_dir system variable.\n* At least one symbol, beyond the required x() - corresponding to an SQL\nfunction X()) - is required. These can be x_init(), x_deinit(), xxx_reset(),\nx_clear() and x_add() functions (see Creating User-defined Functions). The\nallow-suspicious-udfs mysqld option (by default unset) provides a workaround,\npermitting only one symbol to be used. This is not recommended, as it opens\nthe possibility of loading shared objects that are not legitimate user-defined\nfunctions.\n\nURL: https://mariadb.com/kb/en/user-defined-functions-security/','','https://mariadb.com/kb/en/user-defined-functions-security/'); +insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (253,23,'Numeric Data Type Overview','There are a number of numeric data types:\n\n* TINYINT\n* BOOLEAN - Synonym for TINYINT(1)\n* INT1 - Synonym for TINYINT\n* SMALLINT\n* INT2 - Synonym for SMALLINT\n* MEDIUMINT\n* INT3 - Synonym for MEDIUMINT\n* INT, INTEGER\n* INT4 - Synonym for INT\n* BIGINT\n* INT8 - Synonym for BIGINT\n* DECIMAL, DEC, NUMERIC, FIXED\n* FLOAT\n* DOUBLE, DOUBLE PRECISION, REAL\n* BIT\n\nSee the specific articles for detailed information on each.\n\nSIGNED, UNSIGNED and ZEROFILL\n-----------------------------\n\nMost numeric types can be defined as SIGNED, UNSIGNED or ZEROFILL, for example:\n\nTINYINT[(M)] [SIGNED | UNSIGNED | ZEROFILL]\n\nIf SIGNED, or no attribute, is specified, a portion of the numeric type will\nbe reserved for the sign (plus or minus). For example, a TINYINT SIGNED can\nrange from -128 to 127.\n\nIf UNSIGNED is specified, no portion of the numeric type is reserved for the\nsign, so for integer types range can be larger. For example, a TINYINT\nUNSIGNED can range from 0 to 255. Floating point and fixed-point types also\ncan be UNSIGNED, but this only prevents negative values from being stored and\ndoesn\'t alter the range.\n\nIf ZEROFILL is specified, the column will be set to UNSIGNED and the spaces\nused by default to pad the field are replaced with zeros. ZEROFILL is ignored\nin expressions or as part of a UNION. ZEROFILL is a non-standard MySQL and\nMariaDB enhancement.\n\nNote that although the preferred syntax indicates that the attributes are\nexclusive, more than one attribute can be specified.\n\nUntil MariaDB 10.2.7 (MDEV-8659), any combination of the attributes could be\nused in any order, with duplicates. In this case:\n\n* the presence of ZEROFILL makes the column UNSIGNED ZEROFILL.\n* the presence of UNSIGNED makes the column UNSIGNED.\n\nFrom MariaDB 10.2.8, only the following combinations are supported:\n\n* SIGNED\n* UNSIGNED\n* ZEROFILL\n* UNSIGNED ZEROFILL\n* ZEROFILL UNSIGNED\n\nThe latter two should be replaced with simply ZEROFILL, but are still accepted\nby the parser.\n\nExamples\n--------\n\nCREATE TABLE zf (\n i1 TINYINT SIGNED,\n i2 TINYINT UNSIGNED,\n i3 TINYINT ZEROFILL\n);\n\nINSERT INTO zf VALUES (2,2,2);\n\nSELECT * FROM zf;\n+------+------+------+\n| i1 | i2 | i3 |\n+------+------+------+\n| 2 | 2 | 002 |\n+------+------+------+\n\nRange\n-----\n\nWhen attempting to add a value that is out of the valid range for the numeric\ntype, MariaDB will react depending on the strict SQL_MODE setting.\n\nIf strict_mode has been set (the default from MariaDB 10.2.4), MariaDB will\nreturn an error.\n\nIf strict_mode has not been set (the default until MariaDB 10.2.3), MariaDB\nwill adjust the number to fit in the field, returning a warning.\n\nExamples\n--------\n\nWith strict_mode set:\n\nSHOW VARIABLES LIKE \'sql_mode\';\n+---------------+--------------------------------------------------------------\n----------------------------+\n| Variable_name | Value \n |\n+---------------+--------------------------------------------------------------\n----------------------------+\n| sql_mode |\nSTRICT_TRANS_TABLES,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SU\nSTITUTION |\n+---------------+--------------------------------------------------------------\n----------------------------+\n\nCREATE TABLE ranges (i1 TINYINT, i2 SMALLINT, i3 TINYINT UNSIGNED);\n\nINSERT INTO ranges VALUES (257,257,257);\nERROR 1264 (22003): Out of range value for column \'i1\' at row 1\n\nSELECT * FROM ranges;\nEmpty set (0.10 sec)\n\nWith strict_mode unset:\n\nSHOW VARIABLES LIKE \'sql_mode%\';\n+---------------+-------+\n| Variable_name | Value |\n+---------------+-------+\n| sql_mode | |\n+---------------+-------+\n\nCREATE TABLE ranges (i1 TINYINT, i2 SMALLINT, i3 TINYINT UNSIGNED);\n\nINSERT INTO ranges VALUES (257,257,257);\nQuery OK, 1 row affected, 2 warnings (0.00 sec)\n\nSHOW WARNINGS;\n+---------+------+---------------------------------------------+\n| Level | Code | Message |\n+---------+------+---------------------------------------------+\n| Warning | 1264 | Out of range value for column \'i1\' at row 1 |\n| Warning | 1264 | Out of range value for column \'i3\' at row 1 |\n+---------+------+---------------------------------------------+\n2 rows in set (0.00 sec)\n\nSELECT * FROM ranges;\n+------+------+------+\n| i1 | i2 | i3 |\n+------+------+------+\n| 127 | 257 | 255 |\n+------+------+------+\n\nAuto_increment\n--------------\n\nThe AUTO_INCREMENT attribute can be used to generate a unique identity for new\nrows. For more details, see auto_increment.\n\nURL: https://mariadb.com/kb/en/numeric-data-type-overview/','','https://mariadb.com/kb/en/numeric-data-type-overview/'); +insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (254,23,'TINYINT','Syntax\n------\n\nTINYINT[(M)] [SIGNED | UNSIGNED | ZEROFILL]\n\nDescription\n-----------\n\nA very small integer. The signed range is -128 to 127. The unsigned range is 0\nto 255. For details on the attributes, see Numeric Data Type Overview.\n\nINT1 is a synonym for TINYINT. BOOL and BOOLEAN are synonyms for TINYINT(1).\n\nExamples\n--------\n\nCREATE TABLE tinyints (a TINYINT,b TINYINT UNSIGNED,c TINYINT ZEROFILL);\n\nWith strict_mode set, the default from MariaDB 10.2.4:\n\nINSERT INTO tinyints VALUES (-10,-10,-10);\nERROR 1264 (22003): Out of range value for column \'b\' at row 1\n\nINSERT INTO tinyints VALUES (-10,10,-10);\nERROR 1264 (22003): Out of range value for column \'c\' at row 1\n\nINSERT INTO tinyints VALUES (-10,10,10);\n\nSELECT * FROM tinyints;\n+------+------+------+\n| a | b | c |\n+------+------+------+\n| -10 | 10 | 010 |\n+------+------+------+\n\nINSERT INTO tinyints VALUES (128,128,128);\nERROR 1264 (22003): Out of range value for column \'a\' at row 1\n\nINSERT INTO tinyints VALUES (127,128,128);\n\nSELECT * FROM tinyints;\n+------+------+------+\n| a | b | c |\n+------+------+------+\n| -10 | 10 | 010 |\n| 127 | 128 | 128 |\n+------+------+------+\n\nWith strict_mode unset, the default until MariaDB 10.2.3:\n\nINSERT INTO tinyints VALUES (-10,-10,-10);\nQuery OK, 1 row affected, 2 warnings (0.08 sec)\nWarning (Code 1264): Out of range value for column \'b\' at row 1\nWarning (Code 1264): Out of range value for column \'c\' at row 1\n\nINSERT INTO tinyints VALUES (-10,10,-10);\nQuery OK, 1 row affected, 1 warning (0.11 sec)\nWarning (Code 1264): Out of range value for column \'c\' at row 1\n\nINSERT INTO tinyints VALUES (-10,10,10);\n\nSELECT * FROM tinyints;\n+------+------+------+\n| a | b | c |\n+------+------+------+\n| -10 | 0 | 000 |\n| -10 | 10 | 000 |\n| -10 | 10 | 010 |\n+------+------+------+\n\nINSERT INTO tinyints VALUES (128,128,128);\nQuery OK, 1 row affected, 1 warning (0.19 sec)\nWarning (Code 1264): Out of range value for column \'a\' at row 1\n\nINSERT INTO tinyints VALUES (127,128,128);\n\nSELECT * FROM tinyints;\n+------+------+------+\n| a | b | c |\n+------+------+------+\n| -10 | 0 | 000 |\n| -10 | 10 | 000 |\n| -10 | 10 | 010 |\n| 127 | 128 | 128 |\n| 127 | 128 | 128 |\n+------+------+------+\n\nURL: https://mariadb.com/kb/en/tinyint/','','https://mariadb.com/kb/en/tinyint/'); +insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (255,23,'BOOLEAN','Syntax\n------\n\nBOOL, BOOLEAN\n\nDescription\n-----------\n\nThese types are synonyms for TINYINT(1). A value of zero is considered false.\nNon-zero values are considered true.\n\nHowever, the values TRUE and FALSE are merely aliases for 1 and 0. See Boolean\nLiterals, as well as the IS operator for testing values against a boolean.\n\nExamples\n--------\n\nCREATE TABLE boo (i BOOLEAN);\n\nDESC boo;\n+-------+------------+------+-----+---------+-------+\n| Field | Type | Null | Key | Default | Extra |\n+-------+------------+------+-----+---------+-------+\n| i | tinyint(1) | YES | | NULL | |\n+-------+------------+------+-----+---------+-------+\n\nSELECT IF(0, \'true\', \'false\');\n+------------------------+\n| IF(0, \'true\', \'false\') |\n+------------------------+\n| false |\n+------------------------+\n\nSELECT IF(1, \'true\', \'false\');\n+------------------------+\n| IF(1, \'true\', \'false\') |\n+------------------------+\n| true |\n+------------------------+\n\nSELECT IF(2, \'true\', \'false\');\n+------------------------+\n| IF(2, \'true\', \'false\') |\n+------------------------+\n| true |\n+------------------------+\n\nTRUE and FALSE as aliases for 1 and 0:\n\nSELECT IF(0 = FALSE, \'true\', \'false\');\n\n+--------------------------------+\n| IF(0 = FALSE, \'true\', \'false\') |\n+--------------------------------+\n| true |\n+--------------------------------+\n\nSELECT IF(1 = TRUE, \'true\', \'false\');\n+-------------------------------+\n| IF(1 = TRUE, \'true\', \'false\') |\n+-------------------------------+\n| true |\n+-------------------------------+\n\nSELECT IF(2 = TRUE, \'true\', \'false\');\n+-------------------------------+\n| IF(2 = TRUE, \'true\', \'false\') |\n+-------------------------------+\n| false |\n+-------------------------------+\n\nSELECT IF(2 = FALSE, \'true\', \'false\');\n+--------------------------------+\n| IF(2 = FALSE, \'true\', \'false\') |\n+--------------------------------+\n| false |\n+--------------------------------+\n\nThe last two statements display the results shown because 2 is equal to\nneither 1 nor 0.\n\nURL: https://mariadb.com/kb/en/boolean/','','https://mariadb.com/kb/en/boolean/'); +insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (256,23,'SMALLINT','Syntax\n------\n\nSMALLINT[(M)] [SIGNED | UNSIGNED | ZEROFILL]\n\nDescription\n-----------\n\nA small integer. The signed range is -32768 to 32767. The unsigned range is 0\nto 65535.\n\nIf a column has been set to ZEROFILL, all values will be prepended by zeros so\nthat the SMALLINT value contains a number of M digits.\n\nNote: If the ZEROFILL attribute has been specified, the column will\nautomatically become UNSIGNED.\n\nINT2 is a synonym for SMALLINT.\n\nFor more details on the attributes, see Numeric Data Type Overview.\n\nExamples\n--------\n\nCREATE TABLE smallints (a SMALLINT,b SMALLINT UNSIGNED,c SMALLINT ZEROFILL);\n\nWith strict_mode set, the default from MariaDB 10.2.4:\n\nINSERT INTO smallints VALUES (-10,-10,-10);\nERROR 1264 (22003): Out of range value for column \'b\' at row 1\n\nINSERT INTO smallints VALUES (-10,10,-10);\nERROR 1264 (22003): Out of range value for column \'c\' at row 1\n\nINSERT INTO smallints VALUES (-10,10,10);\n\nINSERT INTO smallints VALUES (32768,32768,32768);\nERROR 1264 (22003): Out of range value for column \'a\' at row 1\n\nINSERT INTO smallints VALUES (32767,32768,32768);\n\nSELECT * FROM smallints;\n+-------+-------+-------+\n| a | b | c |\n+-------+-------+-------+\n| -10 | 10 | 00010 |\n| 32767 | 32768 | 32768 |\n+-------+-------+-------+\n\nWith strict_mode unset, the default until MariaDB 10.2.3:\n\nINSERT INTO smallints VALUES (-10,-10,-10);\nQuery OK, 1 row affected, 2 warnings (0.09 sec)\nWarning (Code 1264): Out of range value for column \'b\' at row 1\nWarning (Code 1264): Out of range value for column \'c\' at row 1\n\nINSERT INTO smallints VALUES (-10,10,-10);\nQuery OK, 1 row affected, 1 warning (0.08 sec)\nWarning (Code 1264): Out of range value for column \'c\' at row 1\n\nINSERT INTO smallints VALUES (-10,10,10);\n\nINSERT INTO smallints VALUES (32768,32768,32768);\nQuery OK, 1 row affected, 1 warning (0.04 sec)\nWarning (Code 1264): Out of range value for column \'a\' at row 1\n\nINSERT INTO smallints VALUES (32767,32768,32768);\n\nSELECT * FROM smallints;\n+-------+-------+-------+\n| a | b | c |\n+-------+-------+-------+\n| -10 | 0 | 00000 |\n| -10 | 10 | 00000 |\n| -10 | 10 | 00010 |\n| 32767 | 32768 | 32768 |\n| 32767 | 32768 | 32768 |\n+-------+-------+-------+\n\nURL: https://mariadb.com/kb/en/smallint/','','https://mariadb.com/kb/en/smallint/'); +insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (257,23,'MEDIUMINT','Syntax\n------\n\nMEDIUMINT[(M)] [SIGNED | UNSIGNED | ZEROFILL]\n\nDescription\n-----------\n\nA medium-sized integer. The signed range is -8388608 to 8388607. The unsigned\nrange is 0 to 16777215.\n\nZEROFILL pads the integer with zeroes and assumes UNSIGNED (even if UNSIGNED\nis not specified).\n\nINT3 is a synonym for MEDIUMINT.\n\nFor details on the attributes, see Numeric Data Type Overview.\n\nExamples\n--------\n\nCREATE TABLE mediumints (a MEDIUMINT,b MEDIUMINT UNSIGNED,c MEDIUMINT\nZEROFILL);\n\nDESCRIBE mediumints;\n+-------+--------------------------------+------+-----+---------+-------+\n| Field | Type | Null | Key | Default | Extra |\n+-------+--------------------------------+------+-----+---------+-------+\n| a | mediumint(9) | YES | | NULL | |\n| b | mediumint(8) unsigned | YES | | NULL | |\n| c | mediumint(8) unsigned zerofill | YES | | NULL | |\n+-------+--------------------------------+------+-----+---------+-------+\n\nWith strict_mode set, the default from MariaDB 10.2.4:\n\nINSERT INTO mediumints VALUES (-10,-10,-10);\nERROR 1264 (22003): Out of range value for column \'b\' at row 1\n\nINSERT INTO mediumints VALUES (-10,10,-10);\nERROR 1264 (22003): Out of range value for column \'c\' at row 1\n\nINSERT INTO mediumints VALUES (-10,10,10);\n\nINSERT INTO mediumints VALUES (8388608,8388608,8388608);\nERROR 1264 (22003): Out of range value for column \'a\' at row 1\n\nINSERT INTO mediumints VALUES (8388607,8388608,8388608);\n\nSELECT * FROM mediumints;\n+---------+---------+----------+\n| a | b | c |\n+---------+---------+----------+\n| -10 | 10 | 00000010 |\n| 8388607 | 8388608 | 08388608 |\n+---------+---------+----------+\n\nWith strict_mode unset, the default until MariaDB 10.2.3:\n\nINSERT INTO mediumints VALUES (-10,-10,-10);\nQuery OK, 1 row affected, 2 warnings (0.05 sec)\nWarning (Code 1264): Out of range value for column \'b\' at row 1\nWarning (Code 1264): Out of range value for column \'c\' at row 1\n\nINSERT INTO mediumints VALUES (-10,10,-10);\nQuery OK, 1 row affected, 1 warning (0.08 sec)\nWarning (Code 1264): Out of range value for column \'c\' at row 1\n\nINSERT INTO mediumints VALUES (-10,10,10);\n\nINSERT INTO mediumints VALUES (8388608,8388608,8388608);\nQuery OK, 1 row affected, 1 warning (0.05 sec)\nWarning (Code 1264): Out of range value for column \'a\' at row 1\n\nINSERT INTO mediumints VALUES (8388607,8388608,8388608);\n\nSELECT * FROM mediumints;\n+---------+---------+----------+\n| a | b | c |\n+---------+---------+----------+\n| -10 | 0 | 00000000 |\n| -10 | 0 | 00000000 |\n| -10 | 10 | 00000000 |\n| -10 | 10 | 00000010 |\n| 8388607 | 8388608 | 08388608 |\n| 8388607 | 8388608 | 08388608 |\n+---------+---------+----------+\n\nURL: https://mariadb.com/kb/en/mediumint/','','https://mariadb.com/kb/en/mediumint/'); +insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (258,23,'INT','Syntax\n------\n\nINT[(M)] [SIGNED | UNSIGNED | ZEROFILL]\nINTEGER[(M)] [SIGNED | UNSIGNED | ZEROFILL]\n\nDescription\n-----------\n\nA normal-size integer. When marked UNSIGNED, it ranges from 0 to 4294967295,\notherwise its range is -2147483648 to 2147483647 (SIGNED is the default). If a\ncolumn has been set to ZEROFILL, all values will be prepended by zeros so that\nthe INT value contains a number of M digits. INTEGER is a synonym for INT.\n\nNote: If the ZEROFILL attribute has been specified, the column will\nautomatically become UNSIGNED.\n\nINT4 is a synonym for INT.\n\nFor details on the attributes, see Numeric Data Type Overview.\n\nExamples\n--------\n\nCREATE TABLE ints (a INT,b INT UNSIGNED,c INT ZEROFILL);\n\nWith strict_mode set, the default from MariaDB 10.2.4:\n\nINSERT INTO ints VALUES (-10,-10,-10);\nERROR 1264 (22003): Out of range value for column \'b\' at row 1\n\nINSERT INTO ints VALUES (-10,10,-10);\nERROR 1264 (22003): Out of range value for column \'c\' at row 1\n\nINSERT INTO ints VALUES (-10,10,10);\n\nINSERT INTO ints VALUES (2147483648,2147483648,2147483648);\nERROR 1264 (22003): Out of range value for column \'a\' at row 1\n\nINSERT INTO ints VALUES (2147483647,2147483648,2147483648);\n\nSELECT * FROM ints;\n+------------+------------+------------+\n| a | b | c |\n+------------+------------+------------+\n| -10 | 10 | 0000000010 |\n| 2147483647 | 2147483648 | 2147483648 |\n+------------+------------+------------+\n\nWith strict_mode unset, the default until MariaDB 10.2.3:\n\nINSERT INTO ints VALUES (-10,-10,-10);\nQuery OK, 1 row affected, 2 warnings (0.10 sec)\nWarning (Code 1264): Out of range value for column \'b\' at row 1\nWarning (Code 1264): Out of range value for column \'c\' at row 1\n\nINSERT INTO ints VALUES (-10,10,-10);\nQuery OK, 1 row affected, 1 warning (0.08 sec)\nWarning (Code 1264): Out of range value for column \'c\' at row 1\n\nINSERT INTO ints VALUES (-10,10,10);\n\nINSERT INTO ints VALUES (2147483648,2147483648,2147483648);\nQuery OK, 1 row affected, 1 warning (0.07 sec)\nWarning (Code 1264): Out of range value for column \'a\' at row 1\n\nINSERT INTO ints VALUES (2147483647,2147483648,2147483648);\n\nSELECT * FROM ints;\n+------------+------------+------------+\n| a | b | c |\n+------------+------------+------------+\n| -10 | 0 | 0000000000 |\n| -10 | 10 | 0000000000 |\n| -10 | 10 | 0000000010 |\n| 2147483647 | 2147483648 | 2147483648 |\n| 2147483647 | 2147483648 | 2147483648 |\n+------------+------------+------------+\n\nURL: https://mariadb.com/kb/en/int/','','https://mariadb.com/kb/en/int/'); +insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (259,23,'BIGINT','Syntax\n------\n\nBIGINT[(M)] [SIGNED | UNSIGNED | ZEROFILL]\n\nDescription\n-----------\n\nA large integer. The signed range is -9223372036854775808 to\n9223372036854775807. The unsigned range is 0 to 18446744073709551615.\n\nIf a column has been set to ZEROFILL, all values will be prepended by zeros so\nthat the BIGINT value contains a number of M digits.\n\nNote: If the ZEROFILL attribute has been specified, the column will\nautomatically become UNSIGNED.\n\nFor more details on the attributes, see Numeric Data Type Overview.\n\nSERIAL is an alias for:\n\nBIGINT UNSIGNED NOT NULL AUTO_INCREMENT UNIQUE\n\nINT8 is a synonym for BIGINT.\n\nExamples\n--------\n\nCREATE TABLE bigints (a BIGINT,b BIGINT UNSIGNED,c BIGINT ZEROFILL);\n\nWith strict_mode set, the default from MariaDB 10.2.4:\n\nINSERT INTO bigints VALUES (-10,-10,-10);\nERROR 1264 (22003): Out of range value for column \'b\' at row 1\n\nINSERT INTO bigints VALUES (-10,10,-10);\nERROR 1264 (22003): Out of range value for column \'c\' at row 1\n\nINSERT INTO bigints VALUES (-10,10,10);\n\nINSERT INTO bigints VALUES\n(9223372036854775808,9223372036854775808,9223372036854775808);\nERROR 1264 (22003): Out of range value for column \'a\' at row 1\n\nINSERT INTO bigints VALUES\n(9223372036854775807,9223372036854775808,9223372036854775808);\n\nSELECT * FROM bigints;\n+---------------------+---------------------+----------------------+\n| a | b | c |\n+---------------------+---------------------+----------------------+\n| -10 | 10 | 00000000000000000010 |\n| 9223372036854775807 | 9223372036854775808 | 09223372036854775808 |\n+---------------------+---------------------+----------------------+\n\nWith strict_mode unset, the default until MariaDB 10.2.3:\n\nINSERT INTO bigints VALUES (-10,-10,-10);\nQuery OK, 1 row affected, 2 warnings (0.08 sec)\nWarning (Code 1264): Out of range value for column \'b\' at row 1\nWarning (Code 1264): Out of range value for column \'c\' at row 1\n\nINSERT INTO bigints VALUES (-10,10,-10);\nQuery OK, 1 row affected, 1 warning (0.08 sec)\nWarning (Code 1264): Out of range value for column \'c\' at row 1\n\nINSERT INTO bigints VALUES (-10,10,10);\n\nINSERT INTO bigints VALUES\n(9223372036854775808,9223372036854775808,9223372036854775808);\nQuery OK, 1 row affected, 1 warning (0.07 sec)\nWarning (Code 1264): Out of range value for column \'a\' at row 1\n\nINSERT INTO bigints VALUES\n(9223372036854775807,9223372036854775808,9223372036854775808);\n\nSELECT * FROM bigints;\n+---------------------+---------------------+----------------------+\n| a | b | c |\n+---------------------+---------------------+----------------------+\n| -10 | 0 | 00000000000000000000 |\n| -10 | 10 | 00000000000000000000 |\n| -10 | 10 | 00000000000000000010 |\n| 9223372036854775807 | 9223372036854775808 | 09223372036854775808 |\n| 9223372036854775807 | 9223372036854775808 | 09223372036854775808 |\n+---------------------+---------------------+----------------------+\n\nURL: https://mariadb.com/kb/en/bigint/','','https://mariadb.com/kb/en/bigint/'); +insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (260,23,'DECIMAL','Syntax\n------\n\nDECIMAL[(M[,D])] [SIGNED | UNSIGNED | ZEROFILL]\n\nDescription\n-----------\n\nA packed \"exact\" fixed-point number. M is the total number of digits (the\nprecision) and D is the number of digits after the decimal point (the scale).\n\n* The decimal point and (for negative numbers) the \"-\" sign are not\ncounted in M. \n* If D is 0, values have no decimal point or fractional\npart and on INSERT the value will be rounded to the nearest DECIMAL. \n* The maximum number of digits (M) for DECIMAL is 65. \n* The maximum number of supported decimals (D) is 30 before MariadB 10.2.1 and\n38 afterwards. \n* If D is omitted, the default is 0. If M is omitted, the default is 10.\n\nUNSIGNED, if specified, disallows negative values.\n\nZEROFILL, if specified, pads the number with zeros, up to the total number of\ndigits specified by M.\n\nAll basic calculations (+, -, *, /) with DECIMAL columns are done with a\nprecision of 65 digits.\n\nFor more details on the attributes, see Numeric Data Type Overview.\n\nDEC, NUMERIC and FIXED are synonyms, as well as NUMBER in Oracle mode from\nMariaDB 10.3.\n\nExamples\n--------\n\nCREATE TABLE t1 (d DECIMAL UNSIGNED ZEROFILL);\n\nINSERT INTO t1 VALUES (1),(2),(3),(4.0),(5.2),(5.7);\nQuery OK, 6 rows affected, 2 warnings (0.16 sec)\nRecords: 6 Duplicates: 0 Warnings: 2\n\nNote (Code 1265): Data truncated for column \'d\' at row 5\nNote (Code 1265): Data truncated for column \'d\' at row 6\n\nSELECT * FROM t1;\n+------------+\n| d |\n+------------+\n| 0000000001 |\n| 0000000002 |\n| 0000000003 |\n| 0000000004 |\n| 0000000005 |\n| 0000000006 |\n+------------+\n\nWith strict_mode set, the default from MariaDB 10.2.4:\n\nINSERT INTO t1 VALUES (-7);\nERROR 1264 (22003): Out of range value for column \'d\' at row 1\n\nWith strict_mode unset, the default until MariaDB 10.2.3:\n\nINSERT INTO t1 VALUES (-7);\nQuery OK, 1 row affected, 1 warning (0.02 sec)\nWarning (Code 1264): Out of range value for column \'d\' at row 1\n\nSELECT * FROM t1;\n+------------+\n| d |\n+------------+\n| 0000000001 |\n| 0000000002 |\n| 0000000003 |\n| 0000000004 |\n| 0000000005 |\n| 0000000006 |\n| 0000000000 |\n+------------+\n\nURL: https://mariadb.com/kb/en/decimal/','','https://mariadb.com/kb/en/decimal/'); +insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (261,23,'FLOAT','Syntax\n------\n\nFLOAT[(M,D)] [SIGNED | UNSIGNED | ZEROFILL]\n\nDescription\n-----------\n\nA small (single-precision) floating-point number (see DOUBLE for a\nregular-size floating point number). Allowable values are:\n\n* -3.402823466E+38 to -1.175494351E-38\n* 0\n* 1.175494351E-38 to 3.402823466E+38.\n\nThese are the theoretical limits, based on the IEEE standard. The actual range\nmight be slightly smaller depending on your hardware or operating system.\n\nM is the total number of digits and D is the number of digits following the\ndecimal point. If M and D are omitted, values are stored to the limits allowed\nby the hardware. A single-precision floating-point number is accurate to\napproximately 7 decimal places.\n\nUNSIGNED, if specified, disallows negative values.\n\nUsing FLOAT might give you some unexpected problems because all calculations\nin MariaDB are done with double precision. See Floating Point Accuracy.\n\nFor more details on the attributes, see Numeric Data Type Overview.\n\nURL: https://mariadb.com/kb/en/float/','','https://mariadb.com/kb/en/float/'); +insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (262,23,'DOUBLE','Syntax\n------\n\nDOUBLE[(M,D)] [SIGNED | UNSIGNED | ZEROFILL]\nDOUBLE PRECISION[(M,D)] [SIGNED | UNSIGNED | ZEROFILL]\nREAL[(M,D)] [SIGNED | UNSIGNED | ZEROFILL]\n\nDescription\n-----------\n\nA normal-size (double-precision) floating-point number (see FLOAT for a\nsingle-precision floating-point number).\n\nAllowable values are:\n\n* -1.7976931348623157E+308 to -2.2250738585072014E-308\n* 0\n* 2.2250738585072014E-308 to 1.7976931348623157E+308\n\nThese are the theoretical limits, based on the IEEE standard. The actual range\nmight be slightly smaller depending on your hardware or operating system.\n\nM is the total number of digits and D is the number of digits following the\ndecimal point. If M and D are omitted, values are stored to the limits allowed\nby the hardware. A double-precision floating-point number is accurate to\napproximately 15 decimal places.\n\nUNSIGNED, if specified, disallows negative values.\n\nZEROFILL, if specified, pads the number with zeros, up to the total number of\ndigits specified by M.\n\nREAL and DOUBLE PRECISION are synonyms, unless the REAL_AS_FLOAT SQL mode is\nenabled, in which case REAL is a synonym for FLOAT rather than DOUBLE.\n\nSee Floating Point Accuracy for issues when using floating-point numbers.\n\nFor more details on the attributes, see Numeric Data Type Overview.\n\nExamples\n--------\n\nCREATE TABLE t1 (d DOUBLE(5,0) zerofill);\n\nINSERT INTO t1 VALUES (1),(2),(3),(4);\n\nSELECT * FROM t1;\n+-------+\n| d |\n+-------+\n| 00001 |\n| 00002 |\n| 00003 |\n| 00004 |\n+-------+\n\nURL: https://mariadb.com/kb/en/double/','','https://mariadb.com/kb/en/double/'); +insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (263,23,'BIT','Syntax\n------\n\nBIT[(M)]\n\nDescription\n-----------\n\nA bit-field type. M indicates the number of bits per value, from 1 to 64. The\ndefault is 1 if M is omitted.\n\nBit values can be inserted with b\'value\' notation, where value is the bit\nvalue in 0\'s and 1\'s.\n\nBit fields are automatically zero-padded from the left to the full length of\nthe bit, so for example in a BIT(4) field, \'10\' is equivalent to \'0010\'.\n\nBits are returned as binary, so to display them, either add 0, or use a\nfunction such as HEX, OCT or BIN to convert them.\n\nExamples\n--------\n\nCREATE TABLE b ( b1 BIT(8) );\n\nWith strict_mode set, the default from MariaDB 10.2.4:\n\nINSERT INTO b VALUES (b\'11111111\');\n\nINSERT INTO b VALUES (b\'01010101\');\n\nINSERT INTO b VALUES (b\'1111111111111\');\nERROR 1406 (22001): Data too long for column \'b1\' at row 1\n\nSELECT b1+0, HEX(b1), OCT(b1), BIN(b1) FROM b;\n+------+---------+---------+----------+\n| b1+0 | HEX(b1) | OCT(b1) | BIN(b1) |\n+------+---------+---------+----------+\n| 255 | FF | 377 | 11111111 |\n| 85 | 55 | 125 | 1010101 |\n+------+---------+---------+----------+\n\nWith strict_mode unset, the default until MariaDB 10.2.3:\n\nINSERT INTO b VALUES (b\'11111111\'),(b\'01010101\'),(b\'1111111111111\');\nQuery OK, 3 rows affected, 1 warning (0.10 sec)\nRecords: 3 Duplicates: 0 Warnings: 1\n\nSHOW WARNINGS;\n+---------+------+---------------------------------------------+\n| Level | Code | Message |\n+---------+------+---------------------------------------------+\n| Warning | 1264 | Out of range value for column \'b1\' at row 3 |\n+---------+------+---------------------------------------------+\n\nSELECT b1+0, HEX(b1), OCT(b1), BIN(b1) FROM b;\n+------+---------+---------+----------+\n| b1+0 | HEX(b1) | OCT(b1) | BIN(b1) |\n+------+---------+---------+----------+\n| 255 | FF | 377 | 11111111 |\n| 85 | 55 | 125 | 1010101 |\n| 255 | FF | 377 | 11111111 |\n+------+---------+---------+----------+\n\nURL: https://mariadb.com/kb/en/bit/','','https://mariadb.com/kb/en/bit/'); +insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (264,23,'Floating-point Accuracy','Due to their nature, not all floating-point numbers can be stored with exact\nprecision. Hardware architecture, the CPU or even the compiler version and\noptimization level may affect the precision.\n\nIf you are comparing DOUBLEs or FLOATs with numeric decimals, it is not safe\nto use the equality operator.\n\nSometimes, changing a floating-point number from single-precision (FLOAT) to\ndouble-precision (DOUBLE) will fix the problem.\n\nExample\n-------\n\nf1, f2 and f3 have seemingly identical values across each row, but due to\nfloating point accuracy, the results may be unexpected.\n\nCREATE TABLE fpn (id INT, f1 FLOAT, f2 DOUBLE, f3 DECIMAL (10,3));\nINSERT INTO fpn VALUES (1,2,2,2),(2,0.1,0.1,0.1);\n\nSELECT * FROM fpn WHERE f1*f1 = f2*f2;\n+------+------+------+-------+\n| id | f1 | f2 | f3 |\n+------+------+------+-------+\n| 1 | 2 | 2 | 2.000 |\n+------+------+------+-------+\n\nThe reason why only one instead of two rows was returned becomes clear when we\nsee how the floating point squares were evaluated.\n\nSELECT f1*f1, f2*f2, f3*f3 FROM fpn;\n+----------------------+----------------------+----------+\n| f1*f1 | f2*f2 | f3*f3 |\n+----------------------+----------------------+----------+\n| 4 | 4 | 4.000000 |\n| 0.010000000298023226 | 0.010000000000000002 | 0.010000 |\n+----------------------+----------------------+----------+\n\nURL: https://mariadb.com/kb/en/floating-point-accuracy/','','https://mariadb.com/kb/en/floating-point-accuracy/'); +insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (265,23,'BINARY','This page describes the BINARY data type. For details about the operator, see\nBinary Operator.\n\nSyntax\n------\n\nBINARY(M)\n\nDescription\n-----------\n\nThe BINARY type is similar to the CHAR type, but stores binary byte strings\nrather than non-binary character strings. M represents the column length in\nbytes.\n\nIt contains no character set, and comparison and sorting are based on the\nnumeric value of the bytes.\n\nIf the maximum length is exceeded, and SQL strict mode is not enabled , the\nextra characters will be dropped with a warning. If strict mode is enabled, an\nerror will occur.\n\nBINARY values are right-padded with 0x00 (the zero byte) to the specified\nlength when inserted. The padding is not removed on select, so this needs to\nbe taken into account when sorting and comparing, where all bytes are\nsignificant. The zero byte, 0x00 is less than a space for comparison purposes.\n\nExamples\n--------\n\nInserting too many characters, first with strict mode off, then with it on:\n\nCREATE TABLE bins (a BINARY(10));\n\nINSERT INTO bins VALUES(\'12345678901\');\nQuery OK, 1 row affected, 1 warning (0.04 sec)\n\nSELECT * FROM bins;\n+------------+\n| a |\n+------------+\n| 1234567890 |\n+------------+\n\nSET sql_mode=\'STRICT_ALL_TABLES\';\n\nINSERT INTO bins VALUES(\'12345678901\');\nERROR 1406 (22001): Data too long for column \'a\' at row 1\n\nSorting is performed with the byte value:\n\nTRUNCATE bins;\n\nINSERT INTO bins VALUES(\'A\'),(\'B\'),(\'a\'),(\'b\');\n\nSELECT * FROM bins ORDER BY a;\n+------+\n| a |\n+------+\n| A |\n| B |\n| a |\n| b |\n+------+\n\nUsing CAST to sort as a CHAR instead:\n\nSELECT * FROM bins ORDER BY CAST(a AS CHAR);\n+------+\n| a |\n+------+\n| a |\n| A |\n| b |\n| B |\n+------+\n\nThe field is a BINARY(10), so padding of two \'\\0\'s are inserted, causing\ncomparisons that don\'t take this into account to fail:\n\nTRUNCATE bins;\n\nINSERT INTO bins VALUES(\'12345678\');\n\nSELECT a = \'12345678\', a = \'12345678\\0\\0\' from bins;\n+----------------+--------------------+\n| a = \'12345678\' | a = \'12345678\\0\\0\' |\n+----------------+--------------------+\n| 0 | 1 |\n+----------------+--------------------+\n\nURL: https://mariadb.com/kb/en/binary/','','https://mariadb.com/kb/en/binary/'); +insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (266,23,'BLOB','Syntax\n------\n\nBLOB[(M)]\n\nDescription\n-----------\n\nA BLOB column with a maximum length of 65,535 (216 - 1) bytes. Each BLOB value\nis stored using a two-byte length prefix that indicates the number of bytes in\nthe value.\n\nAn optional length M can be given for this type. If this is done, MariaDB\ncreates the column as the smallest BLOB type large enough to hold values M\nbytes long.\n\nBLOBS can also be used to store dynamic columns.\n\nBefore MariaDB 10.2.1, BLOB and TEXT columns could not be assigned a DEFAULT\nvalue. This restriction was lifted in MariaDB 10.2.1.\n\nIndexing\n--------\n\nMariaDB starting with 10.4\n--------------------------\nFrom MariaDB 10.4, it is possible to set a unique index on a column that uses\nthe BLOB data type. In previous releases this was not possible, as the index\nwould only guarantee the uniqueness of a fixed number of characters.\n\nOracle Mode\n-----------\n\nMariaDB starting with 10.3\n--------------------------\nIn Oracle mode from MariaDB 10.3, BLOB is a synonym for LONGBLOB.\n\nURL: https://mariadb.com/kb/en/blob/','','https://mariadb.com/kb/en/blob/'); +insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (267,23,'BLOB and TEXT Data Types','Description\n-----------\n\nA BLOB is a binary large object that can hold a variable amount of data. The\nfour BLOB types are\n\n* TINYBLOB,\n* BLOB, \n* MEDIUMBLOB, and\n* LONGBLOB.\n\nThese differ only in the maximum length of the values they can hold.\n\nThe TEXT types are\n\n* TINYTEXT,\n* TEXT,\n* MEDIUMTEXT, and\n* LONGTEXT.\n* JSON (alias for LONGTEXT)\n\nThese correspond to the four BLOB types and have the same maximum lengths and\nstorage requirements.\n\nMariaDB starting with 10.2.1\n----------------------------\nStarting from MariaDB 10.2.1, BLOB and TEXT columns can have a DEFAULT value.\n\nMariaDB starting with 10.4.3\n----------------------------\nFrom MariaDB 10.4, it is possible to set a unique index on columns that use\nthe BLOB or TEXT data types.\n\nURL: https://mariadb.com/kb/en/blob-and-text-data-types/','','https://mariadb.com/kb/en/blob-and-text-data-types/'); +insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (268,23,'CHAR','This article covers the CHAR data type. See CHAR Function for the function.\n\nSyntax\n------\n\n[NATIONAL] CHAR[(M)] [CHARACTER SET charset_name] [COLLATE collation_name]\n\nDescription\n-----------\n\nA fixed-length string that is always right-padded with spaces to the specified\nlength when stored. M represents the column length in characters. The range of\nM is 0 to 255. If M is omitted, the length is 1.\n\nCHAR(0) columns can contain 2 values: an empty string or NULL. Such columns\ncannot be part of an index. The CONNECT storage engine does not support\nCHAR(0).\n\nNote: Trailing spaces are removed when CHAR values are retrieved unless the\nPAD_CHAR_TO_FULL_LENGTH SQL mode is enabled.\n\nBefore MariaDB 10.2, all collations were of type PADSPACE, meaning that CHAR\n(as well as VARCHAR and TEXT) values are compared without regard for trailing\nspaces. This does not apply to the LIKE pattern-matching operator, which takes\ninto account trailing spaces.\n\nIf a unique index consists of a column where trailing pad characters are\nstripped or ignored, inserts into that column where values differ only by the\nnumber of trailing pad characters will result in a duplicate-key error.\n\nExamples\n--------\n\nTrailing spaces:\n\nCREATE TABLE strtest (c CHAR(10));\nINSERT INTO strtest VALUES(\'Maria \');\n\nSELECT c=\'Maria\',c=\'Maria \' FROM strtest;\n+-----------+--------------+\n| c=\'Maria\' | c=\'Maria \' |\n+-----------+--------------+\n| 1 | 1 |\n+-----------+--------------+\n\nSELECT c LIKE \'Maria\',c LIKE \'Maria \' FROM strtest;\n+----------------+-------------------+\n| c LIKE \'Maria\' | c LIKE \'Maria \' |\n+----------------+-------------------+\n| 1 | 0 |\n+----------------+-------------------+\n\nNO PAD Collations\n-----------------\n\nNO PAD collations regard trailing spaces as normal characters. You can get a\nlist of all NO PAD collations by querying the Information Schema Collations\ntable, for example:\n\nSELECT collation_name FROM information_schema.collations \n WHERE collation_name LIKE \"%nopad%\";\n+------------------------------+\n| collation_name |\n+------------------------------+\n| big5_chinese_nopad_ci |\n| big5_nopad_bin |\n...\n\nURL: https://mariadb.com/kb/en/char/','','https://mariadb.com/kb/en/char/'); +insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (269,23,'CHAR BYTE','Description\n-----------\n\nThe CHAR BYTE data type is an alias for the BINARY data type. This is a\ncompatibility feature.\n\nURL: https://mariadb.com/kb/en/char-byte/','','https://mariadb.com/kb/en/char-byte/'); +insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (270,23,'ENUM','Syntax\n------\n\nENUM(\'value1\',\'value2\',...) [CHARACTER SET charset_name] [COLLATE\ncollation_name]\n\nDescription\n-----------\n\nAn enumeration. A string object that can have only one value, chosen from the\nlist of values \'value1\', \'value2\', ..., NULL or the special \'\' error value. In\ntheory, an ENUM column can have a maximum of 65,535 distinct values; in\npractice, the real maximum depends on many factors. ENUM values are\nrepresented internally as integers.\n\nTrailing spaces are automatically stripped from ENUM values on table creation.\n\nENUMs require relatively little storage space compared to strings, either one\nor two bytes depending on the number of enumeration values.\n\nNULL and empty values\n---------------------\n\nAn ENUM can also contain NULL and empty values. If the ENUM column is declared\nto permit NULL values, NULL becomes a valid value, as well as the default\nvalue (see below). If strict SQL Mode is not enabled, and an invalid value is\ninserted into an ENUM, a special empty string, with an index value of zero\n(see Numeric index, below), is inserted, with a warning. This may be\nconfusing, because the empty string is also a possible value, and the only\ndifference if that is this case its index is not 0. Inserting will fail with\nan error if strict mode is active.\n\nIf a DEFAULT clause is missing, the default value will be:\n\n* NULL if the column is nullable;\n* otherwise, the first value in the enumeration.\n\nNumeric index\n-------------\n\nENUM values are indexed numerically in the order they are defined, and sorting\nwill be performed in this numeric order. We suggest not using ENUM to store\nnumerals, as there is little to no storage space benefit, and it is easy to\nconfuse the enum integer with the enum numeral value by leaving out the quotes.\n\nAn ENUM defined as ENUM(\'apple\',\'orange\',\'pear\') would have the following\nindex values:\n\n+--------------------------------------+--------------------------------------+\n| Index | Value |\n+--------------------------------------+--------------------------------------+\n| NULL | NULL |\n+--------------------------------------+--------------------------------------+\n| 0 | \'\' |\n+--------------------------------------+--------------------------------------+\n| 1 | \'apple\' |\n+--------------------------------------+--------------------------------------+\n| 2 | \'orange\' |\n+--------------------------------------+--------------------------------------+\n| 3 | \'pear\' |\n+--------------------------------------+--------------------------------------+\n\nExamples\n--------\n\nCREATE TABLE fruits (\n id INT NOT NULL auto_increment PRIMARY KEY,\n fruit ENUM(\'apple\',\'orange\',\'pear\'),\n bushels INT);\n\nDESCRIBE fruits;\n+---------+-------------------------------+------+-----+---------+-------------\n--+\n| Field | Type | Null | Key | Default | Extra \n |\n+---------+-------------------------------+------+-----+---------+-------------\n--+\n| id | int(11) | NO | PRI | NULL |\nauto_increment |\n| fruit | enum(\'apple\',\'orange\',\'pear\') | YES | | NULL | \n |\n| bushels | int(11) | YES | | NULL | \n |\n+---------+-------------------------------+------+-----+---------+-------------\n--+\n\nINSERT INTO fruits\n (fruit,bushels) VALUES\n (\'pear\',20),\n (\'apple\',100),\n (\'orange\',25);\n\nINSERT INTO fruits\n (fruit,bushels) VALUES\n (\'avocado\',10);\nERROR 1265 (01000): Data truncated for column \'fruit\' at row 1\n\nSELECT * FROM fruits;\n+----+--------+---------+\n| id | fruit | bushels |\n+----+--------+---------+\n| 1 | pear | 20 |\n| 2 | apple | 100 |\n| 3 | orange | 25 |\n+----+--------+---------+\n\nSelecting by numeric index:\n\nSELECT * FROM fruits WHERE fruit=2;\n+----+--------+---------+\n| id | fruit | bushels |\n+----+--------+---------+\n| 3 | orange | 25 |\n+----+--------+---------+\n\nSorting is according to the index value:\n\nCREATE TABLE enums (a ENUM(\'2\',\'1\'));\n\nINSERT INTO enums VALUES (\'1\'),(\'2\');\n\nSELECT * FROM enums ORDER BY a ASC;\n+------+\n| a |\n+------+\n| 2 |\n| 1 |\n+------+\n\nIt\'s easy to get confused between returning the enum integer with the stored\nvalue, so we don\'t suggest using ENUM to store numerals. The first example\nreturns the 1st indexed field (\'2\' has an index value of 1, as it\'s defined\nfirst), while the second example returns the string value \'1\'.\n\nSELECT * FROM enums WHERE a=1;\n+------+\n| a |\n+------+\n| 2 |\n+------+\n\nSELECT * FROM enums WHERE a=\'1\';\n+------+\n| a |\n+------+\n| 1 |\n+------+\n\nURL: https://mariadb.com/kb/en/enum/','','https://mariadb.com/kb/en/enum/'); +insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (271,23,'JSON Data Type','MariaDB starting with 10.2.7\n----------------------------\nThe JSON alias was added in MariaDB 10.2.7. This was done to make it possible\nto use JSON columns in statement based replication from MySQL to MariaDB and\nto make it possible for MariaDB to read mysqldumps from MySQL.\n\nJSON is an alias for LONGTEXT introduced for compatibility reasons with\nMySQL\'s JSON data type. MariaDB implements this as a LONGTEXT rather, as the\nJSON data type contradicts the SQL standard, and MariaDB\'s benchmarks indicate\nthat performance is at least equivalent.\n\nIn order to ensure that a a valid json document is inserted, the JSON_VALID\nfunction can be used as a CHECK constraint. This constraint is automatically\nincluded for types using the JSON alias from MariaDB 10.4.3.\n\nExamples\n--------\n\nCREATE TABLE t (j JSON);\n\nDESC t;\n+-------+----------+------+-----+---------+-------+\n| Field | Type | Null | Key | Default | Extra |\n+-------+----------+------+-----+---------+-------+\n| j | longtext | YES | | NULL | |\n+-------+----------+------+-----+---------+-------+\n\nWith validation:\n\nCREATE TABLE t2 (\n j JSON\n CHECK (JSON_VALID(j))\n);\n\nINSERT INTO t2 VALUES (\'invalid\');\nERROR 4025 (23000): CONSTRAINT `j` failed for `test`.`t2`\n\nINSERT INTO t2 VALUES (\'{\"id\": 1, \"name\": \"Monty\"}\');\nQuery OK, 1 row affected (0.13 sec)\n\nReplicating JSON Data Between MySQL and MariaDB\n-----------------------------------------------\n\nThe JSON type in MySQL stores the JSON object in a compact form, not as\nLONGTEXT as in MariaDB. This means that row based replication will not work\nfor JSON types from MySQL to MariaDB.\n\nThere are a a few different ways to solve this:\n\n* Use statement based replication.\n* Change the JSON column to type TEXT in MySQL\n* If you must use row-based replication and cannot change the MySQL master\nfrom JSON to TEXT, you can try to introduce an intermediate MySQL slave and\nchange the column type from JSON to TEXT on it. Then you replicate from this\nintermediate slave to MariaDB.\n\nConverting a MySQL TABLE with JSON Fields to MariaDB\n----------------------------------------------------\n\nMariaDB can\'t directly access MySQL\'s JSON format.\n\nThere are a a few different ways to move the table to MariaDB:\n\n* From MariaDB 10.5.7, see the you can use the mysql_json plugin. See Making\nMariaDB understand MySQL JSON.\n* Change the JSON column to type TEXT in MySQL. After this, MariaDB can\ndirectly use the table without any need for a dump and restore.\n* Use mariadb-dump/mysqldump to copy the table.\n\nDifferences Between MySQL JSON Strings and MariaDB JSON Strings\n---------------------------------------------------------------\n\n* In MySQL, JSON is an object and is compared according to json values. In\nMariaDB JSON strings are normal strings and compared as strings. One exception\nis when using JSON_EXTRACT() in which case strings are unescaped before\ncomparison.\n\nURL: https://mariadb.com/kb/en/json-data-type/','','https://mariadb.com/kb/en/json-data-type/'); +insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (272,23,'MEDIUMBLOB','Syntax\n------\n\nMEDIUMBLOB\n\nDescription\n-----------\n\nA BLOB column with a maximum length of 16,777,215 (224 - 1) bytes. Each\nMEDIUMBLOB value is stored using a three-byte length prefix that indicates the\nnumber of bytes in the value.\n\nURL: https://mariadb.com/kb/en/mediumblob/','','https://mariadb.com/kb/en/mediumblob/'); +insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (273,23,'MEDIUMTEXT','Syntax\n------\n\nMEDIUMTEXT [CHARACTER SET charset_name] [COLLATE collation_name]\n\nDescription\n-----------\n\nA TEXT column with a maximum length of 16,777,215 (224 - 1) characters. The\neffective maximum length is less if the value contains multi-byte characters.\nEach MEDIUMTEXT value is stored using a three-byte length prefix that\nindicates the number of bytes in the value.\n\nURL: https://mariadb.com/kb/en/mediumtext/','','https://mariadb.com/kb/en/mediumtext/'); +insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (274,23,'LONGBLOB','Syntax\n------\n\nLONGBLOB\n\nDescription\n-----------\n\nA BLOB column with a maximum length of 4,294,967,295 bytes or 4GB (232 - 1).\nThe effective maximum length of LONGBLOB columns depends on the configured\nmaximum packet size in the client/server protocol and available memory. Each\nLONGBLOB value is stored using a four-byte length prefix that indicates the\nnumber of bytes in the value.\n\nOracle Mode\n-----------\n\nMariaDB starting with 10.3\n--------------------------\nIn Oracle mode from MariaDB 10.3, BLOB is a synonym for LONGBLOB.\n\nURL: https://mariadb.com/kb/en/longblob/','','https://mariadb.com/kb/en/longblob/'); +insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (275,23,'LONGTEXT','Syntax\n------\n\nLONGTEXT [CHARACTER SET charset_name] [COLLATE collation_name]\n\nDescription\n-----------\n\nA TEXT column with a maximum length of 4,294,967,295 or 4GB (232 - 1)\ncharacters. The effective maximum length is less if the value contains\nmulti-byte characters. The effective maximum length of LONGTEXT columns also\ndepends on the configured maximum packet size in the client/server protocol\nand available memory. Each LONGTEXT value is stored using a four-byte length\nprefix that indicates the number of bytes in the value.\n\nFrom MariaDB 10.2.7, JSON is an alias for LONGTEXT. See JSON Data Type for\ndetails.\n\nOracle Mode\n-----------\n\nMariaDB starting with 10.3\n--------------------------\nIn Oracle mode from MariaDB 10.3, CLOB is a synonym for LONGTEXT.\n\nURL: https://mariadb.com/kb/en/longtext/','','https://mariadb.com/kb/en/longtext/'); +insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (276,23,'ROW','MariaDB starting with 10.3.0\n----------------------------\nThe ROW data type was introduced in MariaDB 10.3.0.\n\nSyntax\n------\n\nROW ( [{, }... ])\n\nDescription\n-----------\n\nROW is a data type for stored procedure variables.\n\nFeatures\n--------\n\nROW fields as normal variables\n------------------------------\n\nROW fields (members) act as normal variables, and are able to appear in all\nquery parts where a stored procedure variable is allowed:\n\n* Assignment is using the := operator and the SET command:\n\na.x:= 10;\na.x:= b.x;\nSET a.x= 10, a.y=20, a.z= b.z;\n\n* Passing to functions and operators:\n\nSELECT f1(rec.a), rec.a<10;\n\n* Clauses (select list, WHERE, HAVING, LIMIT, etc...,):\n\nSELECT var.a, t1.b FROM t1 WHERE t1.b=var.b LIMIT var.c;\n\n* INSERT values:\n\nINSERT INTO t1 VALUES (rec.a, rec.b, rec.c);\n\n* SELECT .. INTO targets\n\nSELECT a,b INTO rec.a, rec.b FROM t1 WHERE t1.id=10;\n\n* Dynamic SQL out parameters (EXECUTE and EXECUTE IMMEDIATE)\n\nEXECUTE IMMEDIATE \'CALL proc_with_out_param(?)\' USING rec.a;\n\nROW type variables as FETCH targets\n-----------------------------------\n\nROW type variables are allowed as FETCH targets:\n\nFETCH cur INTO rec;\n\nwhere cur is a CURSOR and rec is a ROW type stored procedure variable.\n\nNote, currently an attempt to use FETCH for a ROW type variable returns this\nerror:\n\nERROR 1328 (HY000): Incorrect number of FETCH variables\n\nFETCH from a cursor cur into a ROW variable rec works as follows:\n\n* The number of fields in cur must match the number of fields in rec.\n Otherwise, an error is reported.\n\n* Assignment is done from left to right. The first cursor field is assigned to\n the first variable field, the second cursor field is assigned to the second\n variable field, etc.\n\n* Field names in rec are not important and can differ from field names\n in cur.\n\nSee FETCH Examples (below) for examples of using this with sql_mode=ORACLE and\nsql_mode=DEFAULT.\n\nROW type variables as SELECT...INTO targets\n-------------------------------------------\n\nROW type variables are allowed as SELECT..INTO targets with some differences\ndepending on which sql_mode is in use.\n\n* When using sql_mode=ORACLE, table%ROWTYPE and cursor%ROWTYPE\n variables can be used as SELECT...INTO targets.\n\n* Using multiple ROW variables in the SELECT..INTO list will report an\n error.\n\n* Using ROW variables with a different column count than in\n the SELECT..INTO list will report an error.\n\nSee SELECT...INTO Examples (below) for examples of using this with\nsql_mode=ORACLE and sql_mode=DEFAULT.\n\nFeatures not implemented\n------------------------\n\nThe following features are planned, but not implemented yet:\n\n* Returning a ROW type expression from a stored function (see MDEV-12252).\nThis will need some grammar change to support field names after parentheses:\n\nSELECT f1().x FROM DUAL;\n\n* Returning a ROW type expression from a built-in hybrid type function, such\nas CASE, IF, etc. \n* ROW of ROWs\n\nExamples\n--------\n\nDeclaring a ROW in a stored procedure\n-------------------------------------\n\nDELIMITER $$\nCREATE PROCEDURE p1()\nBEGIN\n DECLARE r ROW (c1 INT, c2 VARCHAR(10));\n SET r.c1= 10;\n SET r.c2= \'test\';\n INSERT INTO t1 VALUES (r.c1, r.c2);\nEND;\n$$\nDELIMITER ;\nCALL p1();\n\nFETCH Examples\n--------------\n\nA complete FETCH example for sql_mode=ORACLE:\n\nDROP TABLE IF EXISTS t1;\nCREATE TABLE t1 (a INT, b VARCHAR(32));\nINSERT INTO t1 VALUES (10,\'b10\');\nINSERT INTO t1 VALUES (20,\'b20\');\nINSERT INTO t1 VALUES (30,\'b30\');\n\nSET sql_mode=oracle;\nDROP PROCEDURE IF EXISTS p1;\nDELIMITER $$\nCREATE PROCEDURE p1 AS\n rec ROW(a INT, b VARCHAR(32));\n CURSOR c IS SELECT a,b FROM t1;\nBEGIN\n OPEN c;\n LOOP\n FETCH c INTO rec;\n EXIT WHEN c%NOTFOUND;\n SELECT (\'rec=(\' || rec.a ||\',\'|| rec.b||\')\');\n END LOOP;\n CLOSE c;\nEND;\n$$\nDELIMITER ;\nCALL p1();\n\nA complete FETCH example for sql_mode=DEFAULT:\n\nDROP TABLE IF EXISTS t1;\nCREATE TABLE t1 (a INT, b VARCHAR(32));\nINSERT INTO t1 VALUES (10,\'b10\');\nINSERT INTO t1 VALUES (20,\'b20\');\nINSERT INTO t1 VALUES (30,\'b30\');\n\nSET sql_mode=DEFAULT;\nDROP PROCEDURE IF EXISTS p1;\nDELIMITER $$\nCREATE PROCEDURE p1()\nBEGIN\n DECLARE done INT DEFAULT FALSE;\n DECLARE rec ROW(a INT, b VARCHAR(32));\n DECLARE c CURSOR FOR SELECT a,b FROM t1;\n DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = TRUE;\n OPEN c;\nread_loop:\n LOOP\n FETCH c INTO rec;\n IF done THEN\n LEAVE read_loop;\n END IF;\n SELECT CONCAT(\'rec=(\',rec.a,\',\',rec.b,\')\');\n END LOOP;\n CLOSE c;\nEND;\n$$\nDELIMITER ;\nCALL p1();\n\nSELECT...INTO Examples\n----------------------\n\nA SELECT...INTO example for sql_mode=DEFAULT:\n\nSET sql_mode=DEFAULT;\nDROP TABLE IF EXISTS t1;\nDROP PROCEDURE IF EXISTS p1;\nCREATE TABLE t1 (a INT, b VARCHAR(32));\nINSERT INTO t1 VALUES (10,\'b10\');\nDELIMITER $$\nCREATE PROCEDURE p1()\nBEGIN\n DECLARE rec1 ROW(a INT, b VARCHAR(32));\n SELECT * FROM t1 INTO rec1;\n SELECT rec1.a, rec1.b;\nEND;\n$$\nDELIMITER ;\nCALL p1();\n\nThe above example returns:\n\n+--------+--------+\n| rec1.a | rec1.b |\n+--------+--------+\n| 10 | b10 |\n+--------+--------+\n\nA SELECT...INTO example for sql_mode=ORACLE:\n\nSET sql_mode=ORACLE;\nDROP TABLE IF EXISTS t1;\nDROP PROCEDURE IF EXISTS p1;\nCREATE TABLE t1 (a INT, b VARCHAR(32));\nINSERT INTO t1 VALUES (10,\'b10\');\nDELIMITER $$\nCREATE PROCEDURE p1 AS\n rec1 ROW(a INT, b VARCHAR(32));\nBEGIN\n SELECT * FROM t1 INTO rec1;\n SELECT rec1.a, rec1.b;\nEND;','','https://mariadb.com/kb/en/row/'); +update help_topic set description = CONCAT(description, '\n$$\nDELIMITER ;\nCALL p1();\n\nThe above example returns:\n\n+--------+--------+\n| rec1.a | rec1.b |\n+--------+--------+\n| 10 | b10 |\n+--------+--------+\n\nAn example for sql_mode=ORACLE using table%ROWTYPE variables as SELECT..INTO\ntargets:\n\nSET sql_mode=ORACLE;\nDROP TABLE IF EXISTS t1;\nDROP PROCEDURE IF EXISTS p1;\nCREATE TABLE t1 (a INT, b VARCHAR(32));\nINSERT INTO t1 VALUES (10,\'b10\');\nDELIMITER $$\nCREATE PROCEDURE p1 AS\n rec1 t1%ROWTYPE;\nBEGIN\n SELECT * FROM t1 INTO rec1;\n SELECT rec1.a, rec1.b;\nEND;\n$$\nDELIMITER ;\nCALL p1();\n\nThe above example returns:\n\n+--------+--------+\n| rec1.a | rec1.b |\n+--------+--------+\n| 10 | b10 |\n+--------+--------+\n\nAn example for sql_mode=ORACLE using cursor%ROWTYPE variables as SELECT..INTO\ntargets:\n\nSET sql_mode=ORACLE;\nDROP TABLE IF EXISTS t1;\nDROP PROCEDURE IF EXISTS p1;\nCREATE TABLE t1 (a INT, b VARCHAR(32));\nINSERT INTO t1 VALUES (10,\'b10\');\nDELIMITER $$\nCREATE PROCEDURE p1 AS\n CURSOR cur1 IS SELECT * FROM t1;\n rec1 cur1%ROWTYPE;\nBEGIN\n SELECT * FROM t1 INTO rec1;\n SELECT rec1.a, rec1.b;\nEND;\n$$\nDELIMITER ;\nCALL p1();\n\nThe above example returns:\n\n+--------+--------+\n| rec1.a | rec1.b |\n+--------+--------+\n| 10 | b10 |\n+--------+--------+\n\nURL: https://mariadb.com/kb/en/row/') WHERE help_topic_id = 276; +insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (277,23,'TEXT','Syntax\n------\n\nTEXT[(M)] [CHARACTER SET charset_name] [COLLATE collation_name]\n\nDescription\n-----------\n\nA TEXT column with a maximum length of 65,535 (216 - 1) characters. The\neffective maximum length is less if the value contains multi-byte characters.\nEach TEXT value is stored using a two-byte length prefix that indicates the\nnumber of bytes in the value. If you need a bigger storage, consider using\nMEDIUMTEXT instead.\n\nAn optional length M can be given for this type. If this is done, MariaDB\ncreates the column as the smallest TEXT type large enough to hold values M\ncharacters long.\n\nBefore MariaDB 10.2, all MariaDB collations were of type PADSPACE, meaning\nthat TEXT (as well as VARCHAR and CHAR values) are compared without regard for\ntrailing spaces. This does not apply to the LIKE pattern-matching operator,\nwhich takes into account trailing spaces.\n\nBefore MariaDB 10.2.1, BLOB and TEXT columns could not be assigned a DEFAULT\nvalue. This restriction was lifted in MariaDB 10.2.1.\n\nExamples\n--------\n\nTrailing spaces:\n\nCREATE TABLE strtest (d TEXT(10));\nINSERT INTO strtest VALUES(\'Maria \');\n\nSELECT d=\'Maria\',d=\'Maria \' FROM strtest;\n+-----------+--------------+\n| d=\'Maria\' | d=\'Maria \' |\n+-----------+--------------+\n| 1 | 1 |\n+-----------+--------------+\n\nSELECT d LIKE \'Maria\',d LIKE \'Maria \' FROM strtest;\n+----------------+-------------------+\n| d LIKE \'Maria\' | d LIKE \'Maria \' |\n+----------------+-------------------+\n| 0 | 1 |\n+----------------+-------------------+\n\nIndexing\n--------\n\nTEXT columns can only be indexed over a specified length. This means that they\ncannot be used as the primary key of a table norm until MariaDB 10.4, can a\nunique index be created on them.\n\nMariaDB starting with 10.4\n--------------------------\nStarting with MariaDB 10.4, a unique index can be created on a TEXT column.\n\nInternally, this uses hash indexing to quickly check the values and if a hash\ncollision is found, the actual stored values are compared in order to retain\nthe uniqueness.\n\nDifference between VARCHAR and TEXT\n-----------------------------------\n\n* VARCHAR columns can be fully indexed. TEXT columns can only be indexed over\na specified length.\n* Using TEXT or BLOB in a SELECT query that uses temporary tables for storing\nintermediate results will force the temporary table to be disk based (using\nthe Aria storage engine instead of the memory storage engine, which is a bit\nslower. This is not that bad as the Aria storage engine caches the rows in\nmemory. To get the benefit of this, one should ensure that the\naria_pagecache_buffer_size variable is big enough to hold most of the row and\nindex data for temporary tables.\n\nFor Storage Engine Developers\n-----------------------------\n\n* Internally the full length of the VARCHAR column is allocated inside each\nTABLE objects record[] structure. As there are three such buffers, each open\ntable will allocate 3 times max-length-to-store-varchar bytes of memory.\n* TEXT and BLOB columns are stored with a pointer (4 or 8 bytes) + a 1-4 bytes\nlength. The TEXT data is only stored once. This means that internally TEXT\nuses less memory for each open table but instead has the additional overhead\nthat each TEXT object needs to be allocated and freed for each row access\n(with some caching in between).\n\nURL: https://mariadb.com/kb/en/text/','','https://mariadb.com/kb/en/text/'); +insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (278,23,'TINYBLOB','Syntax\n------\n\nTINYBLOB\n\nDescription\n-----------\n\nA BLOB column with a maximum length of 255 (28 - 1) bytes. Each TINYBLOB value\nis stored using a one-byte length prefix that indicates the number of bytes in\nthe value.\n\nURL: https://mariadb.com/kb/en/tinyblob/','','https://mariadb.com/kb/en/tinyblob/'); +insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (279,23,'TINYTEXT','Syntax\n------\n\nTINYTEXT [CHARACTER SET charset_name] [COLLATE collation_name]\n\nDescription\n-----------\n\nA TEXT column with a maximum length of 255 (28 - 1) characters. The effective\nmaximum length is less if the value contains multi-byte characters. Each\nTINYTEXT value is stored using a one-byte length prefix that indicates the\nnumber of bytes in the value.\n\nURL: https://mariadb.com/kb/en/tinytext/','','https://mariadb.com/kb/en/tinytext/'); +insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (280,23,'VARBINARY','Syntax\n------\n\nVARBINARY(M)\n\nDescription\n-----------\n\nThe VARBINARY type is similar to the VARCHAR type, but stores binary byte\nstrings rather than non-binary character strings. M represents the maximum\ncolumn length in bytes.\n\nIt contains no character set, and comparison and sorting are based on the\nnumeric value of the bytes.\n\nIf the maximum length is exceeded, and SQL strict mode is not enabled , the\nextra characters will be dropped with a warning. If strict mode is enabled, an\nerror will occur.\n\nUnlike BINARY values, VARBINARYs are not right-padded when inserting.\n\nOracle Mode\n-----------\n\nMariaDB starting with 10.3\n--------------------------\nIn Oracle mode from MariaDB 10.3, RAW is a synonym for VARBINARY.\n\nExamples\n--------\n\nInserting too many characters, first with strict mode off, then with it on:\n\nCREATE TABLE varbins (a VARBINARY(10));\n\nINSERT INTO varbins VALUES(\'12345678901\');\nQuery OK, 1 row affected, 1 warning (0.04 sec)\n\nSELECT * FROM varbins;\n+------------+\n| a |\n+------------+\n| 1234567890 |\n+------------+\n\nSET sql_mode=\'STRICT_ALL_TABLES\';\n\nINSERT INTO varbins VALUES(\'12345678901\');\nERROR 1406 (22001): Data too long for column \'a\' at row 1\n\nSorting is performed with the byte value:\n\nTRUNCATE varbins;\n\nINSERT INTO varbins VALUES(\'A\'),(\'B\'),(\'a\'),(\'b\');\n\nSELECT * FROM varbins ORDER BY a;\n+------+\n| a |\n+------+\n| A |\n| B |\n| a |\n| b |\n+------+\n\nUsing CAST to sort as a CHAR instead:\n\nSELECT * FROM varbins ORDER BY CAST(a AS CHAR);\n+------+\n| a |\n+------+\n| a |\n| A |\n| b |\n| B |\n+------+\n\nURL: https://mariadb.com/kb/en/varbinary/','','https://mariadb.com/kb/en/varbinary/'); +insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (281,23,'VARCHAR','Syntax\n------\n\n[NATIONAL] VARCHAR(M) [CHARACTER SET charset_name] [COLLATE collation_name]\n\nDescription\n-----------\n\nA variable-length string. M represents the maximum column length in\ncharacters. The range of M is 0 to 65,532. The effective maximum length of a\nVARCHAR is subject to the maximum row size and the character set used. For\nexample, utf8 characters can require up to three bytes per character, so a\nVARCHAR column that uses the utf8 character set can be declared to be a\nmaximum of 21,844 characters.\n\nNote: For the ColumnStore engine, M represents the maximum column length in\nbytes.\n\nMariaDB stores VARCHAR values as a one-byte or two-byte length prefix plus\ndata. The length prefix indicates the number of bytes in the value. A VARCHAR\ncolumn uses one length byte if values require no more than 255 bytes, two\nlength bytes if values may require more than 255 bytes.\n\nMariaDB follows the standard SQL specification, and does not remove trailing\nspaces from VARCHAR values.\n\nVARCHAR(0) columns can contain 2 values: an empty string or NULL. Such columns\ncannot be part of an index. The CONNECT storage engine does not support\nVARCHAR(0).\n\nVARCHAR is shorthand for CHARACTER VARYING. NATIONAL VARCHAR is the standard\nSQL way to define that a VARCHAR column should use some predefined character\nset. MariaDB uses utf8 as this predefined character set, as does MySQL 4.1 and\nup. NVARCHAR is shorthand for NATIONAL VARCHAR.\n\nBefore MariaDB 10.2, all MariaDB collations were of type PADSPACE, meaning\nthat VARCHAR (as well as CHAR and TEXT values) are compared without regard for\ntrailing spaces. This does not apply to the LIKE pattern-matching operator,\nwhich takes into account trailing spaces. From MariaDB 10.2, a number of NO\nPAD collations are available.\n\nIf a unique index consists of a column where trailing pad characters are\nstripped or ignored, inserts into that column where values differ only by the\nnumber of trailing pad characters will result in a duplicate-key error.\n\nExamples\n--------\n\nThe following are equivalent:\n\nVARCHAR(30) CHARACTER SET utf8\nNATIONAL VARCHAR(30)\nNVARCHAR(30)\nNCHAR VARCHAR(30)\nNATIONAL CHARACTER VARYING(30)\nNATIONAL CHAR VARYING(30)\n\nTrailing spaces:\n\nCREATE TABLE strtest (v VARCHAR(10));\nINSERT INTO strtest VALUES(\'Maria \');\n\nSELECT v=\'Maria\',v=\'Maria \' FROM strtest;\n+-----------+--------------+\n| v=\'Maria\' | v=\'Maria \' |\n+-----------+--------------+\n| 1 | 1 |\n+-----------+--------------+\n\nSELECT v LIKE \'Maria\',v LIKE \'Maria \' FROM strtest;\n+----------------+-------------------+\n| v LIKE \'Maria\' | v LIKE \'Maria \' |\n+----------------+-------------------+\n| 0 | 1 |\n+----------------+-------------------+\n\nTruncation\n----------\n\n* Depending on whether or not strict sql mode is set, you will either get a\nwarning or an error if you try to insert a string that is too long into a\nVARCHAR column. If the extra characters are spaces, the spaces that can\'t fit\nwill be removed and you will always get a warning, regardless of the sql mode\nsetting.\n\nDifference Between VARCHAR and TEXT\n-----------------------------------\n\n* VARCHAR columns can be fully indexed. TEXT columns can only be indexed over\na specified length.\n* Using TEXT or BLOB in a SELECT query that uses temporary tables for storing\nintermediate results will force the temporary table to be disk based (using\nthe Aria storage engine instead of the memory storage engine, which is a bit\nslower. This is not that bad as the Aria storage engine caches the rows in\nmemory. To get the benefit of this, one should ensure that the\naria_pagecache_buffer_size variable is big enough to hold most of the row and\nindex data for temporary tables.\n\nOracle Mode\n-----------\n\nMariaDB starting with 10.3\n--------------------------\nIn Oracle mode from MariaDB 10.3, VARCHAR2 is a synonym.\n\nFor Storage Engine Developers\n-----------------------------\n\n* Internally the full length of the VARCHAR column is allocated inside each\nTABLE objects record[] structure. As there are three such buffers, each open\ntable will allocate 3 times max-length-to-store-varchar bytes of memory.\n* TEXT and BLOB columns are stored with a pointer (4 or 8 bytes) + a 1-4 bytes\nlength. The TEXT data is only stored once. This means that internally TEXT\nuses less memory for each open table but instead has the additional overhead\nthat each TEXT object needs to be allocated and freed for each row access\n(with some caching in between).\n\nURL: https://mariadb.com/kb/en/varchar/','','https://mariadb.com/kb/en/varchar/'); +insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (282,23,'SET Data Type','Syntax\n------\n\nSET(\'value1\',\'value2\',...) [CHARACTER SET charset_name] [COLLATE\ncollation_name]\n\nDescription\n-----------\n\nA set. A string object that can have zero or more values, each of which must\nbe chosen from the list of values \'value1\', \'value2\', ... A SET column can\nhave a maximum of 64 members. SET values are represented internally as\nintegers.\n\nSET values cannot contain commas.\n\nIf a SET contains duplicate values, an error will be returned if strict mode\nis enabled, or a warning if strict mode is not enabled.\n\nURL: https://mariadb.com/kb/en/set-data-type/','','https://mariadb.com/kb/en/set-data-type/'); +insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (283,23,'DATE','Syntax\n------\n\nDATE\n\nDescription\n-----------\n\nA date. The supported range is \'1000-01-01\' to \'9999-12-31\'. MariaDB displays\nDATE values in \'YYYY-MM-DD\' format, but can be assigned dates in looser\nformats, including strings or numbers, as long as they make sense. These\ninclude a short year, YY-MM-DD, no delimiters, YYMMDD, or any other acceptable\ndelimiter, for example YYYY/MM/DD. For details, see date and time literals.\n\n\'0000-00-00\' is a permitted special value (zero-date), unless the NO_ZERO_DATE\nSQL_MODE is used. Also, individual components of a date can be set to 0 (for\nexample: \'2015-00-12\'), unless the NO_ZERO_IN_DATE SQL_MODE is used. In many\ncases, the result of en expression involving a zero-date, or a date with\nzero-parts, is NULL. If the ALLOW_INVALID_DATES SQL_MODE is enabled, if the\nday part is in the range between 1 and 31, the date does not produce any\nerror, even for months that have less than 31 days.\n\nOracle Mode\n-----------\n\nMariaDB starting with 10.3\n--------------------------\nIn Oracle mode from MariaDB 10.3, DATE with a time portion is a synonym for\nDATETIME. See also mariadb_schema.\n\nExamples\n--------\n\nCREATE TABLE t1 (d DATE);\n\nINSERT INTO t1 VALUES (\"2010-01-12\"), (\"2011-2-28\"), (\'120314\'),(\'13*04*21\');\n\nSELECT * FROM t1;\n+------------+\n| d |\n+------------+\n| 2010-01-12 |\n| 2011-02-28 |\n| 2012-03-14 |\n| 2013-04-21 |\n+------------+\n\nURL: https://mariadb.com/kb/en/date/','','https://mariadb.com/kb/en/date/'); +insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (284,23,'TIME','Syntax\n------\n\nTIME [()]\n\nDescription\n-----------\n\nA time. The range is \'-838:59:59.999999\' to \'838:59:59.999999\'. Microsecond\nprecision can be from 0-6; if not specified 0 is used. Microseconds have been\navailable since MariaDB 5.3.\n\nMariaDB displays TIME values in \'HH:MM:SS.ssssss\' format, but allows\nassignment of times in looser formats, including \'D HH:MM:SS\', \'HH:MM:SS\',\n\'HH:MM\', \'D HH:MM\', \'D HH\', \'SS\', or \'HHMMSS\', as well as permitting dropping\nof any leading zeros when a delimiter is provided, for example \'3:9:10\'. For\ndetails, see date and time literals.\n\nMariaDB starting with 10.1.2\n----------------------------\nMariaDB 10.1.2 introduced the --mysql56-temporal-format option, on by default,\nwhich allows MariaDB to store TIMEs using the same low-level format MySQL 5.6\nuses.\n\nInternal Format\n---------------\n\nIn MariaDB 10.1.2 a new temporal format was introduced from MySQL 5.6 that\nalters how the TIME, DATETIME and TIMESTAMP columns operate at lower levels.\nThese changes allow these temporal data types to have fractional parts and\nnegative values. You can disable this feature using the\nmysql56_temporal_format system variable.\n\nTables that include TIMESTAMP values that were created on an older version of\nMariaDB or that were created while the mysql56_temporal_format system variable\nwas disabled continue to store data using the older data type format.\n\nIn order to update table columns from the older format to the newer format,\nexecute an ALTER TABLE... MODIFY COLUMN statement that changes the column to\nthe *same* data type. This change may be needed if you want to export the\ntable\'s tablespace and import it onto a server that has\nmysql56_temporal_format=ON set (see MDEV-15225).\n\nFor instance, if you have a TIME column in your table:\n\nSHOW VARIABLES LIKE \'mysql56_temporal_format\';\n\n+-------------------------+-------+\n| Variable_name | Value |\n+-------------------------+-------+\n| mysql56_temporal_format | ON |\n+-------------------------+-------+\n\nALTER TABLE example_table MODIFY ts_col TIME;\n\nWhen MariaDB executes the ALTER TABLE statement, it converts the data from the\nolder temporal format to the newer one.\n\nIn the event that you have several tables and columns using temporal data\ntypes that you want to switch over to the new format, make sure the system\nvariable is enabled, then perform a dump and restore using mysqldump. The\ncolumns using relevant temporal data types are restored using the new temporal\nformat.\n\nStarting from MariaDB 10.5.1 columns with old temporal formats are marked with\na /* mariadb-5.3 */ comment in the output of SHOW CREATE TABLE, SHOW COLUMNS,\nDESCRIBE statements, as well as in the COLUMN_TYPE column of the\nINFORMATION_SCHEMA.COLUMNS Table.\n\nSHOW CREATE TABLE mariadb5312_time\\G\n*************************** 1. row ***************************\n Table: mariadb5312_time\nCreate Table: CREATE TABLE `mariadb5312_time` (\n `t0` time /* mariadb-5.3 */ DEFAULT NULL,\n `t6` time(6) /* mariadb-5.3 */ DEFAULT NULL\n) ENGINE=MyISAM DEFAULT CHARSET=latin1\n\nNote, columns with the current format are not marked with a comment.\n\nExamples\n--------\n\nINSERT INTO time VALUES (\'90:00:00\'), (\'800:00:00\'), (800), (22), (151413),\n(\'9:6:3\'), (\'12 09\');\n\nSELECT * FROM time;\n+-----------+\n| t |\n+-----------+\n| 90:00:00 |\n| 800:00:00 |\n| 00:08:00 |\n| 00:00:22 |\n| 15:14:13 |\n| 09:06:03 |\n| 297:00:00 |\n+-----------+\n\nURL: https://mariadb.com/kb/en/time/','','https://mariadb.com/kb/en/time/'); +insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (285,23,'DATETIME','Syntax\n------\n\nDATETIME [(microsecond precision)]\n\nDescription\n-----------\n\nA date and time combination.\n\nMariaDB displays DATETIME values in \'YYYY-MM-DD HH:MM:SS.ffffff\' format, but\nallows assignment of values to DATETIME columns using either strings or\nnumbers. For details, see date and time literals.\n\nDATETIME columns also accept CURRENT_TIMESTAMP as the default value.\n\nMariaDB 10.1.2 introduced the --mysql56-temporal-format option, on by default,\nwhich allows MariaDB to store DATETMEs using the same low-level format MySQL\n5.6 uses. For more information, see Internal Format, below.\n\nFor storage requirements, see Data Type Storage Requirements.\n\nSupported Values\n----------------\n\nMariaDB stores values that use the DATETIME data type in a format that\nsupports values between 1000-01-01 00:00:00.000000 and 9999-12-31\n23:59:59.999999.\n\nMariaDB can also store microseconds with a precision between 0 and 6. If no\nmicrosecond precision is specified, then 0 is used by default.\n\nMariaDB also supports \'0000-00-00\' as a special zero-date value, unless\nNO_ZERO_DATE is specified in the SQL_MODE. Similarly, individual components of\na date can be set to 0 (for example: \'2015-00-12\'), unless NO_ZERO_IN_DATE is\nspecified in the SQL_MODE. In many cases, the result of en expression\ninvolving a zero-date, or a date with zero-parts, is NULL. If the\nALLOW_INVALID_DATES SQL_MODE is enabled, if the day part is in the range\nbetween 1 and 31, the date does not produce any error, even for months that\nhave less than 31 days.\n\nTime Zones\n----------\n\nIf a column uses the DATETIME data type, then any inserted values are stored\nas-is, so no automatic time zone conversions are performed.\n\nMariaDB also does not currently support time zone literals that contain time\nzone identifiers. See MDEV-11829 for more information.\n\nMariaDB validates DATETIME literals against the session\'s time zone. For\nexample, if a specific time range never occurred in a specific time zone due\nto daylight savings time, then DATETIME values within that range would be\ninvalid for that time zone.\n\nFor example, daylight savings time started on March 10, 2019 in the US, so the\ntime range between 02:00:00 and 02:59:59 is invalid for that day in US time\nzones:\n\nSET time_zone = \'America/New_York\';\nQuery OK, 0 rows affected (0.000 sec)\n\nINSERT INTO timestamp_test VALUES (\'2019-03-10 02:55:05\');\nERROR 1292 (22007): Incorrect datetime value: \'2019-03-10 02:55:05\' for column\n`db1`.`timestamp_test`.`timestamp_test` at row 1\n\nBut that same time range is fine in other time zones, such as Coordinated\nUniversal Time (UTC). For example:\n\nSET time_zone = \'UTC\';\nQuery OK, 0 rows affected (0.000 sec)\n\nINSERT INTO timestamp_test VALUES (\'2019-03-10 02:55:05\');\nQuery OK, 1 row affected (0.002 sec)\n\nOracle Mode\n-----------\n\nMariaDB starting with 10.3\n--------------------------\nIn Oracle mode from MariaDB 10.3, DATE with a time portion is a synonym for\nDATETIME. See also mariadb_schema.\n\nInternal Format\n---------------\n\nIn MariaDB 10.1.2 a new temporal format was introduced from MySQL 5.6 that\nalters how the TIME, DATETIME and TIMESTAMP columns operate at lower levels.\nThese changes allow these temporal data types to have fractional parts and\nnegative values. You can disable this feature using the\nmysql56_temporal_format system variable.\n\nTables that include TIMESTAMP values that were created on an older version of\nMariaDB or that were created while the mysql56_temporal_format system variable\nwas disabled continue to store data using the older data type format.\n\nIn order to update table columns from the older format to the newer format,\nexecute an ALTER TABLE... MODIFY COLUMN statement that changes the column to\nthe *same* data type. This change may be needed if you want to export the\ntable\'s tablespace and import it onto a server that has\nmysql56_temporal_format=ON set (see MDEV-15225).\n\nFor instance, if you have a DATETIME column in your table:\n\nSHOW VARIABLES LIKE \'mysql56_temporal_format\';\n\n+-------------------------+-------+\n| Variable_name | Value |\n+-------------------------+-------+\n| mysql56_temporal_format | ON |\n+-------------------------+-------+\n\nALTER TABLE example_table MODIFY ts_col DATETIME;\n\nWhen MariaDB executes the ALTER TABLE statement, it converts the data from the\nolder temporal format to the newer one.\n\nIn the event that you have several tables and columns using temporal data\ntypes that you want to switch over to the new format, make sure the system\nvariable is enabled, then perform a dump and restore using mysqldump. The\ncolumns using relevant temporal data types are restored using the new temporal\nformat.\n\nStarting from MariaDB 10.5.1 columns with old temporal formats are marked with\na /* mariadb-5.3 */ comment in the output of SHOW CREATE TABLE, SHOW COLUMNS,\nDESCRIBE statements, as well as in the COLUMN_TYPE column of the\nINFORMATION_SCHEMA.COLUMNS Table.\n\nSHOW CREATE TABLE mariadb5312_datetime\\G\n*************************** 1. row ***************************\n Table: mariadb5312_datetime\nCreate Table: CREATE TABLE `mariadb5312_datetime` (\n `dt0` datetime /* mariadb-5.3 */ DEFAULT NULL,\n `dt6` datetime(6) /* mariadb-5.3 */ DEFAULT NULL\n) ENGINE=MyISAM DEFAULT CHARSET=latin1\n\nExamples\n--------\n\nCREATE TABLE t1 (d DATETIME);\n\nINSERT INTO t1 VALUES (\"2011-03-11\"), (\"2012-04-19 13:08:22\"),\n (\"2013-07-18 13:44:22.123456\");\n\nSELECT * FROM t1;\n+---------------------+','','https://mariadb.com/kb/en/datetime/'); +update help_topic set description = CONCAT(description, '\n| d |\n+---------------------+\n| 2011-03-11 00:00:00 |\n| 2012-04-19 13:08:22 |\n| 2013-07-18 13:44:22 |\n+---------------------+\n\nCREATE TABLE t2 (d DATETIME(6));\n\nINSERT INTO t2 VALUES (\"2011-03-11\"), (\"2012-04-19 13:08:22\"),\n (\"2013-07-18 13:44:22.123456\");\n\nSELECT * FROM t2;\n+----------------------------+\n| d |\n+----------------------------+\n| 2011-03-11 00:00:00.000000 |\n| 2012-04-19 13:08:22.000000 |\n| 2013-07-18 13:44:22.123456 |\n+----------------------------++\n\nStrings used in datetime context are automatically converted to datetime(6).\nIf you want to have a datetime without seconds, you should use\nCONVERT(..,datetime).\n\nSELECT CONVERT(\'2007-11-30 10:30:19\',datetime);\n+-----------------------------------------+\n| CONVERT(\'2007-11-30 10:30:19\',datetime) |\n+-----------------------------------------+\n| 2007-11-30 10:30:19 |\n+-----------------------------------------+\n\nSELECT CONVERT(\'2007-11-30 10:30:19\',datetime(6));\n+--------------------------------------------+\n| CONVERT(\'2007-11-30 10:30:19\',datetime(6)) |\n+--------------------------------------------+\n| 2007-11-30 10:30:19.000000 |\n+--------------------------------------------+\n\nURL: https://mariadb.com/kb/en/datetime/') WHERE help_topic_id = 285; +insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (286,23,'TIMESTAMP','Syntax\n------\n\nTIMESTAMP [(0) THEN BEGIN NOT ATOMIC SELECT 1; END ; END IF;;\n\nExample of how to use WHILE loop:\n\nDELIMITER |\nBEGIN NOT ATOMIC\n DECLARE x INT DEFAULT 0;\n WHILE x <= 10 DO\n SET x = x + 1;\n SELECT x;\n END WHILE;\nEND|\nDELIMITER ;\n\nURL:\nhttps://mariadb.com/kb/en/using-compound-statements-outside-of-stored-programs/','','https://mariadb.com/kb/en/using-compound-statements-outside-of-stored-programs/'); +insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (290,24,'BEGIN END','Syntax\n------\n\n[begin_label:] BEGIN [NOT ATOMIC]\n [statement_list]\nEND [end_label]\n\nNOT ATOMIC is required when used outside of a stored procedure. Inside stored\nprocedures or within an anonymous block, BEGIN alone starts a new anonymous\nblock.\n\nDescription\n-----------\n\nBEGIN ... END syntax is used for writing compound statements. A compound\nstatement can contain multiple statements, enclosed by the BEGIN and END\nkeywords. statement_list represents a list of one or more statements, each\nterminated by a semicolon (i.e., ;) statement delimiter. statement_list is\noptional, which means that the empty compound statement (BEGIN END) is legal.\n\nNote that END will perform a commit. If you are running in autocommit mode,\nevery statement will be committed separately. If you are not running in\nautocommit mode, you must execute a COMMIT or ROLLBACK after END to get the\ndatabase up to date.\n\nUse of multiple statements requires that a client is able to send statement\nstrings containing the ; statement delimiter. This is handled in the mysql\ncommand-line client with the DELIMITER command. Changing the ;\nend-of-statement delimiter (for example, to //) allows ; to be used in a\nprogram body.\n\nA compound statement within a stored program can be labeled. end_label cannot\nbe given unless begin_label also is present. If both are present, they must be\nthe same.\n\nBEGIN ... END constructs can be nested. Each block can define its own\nvariables, a CONDITION, a HANDLER and a CURSOR, which don\'t exist in the outer\nblocks. The most local declarations override the outer objects which use the\nsame name (see example below).\n\nThe declarations order is the following:\n\n* DECLARE local variables;\n* DECLARE CONDITIONs;\n* DECLARE CURSORs;\n* DECLARE HANDLERs;\n\nNote that DECLARE HANDLER contains another BEGIN ... END construct.\n\nHere is an example of a very simple, anonymous block:\n\nBEGIN NOT ATOMIC\nSET @a=1;\nCREATE TABLE test.t1(a INT);\nEND|\n\nBelow is an example of nested blocks in a stored procedure:\n\nCREATE PROCEDURE t( )\nBEGIN\n DECLARE x TINYINT UNSIGNED DEFAULT 1;\n BEGIN\n DECLARE x CHAR(2) DEFAULT \'02\';\n DECLARE y TINYINT UNSIGNED DEFAULT 10;\n SELECT x, y;\n END;\n SELECT x;\nEND;\n\nIn this example, a TINYINT variable, x is declared in the outter block. But in\nthe inner block x is re-declared as a CHAR and an y variable is declared. The\ninner SELECT shows the \"new\" value of x, and the value of y. But when x is\nselected in the outer block, the \"old\" value is returned. The final SELECT\ndoesn\'t try to read y, because it doesn\'t exist in that context.\n\nURL: https://mariadb.com/kb/en/begin-end/','','https://mariadb.com/kb/en/begin-end/'); +insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (291,24,'CASE Statement','Syntax\n------\n\nCASE case_value\n WHEN when_value THEN statement_list\n [WHEN when_value THEN statement_list] ...\n [ELSE statement_list]\nEND CASE\n\nOr:\n\nCASE\n WHEN search_condition THEN statement_list\n [WHEN search_condition THEN statement_list] ...\n [ELSE statement_list]\nEND CASE\n\nDescription\n-----------\n\nThe text on this page describes the CASE statement for stored programs. See\nthe CASE OPERATOR for details on the CASE operator outside of stored programs.\n\nThe CASE statement for stored programs implements a complex conditional\nconstruct. If a search_condition evaluates to true, the corresponding SQL\nstatement list is executed. If no search condition matches, the statement list\nin the ELSE clause is executed. Each statement_list consists of one or more\nstatements.\n\nThe CASE statement cannot have an ELSE NULL clause, and it is terminated with\nEND CASE instead of END. implements a complex conditional construct. If a\nsearch_condition evaluates to true, the corresponding SQL statement list is\nexecuted. If no search condition matches, the statement list in the ELSE\nclause is executed. Each statement_list consists of one or more statements.\n\nIf no when_value or search_condition matches the value tested and the CASE\nstatement contains no ELSE clause, a Case not found for CASE statement error\nresults.\n\nEach statement_list consists of one or more statements; an empty\nstatement_list is not allowed. To handle situations where no value is matched\nby any WHEN clause, use an ELSE containing an empty BEGIN ... END block, as\nshown in this example:\n\nDELIMITER |\nCREATE PROCEDURE p()\nBEGIN\n DECLARE v INT DEFAULT 1;\n CASE v\n WHEN 2 THEN SELECT v;\n WHEN 3 THEN SELECT 0;\n ELSE BEGIN END;\n END CASE;\nEND;\n|\n\nThe indentation used here in the ELSE clause is for purposes of clarity only,\nand is not otherwise significant. See Delimiters in the mysql client for more\non the use of the delimiter command.\n\nNote: The syntax of the CASE statement used inside stored programs differs\nslightly from that of the SQL CASE expression described in CASE OPERATOR. The\nCASE statement cannot have an ELSE NULL clause, and it is terminated with END\nCASE instead of END.\n\nURL: https://mariadb.com/kb/en/case-statement/','','https://mariadb.com/kb/en/case-statement/'); +insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (292,24,'DECLARE CONDITION','Syntax\n------\n\nDECLARE condition_name CONDITION FOR condition_value\n\ncondition_value:\n SQLSTATE [VALUE] sqlstate_value\n | mysql_error_code\n\nDescription\n-----------\n\nThe DECLARE ... CONDITION statement defines a named error condition. It\nspecifies a condition that needs specific handling and associates a name with\nthat condition. Later, the name can be used in a DECLARE ... HANDLER, SIGNAL\nor RESIGNAL statement (as long as the statement is located in the same BEGIN\n... END block).\n\nConditions must be declared after local variables, but before CURSORs and\nHANDLERs.\n\nA condition_value for DECLARE ... CONDITION can be an SQLSTATE value (a\n5-character string literal) or a MySQL error code (a number). You should not\nuse SQLSTATE value \'00000\' or MySQL error code 0, because those indicate\nsucess rather than an error condition. If you try, or if you specify an\ninvalid SQLSTATE value, an error like this is produced:\n\nERROR 1407 (42000): Bad SQLSTATE: \'00000\'\n\nFor a list of SQLSTATE values and MariaDB error codes, see MariaDB Error Codes.\n\nURL: https://mariadb.com/kb/en/declare-condition/','','https://mariadb.com/kb/en/declare-condition/'); +insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (293,24,'DECLARE HANDLER','Syntax\n------\n\nDECLARE handler_type HANDLER\n FOR condition_value [, condition_value] ...\n statement\n\nhandler_type:\n CONTINUE\n | EXIT\n | UNDO\n\ncondition_value:\n SQLSTATE [VALUE] sqlstate_value\n | condition_name\n | SQLWARNING\n | NOT FOUND\n | SQLEXCEPTION\n | mariadb_error_code\n\nDescription\n-----------\n\nThe DECLARE ... HANDLER statement specifies handlers that each may deal with\none or more conditions. If one of these conditions occurs, the specified\nstatement is executed. statement can be a simple statement (for example, SET\nvar_name = value), or it can be a compound statement written using BEGIN and\nEND.\n\nHandlers must be declared after local variables, a CONDITION and a CURSOR.\n\nFor a CONTINUE handler, execution of the current program continues after\nexecution of the handler statement. For an EXIT handler, execution terminates\nfor the BEGIN ... END compound statement in which the handler is declared.\n(This is true even if the condition occurs in an inner block.) The UNDO\nhandler type statement is not supported.\n\nIf a condition occurs for which no handler has been declared, the default\naction is EXIT.\n\nA condition_value for DECLARE ... HANDLER can be any of the following values:\n\n* An SQLSTATE value (a 5-character string literal) or a MariaDB error\ncode (a number). You should not use SQLSTATE value \'00000\' or MariaDB\nerror code 0, because those indicate sucess rather than an error\ncondition. For a list of SQLSTATE values and MariaDB error codes, see\nMariaDB Error Codes.\n* A condition name previously specified with DECLARE ... CONDITION. It must be\nin the same stored program. See DECLARE CONDITION.\n* SQLWARNING is shorthand for the class of SQLSTATE values that begin\nwith \'01\'.\n* NOT FOUND is shorthand for the class of SQLSTATE values that begin\nwith \'02\'. This is relevant only the context of cursors and is used to\ncontrol what happens when a cursor reaches the end of a data set. If\nno more rows are available, a No Data condition occurs with SQLSTATE\nvalue 02000. To detect this condition, you can set up a handler for it\n(or for a NOT FOUND condition). An example is shown in Cursor Overview. This\ncondition also occurs for SELECT ... INTO var_list statements that retrieve no\nrows.\n* SQLEXCEPTION is shorthand for the class of SQLSTATE values that do\nnot begin with \'00\', \'01\', or \'02\'.\n\nWhen an error raises, in some cases it could be handled by multiple HANDLERs.\nFor example, there may be an handler for 1050 error, a separate handler for\nthe 42S01 SQLSTATE, and another separate handler for the SQLEXCEPTION class:\nin theory all occurrences of HANDLER may catch the 1050 error, but MariaDB\nchooses the HANDLER with the highest precedence. Here are the precedence rules:\n\n* Handlers which refer to an error code have the highest precedence.\n* Handlers which refer to a SQLSTATE come next.\n* Handlers which refer to an error class have the lowest precedence.\n\nIn some cases, a statement could produce multiple errors. If this happens, in\nsome cases multiple handlers could have the highest precedence. In such cases,\nthe choice of the handler is indeterminate.\n\nNote that if an error occurs within a CONTINUE HANDLER block, it can be\nhandled by another HANDLER. However, a HANDLER which is already in the stack\n(that is, it has been called to handle an error and its execution didn\'t\nfinish yet) cannot handle new errors—this prevents endless loops. For example,\nsuppose that a stored procedure contains a CONTINUE HANDLER for SQLWARNING and\nanother CONTINUE HANDLER for NOT FOUND. At some point, a NOT FOUND error\noccurs, and the execution enters the NOT FOUND HANDLER. But within that\nhandler, a warning occurs, and the execution enters the SQLWARNING HANDLER. If\nanother NOT FOUND error occurs, it cannot be handled again by the NOT FOUND\nHANDLER, because its execution is not finished.\n\nWhen a DECLARE HANDLER block can handle more than one error condition, it may\nbe useful to know which errors occurred. To do so, you can use the GET\nDIAGNOSTICS statement.\n\nAn error that is handled by a DECLARE HANDLER construct can be issued again\nusing the RESIGNAL statement.\n\nBelow is an example using DECLARE HANDLER:\n\nCREATE TABLE test.t (s1 INT, PRIMARY KEY (s1));\n\nDELIMITER //\n\nCREATE PROCEDURE handlerdemo ( )\n BEGIN\n DECLARE CONTINUE HANDLER FOR SQLSTATE \'23000\' SET @x2 = 1;\n SET @x = 1;\n INSERT INTO test.t VALUES (1);\n SET @x = 2;\n INSERT INTO test.t VALUES (1);\n SET @x = 3;\n END;\n //\n\nDELIMITER ;\n\nCALL handlerdemo( );\n\nSELECT @x;\n+------+\n| @x |\n+------+\n| 3 |\n+------+\n\nURL: https://mariadb.com/kb/en/declare-handler/','','https://mariadb.com/kb/en/declare-handler/'); +insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (294,24,'DECLARE Variable','Syntax\n------\n\nDECLARE var_name [, var_name] ... [[ROW] TYPE OF]] type [DEFAULT value]\n\nDescription\n-----------\n\nThis statement is used to declare local variables within stored programs. To\nprovide a default value for the variable, include a DEFAULT clause. The value\ncan be specified as an expression (even subqueries are permitted); it need not\nbe a constant. If the DEFAULT clause is missing, the initial value is NULL.\n\nLocal variables are treated like stored routine parameters with respect to\ndata type and overflow checking. See CREATE PROCEDURE.\n\nLocal variables must be declared before CONDITIONs, CURSORs and HANDLERs.\n\nLocal variable names are not case sensitive.\n\nThe scope of a local variable is within the BEGIN ... END block where it is\ndeclared. The variable can be referred to in blocks nested within the\ndeclaring block, except those blocks that declare a variable with the same\nname.\n\nTYPE OF / ROW TYPE OF\n---------------------\n\nMariaDB starting with 10.3\n--------------------------\nTYPE OF and ROW TYPE OF anchored data types for stored routines were\nintroduced in MariaDB 10.3.\n\nAnchored data types allow a data type to be defined based on another object,\nsuch as a table row, rather than specifically set in the declaration. If the\nanchor object changes, so will the anchored data type. This can lead to\nroutines being easier to maintain, so that if the data type in the table is\nchanged, it will automatically be changed in the routine as well.\n\nVariables declared with ROW TYPE OF will have the same features as implicit\nROW variables. It is not possible to use ROW TYPE OF variables in a LIMIT\nclause.\n\nThe real data type of TYPE OF and ROW TYPE OF table_name will become known at\nthe very beginning of the stored routine call. ALTER TABLE or DROP TABLE\nstatements performed inside the current routine on the tables that appear in\nanchors won\'t affect the data type of the anchored variables, even if the\nvariable is declared after an ALTER TABLE or DROP TABLE statement.\n\nThe real data type of a ROW TYPE OF cursor_name variable will become known\nwhen execution enters into the block where the variable is declared. Data type\ninstantiation will happen only once. In a cursor ROW TYPE OF variable that is\ndeclared inside a loop, its data type will become known on the very first\niteration and won\'t change on further loop iterations.\n\nThe tables referenced in TYPE OF and ROW TYPE OF declarations will be checked\nfor existence at the beginning of the stored routine call. CREATE PROCEDURE or\nCREATE FUNCTION will not check the referenced tables for existence.\n\nExamples\n--------\n\nTYPE OF and ROW TYPE OF from MariaDB 10.3:\n\nDECLARE tmp TYPE OF t1.a; -- Get the data type from the column {{a}} in the\ntable {{t1}}\n\nDECLARE rec1 ROW TYPE OF t1; -- Get the row data type from the table {{t1}}\n\nDECLARE rec2 ROW TYPE OF cur1; -- Get the row data type from the cursor\n{{cur1}}\n\nURL: https://mariadb.com/kb/en/declare-variable/','','https://mariadb.com/kb/en/declare-variable/'); +insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (295,24,'FOR','MariaDB starting with 10.3\n--------------------------\nFOR loops were introduced in MariaDB 10.3.\n\nSyntax\n------\n\nInteger range FOR loop:\n\n[begin_label:]\nFOR var_name IN [ REVERSE ] lower_bound .. upper_bound\nDO statement_list\nEND FOR [ end_label ]\n\nExplicit cursor FOR loop\n\n[begin_label:]\nFOR record_name IN cursor_name [ ( cursor_actual_parameter_list)]\nDO statement_list\nEND FOR [ end_label ]\n\nExplicit cursor FOR loop (Oracle mode)\n\n[begin_label:]\nFOR record_name IN cursor_name [ ( cursor_actual_parameter_list)]\nLOOP\n statement_list\nEND LOOP [ end_label ]\n\nImplicit cursor FOR loop\n\n[begin_label:]\nFOR record_name IN ( select_statement )\nDO statement_list\nEND FOR [ end_label ]\n\nDescription\n-----------\n\nFOR loops allow code to be executed a fixed number of times.\n\nIn an integer range FOR loop, MariaDB will compare the lower bound and upper\nbound values, and assign the lower bound value to a counter. If REVERSE is not\nspecified, and the upper bound value is greater than or equal to the counter,\nthe counter will be incremented and the statement will continue, after which\nthe loop is entered again. If the upper bound value is greater than the\ncounter, the loop will be exited.\n\nIf REVERSE is specified, the counter is decremented, and the upper bound value\nneeds to be less than or equal for the loop to continue.\n\nExamples\n--------\n\nIntger range FOR loop:\n\nCREATE TABLE t1 (a INT);\n\nDELIMITER //\n\nFOR i IN 1..3\nDO\n INSERT INTO t1 VALUES (i);\nEND FOR;\n//\n\nDELIMITER ;\n\nSELECT * FROM t1;\n+------+\n| a |\n+------+\n| 1 |\n| 2 |\n| 3 |\n+------+\n\nREVERSE integer range FOR loop:\n\nCREATE OR REPLACE TABLE t1 (a INT);\n\nDELIMITER //\nFOR i IN REVERSE 4..12\n DO\n INSERT INTO t1 VALUES (i);\nEND FOR;\n//\nQuery OK, 9 rows affected (0.422 sec)\n\nDELIMITER ;\n\nSELECT * FROM t1;\n+------+\n| a |\n+------+\n| 12 |\n| 11 |\n| 10 |\n| 9 |\n| 8 |\n| 7 |\n| 6 |\n| 5 |\n| 4 |\n+------+\n\nExplicit cursor in Oracle mode:\n\nSET sql_mode=ORACLE;\n\nCREATE OR REPLACE TABLE t1 (a INT, b VARCHAR(32));\n\nINSERT INTO t1 VALUES (10,\'b0\');\nINSERT INTO t1 VALUES (11,\'b1\');\nINSERT INTO t1 VALUES (12,\'b2\');\n\nDELIMITER //\n\nCREATE OR REPLACE PROCEDURE p1(pa INT) AS \n CURSOR cur(va INT) IS\n SELECT a, b FROM t1 WHERE a=va;\nBEGIN\n FOR rec IN cur(pa)\n LOOP\n SELECT rec.a, rec.b;\n END LOOP;\nEND;\n//\n\nDELIMITER ;\n\nCALL p1(10);\n+-------+-------+\n| rec.a | rec.b |\n+-------+-------+\n| 10 | b0 |\n+-------+-------+\n\nCALL p1(11);\n+-------+-------+\n| rec.a | rec.b |\n+-------+-------+\n| 11 | b1 |\n+-------+-------+\n\nCALL p1(12);\n+-------+-------+\n| rec.a | rec.b |\n+-------+-------+\n| 12 | b2 |\n+-------+-------+\n\nCALL p1(13);\nQuery OK, 0 rows affected (0.000 sec)\n\nURL: https://mariadb.com/kb/en/for/','','https://mariadb.com/kb/en/for/'); +insert into help_topic (help_topic_id,help_category_id,name,description,example,url) values (296,24,'GOTO','MariaDB starting with 10.3\n--------------------------\nThe GOTO statement was introduced in MariaDB 10.3 for Oracle compatibility.\n\nSyntax\n------\n\nGOTO label\n\nDescription\n-----------\n\nThe GOTO statement causes the code to jump to the specified label, and\ncontinue operating from there. It is only accepted when in Oracle mode.\n\nExample\n-------\n\nSET sql_mode=ORACLE;\n\nDELIMITER //\n\nCREATE OR REPLACE PROCEDURE p1 AS\n\nBEGIN\n\nSELECT 1;\n GOTO label;\n SELECT 2;\n <