(530,'NOW',31,'Syntax\n------\n\nNOW([precision])\nCURRENT_TIMESTAMP\nCURRENT_TIMESTAMP([precision])\nLOCALTIME, LOCALTIME([precision])\nLOCALTIMESTAMP\nLOCALTIMESTAMP([precision])\n\nDescription\n-----------\n\nReturns the current date and time as a value in \'YYYY-MM-DD HH:MM:SS\' or\nYYYYMMDDHHMMSS.uuuuuu format, depending on whether the function is used in a\nstring or numeric context. The value is expressed in the current time zone.\n\nThe optional precision determines the microsecond precision. See Microseconds\nin MariaDB.\n\nNOW() (or its synonyms) can be used as the default value for TIMESTAMP columns\nas well as, since MariaDB 10.0.1, DATETIME columns. Before MariaDB 10.0.1, it\nwas only possible for a single TIMESTAMP column per table to contain the\nCURRENT_TIMESTAMP as its default.\n\nWhen displayed in the INFORMATION_SCHEMA.COLUMNS table, a default CURRENT\nTIMESTAMP is displayed as CURRENT_TIMESTAMP up until MariaDB 10.2.2, and as\ncurrent_timestamp() from MariaDB 10.2.3, due to to MariaDB 10.2 accepting\nexpressions in the DEFAULT clause.\n\nChanging the timestamp system variable with a SET timestamp statement affects\nthe value returned by NOW(), but not by SYSDATE().\n\nExamples\n--------\n\nSELECT NOW();\n+---------------------+\n| NOW()               |\n+---------------------+\n| 2010-03-27 13:13:25 |\n+---------------------+\n\nSELECT NOW() + 0;\n+-----------------------+\n| NOW() + 0             |\n+-----------------------+\n| 20100327131329.000000 |\n+-----------------------+\n\nWith precision:\n\nSELECT CURRENT_TIMESTAMP(2);\n+------------------------+\n| CURRENT_TIMESTAMP(2)   |\n+------------------------+\n| 2018-07-10 09:47:26.24 |\n+------------------------+\n\nUsed as a default TIMESTAMP:\n\nCREATE TABLE t (createdTS TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP);\n\nFrom MariaDB 10.2.2:\n\nSELECT * FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_SCHEMA=\'test\'\n AND COLUMN_NAME LIKE \'%ts%\'\\G\n*************************** 1. row ***************************\n     TABLE_CATALOG: def\n      TABLE_SCHEMA: test\n       TABLE_NAME: t\n      COLUMN_NAME: ts\n    ORDINAL_POSITION: 1\n     COLUMN_DEFAULT: current_timestamp()\n...\n\n<= MariaDB 10.2.1\n\nSELECT * FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_SCHEMA=\'test\'\n AND COLUMN_NAME LIKE \'%ts%\'\\G\n*************************** 1. row ***************************\n     TABLE_CATALOG: def\n      TABLE_SCHEMA: test\n       TABLE_NAME: t\n      COLUMN_NAME: createdTS\n    ORDINAL_POSITION: 1\n     COLUMN_DEFAULT: CURRENT_TIMESTAMP\n...\n\nURL: https://mariadb.com/kb/en/now/','','https://mariadb.com/kb/en/now/'),(531,'PERIOD_ADD',31,'Syntax\n------\n\nPERIOD_ADD(P,N)\n\nDescription\n-----------\n\nAdds N months to period P. P is in the format YYMM or YYYYMM, and is not a\ndate value. If P contains a two-digit year, values from 00 to 69 are converted\nto from 2000 to 2069, while values from 70 are converted to 1970 upwards.\n\nReturns a value in the format YYYYMM.\n\nExamples\n--------\n\nSELECT PERIOD_ADD(200801,2);\n+----------------------+\n| PERIOD_ADD(200801,2) |\n+----------------------+\n|               200803 |\n+----------------------+\n\nSELECT PERIOD_ADD(6910,2);\n+--------------------+\n| PERIOD_ADD(6910,2) |\n+--------------------+\n|             206912 |\n+--------------------+\n\nSELECT PERIOD_ADD(7010,2);\n+--------------------+\n| PERIOD_ADD(7010,2) |\n+--------------------+\n|             197012 |\n+--------------------+\n\nURL: https://mariadb.com/kb/en/period_add/','','https://mariadb.com/kb/en/period_add/'),(532,'PERIOD_DIFF',31,'Syntax\n------\n\nPERIOD_DIFF(P1,P2)\n\nDescription\n-----------\n\nReturns the number of months between periods P1 and P2. P1 and P2 can be in\nthe format YYMM or YYYYMM, and are not date values.\n\nIf P1 or P2 contains a two-digit year, values from 00 to 69 are converted to\nfrom 2000 to 2069, while values from 70 are converted to 1970 upwards.\n\nExamples\n--------\n\nSELECT PERIOD_DIFF(200802,200703);\n+----------------------------+\n| PERIOD_DIFF(200802,200703) |\n+----------------------------+\n|                         11 |\n+----------------------------+\n\nSELECT PERIOD_DIFF(6902,6803);\n+------------------------+\n| PERIOD_DIFF(6902,6803) |\n+------------------------+\n|                     11 |\n+------------------------+\n\nSELECT PERIOD_DIFF(7002,6803);\n+------------------------+\n| PERIOD_DIFF(7002,6803) |\n+------------------------+\n|                  -1177 |\n+------------------------+\n\nURL: https://mariadb.com/kb/en/period_diff/','','https://mariadb.com/kb/en/period_diff/'),(533,'QUARTER',31,'Syntax\n------\n\nQUARTER(date)\n\nDescription\n-----------\n\nReturns the quarter of the year for date, in the range 1 to 4. Returns 0 if\nmonth contains a zero value, or NULL if the given value is not otherwise a\nvalid date (zero values are accepted).\n\nExamples\n--------\n\nSELECT QUARTER(\'2008-04-01\');\n+-----------------------+\n| QUARTER(\'2008-04-01\') |\n+-----------------------+\n|                     2 |\n+-----------------------+\n\nSELECT QUARTER(\'2019-00-01\');\n+-----------------------+\n| QUARTER(\'2019-00-01\') |\n+-----------------------+\n|                     0 |\n+-----------------------+\n\nURL: https://mariadb.com/kb/en/quarter/','','https://mariadb.com/kb/en/quarter/'),(534,'SECOND',31,'Syntax\n------\n\nSECOND(time)\n\nDescription\n-----------\n\nReturns the second for a given time (which can include microseconds), in the\nrange 0 to 59, or NULL if not given a valid time value.\n\nExamples\n--------\n\nSELECT SECOND(\'10:05:03\');\n+--------------------+\n| SECOND(\'10:05:03\') |\n+--------------------+\n|                  3 |\n+--------------------+\n\nSELECT SECOND(\'10:05:01.999999\');\n+---------------------------+\n| SECOND(\'10:05:01.999999\') |\n+---------------------------+\n|                         1 |\n+---------------------------+\n\nURL: https://mariadb.com/kb/en/second/','','https://mariadb.com/kb/en/second/'),(535,'SEC_TO_TIME',31,'Syntax\n------\n\nSEC_TO_TIME(seconds)\n\nDescription\n-----------\n\nReturns the seconds argument, converted to hours, minutes, and seconds, as a\nTIME value. The range of the result is constrained to that of the TIME data\ntype. A warning occurs if the argument corresponds to a value outside that\nrange.\n\nThe time will be returned in the format hh:mm:ss, or hhmmss if used in a\nnumeric calculation.\n\nExamples\n--------\n\nSELECT SEC_TO_TIME(12414);\n+--------------------+\n| SEC_TO_TIME(12414) |\n+--------------------+\n| 03:26:54           |\n+--------------------+\n\nSELECT SEC_TO_TIME(12414)+0;\n+----------------------+\n| SEC_TO_TIME(12414)+0 |\n+----------------------+\n|                32654 |\n+----------------------+\n\nSELECT SEC_TO_TIME(9999999);\n+----------------------+\n| SEC_TO_TIME(9999999) |\n+----------------------+\n| 838:59:59            |\n+----------------------+\n1 row in set, 1 warning (0.00 sec)\n\nSHOW WARNINGS;\n+---------+------+-------------------------------------------+\n| Level   | Code | Message                                   |\n+---------+------+-------------------------------------------+\n| Warning | 1292 | Truncated incorrect time value: \'9999999\' |\n+---------+------+-------------------------------------------+\n\nURL: https://mariadb.com/kb/en/sec_to_time/','','https://mariadb.com/kb/en/sec_to_time/'),(536,'STR_TO_DATE',31,'Syntax\n------\n\nSTR_TO_DATE(str,format)\n\nDescription\n-----------\n\nThis is the inverse of the DATE_FORMAT() function. It takes a string str and a\nformat string format. STR_TO_DATE() returns a DATETIME value if the format\nstring contains both date and time parts, or a DATE or TIME value if the\nstring contains only date or time parts.\n\nThe date, time, or datetime values contained in str should be given in the\nformat indicated by format. If str contains an illegal date, time, or datetime\nvalue, STR_TO_DATE() returns NULL. An illegal value also produces a warning.\n\nUnder specific SQL_MODE settings an error may also be generated if the str\nisn\'t a valid date:\n\n* ALLOW_INVALID_DATES\n* NO_ZERO_DATE\n* NO_ZERO_IN_DATE\n\nThe options that can be used by STR_TO_DATE(), as well as its inverse\nDATE_FORMAT() and the FROM_UNIXTIME() function, are:\n\n+---------------------------+------------------------------------------------+\n| Option                    | Description                                    |\n+---------------------------+------------------------------------------------+\n| %a                        | Short weekday name in current locale           |\n|                           | (Variable lc_time_names).                      |\n+---------------------------+------------------------------------------------+\n| %b                        | Short form month name in current locale. For   |\n|                           | locale en_US this is one of:                   |\n|                           | Jan,Feb,Mar,Apr,May,Jun,Jul,Aug,Sep,Oct,Nov    |\n|                           | or Dec.                                        |\n+---------------------------+------------------------------------------------+\n| %c                        | Month with 1 or 2 digits.                      |\n+---------------------------+------------------------------------------------+\n| %D                        | Day with English suffix \'th\', \'nd\', \'st\' or    |\n|                           | \'rd\'\'. (1st, 2nd, 3rd...).                     |\n+---------------------------+------------------------------------------------+\n| %d                        | Day with 2 digits.                             |\n+---------------------------+------------------------------------------------+\n| %e                        | Day with 1 or 2 digits.                        |\n+---------------------------+------------------------------------------------+\n| %f                        | Microseconds 6 digits.                         |\n+---------------------------+------------------------------------------------+\n| %H                        | Hour with 2 digits between 00-23.              |\n+---------------------------+------------------------------------------------+\n| %h                        | Hour with 2 digits between 01-12.              |\n+---------------------------+------------------------------------------------+\n| %I                        | Hour with 2 digits between 01-12.              |\n+---------------------------+------------------------------------------------+\n| %i                        | Minute with 2 digits.                          |\n+---------------------------+------------------------------------------------+\n| %j                        | Day of the year (001-366)                      |\n+---------------------------+------------------------------------------------+\n| %k                        | Hour with 1 digits between 0-23.               |\n+---------------------------+------------------------------------------------+\n| %l                        | Hour with 1 digits between 1-12.               |\n+---------------------------+------------------------------------------------+\n| %M                        | Full month name in current locale (Variable    |\n|                           | lc_time_names).                                |\n+---------------------------+------------------------------------------------+\n| %m                        | Month with 2 digits.                           |\n+---------------------------+------------------------------------------------+\n| %p                        | AM/PM according to current locale (Variable    |\n|                           | lc_time_names).                                |\n+---------------------------+------------------------------------------------+\n| %r                        | Time in 12 hour format, followed by AM/PM.     |\n|                           | Short for \'%I:%i:%S %p\'.                       |\n+---------------------------+------------------------------------------------+\n| %S                        | Seconds with 2 digits.                         |\n+---------------------------+------------------------------------------------+\n| %s                        | Seconds with 2 digits.                         |\n+---------------------------+------------------------------------------------+\n| %T                        | Time in 24 hour format. Short for \'%H:%i:%S\'.  |\n+---------------------------+------------------------------------------------+\n| %U                        | Week number (00-53), when first day of the     |\n|                           | week is Sunday.                                |\n+---------------------------+------------------------------------------------+\n| %u                        | Week number (00-53), when first day of the     |\n|                           | week is Monday.                                |\n+---------------------------+------------------------------------------------+\n| %V                        | Week number (01-53), when first day of the     |\n|                           | week is Sunday. Used with %X.                  |\n+---------------------------+------------------------------------------------+\n| %v                        | Week number (01-53), when first day of the     |\n|                           | week is Monday. Used with %x.                  |\n+---------------------------+------------------------------------------------+\n| %W                        | Full weekday name in current locale (Variable  |\n|                           | lc_time_names).                                |\n+---------------------------+------------------------------------------------+\n| %w                        | Day of the week. 0 = Sunday, 6 = Saturday.     |\n+---------------------------+------------------------------------------------+\n| %X                        | Year with 4 digits when first day of the week  |\n|                           | is Sunday. Used with %V.                       |\n+---------------------------+------------------------------------------------+\n| %x                        | Year with 4 digits when first day of the week  |\n|                           | is Monday. Used with %v.                       |\n+---------------------------+------------------------------------------------+\n| %Y                        | Year with 4 digits.                            |\n+---------------------------+------------------------------------------------+\n| %y                        | Year with 2 digits.                            |\n+---------------------------+------------------------------------------------+\n| %#                        | For str_to_date(), skip all numbers.           |\n+---------------------------+------------------------------------------------+\n| %.                        | For str_to_date(), skip all punctation         |\n|                           | characters.                                    |\n+---------------------------+------------------------------------------------+\n| %@                        | For str_to_date(), skip all alpha characters.  |\n+---------------------------+------------------------------------------------+\n| %%                        | A literal % character.                         |\n+---------------------------+------------------------------------------------+\n\nExamples\n--------\n\nSELECT STR_TO_DATE(\'Wednesday, June 2, 2014\', \'%W, %M %e, %Y\');\n+---------------------------------------------------------+\n| STR_TO_DATE(\'Wednesday, June 2, 2014\', \'%W, %M %e, %Y\') |\n+---------------------------------------------------------+\n| 2014-06-02                                              |\n+---------------------------------------------------------+\n\nSELECT STR_TO_DATE(\'Wednesday23423, June 2, 2014\', \'%W, %M %e, %Y\');\n+--------------------------------------------------------------+\n| STR_TO_DATE(\'Wednesday23423, June 2, 2014\', \'%W, %M %e, %Y\') |\n+--------------------------------------------------------------+\n| NULL                                                         |\n+--------------------------------------------------------------+\n1 row in set, 1 warning (0.00 sec)\n\nSHOW WARNINGS;\n+---------+------+-------------------------------------------------------------\n---------------------+\n| Level   | Code | Message                                                    \n           |\n+---------+------+-------------------------------------------------------------\n---------------------+\n| Warning | 1411 | Incorrect datetime value: \'Wednesday23423, June 2, 2014\'\nfor function str_to_date |\n+---------+------+-------------------------------------------------------------\n---------------------+\n\nSELECT STR_TO_DATE(\'Wednesday23423, June 2, 2014\', \'%W%#, %M %e, %Y\');\n+----------------------------------------------------------------+\n| STR_TO_DATE(\'Wednesday23423, June 2, 2014\', \'%W%#, %M %e, %Y\') |\n+----------------------------------------------------------------+\n| 2014-06-02                                                     |\n+----------------------------------------------------------------+\n\nURL: https://mariadb.com/kb/en/str_to_date/','','https://mariadb.com/kb/en/str_to_date/'),(537,'SUBDATE',31,'Syntax\n------\n\nSUBDATE(date,INTERVAL expr unit), SUBDATE(expr,days)\n\nDescription\n-----------\n\nWhen invoked with the INTERVAL form of the second argument, SUBDATE() is a\nsynonym for DATE_SUB(). See Date and Time Units for a complete list of\npermitted units.\n\nThe second form allows the use of an integer value for days. In such cases, it\nis interpreted as the number of days to be subtracted from the date or\ndatetime expression expr.\n\nExamples\n--------\n\nSELECT DATE_SUB(\'2008-01-02\', INTERVAL 31 DAY);\n+-----------------------------------------+\n| DATE_SUB(\'2008-01-02\', INTERVAL 31 DAY) |\n+-----------------------------------------+\n| 2007-12-02                              |\n+-----------------------------------------+\n\nSELECT SUBDATE(\'2008-01-02\', INTERVAL 31 DAY);\n+----------------------------------------+\n| SUBDATE(\'2008-01-02\', INTERVAL 31 DAY) |\n+----------------------------------------+\n| 2007-12-02                             |\n+----------------------------------------+\n\nSELECT SUBDATE(\'2008-01-02 12:00:00\', 31);\n+------------------------------------+\n| SUBDATE(\'2008-01-02 12:00:00\', 31) |\n+------------------------------------+\n| 2007-12-02 12:00:00                |\n+------------------------------------+\n\nCREATE TABLE t1 (d DATETIME);\nINSERT INTO t1 VALUES\n  (\"2007-01-30 21:31:07\"),\n  (\"1983-10-15 06:42:51\"),\n  (\"2011-04-21 12:34:56\"),\n  (\"2011-10-30 06:31:41\"),\n  (\"2011-01-30 14:03:25\"),\n  (\"2004-10-07 11:19:34\");\n\nSELECT d, SUBDATE(d, 10) from t1;\n+---------------------+---------------------+\n| d                   | SUBDATE(d, 10)      |\n+---------------------+---------------------+\n| 2007-01-30 21:31:07 | 2007-01-20 21:31:07 |\n| 1983-10-15 06:42:51 | 1983-10-05 06:42:51 |\n| 2011-04-21 12:34:56 | 2011-04-11 12:34:56 |\n| 2011-10-30 06:31:41 | 2011-10-20 06:31:41 |\n| 2011-01-30 14:03:25 | 2011-01-20 14:03:25 |\n| 2004-10-07 11:19:34 | 2004-09-27 11:19:34 |\n+---------------------+---------------------+\n\nSELECT d, SUBDATE(d, INTERVAL 10 MINUTE) from t1;\n+---------------------+--------------------------------+\n| d                   | SUBDATE(d, INTERVAL 10 MINUTE) |\n+---------------------+--------------------------------+\n| 2007-01-30 21:31:07 | 2007-01-30 21:21:07            |\n| 1983-10-15 06:42:51 | 1983-10-15 06:32:51            |\n| 2011-04-21 12:34:56 | 2011-04-21 12:24:56            |\n| 2011-10-30 06:31:41 | 2011-10-30 06:21:41            |\n| 2011-01-30 14:03:25 | 2011-01-30 13:53:25            |\n| 2004-10-07 11:19:34 | 2004-10-07 11:09:34            |\n+---------------------+--------------------------------+\n\nURL: https://mariadb.com/kb/en/subdate/','','https://mariadb.com/kb/en/subdate/'),(538,'SUBTIME',31,'Syntax\n------\n\nSUBTIME(expr1,expr2)\n\nDescription\n-----------\n\nSUBTIME() returns expr1 - expr2 expressed as a value in the same format as\nexpr1. expr1 is a time or datetime expression, and expr2 is a time expression.\n\nExamples\n--------\n\nSELECT SUBTIME(\'2007-12-31 23:59:59.999999\',\'1 1:1:1.000002\');\n+--------------------------------------------------------+\n| SUBTIME(\'2007-12-31 23:59:59.999999\',\'1 1:1:1.000002\') |\n+--------------------------------------------------------+\n| 2007-12-30 22:58:58.999997                             |\n+--------------------------------------------------------+\n\nSELECT SUBTIME(\'01:00:00.999999\', \'02:00:00.999998\');\n+-----------------------------------------------+\n| SUBTIME(\'01:00:00.999999\', \'02:00:00.999998\') |\n+-----------------------------------------------+\n| -00:59:59.999999                              |\n+-----------------------------------------------+\n\nURL: https://mariadb.com/kb/en/subtime/','','https://mariadb.com/kb/en/subtime/'),(539,'SYSDATE',31,'Syntax\n------\n\nSYSDATE([precision])\n\nDescription\n-----------\n\nReturns the current date and time as a value in \'YYYY-MM-DD HH:MM:SS\' or\nYYYYMMDDHHMMSS.uuuuuu format, depending on whether the function is used in a\nstring or numeric context.\n\nThe optional precision determines the microsecond precision. See Microseconds\nin MariaDB.\n\nSYSDATE() returns the time at which it executes. This differs from the\nbehavior for NOW(), which returns a constant time that indicates the time at\nwhich the statement began to execute. (Within a stored routine or trigger,\nNOW() returns the time at which the routine or triggering statement began to\nexecute.)\n\nIn addition, changing the timestamp system variable with a SET timestamp\nstatement affects the value returned by NOW() but not by SYSDATE(). This means\nthat timestamp settings in the binary log have no effect on invocations of\nSYSDATE().\n\nBecause SYSDATE() can return different values even within the same statement,\nand is not affected by SET TIMESTAMP, it is non-deterministic and therefore\nunsafe for replication if statement-based binary logging is used. If that is a\nproblem, you can use row-based logging, or start the server with the mysqld\noption --sysdate-is-now to cause SYSDATE() to be an alias for NOW(). The\nnon-deterministic nature of SYSDATE() also means that indexes cannot be used\nfor evaluating expressions that refer to it, and that statements using the\nSYSDATE() function are unsafe for statement-based replication.\n\nExamples\n--------\n\nDifference between NOW() and SYSDATE():\n\nSELECT NOW(), SLEEP(2), NOW();\n+---------------------+----------+---------------------+\n| NOW()               | SLEEP(2) | NOW()               |\n+---------------------+----------+---------------------+\n| 2010-03-27 13:23:40 |        0 | 2010-03-27 13:23:40 |\n+---------------------+----------+---------------------+\n\nSELECT SYSDATE(), SLEEP(2), SYSDATE();\n+---------------------+----------+---------------------+\n| SYSDATE()           | SLEEP(2) | SYSDATE()           |\n+---------------------+----------+---------------------+\n| 2010-03-27 13:23:52 |        0 | 2010-03-27 13:23:54 |\n+---------------------+----------+---------------------+\n\nWith precision:\n\nSELECT SYSDATE(4);\n+--------------------------+\n| SYSDATE(4)               |\n+--------------------------+\n| 2018-07-10 10:17:13.1689 |\n+--------------------------+\n\nURL: https://mariadb.com/kb/en/sysdate/','','https://mariadb.com/kb/en/sysdate/'),(540,'TIME Function',31,'Syntax\n------\n\nTIME(expr)\n\nDescription\n-----------\n\nExtracts the time part of the time or datetime expression expr and returns it\nas a string.\n\nExamples\n--------\n\nSELECT TIME(\'2003-12-31 01:02:03\');\n+-----------------------------+\n| TIME(\'2003-12-31 01:02:03\') |\n+-----------------------------+\n| 01:02:03                    |\n+-----------------------------+\n\nSELECT TIME(\'2003-12-31 01:02:03.000123\');\n+------------------------------------+\n| TIME(\'2003-12-31 01:02:03.000123\') |\n+------------------------------------+\n| 01:02:03.000123                    |\n+------------------------------------+\n\nURL: https://mariadb.com/kb/en/time-function/','','https://mariadb.com/kb/en/time-function/'),(541,'TIMEDIFF',31,'Syntax\n------\n\nTIMEDIFF(expr1,expr2)\n\nDescription\n-----------\n\nTIMEDIFF() returns expr1 - expr2 expressed as a time value. expr1 and expr2\nare time or date-and-time expressions, but both must be of the same type.\n\nExamples\n--------\n\nSELECT TIMEDIFF(\'2000:01:01 00:00:00\', \'2000:01:01 00:00:00.000001\');\n+---------------------------------------------------------------+\n| TIMEDIFF(\'2000:01:01 00:00:00\', \'2000:01:01 00:00:00.000001\') |\n+---------------------------------------------------------------+\n| -00:00:00.000001                                              |\n+---------------------------------------------------------------+\n\nSELECT TIMEDIFF(\'2008-12-31 23:59:59.000001\', \'2008-12-30 01:01:01.000002\');\n+----------------------------------------------------------------------+\n| TIMEDIFF(\'2008-12-31 23:59:59.000001\', \'2008-12-30 01:01:01.000002\') |\n+----------------------------------------------------------------------+\n| 46:58:57.999999                                                      |\n+----------------------------------------------------------------------+\n\nURL: https://mariadb.com/kb/en/timediff/','','https://mariadb.com/kb/en/timediff/'),(542,'TIMESTAMP FUNCTION',31,'Syntax\n------\n\nTIMESTAMP(expr), TIMESTAMP(expr1,expr2)\n\nDescription\n-----------\n\nWith a single argument, this function returns the date or datetime expression\nexpr as a datetime value. With two arguments, it adds the time expression\nexpr2 to the date or datetime expression expr1 and returns the result as a\ndatetime value.\n\nExamples\n--------\n\nSELECT TIMESTAMP(\'2003-12-31\');\n+-------------------------+\n| TIMESTAMP(\'2003-12-31\') |\n+-------------------------+\n| 2003-12-31 00:00:00     |\n+-------------------------+\n\nSELECT TIMESTAMP(\'2003-12-31 12:00:00\',\'6:30:00\');\n+--------------------------------------------+\n| TIMESTAMP(\'2003-12-31 12:00:00\',\'6:30:00\') |\n+--------------------------------------------+\n| 2003-12-31 18:30:00                        |\n+--------------------------------------------+\n\nURL: https://mariadb.com/kb/en/timestamp-function/','','https://mariadb.com/kb/en/timestamp-function/'),(543,'TIMESTAMPADD',31,'Syntax\n------\n\nTIMESTAMPADD(unit,interval,datetime_expr)\n\nDescription\n-----------\n\nAdds the integer expression interval to the date or datetime expression\ndatetime_expr. The unit for interval is given by the unit argument, which\nshould be one of the following values: MICROSECOND, SECOND, MINUTE, HOUR, DAY,\nWEEK, MONTH, QUARTER, or YEAR.\n\nThe unit value may be specified using one of keywords as shown, or with a\nprefix of SQL_TSI_. For example, DAY and SQL_TSI_DAY both are legal.\n\nBefore MariaDB 5.5, FRAC_SECOND was permitted as a synonym for MICROSECOND.\n\nExamples\n--------\n\nSELECT TIMESTAMPADD(MINUTE,1,\'2003-01-02\');\n+-------------------------------------+\n| TIMESTAMPADD(MINUTE,1,\'2003-01-02\') |\n+-------------------------------------+\n| 2003-01-02 00:01:00                 |\n+-------------------------------------+\n\nSELECT TIMESTAMPADD(WEEK,1,\'2003-01-02\');\n+-----------------------------------+\n| TIMESTAMPADD(WEEK,1,\'2003-01-02\') |\n+-----------------------------------+\n| 2003-01-09                        |\n+-----------------------------------+\n\nURL: https://mariadb.com/kb/en/timestampadd/','','https://mariadb.com/kb/en/timestampadd/'),(544,'TIMESTAMPDIFF',31,'Syntax\n------\n\nTIMESTAMPDIFF(unit,datetime_expr1,datetime_expr2)\n\nDescription\n-----------\n\nReturns datetime_expr2 - datetime_expr1, where datetime_expr1 and\ndatetime_expr2 are date or datetime expressions. One expression may be a date\nand the other a datetime; a date value is treated as a datetime having the\ntime part \'00:00:00\' where necessary. The unit for the result (an integer) is\ngiven by the unit argument. The legal values for unit are the same as those\nlisted in the description of the TIMESTAMPADD() function, i.e MICROSECOND,\nSECOND, MINUTE, HOUR, DAY, WEEK, MONTH, QUARTER, or YEAR.\n\nTIMESTAMPDIFF can also be used to calculate age.\n\nExamples\n--------\n\nSELECT TIMESTAMPDIFF(MONTH,\'2003-02-01\',\'2003-05-01\');\n+------------------------------------------------+\n| TIMESTAMPDIFF(MONTH,\'2003-02-01\',\'2003-05-01\') |\n+------------------------------------------------+\n|                                              3 |\n+------------------------------------------------+\n\nSELECT TIMESTAMPDIFF(YEAR,\'2002-05-01\',\'2001-01-01\');\n+-----------------------------------------------+\n| TIMESTAMPDIFF(YEAR,\'2002-05-01\',\'2001-01-01\') |\n+-----------------------------------------------+\n|                                            -1 |\n+-----------------------------------------------+\n\nSELECT TIMESTAMPDIFF(MINUTE,\'2003-02-01\',\'2003-05-01 12:05:55\');\n+----------------------------------------------------------+\n| TIMESTAMPDIFF(MINUTE,\'2003-02-01\',\'2003-05-01 12:05:55\') |\n+----------------------------------------------------------+\n|                                                   128885 |\n+----------------------------------------------------------+\n\nCalculating age:\n\nSELECT CURDATE();\n+------------+\n| CURDATE()  |\n+------------+\n| 2019-05-27 |\n+------------+\n\nSELECT TIMESTAMPDIFF(YEAR, \'1971-06-06\', CURDATE()) AS age;\n+------+\n| age  |\n+------+\n|   47 |\n+------+\n\nSELECT TIMESTAMPDIFF(YEAR, \'1971-05-06\', CURDATE()) AS age;\n+------+\n| age  |\n+------+\n|   48 |\n+------+\n\nAge as of 2014-08-02:\n\nSELECT name, date_of_birth, TIMESTAMPDIFF(YEAR,date_of_birth,\'2014-08-02\') AS\nage \n FROM student_details;\n+---------+---------------+------+\n| name    | date_of_birth | age  |\n+---------+---------------+------+\n| Chun    | 1993-12-31    |   20 |\n| Esben   | 1946-01-01    |   68 |\n| Kaolin  | 1996-07-16    |   18 |\n| Tatiana | 1988-04-13    |   26 |\n+---------+---------------+------+\n\nURL: https://mariadb.com/kb/en/timestampdiff/','','https://mariadb.com/kb/en/timestampdiff/'),(545,'TIME_FORMAT',31,'Syntax\n------\n\nTIME_FORMAT(time,format)\n\nDescription\n-----------\n\nThis is used like the DATE_FORMAT() function, but the format string may\ncontain format specifiers only for hours, minutes, and seconds. Other\nspecifiers produce a NULL value or 0.\n\nExamples\n--------\n\nSELECT TIME_FORMAT(\'100:00:00\', \'%H %k %h %I %l\');\n+--------------------------------------------+\n| TIME_FORMAT(\'100:00:00\', \'%H %k %h %I %l\') |\n+--------------------------------------------+\n| 100 100 04 04 4                            |\n+--------------------------------------------+\n\nURL: https://mariadb.com/kb/en/time_format/','','https://mariadb.com/kb/en/time_format/'),(546,'TIME_TO_SEC',31,'Syntax\n------\n\nTIME_TO_SEC(time)\n\nDescription\n-----------\n\nReturns the time argument, converted to seconds.\n\nThe value returned by TIME_TO_SEC is of type DOUBLE. Before MariaDB 5.3 (and\nMySQL 5.6), the type was INT. The returned value preserves microseconds of the\nargument. See also Microseconds in MariaDB.\n\nExamples\n--------\n\nSELECT TIME_TO_SEC(\'22:23:00\');\n+-------------------------+\n| TIME_TO_SEC(\'22:23:00\') |\n+-------------------------+\n|                   80580 |\n+-------------------------+\n\nSELECT TIME_TO_SEC(\'00:39:38\');\n+-------------------------+\n| TIME_TO_SEC(\'00:39:38\') |\n+-------------------------+\n|                    2378 |\n+-------------------------+\n\nSELECT TIME_TO_SEC(\'09:12:55.2355\');\n+------------------------------+\n| TIME_TO_SEC(\'09:12:55.2355\') |\n+------------------------------+\n|                   33175.2355 |\n+------------------------------+\n1 row in set (0.000 sec)\n\nURL: https://mariadb.com/kb/en/time_to_sec/','','https://mariadb.com/kb/en/time_to_sec/'),(547,'TO_DAYS',31,'Syntax\n------\n\nTO_DAYS(date)\n\nDescription\n-----------\n\nGiven a date date, returns the number of days since the start of the current\ncalendar (0000-00-00).\n\nThe function is not designed for use with dates before the advent of the\nGregorian calendar in October 1582. Results will not be reliable since it\ndoesn\'t account for the lost days when the calendar changed from the Julian\ncalendar.\n\nThis is the converse of the FROM_DAYS() function.\n\nExamples\n--------\n\nSELECT TO_DAYS(\'2007-10-07\');\n+-----------------------+\n| TO_DAYS(\'2007-10-07\') |\n+-----------------------+\n|                733321 |\n+-----------------------+\n\nSELECT TO_DAYS(\'0000-01-01\');\n+-----------------------+\n| TO_DAYS(\'0000-01-01\') |\n+-----------------------+\n|                     1 |\n+-----------------------+\n\nSELECT TO_DAYS(950501);\n+-----------------+\n| TO_DAYS(950501) |\n+-----------------+\n|          728779 |\n+-----------------+\n\nURL: https://mariadb.com/kb/en/to_days/','','https://mariadb.com/kb/en/to_days/'),(548,'TO_SECONDS',31,'Syntax\n------\n\nTO_SECONDS(expr)\n\nDescription\n-----------\n\nReturns the number of seconds from year 0 till expr, or NULL if expr is not a\nvalid date or datetime.\n\nExamples\n--------\n\nSELECT TO_SECONDS(\'2013-06-13\');\n+--------------------------+\n| TO_SECONDS(\'2013-06-13\') |\n+--------------------------+\n|              63538300800 |\n+--------------------------+\n\nSELECT TO_SECONDS(\'2013-06-13 21:45:13\');\n+-----------------------------------+\n| TO_SECONDS(\'2013-06-13 21:45:13\') |\n+-----------------------------------+\n|                       63538379113 |\n+-----------------------------------+\n\nSELECT TO_SECONDS(NOW());\n+-------------------+\n| TO_SECONDS(NOW()) |\n+-------------------+\n|       63543530875 |\n+-------------------+\n\nSELECT TO_SECONDS(20130513);\n+----------------------+\n| TO_SECONDS(20130513) |\n+----------------------+\n|          63535622400 |\n+----------------------+\n1 row in set (0.00 sec)\n\nSELECT TO_SECONDS(130513);\n+--------------------+\n| TO_SECONDS(130513) |\n+--------------------+\n|        63535622400 |\n+--------------------+\n\nURL: https://mariadb.com/kb/en/to_seconds/','','https://mariadb.com/kb/en/to_seconds/'),(549,'UNIX_TIMESTAMP',31,'Syntax\n------\n\nUNIX_TIMESTAMP()\nUNIX_TIMESTAMP(date)\n\nDescription\n-----------\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() is\ncalled with a date argument, it returns the value of the argument as seconds\nsince \'1970-01-01 00:00:00\' UTC. date may be a DATE string, a DATETIME string,\na TIMESTAMP, or a number in the format YYMMDD or YYYYMMDD. The server\ninterprets date as a value in the current time zone and converts it to an\ninternal value in UTC. Clients can set their time zone as described in time\nzones.\n\nThe inverse function of UNIX_TIMESTAMP() is FROM_UNIXTIME()\n\nUNIX_TIMESTAMP() supports microseconds.\n\nTimestamps in MariaDB have a maximum value of 2147483647, equivalent to\n2038-01-19 05:14:07. This is due to the underlying 32-bit limitation. Using\nthe function on a date beyond this will result in NULL being returned. Use\nDATETIME as a storage type if you require dates beyond this.\n\nError Handling\n--------------\n\nReturns NULL for wrong arguments to UNIX_TIMESTAMP(). In MySQL and MariaDB\nbefore 5.3 wrong arguments to UNIX_TIMESTAMP() returned 0.\n\nCompatibility\n-------------\n\nAs you can see in the examples above, UNIX_TIMESTAMP(constant-date-string)\nreturns a timestamp with 6 decimals while MariaDB 5.2 and before returns it\nwithout decimals. This can cause a problem if you are using UNIX_TIMESTAMP()\nas a partitioning function. You can fix this by using\nFLOOR(UNIX_TIMESTAMP(..)) or changing the date string to a date number, like\n20080101000000.\n\nExamples\n--------\n\nSELECT UNIX_TIMESTAMP();\n+------------------+\n| UNIX_TIMESTAMP() |\n+------------------+\n|       1269711082 |\n+------------------+\n\nSELECT UNIX_TIMESTAMP(\'2007-11-30 10:30:19\');\n+---------------------------------------+\n| UNIX_TIMESTAMP(\'2007-11-30 10:30:19\') |\n+---------------------------------------+\n|                     1196436619.000000 |\n+---------------------------------------+\n\nSELECT UNIX_TIMESTAMP(\"2007-11-30 10:30:19.123456\");\n+----------------------------------------------+\n| unix_timestamp(\"2007-11-30 10:30:19.123456\") |\n+----------------------------------------------+\n|                            1196411419.123456 |\n+----------------------------------------------+\n\nSELECT FROM_UNIXTIME(UNIX_TIMESTAMP(\'2007-11-30 10:30:19\'));\n+------------------------------------------------------+\n| FROM_UNIXTIME(UNIX_TIMESTAMP(\'2007-11-30 10:30:19\')) |\n+------------------------------------------------------+\n| 2007-11-30 10:30:19.000000                           |\n+------------------------------------------------------+\n\nSELECT FROM_UNIXTIME(FLOOR(UNIX_TIMESTAMP(\'2007-11-30 10:30:19\')));\n+-------------------------------------------------------------+\n| FROM_UNIXTIME(FLOOR(UNIX_TIMESTAMP(\'2007-11-30 10:30:19\'))) |\n+-------------------------------------------------------------+\n| 2007-11-30 10:30:19                                         |\n+-------------------------------------------------------------+\n\nURL: https://mariadb.com/kb/en/unix_timestamp/','','https://mariadb.com/kb/en/unix_timestamp/'),(550,'UTC_DATE',31,'Syntax\n------\n\nUTC_DATE, UTC_DATE()\n\nDescription\n-----------\n\nReturns the current UTC date as a value in \'YYYY-MM-DD\' or YYYYMMDD format,\ndepending on whether the function is used in a string or numeric context.\n\nExamples\n--------\n\nSELECT UTC_DATE(), UTC_DATE() + 0;\n+------------+----------------+\n| UTC_DATE() | UTC_DATE() + 0 |\n+------------+----------------+\n| 2010-03-27 |       20100327 |\n+------------+----------------+\n\nURL: https://mariadb.com/kb/en/utc_date/','','https://mariadb.com/kb/en/utc_date/'),(551,'UTC_TIME',31,'Syntax\n------\n\nUTC_TIME\nUTC_TIME([precision])\n\nDescription\n-----------\n\nReturns the current UTC time as a value in \'HH:MM:SS\' or HHMMSS.uuuuuu format,\ndepending on whether the function is used in a string or numeric context.\n\nThe optional precision determines the microsecond precision. See Microseconds\nin MariaDB.\n\nExamples\n--------\n\nSELECT UTC_TIME(), UTC_TIME() + 0;\n+------------+----------------+\n| UTC_TIME() | UTC_TIME() + 0 |\n+------------+----------------+\n| 17:32:34   |  173234.000000 |\n+------------+----------------+\n\nWith precision:\n\nSELECT UTC_TIME(5);\n+----------------+\n| UTC_TIME(5)    |\n+----------------+\n| 07:52:50.78369 |\n+----------------+\n\nURL: https://mariadb.com/kb/en/utc_time/','','https://mariadb.com/kb/en/utc_time/'),(552,'UTC_TIMESTAMP',31,'Syntax\n------\n\nUTC_TIMESTAMP\nUTC_TIMESTAMP([precision])\n\nDescription\n-----------\n\nReturns the current UTC date and time as a value in \'YYYY-MM-DD HH:MM:SS\' or\nYYYYMMDDHHMMSS.uuuuuu format, depending on whether the function is used in a\nstring or numeric context.\n\nThe optional precision determines the microsecond precision. See Microseconds\nin MariaDB.\n\nExamples\n--------\n\nSELECT UTC_TIMESTAMP(), UTC_TIMESTAMP() + 0;\n+---------------------+-----------------------+\n| UTC_TIMESTAMP()     | UTC_TIMESTAMP() + 0   |\n+---------------------+-----------------------+\n| 2010-03-27 17:33:16 | 20100327173316.000000 |\n+---------------------+-----------------------+\n\nWith precision:\n\nSELECT UTC_TIMESTAMP(4);\n+--------------------------+\n| UTC_TIMESTAMP(4)         |\n+--------------------------+\n| 2018-07-10 07:51:09.1019 |\n+--------------------------+\n\nURL: https://mariadb.com/kb/en/utc_timestamp/','','https://mariadb.com/kb/en/utc_timestamp/'),(553,'WEEK',31,'Syntax\n------\n\nWEEK(date[,mode])\n\nDescription\n-----------\n\nThis function returns the week number for date. The two-argument form of\nWEEK() allows you to specify whether the week starts on Sunday or Monday and\nwhether the return value should be in the range from 0 to 53 or from 1 to 53.\nIf the mode argument is omitted, the value of the default_week_format system\nvariable is used.\n\nModes\n-----\n\n+-------+---------------------+--------+------------------------------------+\n| Mode  | 1st day of week     | Range  | Week 1 is the 1st week with        |\n+-------+---------------------+--------+------------------------------------+\n| 0     | Sunday              | 0-53   | a Sunday in this year              |\n+-------+---------------------+--------+------------------------------------+\n| 1     | Monday              | 0-53   | more than 3 days this year         |\n+-------+---------------------+--------+------------------------------------+\n| 2     | Sunday              | 1-53   | a Sunday in this year              |\n+-------+---------------------+--------+------------------------------------+\n| 3     | Monday              | 1-53   | more than 3 days this year         |\n+-------+---------------------+--------+------------------------------------+\n| 4     | Sunday              | 0-53   | more than 3 days this year         |\n+-------+---------------------+--------+------------------------------------+\n| 5     | Monday              | 0-53   | a Monday in this year              |\n+-------+---------------------+--------+------------------------------------+\n| 6     | Sunday              | 1-53   | more than 3 days this year         |\n+-------+---------------------+--------+------------------------------------+\n| 7     | Monday              | 1-53   | a Monday in this year              |\n+-------+---------------------+--------+------------------------------------+\n\nWith the mode value of 3, which means \'more than 3 days this year\', weeks are\nnumbered according to ISO 8601:1988.\n\nExamples\n--------\n\nSELECT WEEK(\'2008-02-20\');\n+--------------------+\n| WEEK(\'2008-02-20\') |\n+--------------------+\n|                  7 |\n+--------------------+\n\nSELECT WEEK(\'2008-02-20\',0);\n+----------------------+\n| WEEK(\'2008-02-20\',0) |\n+----------------------+\n|                    7 |\n+----------------------+\n\nSELECT WEEK(\'2008-02-20\',1);\n+----------------------+\n| WEEK(\'2008-02-20\',1) |\n+----------------------+\n|                    8 |\n+----------------------+\n\nSELECT WEEK(\'2008-12-31\',0);\n+----------------------+\n| WEEK(\'2008-12-31\',0) |\n+----------------------+\n|                   52 |\n+----------------------+\n\nSELECT WEEK(\'2008-12-31\',1);\n+----------------------+\n| WEEK(\'2008-12-31\',1) |\n+----------------------+\n|                   53 |\n+----------------------+\n\nSELECT WEEK(\'2019-12-30\',3);\n+----------------------+\n| WEEK(\'2019-12-30\',3) |\n+----------------------+\n|                    1 |\n+----------------------+\n\nCREATE TABLE t1 (d DATETIME);\nINSERT INTO t1 VALUES\n  (\"2007-01-30 21:31:07\"),\n  (\"1983-10-15 06:42:51\"),\n  (\"2011-04-21 12:34:56\"),\n  (\"2011-10-30 06:31:41\"),\n  (\"2011-01-30 14:03:25\"),\n  (\"2004-10-07 11:19:34\");\n\nSELECT d, WEEK(d,0), WEEK(d,1) from t1;\n+---------------------+-----------+-----------+\n| d                   | WEEK(d,0) | WEEK(d,1) |\n+---------------------+-----------+-----------+\n| 2007-01-30 21:31:07 |         4 |         5 |\n| 1983-10-15 06:42:51 |        41 |        41 |\n| 2011-04-21 12:34:56 |        16 |        16 |\n| 2011-10-30 06:31:41 |        44 |        43 |\n| 2011-01-30 14:03:25 |         5 |         4 |\n| 2004-10-07 11:19:34 |        40 |        41 |\n+---------------------+-----------+-----------+\n\nURL: https://mariadb.com/kb/en/week/','','https://mariadb.com/kb/en/week/'),(554,'WEEKDAY',31,'Syntax\n------\n\nWEEKDAY(date)\n\nDescription\n-----------\n\nReturns the weekday index for date (0 = Monday, 1 = Tuesday, ... 6 = Sunday).\n\nThis contrasts with DAYOFWEEK() which follows the ODBC standard (1 = Sunday, 2\n= Monday, ..., 7 = Saturday).\n\nExamples\n--------\n\nSELECT WEEKDAY(\'2008-02-03 22:23:00\');\n+--------------------------------+\n| WEEKDAY(\'2008-02-03 22:23:00\') |\n+--------------------------------+\n|                              6 |\n+--------------------------------+\n\nSELECT WEEKDAY(\'2007-11-06\');\n+-----------------------+\n| WEEKDAY(\'2007-11-06\') |\n+-----------------------+\n|                     1 |\n+-----------------------+\n\nCREATE TABLE t1 (d DATETIME);\nINSERT INTO t1 VALUES\n  (\"2007-01-30 21:31:07\"),\n  (\"1983-10-15 06:42:51\"),\n  (\"2011-04-21 12:34:56\"),\n  (\"2011-10-30 06:31:41\"),\n  (\"2011-01-30 14:03:25\"),\n  (\"2004-10-07 11:19:34\");\n\nSELECT d FROM t1 where WEEKDAY(d) = 6;\n+---------------------+\n| d                   |\n+---------------------+\n| 2011-10-30 06:31:41 |\n| 2011-01-30 14:03:25 |\n+---------------------+\n\nURL: https://mariadb.com/kb/en/weekday/','','https://mariadb.com/kb/en/weekday/'),(555,'WEEKOFYEAR',31,'Syntax\n------\n\nWEEKOFYEAR(date)\n\nDescription\n-----------\n\nReturns the calendar week of the date as a number in the range from 1 to 53.\nWEEKOFYEAR() is a compatibility function that is equivalent to WEEK(date,3).\n\nExamples\n--------\n\nSELECT WEEKOFYEAR(\'2008-02-20\');\n+--------------------------+\n| WEEKOFYEAR(\'2008-02-20\') |\n+--------------------------+\n|                        8 |\n+--------------------------+\n\nCREATE TABLE t1 (d DATETIME);\nINSERT INTO t1 VALUES\n  (\"2007-01-30 21:31:07\"),\n  (\"1983-10-15 06:42:51\"),\n  (\"2011-04-21 12:34:56\"),\n  (\"2011-10-30 06:31:41\"),\n  (\"2011-01-30 14:03:25\"),\n  (\"2004-10-07 11:19:34\");\n\nselect * from t1;\n+---------------------+\n| d                   |\n+---------------------+\n| 2007-01-30 21:31:07 |\n| 1983-10-15 06:42:51 |\n| 2011-04-21 12:34:56 |\n| 2011-10-30 06:31:41 |\n| 2011-01-30 14:03:25 |\n| 2004-10-07 11:19:34 |\n+---------------------+\n\nSELECT d, WEEKOFYEAR(d), WEEK(d,3) from t1;\n+---------------------+---------------+-----------+\n| d                   | WEEKOFYEAR(d) | WEEK(d,3) |\n+---------------------+---------------+-----------+\n| 2007-01-30 21:31:07 |             5 |         5 |\n| 1983-10-15 06:42:51 |            41 |        41 |\n| 2011-04-21 12:34:56 |            16 |        16 |\n| 2011-10-30 06:31:41 |            43 |        43 |\n| 2011-01-30 14:03:25 |             4 |         4 |\n| 2004-10-07 11:19:34 |            41 |        41 |\n+---------------------+---------------+-----------+\n\nURL: https://mariadb.com/kb/en/weekofyear/','','https://mariadb.com/kb/en/weekofyear/'),(556,'YEAR',31,'Syntax\n------\n\nYEAR(date)\n\nDescription\n-----------\n\nReturns the year for the given date, in the range 1000 to 9999, or 0 for the\n\"zero\" date.\n\nExamples\n--------\n\nCREATE TABLE t1 (d DATETIME);\nINSERT INTO t1 VALUES\n  (\"2007-01-30 21:31:07\"),\n  (\"1983-10-15 06:42:51\"),\n  (\"2011-04-21 12:34:56\"),\n  (\"2011-10-30 06:31:41\"),\n  (\"2011-01-30 14:03:25\"),\n  (\"2004-10-07 11:19:34\");\n\nSELECT * FROM t1;\n+---------------------+\n| d                   |\n+---------------------+\n| 2007-01-30 21:31:07 |\n| 1983-10-15 06:42:51 |\n| 2011-04-21 12:34:56 |\n| 2011-10-30 06:31:41 |\n| 2011-01-30 14:03:25 |\n| 2004-10-07 11:19:34 |\n+---------------------+\n\nSELECT * FROM t1 WHERE YEAR(d) = 2011;\n+---------------------+\n| d                   |\n+---------------------+\n| 2011-04-21 12:34:56 |\n| 2011-10-30 06:31:41 |\n| 2011-01-30 14:03:25 |\n+---------------------+\n\nSELECT YEAR(\'1987-01-01\');\n+--------------------+\n| YEAR(\'1987-01-01\') |\n+--------------------+\n|               1987 |\n+--------------------+\n\nURL: https://mariadb.com/kb/en/year/','','https://mariadb.com/kb/en/year/'),(557,'YEARWEEK',31,'Syntax\n------\n\nYEARWEEK(date), YEARWEEK(date,mode)\n\nDescription\n-----------\n\nReturns year and week for a date. The mode argument works exactly like the\nmode argument to WEEK(). The year in the result may be different from the year\nin the date argument for the first and the last week of the year.\n\nExamples\n--------\n\nSELECT YEARWEEK(\'1987-01-01\');\n+------------------------+\n| YEARWEEK(\'1987-01-01\') |\n+------------------------+\n|                 198652 |\n+------------------------+\n\nCREATE TABLE t1 (d DATETIME);\nINSERT INTO t1 VALUES\n  (\"2007-01-30 21:31:07\"),\n  (\"1983-10-15 06:42:51\"),\n  (\"2011-04-21 12:34:56\"),\n  (\"2011-10-30 06:31:41\"),\n  (\"2011-01-30 14:03:25\"),\n  (\"2004-10-07 11:19:34\");\n\nSELECT * FROM t1;\n+---------------------+\n| d                   |\n+---------------------+\n| 2007-01-30 21:31:07 |\n| 1983-10-15 06:42:51 |\n| 2011-04-21 12:34:56 |\n| 2011-10-30 06:31:41 |\n| 2011-01-30 14:03:25 |\n| 2004-10-07 11:19:34 |\n+---------------------+\n6 rows in set (0.02 sec)\n\nSELECT YEARWEEK(d) FROM t1 WHERE YEAR(d) = 2011;\n+-------------+\n| YEARWEEK(d) |\n+-------------+\n|      201116 |\n|      201144 |\n|      201105 |\n+-------------+\n3 rows in set (0.03 sec)\n\nURL: https://mariadb.com/kb/en/yearweek/','','https://mariadb.com/kb/en/yearweek/'),(558,'Well-Known Binary (WKB) Format',32,'WKB stands for Well-Known Binary, a format for representing geographical and\ngeometrical data.\n\nWKB uses 1-byte unsigned integers, 4-byte unsigned integers, and 8-byte\ndouble-precision numbers.\n\n* The first byte indicates the byte order. 00 for big endian, or 01 for little\nendian.\n* The next 4 bytes indicate the geometry type. Values from 1 to 7 indicate\nwhether the type is Point, LineString, Polygon, MultiPoint, MultiLineString,\nMultiPolygon, or GeometryCollection respectively. \n* The 8-byte floats represent the co-ordinates.\n\nTake the following example, a sequence of 21 bytes each represented by two hex\ndigits:\n\n000000000140000000000000004010000000000000\n\n* It\'s big endian\n000000000140000000000000004010000000000000\n\n* It\'s a POINT\n000000000140000000000000004010000000000000\n\n* The X co-ordinate is 2.0\n000000000140000000000000004010000000000000\n\n* The Y-co-ordinate is 4.0\n000000000140000000000000004010000000000000\n\nURL: https://mariadb.com/kb/en/well-known-binary-wkb-format/','','https://mariadb.com/kb/en/well-known-binary-wkb-format/'),(559,'AsBinary',32,'A synonym for ST_AsBinary().\n\nURL: https://mariadb.com/kb/en/wkb-asbinary/','','https://mariadb.com/kb/en/wkb-asbinary/'),(560,'AsWKB',32,'A synonym for ST_AsBinary().\n\nURL: https://mariadb.com/kb/en/aswkb/','','https://mariadb.com/kb/en/aswkb/'),(561,'MLineFromWKB',32,'Syntax\n------\n\nMLineFromWKB(wkb[,srid])\nMultiLineStringFromWKB(wkb[,srid])\n\nDescription\n-----------\n\nConstructs a MULTILINESTRING value using its WKB representation and SRID.\n\nMLineFromWKB() and MultiLineStringFromWKB() are synonyms.\n\nExamples\n--------\n\nSET @g = ST_AsBinary(MLineFromText(\'MULTILINESTRING((10 48,10 21,10 0),(16\n0,16 23,16 48))\'));\n\nSELECT ST_AsText(MLineFromWKB(@g));\n+--------------------------------------------------------+\n| ST_AsText(MLineFromWKB(@g))                            |\n+--------------------------------------------------------+\n| MULTILINESTRING((10 48,10 21,10 0),(16 0,16 23,16 48)) |\n+--------------------------------------------------------+\n\nURL: https://mariadb.com/kb/en/mlinefromwkb/','','https://mariadb.com/kb/en/mlinefromwkb/'),(562,'MPointFromWKB',32,'Syntax\n------\n\nMPointFromWKB(wkb[,srid])\nMultiPointFromWKB(wkb[,srid])\n\nDescription\n-----------\n\nConstructs a MULTIPOINT value using its WKB representation and SRID.\n\nMPointFromWKB() and MultiPointFromWKB() are synonyms.\n\nExamples\n--------\n\nSET @g = ST_AsBinary(MPointFromText(\'MultiPoint( 1 1, 2 2, 5 3, 7 2, 9 3, 8 4,\n6 6, 6 9, 4 9, 1 5 )\'));\n\nSELECT ST_AsText(MPointFromWKB(@g));\n+-----------------------------------------------------+\n| ST_AsText(MPointFromWKB(@g))                        |\n+-----------------------------------------------------+\n| MULTIPOINT(1 1,2 2,5 3,7 2,9 3,8 4,6 6,6 9,4 9,1 5) |\n+-----------------------------------------------------+\n\nURL: https://mariadb.com/kb/en/mpointfromwkb/','','https://mariadb.com/kb/en/mpointfromwkb/'),(563,'MPolyFromWKB',32,'Syntax\n------\n\nMPolyFromWKB(wkb[,srid])\nMultiPolygonFromWKB(wkb[,srid])\n\nDescription\n-----------\n\nConstructs a MULTIPOLYGON value using its WKB representation and SRID.\n\nMPolyFromWKB() and MultiPolygonFromWKB() are synonyms.\n\nExamples\n--------\n\nSET @g = ST_AsBinary(MPointFromText(\'MULTIPOLYGON(((28 26,28 0,84 0,84 42,28\n26),(52 18,66 23,73 9,48 6,52 18)),((59 18,67 18,67 13,59 13,59 18)))\'));\n\nSELECT ST_AsText(MPolyFromWKB(@g))\\G\n*************************** 1. row ***************************\nST_AsText(MPolyFromWKB(@g)): MULTIPOLYGON(((28 26,28 0,84 0,84 42,28 26),(52\n18,66 23,73 9,48 6,52 18)),((59 18,67 18,67 13,59 13,59 18)))\n\nURL: https://mariadb.com/kb/en/mpolyfromwkb/','','https://mariadb.com/kb/en/mpolyfromwkb/'),(564,'GeomCollFromWKB',32,'A synonym for ST_GeomCollFromWKB.\n\nURL: https://mariadb.com/kb/en/wkb-geomcollfromwkb/','','https://mariadb.com/kb/en/wkb-geomcollfromwkb/'),(565,'GeometryCollectionFromWKB',32,'A synonym for ST_GeomCollFromWKB.\n\nURL: https://mariadb.com/kb/en/geometrycollectionfromwkb/','','https://mariadb.com/kb/en/geometrycollectionfromwkb/'),(566,'GeometryFromWKB',32,'A synonym for ST_GeomFromWKB.\n\nURL: https://mariadb.com/kb/en/geometryfromwkb/','','https://mariadb.com/kb/en/geometryfromwkb/'),(567,'GeomFromWKB',32,'A synonym for ST_GeomFromWKB.\n\nURL: https://mariadb.com/kb/en/wkb-geomfromwkb/','','https://mariadb.com/kb/en/wkb-geomfromwkb/'),(568,'LineFromWKB',32,'A synonym for ST_LineFromWKB.\n\nURL: https://mariadb.com/kb/en/wkb-linefromwkb/','','https://mariadb.com/kb/en/wkb-linefromwkb/'),(569,'LineStringFromWKB',32,'A synonym for ST_LineFromWKB.\n\nURL: https://mariadb.com/kb/en/linestringfromwkb/','','https://mariadb.com/kb/en/linestringfromwkb/'),(570,'MultiLineStringFromWKB',32,'A synonym for MLineFromWKB().\n\nURL: https://mariadb.com/kb/en/multilinestringfromwkb/','','https://mariadb.com/kb/en/multilinestringfromwkb/'),(571,'MultiPointFromWKB',32,'A synonym for MPointFromWKB.\n\nURL: https://mariadb.com/kb/en/multipointfromwkb/','','https://mariadb.com/kb/en/multipointfromwkb/'),(572,'MultiPolygonFromWKB',32,'Synonym for MPolyFromWKB.\n\nURL: https://mariadb.com/kb/en/multipolygonfromwkb/','','https://mariadb.com/kb/en/multipolygonfromwkb/'),(573,'PointFromWKB',32,'A synonym for ST_PointFromWKB.\n\nURL: https://mariadb.com/kb/en/wkb-pointfromwkb/','','https://mariadb.com/kb/en/wkb-pointfromwkb/'),(574,'PolyFromWKB',32,'A synonym for ST_PolyFromWKB.\n\nURL: https://mariadb.com/kb/en/wkb-polyfromwkb/','','https://mariadb.com/kb/en/wkb-polyfromwkb/'),(575,'PolygonFromWKB',32,'A synonym for ST_PolyFromWKB.\n\nURL: https://mariadb.com/kb/en/polygonfromwkb/','','https://mariadb.com/kb/en/polygonfromwkb/'),(576,'ST_AsBinary',32,'Syntax\n------\n\nST_AsBinary(g)\nAsBinary(g)\nST_AsWKB(g)\nAsWKB(g)\n\nDescription\n-----------\n\nConverts a value in internal geometry format to its WKB representation and\nreturns the binary result.\n\nST_AsBinary(), AsBinary(), ST_AsWKB() and AsWKB() are synonyms,\n\nExamples\n--------\n\nSET @poly = ST_GeomFromText(\'POLYGON((0 0,0 1,1 1,1 0,0 0))\');\nSELECT ST_AsBinary(@poly);\n\nSELECT ST_AsText(ST_GeomFromWKB(ST_AsWKB(@poly)));\n+--------------------------------------------+\n| ST_AsText(ST_GeomFromWKB(ST_AsWKB(@poly))) |\n+--------------------------------------------+\n| POLYGON((0 0,0 1,1 1,1 0,0 0))             |\n+--------------------------------------------+\n\nURL: https://mariadb.com/kb/en/st_asbinary/','','https://mariadb.com/kb/en/st_asbinary/'),(577,'ST_AsWKB',32,'A synonym for ST_AsBinary().\n\nURL: https://mariadb.com/kb/en/st_aswkb/','','https://mariadb.com/kb/en/st_aswkb/'),(578,'ST_GeomCollFromWKB',32,'Syntax\n------\n\nST_GeomCollFromWKB(wkb[,srid])\nST_GeometryCollectionFromWKB(wkb[,srid])\nGeomCollFromWKB(wkb[,srid])\nGeometryCollectionFromWKB(wkb[,srid])\n\nDescription\n-----------\n\nConstructs a GEOMETRYCOLLECTION value using its WKB representation and SRID.\n\nST_GeomCollFromWKB(), ST_GeometryCollectionFromWKB(), GeomCollFromWKB() and\nGeometryCollectionFromWKB() are synonyms.\n\nExamples\n--------\n\nSET @g = ST_AsBinary(ST_GeomFromText(\'GEOMETRYCOLLECTION(\n POLYGON((5 5,10 5,10 10,5 5)),POINT(10 10))\'));\n\nSELECT ST_AsText(ST_GeomCollFromWKB(@g));\n+----------------------------------------------------------------+\n| ST_AsText(ST_GeomCollFromWKB(@g))                              |\n+----------------------------------------------------------------+\n| GEOMETRYCOLLECTION(POLYGON((5 5,10 5,10 10,5 5)),POINT(10 10)) |\n+----------------------------------------------------------------+\n\nURL: https://mariadb.com/kb/en/st_geomcollfromwkb/','','https://mariadb.com/kb/en/st_geomcollfromwkb/'),(579,'ST_GeometryCollectionFromWKB',32,'A synonym for ST_GeomCollFromWKB.\n\nURL: https://mariadb.com/kb/en/st_geometrycollectionfromwkb/','','https://mariadb.com/kb/en/st_geometrycollectionfromwkb/'),(580,'ST_GeometryFromWKB',32,'A synonym for ST_GeomFromWKB.\n\nURL: https://mariadb.com/kb/en/st_geometryfromwkb/','','https://mariadb.com/kb/en/st_geometryfromwkb/'),(581,'ST_GeomFromWKB',32,'Syntax\n------\n\nST_GeomFromWKB(wkb[,srid])\nST_GeometryFromWKB(wkb[,srid])\nGeomFromWKB(wkb[,srid])\nGeometryFromWKB(wkb[,srid])\n\nDescription\n-----------\n\nConstructs a geometry value of any type using its WKB representation and SRID.\n\nST_GeomFromWKB(), ST_GeometryFromWKB(), GeomFromWKB() and GeometryFromWKB()\nare synonyms.\n\nExamples\n--------\n\nSET @g = ST_AsBinary(ST_LineFromText(\'LINESTRING(0 4, 4 6)\'));\n\nSELECT ST_AsText(ST_GeomFromWKB(@g));\n+-------------------------------+\n| ST_AsText(ST_GeomFromWKB(@g)) |\n+-------------------------------+\n| LINESTRING(0 4,4 6)           |\n+-------------------------------+\n\nURL: https://mariadb.com/kb/en/st_geomfromwkb/','','https://mariadb.com/kb/en/st_geomfromwkb/'),(582,'ST_LineFromWKB',32,'Syntax\n------\n\nST_LineFromWKB(wkb[,srid])\nLineFromWKB(wkb[,srid])\nST_LineStringFromWKB(wkb[,srid])\nLineStringFromWKB(wkb[,srid])\n\nDescription\n-----------\n\nConstructs a LINESTRING value using its WKB representation and SRID.\n\nST_LineFromWKB(), LineFromWKB(), ST_LineStringFromWKB(), and\nLineStringFromWKB() are synonyms.\n\nExamples\n--------\n\nSET @g = ST_AsBinary(ST_LineFromText(\'LineString(0 4,4 6)\'));\n\nSELECT ST_AsText(ST_LineFromWKB(@g)) AS l;\n+---------------------+\n| l                   |\n+---------------------+\n| LINESTRING(0 4,4 6) |\n+---------------------+\n\nURL: https://mariadb.com/kb/en/st_linefromwkb/','','https://mariadb.com/kb/en/st_linefromwkb/'),(583,'ST_LineStringFromWKB',32,'A synonym for ST_LineFromWKB.\n\nURL: https://mariadb.com/kb/en/st_linestringfromwkb/','','https://mariadb.com/kb/en/st_linestringfromwkb/'),(584,'ST_PointFromWKB',32,'Syntax\n------\n\nST_PointFromWKB(wkb[,srid])\nPointFromWKB(wkb[,srid])\n\nDescription\n-----------\n\nConstructs a POINT value using its WKB representation and SRID.\n\nST_PointFromWKB() and PointFromWKB() are synonyms.\n\nExamples\n--------\n\nSET @g = ST_AsBinary(ST_PointFromText(\'POINT(0 4)\'));\n\nSELECT ST_AsText(ST_PointFromWKB(@g)) AS p;\n+------------+\n| p          |\n+------------+\n| POINT(0 4) |\n+------------+\n\nURL: https://mariadb.com/kb/en/st_pointfromwkb/','','https://mariadb.com/kb/en/st_pointfromwkb/'),(585,'ST_PolyFromWKB',32,'Syntax\n------\n\nST_PolyFromWKB(wkb[,srid])\nST_PolygonFromWKB(wkb[,srid])\nPolyFromWKB(wkb[,srid])\nPolygonFromWKB(wkb[,srid])\n\nDescription\n-----------\n\nConstructs a POLYGON value using its WKB representation and SRID.\n\nST_PolyFromWKB(), ST_PolygonFromWKB(), PolyFromWKB() and PolygonFromWKB() are\nsynonyms.\n\nExamples\n--------\n\nSET @g = ST_AsBinary(ST_PolyFromText(\'POLYGON((1 1,1 5,4 9,6 9,9 3,7 2,1\n1))\'));\n\nSELECT ST_AsText(ST_PolyFromWKB(@g)) AS p;\n+----------------------------------------+\n| p                                      |\n+----------------------------------------+\n| POLYGON((1 1,1 5,4 9,6 9,9 3,7 2,1 1)) |\n+----------------------------------------+\n\nURL: https://mariadb.com/kb/en/st_polyfromwkb/','','https://mariadb.com/kb/en/st_polyfromwkb/'),(586,'ST_PolygonFromWKB',32,'A synonym for ST_PolyFromWKB.\n\nURL: https://mariadb.com/kb/en/st_polygonfromwkb/','','https://mariadb.com/kb/en/st_polygonfromwkb/'),(587,'Geometry Types',34,'Description\n-----------\n\nMariaDB provides a standard way of creating spatial columns for geometry\ntypes, for example, with CREATE TABLE or ALTER TABLE. Currently, spatial\ncolumns are supported for MyISAM, InnoDB and ARCHIVE tables. See also SPATIAL\nINDEX.\n\nThe basic geometry type is GEOMETRY. But the type can be more specific. The\nfollowing types are supported:\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\nExamples\n--------\n\nNote: For clarity, only one type is listed per table in the examples below,\nbut a table row can contain multiple types. For example:\n\nCREATE TABLE object (shapeA POLYGON, shapeB LINESTRING);\n\nPOINT\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\nLINESTRING\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\nPOLYGON\n-------\n\nCREATE TABLE gis_polygon   (g POLYGON);\nSHOW FIELDS FROM gis_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  (PolyFromWKB(AsWKB(Polygon(LineString(Point(0, 0), Point(30, 0), Point(30,\n30), Point(0, 0))))));\n\nMULTIPOINT\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\nMULTILINESTRING\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(LineString(Point(1, 2), Point(3, 5)),\nLineString(Point(2, 5), Point(5, 8), Point(21, 7))))));\n\nMULTIPOLYGON\n------------\n\nCREATE TABLE gis_multi_polygon  (g MULTIPOLYGON);\nSHOW FIELDS FROM gis_multi_polygon;\nINSERT INTO gis_multi_polygon VALUES\n  (MultiPolygonFromText(\'MULTIPOLYGON(((28 26,28 0,84 0,84 42,28 26),(52\n18,66 23,73 9,48 6,52 18)),((59 18,67 18,67 13,59 13,59 18)))\')),\n  (MPolyFromText(\'MULTIPOLYGON(((28 26,28 0,84 0,84 42,28 26),(52 18,66\n23,73 9,48 6,52 18)),((59 18,67 18,67 13,59 13,59 18)))\')),\n  (MPolyFromWKB(AsWKB(MultiPolygon(Polygon(LineString(Point(0, 3), Point(3,\n3), Point(3, 0), Point(0, 3)))))));\n\nGEOMETRYCOLLECTION\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\nGEOMETRY\n--------\n\nCREATE TABLE gis_geometry (g GEOMETRY);\nSHOW FIELDS FROM gis_geometry;\nINSERT into gis_geometry SELECT * FROM gis_point;\nINSERT into gis_geometry SELECT * FROM gis_line;\nINSERT into gis_geometry SELECT * FROM gis_polygon;\nINSERT into gis_geometry SELECT * FROM gis_multi_point;\nINSERT into gis_geometry SELECT * FROM gis_multi_line;\nINSERT into gis_geometry SELECT * FROM gis_multi_polygon;\nINSERT into gis_geometry SELECT * FROM gis_geometrycollection;\n\nURL: https://mariadb.com/kb/en/geometry-types/','','https://mariadb.com/kb/en/geometry-types/'),(588,'Geometry Hierarchy',34,'Description\n-----------\n\nGeometry is the base class. It is an abstract class. The instantiable\nsubclasses of Geometry are restricted to zero-, one-, and two-dimensional\ngeometric objects that exist in two-dimensional coordinate space. All\ninstantiable geometry classes are defined so that valid instances of a\ngeometry class are topologically closed (that is, all defined geometries\ninclude their boundary).\n\nThe base Geometry class has subclasses for Point, Curve, Surface, and\nGeometryCollection:\n\n* Point represents zero-dimensional objects.\n* Curve represents one-dimensional objects, and has subclass LineString, with\nsub-subclasses Line and LinearRing.\n* Surface is designed for two-dimensional objects and has subclass Polygon.\n* GeometryCollection has specialized zero-, one-, and two-dimensional\ncollection classes named MultiPoint, MultiLineString, and MultiPolygon for\nmodeling geometries corresponding to collections of Points, LineStrings, and\nPolygons, respectively. MultiCurve and MultiSurface are introduced as abstract\nsuperclasses that generalize the collection interfaces to handle Curves and\nSurfaces.\n\nGeometry, Curve, Surface, MultiCurve, and MultiSurface are defined as\nnon-instantiable classes. They define a common set of methods for their\nsubclasses and are included for extensibility.\n\nPoint, LineString, Polygon, GeometryCollection, MultiPoint, MultiLineString,\nand MultiPolygon are instantiable classes.\n\nURL: https://mariadb.com/kb/en/geometry-hierarchy/','','https://mariadb.com/kb/en/geometry-hierarchy/'),(589,'SPATIAL INDEX',34,'Description\n-----------\n\nOn MyISAM, Aria and InnoDB tables, MariaDB can create spatial indexes (an\nR-tree index) using syntax similar to that for creating regular indexes, but\nextended with the SPATIAL keyword. Currently, columns in spatial indexes must\nbe declared NOT NULL.\n\nSpatial indexes can be created when the table is created, or added after the\nfact like so:\n\n* with CREATE TABLE: CREATE TABLE geom (g GEOMETRY NOT NULL, SPATIAL INDEX(g));\n\n* with ALTER TABLE: ALTER TABLE geom ADD SPATIAL INDEX(g);\n\n* with CREATE INDEX: CREATE SPATIAL INDEX sp_index ON geom (g);\n\nSPATIAL INDEX creates an R-tree index. For storage engines that support\nnon-spatial indexing of spatial columns, the engine creates a B-tree index. A\nB-tree index on spatial values is useful for exact-value lookups, but not for\nrange scans.\n\nFor more information on indexing spatial columns, see CREATE INDEX.\n\nTo drop spatial indexes, use ALTER TABLE or DROP INDEX:\n\n* with ALTER TABLE: ALTER TABLE geom DROP INDEX g;\n\n* with DROP INDEX: DROP INDEX sp_index ON geom;\n\nData-at-Rest Encyption\n----------------------\n\nBefore MariaDB 10.4.3, InnoDB\'s spatial indexes could not be encrypted. If an\nInnoDB table was encrypted and if it contained spatial indexes, then those\nindexes would be unencrypted.\n\nIn MariaDB 10.4.3 and later, if innodb_checksum_algorithm is set to full_crc32\nor strict_full_crc32, and if the table does not use ROW_FORMAT=COMPRESSED,\nthen InnoDB spatial indexes will be encrypted if the table is encrypted.\n\nSee MDEV-12026 for more information.\n\nURL: https://mariadb.com/kb/en/spatial-index/','','https://mariadb.com/kb/en/spatial-index/'),(590,'BOUNDARY',35,'A synonym for ST_BOUNDARY.\n\nURL: https://mariadb.com/kb/en/geometry-properties-boundary/','','https://mariadb.com/kb/en/geometry-properties-boundary/'),(591,'DIMENSION',35,'A synonym for ST_DIMENSION.\n\nURL: https://mariadb.com/kb/en/dimension/','','https://mariadb.com/kb/en/dimension/'),(592,'ENVELOPE',35,'A synonym for ST_ENVELOPE.\n\nURL: https://mariadb.com/kb/en/geometry-properties-envelope/','','https://mariadb.com/kb/en/geometry-properties-envelope/'),(593,'GeometryN',35,'A synonym for ST_GeometryN.\n\nURL: https://mariadb.com/kb/en/geometry-properties-geometryn/','','https://mariadb.com/kb/en/geometry-properties-geometryn/'),(594,'GeometryType',35,'A synonym for ST_GeometryType.\n\nURL: https://mariadb.com/kb/en/geometry-properties-geometrytype/','','https://mariadb.com/kb/en/geometry-properties-geometrytype/'),(595,'IsClosed',35,'A synonym for ST_IsClosed.\n\nURL: https://mariadb.com/kb/en/isclosed/','','https://mariadb.com/kb/en/isclosed/'),(596,'IsEmpty',35,'A synonym for ST_IsEmpty.\n\nURL: https://mariadb.com/kb/en/geometry-properties-isempty/','','https://mariadb.com/kb/en/geometry-properties-isempty/'),(597,'IsRing',35,'A synonym for ST_IsRing.\n\nURL: https://mariadb.com/kb/en/isring/','','https://mariadb.com/kb/en/isring/'),(598,'IsSimple',35,'A synonym for ST_IsSImple.\n\nURL: https://mariadb.com/kb/en/geometry-properties-issimple/','','https://mariadb.com/kb/en/geometry-properties-issimple/'),(599,'NumGeometries',35,'A synonym for ST_NumGeometries.\n\nURL: https://mariadb.com/kb/en/geometry-properties-numgeometries/','','https://mariadb.com/kb/en/geometry-properties-numgeometries/'),(600,'SRID',35,'A synonym for ST_SRID.\n\nURL: https://mariadb.com/kb/en/geometry-properties-srid/','','https://mariadb.com/kb/en/geometry-properties-srid/'),(601,'ST_BOUNDARY',35,'MariaDB starting with 10.1.2\n----------------------------\nThe ST_BOUNDARY function was introduced in MariaDB 10.1.2\n\nSyntax\n------\n\nST_BOUNDARY(g)\nBOUNDARY(g)\n\nDescription\n-----------\n\nReturns a geometry that is the closure of the combinatorial boundary of the\ngeometry value g.\n\nBOUNDARY() is a synonym.\n\nExamples\n--------\n\nSELECT ST_AsText(ST_Boundary(ST_GeomFromText(\'LINESTRING(3 3,0 0, -3 3)\')));\n+----------------------------------------------------------------------+\n| ST_AsText(ST_Boundary(ST_GeomFromText(\'LINESTRING(3 3,0 0, -3 3)\'))) |\n+----------------------------------------------------------------------+\n| MULTIPOINT(3 3,-3 3)                                                 |\n+----------------------------------------------------------------------+\n\nSELECT ST_AsText(ST_Boundary(ST_GeomFromText(\'POLYGON((3 3,0 0, -3 3, 3\n3))\')));\n+--------------------------------------------------------------------------+\n| ST_AsText(ST_Boundary(ST_GeomFromText(\'POLYGON((3 3,0 0, -3 3, 3 3))\'))) |\n+--------------------------------------------------------------------------+\n| LINESTRING(3 3,0 0,-3 3,3 3)                                             |\n+--------------------------------------------------------------------------+\n\nURL: https://mariadb.com/kb/en/st_boundary/','','https://mariadb.com/kb/en/st_boundary/'),(602,'ST_DIMENSION',35,'Syntax\n------\n\nST_Dimension(g)\nDimension(g)\n\nDescription\n-----------\n\nReturns the inherent dimension of the geometry value g. The result can be\n\n+------------------------------------+---------------------------------------+\n| Dimension                          | Definition                            |\n+------------------------------------+---------------------------------------+\n| -1                                 | empty geometry                        |\n+------------------------------------+---------------------------------------+\n| 0                                  | geometry with no length or area       |\n+------------------------------------+---------------------------------------+\n| 1                                  | geometry with no area but nonzero     |\n|                                    | length                                |\n+------------------------------------+---------------------------------------+\n| 2                                  | geometry with nonzero area            |\n+------------------------------------+---------------------------------------+\n\nST_Dimension() and Dimension() are synonyms.\n\nExamples\n--------\n\nSELECT Dimension(GeomFromText(\'LineString(1 1,2 2)\'));\n+------------------------------------------------+\n| Dimension(GeomFromText(\'LineString(1 1,2 2)\')) |\n+------------------------------------------------+\n|                                              1 |\n+------------------------------------------------+\n\nURL: https://mariadb.com/kb/en/st_dimension/','','https://mariadb.com/kb/en/st_dimension/'),(603,'ST_ENVELOPE',35,'Syntax\n------\n\nST_ENVELOPE(g)\nENVELOPE(g)\n\nDescription\n-----------\n\nReturns the Minimum Bounding Rectangle (MBR) for the geometry value g. The\nresult 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\nST_ENVELOPE() and ENVELOPE() are synonyms.\n\nExamples\n--------\n\nSELECT AsText(ST_ENVELOPE(GeomFromText(\'LineString(1 1,4 4)\')));\n+----------------------------------------------------------+\n| AsText(ST_ENVELOPE(GeomFromText(\'LineString(1 1,4 4)\'))) |\n+----------------------------------------------------------+\n| POLYGON((1 1,4 1,4 4,1 4,1 1))                           |\n+----------------------------------------------------------+\n\nURL: https://mariadb.com/kb/en/st_envelope/','','https://mariadb.com/kb/en/st_envelope/'),(604,'ST_GEOMETRYN',35,'Syntax\n------\n\nST_GeometryN(gc,N)\nGeometryN(gc,N)\n\nDescription\n-----------\n\nReturns the N-th geometry in the GeometryCollection gc. Geometries are\nnumbered beginning with 1.\n\nST_GeometryN() and GeometryN() are synonyms.\n\nExample\n-------\n\nSET @gc = \'GeometryCollection(Point(1 1),LineString(12 14, 9 11))\';\n\nSELECT AsText(GeometryN(GeomFromText(@gc),1));\n+----------------------------------------+\n| AsText(GeometryN(GeomFromText(@gc),1)) |\n+----------------------------------------+\n| POINT(1 1)                             |\n+----------------------------------------+\n\nURL: https://mariadb.com/kb/en/st_geometryn/','','https://mariadb.com/kb/en/st_geometryn/'),(605,'ST_GEOMETRYTYPE',35,'Syntax\n------\n\nST_GeometryType(g)\nGeometryType(g)\n\nDescription\n-----------\n\nReturns as a string the name of the geometry type of which the geometry\ninstance g is a member. The name corresponds to one of the instantiable\nGeometry subclasses.\n\nST_GeometryType() and GeometryType() are synonyms.\n\nExamples\n--------\n\nSELECT GeometryType(GeomFromText(\'POINT(1 1)\'));\n+------------------------------------------+\n| GeometryType(GeomFromText(\'POINT(1 1)\')) |\n+------------------------------------------+\n| POINT                                    |\n+------------------------------------------+\n\nURL: https://mariadb.com/kb/en/st_geometrytype/','','https://mariadb.com/kb/en/st_geometrytype/'),(606,'ST_ISCLOSED',35,'Syntax\n------\n\nST_IsClosed(g)\nIsClosed(g)\n\nDescription\n-----------\n\nReturns 1 if a given LINESTRING\'s start and end points are the same, or 0 if\nthey are not the same. Before MariaDB 10.1.5, returns NULL if not given a\nLINESTRING. After MariaDB 10.1.5, returns -1.\n\nST_IsClosed() and IsClosed() are synonyms.\n\nExamples\n--------\n\nSET @ls = \'LineString(0 0, 0 4, 4 4, 0 0)\';\nSELECT ST_ISCLOSED(GEOMFROMTEXT(@ls));\n+--------------------------------+\n| ST_ISCLOSED(GEOMFROMTEXT(@ls)) |\n+--------------------------------+\n|                              1 |\n+--------------------------------+\n\nSET @ls = \'LineString(0 0, 0 4, 4 4, 0 1)\';\nSELECT ST_ISCLOSED(GEOMFROMTEXT(@ls));\n+--------------------------------+\n| ST_ISCLOSED(GEOMFROMTEXT(@ls)) |\n+--------------------------------+\n|                              0 |\n+--------------------------------+\n\nURL: https://mariadb.com/kb/en/st_isclosed/','','https://mariadb.com/kb/en/st_isclosed/'),(607,'ST_ISEMPTY',35,'Syntax\n------\n\nST_IsEmpty(g)\nIsEmpty(g)\n\nDescription\n-----------\n\nIsEmpty is a function defined by the OpenGIS specification, but is not fully\nimplemented by MariaDB or MySQL.\n\nSince MariaDB and MySQL do not support GIS EMPTY values such as POINT EMPTY,\nas implemented it simply returns 1 if the geometry value g is invalid, 0 if it\nis valid, and NULL if the argument is NULL.\n\nST_IsEmpty() and IsEmpty() are synonyms.\n\nURL: https://mariadb.com/kb/en/st_isempty/','','https://mariadb.com/kb/en/st_isempty/'),(608,'ST_IsRing',35,'MariaDB starting with 10.1.2\n----------------------------\nThe ST_IsRing function was introduced in MariaDB 10.1.2\n\nSyntax\n------\n\nST_IsRing(g)\nIsRing(g)\n\nDescription\n-----------\n\nReturns true if a given LINESTRING is a ring, that is, both ST_IsClosed and\nST_IsSimple. A simple curve does not pass through the same point more than\nonce. However, see MDEV-7510.\n\nSt_IsRing() and IsRing() are synonyms.\n\nURL: https://mariadb.com/kb/en/st_isring/','','https://mariadb.com/kb/en/st_isring/'),(609,'ST_IsSimple',35,'Syntax\n------\n\nST_IsSimple(g)\nIsSimple(g)\n\nDescription\n-----------\n\nReturns true if the given Geometry has no anomalous geometric points, false if\nit does, or NULL if given a NULL value.\n\nST_IsSimple() and IsSimple() are synonyms.\n\nExamples\n--------\n\nA POINT is always simple.\n\nSET @g = \'Point(1 2)\';\n\nSELECT ST_ISSIMPLE(GEOMFROMTEXT(@g));\n+-------------------------------+\n| ST_ISSIMPLE(GEOMFROMTEXT(@g)) |\n+-------------------------------+\n|                             1 |\n+-------------------------------+\n\nURL: https://mariadb.com/kb/en/st_issimple/','','https://mariadb.com/kb/en/st_issimple/'),(610,'ST_NUMGEOMETRIES',35,'Syntax\n------\n\nST_NumGeometries(gc)\nNumGeometries(gc)\n\nDescription\n-----------\n\nReturns the number of geometries in the GeometryCollection gc.\n\nST_NumGeometries() and NumGeometries() are synonyms.\n\nExample\n-------\n\nSET @gc = \'GeometryCollection(Point(1 1),LineString(2 2, 3 3))\';\n\nSELECT NUMGEOMETRIES(GeomFromText(@gc));\n+----------------------------------+\n| NUMGEOMETRIES(GeomFromText(@gc)) |\n+----------------------------------+\n|                                2 |\n+----------------------------------+\n\nURL: https://mariadb.com/kb/en/st_numgeometries/','','https://mariadb.com/kb/en/st_numgeometries/'),(611,'ST_RELATE',35,'MariaDB starting with 10.1.2\n----------------------------\nThe ST_RELATE() function was introduced in MariaDB 10.1.2\n\nSyntax\n------\n\nST_Relate(g1, g2, i)\n\nDescription\n-----------\n\nReturns true if Geometry g1 is spatially related to Geometryg2 by testing for\nintersections between the interior, boundary and exterior of the two\ngeometries as specified by the values in intersection matrix pattern i.\n\nURL: https://mariadb.com/kb/en/st_relate/','','https://mariadb.com/kb/en/st_relate/'),(612,'ST_SRID',35,'Syntax\n------\n\nST_SRID(g)\nSRID(g)\n\nDescription\n-----------\n\nReturns an integer indicating the Spatial Reference System ID for the geometry\nvalue g.\n\nIn MariaDB, the SRID value is just an integer associated with the geometry\nvalue. All calculations are done assuming Euclidean (planar) geometry.\n\nST_SRID() and SRID() are synonyms.\n\nExamples\n--------\n\nSELECT SRID(GeomFromText(\'LineString(1 1,2 2)\',101));\n+-----------------------------------------------+\n| SRID(GeomFromText(\'LineString(1 1,2 2)\',101)) |\n+-----------------------------------------------+\n|                                           101 |\n+-----------------------------------------------+\n\nURL: https://mariadb.com/kb/en/st_srid/','','https://mariadb.com/kb/en/st_srid/'),(613,'LOAD_FILE',36,'Syntax\n------\n\nLOAD_FILE(file_name)\n\nDescription\n-----------\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 the\nfull path name to the file, and you must have the FILE privilege. The file\nmust be readable by all and it must be less than the size, in bytes, of the\nmax_allowed_packet system variable. If the secure_file_priv system variable is\nset to a non-empty directory name, the file to be loaded must be located in\nthat directory.\n\nIf the file does not exist or cannot be read because one of the preceding\nconditions is not satisfied, the function returns NULL.\n\nSince MariaDB 5.1, the character_set_filesystem system variable has controlled\ninterpretation of file names that are given as literal strings.\n\nStatements using the LOAD_FILE() function are not safe for statement based\nreplication. This is because the slave will execute the LOAD_FILE() command\nitself. If the file doesn\'t exist on the slave, the function will return NULL.\n\nExamples\n--------\n\nUPDATE t SET blob_col=LOAD_FILE(\'/tmp/picture\') WHERE id=1;\n\nURL: https://mariadb.com/kb/en/load_file/','','https://mariadb.com/kb/en/load_file/'),(614,'NOT REGEXP',36,'Syntax\n------\n\nexpr NOT REGEXP pat, expr NOT RLIKE pat\n\nDescription\n-----------\n\nThis is the same as NOT (expr REGEXP pat).\n\nURL: https://mariadb.com/kb/en/not-regexp/','','https://mariadb.com/kb/en/not-regexp/'),(615,'REGEXP',36,'Syntax\n------\n\nexpr REGEXP pat, expr RLIKE pat\n\nDescription\n-----------\n\nPerforms a pattern match of a string expression expr against a pattern pat.\nThe pattern can be an extended regular expression. See Regular Expressions\nOverview for details on the syntax for regular expressions (see also PCRE\nRegular Expressions).\n\nReturns 1 if expr matches pat or 0 if it doesn\'t match. If either expr or pat\nare NULL, the result is NULL.\n\nThe negative form NOT REGEXP also exists, as an alias for NOT (string REGEXP\npattern). RLIKE and NOT RLIKE are synonyms for REGEXP and NOT REGEXP,\noriginally provided for mSQL compatibility.\n\nThe pattern need not be a literal string. For example, it can be specified as\na string expression or table column.\n\nNote: Because MariaDB uses the C escape syntax in strings (for example, \"\\n\"\nto represent the newline character), you must double any \"\\\" that you use in\nyour REGEXP strings.\n\nREGEXP is not case sensitive, except when used with binary strings.\n\nMariaDB 10.0.5 moved to the PCRE regex library - see PCRE Regular Expressions\nfor enhancements to REGEXP introduced in MariaDB 10.0.5.\n\nThe default_regex_flags variable addresses the remaining compatibilities\nbetween PCRE and the old regex library.\n\nExamples\n--------\n\nSELECT \'Monty!\' REGEXP \'m%y%%\';\n+-------------------------+\n| \'Monty!\' REGEXP \'m%y%%\' |\n+-------------------------+\n|                       0 |\n+-------------------------+\n\nSELECT \'Monty!\' REGEXP \'.*\';\n+----------------------+\n| \'Monty!\' REGEXP \'.*\' |\n+----------------------+\n|                    1 |\n+----------------------+\n\nSELECT \'new*\\n*line\' REGEXP \'new\\\\*.\\\\*line\';\n+---------------------------------------+\n| \'new*\\n*line\' REGEXP \'new\\\\*.\\\\*line\' |\n+---------------------------------------+\n|                                     1 |\n+---------------------------------------+\n\nSELECT \'a\' REGEXP \'A\', \'a\' REGEXP BINARY \'A\';\n+----------------+-----------------------+\n| \'a\' REGEXP \'A\' | \'a\' REGEXP BINARY \'A\' |\n+----------------+-----------------------+\n|              1 |                     0 |\n+----------------+-----------------------+\n\nSELECT \'a\' REGEXP \'^[a-d]\';\n+---------------------+\n| \'a\' REGEXP \'^[a-d]\' |\n+---------------------+\n|                   1 |\n+---------------------+\n\ndefault_regex_flags examples\n----------------------------\n\nMariaDB 10.0.11 introduced the default_regex_flags variable to address the\nremaining compatibilities between PCRE and the old regex library.\n\nThe default behaviour (multiline match is off)\n\nSELECT \'a\\nb\\nc\' RLIKE \'^b$\';\n+---------------------------+\n| \'(?m)a\\nb\\nc\' RLIKE \'^b$\' |\n+---------------------------+\n|                         0 |\n+---------------------------+\n\nEnabling the multiline option using the PCRE option syntax:\n\nSELECT \'a\\nb\\nc\' RLIKE \'(?m)^b$\';\n+---------------------------+\n| \'a\\nb\\nc\' RLIKE \'(?m)^b$\' |\n+---------------------------+\n|                         1 |\n+---------------------------+\n\nEnabling the multiline option using default_regex_flags\n\nSET default_regex_flags=\'MULTILINE\';\nSELECT \'a\\nb\\nc\' RLIKE \'^b$\';\n+-----------------------+\n| \'a\\nb\\nc\' RLIKE \'^b$\' |\n+-----------------------+\n|                     1 |\n+-----------------------+\n\nURL: https://mariadb.com/kb/en/regexp/','','https://mariadb.com/kb/en/regexp/'),(616,'REGEXP_INSTR',36,'Syntax\n------\n\nREGEXP_INSTR(subject, pattern)\n\nReturns the position of the first occurrence of the regular expression pattern\nin the string subject, or 0 if pattern was not found.\n\nThe positions start with 1 and are measured in characters (i.e. not in bytes),\nwhich is important for multi-byte character sets. You can cast a multi-byte\ncharacter set to BINARY to get offsets in bytes.\n\nThe function follows the case sensitivity rules of the effective collation.\nMatching is performed case insensitively for case insensitive collations, and\ncase sensitively for case sensitive collations and for binary data.\n\nThe collation case sensitivity can be overwritten using the (?i) and (?-i)\nPCRE flags.\n\nMariaDB uses the PCRE regular expression library for enhanced regular\nexpression performance, and REGEXP_INSTR was introduced as part of this\nenhancement.\n\nExamples\n--------\n\nSELECT REGEXP_INSTR(\'abc\',\'b\');\n-> 2\n\nSELECT REGEXP_INSTR(\'abc\',\'x\');\n-> 0\n\nSELECT REGEXP_INSTR(\'BJÖRN\',\'N\');\n-> 5\n\nCasting a multi-byte character set as BINARY to get offsets in bytes:\n\nSELECT REGEXP_INSTR(BINARY \'BJÖRN\',\'N\') AS cast_utf8_to_binary;\n-> 6\n\nCase sensitivity:\n\nSELECT REGEXP_INSTR(\'ABC\',\'b\');\n-> 2\n\nSELECT REGEXP_INSTR(\'ABC\' COLLATE utf8_bin,\'b\');\n-> 0\n\nSELECT REGEXP_INSTR(BINARY\'ABC\',\'b\');\n-> 0\n\nSELECT REGEXP_INSTR(\'ABC\',\'(?-i)b\');\n-> 0\n\nSELECT REGEXP_INSTR(\'ABC\' COLLATE utf8_bin,\'(?i)b\');\n-> 2\n\nURL: https://mariadb.com/kb/en/regexp_instr/','','https://mariadb.com/kb/en/regexp_instr/'),(617,'REGEXP_REPLACE',36,'Syntax\n------\n\nREGEXP_REPLACE(subject, pattern, replace)\n\nDescription\n-----------\n\nREGEXP_REPLACE returns the string subject with all occurrences of the regular\nexpression pattern replaced by the string replace. If no occurrences are\nfound, then subject is returned as is.\n\nThe replace string can have backreferences to the subexpressions in the form\n\\N, where N is a number from 1 to 9.\n\nThe function follows the case sensitivity rules of the effective collation.\nMatching is performed case insensitively for case insensitive collations, and\ncase sensitively for case sensitive collations and for binary data.\n\nThe collation case sensitivity can be overwritten using the (?i) and (?-i)\nPCRE flags.\n\nMariaDB uses the PCRE regular expression library for enhanced regular\nexpression performance, and REGEXP_REPLACE was introduced as part of this\nenhancement.\n\nThe default_regex_flags variable addresses the remaining compatibilities\nbetween PCRE and the old regex library.\n\nExamples\n--------\n\nSELECT REGEXP_REPLACE(\'ab12cd\',\'[0-9]\',\'\') AS remove_digits;\n-> abcd\n\nSELECT\nREGEXP_REPLACE(\'<html><head><title>title</title><body>body</body></htm>\',\n\'<.+?>\',\' \')\nAS strip_html;\n-> title  body\n\nBackreferences to the subexpressions in the form \\N, where N is a number from\n1 to 9:\n\nSELECT REGEXP_REPLACE(\'James Bond\',\'^(.*) (.*)$\',\'\\\\2, \\\\1\') AS reorder_name;\n-> Bond, James\n\nCase insensitive and case sensitive matches:\n\nSELECT REGEXP_REPLACE(\'ABC\',\'b\',\'-\') AS case_insensitive;\n-> A-C\n\nSELECT REGEXP_REPLACE(\'ABC\' COLLATE utf8_bin,\'b\',\'-\') AS case_sensitive;\n-> ABC\n\nSELECT REGEXP_REPLACE(BINARY \'ABC\',\'b\',\'-\') AS binary_data;\n-> ABC\n\nOverwriting the collation case sensitivity using the (?i) and (?-i) PCRE flags.\n\nSELECT REGEXP_REPLACE(\'ABC\',\'(?-i)b\',\'-\') AS force_case_sensitive;\n-> ABC\n\nSELECT REGEXP_REPLACE(BINARY \'ABC\',\'(?i)b\',\'-\') AS force_case_insensitive;\n-> A-C\n\nURL: https://mariadb.com/kb/en/regexp_replace/','','https://mariadb.com/kb/en/regexp_replace/'),(618,'REGEXP_SUBSTR',36,'Syntax\n------\n\nREGEXP_SUBSTR(subject,pattern)\n\nDescription\n-----------\n\nReturns the part of the string subject that matches the regular expression\npattern, or an empty string if pattern was not found.\n\nThe function follows the case sensitivity rules of the effective collation.\nMatching is performed case insensitively for case insensitive collations, and\ncase sensitively for case sensitive collations and for binary data.\n\nThe collation case sensitivity can be overwritten using the (?i) and (?-i)\nPCRE flags.\n\nMariaDB uses the PCRE regular expression library for enhanced regular\nexpression performance, and REGEXP_SUBSTR was introduced as part of this\nenhancement.\n\nThe default_regex_flags variable addresses the remaining compatibilities\nbetween PCRE and the old regex library.\n\nExamples\n--------\n\nSELECT REGEXP_SUBSTR(\'ab12cd\',\'[0-9]+\');\n-> 12\n\nSELECT REGEXP_SUBSTR(\n \'See https://mariadb.org/en/foundation/ for details\',\n \'https?://[^/]*\');\n-> https://mariadb.org\n\nSELECT REGEXP_SUBSTR(\'ABC\',\'b\');\n-> B\n\nSELECT REGEXP_SUBSTR(\'ABC\' COLLATE utf8_bin,\'b\');\n->\n\nSELECT REGEXP_SUBSTR(BINARY\'ABC\',\'b\');\n->\n\nSELECT REGEXP_SUBSTR(\'ABC\',\'(?i)b\');\n-> B\n\nSELECT REGEXP_SUBSTR(\'ABC\' COLLATE utf8_bin,\'(?+i)b\');\n-> B\n\nURL: https://mariadb.com/kb/en/regexp_substr/','','https://mariadb.com/kb/en/regexp_substr/'),(619,'ASCII',36,'Syntax\n------\n\nASCII(str)\n\nDescription\n-----------\n\nReturns the numeric ASCII value of the leftmost character of the string\nargument. Returns 0 if the given string is empty and NULL if it is NULL.\n\nASCII() works for 8-bit characters.\n\nExamples\n--------\n\nSELECT ASCII(9);\n+----------+\n| ASCII(9) |\n+----------+\n|       57 |\n+----------+\n\nSELECT ASCII(\'9\');\n+------------+\n| ASCII(\'9\') |\n+------------+\n|         57 |\n+------------+\n\nSELECT ASCII(\'abc\');\n+--------------+\n| ASCII(\'abc\') |\n+--------------+\n|           97 |\n+--------------+\n\nURL: https://mariadb.com/kb/en/ascii/','','https://mariadb.com/kb/en/ascii/'),(620,'BIN',36,'Syntax\n------\n\nBIN(N)\n\nDescription\n-----------\n\nReturns a string representation of the binary value of the given longlong\n(that is, BIGINT) number. This is equivalent to CONV(N,10,2). The argument\nshould be positive. If it is a FLOAT, it will be truncated. Returns NULL if\nthe argument is NULL.\n\nExamples\n--------\n\nSELECT BIN(12);\n+---------+\n| BIN(12) |\n+---------+\n| 1100    |\n+---------+\n\nURL: https://mariadb.com/kb/en/bin/','','https://mariadb.com/kb/en/bin/'),(621,'BINARY Operator',36,'This page describes the BINARY operator. For details about the data type, see\nBinary Data Type.\n\nSyntax\n------\n\nBINARY\n\nDescription\n-----------\n\nThe BINARY operator casts the string following it to a binary string. This is\nan easy way to force a column comparison to be done byte by byte rather than\ncharacter by character. This causes the comparison to be case sensitive even\nif the column isn\'t defined as BINARY or BLOB.\n\nBINARY also causes trailing spaces to be significant.\n\nExamples\n--------\n\nSELECT \'a\' = \'A\';\n+-----------+\n| \'a\' = \'A\' |\n+-----------+\n|         1 |\n+-----------+\n\nSELECT BINARY \'a\' = \'A\';\n+------------------+\n| BINARY \'a\' = \'A\' |\n+------------------+\n|                0 |\n+------------------+\n\nSELECT \'a\' = \'a \';\n+------------+\n| \'a\' = \'a \' |\n+------------+\n|          1 |\n+------------+\n\nSELECT BINARY \'a\' = \'a \';\n+-------------------+\n| BINARY \'a\' = \'a \' |\n+-------------------+\n|                 0 |\n+-------------------+\n\nURL: https://mariadb.com/kb/en/binary-operator/','','https://mariadb.com/kb/en/binary-operator/'),(622,'BIT_LENGTH',36,'Syntax\n------\n\nBIT_LENGTH(str)\n\nDescription\n-----------\n\nReturns the length of the given string argument in bits. If the argument is\nnot a string, it will be converted to string. If the argument is NULL, it\nreturns NULL.\n\nExamples\n--------\n\nSELECT BIT_LENGTH(\'text\');\n+--------------------+\n| BIT_LENGTH(\'text\') |\n+--------------------+\n|                 32 |\n+--------------------+\n\nSELECT BIT_LENGTH(\'\');\n+----------------+\n| BIT_LENGTH(\'\') |\n+----------------+\n|              0 |\n+----------------+\n\nCompatibility\n-------------\n\nPostgreSQL and Sybase support BIT_LENGTH().\n\nURL: https://mariadb.com/kb/en/bit_length/','','https://mariadb.com/kb/en/bit_length/'),(623,'CAST',36,'Syntax\n------\n\nCAST(expr AS type)\n\nDescription\n-----------\n\nThe CAST() function takes a value of one type and produces a value of another\ntype, similar to the CONVERT() function.\n\nThe type can be one of the following values:\n\n* BINARY\n* CHAR\n* DATE\n* DATETIME\n* DECIMAL[(M[,D])]\n* DOUBLE\n* FLOAT (from MariaDB 10.4.5)\n* INTEGER\nShort for SIGNED INTEGER\n\n* SIGNED [INTEGER]\n* UNSIGNED [INTEGER]\n* TIME\n* VARCHAR (in Oracle mode, from MariaDB 10.3)\n\nThe main difference between CAST and CONVERT() is that CONVERT(expr,type) is\nODBC syntax while CAST(expr as type) and CONVERT(... USING ...) are SQL92\nsyntax.\n\nIn MariaDB 10.4 and later, you can use the CAST() function with the INTERVAL\nkeyword.\n\nUntil MariaDB 5.5.31, X\'HHHH\', the standard SQL syntax for binary string\nliterals, erroneously worked in the same way as 0xHHHH. In 5.5.31 it was\nintentionally changed to behave as a string in all contexts (and never as a\nnumber).\n\nThis introduced an incompatibility with previous versions of MariaDB, and all\nversions of MySQL (see the example below).\n\nExamples\n--------\n\nSimple casts:\n\nSELECT CAST(\"abc\" AS BINARY);\nSELECT CAST(\"1\" AS UNSIGNED INTEGER);\nSELECT CAST(123 AS CHAR CHARACTER SET utf8)\n\nNote that when one casts to CHAR without specifying the character set, the\ncollation_connection character set collation will be used. When used with CHAR\nCHARACTER SET, the default collation for that character set will be used.\n\nSELECT COLLATION(CAST(123 AS CHAR));\n+------------------------------+\n| COLLATION(CAST(123 AS CHAR)) |\n+------------------------------+\n| latin1_swedish_ci            |\n+------------------------------+\n\nSELECT COLLATION(CAST(123 AS CHAR CHARACTER SET utf8));\n+-------------------------------------------------+\n| COLLATION(CAST(123 AS CHAR CHARACTER SET utf8)) |\n+-------------------------------------------------+\n| utf8_general_ci                                 |\n+-------------------------------------------------+\n\nIf you also want to change the collation, you have to use the COLLATE operator:\n\nSELECT COLLATION(CAST(123 AS CHAR CHARACTER SET utf8) \n COLLATE utf8_unicode_ci);\n+-------------------------------------------------------------------------+\n| COLLATION(CAST(123 AS CHAR CHARACTER SET utf8) COLLATE utf8_unicode_ci) |\n+-------------------------------------------------------------------------+\n| utf8_unicode_ci                                                         |\n+-------------------------------------------------------------------------+\n\nUsing CAST() to order an ENUM field as a CHAR rather than the internal\nnumerical value:\n\nCREATE TABLE enum_list (enum_field enum(\'c\',\'a\',\'b\'));\n\nINSERT INTO enum_list (enum_field) \nVALUES(\'c\'),(\'a\'),(\'c\'),(\'b\');\n\nSELECT * FROM enum_list \nORDER BY enum_field;\n+------------+\n| enum_field |\n+------------+\n| c          |\n| c          |\n| a          |\n| b          |\n+------------+\n\nSELECT * FROM enum_list \nORDER BY CAST(enum_field AS CHAR);\n+------------+\n| enum_field |\n+------------+\n| a          |\n| b          |\n| c          |\n| c          |\n+------------+\n\nFrom MariaDB 5.5.31, the following will trigger warnings, since x\'aa\' and\n\'X\'aa\' no longer behave as a number. Previously, and in all versions of MySQL,\nno warnings are triggered since they did erroneously behave as a number:\n\nSELECT CAST(0xAA AS UNSIGNED), CAST(x\'aa\' AS UNSIGNED), CAST(X\'aa\' AS\nUNSIGNED);\n+------------------------+-------------------------+-------------------------+\n| CAST(0xAA AS UNSIGNED) | CAST(x\'aa\' AS UNSIGNED) | CAST(X\'aa\' AS UNSIGNED) |\n+------------------------+-------------------------+-------------------------+\n|                    170 |                       0 |                       0 |\n+------------------------+-------------------------+-------------------------+\n1 row in set, 2 warnings (0.00 sec)\n\nWarning (Code 1292): Truncated incorrect INTEGER value: \'\\xAA\'\nWarning (Code 1292): Truncated incorrect INTEGER value: \'\\xAA\'\n\nCasting to intervals:\n\nSELECT CAST(2019-01-04 INTERVAL AS DAY_SECOND(2)) AS \"Cast\";\n\n+-------------+\n| Cast        |\n+-------------+\n| 00:20:17.00 |\n+-------------+\n\nURL: https://mariadb.com/kb/en/cast/','','https://mariadb.com/kb/en/cast/'),(624,'CHAR Function',36,'Syntax\n------\n\nCHAR(N,... [USING charset_name])\n\nDescription\n-----------\n\nCHAR() interprets each argument as an INT and returns a string consisting of\nthe characters given by the code values of those integers. NULL values are\nskipped. By default, CHAR() returns a binary string. To produce a string in a\ngiven character set, use the optional USING clause:\n\nSELECT 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 character\nset, a warning is issued. Also, if strict SQL mode is enabled, the result from\nCHAR() becomes NULL.\n\nExamples\n--------\n\nSELECT CHAR(77,97,114,\'105\',97,\'68\',66);\n+----------------------------------+\n| CHAR(77,97,114,\'105\',97,\'68\',66) |\n+----------------------------------+\n| MariaDB                          |\n+----------------------------------+\n\nSELECT CHAR(77,77.3,\'77.3\');\n+----------------------+\n| CHAR(77,77.3,\'77.3\') |\n+----------------------+\n| MMM                  |\n+----------------------+\n1 row in set, 1 warning (0.00 sec)\n\nWarning (Code 1292): Truncated incorrect INTEGER value: \'77.3\'\n\nURL: https://mariadb.com/kb/en/char-function/','','https://mariadb.com/kb/en/char-function/'),(625,'CHAR_LENGTH',36,'Syntax\n------\n\nCHAR_LENGTH(str)\nCHARACTER_LENGTH(str)\n\nDescription\n-----------\n\nReturns the length of the given string argument, measured in characters. A\nmulti-byte character counts as a single character. This means that for a\nstring containing five two-byte characters, LENGTH() (or OCTET_LENGTH() in\nOracle mode) returns 10, whereas CHAR_LENGTH() returns 5. If the argument is\nNULL, it returns NULL.\n\nIf the argument is not a string value, it is converted into a string.\n\nIt is synonymous with the CHARACTER_LENGTH() function.\n\nExamples\n--------\n\nSELECT CHAR_LENGTH(\'MariaDB\');\n+------------------------+\n| CHAR_LENGTH(\'MariaDB\') |\n+------------------------+\n|                      7 |\n+------------------------+\n\nWhen Oracle mode from MariaDB 10.3 is not set:\n\nSELECT CHAR_LENGTH(\'π\'), LENGTH(\'π\'), LENGTHB(\'π\'), OCTET_LENGTH(\'π\');\n+-------------------+--------------+---------------+--------------------+\n| CHAR_LENGTH(\'π\')  | LENGTH(\'π\')  | LENGTHB(\'π\')  | OCTET_LENGTH(\'π\')  |\n+-------------------+--------------+---------------+--------------------+\n|                 1 |            2 |             2 |                  2 |\n+-------------------+--------------+---------------+--------------------+\n\nIn Oracle mode from MariaDB 10.3:\n\nSELECT CHAR_LENGTH(\'π\'), LENGTH(\'π\'), LENGTHB(\'π\'), OCTET_LENGTH(\'π\');\n+-------------------+--------------+---------------+--------------------+\n| CHAR_LENGTH(\'π\')  | LENGTH(\'π\')  | LENGTHB(\'π\')  | OCTET_LENGTH(\'π\')  |\n+-------------------+--------------+---------------+--------------------+\n|                 1 |            1 |             2 |                  2 |\n+-------------------+--------------+---------------+--------------------+\n\nURL: https://mariadb.com/kb/en/char_length/','','https://mariadb.com/kb/en/char_length/'),(626,'CHR',36,'MariaDB starting with 10.3.1\n----------------------------\nThe CHR() function was introduced in MariaDB 10.3.1 to provide Oracle\ncompatibility\n\nSyntax\n------\n\nCHR(N)\n\nDescription\n-----------\n\nCHR() interprets each argument N as an integer and returns a VARCHAR(1) string\nconsisting of the character given by the code values of the integer. The\ncharacter set and collation of the string are set according to the values of\nthe character_set_database and collation_database system variables.\n\nCHR() is similar to the CHAR() function, but only accepts a single argument.\n\nCHR() is available in all sql_modes.\n\nExamples\n--------\n\nSELECT CHR(67);\n+---------+\n| CHR(67) |\n+---------+\n| C       |\n+---------+\n\nSELECT CHR(\'67\');\n+-----------+\n| CHR(\'67\') |\n+-----------+\n| C         |\n+-----------+\n\nSELECT CHR(\'C\');\n+----------+\n| CHR(\'C\') |\n+----------+\n|          |\n+----------+\n1 row in set, 1 warning (0.000 sec)\n\nSHOW WARNINGS;\n+---------+------+----------------------------------------+\n| Level   | Code | Message                                |\n+---------+------+----------------------------------------+\n| Warning | 1292 | Truncated incorrect INTEGER value: \'C\' |\n+---------+------+----------------------------------------+\n\nURL: https://mariadb.com/kb/en/chr/','','https://mariadb.com/kb/en/chr/'),(627,'CONCAT',36,'Syntax\n------\n\nCONCAT(str1,str2,...)\n\nDescription\n-----------\n\nReturns the string that results from concatenating the arguments. May have one\nor more arguments. If all arguments are non-binary strings, the result is a\nnon-binary string. If the arguments include any binary strings, the result is\na binary string. A numeric argument is converted to its equivalent binary\nstring form; if you want to avoid that, you can use an explicit type cast, as\nin this example:\n\nSELECT CONCAT(CAST(int_col AS CHAR), char_col);\n\nCONCAT() returns NULL if any argument is NULL.\n\nA NULL parameter hides all information contained in other parameters from the\nresult. Sometimes this is not desirable; to avoid this, you can:\n\n* Use the CONCAT_WS() function with an empty separator, because that function\nis NULL-safe.\n* Use IFNULL() to turn NULLs into empty strings.\n\nOracle Mode\n-----------\n\nMariaDB starting with 10.3\n--------------------------\nIn Oracle mode from MariaDB 10.3, CONCAT ignores NULL.\n\nExamples\n--------\n\nSELECT CONCAT(\'Ma\', \'ria\', \'DB\');\n+---------------------------+\n| CONCAT(\'Ma\', \'ria\', \'DB\') |\n+---------------------------+\n| MariaDB                   |\n+---------------------------+\n\nSELECT CONCAT(\'Ma\', \'ria\', NULL, \'DB\');\n+---------------------------------+\n| CONCAT(\'Ma\', \'ria\', NULL, \'DB\') |\n+---------------------------------+\n| NULL                            |\n+---------------------------------+\n\nSELECT CONCAT(42.0);\n+--------------+\n| CONCAT(42.0) |\n+--------------+\n| 42.0         |\n+--------------+\n\nUsing IFNULL() to handle NULLs:\n\nSELECT CONCAT(\'The value of @v is: \', IFNULL(@v, \'\'));\n+------------------------------------------------+\n| CONCAT(\'The value of @v is: \', IFNULL(@v, \'\')) |\n+------------------------------------------------+\n| The value of @v is:                            |\n+------------------------------------------------+\n\nIn Oracle mode, from MariaDB 10.3:\n\nSELECT CONCAT(\'Ma\', \'ria\', NULL, \'DB\');\n+---------------------------------+\n| CONCAT(\'Ma\', \'ria\', NULL, \'DB\') |\n+---------------------------------+\n| MariaDB                         |\n+---------------------------------+\n\nURL: https://mariadb.com/kb/en/concat/','','https://mariadb.com/kb/en/concat/'),(628,'CONCAT_WS',36,'Syntax\n------\n\nCONCAT_WS(separator,str1,str2,...)\n\nDescription\n-----------\n\nCONCAT_WS() stands for Concatenate With Separator and is a special form of\nCONCAT(). The first argument is the separator for the rest of the arguments.\nThe separator is added between the strings to be concatenated. The separator\ncan be a string, as can the rest of the arguments.\n\nIf the separator is NULL, the result is NULL; all other NULL values are\nskipped. This makes CONCAT_WS() suitable when you want to concatenate some\nvalues and avoid losing all information if one of them is NULL.\n\nExamples\n--------\n\nSELECT CONCAT_WS(\',\',\'First name\',\'Second name\',\'Last Name\');\n+-------------------------------------------------------+\n| CONCAT_WS(\',\',\'First name\',\'Second name\',\'Last Name\') |\n+-------------------------------------------------------+\n| First name,Second name,Last Name                      |\n+-------------------------------------------------------+\n\nSELECT CONCAT_WS(\'-\',\'Floor\',NULL,\'Room\');\n+------------------------------------+\n| CONCAT_WS(\'-\',\'Floor\',NULL,\'Room\') |\n+------------------------------------+\n| Floor-Room                         |\n+------------------------------------+\n\nIn some cases, remember to include a space in the separator string:\n\nSET @a = \'gnu\', @b = \'penguin\', @c = \'sea lion\';\nQuery OK, 0 rows affected (0.00 sec)\n\nSELECT CONCAT_WS(\', \', @a, @b, @c);\n+-----------------------------+\n| CONCAT_WS(\', \', @a, @b, @c) |\n+-----------------------------+\n| gnu, penguin, sea lion      |\n+-----------------------------+\n\nUsing CONCAT_WS() to handle NULLs:\n\nSET @a = \'a\', @b = NULL, @c = \'c\';\n\nSELECT CONCAT_WS(\'\', @a, @b, @c);\n+---------------------------+\n| CONCAT_WS(\'\', @a, @b, @c) |\n+---------------------------+\n| ac                        |\n+---------------------------+\n\nURL: https://mariadb.com/kb/en/concat_ws/','','https://mariadb.com/kb/en/concat_ws/'),(629,'CONVERT',36,'Syntax\n------\n\nCONVERT(expr,type), CONVERT(expr USING transcoding_name)\n\nDescription\n-----------\n\nThe	CONVERT() and CAST() functions take a value of one type and produce a\nvalue of another type.\n\nThe type can be one of the following values:\n\n* BINARY\n* CHAR\n* DATE\n* DATETIME\n* DECIMAL[(M[,D])]\n* DOUBLE\n* FLOAT (from MariaDB 10.4.5)\n* INTEGER\nShort for SIGNED INTEGER\n\n* SIGNED [INTEGER]\n* UNSIGNED [INTEGER]\n* TIME\n* VARCHAR (in Oracle mode, from MariaDB 10.3)\n\nNote that in MariaDB, INT and INTEGER are the same thing.\n\nBINARY produces a string with the BINARY data type. If the optional length is\ngiven, BINARY(N) causes the cast to use no more than N bytes of the argument.\nValues shorter than the given number in bytes are padded with 0x00 bytes to\nmake them equal the length value.\n\nCHAR(N) causes the cast to use no more than the number of characters given in\nthe argument.\n\nThe main difference between the CAST() and CONVERT() is that\nCONVERT(expr,type) is ODBC syntax while CAST(expr as type) and CONVERT(...\nUSING ...) are SQL92 syntax.\n\nCONVERT() with USING is used to convert data between different character sets.\nIn MariaDB, transcoding names are the same as the corresponding character set\nnames. For example, this statement converts the string \'abc\' in the default\ncharacter set to the corresponding string in the utf8 character set:\n\nSELECT CONVERT(\'abc\' USING utf8);\n\nExamples\n--------\n\nSELECT enum_col FROM tbl_name \nORDER BY CAST(enum_col AS CHAR);\n\nConverting a BINARY to string to permit the LOWER function to work:\n\nSET @x = \'AardVark\';\n\nSET @x = BINARY \'AardVark\';\n\nSELECT LOWER(@x), LOWER(CONVERT (@x USING latin1));\n+-----------+----------------------------------+\n| LOWER(@x) | LOWER(CONVERT (@x USING latin1)) |\n+-----------+----------------------------------+\n| AardVark  | aardvark                         |\n+-----------+----------------------------------+\n\nURL: https://mariadb.com/kb/en/convert/','','https://mariadb.com/kb/en/convert/'),(630,'ELT',36,'Syntax\n------\n\nELT(N, str1[, str2, str3,...])\n\nDescription\n-----------\n\nTakes a numeric argument and a series of string arguments. Returns the string\nthat corresponds to the given numeric position. For instance, it returns str1\nif N is 1, str2 if N is 2, and so on. If the numeric argument is a FLOAT,\nMariaDB rounds it to the nearest INTEGER. If the numeric argument is less than\n1, greater than the total number of arguments, or not a number, ELT() returns\nNULL. It must have at least two arguments.\n\nIt is complementary to the FIELD() function.\n\nExamples\n--------\n\nSELECT ELT(1, \'ej\', \'Heja\', \'hej\', \'foo\');\n+------------------------------------+\n| ELT(1, \'ej\', \'Heja\', \'hej\', \'foo\') |\n+------------------------------------+\n| ej                                 |\n+------------------------------------+\n\nSELECT ELT(4, \'ej\', \'Heja\', \'hej\', \'foo\');\n+------------------------------------+\n| ELT(4, \'ej\', \'Heja\', \'hej\', \'foo\') |\n+------------------------------------+\n| foo                                |\n+------------------------------------+\n\nURL: https://mariadb.com/kb/en/elt/','','https://mariadb.com/kb/en/elt/'),(631,'EXPORT_SET',36,'Syntax\n------\n\nEXPORT_SET(bits, on, off[, separator[, number_of_bits]])\n\nDescription\n-----------\n\nTakes a minimum of three arguments. Returns a string where each bit in the\ngiven bits argument is returned, with the string values given for on and off.\n\nBits are examined from right to left, (from low-order to high-order bits).\nStrings are added to the result from left to right, separated by a separator\nstring (defaults as \',\'). You can optionally limit the number of bits the\nEXPORT_SET() function examines using the number_of_bits option.\n\nIf any of the arguments are set as NULL, the function returns NULL.\n\nExamples\n--------\n\nSELECT EXPORT_SET(5,\'Y\',\'N\',\',\',4);\n+-----------------------------+\n| EXPORT_SET(5,\'Y\',\'N\',\',\',4) |\n+-----------------------------+\n| Y,N,Y,N                     |\n+-----------------------------+\n\nSELECT EXPORT_SET(6,\'1\',\'0\',\',\',10);\n+------------------------------+\n| EXPORT_SET(6,\'1\',\'0\',\',\',10) |\n+------------------------------+\n| 0,1,1,0,0,0,0,0,0,0          |\n+------------------------------+\n\nURL: https://mariadb.com/kb/en/export_set/','','https://mariadb.com/kb/en/export_set/'),(632,'EXTRACTVALUE',36,'Syntax\n------\n\nEXTRACTVALUE(xml_frag, xpath_expr)\n\nDescription\n-----------\n\nThe EXTRACTVALUE() function takes two string arguments: a fragment of XML\nmarkup and an XPath expression, (also known as a locator). It returns the text\n(That is, CDDATA), of the first text node which is a child of the element or\nelements matching the XPath expression.\n\nIn cases where a valid XPath expression does not match any text nodes in a\nvalid XML fragment, (including the implicit /text() expression), the\nEXTRACTVALUE() function returns an empty string.\n\nInvalid Arguments\n-----------------\n\nWhen either the XML fragment or the XPath expression is NULL, the\nEXTRACTVALUE() function returns NULL. When the XML fragment is invalid, it\nraises a warning Code 1525:\n\nWarning (Code 1525): Incorrect XML value: \'parse error at line 1 pos 11:\nunexpected END-OF-INPUT\'\n\nWhen the XPath value is invalid, it generates an Error 1105:\n\nERROR 1105 (HY000): XPATH syntax error: \')\'\n\nExplicit text() Expressions\n---------------------------\n\nThis function is the equivalent of performing a match using the XPath\nexpression after appending /text(). In other words:\n\nSELECT\n EXTRACTVALUE(\'<cases><case>example</case></cases>\', \'/cases/case\')\n  AS \'Base Example\',\n EXTRACTVALUE(\'<cases><case>example</case></cases>\', \'/cases/case/text()\')\n  AS \'text() Example\';\n+--------------+----------------+\n| Base Example | text() Example |\n+--------------+----------------+\n| example      | example        |\n+--------------+----------------+\n\nCount Matches\n-------------\n\nWhen EXTRACTVALUE() returns multiple matches, it returns the content of the\nfirst child text node of each matching element, in the matched order, as a\nsingle, space-delimited string.\n\nBy design, the EXTRACTVALUE() function makes no distinction between a match on\nan empty element and no match at all. If you need to determine whether no\nmatching element was found in the XML fragment or if an element was found that\ncontained no child text nodes, use the XPath count() function.\n\nFor instance, when looking for a value that exists, but contains no child text\nnodes, you would get a count of the number of matching instances:\n\nSELECT\n EXTRACTVALUE(\'<cases><case/></cases>\', \'/cases/case\')\n  AS \'Empty Example\',\n EXTRACTVALUE(\'<cases><case/></cases>\', \'count(/cases/case)\')\n  AS \'count() Example\';\n+---------------+-----------------+\n| Empty Example | count() Example |\n+---------------+-----------------+\n|               |               1 |\n+---------------+-----------------+\n\nAlternatively, when looking for a value that doesn\'t exist, count() returns 0.\n\nSELECT\n EXTRACTVALUE(\'<cases><case/></cases>\', \'/cases/person\')\n  AS \'No Match Example\',\n EXTRACTVALUE(\'<cases><case/></cases>\', \'count(/cases/person)\')\n  AS \'count() Example\';\n+------------------+-----------------+\n| No Match Example | count() Example |\n+------------------+-----------------+\n|                  |                0|\n+------------------+-----------------+\n\nMatches\n-------\n\nImportant: The EXTRACTVALUE() function only returns CDDATA. It does not return\ntags that the element might contain or the text that these child elements\ncontain.\n\nSELECT\n\nEXTRACTVALUE(\'<cases><case>Person<email>x@example.com</email></case></cases>\',\n\'/cases\')\n AS Case;\n+--------+\n| Case   |\n+--------+\n| Person |\n+--------+\n\nNote, in the above example, while the XPath expression matches to the parent\n<case> instance, it does not return the contained <email> tag or its content.\n\nExamples\n--------\n\nSELECT\n  ExtractValue(\'<a>ccc<b>ddd</b></a>\', \'/a\')            AS val1,\n  ExtractValue(\'<a>ccc<b>ddd</b></a>\', \'/a/b\')          AS val2,\n  ExtractValue(\'<a>ccc<b>ddd</b></a>\', \'//b\')           AS val3,\n  ExtractValue(\'<a>ccc<b>ddd</b></a>\', \'/b\')            AS val4,\n  ExtractValue(\'<a>ccc<b>ddd</b><b>eee</b></a>\', \'//b\') AS val5;\n+------+------+------+------+---------+\n| val1 | val2 | val3 | val4 | val5    |\n+------+------+------+------+---------+\n| ccc  | ddd  | ddd  |      | ddd eee |\n+------+------+------+------+---------+\n\nURL: https://mariadb.com/kb/en/extractvalue/','','https://mariadb.com/kb/en/extractvalue/'),(633,'FIELD',36,'Syntax\n------\n\nFIELD(pattern, str1[,str2,...])\n\nDescription\n-----------\n\nReturns the index position of the string or number matching the given pattern.\nReturns 0 in the event that none of the arguments match the pattern. Raises an\nError 1582 if not given at least two arguments.\n\nWhen all arguments given to the FIELD() function are strings, they are treated\nas case-insensitive. When all the arguments are numbers, they are treated as\nnumbers. Otherwise, they are treated as doubles.\n\nIf the given pattern occurs more than once, the	FIELD() function only returns\nthe index of the first instance. If the given pattern is NULL, the function\nreturns 0, as a NULL pattern always fails to match.\n\nThis function is complementary to the ELT() function.\n\nExamples\n--------\n\nSELECT FIELD(\'ej\', \'Hej\', \'ej\', \'Heja\', \'hej\', \'foo\') \n AS \'Field Results\';\n+---------------+\n| Field Results | \n+---------------+\n|             2 |\n+---------------+\n\nSELECT FIELD(\'fo\', \'Hej\', \'ej\', \'Heja\', \'hej\', \'foo\')\n AS \'Field Results\';\n+---------------+\n| Field Results | \n+---------------+\n|             0 |\n+---------------+\n\nSELECT FIELD(1, 2, 3, 4, 5, 1) AS \'Field Results\';\n+---------------+\n| Field Results |\n+---------------+\n|             5 |\n+---------------+\n\nSELECT FIELD(NULL, 2, 3) AS \'Field Results\';\n+---------------+\n| Field Results |\n+---------------+\n|             0 |\n+---------------+\n\nSELECT FIELD(\'fail\') AS \'Field Results\';\nError 1582 (42000): Incorrect parameter count in call\nto native function \'field\'\n\nURL: https://mariadb.com/kb/en/field/','','https://mariadb.com/kb/en/field/'),(634,'FIND_IN_SET',36,'Syntax\n------\n\nFIND_IN_SET(pattern, strlist)\n\nDescription\n-----------\n\nReturns the index position where the given pattern occurs in a string list.\nThe first argument is the pattern you want to search for. The second argument\nis a string containing comma-separated variables. If the second argument is of\nthe SET data-type, the function is optimized to use bit arithmetic.\n\nIf the pattern does not occur in the string list or if the string list is an\nempty string, the function returns 0. If either argument is NULL, the function\nreturns NULL. The function does not return the correct result if the pattern\ncontains a comma (\",\") character.\n\nExamples\n--------\n\nSELECT FIND_IN_SET(\'b\',\'a,b,c,d\') AS \"Found Results\";\n+---------------+\n| Found Results |\n+---------------+\n|             2 |\n+---------------+\n\nURL: https://mariadb.com/kb/en/find_in_set/','','https://mariadb.com/kb/en/find_in_set/'),(635,'FORMAT',36,'Syntax\n------\n\nFORMAT(num, decimal_position[, locale])\n\nDescription\n-----------\n\nFormats the given number for display as a string, adding separators to\nappropriate position and rounding the results to the given decimal position.\nFor instance, it would format 15233.345 to 15,233.35.\n\nIf the given decimal position is 0, it rounds to return no decimal point or\nfractional part. You can optionally specify a locale value to format numbers\nto the pattern appropriate for the given region.\n\nExamples\n--------\n\nSELECT FORMAT(1234567890.09876543210, 4) AS \'Format\';\n+--------------------+\n| Format             |\n+--------------------+\n| 1,234,567,890.0988 |\n+--------------------+\n\nSELECT FORMAT(1234567.89, 4) AS \'Format\';\n+----------------+\n| Format         |\n+----------------+\n| 1,234,567.8900 |\n+----------------+\n\nSELECT FORMAT(1234567.89, 0) AS \'Format\';\n+-----------+\n| Format    |\n+-----------+\n| 1,234,568 |\n+-----------+\n\nSELECT FORMAT(123456789,2,\'rm_CH\') AS \'Format\';\n+----------------+\n| Format         |\n+----------------+\n| 123\'456\'789,00 |\n+----------------+\n\nURL: https://mariadb.com/kb/en/format/','','https://mariadb.com/kb/en/format/'),(636,'FROM_BASE64',36,'Syntax\n------\n\nFROM_BASE64(str)\n\nDescription\n-----------\n\nDecodes the given base-64 encode string, returning the result as a binary\nstring. Returns NULL if the given string is NULL or if it\'s invalid.\n\nIt is the reverse of the TO_BASE64 function.\n\nThere are numerous methods to base-64 encode a string. MariaDB uses the\nfollowing:\n\n* It encodes alphabet value 64 as \'+\'.\n* It encodes alphabet value 63 as \'/\'.\n* It codes output in groups of four printable characters.  Each three byte of\ndata encoded uses four characters.  If the final group is incomplete, it pads\nthe difference with the \'=\' character.\n* It divides long output, adding a new line very 76 characters.\n* In decoding, it recognizes and ignores newlines, carriage returns, tabs and\nspace whitespace characters.\n\nSELECT TO_BASE64(\'Maria\') AS \'Input\';\n+-----------+\n| Input     |\n+-----------+\n| TWFyaWE=  |\n+-----------+\n\nSELECT FROM_BASE64(\'TWFyaWE=\') AS \'Output\';\n+--------+\n| Output |\n+--------+\n| Maria  |\n+--------+\n\nURL: https://mariadb.com/kb/en/from_base64/','','https://mariadb.com/kb/en/from_base64/'),(637,'HEX',36,'Syntax\n------\n\nHEX(N_or_S)\n\nDescription\n-----------\n\nIf N_or_S is a number, returns a string representation of the hexadecimal\nvalue of N, where N is a longlong (BIGINT) number. This is equivalent to\nCONV(N,10,16).\n\nIf N_or_S is a string, returns a hexadecimal string representation of N_or_S\nwhere each byte of each character in N_or_S is converted to two hexadecimal\ndigits. If N_or_S is NULL, returns NULL. The inverse of this operation is\nperformed by the UNHEX() function.\n\nMariaDB starting with 10.5.0\n----------------------------\nHEX() with an INET6 argument returns a hexadecimal representation of the\nunderlying 16-byte binary string.\n\nExamples\n--------\n\nSELECT HEX(255);\n+----------+\n| HEX(255) |\n+----------+\n| FF       |\n+----------+\n\nSELECT 0x4D617269614442;\n+------------------+\n| 0x4D617269614442 |\n+------------------+\n| MariaDB          |\n+------------------+\n\nSELECT HEX(\'MariaDB\');\n+----------------+\n| HEX(\'MariaDB\') |\n+----------------+\n| 4D617269614442 |\n+----------------+\n\nFrom MariaDB 10.5.0:\n\nSELECT HEX(CAST(\'2001:db8::ff00:42:8329\' AS INET6));\n+----------------------------------------------+\n| HEX(CAST(\'2001:db8::ff00:42:8329\' AS INET6)) |\n+----------------------------------------------+\n| 20010DB8000000000000FF0000428329             |\n+----------------------------------------------+\n\nURL: https://mariadb.com/kb/en/hex/','','https://mariadb.com/kb/en/hex/'),(638,'INSTR',36,'Syntax\n------\n\nINSTR(str,substr)\n\nDescription\n-----------\n\nReturns the position of the first occurrence of substring substr in string\nstr. This is the same as the two-argument form of LOCATE(), except that the\norder of the arguments is reversed.\n\nINSTR() performs a case-insensitive search.\n\nIf any argument is NULL, returns NULL.\n\nExamples\n--------\n\nSELECT INSTR(\'foobarbar\', \'bar\');\n+---------------------------+\n| INSTR(\'foobarbar\', \'bar\') |\n+---------------------------+\n|                         4 |\n+---------------------------+\n\nSELECT INSTR(\'My\', \'Maria\');\n+----------------------+\n| INSTR(\'My\', \'Maria\') |\n+----------------------+\n|                    0 |\n+----------------------+\n\nURL: https://mariadb.com/kb/en/instr/','','https://mariadb.com/kb/en/instr/'),(639,'LCASE',36,'Syntax\n------\n\nLCASE(str)\n\nDescription\n-----------\n\nLCASE() is a synonym for LOWER().\n\nURL: https://mariadb.com/kb/en/lcase/','','https://mariadb.com/kb/en/lcase/'),(640,'LEFT',36,'Syntax\n------\n\nLEFT(str,len)\n\nDescription\n-----------\n\nReturns the leftmost len characters from the string str, or NULL if any\nargument is NULL.\n\nExamples\n--------\n\nSELECT LEFT(\'MariaDB\', 5);\n+--------------------+\n| LEFT(\'MariaDB\', 5) |\n+--------------------+\n| Maria              |\n+--------------------+\n\nURL: https://mariadb.com/kb/en/left/','','https://mariadb.com/kb/en/left/'),(641,'INSERT Function',36,'Syntax\n------\n\nINSERT(str,pos,len,newstr)\n\nDescription\n-----------\n\nReturns the string str, with the substring beginning at position pos and len\ncharacters long replaced by the string newstr. Returns the original string if\npos is not within the length of the string. Replaces the rest of the string\nfrom position pos if len is not within the length of the rest of the string.\nReturns NULL if any argument is NULL.\n\nExamples\n--------\n\nSELECT INSERT(\'Quadratic\', 3, 4, \'What\');\n+-----------------------------------+\n| INSERT(\'Quadratic\', 3, 4, \'What\') |\n+-----------------------------------+\n| QuWhattic                         |\n+-----------------------------------+\n\nSELECT INSERT(\'Quadratic\', -1, 4, \'What\');\n+------------------------------------+\n| INSERT(\'Quadratic\', -1, 4, \'What\') |\n+------------------------------------+\n| Quadratic                          |\n+------------------------------------+\n\nSELECT INSERT(\'Quadratic\', 3, 100, \'What\');\n+-------------------------------------+\n| INSERT(\'Quadratic\', 3, 100, \'What\') |\n+-------------------------------------+\n| QuWhat                              |\n+-------------------------------------+\n\nURL: https://mariadb.com/kb/en/insert-function/','','https://mariadb.com/kb/en/insert-function/'),(642,'LENGTH',36,'Syntax\n------\n\nLENGTH(str)\n\nDescription\n-----------\n\nReturns the length of the string str.\n\nIn the default mode, when Oracle mode from MariaDB 10.3 is not set, the length\nis measured in bytes. In this case, a multi-byte character counts as multiple\nbytes. This means that for a string containing five two-byte characters,\nLENGTH() returns 10, whereas CHAR_LENGTH() returns 5.\n\nWhen running Oracle mode from MariaDB 10.3, the length is measured in\ncharacters, and LENGTH is a synonym for CHAR_LENGTH().\n\nIf str is not a string value, it is converted into a string. If str is NULL,\nthe function returns NULL.\n\nExamples\n--------\n\nSELECT LENGTH(\'MariaDB\');\n+-------------------+\n| LENGTH(\'MariaDB\') |\n+-------------------+\n|                 7 |\n+-------------------+\n\nWhen Oracle mode from MariaDB 10.3 is not set:\n\nSELECT CHAR_LENGTH(\'π\'), LENGTH(\'π\'), LENGTHB(\'π\'), OCTET_LENGTH(\'π\');\n+-------------------+--------------+---------------+--------------------+\n| CHAR_LENGTH(\'π\')  | LENGTH(\'π\')  | LENGTHB(\'π\')  | OCTET_LENGTH(\'π\')  |\n+-------------------+--------------+---------------+--------------------+\n|                 1 |            2 |             2 |                  2 |\n+-------------------+--------------+---------------+--------------------+\n\nIn Oracle mode from MariaDB 10.3:\n\nSELECT CHAR_LENGTH(\'π\'), LENGTH(\'π\'), LENGTHB(\'π\'), OCTET_LENGTH(\'π\');\n+-------------------+--------------+---------------+--------------------+\n| CHAR_LENGTH(\'π\')  | LENGTH(\'π\')  | LENGTHB(\'π\')  | OCTET_LENGTH(\'π\')  |\n+-------------------+--------------+---------------+--------------------+\n|                 1 |            1 |             2 |                  2 |\n+-------------------+--------------+---------------+--------------------+\n\nURL: https://mariadb.com/kb/en/length/','','https://mariadb.com/kb/en/length/'),(643,'LENGTHB',36,'MariaDB starting with 10.3.1\n----------------------------\nIntroduced in MariaDB 10.3.1 as part of the Oracle compatibility enhancements.\n\nSyntax\n------\n\nLENGTHB(str)\n\nDescription\n-----------\n\nLENGTHB() returns the length of the given string, in bytes. When Oracle mode\nis not set, this is a synonym for LENGTH.\n\nA multi-byte character counts as multiple bytes. This means that for a string\ncontaining five two-byte characters, LENGTHB() returns 10, whereas\nCHAR_LENGTH() returns 5.\n\nIf str is not a string value, it is converted into a string. If str is NULL,\nthe function returns NULL.\n\nExamples\n--------\n\nWhen Oracle mode from MariaDB 10.3 is not set:\n\nSELECT CHAR_LENGTH(\'π\'), LENGTH(\'π\'), LENGTHB(\'π\'), OCTET_LENGTH(\'π\');\n+-------------------+--------------+---------------+--------------------+\n| CHAR_LENGTH(\'π\')  | LENGTH(\'π\')  | LENGTHB(\'π\')  | OCTET_LENGTH(\'π\')  |\n+-------------------+--------------+---------------+--------------------+\n|                 1 |            2 |             2 |                  2 |\n+-------------------+--------------+---------------+--------------------+\n\nIn Oracle mode from MariaDB 10.3:\n\nSELECT CHAR_LENGTH(\'π\'), LENGTH(\'π\'), LENGTHB(\'π\'), OCTET_LENGTH(\'π\');\n+-------------------+--------------+---------------+--------------------+\n| CHAR_LENGTH(\'π\')  | LENGTH(\'π\')  | LENGTHB(\'π\')  | OCTET_LENGTH(\'π\')  |\n+-------------------+--------------+---------------+--------------------+\n|                 1 |            1 |             2 |                  2 |\n+-------------------+--------------+---------------+--------------------+\n\nURL: https://mariadb.com/kb/en/lengthb/','','https://mariadb.com/kb/en/lengthb/'),(644,'LIKE',36,'Syntax\n------\n\nexpr LIKE pat [ESCAPE \'escape_char\']\nexpr NOT LIKE pat [ESCAPE \'escape_char\']\n\nDescription\n-----------\n\nTests whether expr matches the pattern pat. Returns either 1 (TRUE) or 0\n(FALSE). Both expr and pat may be any valid expression and are evaluated to\nstrings. Patterns may use the following wildcard characters:\n\n* % matches any number of characters, including zero.\n* _ matches any single character.\n\nUse NOT LIKE to test if a string does not match a pattern. This is equivalent\nto using the NOT operator on the entire LIKE expression.\n\nIf either the expression or the pattern is NULL, the result is NULL.\n\nLIKE performs case-insensitive substring matches if the collation for the\nexpression and pattern is case-insensitive. For case-sensitive matches,\ndeclare either argument to use a binary collation using COLLATE, or coerce\neither of them to a BINARY string using CAST. Use SHOW COLLATION to get a list\nof available collations. Collations ending in _bin are case-sensitive.\n\nNumeric arguments are coerced to binary strings.\n\nThe _ wildcard matches a single character, not byte. It will only match a\nmulti-byte character if it is valid in the expression\'s character set. For\nexample, _ will match _utf8\"€\", but it will not match _latin1\"€\" because the\nEuro sign is not a valid latin1 character. If necessary, use CONVERT to use\nthe expression in a different character set.\n\nIf you need to match the characters _ or %, you must escape them. By default,\nyou can prefix the wildcard characters the backslash character \\ to escape\nthem. The backslash is used both to encode special characters like newlines\nwhen a string is parsed as well as to escape wildcards in a pattern after\nparsing. Thus, to match an actual backslash, you sometimes need to\ndouble-escape it as \"\\\\\\\\\".\n\nTo avoid difficulties with the backslash character, you can change the\nwildcard escape character using ESCAPE in a LIKE expression. The argument to\nESCAPE must be a single-character string.\n\nExamples\n--------\n\nSelect the days that begin with \"T\":\n\nCREATE TABLE t1 (d VARCHAR(16));\nINSERT INTO t1 VALUES \n (\"Monday\"), (\"Tuesday\"), (\"Wednesday\"),\n (\"Thursday\"), (\"Friday\"), (\"Saturday\"), (\"Sunday\");\nSELECT * FROM t1 WHERE d LIKE \"T%\";\n\nSELECT * FROM t1 WHERE d LIKE \"T%\";\n+----------+\n| d        |\n+----------+\n| Tuesday  |\n| Thursday |\n+----------+\n\nSelect the days that contain the substring \"es\":\n\nSELECT * FROM t1 WHERE d LIKE \"%es%\";\n\nSELECT * FROM t1 WHERE d LIKE \"%es%\";\n+-----------+\n| d         |\n+-----------+\n| Tuesday   |\n| Wednesday |\n+-----------+\n\nSelect the six-character day names:\n\nSELECT * FROM t1 WHERE d like \"___day\";\n\nSELECT * FROM t1 WHERE d like \"___day\";\n+---------+\n| d       |\n+---------+\n| Monday  |\n| Friday  |\n| Sunday  |\n+---------+\n\nWith the default collations, LIKE is case-insensitive:\n\nSELECT * FROM t1 where d like \"t%\";\n\nSELECT * FROM t1 where d like \"t%\";\n+----------+\n| d        |\n+----------+\n| Tuesday  |\n| Thursday |\n+----------+\n\nUse COLLATE to specify a binary collation, forcing case-sensitive matches:\n\nSELECT * FROM t1 WHERE d like \"t%\" COLLATE latin1_bin;\n\nSELECT * FROM t1 WHERE d like \"t%\" COLLATE latin1_bin;\nEmpty set (0.00 sec)\n\nYou can include functions and operators in the expression to match. Select\ndates based on their day name:\n\nCREATE TABLE t2 (d DATETIME);\nINSERT INTO t2 VALUES\n  (\"2007-01-30 21:31:07\"),\n  (\"1983-10-15 06:42:51\"),\n  (\"2011-04-21 12:34:56\"),\n  (\"2011-10-30 06:31:41\"),\n  (\"2011-01-30 14:03:25\"),\n  (\"2004-10-07 11:19:34\");\nSELECT * FROM t2 WHERE DAYNAME(d) LIKE \"T%\";\n\nSELECT * FROM t2 WHERE DAYNAME(d) LIKE \"T%\";\n+------------------+\n| d                |\n+------------------+\n| 2007-01-30 21:31 |\n| 2011-04-21 12:34 |\n| 2004-10-07 11:19 |\n+------------------+\n3 rows in set, 7 warnings (0.00 sec)\n\nOptimizing LIKE\n---------------\n\n* MariaDB can use indexes for LIKE on string columns in the case where the\nLIKE doesn\'t start with % or _.\n* Starting from MariaDB 10.0, one can set  the\noptimizer_use_condition_selectivity variable to 5. If this is done, then the\noptimizer will read optimizer_selectivity_sampling_limit rows to calculate the\nselectivity of the LIKE expression before starting to calculate the query\nplan. This can help speed up some LIKE queries by providing the optimizer with\nmore information about your data.\n\nURL: https://mariadb.com/kb/en/like/','','https://mariadb.com/kb/en/like/'),(645,'LOCATE',36,'Syntax\n------\n\nLOCATE(substr,str), LOCATE(substr,str,pos)\n\nDescription\n-----------\n\nThe first syntax returns the position of the first occurrence of substring\nsubstr in string str. The second syntax returns the position of the first\noccurrence of substring substr in string str, starting at position pos.\nReturns 0 if substr is not in str.\n\nLOCATE() performs a case-insensitive search.\n\nIf any argument is NULL, returns NULL.\n\nINSTR() is the same as the two-argument form of LOCATE(), except that the\norder of the arguments is reversed.\n\nExamples\n--------\n\nSELECT LOCATE(\'bar\', \'foobarbar\');\n+----------------------------+\n| LOCATE(\'bar\', \'foobarbar\') |\n+----------------------------+\n|                          4 |\n+----------------------------+\n\nSELECT LOCATE(\'My\', \'Maria\');\n+-----------------------+\n| LOCATE(\'My\', \'Maria\') |\n+-----------------------+\n|                     0 |\n+-----------------------+\n\nSELECT LOCATE(\'bar\', \'foobarbar\', 5);\n+-------------------------------+\n| LOCATE(\'bar\', \'foobarbar\', 5) |\n+-------------------------------+\n|                             7 |\n+-------------------------------+\n\nURL: https://mariadb.com/kb/en/locate/','','https://mariadb.com/kb/en/locate/'),(646,'LOWER',36,'Syntax\n------\n\nLOWER(str)\n\nDescription\n-----------\n\nReturns the string str with all characters changed to lowercase according to\nthe current character set mapping. The default is latin1 (cp1252 West\nEuropean).\n\nExamples\n--------\n\nSELECT LOWER(\'QUADRATICALLY\');\n+------------------------+\n| LOWER(\'QUADRATICALLY\') |\n+------------------------+\n| quadratically          |\n+------------------------+\n\nLOWER() (and UPPER()) are ineffective when applied to binary strings (BINARY,\nVARBINARY, BLOB). To perform lettercase conversion, CONVERT the string to a\nnon-binary string:\n\nSET @str = BINARY \'North Carolina\';\n\nSELECT LOWER(@str), LOWER(CONVERT(@str USING latin1));\n+----------------+-----------------------------------+\n| LOWER(@str)    | LOWER(CONVERT(@str USING latin1)) |\n+----------------+-----------------------------------+\n| North Carolina | north carolina                    |\n+----------------+-----------------------------------+\n\nURL: https://mariadb.com/kb/en/lower/','','https://mariadb.com/kb/en/lower/'),(647,'LPAD',36,'Syntax\n------\n\nLPAD(str, len [,padstr])\n\nDescription\n-----------\n\nReturns the string str, left-padded with the string padstr to a length of len\ncharacters. If str is longer than len, the return value is shortened to len\ncharacters. If padstr is omitted, the LPAD function pads spaces.\n\nPrior to MariaDB 10.3.1, the padstr parameter was mandatory.\n\nReturns NULL if given a NULL argument. If the result is empty (zero length),\nreturns either an empty string or, from MariaDB 10.3.6 with SQL_MODE=Oracle,\nNULL.\n\nThe Oracle mode version of the function can be accessed outside of Oracle mode\nby using LPAD_ORACLE as the function name.\n\nExamples\n--------\n\nSELECT LPAD(\'hello\',10,\'.\');\n+----------------------+\n| LPAD(\'hello\',10,\'.\') |\n+----------------------+\n| .....hello           |\n+----------------------+\n\nSELECT LPAD(\'hello\',2,\'.\');\n+---------------------+\n| LPAD(\'hello\',2,\'.\') |\n+---------------------+\n| he                  |\n+---------------------+\n\nFrom MariaDB 10.3.1, with the pad string defaulting to space.\n\nSELECT LPAD(\'hello\',10);\n+------------------+\n| LPAD(\'hello\',10) |\n+------------------+\n|      hello       |\n+------------------+\n\nOracle mode version from MariaDB 10.3.6:\n\nSELECT LPAD(\'\',0),LPAD_ORACLE(\'\',0);\n+------------+-------------------+\n| LPAD(\'\',0) | LPAD_ORACLE(\'\',0) |\n+------------+-------------------+\n|            | NULL              |\n+------------+-------------------+\n\nURL: https://mariadb.com/kb/en/lpad/','','https://mariadb.com/kb/en/lpad/'),(648,'LTRIM',36,'Syntax\n------\n\nLTRIM(str)\n\nDescription\n-----------\n\nReturns the string str with leading space characters removed.\n\nReturns NULL if given a NULL argument. If the result is empty, returns either\nan empty string, or, from MariaDB 10.3.6 with SQL_MODE=Oracle, NULL.\n\nThe Oracle mode version of the function can be accessed outside of Oracle mode\nby using LTRIM_ORACLE as the function name.\n\nExamples\n--------\n\nSELECT QUOTE(LTRIM(\'   MariaDB   \'));\n+-------------------------------+\n| QUOTE(LTRIM(\'   MariaDB   \')) |\n+-------------------------------+\n| \'MariaDB   \'                  |\n+-------------------------------+\n\nOracle mode version from MariaDB 10.3.6:\n\nSELECT LTRIM(\'\'),LTRIM_ORACLE(\'\');\n+-----------+------------------+\n| LTRIM(\'\') | LTRIM_ORACLE(\'\') |\n+-----------+------------------+\n|           | NULL             |\n+-----------+------------------+\n\nURL: https://mariadb.com/kb/en/ltrim/','','https://mariadb.com/kb/en/ltrim/'),(649,'MAKE_SET',36,'Syntax\n------\n\nMAKE_SET(bits,str1,str2,...)\n\nDescription\n-----------\n\nReturns a set value (a string containing substrings separated by \",\"\ncharacters) consisting of the strings that have the corresponding bit in bits\nset. str1 corresponds to bit 0, str2 to bit 1, and so on. NULL values in str1,\nstr2, ... are not appended to the result.\n\nExamples\n--------\n\nSELECT MAKE_SET(1,\'a\',\'b\',\'c\');\n+-------------------------+\n| MAKE_SET(1,\'a\',\'b\',\'c\') |\n+-------------------------+\n| a                       |\n+-------------------------+\n\nSELECT MAKE_SET(1 | 4,\'hello\',\'nice\',\'world\');\n+----------------------------------------+\n| MAKE_SET(1 | 4,\'hello\',\'nice\',\'world\') |\n+----------------------------------------+\n| hello,world                            |\n+----------------------------------------+\n\nSELECT MAKE_SET(1 | 4,\'hello\',\'nice\',NULL,\'world\');\n+---------------------------------------------+\n| MAKE_SET(1 | 4,\'hello\',\'nice\',NULL,\'world\') |\n+---------------------------------------------+\n| hello                                       |\n+---------------------------------------------+\n\nSELECT QUOTE(MAKE_SET(0,\'a\',\'b\',\'c\'));\n+--------------------------------+\n| QUOTE(MAKE_SET(0,\'a\',\'b\',\'c\')) |\n+--------------------------------+\n| \'\'                             |\n+--------------------------------+\n\nURL: https://mariadb.com/kb/en/make_set/','','https://mariadb.com/kb/en/make_set/'),(650,'MATCH AGAINST',36,'Syntax\n------\n\nMATCH (col1,col2,...) AGAINST (expr [search_modifier])\n\nDescription\n-----------\n\nA special construct used to perform a fulltext search on a fulltext index.\n\nSee Fulltext Index Overview for a full description, and Full-text Indexes for\nmore articles on the topic.\n\nExamples\n--------\n\nCREATE TABLE ft_myisam(copy TEXT,FULLTEXT(copy)) ENGINE=MyISAM;\n\nINSERT INTO ft_myisam(copy) VALUES (\'Once upon a time\'), (\'There was a wicked\nwitch\'), \n (\'Who ate everybody up\');\n\nSELECT * FROM ft_myisam WHERE MATCH(copy) AGAINST(\'wicked\');\n+--------------------------+\n| copy                     |\n+--------------------------+\n| There was a wicked witch |\n+--------------------------+\n\nSELECT 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+----+-------------------------------------+-----------------+\n\nURL: https://mariadb.com/kb/en/match-against/','','https://mariadb.com/kb/en/match-against/'),(651,'MID',36,'Syntax\n------\n\nMID(str,pos,len)\n\nDescription\n-----------\n\nMID(str,pos,len) is a synonym for SUBSTRING(str,pos,len).\n\nExamples\n--------\n\nSELECT MID(\'abcd\',4,1);\n+-----------------+\n| MID(\'abcd\',4,1) |\n+-----------------+\n| d               |\n+-----------------+\n\nSELECT MID(\'abcd\',2,2);\n+-----------------+\n| MID(\'abcd\',2,2) |\n+-----------------+\n| bc              |\n+-----------------+\n\nA negative starting position:\n\nSELECT MID(\'abcd\',-2,4);\n+------------------+\n| MID(\'abcd\',-2,4) |\n+------------------+\n| cd               |\n+------------------+\n\nURL: https://mariadb.com/kb/en/mid/','','https://mariadb.com/kb/en/mid/'),(652,'NOT LIKE',36,'Syntax\n------\n\nexpr NOT LIKE pat [ESCAPE \'escape_char\']\n\nDescription\n-----------\n\nThis is the same as NOT (expr LIKE pat [ESCAPE \'escape_char\']).\n\nURL: https://mariadb.com/kb/en/not-like/','','https://mariadb.com/kb/en/not-like/'),(653,'OCTET_LENGTH',36,'Syntax\n------\n\nOCTET_LENGTH(str)\n\nDescription\n-----------\n\nOCTET_LENGTH() returns the length of the given string, in octets (bytes). This\nis a synonym for LENGTHB(), and, when Oracle mode from MariaDB 10.3 is not\nset, a synonym for LENGTH().\n\nA multi-byte character counts as multiple bytes. This means that for a string\ncontaining five two-byte characters, OCTET_LENGTH() returns 10, whereas\nCHAR_LENGTH() returns 5.\n\nIf str is not a string value, it is converted into a string. If str is NULL,\nthe function returns NULL.\n\nExamples\n--------\n\nWhen Oracle mode from MariaDB 10.3 is not set:\n\nSELECT CHAR_LENGTH(\'π\'), LENGTH(\'π\'), LENGTHB(\'π\'), OCTET_LENGTH(\'π\');\n+-------------------+--------------+---------------+--------------------+\n| CHAR_LENGTH(\'π\')  | LENGTH(\'π\')  | LENGTHB(\'π\')  | OCTET_LENGTH(\'π\')  |\n+-------------------+--------------+---------------+--------------------+\n|                 1 |            2 |             2 |                  2 |\n+-------------------+--------------+---------------+--------------------+\n\nIn Oracle mode from MariaDB 10.3:\n\nSELECT CHAR_LENGTH(\'π\'), LENGTH(\'π\'), LENGTHB(\'π\'), OCTET_LENGTH(\'π\');\n+-------------------+--------------+---------------+--------------------+\n| CHAR_LENGTH(\'π\')  | LENGTH(\'π\')  | LENGTHB(\'π\')  | OCTET_LENGTH(\'π\')  |\n+-------------------+--------------+---------------+--------------------+\n|                 1 |            1 |             2 |                  2 |\n+-------------------+--------------+---------------+--------------------+\n\nURL: https://mariadb.com/kb/en/octet_length/','','https://mariadb.com/kb/en/octet_length/'),(654,'ORD',36,'Syntax\n------\n\nORD(str)\n\nDescription\n-----------\n\nIf the leftmost character of the string str is a multi-byte character, returns\nthe code for that character, calculated from the numeric values of its\nconstituent bytes using this formula:\n\n(1st byte code)\n+ (2nd byte code x 256)\n+ (3rd byte code x 256 x 256) ...\n\nIf the leftmost character is not a multi-byte character, ORD() returns the\nsame value as the ASCII() function.\n\nExamples\n--------\n\nSELECT ORD(\'2\');\n+----------+\n| ORD(\'2\') |\n+----------+\n|       50 |\n+----------+\n\nURL: https://mariadb.com/kb/en/ord/','','https://mariadb.com/kb/en/ord/'),(655,'POSITION',36,'Syntax\n------\n\nPOSITION(substr IN str)\n\nDescription\n-----------\n\nPOSITION(substr IN str) is a synonym for LOCATE(substr,str).\n\nIt\'s part of ODBC 3.0.\n\nURL: https://mariadb.com/kb/en/position/','','https://mariadb.com/kb/en/position/'),(656,'QUOTE',36,'Syntax\n------\n\nQUOTE(str)\n\nDescription\n-----------\n\nQuotes a string to produce a result that can be used as a properly escaped\ndata value in an SQL statement. The string is returned enclosed by single\nquotes and with each instance of single quote (\"\'\"), backslash (\"\\\"), ASCII\nNUL, and Control-Z preceded by a backslash. If the argument is NULL, the\nreturn value is the word \"NULL\" without enclosing single quotes.\n\nExamples\n--------\n\nSELECT QUOTE(\"Don\'t!\");\n+-----------------+\n| QUOTE(\"Don\'t!\") |\n+-----------------+\n| \'Don\\\'t!\'       |\n+-----------------+\n\nSELECT QUOTE(NULL); \n+-------------+\n| QUOTE(NULL) |\n+-------------+\n| NULL        |\n+-------------+\n\nURL: https://mariadb.com/kb/en/quote/','','https://mariadb.com/kb/en/quote/'),(657,'REPEAT Function',36,'Syntax\n------\n\nREPEAT(str,count)\n\nDescription\n-----------\n\nReturns a string consisting of the string str repeated count times. If count\nis less than 1, returns an empty string. Returns NULL if str or count are NULL.\n\nExamples\n--------\n\nSELECT QUOTE(REPEAT(\'MariaDB \',4));\n+------------------------------------+\n| QUOTE(REPEAT(\'MariaDB \',4))        |\n+------------------------------------+\n| \'MariaDB MariaDB MariaDB MariaDB \' |\n+------------------------------------+\n\nURL: https://mariadb.com/kb/en/repeat-function/','','https://mariadb.com/kb/en/repeat-function/'),(658,'REPLACE Function',36,'Syntax\n------\n\nREPLACE(str,from_str,to_str)\n\nDescription\n-----------\n\nReturns the string str with all occurrences of the string from_str replaced by\nthe string to_str. REPLACE() performs a case-sensitive match when searching\nfor from_str.\n\nExamples\n--------\n\nSELECT REPLACE(\'www.mariadb.org\', \'w\', \'Ww\');\n+---------------------------------------+\n| REPLACE(\'www.mariadb.org\', \'w\', \'Ww\') |\n+---------------------------------------+\n| WwWwWw.mariadb.org                    |\n+---------------------------------------+\n\nURL: https://mariadb.com/kb/en/replace-function/','','https://mariadb.com/kb/en/replace-function/'),(659,'REVERSE',36,'Syntax\n------\n\nREVERSE(str)\n\nDescription\n-----------\n\nReturns the string str with the order of the characters reversed.\n\nExamples\n--------\n\nSELECT REVERSE(\'desserts\');\n+---------------------+\n| REVERSE(\'desserts\') |\n+---------------------+\n| stressed            |\n+---------------------+\n\nURL: https://mariadb.com/kb/en/reverse/','','https://mariadb.com/kb/en/reverse/'),(660,'RIGHT',36,'Syntax\n------\n\nRIGHT(str,len)\n\nDescription\n-----------\n\nReturns the rightmost len characters from the string str, or NULL if any\nargument is NULL.\n\nExamples\n--------\n\nSELECT RIGHT(\'MariaDB\', 2);\n+---------------------+\n| RIGHT(\'MariaDB\', 2) |\n+---------------------+\n| DB                  |\n+---------------------+\n\nURL: https://mariadb.com/kb/en/right/','','https://mariadb.com/kb/en/right/'),(661,'RPAD',36,'Syntax\n------\n\nRPAD(str, len [, padstr])\n\nDescription\n-----------\n\nReturns the string str, right-padded with the string padstr to a length of len\ncharacters. If str is longer than len, the return value is shortened to len\ncharacters. If padstr is omitted, the RPAD function pads spaces.\n\nPrior to MariaDB 10.3.1, the padstr parameter was mandatory.\n\nReturns NULL if given a NULL argument. If the result is empty (a length of\nzero), returns either an empty string, or, from MariaDB 10.3.6 with\nSQL_MODE=Oracle, NULL.\n\nThe Oracle mode version of the function can be accessed outside of Oracle mode\nby using RPAD_ORACLE as the function name.\n\nExamples\n--------\n\nSELECT RPAD(\'hello\',10,\'.\');\n+----------------------+\n| RPAD(\'hello\',10,\'.\') |\n+----------------------+\n| hello.....           |\n+----------------------+\n\nSELECT RPAD(\'hello\',2,\'.\');\n+---------------------+\n| RPAD(\'hello\',2,\'.\') |\n+---------------------+\n| he                  |\n+---------------------+\n\nFrom MariaDB 10.3.1, with the pad string defaulting to space.\n\nSELECT RPAD(\'hello\',30);\n+--------------------------------+\n| RPAD(\'hello\',30)               |\n+--------------------------------+\n| hello                          |\n+--------------------------------+\n\nOracle mode version from MariaDB 10.3.6:\n\nSELECT RPAD(\'\',0),RPAD_ORACLE(\'\',0);\n+------------+-------------------+\n| RPAD(\'\',0) | RPAD_ORACLE(\'\',0) |\n+------------+-------------------+\n|            | NULL              |\n+------------+-------------------+\n\nURL: https://mariadb.com/kb/en/rpad/','','https://mariadb.com/kb/en/rpad/'),(662,'RTRIM',36,'Syntax\n------\n\nRTRIM(str)\n\nDescription\n-----------\n\nReturns the string str with trailing space characters removed.\n\nReturns NULL if given a NULL argument. If the result is empty, returns either\nan empty string, or, from MariaDB 10.3.6 with SQL_MODE=Oracle, NULL.\n\nThe Oracle mode version of the function can be accessed outside of Oracle mode\nby using RTRIM_ORACLE as the function name.\n\nExamples\n--------\n\nSELECT QUOTE(RTRIM(\'MariaDB    \'));\n+-----------------------------+\n| QUOTE(RTRIM(\'MariaDB    \')) |\n+-----------------------------+\n| \'MariaDB\'                   |\n+-----------------------------+\n\nOracle mode version from MariaDB 10.3.6:\n\nSELECT RTRIM(\'\'),RTRIM_ORACLE(\'\');\n+-----------+------------------+\n| RTRIM(\'\') | RTRIM_ORACLE(\'\') |\n+-----------+------------------+\n|           | NULL             |\n+-----------+------------------+\n\nURL: https://mariadb.com/kb/en/rtrim/','','https://mariadb.com/kb/en/rtrim/'),(663,'SOUNDEX',36,'Syntax\n------\n\nSOUNDEX(str)\n\nDescription\n-----------\n\nReturns a soundex string from str. Two strings that sound almost the same\nshould have identical soundex strings. A standard soundex string is four\ncharacters long, but the SOUNDEX() function returns an arbitrarily long\nstring. You can use SUBSTRING() on the result to get a standard soundex\nstring. All non-alphabetic characters in str are ignored. All international\nalphabetic characters outside the A-Z range are treated as vowels.\n\nImportant: When using SOUNDEX(), you should be aware of the following details:\n\n* This function, as currently implemented, is intended to work well with\n strings that are in the English language only. Strings in other languages may\n not produce reasonable results.\n\n* This function implements the original Soundex algorithm, not the more\npopular enhanced version (also described by D. Knuth). The difference is that\noriginal version discards vowels first and duplicates second, whereas the\nenhanced version discards duplicates first and vowels second.\n\nExamples\n--------\n\nSOUNDEX(\'Hello\');\n+------------------+\n| SOUNDEX(\'Hello\') |\n+------------------+\n| H400             |\n+------------------+\n\nSELECT SOUNDEX(\'MariaDB\');\n+--------------------+\n| SOUNDEX(\'MariaDB\') |\n+--------------------+\n| M631               |\n+--------------------+\n\nSELECT SOUNDEX(\'Knowledgebase\');\n+--------------------------+\n| SOUNDEX(\'Knowledgebase\') |\n+--------------------------+\n| K543212                  |\n+--------------------------+\n\nSELECT givenname, surname FROM users WHERE SOUNDEX(givenname) =\nSOUNDEX(\"robert\");\n+-----------+---------+\n| givenname | surname |\n+-----------+---------+\n| Roberto   | Castro  |\n+-----------+---------+\n\nURL: https://mariadb.com/kb/en/soundex/','','https://mariadb.com/kb/en/soundex/'),(664,'SOUNDS LIKE',36,'Syntax\n------\n\nexpr1 SOUNDS LIKE expr2\n\nDescription\n-----------\n\nThis is the same as SOUNDEX(expr1) = SOUNDEX(expr2).\n\nExample\n-------\n\nSELECT givenname, surname FROM users WHERE givenname SOUNDS LIKE \"robert\";\n+-----------+---------+\n| givenname | surname |\n+-----------+---------+\n| Roberto   | Castro  |\n+-----------+---------+\n\nURL: https://mariadb.com/kb/en/sounds-like/','','https://mariadb.com/kb/en/sounds-like/'),(665,'SPACE',36,'Syntax\n------\n\nSPACE(N)\n\nDescription\n-----------\n\nReturns a string consisting of N space characters. If N is NULL, returns NULL.\n\nExamples\n--------\n\nSELECT QUOTE(SPACE(6));\n+-----------------+\n| QUOTE(SPACE(6)) |\n+-----------------+\n| \'      \'        |\n+-----------------+\n\nURL: https://mariadb.com/kb/en/space/','','https://mariadb.com/kb/en/space/'),(666,'STRCMP',36,'Syntax\n------\n\nSTRCMP(expr1,expr2)\n\nDescription\n-----------\n\nSTRCMP() returns 0 if the strings are the same, -1 if the first argument is\nsmaller than the second according to the current sort order, and 1 if the\nstrings are otherwise not the same. Returns NULL is either argument is NULL.\n\nExamples\n--------\n\nSELECT STRCMP(\'text\', \'text2\');\n+-------------------------+\n| STRCMP(\'text\', \'text2\') |\n+-------------------------+\n|                      -1 |\n+-------------------------+\n\nSELECT STRCMP(\'text2\', \'text\');\n+-------------------------+\n| STRCMP(\'text2\', \'text\') |\n+-------------------------+\n|                       1 |\n+-------------------------+\n\nSELECT STRCMP(\'text\', \'text\');\n+------------------------+\n| STRCMP(\'text\', \'text\') |\n+------------------------+\n|                      0 |\n+------------------------+\n\nURL: https://mariadb.com/kb/en/strcmp/','','https://mariadb.com/kb/en/strcmp/'),(667,'SUBSTR',36,'Description\n-----------\n\nSUBSTR() is a synonym for SUBSTRING().\n\nURL: https://mariadb.com/kb/en/substr/','','https://mariadb.com/kb/en/substr/'),(668,'SUBSTRING',36,'Syntax\n------\n\nSUBSTRING(str,pos), \nSUBSTRING(str FROM pos), \nSUBSTRING(str,pos,len),\nSUBSTRING(str FROM pos FOR len)\n\nSUBSTR(str,pos), \nSUBSTR(str FROM pos), \nSUBSTR(str,pos,len),\nSUBSTR(str FROM pos FOR len)\n\nDescription\n-----------\n\nThe forms without a len argument return a substring from string str starting\nat position pos.\n\nThe forms with a len argument return a substring len characters long from\nstring str, starting at position pos.\n\nThe forms that use FROM are standard SQL syntax.\n\nIt is also possible to use a negative value for pos. In this case, the\nbeginning of the substring is pos characters from the end of the string,\nrather than the beginning. A negative value may be used for pos in any of the\nforms of this function.\n\nBy default, the position of the first character in the string from which the\nsubstring is to be extracted is reckoned as 1. For Oracle-compatibility, from\nMariaDB 10.3.3, when sql_mode is set to \'oracle\', position zero is treated as\nposition 1 (although the first character is still reckoned as 1).\n\nIf any argument is NULL, returns NULL.\n\nExamples\n--------\n\nSELECT SUBSTRING(\'Knowledgebase\',5);\n+------------------------------+\n| SUBSTRING(\'Knowledgebase\',5) |\n+------------------------------+\n| ledgebase                    |\n+------------------------------+\n\nSELECT SUBSTRING(\'MariaDB\' FROM 6);\n+-----------------------------+\n| SUBSTRING(\'MariaDB\' FROM 6) |\n+-----------------------------+\n| DB                          |\n+-----------------------------+\n\nSELECT SUBSTRING(\'Knowledgebase\',3,7);\n+--------------------------------+\n| SUBSTRING(\'Knowledgebase\',3,7) |\n+--------------------------------+\n| owledge                        |\n+--------------------------------+\n\nSELECT SUBSTRING(\'Knowledgebase\', -4);\n+--------------------------------+\n| SUBSTRING(\'Knowledgebase\', -4) |\n+--------------------------------+\n| base                           |\n+--------------------------------+\n\nSELECT SUBSTRING(\'Knowledgebase\', -8, 4);\n+-----------------------------------+\n| SUBSTRING(\'Knowledgebase\', -8, 4) |\n+-----------------------------------+\n| edge                              |\n+-----------------------------------+\n\nSELECT SUBSTRING(\'Knowledgebase\' FROM -8 FOR 4);\n+------------------------------------------+\n| SUBSTRING(\'Knowledgebase\' FROM -8 FOR 4) |\n+------------------------------------------+\n| edge                                     |\n+------------------------------------------+\n\nOracle mode from MariaDB 10.3.3:\n\nSELECT SUBSTR(\'abc\',0,3);\n+-------------------+\n| SUBSTR(\'abc\',0,3) |\n+-------------------+\n|                   |\n+-------------------+\n\nSELECT SUBSTR(\'abc\',1,2);\n+-------------------+\n| SUBSTR(\'abc\',1,2) |\n+-------------------+\n| ab                |\n+-------------------+\n\nSET sql_mode=\'oracle\';\n\nSELECT SUBSTR(\'abc\',0,3);\n+-------------------+\n| SUBSTR(\'abc\',0,3) |\n+-------------------+\n| abc               |\n+-------------------+\n\nSELECT SUBSTR(\'abc\',1,2);\n+-------------------+\n| SUBSTR(\'abc\',1,2) |\n+-------------------+\n| ab                |\n+-------------------+\n\nURL: https://mariadb.com/kb/en/substring/','','https://mariadb.com/kb/en/substring/'),(669,'SUBSTRING_INDEX',36,'Syntax\n------\n\nSUBSTRING_INDEX(str,delim,count)\n\nDescription\n-----------\n\nReturns the substring from string str before count occurrences of the\ndelimiter delim. If count is positive, everything to the left of the final\ndelimiter (counting from the left) is returned. If count is negative,\neverything to the right of the final delimiter (counting from the right) is\nreturned. SUBSTRING_INDEX() performs a case-sensitive match when searching for\ndelim.\n\nIf any argument is NULL, returns NULL.\n\nFor example\n\nSUBSTRING_INDEX(\'www.mariadb.org\', \'.\', 2)\n\nmeans \"Return all of the characters up to the 2nd occurrence of .\"\n\nExamples\n--------\n\nSELECT SUBSTRING_INDEX(\'www.mariadb.org\', \'.\', 2);\n+--------------------------------------------+\n| SUBSTRING_INDEX(\'www.mariadb.org\', \'.\', 2) |\n+--------------------------------------------+\n| www.mariadb                                |\n+--------------------------------------------+\n\nSELECT SUBSTRING_INDEX(\'www.mariadb.org\', \'.\', -2);\n+---------------------------------------------+\n| SUBSTRING_INDEX(\'www.mariadb.org\', \'.\', -2) |\n+---------------------------------------------+\n| mariadb.org                                 |\n+---------------------------------------------+\n\nURL: https://mariadb.com/kb/en/substring_index/','','https://mariadb.com/kb/en/substring_index/'),(670,'TO_BASE64',36,'Syntax\n------\n\nTO_BASE64(str)\n\nDescription\n-----------\n\nConverts the string argument str to its base-64 encoded form, returning the\nresult as a character string in the connection character set and collation.\n\nThe argument str will be converted to string first if it is not a string. A\nNULL argument will return a NULL result.\n\nThe reverse function, FROM_BASE64(), decodes an encoded base-64 string.\n\nThere are a numerous different methods to base-64 encode a string. The\nfollowing are used by MariaDB and MySQL:\n\n* Alphabet value 64 is encoded as \'+\'.\n* Alphabet value 63 is encoded as \'/\'.\n* Encoding output is made up of groups of four printable characters, with each\nthree bytes of data encoded using four characters. If the final group is not\ncomplete, it is padded with \'=\' characters to make up a length of four.\n* To divide long output, a newline is added after every 76 characters.\n* Decoding will recognize and ignore newlines, carriage returns, tabs, and\nspaces.\n\nExamples\n--------\n\nSELECT TO_BASE64(\'Maria\');\n+--------------------+\n| TO_BASE64(\'Maria\') |\n+--------------------+\n| TWFyaWE=           |\n+--------------------+\n\nURL: https://mariadb.com/kb/en/to_base64/','','https://mariadb.com/kb/en/to_base64/'),(671,'TRIM',36,'Syntax\n------\n\nTRIM([{BOTH | LEADING | TRAILING} [remstr] FROM] str), TRIM([remstr FROM] str)\n\nFrom MariaDB 10.3.6\n\nTRIM_ORACLE([{BOTH | LEADING | TRAILING} [remstr] FROM] str), TRIM([remstr\nFROM] str)\n\nDescription\n-----------\n\nReturns the string str with all remstr prefixes or suffixes removed. If none\nof the specifiers BOTH, LEADING, or TRAILING is given, BOTH is assumed. remstr\nis optional and, if not specified, spaces are removed.\n\nReturns NULL if given a NULL argument. If the result is empty, returns either\nan empty string, or, from MariaDB 10.3.6 with SQL_MODE=Oracle, NULL.\nSQL_MODE=Oracle is not set by default.\n\nThe Oracle mode version of the function can be accessed in any mode by using\nTRIM_ORACLE as the function name.\n\nExamples\n--------\n\nSELECT TRIM(\'  bar   \')\\G\n*************************** 1. row ***************************\nTRIM(\'  bar   \'): bar\n\nSELECT TRIM(LEADING \'x\' FROM \'xxxbarxxx\')\\G\n*************************** 1. row ***************************\nTRIM(LEADING \'x\' FROM \'xxxbarxxx\'): barxxx\n\nSELECT TRIM(BOTH \'x\' FROM \'xxxbarxxx\')\\G\n*************************** 1. row ***************************\nTRIM(BOTH \'x\' FROM \'xxxbarxxx\'): bar\n\nSELECT TRIM(TRAILING \'xyz\' FROM \'barxxyz\')\\G\n*************************** 1. row ***************************\nTRIM(TRAILING \'xyz\' FROM \'barxxyz\'): barx\n\nFrom MariaDB 10.3.6, with SQL_MODE=Oracle not set:\n\nSELECT TRIM(\'\'),TRIM_ORACLE(\'\');\n+----------+-----------------+\n| TRIM(\'\') | TRIM_ORACLE(\'\') |\n+----------+-----------------+\n|          | NULL            |\n+----------+-----------------+\n\nFrom MariaDB 10.3.6, with SQL_MODE=Oracle set:\n\nSELECT TRIM(\'\'),TRIM_ORACLE(\'\');\n+----------+-----------------+\n| TRIM(\'\') | TRIM_ORACLE(\'\') |\n+----------+-----------------+\n| NULL     | NULL            |\n+----------+-----------------+\n\nURL: https://mariadb.com/kb/en/trim/','','https://mariadb.com/kb/en/trim/'),(672,'UCASE',36,'Syntax\n------\n\nUCASE(str)\n\nDescription\n-----------\n\nUCASE() is a synonym for UPPER().\n\nURL: https://mariadb.com/kb/en/ucase/','','https://mariadb.com/kb/en/ucase/'),(673,'UNCOMPRESSED_LENGTH',36,'Syntax\n------\n\nUNCOMPRESSED_LENGTH(compressed_string)\n\nDescription\n-----------\n\nReturns the length that the compressed string had before being compressed with\nCOMPRESS().\n\nUNCOMPRESSED_LENGTH() returns NULL or an incorrect result if the string is not\ncompressed.\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 UNCOMPRESSED_LENGTH(COMPRESS(REPEAT(\'a\',30)));\n+-----------------------------------------------+\n| UNCOMPRESSED_LENGTH(COMPRESS(REPEAT(\'a\',30))) |\n+-----------------------------------------------+\n|                                            30 |\n+-----------------------------------------------+\n\nURL: https://mariadb.com/kb/en/uncompressed_length/','','https://mariadb.com/kb/en/uncompressed_length/'),(674,'UNHEX',36,'Syntax\n------\n\nUNHEX(str)\n\nDescription\n-----------\n\nPerforms the inverse operation of HEX(str). That is, it interprets each pair\nof hexadecimal digits in the argument as a number and converts it to the\ncharacter represented by the number. The resulting characters are returned as\na binary string.\n\nIf str is NULL, UNHEX() returns NULL.\n\nExamples\n--------\n\nSELECT HEX(\'MariaDB\');\n+----------------+\n| HEX(\'MariaDB\') |\n+----------------+\n| 4D617269614442 |\n+----------------+\n\nSELECT UNHEX(\'4D617269614442\');\n+-------------------------+\n| UNHEX(\'4D617269614442\') |\n+-------------------------+\n| MariaDB                 |\n+-------------------------+\n\nSELECT 0x4D617269614442;\n+------------------+\n| 0x4D617269614442 |\n+------------------+\n| MariaDB          |\n+------------------+\n\nSELECT UNHEX(HEX(\'string\'));\n+----------------------+\n| UNHEX(HEX(\'string\')) |\n+----------------------+\n| string               |\n+----------------------+\n\nSELECT HEX(UNHEX(\'1267\'));\n+--------------------+\n| HEX(UNHEX(\'1267\')) |\n+--------------------+\n| 1267               |\n+--------------------+\n\nURL: https://mariadb.com/kb/en/unhex/','','https://mariadb.com/kb/en/unhex/'),(675,'UPDATEXML',36,'Syntax\n------\n\nUpdateXML(xml_target, xpath_expr, new_xml)\n\nDescription\n-----------\n\nThis function replaces a single portion of a given fragment of XML markup\nxml_target with a new XML fragment new_xml, and then returns the changed XML.\nThe portion of xml_target that is replaced matches an XPath expression\nxpath_expr supplied by the user. If no expression matching xpath_expr is\nfound, or if multiple matches are found, the function returns the original\nxml_target XML fragment. All three arguments should be strings.\n\nExamples\n--------\n\nSELECT\n  UpdateXML(\'<a><b>ccc</b><d></d></a>\', \'/a\', \'<e>fff</e>\') AS val1,\n  UpdateXML(\'<a><b>ccc</b><d></d></a>\', \'/b\', \'<e>fff</e>\') AS val2,\n  UpdateXML(\'<a><b>ccc</b><d></d></a>\', \'//b\', \'<e>fff</e>\') AS val3,\n  UpdateXML(\'<a><b>ccc</b><d></d></a>\', \'/a/d\', \'<e>fff</e>\') AS val4,\n  UpdateXML(\'<a><d></d><b>ccc</b><d></d></a>\', \'/a/d\', \'<e>fff</e>\') AS val5\n  \\G\n*************************** 1. row ***************************\nval1: <e>fff</e>\nval2: <a><b>ccc</b><d></d></a>\nval3: <a><e>fff</e><d></d></a>\nval4: <a><b>ccc</b><e>fff</e></a>\nval5: <a><d></d><b>ccc</b><d></d></a>\n1 row in set (0.00 sec)\n\nURL: https://mariadb.com/kb/en/updatexml/','','https://mariadb.com/kb/en/updatexml/'),(676,'UPPER',36,'Syntax\n------\n\nUPPER(str)\n\nDescription\n-----------\n\nReturns the string str with all characters changed to uppercase according to\nthe current character set mapping. The default is latin1 (cp1252 West\nEuropean).\n\nSELECT UPPER(surname), givenname FROM users ORDER BY surname;\n+----------------+------------+\n| UPPER(surname) | givenname  |\n+----------------+------------+\n| ABEL           | Jacinto    |\n| CASTRO         | Robert     |\n| COSTA          | Phestos    |\n| MOSCHELLA      | Hippolytos |\n+----------------+------------+\n\nUPPER() is ineffective when applied to binary strings (BINARY, VARBINARY,\nBLOB). The description of LOWER() shows how to perform lettercase conversion\nof binary strings.\n\nURL: https://mariadb.com/kb/en/upper/','','https://mariadb.com/kb/en/upper/'),(677,'WEIGHT_STRING',36,'Syntax\n------\n\nWEIGHT_STRING(str [AS {CHAR|BINARY}(N)] [LEVEL levels] [flags])\n levels: N [ASC|DESC|REVERSE] [, N [ASC|DESC|REVERSE]] ...\n\nDescription\n-----------\n\nReturns a binary string representing the string\'s sorting and comparison\nvalue. A string with a lower result means that for sorting purposes the string\nappears before a string with a higher result.\n\nWEIGHT_STRING() is particularly useful when adding new collations, for testing\npurposes.\n\nIf str is a non-binary string (CHAR, VARCHAR or TEXT), WEIGHT_STRING returns\nthe string\'s collation weight. If str is a binary string (BINARY, VARBINARY or\nBLOB), the return value is simply the input value, since the weight for each\nbyte in a binary string is the byte value.\n\nWEIGHT_STRING() returns NULL if given a NULL input.\n\nThe optional AS clause permits casting the input string to a binary or\nnon-binary string, as well as to a particular length.\n\nAS BINARY(N) measures the length in bytes rather than characters, and right\npads with 0x00 bytes to the desired length.\n\nAS CHAR(N) measures the length in characters, and right pads with spaces to\nthe desired length.\n\nN has a minimum value of 1, and if it is less than the length of the input\nstring, the string is truncated without warning.\n\nThe optional LEVEL clause specifies that the return value should contain\nweights for specific collation levels. The levels specifier can either be a\nsingle integer, a comma-separated list of integers, or a range of integers\nseparated by a dash (whitespace is ignored). Integers can range from 1 to a\nmaximum of 6, dependent on the collation, and need to be listed in ascending\norder.\n\nIf the LEVEL clause is no provided, a default of 1 to the maximum for the\ncollation is assumed.\n\nIf the LEVEL is specified without using a range, an optional modifier is\npermitted.\n\nASC, the default, returns the weights without any modification.\n\nDESC returns bitwise-inverted weights.\n\nREVERSE returns the weights in reverse order.\n\nExamples\n--------\n\nThe examples below use the HEX() function to represent non-printable results\nin hexadecimal format.\n\nSELECT HEX(WEIGHT_STRING(\'x\'));\n+-------------------------+\n| HEX(WEIGHT_STRING(\'x\')) |\n+-------------------------+\n| 0058                    |\n+-------------------------+\n\nSELECT HEX(WEIGHT_STRING(\'x\' AS BINARY(4)));\n+--------------------------------------+\n| HEX(WEIGHT_STRING(\'x\' AS BINARY(4))) |\n+--------------------------------------+\n| 78000000                             |\n+--------------------------------------+\n\nSELECT HEX(WEIGHT_STRING(\'x\' AS CHAR(4)));\n+------------------------------------+\n| HEX(WEIGHT_STRING(\'x\' AS CHAR(4))) |\n+------------------------------------+\n| 0058002000200020                   |\n+------------------------------------+\n\nSELECT HEX(WEIGHT_STRING(0xaa22ee LEVEL 1));\n+--------------------------------------+\n| HEX(WEIGHT_STRING(0xaa22ee LEVEL 1)) |\n+--------------------------------------+\n| AA22EE                               |\n+--------------------------------------+\n\nSELECT HEX(WEIGHT_STRING(0xaa22ee LEVEL 1 DESC));\n+-------------------------------------------+\n| HEX(WEIGHT_STRING(0xaa22ee LEVEL 1 DESC)) |\n+-------------------------------------------+\n| 55DD11                                    |\n+-------------------------------------------+\n\nSELECT HEX(WEIGHT_STRING(0xaa22ee LEVEL 1 REVERSE));\n+----------------------------------------------+\n| HEX(WEIGHT_STRING(0xaa22ee LEVEL 1 REVERSE)) |\n+----------------------------------------------+\n| EE22AA                                       |\n+----------------------------------------------+\n\nURL: https://mariadb.com/kb/en/weight_string/','','https://mariadb.com/kb/en/weight_string/'),(678,'Type Conversion',36,'Implicit type conversion takes place when MariaDB is using operands or\ndifferent types, in order to make the operands compatible.\n\nIt is best practice not to rely upon implicit conversion; rather use CAST to\nexplicitly convert types.\n\nRules for Conversion on Comparison\n----------------------------------\n\n* If  either argument is NULL, the result of the comparison is NULL unless the\nNULL-safe <=> equality comparison operator is used.\n* If both arguments are integers, they are compared as integers.\n* If both arguments are strings, they are compared as strings.\n* If one argument is decimal and the other argument is decimal or integer,\nthey are compared as decimals.\n* If one argument is decimal and the other argument is a floating point, they\nare compared as floating point values.\n* If one argument is string and the other argument is integer, they are\ncompared as decimals. This conversion was added in MariaDB 10.3.36. Prior to\n10.3.36, this combination was compared as floating point values, which did not\nalways work well for huge 64-bit integers because of a possible precision loss\non conversion to double.\n* If a hexadecimal argument is not compared to a number, it is treated as a\nbinary string.\n* If a constant is compared to a TIMESTAMP or DATETIME, the constant is\nconverted to a timestamp, unless used as an argument to the IN function.\n* In other cases, arguments are compared as floating point, or real, numbers.\n\nNote that if a string column is being compared with a numeric value, MariaDB\nwill not use the index on the column, as there are numerous alternatives that\nmay evaluate as equal (see examples below).\n\nComparison Examples\n-------------------\n\nConverting a string to a number:\n\nSELECT 15+\'15\';\n+---------+\n| 15+\'15\' |\n+---------+\n|      30 |\n+---------+\n\nConverting a number to a string:\n\nSELECT CONCAT(15,\'15\');\n+-----------------+\n| CONCAT(15,\'15\') |\n+-----------------+\n| 1515            |\n+-----------------+\n\nFloating point number errors:\n\nSELECT \'9746718491924563214\' = 9746718491924563213;\n+---------------------------------------------+\n| \'9746718491924563214\' = 9746718491924563213 |\n+---------------------------------------------+\n|                                           1 |\n+---------------------------------------------+\n\nNumeric equivalence with strings:\n\nSELECT \'5\' = 5;\n+---------+\n| \'5\' = 5 |\n+---------+\n|       1 |\n+---------+\n\nSELECT \'   5\' = 5;\n+------------+\n| \'   5\' = 5 |\n+------------+\n|          1 |\n+------------+\n\nSELECT \'   5  \' = 5;\n+--------------+\n| \'   5  \' = 5 |\n+--------------+\n|            1 |\n+--------------+\n1 row in set, 1 warning (0.000 sec)\n\nSHOW WARNINGS;\n+-------+------+--------------------------------------------+\n| Level | Code | Message                                    |\n+-------+------+--------------------------------------------+\n| Note  | 1292 | Truncated incorrect DOUBLE value: \'   5  \' |\n+-------+------+--------------------------------------------+\n\nAs a result of the above, MariaDB cannot use the index when comparing a string\nwith a numeric value in the example below:\n\nCREATE TABLE t (a VARCHAR(10), b VARCHAR(10), INDEX idx_a (a));\n\nINSERT INTO t VALUES \n (\'1\', \'1\'), (\'2\', \'2\'), (\'3\', \'3\'),\n (\'4\', \'4\'), (\'5\', \'5\'), (\'1\', \'5\');\n\nEXPLAIN SELECT * FROM t WHERE a = \'3\' \\G\n*************************** 1. row ***************************\n     id: 1\n select_type: SIMPLE\n    table: t\n    type: ref\npossible_keys: idx_a\n     key: idx_a\n   key_len: 13\n     ref: const\n    rows: 1\n    Extra: Using index condition\n\nEXPLAIN SELECT * FROM t WHERE a = 3 \\G\n*************************** 1. row ***************************\n     id: 1\n select_type: SIMPLE\n    table: t\n    type: ALL\npossible_keys: idx_a\n     key: NULL\n   key_len: NULL\n     ref: NULL\n    rows: 6\n    Extra: Using where\n\nRules for Conversion on Dyadic Arithmetic Operations\n----------------------------------------------------\n\nImplicit type conversion also takes place on dyadic arithmetic operations\n(+,-,*,/). MariaDB chooses the minimum data type that is guaranteed to fit the\nresult and converts both arguments to the result data type.\n\nFor addition (+), subtraction (-) and multiplication (*), the result data type\nis chosen as follows:\n\n* If either of the arguments is an approximate number (float, double), the\nresult is double.\n* If either of the arguments is a string (char, varchar, text), the result is\ndouble.\n* If either of the arguments is a decimal number, the result is decimal.\n* If either of the arguments is of a temporal type with a non-zero fractional\nsecond precision (time(N), datetime(N), timestamp(N)), the result is decimal.\n* If either of the arguments is of a temporal type with a zero fractional\nsecond precision (time(0), date, datetime(0), timestamp(0)), the result may\nvary between int, int unsigned, bigint or bigint unsigned, depending on the\nexact data type combination.\n* If both arguments are integer numbers (tinyint, smallint, mediumint,\nbigint), the result may vary between int, int unsigned, bigint or bigint\nunsigned, depending of the exact data types and their signs.\n\nFor division (/), the result data type is chosen as follows:\n\n* If either of the arguments is an approximate number (float, double), the\nresult is double.\n* If either of the arguments is a string (char, varchar, text), the result is\ndouble.\n* Otherwise, the result is decimal.\n\nArithmetic Examples\n-------------------\n\nNote, the above rules mean that when an argument of a temporal data type\nappears in addition or subtraction, it\'s treated as a number by default.\n\nSELECT TIME\'10:20:30\' + 1;\n+--------------------+\n| TIME\'10:20:30\' + 1 |\n+--------------------+\n|             102031 |\n+--------------------+\n\nIn order to do temporal addition or subtraction instead, use the DATE_ADD() or\nDATE_SUB() functions, or an INTERVAL expression as the second argument:\n\nSELECT TIME\'10:20:30\' + INTERVAL 1 SECOND;\n+------------------------------------+\n| TIME\'10:20:30\' + INTERVAL 1 SECOND |\n+------------------------------------+\n| 10:20:31                           |\n+------------------------------------+\n\nSELECT \"2.2\" + 3;\n+-----------+\n| \"2.2\" + 3 |\n+-----------+\n|       5.2 |\n+-----------+\n\nSELECT 2.2 + 3;\n+---------+\n| 2.2 + 3 |\n+---------+\n| 5.2     |\n+---------+\n\nSELECT 2.2 / 3;\n+---------+\n| 2.2 / 3 |\n+---------+\n| 0.73333 |\n+---------+\n\nSELECT \"2.2\" / 3;\n+--------------------+\n| \"2.2\" / 3          |\n+--------------------+\n| 0.7333333333333334 |\n+--------------------+\n\nURL: https://mariadb.com/kb/en/type-conversion/','','https://mariadb.com/kb/en/type-conversion/'),(679,'_rowid',37,'Syntax\n------\n\n_rowid\n\nDescription\n-----------\n\nThe _rowid pseudo column is mapped to the primary key in the related table.\nThis can be used as a replacement of the rowid pseudo column in other\ndatabases. Another usage is to simplify sql queries as one doesn\'t have to\nknow the name of the primary key.\n\nExamples\n--------\n\ncreate table t1 (a int primary key, b varchar(80));\ninsert into t1 values (1,\"one\"),(2,\"two\");\nselect * from t1 where _rowid=1;\n\n+---+------+\n| a | b    |\n+---+------+\n| 1 | one  |\n+---+------+\n\nupdate t1 set b=\"three\" where _rowid=2;\nselect * from t1 where _rowid>=1 and _rowid<=10;\n\n+---+-------+\n| a | b     |\n+---+-------+\n| 1 | one   |\n| 2 | three |\n+---+-------+\n\nURL: https://mariadb.com/kb/en/_rowid/','','https://mariadb.com/kb/en/_rowid/'),(680,'ALTER TABLE',38,'Syntax\n------\n\nALTER [ONLINE] [IGNORE] TABLE [IF EXISTS] tbl_name\n  [WAIT n | NOWAIT]\n  alter_specification [, alter_specification] ...\nalter_specification:\n  table_option ...\n | ADD [COLUMN] [IF NOT EXISTS] col_name column_definition\n    [FIRST | AFTER col_name ]\n | ADD [COLUMN] [IF NOT EXISTS] (col_name column_definition,...)\n | ADD {INDEX|KEY} [IF NOT EXISTS] [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 [IF NOT EXISTS] [index_name] (index_col_name,...)\n    reference_definition\n | ADD PERIOD FOR SYSTEM_TIME (start_column_name, end_column_name)\n | ALTER [COLUMN] col_name SET DEFAULT literal | (expression)\n | ALTER [COLUMN] col_name DROP DEFAULT\n | ALTER {INDEX|KEY} index_name [NOT] INVISIBLE\n | CHANGE [COLUMN] [IF EXISTS] old_col_name new_col_name column_definition\n    [FIRST|AFTER col_name]\n | MODIFY [COLUMN] [IF EXISTS] col_name column_definition\n    [FIRST | AFTER col_name]\n | DROP [COLUMN] [IF EXISTS] col_name [RESTRICT|CASCADE]\n | DROP PRIMARY KEY\n | DROP {INDEX|KEY} [IF EXISTS] index_name\n | DROP FOREIGN KEY [IF EXISTS] fk_symbol\n | DROP CONSTRAINT [IF EXISTS] constraint_name\n | DISABLE KEYS\n | ENABLE KEYS\n | RENAME [TO] new_tbl_name\n | ORDER BY col_name [, col_name] ...\n | RENAME COLUMN old_col_name TO new_col_name\n | RENAME {INDEX|KEY} old_index_name TO new_index_name\n | CONVERT TO CHARACTER SET charset_name [COLLATE collation_name]\n | [DEFAULT] CHARACTER SET [=] charset_name\n | [DEFAULT] COLLATE [=] collation_name\n | DISCARD TABLESPACE\n | IMPORT TABLESPACE\n | ALGORITHM [=] {DEFAULT|INPLACE|COPY|NOCOPY|INSTANT}\n | LOCK [=] {DEFAULT|NONE|SHARED|EXCLUSIVE}\n | FORCE\n | partition_options\n | ADD PARTITION [IF NOT EXISTS] (partition_definition)\n | DROP PARTITION [IF EXISTS] partition_names\n | COALESCE PARTITION number\n | REORGANIZE PARTITION [partition_names INTO (partition_definitions)]\n | ANALYZE PARTITION partition_names\n | CHECK PARTITION partition_names\n | OPTIMIZE PARTITION partition_names\n | REBUILD PARTITION partition_names\n | REPAIR PARTITION partition_names\n | EXCHANGE PARTITION partition_name WITH TABLE tbl_name\n | REMOVE PARTITIONING\n | ADD SYSTEM VERSIONING\n | DROP SYSTEM VERSIONING\nindex_col_name:\n  col_name [(length)] [ASC | DESC]\nindex_type:\n  USING {BTREE | HASH | RTREE}\nindex_option:\n  [ KEY_BLOCK_SIZE [=] value\n | index_type\n | WITH PARSER parser_name\n | COMMENT \'string\'\n | CLUSTERING={YES| NO} ]\n [ IGNORED | NOT IGNORED ]\ntable_options:\n  table_option [[,] table_option] ...\n\nDescription\n-----------\n\nALTER TABLE enables you to change the structure of an existing table. For\nexample, you can add or delete columns, create or destroy indexes, change the\ntype of existing columns, or rename columns or the table itself. You can also\nchange the comment for the table and the storage engine of the table.\n\nIf another connection is using the table, a metadata lock is active, and this\nstatement will wait until the lock is released. This is also true for\nnon-transactional tables.\n\nWhen adding a UNIQUE index on a column (or a set of columns) which have\nduplicated values, an error will be produced and the statement will be\nstopped. To suppress the error and force the creation of UNIQUE indexes,\ndiscarding duplicates, the IGNORE option can be specified. This can be useful\nif a column (or a set of columns) should be UNIQUE but it contains duplicate\nvalues; however, this technique provides no control on which rows are\npreserved and which are deleted. Also, note that IGNORE is accepted but\nignored in ALTER TABLE ... EXCHANGE PARTITION statements.\n\nThis statement can also be used to rename a table. For details see RENAME\nTABLE.\n\nWhen an index is created, the storage engine may use a configurable buffer in\nthe 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 REPAIR TABLE. InnoDB allocates three\nbuffers whose size is defined by innodb_sort_buffer_size.\n\nPrivileges\n----------\n\nExecuting the ALTER TABLE statement generally requires at least the ALTER\nprivilege for the table or the database..\n\nIf you are renaming a table, then it also requires the DROP, CREATE and INSERT\nprivileges for the table or the database as well.\n\nOnline DDL\n----------\n\nOnline DDL is supported with the ALGORITHM and LOCK clauses.\n\nSee InnoDB Online DDL Overview for more information on online DDL with InnoDB.\n\nALTER ONLINE TABLE\n------------------\n\nALTER ONLINE TABLE also works for partitioned tables.\n\nOnline ALTER TABLE is available by executing the following:\n\nALTER ONLINE TABLE ...;\n\nThis statement has the following semantics:\n\nThis statement is equivalent to the following:\n\nALTER TABLE ... LOCK=NONE;\n\nSee the LOCK alter specification for more information.\n\nThis statement is equivalent to the following:\n\nALTER TABLE ... ALGORITHM=INPLACE;\n\nSee the ALGORITHM alter specification for more information.\n\nWAIT/NOWAIT\n-----------\n\nMariaDB starting with 10.3.0\n----------------------------\nSet the lock wait timeout. See WAIT and NOWAIT.\n\nIF EXISTS\n---------\n\nThe IF EXISTS and IF NOT EXISTS clauses are available for the following:\n\nADD COLUMN       [IF NOT EXISTS]\nADD INDEX        [IF NOT EXISTS]\nADD FOREIGN KEY  [IF NOT EXISTS]\nADD PARTITION    [IF NOT EXISTS]\nCREATE INDEX     [IF NOT EXISTS]\nDROP COLUMN      [IF EXISTS]\nDROP INDEX       [IF EXISTS]\nDROP FOREIGN KEY [IF EXISTS]\nDROP PARTITION   [IF EXISTS]\nCHANGE COLUMN    [IF EXISTS]\nMODIFY COLUMN    [IF EXISTS]\nDROP INDEX       [IF EXISTS]\nWhen IF EXISTS and IF NOT EXISTS are used in clauses, queries will not report\nerrors when the condition is triggered for that clause. A warning with the\nsame message text will be issued and the ALTER will move on to the next clause\nin the statement (or end if finished).\n\nMariaDB starting with 10.5.2\n----------------------------\nIf this is directive is used after ALTER ... TABLE, one will not get an error\nif the table doesn\'t exist.\n\nColumn Definitions\n------------------\n\nSee CREATE TABLE: Column Definitions for information about column definitions.\n\nIndex Definitions\n-----------------\n\nSee CREATE TABLE: Index Definitions for information about index definitions.\n\nThe CREATE INDEX and DROP INDEX statements can also be used to add or remove\nan index.\n\nCharacter Sets and Collations\n-----------------------------\n\nCONVERT TO CHARACTER SET charset_name [COLLATE collation_name]\n[DEFAULT] CHARACTER SET [=] charset_name\n[DEFAULT] COLLATE [=] collation_name\nSee Setting Character Sets and Collations for details on setting the character\nsets and collations.\n\nAlter Specifications\n--------------------\n\nTable Options\n-------------\n\nSee CREATE TABLE: Table Options for information about table options.\n\nADD COLUMN\n----------\n\n... ADD COLUMN [IF NOT EXISTS]  (col_name column_definition,...)\nAdds a column to the table. The syntax is the same as in CREATE TABLE. If you\nare using IF NOT_EXISTS the column will not be added if it was not there\nalready. This is very useful when doing scripts to modify tables.\n\nThe FIRST and AFTER clauses affect the physical order of columns in the\ndatafile. Use FIRST to add a column in the first (leftmost) position, or AFTER\nfollowed by a column name to add the new column in any other position. Note\nthat, nowadays, the physical position of a column is usually irrelevant.\n\nSee also Instant ADD COLUMN for InnoDB.\n\nDROP COLUMN\n-----------\n\n... DROP COLUMN [IF EXISTS] col_name [CASCADE|RESTRICT]\nDrops the column from the table. If you are using IF EXISTS you will not get\nan error if the column didn\'t exist. If the column is part of any index, the\ncolumn will be dropped from them, except if you add a new column with\nidentical name at the same time. The index will be dropped if all columns from\nthe index were dropped. If the column was used in a view or trigger, you will\nget an error next time the view or trigger is accessed.\n\nMariaDB starting with 10.2.8\n----------------------------\nDropping a column that is part of a multi-column UNIQUE constraint is not\npermitted. For example:\n\nCREATE TABLE a (\n a int,\n b int,\n primary key (a,b)\n);\n\nALTER TABLE x DROP COLUMN a;\n[42000][1072] Key column \'A\' doesn\'t exist in table\n\nThe reason is that dropping column a would result in the new constraint that\nall values in column b be unique. In order to drop the column, an explicit\nDROP PRIMARY KEY and ADD PRIMARY KEY would be required. Up until MariaDB\n10.2.7, the column was dropped and the additional constraint applied,\nresulting in the following structure:\n\nALTER TABLE x DROP COLUMN a;\nQuery OK, 0 rows affected (0.46 sec)\n\nDESC x;\n+-------+---------+------+-----+---------+-------+\n| Field | Type    | Null | Key | Default | Extra |\n+-------+---------+------+-----+---------+-------+\n| b     | int(11) | NO   | PRI | NULL    |       |\n+-------+---------+------+-----+---------+-------+\n\nMariaDB starting with 10.4.0\n----------------------------\nMariaDB 10.4.0 supports instant DROP COLUMN. DROP COLUMN of an indexed column\nwould imply DROP INDEX (and in the case of a non-UNIQUE multi-column index,\npossibly ADD INDEX). These will not be allowed with ALGORITHM=INSTANT, but\nunlike before, they can be allowed with ALGORITHM=NOCOPY\n\nRESTRICT and CASCADE are allowed to make porting from other database systems\neasier. In MariaDB, they do nothing.\n\nMODIFY COLUMN\n-------------\n\nAllows you to modify the type of a column. The column will be at the same\nplace as the original column and all indexes on the column will be kept. Note\nthat when modifying column, you should specify all attributes for the new\ncolumn.\n\nCREATE TABLE t1 (a INT UNSIGNED AUTO_INCREMENT, PRIMARY KEY((a));\nALTER TABLE t1 MODIFY a BIGINT UNSIGNED AUTO_INCREMENT;\n\nCHANGE COLUMN\n-------------\n\nWorks like MODIFY COLUMN except that you can also change the name of the\ncolumn. The column will be at the same place as the original column and all\nindex on the column will be kept.\n\nCREATE TABLE t1 (a INT UNSIGNED AUTO_INCREMENT, PRIMARY KEY(a));\nALTER TABLE t1 CHANGE a b BIGINT UNSIGNED AUTO_INCREMENT;\n\nALTER COLUMN\n------------\n\nThis lets you change column options.\n\nCREATE TABLE t1 (a INT UNSIGNED AUTO_INCREMENT, b varchar(50), PRIMARY KEY(a));\nALTER TABLE t1 ALTER b SET DEFAULT \'hello\';\n\nRENAME INDEX/KEY\n----------------\n\nMariaDB starting with 10.5.2\n----------------------------\nFrom MariaDB 10.5.2, it is possible to rename an index using the RENAME INDEX\n(or RENAME KEY) syntax, for example:\n\nALTER TABLE t1 RENAME INDEX i_old TO i_new;\n\nRENAME COLUMN\n-------------\n\nMariaDB starting with 10.5.2\n----------------------------\nFrom MariaDB 10.5.2, it is possible to rename a column using the RENAME COLUMN\nsyntax, for example:\n\nALTER TABLE t1 RENAME COLUMN c_old TO c_new;\n\nADD PRIMARY KEY\n---------------\n\nAdd a primary key.\n\nFor PRIMARY KEY indexes, you can specify a name for the index, but it is\nsilently ignored, and the name of the index is always PRIMARY.\n\nSee Getting Started with Indexes: Primary Key for more information.\n\nDROP PRIMARY KEY\n----------------\n\nDrop a primary key.\n\nFor PRIMARY KEY indexes, you can specify a name for the index, but it is\nsilently ignored, and the name of the index is always PRIMARY.\n\nSee Getting Started with Indexes: Primary Key for more information.\n\nADD FOREIGN KEY\n---------------\n\nAdd a foreign key.\n\nFor FOREIGN KEY indexes, a reference definition must be provided.\n\nFor FOREIGN KEY indexes, you can specify a name for the constraint, using the\nCONSTRAINT keyword. That name will be used in error messages.\n\nFirst, you have to specify the name of the target (parent) table and a column\nor a column list which must be indexed and whose values must match to the\nforeign key\'s values. The MATCH clause is accepted to improve the\ncompatibility with other DBMS\'s, but has no meaning in MariaDB. The ON DELETE\nand ON UPDATE clauses specify what must be done when a DELETE (or a REPLACE)\nstatements attempts to delete a referenced row from the parent table, and when\nan UPDATE statement attempts to modify the referenced foreign key columns in a\nparent table row, respectively. The following options are allowed:\n\n* RESTRICT: The delete/update operation is not performed.  The statement\nterminates with a 1451 error (SQLSTATE \'2300\').\n* NO ACTION: Synonym for RESTRICT.\n* CASCADE: The delete/update operation is performed in both tables.\n* SET NULL: The update or delete goes ahead in the parent table, and the\ncorresponding foreign key fields in the child table are set to NULL.  (They\nmust not be defined as NOT NULL for this to succeed).\n* SET DEFAULT: This option is implemented only for the legacy PBXT storage\nengine, which is disabled by default and no longer maintained. It sets the\nchild table\'s foreign key fields to their DEFAULT values when the referenced\nparent table key entries are updated or deleted.\n\nIf either clause is omitted, the default behavior for the omitted clause is\nRESTRICT.\n\nSee Foreign Keys for more information.\n\nDROP FOREIGN KEY\n----------------\n\nDrop a foreign key.\n\nSee Foreign Keys for more information.\n\nADD INDEX\n---------\n\nAdd a plain index.\n\nPlain indexes are regular indexes that are not unique, and are not acting as a\nprimary key or a foreign key. They are also not the \"specialized\" FULLTEXT or\nSPATIAL indexes.\n\nSee Getting Started with Indexes: Plain Indexes for more information.\n\nDROP INDEX\n----------\n\nDrop a plain index.\n\nPlain indexes are regular indexes that are not unique, and are not acting as a\nprimary key or a foreign key. They are also not the \"specialized\" FULLTEXT or\nSPATIAL indexes.\n\nSee Getting Started with Indexes: Plain Indexes for more information.\n\nADD UNIQUE INDEX\n----------------\n\nAdd a unique index.\n\nThe UNIQUE keyword means that the index will not accept duplicated values,\nexcept for NULLs. An error will raise if you try to insert duplicate values in\na UNIQUE index.\n\nFor UNIQUE indexes, you can specify a name for the constraint, using the\nCONSTRAINT keyword. That name will be used in error messages.\n\nSee Getting Started with Indexes: Unique Index for more information.\n\nDROP UNIQUE INDEX\n-----------------\n\nDrop a unique index.\n\nThe UNIQUE keyword means that the index will not accept duplicated values,\nexcept for NULLs. An error will raise if you try to insert duplicate values in\na UNIQUE index.\n\nFor UNIQUE indexes, you can specify a name for the constraint, using the\nCONSTRAINT keyword. That name will be used in error messages.\n\nSee Getting Started with Indexes: Unique Index for more information.\n\nADD FULLTEXT INDEX\n------------------\n\nAdd a FULLTEXT index.\n\nSee Full-Text Indexes for more information.\n\nDROP FULLTEXT INDEX\n-------------------\n\nDrop a FULLTEXT index.\n\nSee Full-Text Indexes for more information.\n\nADD SPATIAL INDEX\n-----------------\n\nAdd a SPATIAL index.\n\nSee SPATIAL INDEX for more information.\n\nDROP SPATIAL INDEX\n------------------\n\nDrop a SPATIAL index.\n\nSee SPATIAL INDEX for more information.\n\nENABLE/ DISABLE KEYS\n--------------------\n\nDISABLE KEYS will disable all non unique keys for the table for storage\nengines that support this (at least MyISAM and Aria). This can be used to\nspeed up inserts into empty tables.\n\nENABLE KEYS will enable all disabled keys.\n\nRENAME TO\n---------\n\nRenames the table. See also RENAME TABLE.\n\nADD CONSTRAINT\n--------------\n\nModifies the table adding a constraint on a particular column or columns.\n\nMariaDB starting with 10.2.1\n----------------------------\nMariaDB 10.2.1 introduced new ways to define a constraint.\n\nNote: Before MariaDB 10.2.1, constraint expressions were accepted in syntax,\nbut ignored.\n\nALTER TABLE table_name \nADD CONSTRAINT [constraint_name] CHECK(expression);\nBefore a row is inserted or updated, all constraints are evaluated in the\norder they are defined. If any constraint fails, then the row will not be\nupdated. One can use most deterministic functions in a constraint, including\nUDF\'s.\n\nCREATE TABLE account_ledger (\n	id INT PRIMARY KEY AUTO_INCREMENT,\n	transaction_name VARCHAR(100),\n	credit_account VARCHAR(100),\n	credit_amount INT,\n	debit_account VARCHAR(100),\n	debit_amount INT);\n\nALTER TABLE account_ledger \nADD CONSTRAINT is_balanced \n  CHECK((debit_amount + credit_amount) = 0);\n\nThe constraint_name is optional. If you don\'t provide one in the ALTER TABLE\nstatement, MariaDB auto-generates a name for you. This is done so that you can\nremove it later using DROP CONSTRAINT clause.\n\nYou can disable all constraint expression checks by setting the variable\ncheck_constraint_checks to OFF. You may find this useful when loading a table\nthat violates some constraints that you want to later find and fix in SQL.\n\nTo view constraints on a table, query information_schema.TABLE_CONSTRAINTS:\n\nSELECT CONSTRAINT_NAME, TABLE_NAME, CONSTRAINT_TYPE \nFROM information_schema.TABLE_CONSTRAINTS\nWHERE TABLE_NAME = \'account_ledger\';\n\n+-----------------+----------------+-----------------+\n| CONSTRAINT_NAME | TABLE_NAME     | CONSTRAINT_TYPE |\n+-----------------+----------------+-----------------+\n| is_balanced     | account_ledger | CHECK           |\n+-----------------+----------------+-----------------+\n\nDROP CONSTRAINT\n---------------\n\nMariaDB starting with 10.2.22\n-----------------------------\nDROP CONSTRAINT for UNIQUE and FOREIGN KEY constraints was introduced in\nMariaDB 10.2.22 and MariaDB 10.3.13.\n\nMariaDB starting with 10.2.1\n----------------------------\nDROP CONSTRAINT for CHECK constraints was introduced in MariaDB 10.2.1\n\nModifies the table, removing the given constraint.\n\nALTER TABLE table_name\nDROP CONSTRAINT constraint_name;\n\nWhen you add a constraint to a table, whether through a CREATE TABLE or ALTER\nTABLE...ADD CONSTRAINT statement, you can either set a constraint_name\nyourself, or allow MariaDB to auto-generate one for you. To view constraints\non a table, query information_schema.TABLE_CONSTRAINTS. For instance,\n\nCREATE TABLE t (\n a INT,\n b INT,\n c INT,\n CONSTRAINT CHECK(a > b),\n CONSTRAINT check_equals CHECK(a = c));\n\nSELECT CONSTRAINT_NAME, TABLE_NAME, CONSTRAINT_TYPE \nFROM information_schema.TABLE_CONSTRAINTS\nWHERE TABLE_NAME = \'t\';\n\n+-----------------+----------------+-----------------+\n| CONSTRAINT_NAME | TABLE_NAME     | CONSTRAINT_TYPE |\n+-----------------+----------------+-----------------+\n| check_equals    | t              | CHECK           |\n| CONSTRAINT_1    | t              | CHECK           |\n+-----------------+----------------+-----------------+\n\nTo remove a constraint from the table, issue an ALTER TABLE...DROP CONSTRAINT\nstatement. For example,\n\nALTER TABLE t DROP CONSTRAINT is_unique;\n\nADD SYSTEM VERSIONING\n---------------------\n\nMariaDB starting with 10.3.4\n----------------------------\nSystem-versioned tables was added in MariaDB 10.3.4.\n\nAdd system versioning.\n\nDROP SYSTEM VERSIONING\n----------------------\n\nMariaDB starting with 10.3.4\n----------------------------\nSystem-versioned tables was added in MariaDB 10.3.4.\n\nDrop system versioning.\n\nADD PERIOD FOR SYSTEM_TIME\n--------------------------\n\nMariaDB starting with 10.3.4\n----------------------------\nSystem-versioned tables was added in MariaDB 10.3.4.\n\nFORCE\n-----\n\nALTER TABLE ... FORCE can force MariaDB to re-build the table.\n\nIn MariaDB 5.5 and before, this could only be done by setting the ENGINE table\noption to its old value. For example, for an InnoDB table, one could execute\nthe following:\n\nALTER TABLE tab_name ENGINE = InnoDB;\n\nThe FORCE option can be used instead. For example, :\n\nALTER TABLE tab_name FORCE;\n\nWith InnoDB, the table rebuild will only reclaim unused space (i.e. the space\npreviously used for deleted rows) if the innodb_file_per_table system variable\nis set to ON (the default). If the system variable is OFF, then the space will\nnot be reclaimed, but it will be-re-used for new data that\'s later added.\n\nEXCHANGE PARTITION\n------------------\n\nThis is used to exchange the contents of a partition with another table.\n\nThis is performed by swapping the tablespaces of the partition with the other\ntable.\n\nSee copying InnoDB\'s transportable tablespaces for more information.\n\nDISCARD TABLESPACE\n------------------\n\nThis is used to discard an InnoDB table\'s tablespace.\n\nSee copying InnoDB\'s transportable tablespaces for more information.\n\nIMPORT TABLESPACE\n-----------------\n\nThis is used to import an InnoDB table\'s tablespace. The tablespace should\nhave been copied from its original server after executing FLUSH TABLES FOR\nEXPORT.\n\nSee copying InnoDB\'s transportable tablespaces for more information.\n\nALTER TABLE ... IMPORT only applies to InnoDB tables. Most other popular\nstorage engines, such as Aria and MyISAM, will recognize their data files as\nsoon as they\'ve been placed in the proper directory under the datadir, and no\nspecial DDL is required to import them.\n\nALGORITHM\n---------\n\nThe ALTER TABLE statement supports the ALGORITHM clause. This clause is one of\nthe clauses that is used to implement online DDL. ALTER TABLE supports several\ndifferent algorithms. An algorithm can be explicitly chosen for an ALTER TABLE\noperation by setting the ALGORITHM clause. The supported values are:\n\n* ALGORITHM=DEFAULT - This implies the default behavior for the specific\nstatement, such as if no ALGORITHM clause is specified.\n* ALGORITHM=COPY\n* ALGORITHM=INPLACE\n* ALGORITHM=NOCOPY - This was added in MariaDB 10.3.7.\n* ALGORITHM=INSTANT - This was added in MariaDB 10.3.7.\n\nSee InnoDB Online DDL Overview: ALGORITHM for information on how the ALGORITHM\nclause affects InnoDB.\n\nALGORITHM=DEFAULT\n-----------------\n\nThe default behavior, which occurs if ALGORITHM=DEFAULT is specified, or if\nALGORITHM is not specified at all, usually only makes a copy if the operation\ndoesn\'t support being done in-place at all. In this case, the most efficient\navailable algorithm will usually be used.\n\nHowever, in MariaDB 10.3.6 and before, if the value of the old_alter_table\nsystem variable is set to ON, then the default behavior is to perform ALTER\nTABLE operations by making a copy of the table using the old algorithm.\n\nIn MariaDB 10.3.7 and later, the old_alter_table system variable is\ndeprecated. Instead, the alter_algorithm system variable defines the default\nalgorithm for ALTER TABLE operations.\n\nALGORITHM=COPY\n--------------\n\nALGORITHM=COPY is the name for the original ALTER TABLE algorithm from early\nMariaDB versions.\n\nWhen ALGORITHM=COPY is set, MariaDB essentially does the following operations:\n\n-- Create a temporary table with the new definition\nCREATE TEMPORARY TABLE tmp_tab (\n...\n);\n\n-- Copy the data from the original table\nINSERT INTO tmp_tab\n SELECT * FROM original_tab;\n\n-- Drop the original table\nDROP TABLE original_tab;\n\n-- Rename the temporary table, so that it replaces the original one\nRENAME TABLE tmp_tab TO original_tab;\n\nThis algorithm is very inefficient, but it is generic, so it works for all\nstorage engines.\n\nIf ALGORITHM=COPY is specified, then the copy algorithm will be used even if\nit is not necessary. This can result in a lengthy table copy. If multiple\nALTER TABLE operations are required that each require the table to be rebuilt,\nthen it is best to specify all operations in a single ALTER TABLE statement,\nso that the table is only rebuilt once.\n\nALGORITHM=INPLACE\n-----------------\n\nALGORITHM=COPY can be incredibly slow, because the whole table has to be\ncopied and rebuilt. ALGORITHM=INPLACE was introduced as a way to avoid this by\nperforming operations in-place and avoiding the table copy and rebuild, when\npossible.\n\nWhen ALGORITHM=INPLACE is set, the underlying storage engine uses\noptimizations to perform the operation while avoiding the table copy and\nrebuild. However, INPLACE is a bit of a misnomer, since some operations may\nstill require the table to be rebuilt for some storage engines. Regardless,\nseveral operations can be performed without a full copy of the table for some\nstorage engines.\n\nA more accurate name would have been ALGORITHM=ENGINE, where ENGINE refers to\nan \"engine-specific\" algorithm.\n\nIf an ALTER TABLE operation supports ALGORITHM=INPLACE, then it can be\nperformed using optimizations by the underlying storage engine, but it may\nrebuilt.\n\nSee InnoDB Online DDL Operations with ALGORITHM=INPLACE for more.\n\nALGORITHM=NOCOPY\n----------------\n\nALGORITHM=NOCOPY was introduced in MariaDB 10.3.7.\n\nALGORITHM=INPLACE can sometimes be surprisingly slow in instances where it has\nto rebuild the clustered index, because when the clustered index has to be\nrebuilt, the whole table has to be rebuilt. ALGORITHM=NOCOPY was introduced as\na way to avoid this.\n\nIf an ALTER TABLE operation supports ALGORITHM=NOCOPY, then it can be\nperformed without rebuilding the clustered index.\n\nIf ALGORITHM=NOCOPY is specified for an ALTER TABLE operation that does not\nsupport ALGORITHM=NOCOPY, then an error will be raised. In this case, raising\nan error is preferable, if the alternative is for the operation to rebuild the\nclustered index, and perform unexpectedly slowly.\n\nSee InnoDB Online DDL Operations with ALGORITHM=NOCOPY for more.\n\nALGORITHM=INSTANT\n-----------------\n\nALGORITHM=INSTANT was introduced in MariaDB 10.3.7.\n\nALGORITHM=INPLACE can sometimes be surprisingly slow in instances where it has\nto modify data files. ALGORITHM=INSTANT was introduced as a way to avoid this.\n\nIf an ALTER TABLE operation supports ALGORITHM=INSTANT, then it can be\nperformed without modifying any data files.\n\nIf ALGORITHM=INSTANT is specified for an ALTER TABLE operation that does not\nsupport ALGORITHM=INSTANT, then an error will be raised. In this case, raising\nan error is preferable, if the alternative is for the operation to modify data\nfiles, and perform unexpectedly slowly.\n\nSee InnoDB Online DDL Operations with ALGORITHM=INSTANT for more.\n\nLOCK\n----\n\nThe ALTER TABLE statement supports the LOCK clause. This clause is one of the\nclauses that is used to implement online DDL. ALTER TABLE supports several\ndifferent locking strategies. A locking strategy can be explicitly chosen for\nan ALTER TABLE operation by setting the LOCK clause. The supported values are:\n\n* DEFAULT: Acquire the least restrictive lock on the table that is supported\nfor the specific operation. Permit the maximum amount of concurrency that is\nsupported for the specific operation.\n* NONE: Acquire no lock on the table. Permit all concurrent DML. If this\nlocking strategy is not permitted for an operation, then an error is raised.\n* SHARED: Acquire a read lock on the table. Permit read-only concurrent DML.\nIf this locking strategy is not permitted for an operation, then an error is\nraised.\n* EXCLUSIVE: Acquire a write lock on the table. Do not permit concurrent DML.\n\nDifferent storage engines support different locking strategies for different\noperations. If a specific locking strategy is chosen for an ALTER TABLE\noperation, and that table\'s storage engine does not support that locking\nstrategy for that specific operation, then an error will be raised.\n\nIf the LOCK clause is not explicitly set, then the operation uses LOCK=DEFAULT.\n\nALTER ONLINE TABLE is equivalent to LOCK=NONE. Therefore, the ALTER ONLINE\nTABLE statement can be used to ensure that your ALTER TABLE operation allows\nall concurrent DML.\n\nSee InnoDB Online DDL Overview: LOCK for information on how the LOCK clause\naffects InnoDB.\n\nProgress Reporting\n------------------\n\nMariaDB provides progress reporting for ALTER TABLE statement for clients that\nsupport the new progress reporting protocol. For example, if you were using\nthe mysql client, then the progress report might look like this::\n\nALTER TABLE test ENGINE=Aria;\nStage: 1 of 2 \'copy to tmp table\'    46% of stage\n\nThe progress report is also shown in the output of the SHOW PROCESSLIST\nstatement and in the contents of the information_schema.PROCESSLIST table.\n\nSee Progress Reporting for more information.\n\nAborting ALTER TABLE Operations\n-------------------------------\n\nIf an ALTER TABLE operation is being performed and the connection is killed,\nthe changes will be rolled back in a controlled manner. The rollback can be a\nslow operation as the time it takes is relative to how far the operation has\nprogressed.\n\nMariaDB starting with 10.2.13\n-----------------------------\nAborting ALTER TABLE ... ALGORITHM=COPY was made faster by removing excessive\nundo logging (MDEV-11415). This significantly shortens the time it takes to\nabort a running ALTER TABLE operation.\n\nAtomic ALTER TABLE\n------------------\n\nMariaDB starting with 10.6.1\n----------------------------\nFrom MariaDB 10.6, ALTER TABLE is atomic for most engines, including InnoDB,\nMyRocks, MyISAM and Aria (MDEV-25180). This means that if there is a crash\n(server down or power outage) during an ALTER TABLE operation, after recovery,\neither the old table and associated triggers and status will be intact, or the\nnew table will be active.\n\nIn older MariaDB versions one could get leftover #sql-alter..\',\n\'#sql-backup..\' or \'table_name.frm˝\' files if the system crashed during the\nALTER TABLE operation.\n\nSee Atomic DDL for more information.\n\nReplication\n-----------\n\nMariaDB starting with 10.8.1\n----------------------------\nBefore MariaDB 10.8.1, ALTER TABLE got fully executed on the primary first,\nand only then was it replicated and started executing on replicas. From\nMariaDB 10.8.1, ALTER TABLE gains an option to replicate sooner and begin\nexecuting on replicas when it merely starts executing on the primary, not when\nit finishes. This way the replication lag caused by a heavy ALTER TABLE can be\ncompletely eliminated (MDEV-11675).\n\nExamples\n--------\n\nAdding a new column:\n\nALTER TABLE t1 ADD x INT;\n\nDropping a column:\n\nALTER TABLE t1 DROP x;\n\nModifying the type of a column:\n\nALTER TABLE t1 MODIFY x bigint unsigned;\n\nChanging the name and type of a column:\n\nALTER TABLE t1 CHANGE a b bigint unsigned auto_increment;\n\nCombining multiple clauses in a single ALTER TABLE statement, separated by\ncommas:\n\nALTER TABLE t1 DROP x, ADD x2 INT,  CHANGE y y2 INT;\n\nChanging the storage engine and adding a comment:\n\nALTER TABLE t1 \n ENGINE = InnoDB\n COMMENT = \'First of three tables containing usage info\';\n\nRebuilding the table (the previous example will also rebuild the table if it\nwas already InnoDB):\n\nALTER TABLE t1 FORCE;\n\nDropping an index:\n\nALTER TABLE rooms DROP INDEX u;\n\nAdding a unique index:\n\nALTER TABLE rooms ADD UNIQUE INDEX u(room_number);\n\nFrom MariaDB 10.5.3, adding a primary key for an application-time period table\nwith a WITHOUT OVERLAPS constraint:\n\nALTER TABLE rooms ADD PRIMARY KEY(room_number, p WITHOUT OVERLAPS);\n\nFrom MariaDB 10.8.1, ALTER query can be replicated faster with the setting of\n\nSET @@SESSION.binlog_alter_two_phase = true;\n\nprior the ALTER query. Binlog would contain two event groups\n\n| master-bin.000001 | 495 | Gtid              |         1 |         537 | GTID\n0-1-2 START ALTER                                        |\n| master-bin.000001 | 537 | Query             |         1 |         655 | use\n`test`; alter table t add column b int, algorithm=inplace |\n| master-bin.000001 | 655 | Gtid              |         1 |         700 | GTID\n0-1-3 COMMIT ALTER id=2                                  |\n| master-bin.000001 | 700 | Query             |         1 |         835 | use\n`test`; alter table t add column b int, algorithm=inplace |\n\nof which the first one gets delivered to replicas before ALTER is taken to\nactual execution on the primary.\n\nURL: https://mariadb.com/kb/en/alter-table/','','https://mariadb.com/kb/en/alter-table/'),(681,'ALTER DATABASE',38,'Modifies a database, changing its overall characteristics.\n\nSyntax\n------\n\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 | COMMENT [=] \'comment\'\n\nDescription\n-----------\n\nALTER DATABASE enables you to change the overall characteristics of a\ndatabase. These characteristics are stored in the db.opt file in the database\ndirectory. To use ALTER DATABASE, you need the ALTER privilege on the\ndatabase. ALTER SCHEMA is a synonym for ALTER DATABASE.\n\nThe CHARACTER SET clause changes the default database character set. The\nCOLLATE clause changes the default database collation. See Character Sets and\nCollations for more.\n\nYou can see what character sets and collations are available using,\nrespectively, the SHOW CHARACTER SET and SHOW COLLATION statements.\n\nChanging the default character set/collation of a database does not change the\ncharacter set/collation of any stored procedures or stored functions that were\npreviously created, and relied on the defaults. These need to be dropped and\nrecreated in order to apply the character set/collation changes.\n\nThe database name can be omitted from the first syntax, in which case the\nstatement applies to the default database.\n\nThe syntax that includes the UPGRADE DATA DIRECTORY NAME clause was added in\nMySQL 5.1.23. It updates the name of the directory associated with the\ndatabase to use the encoding implemented in MySQL 5.1 for mapping database\nnames to database directory names (see Identifier to File Name Mapping). This\nclause is for use under these conditions:\n\n* It is intended when upgrading MySQL to 5.1 or later from older versions.\n* It is intended to update a database directory name to the current encoding\nformat if the name contains special characters that need encoding.\n* The statement is used by mysqlcheck (as invoked by mysql_upgrade).\n\nFor example,if a database in MySQL 5.0 has a name of a-b-c, the name contains\ninstance of the `-\' character. In 5.0, the database directory is also named\na-b-c, which is not necessarily safe for all file systems. In MySQL 5.1 and\nup, the same database name is encoded as a@002db@002dc to produce a file\nsystem-neutral directory name.\n\nWhen a MySQL installation is upgraded to MySQL 5.1 or later from an older\nversion,the server displays a name such as a-b-c (which is in the old format)\nas #mysql50#a-b-c, and you must refer to the name using the #mysql50# prefix.\nUse UPGRADE DATA DIRECTORY NAME in this case to explicitly tell the server to\nre-encode the database directory name to the 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 without\nthe special #mysql50# prefix.\n\nCOMMENT\n-------\n\nMariaDB starting with 10.5.0\n----------------------------\nFrom MariaDB 10.5.0, it is possible to add a comment of a maximum of 1024\nbytes. If the comment length exceeds this length, a error/warning code 4144 is\nthrown. The database comment is also added to the db.opt file, as well as to\nthe information_schema.schemata table.\n\nExamples\n--------\n\nALTER DATABASE test CHARACTER SET=\'utf8\'  COLLATE=\'utf8_bin\';\n\nFrom MariaDB 10.5.0:\n\nALTER DATABASE p COMMENT=\'Presentations\';\n\nURL: https://mariadb.com/kb/en/alter-database/','','https://mariadb.com/kb/en/alter-database/'),(682,'ALTER EVENT',38,'Modifies one or more characteristics of an existing event.\n\nSyntax\n------\n\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 sql_statement]\n\nDescription\n-----------\n\nThe ALTER EVENT statement is used to change one or more of the characteristics\nof an existing event without the need to drop and recreate it. The syntax for\neach of the DEFINER, ON SCHEDULE, ON COMPLETION, COMMENT, ENABLE / DISABLE,\nand DO clauses is exactly the same as when used with CREATE EVENT.\n\nThis statement requires the EVENT privilege. When a user executes a successful\nALTER EVENT statement, that user becomes the definer for the affected event.\n\n(In MySQL 5.1.11 and earlier, an event could be altered only by its definer,\nor by a user having the SUPER privilege.)\n\nALTER EVENT works only with an existing event:\n\nALTER EVENT no_such_event ON SCHEDULE EVERY \'2:3\' DAY_HOUR;\nERROR 1539 (HY000): Unknown event \'no_such_event\'\n\nExamples\n--------\n\nALTER EVENT myevent \n ON SCHEDULE AT CURRENT_TIMESTAMP + INTERVAL 2 HOUR\n DO\n  UPDATE myschema.mytable SET mycol = mycol + 1;\n\nURL: https://mariadb.com/kb/en/alter-event/','','https://mariadb.com/kb/en/alter-event/'),(683,'ALTER FUNCTION',38,'Syntax\n------\n\nALTER FUNCTION func_name [characteristic ...]\n\ncharacteristic:\n  { CONTAINS SQL | NO SQL | READS SQL DATA | MODIFIES SQL DATA }\n | SQL SECURITY { DEFINER | INVOKER }\n | COMMENT \'string\'\n\nDescription\n-----------\n\nThis statement can be used to change the characteristics of a stored function.\nMore than one change may be specified in an ALTER FUNCTION statement. However,\nyou cannot change the parameters or body of a stored function using this\nstatement; to make such changes, you must drop and re-create the function\nusing DROP FUNCTION and CREATE FUNCTION.\n\nYou must have the ALTER ROUTINE privilege for the function. (That privilege is\ngranted automatically to the function creator.) If binary logging is enabled,\nthe ALTER FUNCTION statement might also require the SUPER privilege, as\ndescribed in Binary Logging of Stored Routines.\n\nExample\n-------\n\nALTER FUNCTION hello SQL SECURITY INVOKER;\n\nURL: https://mariadb.com/kb/en/alter-function/','','https://mariadb.com/kb/en/alter-function/'),(684,'ALTER LOGFILE GROUP',38,'Syntax\n------\n\nALTER LOGFILE GROUP logfile_group\n  ADD UNDOFILE \'file_name\'\n  [INITIAL_SIZE [=] size]\n  [WAIT]\n  ENGINE [=] engine_name\n\nThe ALTER LOGFILE GROUP statement is not supported by MariaDB. It was\noriginally inherited from MySQL NDB Cluster. See MDEV-19295 for more\ninformation.\n\nURL: https://mariadb.com/kb/en/alter-logfile-group/','','https://mariadb.com/kb/en/alter-logfile-group/'),(685,'ALTER PROCEDURE',38,'Syntax\n------\n\nALTER PROCEDURE proc_name [characteristic ...]\n\ncharacteristic:\n  { CONTAINS SQL | NO SQL | READS SQL DATA | MODIFIES SQL DATA }\n | SQL SECURITY { DEFINER | INVOKER }\n | COMMENT \'string\'\n\nDescription\n-----------\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 stored\nprocedure using this statement. To make such changes, you must drop and\nre-create the procedure using either CREATE OR REPLACE PROCEDURE (since\nMariaDB 10.1.3) or DROP PROCEDURE and CREATE PROCEDURE (MariaDB 10.1.2 and\nbefore).\n\nYou must have the ALTER ROUTINE privilege for the procedure. By default, that\nprivilege is granted automatically to the procedure creator. See Stored\nRoutine Privileges.\n\nExample\n-------\n\nALTER PROCEDURE simpleproc SQL SECURITY INVOKER;\n\nURL: https://mariadb.com/kb/en/alter-procedure/','','https://mariadb.com/kb/en/alter-procedure/'),(686,'ALTER SERVER',38,'Syntax\n------\n\nALTER SERVER server_name\n  OPTIONS (option [, option] ...)\n\nDescription\n-----------\n\nAlters the server information for server_name, adjusting the specified options\nas per the CREATE SERVER command. The corresponding fields in the\nmysql.servers table are updated accordingly. This statement requires the SUPER\nprivilege or, from MariaDB 10.5.2, the FEDERATED ADMIN privilege.\n\nALTER SERVER is not written to the binary log, irrespective of the binary log\nformat being used. From MariaDB 10.1.13, Galera replicates the CREATE SERVER,\nALTER SERVER and DROP SERVER statements.\n\nExamples\n--------\n\nALTER SERVER s OPTIONS (USER \'sally\');\n\nURL: https://mariadb.com/kb/en/alter-server/','','https://mariadb.com/kb/en/alter-server/'),(687,'ALTER TABLESPACE',38,'The ALTER TABLESPACE statement is not supported by MariaDB. It was originally\ninherited from MySQL NDB Cluster. In MySQL 5.7 and later, the statement is\nalso supported for InnoDB. However, MariaDB has chosen not to include that\nspecific feature. See MDEV-19294 for more information.\n\nURL: https://mariadb.com/kb/en/alter-tablespace/','','https://mariadb.com/kb/en/alter-tablespace/'),(688,'ALTER VIEW',38,'Syntax\n------\n\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\nDescription\n-----------\n\nThis statement changes the definition of a view, which must exist. The syntax\nis similar to that for CREATE VIEW and the effect is the same as for CREATE OR\nREPLACE VIEW if the view exists. This statement requires the CREATE VIEW and\nDROP privileges for the view, and some privilege for each column referred to\nin the SELECT statement. ALTER VIEW is allowed only to the definer or users\nwith the SUPER privilege.\n\nExample\n-------\n\nALTER VIEW v AS SELECT a, a*3 AS a2 FROM t;\n\nURL: https://mariadb.com/kb/en/alter-view/','','https://mariadb.com/kb/en/alter-view/'),(689,'CREATE TABLE',38,'Syntax\n------\n\nCREATE [OR REPLACE] [TEMPORARY] TABLE [IF NOT EXISTS] tbl_name\n  (create_definition,...) [table_options    ]... [partition_options]\nCREATE [OR REPLACE] [TEMPORARY] TABLE [IF NOT EXISTS] tbl_name\n  [(create_definition,...)] [table_options   ]... [partition_options]\n  select_statement\nCREATE [OR REPLACE] [TEMPORARY] TABLE [IF NOT EXISTS] tbl_name\n { LIKE old_table_name | (LIKE old_table_name) }\nselect_statement:\n  [IGNORE | REPLACE] [AS] SELECT ...   (Some legal select statement)\n\nDescription\n-----------\n\nUse the CREATE TABLE statement to create a table with the given name.\n\nIn its most basic form, the CREATE TABLE statement provides a table name\nfollowed by a list of columns, indexes, and constraints. By default, the table\nis created in the default database. Specify a database with db_name.tbl_name.\nIf you quote the table name, you must quote the database name and table name\nseparately as `db_name`.`tbl_name`. This is particularly useful for CREATE\nTABLE ... SELECT, because it allows to create a table into a database, which\ncontains data from other databases. See Identifier Qualifiers.\n\nIf a table with the same name exists, error 1050 results. Use IF NOT EXISTS to\nsuppress this error and issue a note instead. Use SHOW WARNINGS to see notes.\n\nThe CREATE TABLE statement automatically commits the current transaction,\nexcept when using the TEMPORARY keyword.\n\nFor valid identifiers to use as table names, see Identifier Names.\n\nNote: if the default_storage_engine is set to ColumnStore then it needs\nsetting on all UMs. Otherwise when the tables using the default engine are\nreplicated across UMs they will use the wrong engine. You should therefore not\nuse this option as a session variable with ColumnStore.\n\nMicrosecond precision can be between 0-6. If no precision is specified it is\nassumed to be 0, for backward compatibility reasons.\n\nPrivileges\n----------\n\nExecuting the CREATE TABLE statement requires the CREATE privilege for the\ntable or the database.\n\nCREATE OR REPLACE\n-----------------\n\nIf the OR REPLACE clause is used and the table already exists, then instead of\nreturning an error, the server will drop the existing table and replace it\nwith the newly defined table.\n\nThis syntax was originally added to make replication more robust if it has to\nrollback and repeat statements such as CREATE ... SELECT on replicas.\n\nCREATE OR REPLACE TABLE table_name (a int);\n\nis basically the same as:\n\nDROP TABLE IF EXISTS table_name;\nCREATE TABLE table_name (a int);\n\nwith the following exceptions:\n\n* If table_name was locked with LOCK TABLES it will continue to be locked\nafter the statement.\n* Temporary tables are only dropped if the TEMPORARY keyword was used.  (With\nDROP TABLE,  temporary tables are preferred to be dropped before normal\ntables).\n\nThings to be Aware of With CREATE OR REPLACE\n--------------------------------------------\n\n* The table is dropped first (if it existed), after that the CREATE is done.\nBecause of this, if the CREATE fails, then the table will not exist anymore\nafter the statement.  If the table was used with LOCK TABLES it will be\nunlocked.\n* One can\'t use OR REPLACE together with IF EXISTS.\n* Slaves in replication will by default use CREATE OR REPLACE when replicating\nCREATE statements that don\'\'t use IF EXISTS. This can be changed by setting\nthe variable slave-ddl-exec-mode to STRICT.\n\nCREATE TABLE IF NOT EXISTS\n--------------------------\n\nIf the IF NOT EXISTS clause is used, then the table will only be created if a\ntable with the same name does not already exist. If the table already exists,\nthen a warning will be triggered by default.\n\nCREATE TEMPORARY TABLE\n----------------------\n\nUse the TEMPORARY keyword to create a temporary table that is only available\nto the current session. Temporary tables are dropped when the session ends.\nTemporary table names are specific to the session. They will not conflict with\nother temporary tables from other sessions even if they share the same name.\nThey will shadow names of non-temporary tables or views, if they are\nidentical. A temporary table can have the same name as a non-temporary table\nwhich is located in the same database. In that case, their name will reference\nthe temporary table when used in SQL statements. You must have the CREATE\nTEMPORARY TABLES privilege on the database to create temporary tables. If no\nstorage engine is specified, the default_tmp_storage_engine setting will\ndetermine the engine.\n\nROCKSDB temporary tables cannot be created by setting the\ndefault_tmp_storage_engine system variable, or using CREATE TEMPORARY TABLE\nLIKE. Before MariaDB 10.7, they could be specified, but would silently fail,\nand a MyISAM table would be created instead. From MariaDB 10.7 an error is\nreturned. Explicitly creating a temporary table with ENGINE=ROCKSDB has never\nbeen permitted.\n\nCREATE TABLE ... LIKE\n---------------------\n\nUse the LIKE clause instead of a full table definition to create a table with\nthe same definition as another table, including columns, indexes, and table\noptions. Foreign key definitions, as well as any DATA DIRECTORY or INDEX\nDIRECTORY table options specified on the original table, will not be created.\n\nCREATE TABLE ... SELECT\n-----------------------\n\nYou can create a table containing data from other tables using the CREATE ...\nSELECT statement. Columns will be created in the table for each field returned\nby the SELECT query.\n\nYou can also define some columns normally and add other columns from a SELECT.\nYou can also create columns in the normal way and assign them some values\nusing the query, this is done to force a certain type or other field\ncharacteristics. The columns that are not named in the query will be placed\nbefore the others. For example:\n\nCREATE TABLE test (a INT NOT NULL, b CHAR(10)) ENGINE=MyISAM\n  SELECT 5 AS b, c, d FROM another_table;\n\nRemember that the query just returns data. If you want to use the same\nindexes, or the same columns attributes ([NOT] NULL, DEFAULT, AUTO_INCREMENT)\nin the new table, you need to specify them manually. Types and sizes are not\nautomatically preserved if no data returned by the SELECT requires the full\nsize, and VARCHAR could be converted into CHAR. The CAST() function can be\nused to forcee the new table to use certain types.\n\nAliases (AS) are taken into account, and they should always be used when you\nSELECT an expression (function, arithmetical operation, etc).\n\nIf an error occurs during the query, the table will not be created at all.\n\nIf the new table has a primary key or UNIQUE indexes, you can use the IGNORE\nor REPLACE keywords to handle duplicate key errors during the query. IGNORE\nmeans that the newer values must not be inserted an identical value exists in\nthe index. REPLACE means that older values must be overwritten.\n\nIf the columns in the new table are more than the rows returned by the query,\nthe columns populated by the query will be placed after other columns. Note\nthat if the strict SQL_MODE is on, and the columns that are not names in the\nquery do not have a DEFAULT value, an error will raise and no rows will be\ncopied.\n\nConcurrent inserts are not used during the execution of a CREATE ... SELECT.\n\nIf the table already exists, an error similar to the following will be\nreturned:\n\nERROR 1050 (42S01): Table \'t\' already exists\n\nIf the IF NOT EXISTS clause is used and the table exists, a note will be\nproduced instead of an error.\n\nTo insert rows from a query into an existing table, INSERT ... SELECT can be\nused.\n\nColumn Definitions\n------------------\n\ncreate_definition:\n { col_name column_definition | index_definition | period_definition | CHECK\n(expr) }\ncolumn_definition:\n data_type\n  [NOT NULL | NULL] [DEFAULT default_value | (expression)]\n  [ON UPDATE [NOW | CURRENT_TIMESTAMP] [(precision)]]\n  [AUTO_INCREMENT] [ZEROFILL] [UNIQUE [KEY] | [PRIMARY] KEY]\n  [INVISIBLE] [{WITH|WITHOUT} SYSTEM VERSIONING]\n  [COMMENT \'string\'] [REF_SYSTEM_ID = value]\n  [reference_definition]\n | data_type [GENERATED ALWAYS]\n AS { { ROW {START|END} } | { (expression) [VIRTUAL | PERSISTENT | STORED] } }\n   [UNIQUE [KEY]] [COMMENT \'string\']\nconstraint_definition:\n CONSTRAINT [constraint_name] CHECK (expression)\nNote: Until MariaDB 10.4, MariaDB accepts the shortcut format with a\nREFERENCES clause only in ALTER TABLE and CREATE TABLE statements, but that\nsyntax does nothing. For example:\n\nCREATE TABLE b(for_key INT REFERENCES a(not_key));\n\nMariaDB simply parses it without returning any error or warning, for\ncompatibility with other DBMS\'s. Before MariaDB 10.2.1 this was also true for\nCHECK constraints. However, only the syntax described below creates foreign\nkeys.\n\nFrom MariaDB 10.5, MariaDB will attempt to apply the constraint. See Foreign\nKeys examples.\n\nEach definition either creates a column in the table or specifies and index or\nconstraint on one or more columns. See Indexes below for details on creating\nindexes.\n\nCreate a column by specifying a column name and a data type, optionally\nfollowed by column options. See Data Types for a full list of data types\nallowed in MariaDB.\n\nNULL and NOT NULL\n-----------------\n\nUse the NULL or NOT NULL options to specify that values in the column may or\nmay not be NULL, respectively. By default, values may be NULL. See also NULL\nValues in MariaDB.\n\nDEFAULT Column Option\n---------------------\n\nMariaDB starting with 10.2.1\n----------------------------\nThe DEFAULT clause was enhanced in MariaDB 10.2.1. Some enhancements include\n\n* BLOB and TEXT columns now support DEFAULT.\n* The DEFAULT clause can now be used with an expression or function.\n\nSpecify a default value using the DEFAULT clause. If you don\'t specify DEFAULT\nthen the following rules apply:\n\n* If the column is not defined with NOT NULL, AUTO_INCREMENT or TIMESTAMP, an\nexplicit DEFAULT NULL will be added.\nNote that in MySQL and in MariaDB before 10.1.6, you may get an explicit\nDEFAULT for primary key parts, if not specified with NOT NULL.\n\nThe default value will be used if you INSERT a row without specifying a value\nfor that column, or if you specify DEFAULT for that column. Before MariaDB\n10.2.1 you couldn\'t usually provide an expression or function to evaluate at\ninsertion time. You had to provide a constant default value instead. The one\nexception is that you may use CURRENT_TIMESTAMP as the default value for a\nTIMESTAMP column to use the current timestamp at insertion time.\n\nCURRENT_TIMESTAMP may also be used as the default value for a DATETIME\n\nFrom MariaDB 10.2.1 you can use most functions in DEFAULT. Expressions should\nhave parentheses around them. If you use a non deterministic function in\nDEFAULT then all inserts to the table will be replicated in row mode. You can\neven refer to earlier columns in the DEFAULT expression (excluding\nAUTO_INCREMENT columns):\n\nCREATE TABLE t1 (a int DEFAULT (1+1), b int DEFAULT (a+1));\nCREATE TABLE t2 (a bigint primary key DEFAULT UUID_SHORT());\n\nThe DEFAULT clause cannot contain any stored functions or subqueries, and a\ncolumn used in the clause must already have been defined earlier in the\nstatement.\n\nSince MariaDB 10.2.1, it is possible to assign BLOB or TEXT columns a DEFAULT\nvalue. In earlier versions, assigning a default to these columns was not\npossible.\n\nMariaDB starting with 10.3.3\n----------------------------\nStarting from 10.3.3 you can also use DEFAULT (NEXT VALUE FOR sequence)\n\nAUTO_INCREMENT Column Option\n----------------------------\n\nUse AUTO_INCREMENT to create a column whose value can can be set automatically\nfrom a simple counter. You can only use AUTO_INCREMENT on a column with an\ninteger type. The column must be a key, and there can only be one\nAUTO_INCREMENT column in a table. If you insert a row without specifying a\nvalue for that column (or if you specify 0, NULL, or DEFAULT as the value),\nthe actual value will be taken from the counter, with each insertion\nincrementing the counter by one. You can still insert a value explicitly. If\nyou insert a value that is greater than the current counter value, the counter\nis set based on the new value. An AUTO_INCREMENT column is implicitly NOT\nNULL. Use LAST_INSERT_ID to get the AUTO_INCREMENT value most recently used by\nan INSERT statement.\n\nZEROFILL Column Option\n----------------------\n\nIf the ZEROFILL column option is specified for a column using a numeric data\ntype, then the column will be set to UNSIGNED and the spaces used by default\nto pad the field are replaced with zeros. ZEROFILL is ignored in expressions\nor as part of a UNION. ZEROFILL is a non-standard MySQL and MariaDB\nenhancement.\n\nPRIMARY KEY Column Option\n-------------------------\n\nUse PRIMARY KEY to make a column a primary key. A primary key is a special\ntype of a unique key. There can be at most one primary key per table, and it\nis implicitly NOT NULL.\n\nSpecifying a column as a unique key creates a unique index on that column. See\nthe Index Definitions section below for more information.\n\nUNIQUE KEY Column Option\n------------------------\n\nUse UNIQUE KEY (or just UNIQUE) to specify that all values in the column must\nbe distinct from each other. Unless the column is NOT NULL, there may be\nmultiple rows with NULL in the column.\n\nSpecifying a column as a unique key creates a unique index on that column. See\nthe Index Definitions section below for more information.\n\nCOMMENT Column Option\n---------------------\n\nYou can provide a comment for each column using the COMMENT clause. The\nmaximum length is 1024 characters. Use the SHOW FULL COLUMNS statement to see\ncolumn comments.\n\nREF_SYSTEM_ID\n-------------\n\nREF_SYSTEM_ID can be used to specify Spatial Reference System IDs for spatial\ndata type columns. For example:\n\nCREATE TABLE t1(g GEOMETRY(9,4) REF_SYSTEM_ID=101);\n\nGenerated Columns\n-----------------\n\nA generated column is a column in a table that cannot explicitly be set to a\nspecific value in a DML query. Instead, its value is automatically generated\nbased on an expression. This expression might generate the value based on the\nvalues of other columns in the table, or it might generate the value by\ncalling built-in functions or user-defined functions (UDFs).\n\nThere are two types of generated columns:\n\n* PERSISTENT or STORED: This type\'s value is actually stored in the table.\n* VIRTUAL: This type\'s value is not stored at all. Instead, the value is\ngenerated dynamically when the table is queried. This type is the default.\n\nGenerated columns are also sometimes called computed columns or virtual\ncolumns.\n\nFor a complete description about generated columns and their limitations, see\nGenerated (Virtual and Persistent/Stored) Columns.\n\nCOMPRESSED\n----------\n\nMariaDB starting with 10.3.3\n----------------------------\nCertain columns may be compressed. See Storage-Engine Independent Column\nCompression.\n\nINVISIBLE\n---------\n\nMariaDB starting with 10.3.3\n----------------------------\nColumns may be made invisible, and hidden in certain contexts. See Invisible\nColumns.\n\nWITH SYSTEM VERSIONING Column Option\n------------------------------------\n\nMariaDB starting with 10.3.4\n----------------------------\nColumns may be explicitly marked as included from system versioning. See\nSystem-versioned tables for details.\n\nWITHOUT SYSTEM VERSIONING Column Option\n---------------------------------------\n\nMariaDB starting with 10.3.4\n----------------------------\nColumns may be explicitly marked as excluded from system versioning. See\nSystem-versioned tables for details.\n\nIndex Definitions\n-----------------\n\nindex_definition:\n  {INDEX|KEY} [index_name] [index_type] (index_col_name,...) [index_option]\n...\n {{{|}}} {FULLTEXT|SPATIAL} [INDEX|KEY] [index_name] (index_col_name,...)\n[index_option] ...\n {{{|}}} [CONSTRAINT [symbol]] PRIMARY KEY [index_type] (index_col_name,...)\n[index_option] ...\n {{{|}}} [CONSTRAINT [symbol]] UNIQUE [INDEX|KEY] [index_name] [index_type]\n(index_col_name,...) [index_option] ...\n {{{|}}} [CONSTRAINT [symbol]] FOREIGN KEY [index_name] (index_col_name,...)\nreference_definition\n\nindex_col_name:\n  col_name [(length)] [ASC | DESC]\n\nindex_type:\n  USING {BTREE | HASH | RTREE}\n\nindex_option:\n  [ KEY_BLOCK_SIZE [=] value\n {{{|}}} index_type\n {{{|}}} WITH PARSER parser_name\n {{{|}}} COMMENT \'string\'\n {{{|}}} CLUSTERING={YES| NO} ]\n [ IGNORED | NOT IGNORED ]\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\nINDEX and KEY are synonyms.\n\nIndex names are optional, if not specified an automatic name will be assigned.\nIndex name are needed to drop indexes and appear in error messages when a\nconstraint is violated.\n\nIndex Categories\n----------------\n\nPlain Indexes\n-------------\n\nPlain indexes are regular indexes that are not unique, and are not acting as a\nprimary key or a foreign key. They are also not the \"specialized\" FULLTEXT or\nSPATIAL indexes.\n\nSee Getting Started with Indexes: Plain Indexes for more information.\n\nPRIMARY KEY\n-----------\n\nFor PRIMARY KEY indexes, you can specify a name for the index, but it is\nignored, and the name of the index is always PRIMARY. From MariaDB 10.3.18 and\nMariaDB 10.4.8, a warning is explicitly issued if a name is specified. Before\nthen, the name was silently ignored.\n\nSee Getting Started with Indexes: Primary Key for more information.\n\nUNIQUE\n------\n\nThe UNIQUE keyword means that the index will not accept duplicated values,\nexcept for NULLs. An error will raise if you try to insert duplicate values in\na UNIQUE index.\n\nFor UNIQUE indexes, you can specify a name for the constraint, using the\nCONSTRAINT keyword. That name will be used in error messages.\n\nSee Getting Started with Indexes: Unique Index for more information.\n\nFOREIGN KEY\n-----------\n\nFor FOREIGN KEY indexes, a reference definition must be provided.\n\nFor FOREIGN KEY indexes, you can specify a name for the constraint, using the\nCONSTRAINT keyword. That name will be used in error messages.\n\nFirst, you have to specify the name of the target (parent) table and a column\nor a column list which must be indexed and whose values must match to the\nforeign key\'s values. The MATCH clause is accepted to improve the\ncompatibility with other DBMS\'s, but has no meaning in MariaDB. The ON DELETE\nand ON UPDATE clauses specify what must be done when a DELETE (or a REPLACE)\nstatements attempts to delete a referenced row from the parent table, and when\nan UPDATE statement attempts to modify the referenced foreign key columns in a\nparent table row, respectively. The following options are allowed:\n\n* RESTRICT: The delete/update operation is not performed.  The statement\nterminates with a 1451 error (SQLSTATE \'2300\').\n* NO ACTION: Synonym for RESTRICT.\n* CASCADE: The delete/update operation is performed in both tables.\n* SET NULL: The update or delete goes ahead in the parent table, and the\ncorresponding foreign key fields in the child table are set to NULL.  (They\nmust not be defined as NOT NULL for this to succeed).\n* SET DEFAULT: This option is currently implemented only for the PBXT storage\nengine, which is disabled by default and no longer maintained. It sets the\nchild table\'s foreign key fields to their DEFAULT values when the referenced\nparent table key entries are updated or deleted.\n\nIf either clause is omitted, the default behavior for the omitted clause is\nRESTRICT.\n\nSee Foreign Keys for more information.\n\nFULLTEXT\n--------\n\nUse the FULLTEXT keyword to create full-text indexes.\n\nSee Full-Text Indexes for more information.\n\nSPATIAL\n-------\n\nUse the SPATIAL keyword to create geometric indexes.\n\nSee SPATIAL INDEX for more information.\n\nIndex Options\n-------------\n\nKEY_BLOCK_SIZE Index Option\n---------------------------\n\nThe KEY_BLOCK_SIZE index option is similar to the KEY_BLOCK_SIZE table option.\n\nWith the InnoDB storage engine, if you specify a non-zero value for the\nKEY_BLOCK_SIZE table option for the whole table, then the table will\nimplicitly be created with the ROW_FORMAT table option set to COMPRESSED.\nHowever, this does not happen if you just set the KEY_BLOCK_SIZE index option\nfor one or more indexes in the table. The InnoDB storage engine ignores the\nKEY_BLOCK_SIZE index option. However, the SHOW CREATE TABLE statement may\nstill report it for the index.\n\nFor information about the KEY_BLOCK_SIZE index option, see the KEY_BLOCK_SIZE\ntable option below.\n\nIndex Types\n-----------\n\nEach storage engine supports some or all index types. See Storage Engine Index\nTypes for details on permitted index types for each storage engine.\n\nDifferent index types are optimized for different kind of operations:\n\n* BTREE is the default type, and normally is the best choice. It is supported\nby all storage engines. It can be used to compare a column\'s value with a\nvalue using the =, >, >=, <, <=, BETWEEN, and LIKE operators. BTREE can also\nbe used to find NULL values. Searches against an index prefix are possible.\n* HASH is only supported by the MEMORY storage engine. HASH indexes can only\nbe used for =, <=, and >= comparisons. It can not be used for the ORDER BY\nclause. Searches against an index prefix are not possible.\n* RTREE is the default for SPATIAL indexes, but if the storage engine does not\nsupport it BTREE can be used.\n\nIndex columns names are listed between parenthesis. After each column, a\nprefix length can be specified. If no length is specified, the whole column\nwill be indexed. ASC and DESC can be specified for compatibility with are\nDBMS\'s, but have no meaning in MariaDB.\n\nWITH PARSER Index Option\n------------------------\n\nThe WITH PARSER index option only applies to FULLTEXT indexes and contains the\nfulltext parser name. The fulltext parser must be an installed plugin.\n\nCOMMENT Index Option\n--------------------\n\nA comment of up to 1024 characters is permitted with the COMMENT index option.\n\nThe COMMENT index option allows you to specify a comment with user-readable\ntext describing what the index is for. This information is not used by the\nserver itself.\n\nCLUSTERING Index Option\n-----------------------\n\nThe CLUSTERING index option is only valid for tables using the TokuDB storage\nengine.\n\nIGNORED / NOT IGNORED\n---------------------\n\nMariaDB starting with 10.6.0\n----------------------------\nFrom MariaDB 10.6.0, indexes can be specified to be ignored by the optimizer.\nSee Ignored Indexes.\n\nPeriods\n-------\n\nMariaDB starting with 10.3.4\n----------------------------\n\nperiod_definition:\n  PERIOD FOR SYSTEM_TIME (start_column_name, end_column_name)\nMariaDB supports a subset of the standard syntax for periods. At the moment\nit\'s only used for creating System-versioned tables. Both columns must be\ncreated, must be either of a TIMESTAMP(6) or BIGINT UNSIGNED type, and be\ngenerated as ROW START and ROW END accordingly. See System-versioned tables\nfor details.\n\nThe table must also have the WITH SYSTEM VERSIONING clause.\n\nConstraint Expressions\n----------------------\n\nMariaDB starting with 10.2.1\n----------------------------\nMariaDB 10.2.1 introduced new ways to define a constraint.\n\nNote: Before MariaDB 10.2.1, constraint expressions were accepted in the\nsyntax but ignored.\n\nMariaDB 10.2.1 introduced two ways to define a constraint:\n\n* CHECK(expression) given as part of a column definition.\n* CONSTRAINT [constraint_name] CHECK (expression)\n\nBefore a row is inserted or updated, all constraints are evaluated in the\norder they are defined. If any constraints fails, then the row will not be\nupdated. One can use most deterministic functions in a constraint, including\nUDFs.\n\ncreate table t1 (a int check(a>0) ,b int check (b> 0), constraint abc check\n(a>b));\n\nIf you use the second format and you don\'t give a name to the constraint, then\nthe constraint will get a auto generated name. This is done so that you can\nlater delete the constraint with ALTER TABLE DROP constraint_name.\n\nOne can disable all constraint expression checks by setting the variable\ncheck_constraint_checks to OFF. This is useful for example when loading a\ntable that violates some constraints that you want to later find and fix in\nSQL.\n\nSee CONSTRAINT for more information.\n\nTable Options\n-------------\n\nFor each individual table you create (or alter), you can set some table\noptions. The general syntax for setting options is:\n\n<OPTION_NAME> = <option_value>, [<OPTION_NAME> = <option_value> ...]\n\nThe equal sign is optional.\n\nSome options are supported by the server and can be used for all tables, no\nmatter what storage engine they use; other options can be specified for all\nstorage engines, but have a meaning only for some engines. Also, engines can\nextend CREATE TABLE with new options.\n\nIf the IGNORE_BAD_TABLE_OPTIONS SQL_MODE is enabled, wrong table options\ngenerate a warning; otherwise, they generate an error.\n\ntable_option:    \n  [STORAGE] 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 | ENCRYPTED [=] {YES | NO}\n | ENCRYPTION_KEY_ID [=] value\n | IETF_QUOTES [=] {YES | NO}\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 | PAGE_CHECKSUM [=] {0 | 1}\n | PAGE_COMPRESSED [=] {0 | 1}\n | PAGE_COMPRESSION_LEVEL [=] {0 .. 9}\n | PASSWORD [=] \'string\'\n | ROW_FORMAT [=] {DEFAULT|DYNAMIC|FIXED|COMPRESSED|REDUNDANT|COMPACT|PAGE}\n | SEQUENCE [=] {0|1}\n | STATS_AUTO_RECALC [=] {DEFAULT|0|1}\n | STATS_PERSISTENT [=] {DEFAULT|0|1}\n | STATS_SAMPLE_PAGES [=] {DEFAULT|value}\n | TABLESPACE tablespace_name\n | TRANSACTIONAL [=]  {0 | 1}\n | UNION [=] (tbl_name[,tbl_name]...)\n | WITH SYSTEM VERSIONING\n\n[STORAGE] ENGINE\n----------------\n\n[STORAGE] ENGINE specifies a storage engine for the table. If this option is\nnot used, the default storage engine is used instead. That is, the\ndefault_storage_engine session option value if it is set, or the value\nspecified for the --default-storage-engine mysqld startup option, or the\ndefault storage engine, InnoDB. If the specified storage engine is not\ninstalled and active, the default value will be used, unless the\nNO_ENGINE_SUBSTITUTION SQL MODE is set (default). This is only true for CREATE\nTABLE, not for ALTER TABLE. For a list of storage engines that are present in\nyour server, issue a SHOW ENGINES.\n\nAUTO_INCREMENT\n--------------\n\nAUTO_INCREMENT specifies the initial value for the AUTO_INCREMENT primary key.\nThis works for MyISAM, Aria, InnoDB, MEMORY, and ARCHIVE tables. You can\nchange this option with ALTER TABLE, but in that case the new value must be\nhigher than the highest value which is present in the AUTO_INCREMENT column.\nIf the storage engine does not support this option, you can insert (and then\ndelete) a row having the wanted value - 1 in the AUTO_INCREMENT column.\n\nAVG_ROW_LENGTH\n--------------\n\nAVG_ROW_LENGTH is the average rows size. It only applies to tables using\nMyISAM and Aria storage engines that have the ROW_FORMAT table option set to\nFIXED format.\n\nMyISAM uses MAX_ROWS and AVG_ROW_LENGTH to decide the maximum size of a table\n(default: 256TB, or the maximum file size allowed by the system).\n\n[DEFAULT] CHARACTER SET/CHARSET\n-------------------------------\n\n[DEFAULT] CHARACTER SET (or [DEFAULT] CHARSET) is used to set a default\ncharacter set for the table. This is the character set used for all columns\nwhere an explicit character set is not specified. If this option is omitted or\nDEFAULT is specified, database\'s default character set will be used. See\nSetting Character Sets and Collations for details on setting the character\nsets.\n\nCHECKSUM/TABLE_CHECKSUM\n-----------------------\n\nCHECKSUM (or TABLE_CHECKSUM) can be set to 1 to maintain a live checksum for\nall table\'s rows. This makes write operations slower, but CHECKSUM TABLE will\nbe very fast. This option is only supported for MyISAM and Aria tables.\n\n[DEFAULT] COLLATE\n-----------------\n\n[DEFAULT] COLLATE is used to set a default collation for the table. This is\nthe collation used for all columns where an explicit character set is not\nspecified. If this option is omitted or DEFAULT is specified, database\'s\ndefault option will be used. See Setting Character Sets and Collations for\ndetails on setting the collations\n\nCOMMENT\n-------\n\nCOMMENT is a comment for the table. The maximum length is 2048 characters.\nAlso used to define table parameters when creating a Spider table.\n\nCONNECTION\n----------\n\nCONNECTION is used to specify a server name or a connection string for a\nSpider, CONNECT, Federated or FederatedX table.\n\nDATA DIRECTORY/INDEX DIRECTORY\n------------------------------\n\nDATA DIRECTORY and INDEX DIRECTORY are supported for MyISAM and Aria, and DATA\nDIRECTORY is also supported by InnoDB if the innodb_file_per_table server\nsystem variable is enabled, but only in CREATE TABLE, not in ALTER TABLE. So,\ncarefully choose a path for InnoDB tables at creation time, because it cannot\nbe changed without dropping and re-creating the table. These options specify\nthe paths for data files and index files, respectively. If these options are\nomitted, the database\'s directory will be used to store data files and index\nfiles. Note that these table options do not work for partitioned tables (use\nthe partition options instead), or if the server has been invoked with the\n--skip-symbolic-links startup option. To avoid the overwriting of old files\nwith the same name that could be present in the directories, you can use the\n--keep_files_on_create option (an error will be issued if files already\nexist). These options are ignored if the NO_DIR_IN_CREATE SQL_MODE is enabled\n(useful for replication slaves). Also note that symbolic links cannot be used\nfor InnoDB tables.\n\nDATA DIRECTORY works by creating symlinks from where the table would normally\nhave been (inside the datadir) to where the option specifies. For security\nreasons, to avoid bypassing the privilege system, the server does not permit\nsymlinks inside the datadir. Therefore, DATA DIRECTORY cannot be used to\nspecify a location inside the datadir. An attempt to do so will result in an\nerror 1210 (HY000) Incorrect arguments to DATA DIRECTORY.\n\nDELAY_KEY_WRITE\n---------------\n\nDELAY_KEY_WRITE is supported by MyISAM and Aria, and can be set to 1 to speed\nup write operations. In that case, when data are modified, the indexes are not\nupdated until the table is closed. Writing the changes to the index file\naltogether can be much faster. However, note that this option is applied only\nif the delay_key_write server variable is set to \'ON\'. If it is \'OFF\' the\ndelayed index writes are always disabled, and if it is \'ALL\' the delayed index\nwrites are always used, disregarding the value of DELAY_KEY_WRITE.\n\nENCRYPTED\n---------\n\nThe ENCRYPTED table option can be used to manually set the encryption status\nof an InnoDB table. See InnoDB Encryption for more information.\n\nAria does not support the ENCRYPTED table option. See MDEV-18049.\n\nSee Data-at-Rest Encryption for more information.\n\nENCRYPTION_KEY_ID\n-----------------\n\nThe ENCRYPTION_KEY_ID table option can be used to manually set the encryption\nkey of an InnoDB table. See InnoDB Encryption for more information.\n\nAria does not support the ENCRYPTION_KEY_ID table option. See MDEV-18049.\n\nSee Data-at-Rest Encryption for more information.\n\nIETF_QUOTES\n-----------\n\nFor the CSV storage engine, the IETF_QUOTES option, when set to YES, enables\nIETF-compatible parsing of embedded quote and comma characters. Enabling this\noption for a table improves compatibility with other tools that use CSV, but\nis not compatible with MySQL CSV tables, or MariaDB CSV tables created without\nthis option. Disabled by default.\n\nINSERT_METHOD\n-------------\n\nINSERT_METHOD is only used with MERGE tables. This option determines in which\nunderlying table the new rows should be inserted. If you set it to \'NO\' (which\nis the default) no new rows can be added to the table (but you will still be\nable to perform INSERTs directly against the underlying tables). FIRST means\nthat the rows are inserted into the first table, and LAST means that thet are\ninserted into the last table.\n\nKEY_BLOCK_SIZE\n--------------\n\nKEY_BLOCK_SIZE is used to determine the size of key blocks, in bytes or\nkilobytes. However, this value is just a hint, and the storage engine could\nmodify or ignore it. If KEY_BLOCK_SIZE is set to 0, the storage engine\'s\ndefault value will be used.\n\nWith the InnoDB storage engine, if you specify a non-zero value for the\nKEY_BLOCK_SIZE table option for the whole table, then the table will\nimplicitly be created with the ROW_FORMAT table option set to COMPRESSED.\n\nMIN_ROWS/MAX_ROWS\n-----------------\n\nMIN_ROWS and MAX_ROWS let the storage engine know how many rows you are\nplanning to store as a minimum and as a maximum. These values will not be used\nas real limits, but they help the storage engine to optimize the table.\nMIN_ROWS is only used by MEMORY storage engine to decide the minimum memory\nthat is always allocated. MAX_ROWS is used to decide the minimum size for\nindexes.\n\nPACK_KEYS\n---------\n\nPACK_KEYS can be used to determine whether the indexes will be compressed. Set\nit to 1 to compress all keys. With a value of 0, compression will not be used.\nWith the DEFAULT value, only long strings will be compressed. Uncompressed\nkeys are faster.\n\nPAGE_CHECKSUM\n-------------\n\nPAGE_CHECKSUM is only applicable to Aria tables, and determines whether\nindexes and data should use page checksums for extra safety.\n\nPAGE_COMPRESSED\n---------------\n\nPAGE_COMPRESSED is used to enable InnoDB page compression for InnoDB tables.\n\nPAGE_COMPRESSION_LEVEL\n----------------------\n\nPAGE_COMPRESSION_LEVEL is used to set the compression level for InnoDB page\ncompression for InnoDB tables. The table must also have the PAGE_COMPRESSED\ntable option set to 1.\n\nValid values for PAGE_COMPRESSION_LEVEL are 1 (the best speed) through 9 (the\nbest compression), .\n\nPASSWORD\n--------\n\nPASSWORD is unused.\n\nRAID_TYPE\n---------\n\nRAID_TYPE is an obsolete option, as the raid support has been disabled since\nMySQL 5.0.\n\nROW_FORMAT\n----------\n\nThe ROW_FORMAT table option specifies the row format for the data file.\nPossible values are engine-dependent.\n\nSupported MyISAM Row Formats\n----------------------------\n\nFor MyISAM, the supported row formats are:\n\n* FIXED\n* DYNAMIC\n* COMPRESSED\n\nThe COMPRESSED row format can only be set by the myisampack command line tool.\n\nSee MyISAM Storage Formats for more information.\n\nSupported Aria Row Formats\n--------------------------\n\nFor Aria, the supported row formats are:\n\n* PAGE\n* FIXED\n* DYNAMIC.\n\nSee Aria Storage Formats for more information.\n\nSupported InnoDB Row Formats\n----------------------------\n\nFor InnoDB, the supported row formats are:\n\n* COMPACT\n* REDUNDANT\n* COMPRESSED\n* DYNAMIC.\n\nIf the ROW_FORMAT table option is set to FIXED for an InnoDB table, then the\nserver will either return an error or a warning depending on the value of the\ninnodb_strict_mode system variable. If the innodb_strict_mode system variable\nis set to OFF, then a warning is issued, and MariaDB will create the table\nusing the default row format for the specific MariaDB server version. If the\ninnodb_strict_mode system variable is set to ON, then an error will be raised.\n\nSee InnoDB Storage Formats for more information.\n\nOther Storage Engines and ROW_FORMAT\n------------------------------------\n\nOther storage engines do not support the ROW_FORMAT table option.\n\nSEQUENCE\n--------\n\nMariaDB starting with 10.3\n--------------------------\nIf the table is a sequence, then it will have the SEQUENCE set to 1.\n\nSTATS_AUTO_RECALC\n-----------------\n\nSTATS_AUTO_RECALC indicates whether to automatically recalculate persistent\nstatistics (see STATS_PERSISTENT, below) for an InnoDB table. If set to 1,\nstatistics will be recalculated when more than 10% of the data has changed.\nWhen set to 0, stats will be recalculated only when an ANALYZE TABLE is run.\nIf set to DEFAULT, or left out, the value set by the innodb_stats_auto_recalc\nsystem variable applies. See InnoDB Persistent Statistics.\n\nSTATS_PERSISTENT\n----------------\n\nSTATS_PERSISTENT indicates whether the InnoDB statistics created by ANALYZE\nTABLE will remain on disk or not. It can be set to 1 (on disk), 0 (not on\ndisk, the pre-MariaDB 10 behavior), or DEFAULT (the same as leaving out the\noption), in which case the value set by the innodb_stats_persistent system\nvariable will apply. Persistent statistics stored on disk allow the statistics\nto survive server restarts, and provide better query plan stability. See\nInnoDB Persistent Statistics.\n\nSTATS_SAMPLE_PAGES\n------------------\n\nSTATS_SAMPLE_PAGES indicates how many pages are used to sample index\nstatistics. If 0 or DEFAULT, the default value, the innodb_stats_sample_pages\nvalue is used. See InnoDB Persistent Statistics.\n\nTRANSACTIONAL\n-------------\n\nTRANSACTIONAL is only applicable for Aria tables. In future Aria tables\ncreated with this option will be fully transactional, but currently this\nprovides a form of crash protection. See Aria Storage Engine for more details.\n\nUNION\n-----\n\nUNION must be specified when you create a MERGE table. This option contains a\ncomma-separated list of MyISAM tables which are accessed by the new table. The\nlist is enclosed between parenthesis. Example: UNION = (t1,t2)\n\nWITH SYSTEM VERSIONING\n----------------------\n\nWITH SYSTEM VERSIONING is used for creating System-versioned tables.\n\nPartitions\n----------\n\npartition_options:\n  PARTITION BY\n    { [LINEAR] HASH(expr)\n    | [LINEAR] KEY(column_list)\n    | RANGE(expr)\n    | LIST(expr)\n    | SYSTEM_TIME [INTERVAL time_quantity time_unit] [LIMIT num] }\n  [PARTITIONS num]\n  [SUBPARTITION BY\n    { [LINEAR] HASH(expr)\n    | [LINEAR] KEY(column_list) }\n   [SUBPARTITIONS num]\n  ]\n  [(partition_definition [, partition_definition] ...)]\npartition_definition:\n  PARTITION partition_name\n    [VALUES {LESS THAN {(expr) | MAXVALUE} | 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] ...)]\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]\nIf the PARTITION BY clause is used, the table will be partitioned. A partition\nmethod must be explicitly indicated for partitions and subpartitions.\nPartition methods are:\n\n* [LINEAR] HASH creates a hash key which will be used to read and write rows.\nThe partition function can be any valid SQL expression which returns an\nINTEGER number. Thus, it is possible to use the HASH method on an integer\ncolumn, or on functions which accept integer columns as an argument. However,\nVALUES LESS THAN and VALUES IN clauses can not be used with HASH. An example:\n\nCREATE TABLE t1 (a INT, b CHAR(5), c DATETIME)\n  PARTITION BY HASH ( YEAR(c) );\n\n[LINEAR] HASH can be used for subpartitions, too.\n\n* [LINEAR] KEY is similar to HASH, but the index has an even distribution of\ndata. Also, the expression can only be a column or a list of columns. VALUES\nLESS THAN and VALUES IN clauses can not be used with KEY.\n* RANGE partitions the rows using on a range of values, using the VALUES LESS\nTHAN operator. VALUES IN is not allowed with RANGE. The partition function can\nbe any valid SQL expression which returns a single value.\n* LIST assigns partitions based on a table\'s column with a restricted set of\npossible values. It is similar to RANGE, but VALUES IN must be used for at\nleast 1 columns, and VALUES LESS THAN is disallowed.\n* SYSTEM_TIME partitioning is used for System-versioned tables to store\nhistorical data separately from current data.\n\nOnly HASH and KEY can be used for subpartitions, and they can be [LINEAR].\n\nIt is possible to define up to 1024 partitions and subpartitions.\n\nThe number of defined partitions can be optionally specified as PARTITION\ncount. This can be done to avoid specifying all partitions individually. But\nyou can also declare each individual partition and, additionally, specify a\nPARTITIONS count clause; in the case, the number of PARTITIONs must equal\ncount.\n\nAlso see Partitioning Types Overview.\n\nSequences\n---------\n\nMariaDB starting with 10.3\n--------------------------\nCREATE TABLE can also be used to create a SEQUENCE. See CREATE SEQUENCE and\nSequence Overview.\n\nAtomic DDL\n----------\n\nMariaDB starting with 10.6.1\n----------------------------\nMariaDB 10.6.1 supports Atomic DDL. CREATE TABLE is atomic, except for CREATE\nOR REPLACE, which is only crash safe.\n\nExamples\n--------\n\ncreate table if not exists test (\na bigint auto_increment primary key,\nname varchar(128) charset utf8,\nkey name (name(32))\n) engine=InnoDB default charset latin1;\n\nThis example shows a couple of things:\n\n* Usage of IF NOT EXISTS; If the table already existed, it will not be\ncreated.  There will not be any error for the client, just a warning.\n* How to create a PRIMARY KEY that is automatically generated.\n* How to specify a table-specific character set and another for a column.\n* How to create an index (name) that is only partly indexed (to save space).\n\nThe following clauses will work from MariaDB 10.2.1 only.\n\nCREATE TABLE t1(\n a int DEFAULT (1+1),\n b int DEFAULT (a+1),\n expires DATETIME DEFAULT(NOW() + INTERVAL 1 YEAR),\n x BLOB DEFAULT USER()\n);\n\nURL: https://mariadb.com/kb/en/create-table/','','https://mariadb.com/kb/en/create-table/'),(690,'DROP TABLE',38,'Syntax\n------\n\nDROP [TEMPORARY] TABLE [IF EXISTS] [/*COMMENT TO SAVE*/]\n  tbl_name [, tbl_name] ...\n  [WAIT n|NOWAIT]\n  [RESTRICT | CASCADE]\n\nDescription\n-----------\n\nDROP TABLE removes one or more tables. You must have the DROP privilege for\neach table. All table data and the table definition are removed, as well as\ntriggers associated to the table, so be careful with this statement! If any of\nthe tables named in the argument list do not exist, MariaDB returns an error\nindicating by name which non-existing tables it was unable to drop, but it\nalso drops all of the tables in the list that do exist.\n\nImportant: When a table is dropped, user privileges on the table are not\nautomatically dropped. See GRANT.\n\nIf another thread is using the table in an explicit transaction or an\nautocommit transaction, then the thread acquires a metadata lock (MDL) on the\ntable. The DROP TABLE statement will wait in the \"Waiting for table metadata\nlock\" thread state until the MDL is released. MDLs are released in the\nfollowing cases:\n\n* If an MDL is acquired in an explicit transaction, then the MDL will be\nreleased when the transaction ends.\n* If an MDL is acquired in an autocommit transaction, then the MDL will be\nreleased when the statement ends.\n* Transactional and non-transactional tables are handled the same.\n\nNote that for a partitioned table, DROP TABLE permanently removes the table\ndefinition, all of its partitions, and all of the data which was stored in\nthose partitions. It also removes the partitioning definition (.par) file\nassociated with the dropped table.\n\nFor each referenced table, DROP TABLE drops a temporary table with that name,\nif it exists. If it does not exist, and the TEMPORARY keyword is not used, it\ndrops a non-temporary table with the same name, if it exists. The TEMPORARY\nkeyword ensures that a non-temporary table will not accidentally be dropped.\n\nUse IF EXISTS to prevent an error from occurring for tables that do not exist.\nA NOTE is generated for each non-existent table when using IF EXISTS. See SHOW\nWARNINGS.\n\nIf a foreign key references this table, the table cannot be dropped. In this\ncase, it is necessary to drop the foreign key first.\n\nRESTRICT and CASCADE are allowed to make porting from other database systems\neasier. In MariaDB, they do nothing.\n\nThe comment before the table names (/*COMMENT TO SAVE*/) is stored in the\nbinary log. That feature can be used by replication tools to send their\ninternal messages.\n\nIt is possible to specify table names as db_name.tab_name. This is useful to\ndelete tables from multiple databases with one statement. See Identifier\nQualifiers for details.\n\nThe DROP privilege is required to use DROP TABLE on non-temporary tables. For\ntemporary tables, no privilege is required, because such tables are only\nvisible for the current session.\n\nNote: DROP TABLE automatically commits the current active transaction, unless\nyou use the TEMPORARY keyword.\n\nMariaDB starting with 10.5.4\n----------------------------\nFrom MariaDB 10.5.4, DROP TABLE reliably deletes table remnants inside a\nstorage engine even if the .frm file is missing. Before then, a missing .frm\nfile would result in the statement failing.\n\nMariaDB starting with 10.3.1\n----------------------------\n\nWAIT/NOWAIT\n-----------\n\nSet the lock wait timeout. See WAIT and NOWAIT.\n\nDROP TABLE in replication\n-------------------------\n\nDROP TABLE has the following characteristics in replication:\n\n* DROP TABLE IF EXISTS are always logged.\n* DROP TABLE without IF EXISTS for tables that don\'t exist are not written to\nthe binary log.\n* Dropping of TEMPORARY tables are prefixed in the log with TEMPORARY. These\ndrops are only logged when running statement or mixed mode replication.\n* One DROP TABLE statement can be logged with up to 3 different DROP\nstatements:\nDROP TEMPORARY TABLE list_of_non_transactional_temporary_tables\nDROP TEMPORARY TABLE list_of_transactional_temporary_tables\nDROP TABLE list_of_normal_tables\n\nDROP TABLE on the primary is treated on the replica as DROP TABLE IF EXISTS.\nYou can change that by setting slave-ddl-exec-mode to STRICT.\n\nDropping an Internal #sql-... Table\n-----------------------------------\n\nFrom MariaDB 10.6, DROP TABLE is atomic and the following does not apply.\nUntil MariaDB 10.5, if the mariadbd/mysqld process is killed during an ALTER\nTABLE you may find a table named #sql-... in your data directory. In MariaDB\n10.3, InnoDB tables with this prefix will be deleted automatically during\nstartup. From MariaDB 10.4, these temporary tables will always be deleted\nautomatically.\n\nIf you want to delete one of these tables explicitly you can do so by using\nthe following syntax:\n\nDROP TABLE `#mysql50##sql-...`;\n\nWhen running an ALTER TABLE…ALGORITHM=INPLACE that rebuilds the table, InnoDB\nwill create an internal #sql-ib table. Until MariaDB 10.3.2, for these tables,\nthe .frm file will be called something else. In order to drop such a table\nafter a server crash, you must rename the #sql*.frm file to match the\n#sql-ib*.ibd file.\n\nFrom MariaDB 10.3.3, the same name as the .frm file is used for the\nintermediate copy of the table. The #sql-ib names are used by TRUNCATE and\ndelayed DROP.\n\nFrom MariaDB 10.2.19 and MariaDB 10.3.10, the #sql-ib tables will be deleted\nautomatically.\n\nDropping All Tables in a Database\n---------------------------------\n\nThe best way to drop all tables in a database is by executing DROP DATABASE,\nwhich will drop the database itself, and all tables in it.\n\nHowever, if you want to drop all tables in the database, but you also want to\nkeep the database itself and any other non-table objects in it, then you would\nneed to execute DROP TABLE to drop each individual table. You can construct\nthese DROP TABLE commands by querying the TABLES table in the\ninformation_schema database. For example:\n\nSELECT CONCAT(\'DROP TABLE IF EXISTS `\', TABLE_SCHEMA, \'`.`\', TABLE_NAME, \'`;\')\nFROM information_schema.TABLES\nWHERE TABLE_SCHEMA = \'mydb\';\n\nAtomic DROP TABLE\n-----------------\n\nMariaDB starting with 10.6.1\n----------------------------\nFrom MariaDB 10.6, DROP TABLE for a single table is atomic (MDEV-25180) for\nmost engines, including InnoDB, MyRocks, MyISAM and Aria.\n\nThis means that if there is a crash (server down or power outage) during DROP\nTABLE, all tables that have been processed so far will be completely dropped,\nincluding related trigger files and status entries, and the binary log will\ninclude a DROP TABLE statement for the dropped tables. Tables for which the\ndrop had not started will be left intact.\n\nIn older MariaDB versions, there was a small chance that, during a server\ncrash happening in the middle of DROP TABLE, some storage engines that were\nusing multiple storage files, like MyISAM, could have only a part of its\ninternal files dropped.\n\nIn MariaDB 10.5, DROP TABLE was extended to be able to delete a table that was\nonly partly dropped (MDEV-11412) as explained above. Atomic DROP TABLE is the\nfinal piece to make DROP TABLE fully reliable.\n\nDropping multiple tables is crash-safe.\n\nSee Atomic DDL for more information.\n\nExamples\n--------\n\nDROP TABLE Employees, Customers;\n\nNotes\n-----\n\nBeware that DROP TABLE can drop both tables and sequences. This is mainly done\nto allow old tools like mysqldump to work with sequences.\n\nURL: https://mariadb.com/kb/en/drop-table/','','https://mariadb.com/kb/en/drop-table/'),(691,'RENAME TABLE',38,'Syntax\n------\n\nRENAME TABLE[S] [IF EXISTS] tbl_name \n [WAIT n | NOWAIT]\n TO new_tbl_name\n  [, tbl_name2 TO new_tbl_name2] ...\n\nDescription\n-----------\n\nThis statement renames one or more tables or views, but not the privileges\nassociated with them.\n\nIF EXISTS\n---------\n\nMariaDB starting with 10.5.2\n----------------------------\nIf this directive is used, one will not get an error if the table to be\nrenamed doesn\'t exist.\n\nThe rename operation is done atomically, which means that no other session can\naccess any of the tables while the rename is running. For example, if you have\nan existing table old_table, you can create another table new_table that has\nthe same structure but is empty, and then replace the existing table with the\nempty one as follows (assuming that backup_table does not already exist):\n\nCREATE TABLE new_table (...);\nRENAME TABLE old_table TO backup_table, new_table TO old_table;\n\ntbl_name can optionally be specified as db_name.tbl_name. See Identifier\nQualifiers. This allows to use RENAME to move a table from a database to\nanother (as long as they are on the same filesystem):\n\nRENAME TABLE db1.t TO db2.t;\n\nNote that moving a table to another database is not possible if it has some\ntriggers. Trying to do so produces the following error:\n\nERROR 1435 (HY000): Trigger in wrong schema\n\nAlso, views cannot be moved to another database:\n\nERROR 1450 (HY000): Changing schema from \'old_db\' to \'new_db\' is not allowed.\n\nMultiple tables can be renamed in a single statement. The presence or absence\nof the optional S (RENAME TABLE or RENAME TABLES) has no impact, whether a\nsingle or multiple tables are being renamed.\n\nIf a RENAME TABLE renames more than one table and one renaming fails, all\nrenames executed by the same statement are rolled back.\n\nRenames are always executed in the specified order. Knowing this, it is also\npossible to swap two tables\' names:\n\nRENAME TABLE t1 TO tmp_table,\n  t2 TO t1,\n  tmp_table TO t2;\n\nWAIT/NOWAIT\n-----------\n\nMariaDB starting with 10.3.0\n----------------------------\nSet the lock wait timeout. See WAIT and NOWAIT.\n\nPrivileges\n----------\n\nExecuting the RENAME TABLE statement requires the DROP, CREATE and INSERT\nprivileges for the table or the database.\n\nAtomic RENAME TABLE\n-------------------\n\nMariaDB starting with 10.6.1\n----------------------------\nFrom MariaDB 10.6, RENAME TABLE is atomic for most engines, including InnoDB,\nMyRocks, MyISAM and Aria (MDEV-23842). This means that if there is a crash\n(server down or power outage) during RENAME TABLE, all tables will revert to\ntheir original names and any changes to trigger files will be reverted.\n\nIn older MariaDB version there was a small chance that, during a server crash\nhappening in the middle of RENAME TABLE, some tables could have been renamed\n(in the worst case partly) while others would not be renamed.\n\nSee Atomic DDL for more information.\n\nURL: https://mariadb.com/kb/en/rename-table/','','https://mariadb.com/kb/en/rename-table/'),(692,'TRUNCATE TABLE',38,'Syntax\n------\n\nTRUNCATE [TABLE] tbl_name\n [WAIT n | NOWAIT]\n\nDescription\n-----------\n\nTRUNCATE TABLE empties a table completely. It requires the DROP privilege. See\nGRANT.\n\ntbl_name can also be specified in the form db_name.tbl_name (see Identifier\nQualifiers).\n\nLogically, TRUNCATE TABLE is equivalent to a DELETE statement that deletes all\nrows, but there are practical differences under some circumstances.\n\nTRUNCATE TABLE will fail for an InnoDB table if any FOREIGN KEY constraints\nfrom other tables reference the table, returning the error:\n\nERROR 1701 (42000): Cannot truncate a table referenced in a foreign key\nconstraint\n\nForeign Key constraints between columns in the same table are permitted.\n\nFor an InnoDB table, if there are no FOREIGN KEY constraints, InnoDB performs\nfast truncation by dropping the original table and creating an empty one with\nthe same definition, which is much faster than deleting rows one by one. The\nAUTO_INCREMENT counter is reset by TRUNCATE TABLE, regardless of whether there\nis a FOREIGN KEY constraint.\n\nThe count of rows affected by TRUNCATE TABLE is accurate only when it is\nmapped to a DELETE statement.\n\nFor other storage engines, TRUNCATE TABLE differs from DELETE in the following\nways:\n\n* Truncate operations drop and re-create the table, which is much\n faster than deleting rows one by one, particularly for large tables.\n* Truncate operations cause an implicit commit.\n* Truncation operations cannot be performed if the session holds an\n active table lock.\n* 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* As long as the table format file tbl_name.frm is valid, the\n table can be re-created as an empty table\n with TRUNCATE TABLE, even if the data or index files have become\n corrupted.\n* The table handler does not remember the last\n used AUTO_INCREMENT value, but starts counting\n from the beginning. This is true even for MyISAM and InnoDB, which normally\n do not reuse sequence values.\n* When used with partitioned tables, TRUNCATE TABLE preserves\n the partitioning; that is, the data and index files are dropped and\n re-created, while the partition definitions (.par) file is\n unaffected.\n* Since truncation of a table does not make any use of DELETE,\n the TRUNCATE statement does not invoke ON DELETE triggers.\n* TRUNCATE TABLE will only reset the values in the Performance Schema summary\ntables to zero or null, and will not remove the rows.\n\nFor the purposes of binary logging and replication, TRUNCATE TABLE is treated\nas DROP TABLE followed by CREATE TABLE (DDL rather than DML).\n\nTRUNCATE TABLE does not work on views. Currently, TRUNCATE TABLE drops all\nhistorical records from a system-versioned table.\n\nMariaDB starting with 10.3.0\n----------------------------\n\nWAIT/NOWAIT\n-----------\n\nSet the lock wait timeout. See WAIT and NOWAIT.\n\nOracle-mode\n-----------\n\nOracle-mode from MariaDB 10.3 permits the optional keywords REUSE STORAGE or\nDROP STORAGE to be used.\n\nTRUNCATE [TABLE] tbl_name [{DROP | REUSE} STORAGE] [WAIT n | NOWAIT]\n\nThese have no effect on the operation.\n\nPerformance\n-----------\n\nTRUNCATE TABLE is faster than DELETE, because it drops and re-creates a table.\n\nWith InnoDB, TRUNCATE TABLE is slower if innodb_file_per_table=ON is set (the\ndefault). This is because TRUNCATE TABLE unlinks the underlying tablespace\nfile, which can be an expensive operation. See MDEV-8069 for more details.\n\nThe performance issues with innodb_file_per_table=ON can be exacerbated in\ncases where the InnoDB buffer pool is very large and\ninnodb_adaptive_hash_index=ON is set. In that case, using DROP TABLE followed\nby CREATE TABLE instead of TRUNCATE TABLE may perform better. Setting\ninnodb_adaptive_hash_index=OFF (it defaults to ON before MariaDB 10.5) can\nalso help. In MariaDB 10.2 only, from MariaDB 10.2.19, this performance can\nalso be improved by setting innodb_safe_truncate=OFF. See MDEV-9459 for more\ndetails.\n\nSetting innodb_adaptive_hash_index=OFF can also improve TRUNCATE TABLE\nperformance in general. See MDEV-16796 for more details.\n\nURL: https://mariadb.com/kb/en/truncate-table/','','https://mariadb.com/kb/en/truncate-table/'),(693,'CREATE DATABASE',38,'Syntax\n------\n\nCREATE [OR REPLACE] {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 | COMMENT [=] \'comment\'\n\nDescription\n-----------\n\nCREATE DATABASE creates a database with the given name. To use this statement,\nyou need the CREATE privilege for the database. CREATE SCHEMA is a synonym for\nCREATE DATABASE.\n\nFor valid identifiers to use as database names, see Identifier Names.\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 DATABASE IF EXISTS db_name;\nCREATE DATABASE db_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 database already exists.\n\nCOMMENT\n-------\n\nMariaDB starting with 10.5.0\n----------------------------\nFrom MariaDB 10.5.0, it is possible to add a comment of a maximum of 1024\nbytes. If the comment length exceeds this length, a error/warning code 4144 is\nthrown. The database comment is also added to the db.opt file, as well as to\nthe information_schema.schemata table.\n\nExamples\n--------\n\nCREATE DATABASE db1;\nQuery OK, 1 row affected (0.18 sec)\n\nCREATE DATABASE db1;\nERROR 1007 (HY000): Can\'t create database \'db1\'; database exists\n\nCREATE OR REPLACE DATABASE db1;\nQuery OK, 2 rows affected (0.00 sec)\n\nCREATE DATABASE IF NOT EXISTS db1;\nQuery OK, 1 row affected, 1 warning (0.01 sec)\n\nSHOW WARNINGS;\n+-------+------+----------------------------------------------+\n| Level | Code | Message                                      |\n+-------+------+----------------------------------------------+\n| Note  | 1007 | Can\'t create database \'db1\'; database exists |\n+-------+------+----------------------------------------------+\n\nSetting the character sets and collation. See Setting Character Sets and\nCollations for more details.\n\nCREATE DATABASE czech_slovak_names \n CHARACTER SET = \'keybcs2\'\n COLLATE = \'keybcs2_bin\';\n\nComments, from MariaDB 10.5.0:\n\nCREATE DATABASE presentations COMMENT \'Presentations for conferences\';\n\nURL: https://mariadb.com/kb/en/create-database/','','https://mariadb.com/kb/en/create-database/'),(694,'CREATE EVENT',38,'Syntax\n------\n\nCREATE [OR REPLACE]\n  [DEFINER = { user | CURRENT_USER | role | CURRENT_ROLE }]\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 sql_statement;\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\nDescription\n-----------\n\nThis statement creates and schedules a new event. It requires the EVENT\nprivilege for the schema in which the event is to be created.\n\nThe minimum requirements for a valid CREATE EVENT statement are as follows:\n\n* The keywords CREATE EVENT plus an event name, which uniquely identifies\n the event in the current schema. (Prior to MySQL 5.1.12, the event name\n needed to be unique only among events created by the same user on a given\n database.)\n* An ON SCHEDULE clause, which determines when and how often the event\n executes.\n* A DO clause, which contains the SQL statement to be executed by an\n event.\n\nHere 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 executes\nonce — one hour following its creation — by running an SQL statement that\nincrements the value of the myschema.mytable table\'s mycol column by 1.\n\nThe event_name must be a valid MariaDB identifier with a maximum length of 64\ncharacters. It may be delimited using back ticks, and may be qualified with\nthe name of a database schema. An event is associated with both a MariaDB user\n(the definer) and a schema, and its name must be unique among names of events\nwithin that schema. In general, the rules governing event names are the same\nas those for names of stored routines. See Identifier Names.\n\nIf no schema is indicated as part of event_name, the default (current) schema\nis assumed.\n\nFor valid identifiers to use as event names, see Identifier Names.\n\nOR REPLACE\n----------\n\nThe OR REPLACE clause was included in MariaDB 10.1.4. If used and the event\nalready exists, instead of an error being returned, the existing event will be\ndropped and replaced by the newly defined event.\n\nIF NOT EXISTS\n-------------\n\nIf the IF NOT EXISTS clause is used, MariaDB will return a warning instead of\nan error if the event already exists. Cannot be used together with OR REPLACE.\n\nON SCHEDULE\n-----------\n\nThe ON SCHEDULE clause can be used to specify when the event must be triggered.\n\nAT\n--\n\nIf you want to execute the event only once (one time event), you can use the\nAT keyword, followed by a timestamp. If you use CURRENT_TIMESTAMP, the event\nacts as soon as it is created. As a convenience, you can add one or more\nintervals to that timestamp. You can also specify a timestamp in the past, so\nthat the event is stored but not triggered, until you modify it via ALTER\nEVENT.\n\nThe following example shows how to create an event that will be triggered\ntomorrow at a certain time:\n\nCREATE EVENT example\nON SCHEDULE AT CURRENT_TIMESTAMP + INTERVAL 1 DAY + INTERVAL 3 HOUR\nDO something;\n\nYou can also specify that an event must be triggered at a regular interval\n(recurring event). In such cases, use the EVERY clause followed by the\ninterval.\n\nIf an event is recurring, you can specify when the first execution must happen\nvia the STARTS clause and a maximum time for the last execution via the ENDS\nclause. STARTS and ENDS clauses are followed by a timestamp and, optionally,\none or more intervals. The ENDS clause can specify a timestamp in the past, so\nthat the event is stored but not executed until you modify it via ALTER EVENT.\n\nIn the following example, next month a recurring event will be triggered\nhourly for a week:\n\nCREATE EVENT example\nON SCHEDULE EVERY 1 HOUR\nSTARTS CURRENT_TIMESTAMP + INTERVAL 1 MONTH\nENDS CURRENT_TIMESTAMP + INTERVAL 1 MONTH + INTERVAL 1 WEEK\nDO some_task;\n\nIntervals consist of a quantity and a time unit. The time units are the same\nused for other staments and time functions, except that you can\'t use\nmicroseconds for events. For simple time units, like HOUR or MINUTE, the\nquantity is an integer number, for example \'10 MINUTE\'. For composite time\nunits, like HOUR_MINUTE or HOUR_SECOND, the quantity must be a string with all\ninvolved simple values and their separators, for example \'2:30\' or \'2:30:30\'.\n\nON COMPLETION [NOT] PRESERVE\n----------------------------\n\nThe ON COMPLETION clause can be used to specify if the event must be deleted\nafter its last execution (that is, after its AT or ENDS timestamp is past). By\ndefault, events are dropped when they are expired. To explicitly state that\nthis is the desired behaviour, you can use ON COMPLETION NOT PRESERVE.\nInstead, if you want the event to be preserved, you can use ON COMPLETION\nPRESERVE.\n\nIn you specify ON COMPLETION NOT PRESERVE, and you specify a timestamp in the\npast for AT or ENDS clause, the event will be immediatly dropped. In such\ncases, you will get a Note 1558: \"Event execution time is in the past and ON\nCOMPLETION NOT PRESERVE is set. The event was dropped immediately after\ncreation\".\n\nENABLE/DISABLE/DISABLE ON SLAVE\n-------------------------------\n\nEvents are ENABLEd by default. If you want to stop MariaDB from executing an\nevent, you may specify DISABLE. When it is ready to be activated, you may\nenable it using ALTER EVENT. Another option is DISABLE ON SLAVE, which\nindicates that an event was created on a master and has been replicated to the\nslave, which is prevented from executing the event. If DISABLE ON SLAVE is\nspecifically set, the event will be disabled everywhere. It will not be\nexecuted on the mater or the slaves.\n\nCOMMENT\n-------\n\nThe COMMENT clause may be used to set a comment for the event. Maximum length\nfor comments is 64 characters. The comment is a string, so it must be quoted.\nTo see events comments, you can query the INFORMATION_SCHEMA.EVENTS table (the\ncolumn is named EVENT_COMMENT).\n\nExamples\n--------\n\nMinimal 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\nAn event that will be triggered tomorrow at a certain time:\n\nCREATE EVENT example\nON SCHEDULE AT CURRENT_TIMESTAMP + INTERVAL 1 DAY + INTERVAL 3 HOUR\nDO something;\n\nNext month a recurring event will be triggered hourly for a week:\n\nCREATE EVENT example\nON SCHEDULE EVERY 1 HOUR\nSTARTS CURRENT_TIMESTAMP + INTERVAL 1 MONTH\nENDS CURRENT_TIMESTAMP + INTERVAL 1 MONTH + INTERVAL 1 WEEK\nDO some_task;\n\nOR REPLACE and IF NOT EXISTS:\n\nCREATE EVENT myevent\n  ON SCHEDULE AT CURRENT_TIMESTAMP + INTERVAL 1 HOUR\n  DO\n   UPDATE myschema.mytable SET mycol = mycol + 1;\nERROR 1537 (HY000): Event \'myevent\' already exists\n\nCREATE OR REPLACE EVENT myevent\n  ON SCHEDULE AT CURRENT_TIMESTAMP + INTERVAL 1 HOUR\n  DO\n   UPDATE myschema.mytable SET mycol = mycol + 1;;\nQuery OK, 0 rows affected (0.00 sec)\n\nCREATE EVENT IF NOT EXISTS myevent\n  ON SCHEDULE AT CURRENT_TIMESTAMP + INTERVAL 1 HOUR\n  DO\n   UPDATE myschema.mytable SET mycol = mycol + 1;\nQuery OK, 0 rows affected, 1 warning (0.00 sec)\n\nSHOW WARNINGS;\n+-------+------+--------------------------------+\n| Level | Code | Message                        |\n+-------+------+--------------------------------+\n| Note  | 1537 | Event \'myevent\' already exists |\n+-------+------+--------------------------------+\n\nURL: https://mariadb.com/kb/en/create-event/','','https://mariadb.com/kb/en/create-event/'),(695,'CREATE FUNCTION',38,'Syntax\n------\n\nCREATE [OR REPLACE]\n  [DEFINER = {user | CURRENT_USER | role | CURRENT_ROLE }]\n  [AGGREGATE] FUNCTION [IF NOT EXISTS] func_name ([func_parameter[,...]])\n  RETURNS type\n  [characteristic ...]\n  RETURN func_body\nfunc_parameter:\n  [ IN | OUT | INOUT | IN OUT ]  param_name type\ntype:\n  Any valid MariaDB data type\ncharacteristic:\n  LANGUAGE SQL\n | [NOT] DETERMINISTIC\n | { CONTAINS SQL | NO SQL | READS SQL DATA | MODIFIES SQL DATA }\n | SQL SECURITY { DEFINER | INVOKER }\n | COMMENT \'string\'\nfunc_body:\n  Valid SQL procedure statement\n\nDescription\n-----------\n\nUse the CREATE FUNCTION statement to create a new stored function. You must\nhave the CREATE ROUTINE database privilege to use CREATE FUNCTION. A function\ntakes any number of arguments and returns a value from the function body. The\nfunction body can be any valid SQL expression as you would use, for example,\nin any select expression. If you have the appropriate privileges, you can call\nthe function exactly as you would any built-in function. See Security below\nfor details on privileges.\n\nYou can also use a variant of the CREATE FUNCTION statement to install a\nuser-defined function (UDF) defined by a plugin. See CREATE FUNCTION (UDF) for\ndetails.\n\nYou can use a SELECT statement for the function body by enclosing it in\nparentheses, exactly as you would to use a subselect for any other expression.\nThe SELECT statement must return a single value. If more than one column is\nreturned when the function is called, error 1241 results. If more than one row\nis returned when the function is called, error 1242 results. Use a LIMIT\nclause to ensure only one row is returned.\n\nYou can also replace the RETURN clause with a BEGIN...END compound statement.\nThe compound statement must contain a RETURN statement. When the function is\ncalled, the RETURN statement immediately returns its result, and any\nstatements after RETURN are effectively ignored.\n\nBy default, a function is associated with the current database. To associate\nthe function explicitly with a given database, specify the fully-qualified\nname as db_name.func_name when you create it. If the function name is the same\nas the name of a built-in function, you must use the fully qualified name when\nyou call it.\n\nThe parameter list enclosed within parentheses must always be present. If\nthere are no parameters, an empty parameter list of () should be used.\nParameter names are not case sensitive.\n\nEach parameter can be declared to use any valid data type, except that the\nCOLLATE attribute cannot be used.\n\nFor valid identifiers to use as function names, see Identifier Names.\n\nIN | OUT | INOUT | IN OUT\n-------------------------\n\nMariaDB starting with 10.8.0\n----------------------------\nThe function parameter qualifiers for IN, OUT, INOUT, and IN OUT were added in\na 10.8.0 preview release. Prior to 10.8.0 quantifiers were supported only in\nprocedures.\n\nOUT, INOUT and its equivalent IN OUT, are only valid if called from SET and\nnot SELECT. These quantifiers are especially useful for creating functions\nwith more than one return value. This allows functions to be more complex and\nnested.\n\nDELIMITER $$\nCREATE FUNCTION add_func3(IN a INT, IN b INT, OUT c INT) RETURNS INT\nBEGIN\n SET c = 100;\n RETURN a + b;\nEND;\n$$\nDELIMITER ;\n\nSET @a = 2;\nSET @b = 3;\nSET @c = 0;\nSET @res= add_func3(@a, @b, @c);\n\nSELECT add_func3(@a, @b, @c);\nERROR 4186 (HY000): OUT or INOUT argument 3 for function add_func3 is not\nallowed here\n\nDELIMITER $$\nCREATE FUNCTION add_func4(IN a INT, IN b INT, d INT) RETURNS INT\nBEGIN\n DECLARE c, res INT;\n SET res = add_func3(a, b, c) + d;\n if (c > 99) then\n  return  3;\n else\n  return res;\n end if;\nEND;\n$$\n\nDELIMITER ;\n\nSELECT add_func4(1,2,3);\n+------------------+\n| add_func4(1,2,3) |\n+------------------+\n|                3 |\n+------------------+\n\nAGGREGATE\n---------\n\nMariaDB starting with 10.3.3\n----------------------------\nFrom MariaDB 10.3.3, it is possible to create stored aggregate functions as\nwell. See Stored Aggregate Functions for details.\n\nRETURNS\n-------\n\nThe RETURNS clause specifies the return type of the function. NULL values are\npermitted with all return types.\n\nWhat happens if the RETURN clause returns a value of a different type? It\ndepends on the SQL_MODE in effect at the moment of the function creation.\n\nIf the SQL_MODE is strict (STRICT_ALL_TABLES or STRICT_TRANS_TABLES flags are\nspecified), a 1366 error will be produced.\n\nOtherwise, the value is coerced to the proper type. For example, if a function\nspecifies an ENUM or SET value in the RETURNS clause, but the RETURN clause\nreturns an integer, the value returned from the function is the string for the\ncorresponding ENUM member of set of SET members.\n\nMariaDB stores the SQL_MODE system variable setting that is in effect at the\ntime a routine is created, and always executes the routine with this setting\nin force, regardless of the server SQL mode in effect when the routine is\ninvoked.\n\nLANGUAGE SQL\n------------\n\nLANGUAGE SQL is a standard SQL clause, and it can be used in MariaDB for\nportability. However that clause has no meaning, because SQL is the only\nsupported language for stored functions.\n\nA function is deterministic if it can produce only one result for a given list\nof parameters. If the result may be affected by stored data, server variables,\nrandom numbers or any value that is not explicitly passed, then the function\nis not deterministic. Also, a function is non-deterministic if it uses\nnon-deterministic functions like NOW() or CURRENT_TIMESTAMP(). The optimizer\nmay choose a faster execution plan if it known that the function is\ndeterministic. In such cases, you should declare the routine using the\nDETERMINISTIC keyword. If you want to explicitly state that the function is\nnot deterministic (which is the default) you can use the NOT DETERMINISTIC\nkeywords.\n\nIf you declare a non-deterministic function as DETERMINISTIC, you may get\nincorrect results. If you declare a deterministic function as NOT\nDETERMINISTIC, in some cases the queries will be slower.\n\nOR REPLACE\n----------\n\nMariaDB starting with 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 function_name ...;\n\nwith the exception that any existing privileges for the function are not\ndropped.\n\nIF NOT EXISTS\n-------------\n\nMariaDB starting with 10.1.3\n----------------------------\nIf the IF NOT EXISTS clause is used, MariaDB will return a warning instead of\nan error if the function already exists. Cannot be used together with OR\nREPLACE.\n\n[NOT] DETERMINISTIC\n-------------------\n\nThe [NOT] DETERMINISTIC clause also affects binary logging, because the\nSTATEMENT format can not be used to store or replicate non-deterministic\nstatements.\n\nCONTAINS SQL, NO SQL, READS SQL DATA, and MODIFIES SQL DATA are informative\nclauses that tell the server what the function does. MariaDB does not check in\nany way whether the specified clause is correct. If none of these clauses are\nspecified, CONTAINS SQL is used by default.\n\nMODIFIES SQL DATA\n-----------------\n\nMODIFIES SQL DATA means that the function contains statements that may modify\ndata stored in databases. This happens if the function contains statements\nlike DELETE, UPDATE, INSERT, REPLACE or DDL.\n\nREADS SQL DATA\n--------------\n\nREADS SQL DATA means that the function reads data stored in databases, but\ndoes not modify any data. This happens if SELECT statements are used, but\nthere no write operations are executed.\n\nCONTAINS SQL\n------------\n\nCONTAINS SQL means that the function contains at least one SQL statement, but\nit does not read or write any data stored in a database. Examples include SET\nor DO.\n\nNO SQL\n------\n\nNO SQL means nothing, because MariaDB does not currently support any language\nother than SQL.\n\nOracle Mode\n-----------\n\nMariaDB starting with 10.3\n--------------------------\nFrom MariaDB 10.3, a subset of Oracle\'s PL/SQL language has been supported in\naddition to the traditional SQL/PSM-based MariaDB syntax. See Oracle mode from\nMariaDB 10.3 for details on changes when running Oracle mode.\n\nSecurity\n--------\n\nYou must have the EXECUTE privilege on a function to call it. MariaDB\nautomatically grants the EXECUTE and ALTER ROUTINE privileges to the account\nthat called CREATE FUNCTION, even if the DEFINER clause was used.\n\nEach function has an account associated as the definer. By default, the\ndefiner is the account that created the function. Use the DEFINER clause to\nspecify a different account as the definer. You must have the SUPER privilege,\nor, from MariaDB 10.5.2, the SET USER privilege, to use the DEFINER clause.\nSee Account Names for details on specifying accounts.\n\nThe SQL SECURITY clause specifies what privileges are used when a function is\ncalled. If SQL SECURITY is INVOKER, the function body will be evaluated using\nthe privileges of the user calling the function. If SQL SECURITY is DEFINER,\nthe function body is always evaluated using the privileges of the definer\naccount. DEFINER is the default.\n\nThis allows you to create functions that grant limited access to certain data.\nFor example, say you have a table that stores some employee information, and\nthat you\'ve granted SELECT privileges only on certain columns to the user\naccount roger.\n\nCREATE TABLE employees (name TINYTEXT, dept TINYTEXT, salary INT);\nGRANT SELECT (name, dept) ON employees TO roger;\n\nTo allow the user the get the maximum salary for a department, define a\nfunction and grant the EXECUTE privilege:\n\nCREATE FUNCTION max_salary (dept TINYTEXT) RETURNS INT RETURN\n (SELECT MAX(salary) FROM employees WHERE employees.dept = dept);\nGRANT EXECUTE ON FUNCTION max_salary TO roger;\n\nSince SQL SECURITY defaults to DEFINER, whenever the user roger calls this\nfunction, the subselect will execute with your privileges. As long as you have\nprivileges to select the salary of each employee, the caller of the function\nwill be able to get the maximum salary for each department without being able\nto see individual salaries.\n\nCharacter sets and collations\n-----------------------------\n\nFunction return types can be declared to use any valid character set and\ncollation. If used, the COLLATE attribute needs to be preceded by a CHARACTER\nSET attribute.\n\nIf the character set and collation are not specifically set in the statement,\nthe database defaults at the time of creation will be used. If the database\ndefaults change at a later stage, the stored function character set/collation\nwill not be changed at the same time; the stored function needs to be dropped\nand recreated to ensure the same character set/collation as the database is\nused.\n\nExamples\n--------\n\nThe following example function takes a parameter, performs an operation using\nan SQL function, and returns the result.\n\nCREATE FUNCTION hello (s CHAR(20))\n  RETURNS CHAR(50) DETERMINISTIC\n  RETURN CONCAT(\'Hello, \',s,\'!\');\n\nSELECT hello(\'world\');\n+----------------+\n| hello(\'world\') |\n+----------------+\n| Hello, world!  |\n+----------------+\n\nYou can use a compound statement in a function to manipulate data with\nstatements like INSERT and UPDATE. The following example creates a counter\nfunction that uses a temporary table to store the current value. Because the\ncompound statement contains statements terminated with semicolons, you have to\nfirst change the statement delimiter with the DELIMITER statement to allow the\nsemicolon to be used in the function body. See Delimiters in the mysql client\nfor more.\n\nCREATE TEMPORARY TABLE counter (c INT);\nINSERT INTO counter VALUES (0);\nDELIMITER //\nCREATE FUNCTION counter () RETURNS INT\n BEGIN\n  UPDATE counter SET c = c + 1;\n  RETURN (SELECT c FROM counter LIMIT 1);\n END //\nDELIMITER ;\n\nCharacter set and collation:\n\nCREATE FUNCTION hello2 (s CHAR(20))\n RETURNS CHAR(50) CHARACTER SET \'utf8\' COLLATE \'utf8_bin\' DETERMINISTIC\n RETURN CONCAT(\'Hello, \',s,\'!\');\n\nURL: https://mariadb.com/kb/en/create-function/','','https://mariadb.com/kb/en/create-function/'),(696,'CREATE INDEX',38,'Syntax\n------\n\nCREATE [OR REPLACE] [UNIQUE|FULLTEXT|SPATIAL] INDEX \n [IF NOT EXISTS] index_name\n  [index_type]\n  ON tbl_name (index_col_name,...)\n  [WAIT n | NOWAIT]\n  [index_option]\n  [algorithm_option | lock_option] ...\n\nindex_col_name:\n  col_name [(length)] [ASC | DESC]\n\nindex_type:\n  USING {BTREE | HASH | RTREE}\n\nindex_option:\n  [ KEY_BLOCK_SIZE [=] value\n | index_type\n | WITH PARSER parser_name\n | COMMENT \'string\'\n | CLUSTERING={YES| NO} ]\n [ IGNORED | NOT IGNORED ]\n\nalgorithm_option:\n  ALGORITHM [=] {DEFAULT|INPLACE|COPY|NOCOPY|INSTANT}\n\nlock_option:\n  LOCK [=] {DEFAULT|NONE|SHARED|EXCLUSIVE}\n\nDescription\n-----------\n\nCREATE INDEX is mapped to an ALTER TABLE statement to create indexes. See\nALTER TABLE. CREATE INDEX cannot be used to create a PRIMARY KEY; use ALTER\nTABLE instead.\n\nIf another connection is using the table, a metadata lock is active, and this\nstatement will wait until the lock is released. This is also true for\nnon-transactional tables.\n\nAnother shortcut, DROP INDEX, allows the removal of an index.\n\nFor valid identifiers to use as index names, see Identifier Names.\n\nNote that KEY_BLOCK_SIZE is currently ignored in CREATE INDEX, although it is\nincluded in the output of SHOW CREATE TABLE.\n\nPrivileges\n----------\n\nExecuting the CREATE INDEX statement requires the INDEX privilege for the\ntable or the database.\n\nOnline DDL\n----------\n\nOnline DDL is supported with the ALGORITHM and LOCK clauses.\n\nSee InnoDB Online DDL Overview for more information on online DDL with InnoDB.\n\nCREATE OR REPLACE INDEX\n-----------------------\n\nIf the OR REPLACE clause is used and if the index already exists, then instead\nof returning an error, the server will drop the existing index and replace it\nwith the newly defined index.\n\nCREATE INDEX IF NOT EXISTS\n--------------------------\n\nIf the IF NOT EXISTS clause is used, then the index will only be created if an\nindex with the same name does not already exist. If the index already exists,\nthen a warning will be triggered by default.\n\nIndex Definitions\n-----------------\n\nSee CREATE TABLE: Index Definitions for information about index definitions.\n\nWAIT/NOWAIT\n-----------\n\nSet the lock wait timeout. See WAIT and NOWAIT.\n\nALGORITHM\n---------\n\nSee ALTER TABLE: ALGORITHM for more information.\n\nLOCK\n----\n\nSee ALTER TABLE: LOCK for more information.\n\nProgress Reporting\n------------------\n\nMariaDB provides progress reporting for CREATE INDEX statement for clients\nthat support the new progress reporting protocol. For example, if you were\nusing the mysql client, then the progress report might look like this::\n\nCREATE INDEX i ON tab (num);\nStage: 1 of 2 \'copy to tmp table\'    46% of stage\n\nThe progress report is also shown in the output of the SHOW PROCESSLIST\nstatement and in the contents of the information_schema.PROCESSLIST table.\n\nSee Progress Reporting for more information.\n\nWITHOUT OVERLAPS\n----------------\n\nMariaDB starting with 10.5.3\n----------------------------\nThe WITHOUT OVERLAPS clause allows one to constrain a primary or unique index\nsuch that application-time periods cannot overlap.\n\nExamples\n--------\n\nCreating a unique index:\n\nCREATE UNIQUE INDEX HomePhone ON Employees(Home_Phone);\n\nOR REPLACE and IF NOT EXISTS:\n\nCREATE INDEX xi ON xx5 (x);\nQuery OK, 0 rows affected (0.03 sec)\n\nCREATE INDEX xi ON xx5 (x);\nERROR 1061 (42000): Duplicate key name \'xi\'\n\nCREATE OR REPLACE INDEX xi ON xx5 (x);\nQuery OK, 0 rows affected (0.03 sec)\n\nCREATE INDEX IF NOT EXISTS xi ON xx5 (x);\nQuery OK, 0 rows affected, 1 warning (0.00 sec)\n\nSHOW WARNINGS;\n+-------+------+-------------------------+\n| Level | Code | Message                 |\n+-------+------+-------------------------+\n| Note  | 1061 | Duplicate key name \'xi\' |\n+-------+------+-------------------------+\n\nFrom MariaDB 10.5.3, creating a unique index for an application-time period\ntable with a WITHOUT OVERLAPS constraint:\n\nCREATE UNIQUE INDEX u ON rooms (room_number, p WITHOUT OVERLAPS);\n\nURL: https://mariadb.com/kb/en/create-index/','','https://mariadb.com/kb/en/create-index/'),(697,'CREATE PACKAGE',38,'MariaDB starting with 10.3.5\n----------------------------\nOracle-style packages were introduced in MariaDB 10.3.5.\n\nSyntax\n------\n\nCREATE\n  [ OR REPLACE]\n  [DEFINER = { user | CURRENT_USER | role | CURRENT_ROLE }]\n  PACKAGE [ IF NOT EXISTS ]\n  [ db_name . ] package_name\n  [ package_characteristic ... ]\n{ AS | IS }\n  [ package_specification_element ... ]\nEND [ package_name ]\n\npackage_characteristic:\n  COMMENT \'string\'\n | SQL SECURITY { DEFINER | INVOKER }\n\npackage_specification_element:\n  FUNCTION_SYM package_specification_function ;\n | PROCEDURE_SYM package_specification_procedure ;\n\npackage_specification_function:\n  func_name [ ( func_param [, func_param]... ) ]\n  RETURNS func_return_type\n  [ package_routine_characteristic... ]\n\npackage_specification_procedure:\n  proc_name [ ( proc_param [, proc_param]... ) ]\n  [ package_routine_characteristic... ]\n\nfunc_return_type:\n  type\n\nfunc_param:\n  param_name [ IN | OUT | INOUT | IN OUT ] type\n\nproc_param:\n  param_name [ IN | OUT | INOUT | IN OUT ] type\n\ntype:\n  Any valid MariaDB explicit or anchored data type\n\npackage_routine_characteristic:\n   COMMENT  \'string\'\n  | LANGUAGE SQL\n  | { CONTAINS SQL | NO SQL | READS SQL DATA | MODIFIES SQL DATA }\n  | SQL SECURITY { DEFINER | INVOKER }\n\nDescription\n-----------\n\nThe CREATE PACKAGE statement can be used when Oracle SQL_MODE is set.\n\nThe CREATE PACKAGE creates the specification for a stored package (a\ncollection of logically related stored objects). A stored package\nspecification declares public routines (procedures and functions) of the\npackage, but does not implement these routines.\n\nA package whose specification was created by the CREATE PACKAGE statement,\nshould later be implemented using the CREATE PACKAGE BODY statement.\n\nFunction parameter quantifiers IN | OUT | INOUT | IN OUT\n--------------------------------------------------------\n\nMariaDB starting with 10.8.0\n----------------------------\nThe function parameter quantifiers for IN, OUT, INOUT, and IN OUT where added\nin a 10.8.0 preview release. Prior to 10.8.0 quantifiers were supported only\nin procedures.\n\nOUT, INOUT and its equivalent IN OUT, are only valid if called from SET and\nnot SELECT. These quantifiers are especially useful for creating functions and\nprocedures with more than one return value. This allows functions and\nprocedures to be more complex and nested.\n\nExamples\n--------\n\nSET sql_mode=ORACLE;\nDELIMITER $$\nCREATE OR REPLACE PACKAGE employee_tools AS\n FUNCTION getSalary(eid INT) RETURN DECIMAL(10,2);\n PROCEDURE raiseSalary(eid INT, amount DECIMAL(10,2));\n PROCEDURE raiseSalaryStd(eid INT);\n PROCEDURE hire(ename TEXT, esalary DECIMAL(10,2));\nEND;\n$$\nDELIMITER ;\n\nURL: https://mariadb.com/kb/en/create-package/','','https://mariadb.com/kb/en/create-package/'),(698,'CREATE PACKAGE BODY',38,'MariaDB starting with 10.3.5\n----------------------------\nOracle-style packages were introduced in MariaDB 10.3.5.\n\nSyntax\n------\n\nCREATE [ OR REPLACE ]\n  [DEFINER = { user | CURRENT_USER | role | CURRENT_ROLE }]\n  PACKAGE BODY\n  [ IF NOT EXISTS ]\n  [ db_name . ] package_name\n  [ package_characteristic... ]\n{ AS | IS }\n  package_implementation_declare_section\n  package_implementation_executable_section\nEND [ package_name]\n\npackage_implementation_declare_section:\n  package_implementation_item_declaration\n   [ package_implementation_item_declaration... ]\n   [ package_implementation_routine_definition... ]\n | package_implementation_routine_definition\n   [ package_implementation_routine_definition...]\n\npackage_implementation_item_declaration:\n  variable_declaration ;\n\nvariable_declaration:\n  variable_name[,...] type [:= expr ]\n\npackage_implementation_routine_definition:\n  FUNCTION package_specification_function\n   [ package_implementation_function_body ] ;\n | PROCEDURE package_specification_procedure\n   [ package_implementation_procedure_body ] ;\n\npackage_implementation_function_body:\n  { AS | IS } package_routine_body [func_name]\n\npackage_implementation_procedure_body:\n  { AS | IS } package_routine_body [proc_name]\n\npackage_routine_body:\n  [ package_routine_declarations ]\n  BEGIN\n   statements [ EXCEPTION exception_handlers ]\n  END\n\npackage_routine_declarations:\n  package_routine_declaration \';\' [package_routine_declaration \';\']...\n\npackage_routine_declaration:\n     variable_declaration\n    | condition_name CONDITION FOR condition_value\n    | user_exception_name EXCEPTION\n    | CURSOR_SYM cursor_name\n     [ ( cursor_formal_parameters ) ]\n     IS select_statement\n    ;\n\npackage_implementation_executable_section:\n     END\n    | BEGIN\n      statement ; [statement ; ]...\n     [EXCEPTION exception_handlers]\n     END\n\nexception_handlers:\n     exception_handler [exception_handler...]\n\nexception_handler:\n     WHEN_SYM condition_value [, condition_value]...\n      THEN_SYM statement ; [statement ;]...\n\ncondition_value:\n     condition_name\n    | user_exception_name\n    | SQLWARNING\n    | SQLEXCEPTION\n    | NOT FOUND\n    | OTHERS_SYM\n    | SQLSTATE [VALUE] sqlstate_value\n    | mariadb_error_code\n\nDescription\n-----------\n\nThe CREATE PACKAGE BODY statement can be used when Oracle SQL_MODE is set.\n\nThe CREATE PACKAGE BODY statement creates the package body for a stored\npackage. The package specification must be previously created using the CREATE\nPACKAGE statement.\n\nA package body provides implementations of the package public routines and can\noptionally have:\n\n* package-wide private variables\n* package private routines\n* forward declarations for private routines\n* an executable initialization section\n\nExamples\n--------\n\nSET sql_mode=ORACLE;\nDELIMITER $$\nCREATE OR REPLACE PACKAGE employee_tools AS\n FUNCTION getSalary(eid INT) RETURN DECIMAL(10,2);\n PROCEDURE raiseSalary(eid INT, amount DECIMAL(10,2));\n PROCEDURE raiseSalaryStd(eid INT);\n PROCEDURE hire(ename TEXT, esalary DECIMAL(10,2));\nEND;\n$$\nCREATE PACKAGE BODY employee_tools AS\n -- package body variables\n stdRaiseAmount DECIMAL(10,2):=500;\n\n-- private routines\n PROCEDURE log (eid INT, ecmnt TEXT) AS\n BEGIN\n  INSERT INTO employee_log (id, cmnt) VALUES (eid, ecmnt);\n END;\n\n-- public routines\n PROCEDURE hire(ename TEXT, esalary DECIMAL(10,2)) AS\n  eid INT;\n BEGIN\n  INSERT INTO employee (name, salary) VALUES (ename, esalary);\n  eid:= last_insert_id();\n  log(eid, \'hire \' || ename);\n END;\n\nFUNCTION getSalary(eid INT) RETURN DECIMAL(10,2) AS\n  nSalary DECIMAL(10,2);\n BEGIN\n  SELECT salary INTO nSalary FROM employee WHERE id=eid;\n  log(eid, \'getSalary id=\' || eid || \' salary=\' || nSalary);\n  RETURN nSalary;\n END;\n\nPROCEDURE raiseSalary(eid INT, amount DECIMAL(10,2)) AS\n BEGIN\n  UPDATE employee SET salary=salary+amount WHERE id=eid;\n  log(eid, \'raiseSalary id=\' || eid || \' amount=\' || amount);\n END;\n\nPROCEDURE raiseSalaryStd(eid INT) AS\n BEGIN\n  raiseSalary(eid, stdRaiseAmount);\n  log(eid, \'raiseSalaryStd id=\' || eid);\n END;\n\nBEGIN\n -- This code is executed when the current session\n -- accesses any of the package routines for the first time\n log(0, \'Session \' || connection_id() || \' \' || current_user || \' started\');\nEND;\n$$\n\nDELIMITER ;\n\nURL: https://mariadb.com/kb/en/create-package-body/','','https://mariadb.com/kb/en/create-package-body/'),(699,'CREATE PROCEDURE',38,'Syntax\n------\n\nCREATE\n  [OR REPLACE]\n  [DEFINER = { user | CURRENT_USER | role | CURRENT_ROLE }]\n  PROCEDURE [IF NOT EXISTS] sp_name ([proc_parameter[,...]])\n  [characteristic ...] routine_body\n\nproc_parameter:\n  [ IN | OUT | INOUT ] param_name type\n\ntype:\n  Any valid MariaDB data type\n\ncharacteristic:\n  LANGUAGE SQL\n | [NOT] DETERMINISTIC\n | { CONTAINS SQL | NO SQL | READS SQL DATA | MODIFIES SQL DATA }\n | SQL SECURITY { DEFINER | INVOKER }\n | COMMENT \'string\'\n\nroutine_body:\n  Valid SQL procedure statement\n\nDescription\n-----------\n\nCreates a stored procedure. By default, a routine is associated with the\ndefault database. To associate the routine explicitly with a given database,\nspecify the name as db_name.sp_name when you create it.\n\nWhen the routine is invoked, an implicit USE db_name is performed (and undone\nwhen the routine terminates). The causes the routine to have the given default\ndatabase while it executes. USE statements within stored routines are\ndisallowed.\n\nWhen a stored procedure has been created, you invoke it by using the CALL\nstatement (see CALL).\n\nTo execute the CREATE PROCEDURE statement, it is necessary to have the CREATE\nROUTINE privilege. By default, MariaDB automatically grants the ALTER ROUTINE\nand EXECUTE privileges to the routine creator. See also Stored Routine\nPrivileges.\n\nThe DEFINER and SQL SECURITY clauses specify the security context to be used\nwhen checking access privileges at routine execution time, as described here.\nRequires the SUPER privilege, or, from MariaDB 10.5.2, the SET USER privilege.\n\nIf the routine name is the same as the name of a built-in SQL function, you\nmust use a space between the name and the following parenthesis when defining\nthe routine, or a syntax error occurs. This is also true when you invoke the\nroutine later. For this reason, we suggest that it is better to avoid re-using\nthe names of existing SQL functions for your own stored routines.\n\nThe IGNORE_SPACE SQL mode applies to built-in functions, not to stored\nroutines. It is always allowable to have spaces after a routine name,\nregardless of whether IGNORE_SPACE is enabled.\n\nThe parameter list enclosed within parentheses must always be present. If\nthere are no parameters, an empty parameter list of () should be used.\nParameter names are not case sensitive.\n\nEach parameter can be declared to use any valid data type, except that the\nCOLLATE attribute cannot be used.\n\nFor valid identifiers to use as procedure names, see Identifier Names.\n\nThings to be Aware of With CREATE OR REPLACE\n--------------------------------------------\n\n* One can\'t use OR REPLACE together with IF EXISTS.\n\nCREATE PROCEDURE IF NOT EXISTS\n------------------------------\n\nIf the IF NOT EXISTS clause is used, then the procedure will only be created\nif a procedure with the same name does not already exist. If the procedure\nalready exists, then a warning will be triggered by default.\n\nIN/OUT/INOUT\n------------\n\nEach parameter is an IN parameter by default. To specify otherwise for a\nparameter, use the keyword OUT or INOUT before the parameter name.\n\nAn IN parameter passes a value into a procedure. The procedure might modify\nthe value, but the modification is not visible to the caller when the\nprocedure returns. An OUT parameter passes a value from the procedure back to\nthe caller. Its initial value is NULL within the procedure, and its value is\nvisible to the caller when the procedure returns. An INOUT parameter is\ninitialized by the caller, can be modified by the procedure, and any change\nmade by the procedure is visible to the caller when the procedure returns.\n\nFor each OUT or INOUT parameter, pass a user-defined variable in the CALL\nstatement that invokes the procedure so that you can obtain its value when the\nprocedure returns. If you are calling the procedure from within another stored\nprocedure or function, you can also pass a routine parameter or local routine\nvariable as an IN or INOUT parameter.\n\nDETERMINISTIC/NOT DETERMINISTIC\n-------------------------------\n\nDETERMINISTIC and NOT DETERMINISTIC apply only to functions. Specifying\nDETERMINISTC or NON-DETERMINISTIC in procedures has no effect. The default\nvalue is NOT DETERMINISTIC. Functions are DETERMINISTIC when they always\nreturn the same value for the same input. For example, a truncate or substring\nfunction. Any function involving data, therefore, is always NOT DETERMINISTIC.\n\nCONTAINS SQL/NO SQL/READS SQL DATA/MODIFIES SQL DATA\n----------------------------------------------------\n\nCONTAINS SQL, NO SQL, READS SQL DATA, and MODIFIES SQL DATA are informative\nclauses that tell the server what the function does. MariaDB does not check in\nany way whether the specified clause is correct. If none of these clauses are\nspecified, CONTAINS SQL is used by default.\n\nMODIFIES SQL DATA means that the function contains statements that may modify\ndata stored in databases. This happens if the function contains statements\nlike DELETE, UPDATE, INSERT, REPLACE or DDL.\n\nREADS SQL DATA means that the function reads data stored in databases, but\ndoes not modify any data. This happens if SELECT statements are used, but\nthere no write operations are executed.\n\nCONTAINS SQL means that the function contains at least one SQL statement, but\nit does not read or write any data stored in a database. Examples include SET\nor DO.\n\nNO SQL means nothing, because MariaDB does not currently support any language\nother than SQL.\n\nThe routine_body consists of a valid SQL procedure statement. This can be a\nsimple statement such as SELECT or INSERT, or it can be a compound statement\nwritten using BEGIN and END. Compound statements can contain declarations,\nloops, and other control structure statements. See Programmatic and Compound\nStatements for syntax details.\n\nMariaDB allows routines to contain DDL statements, such as CREATE and DROP.\nMariaDB also allows stored procedures (but not stored functions) to contain\nSQL transaction statements such as COMMIT.\n\nFor additional information about statements that are not allowed in stored\nroutines, see Stored Routine Limitations.\n\nInvoking stored procedure from within programs\n----------------------------------------------\n\nFor information about invoking stored procedures from within programs written\nin a language that has a MariaDB/MySQL interface, see CALL.\n\nOR REPLACE\n----------\n\nIf the optional OR REPLACE clause is used, it acts as a shortcut for:\n\nDROP PROCEDURE IF EXISTS name;\nCREATE PROCEDURE name ...;\n\nwith the exception that any existing privileges for the procedure are not\ndropped.\n\nsql_mode\n--------\n\nMariaDB stores the sql_mode system variable setting that is in effect at the\ntime a routine is created, and always executes the routine with this setting\nin force, regardless of the server SQL mode in effect when the routine is\ninvoked.\n\nCharacter Sets and Collations\n-----------------------------\n\nProcedure parameters can be declared with any character set/collation. If the\ncharacter set and collation are not specifically set, the database defaults at\nthe time of creation will be used. If the database defaults change at a later\nstage, the stored procedure character set/collation will not be changed at the\nsame time; the stored procedure needs to be dropped and recreated to ensure\nthe same character set/collation as the database is used.\n\nOracle Mode\n-----------\n\nMariaDB starting with 10.3\n--------------------------\nFrom MariaDB 10.3, a subset of Oracle\'s PL/SQL language has been supported in\naddition to the traditional SQL/PSM-based MariaDB syntax. See Oracle mode from\nMariaDB 10.3 for details on changes when running Oracle mode.\n\nExamples\n--------\n\nThe following example shows a simple stored procedure that uses an OUT\nparameter. It uses the DELIMITER command to set a new delimiter for the\nduration of the process — see Delimiters in the mysql client.\n\nDELIMITER //\n\nCREATE PROCEDURE simpleproc (OUT param1 INT)\n BEGIN\n SELECT COUNT(*) INTO param1 FROM t;\n END;\n//\n\nDELIMITER ;\n\nCALL simpleproc(@a);\n\nSELECT @a;\n+------+\n| @a   |\n+------+\n|    1 |\n+------+\n\nCharacter set and collation:\n\nDELIMITER //\n\nCREATE PROCEDURE simpleproc2 (\n OUT param1 CHAR(10) CHARACTER SET \'utf8\' COLLATE \'utf8_bin\'\n)\n BEGIN\n SELECT CONCAT(\'a\'),f1 INTO param1 FROM t;\n END;\n//\n\nDELIMITER ;\n\nCREATE OR REPLACE:\n\nDELIMITER //\n\nCREATE PROCEDURE simpleproc2 (\n OUT param1 CHAR(10) CHARACTER SET \'utf8\' COLLATE \'utf8_bin\'\n)\n BEGIN\n SELECT CONCAT(\'a\'),f1 INTO param1 FROM t;\n END;\n//\nERROR 1304 (42000): PROCEDURE simpleproc2 already exists\n\nDELIMITER ;\n\nDELIMITER //\n\nCREATE OR REPLACE PROCEDURE simpleproc2 (\n OUT param1 CHAR(10) CHARACTER SET \'utf8\' COLLATE \'utf8_bin\'\n)\n BEGIN\n SELECT CONCAT(\'a\'),f1 INTO param1 FROM t;\n END;\n//\nERROR 1304 (42000): PROCEDURE simpleproc2 already exists\n\nDELIMITER ;\nQuery OK, 0 rows affected (0.03 sec)\n\nURL: https://mariadb.com/kb/en/create-procedure/','','https://mariadb.com/kb/en/create-procedure/'),(700,'CREATE SERVER',38,'Syntax\n------\n\nCREATE [OR REPLACE] SERVER [IF NOT EXISTS] 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\nDescription\n-----------\n\nThis statement creates the definition of a server for use with the Spider,\nConnect, FEDERATED or FederatedX storage engine. The CREATE SERVER statement\ncreates a new row within the servers table within the mysql database. This\nstatement requires the SUPER privilege or, from MariaDB 10.5.2, the FEDERATED\nADMIN privilege.\n\nThe server_name should be a unique reference to the server. Server definitions\nare global within the scope of the server, it is not possible to qualify the\nserver definition to a specific database. server_name has a maximum length of\n64 characters (names longer than 64 characters are silently truncated), and is\ncase insensitive. You may specify the name as a quoted string.\n\nThe wrapper_name may be quoted with single quotes. Supported values are:\n\n* mysql\n* mariadb (in MariaDB 10.3 and later)\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 silently\ntruncated to 64 characters. Numeric literals must be a number between 0 and\n9999, default value is 0.\n\nNote: The OWNER option is currently not applied, and has no effect on the\nownership or operation of the server connection that is created.\n\nThe CREATE SERVER statement creates an entry in the mysql.servers table that\ncan later be used with the CREATE TABLE statement when creating a Spider,\nConnect, FederatedX or FEDERATED table. The options that you specify will be\nused to populate the columns in the mysql.servers table. The table columns are\nServer_name, Host, Db, Username, Password, Port and Socket.\n\nDROP SERVER removes a previously created server definition.\n\nCREATE SERVER is not written to the binary log, irrespective of the binary log\nformat being used. From MariaDB 10.1.13, Galera replicates the CREATE SERVER,\nALTER SERVER and DROP SERVER statements.\n\nFor valid identifiers to use as server names, see Identifier Names.\n\nOR REPLACE\n----------\n\nIf the optional OR REPLACE clause is used, it acts as a shortcut for:\n\nDROP SERVER IF EXISTS name;\nCREATE SERVER server_name ...;\n\nIF NOT EXISTS\n-------------\n\nIf the IF NOT EXISTS clause is used, MariaDB will return a warning instead of\nan error if the server already exists. Cannot be used together with OR REPLACE.\n\nExamples\n--------\n\nCREATE SERVER s\nFOREIGN DATA WRAPPER mysql\nOPTIONS (USER \'Remote\', HOST \'192.168.1.106\', DATABASE \'test\');\n\nOR REPLACE and IF NOT EXISTS:\n\nCREATE SERVER s \nFOREIGN DATA WRAPPER mysql \nOPTIONS (USER \'Remote\', HOST \'192.168.1.106\', DATABASE \'test\');\nERROR 1476 (HY000): The foreign server, s, you are trying to create already\nexists\n\nCREATE OR REPLACE SERVER s \nFOREIGN DATA WRAPPER mysql \nOPTIONS (USER \'Remote\', HOST \'192.168.1.106\', DATABASE \'test\');\nQuery OK, 0 rows affected (0.00 sec)\n\nCREATE SERVER IF NOT EXISTS s \nFOREIGN DATA WRAPPER mysql \nOPTIONS (USER \'Remote\', HOST \'192.168.1.106\', DATABASE \'test\');\nQuery OK, 0 rows affected, 1 warning (0.00 sec)\n\nSHOW WARNINGS;\n+-------+------+---------------------------------------------------------------\n+\n| Level | Code | Message                                                      \n |\n+-------+------+---------------------------------------------------------------\n+\n| Note  | 1476 | The foreign server, s, you are trying to create already\nexists |\n+-------+------+---------------------------------------------------------------\n+\n\nURL: https://mariadb.com/kb/en/create-server/','','https://mariadb.com/kb/en/create-server/'),(701,'CREATE TABLESPACE',38,'The CREATE TABLESPACE statement is not supported by MariaDB. It was originally\ninherited from MySQL NDB Cluster. In MySQL 5.7 and later, the statement is\nalso supported for InnoDB. However, MariaDB has chosen not to include that\nspecific feature. See MDEV-19294 for more information.\n\nURL: https://mariadb.com/kb/en/create-tablespace/','','https://mariadb.com/kb/en/create-tablespace/'),(702,'CREATE TRIGGER',38,'Syntax\n------\n\nCREATE [OR REPLACE]\n  [DEFINER = { user | CURRENT_USER | role | CURRENT_ROLE }]\n  TRIGGER [IF NOT EXISTS] trigger_name trigger_time trigger_event\n  ON tbl_name FOR EACH ROW\n [{ FOLLOWS | PRECEDES } other_trigger_name ]\n trigger_stmt;\n\nDescription\n-----------\n\nThis statement creates a new trigger. A trigger is a named database object\nthat is associated with a table, and that activates when a particular event\noccurs for the table. The trigger becomes associated with the table named\ntbl_name, which must refer to a permanent table. You cannot associate a\ntrigger with a TEMPORARY table or a view.\n\nCREATE TRIGGER requires the TRIGGER privilege for the table associated with\nthe trigger.\n\nMariaDB starting with 10.2.3\n----------------------------\nYou can have multiple triggers for the same trigger_time and trigger_event.\n\nFor valid identifiers to use as trigger names, see Identifier Names.\n\nOR REPLACE\n----------\n\nMariaDB starting with 10.1.4\n----------------------------\nIf used and the trigger already exists, instead of an error being returned,\nthe existing trigger will be dropped and replaced by the newly defined trigger.\n\nDEFINER\n-------\n\nThe DEFINER clause determines the security context to be used when checking\naccess privileges at trigger activation time. Usage requires the SUPER\nprivilege, or, from MariaDB 10.5.2, the SET USER privilege.\n\nIF NOT EXISTS\n-------------\n\nMariaDB starting with 10.1.4\n----------------------------\nIf the IF NOT EXISTS clause is used, the trigger will only be created if a\ntrigger of the same name does not exist. If the trigger already exists, by\ndefault a warning will be returned.\n\ntrigger_time\n------------\n\ntrigger_time is the trigger action time. It can be BEFORE or AFTER to indicate\nthat the trigger activates before or after each row to be modified.\n\ntrigger_event\n-------------\n\ntrigger_event indicates the kind of statement that activates the trigger. The\ntrigger_event can be one of the following:\n\n* INSERT: The trigger is activated whenever a new row is inserted into the\ntable; for example, through INSERT, LOAD DATA, and REPLACE statements.\n* UPDATE: The trigger is activated whenever a row is modified; for example,\nthrough UPDATE statements.\n* DELETE: The trigger is activated whenever a row is deleted from the table;\nfor example, through DELETE and REPLACE statements. However, DROP TABLE and\nTRUNCATE statements on the table do not activate this trigger, because they do\nnot use DELETE. Dropping a partition does not activate DELETE triggers, either.\n\nFOLLOWS/PRECEDES other_trigger_name\n-----------------------------------\n\nMariaDB starting with 10.2.3\n----------------------------\nThe FOLLOWS other_trigger_name and PRECEDES other_trigger_name options were\nadded in MariaDB 10.2.3 as part of supporting multiple triggers per action\ntime. This is the same syntax used by MySQL 5.7, although MySQL 5.7 does not\nhave multi-trigger support.\n\nFOLLOWS adds the new trigger after another trigger while PRECEDES adds the new\ntrigger before another trigger. If neither option is used, the new trigger is\nadded last for the given action and time.\n\nFOLLOWS and PRECEDES are not stored in the trigger definition. However the\ntrigger order is guaranteed to not change over time. mariadb-dump/mysqldump\nand other backup methods will not change trigger order. You can verify the\ntrigger order from the ACTION_ORDER column in INFORMATION_SCHEMA.TRIGGERS\ntable.\n\nSELECT trigger_name, action_order FROM information_schema.triggers \n WHERE event_object_table=\'t1\';\n\nAtomic DDL\n----------\n\nMariaDB starting with 10.6.1\n----------------------------\nMariaDB 10.6.1 supports Atomic DDL and CREATE TRIGGER is atomic.\n\nExamples\n--------\n\nCREATE DEFINER=`root`@`localhost` TRIGGER increment_animal\n AFTER INSERT ON animals FOR EACH ROW\n UPDATE animal_count SET animal_count.animals = animal_count.animals+1;\n\nOR REPLACE and IF NOT EXISTS\n\nCREATE DEFINER=`root`@`localhost` TRIGGER increment_animal\n AFTER INSERT ON animals FOR EACH ROW\n  UPDATE animal_count SET animal_count.animals = animal_count.animals+1;\nERROR 1359 (HY000): Trigger already exists\n\nCREATE OR REPLACE DEFINER=`root`@`localhost` TRIGGER increment_animal\n AFTER INSERT ON animals  FOR EACH ROW\n  UPDATE animal_count SET animal_count.animals = animal_count.animals+1;\nQuery OK, 0 rows affected (0.12 sec)\n\nCREATE DEFINER=`root`@`localhost` TRIGGER IF NOT EXISTS increment_animal\n AFTER INSERT ON animals FOR EACH ROW\n  UPDATE animal_count SET animal_count.animals = animal_count.animals+1;\nQuery OK, 0 rows affected, 1 warning (0.00 sec)\n\nSHOW WARNINGS;\n+-------+------+------------------------+\n| Level | Code | Message                |\n+-------+------+------------------------+\n| Note  | 1359 | Trigger already exists |\n+-------+------+------------------------+\n1 row in set (0.00 sec)\n\nURL: https://mariadb.com/kb/en/create-trigger/','','https://mariadb.com/kb/en/create-trigger/'),(703,'CREATE VIEW',38,'Syntax\n------\n\nCREATE\n  [OR REPLACE]\n  [ALGORITHM = {UNDEFINED | MERGE | TEMPTABLE}]\n  [DEFINER = { user | CURRENT_USER | role | CURRENT_ROLE }]\n  [SQL SECURITY { DEFINER | INVOKER }]\n  VIEW [IF NOT EXISTS] view_name [(column_list)]\n  AS select_statement\n  [WITH [CASCADED | LOCAL] CHECK OPTION]\n\nDescription\n-----------\n\nThe CREATE VIEW statement creates a new view, or replaces an existing one if\nthe OR REPLACE clause is given. If the view does not exist, CREATE OR REPLACE\nVIEW is the same as CREATE VIEW. If the view does exist, CREATE OR REPLACE\nVIEW is the same as ALTER VIEW.\n\nThe select_statement is a SELECT statement that provides the definition of the\nview. (When you select from the view, you select in effect using the SELECT\nstatement.) select_statement can select from base tables or other views.\n\nThe view definition is \"frozen\" at creation time, so changes to the underlying\ntables afterwards do not affect the view definition. For example, if a view is\ndefined as SELECT * on a table, new columns added to the table later do not\nbecome part of the view. A SHOW CREATE VIEW shows that such queries are\nrewritten and column names are included in the view definition.\n\nThe view definition must be a query that does not return errors at view\ncreation times. However, the base tables used by the views might be altered\nlater and the query may not be valid anymore. In this case, querying the view\nwill result in an error. CHECK TABLE helps in finding this kind of problems.\n\nThe ALGORITHM clause affects how MariaDB processes the view. The DEFINER and\nSQL SECURITY clauses specify the security context to be used when checking\naccess privileges at view invocation time. The WITH CHECK OPTION clause can be\ngiven to constrain inserts or updates to rows in tables referenced by the\nview. These clauses are described later in this section.\n\nThe CREATE VIEW statement requires the CREATE VIEW privilege for the view, and\nsome privilege for each column selected by the SELECT statement. For columns\nused elsewhere in the SELECT statement you must have the SELECT privilege. If\nthe OR REPLACE clause is present, you must also have the DROP privilege for\nthe view.\n\nA view belongs to a database. By default, a new view is created in the default\ndatabase. To create the view explicitly in a given database, specify the name\nas db_name.view_name when you create it.\n\nCREATE VIEW test.v AS SELECT * FROM t;\n\nBase tables and views share the same namespace within a database, so a\ndatabase cannot contain a base table and a view that have the same name.\n\nViews must have unique column names with no duplicates, just like base tables.\nBy default, the names of the columns retrieved by the SELECT statement are\nused for the view column names. To define explicit names for the view columns,\nthe optional column_list clause can be given as a list of comma-separated\nidentifiers. The number of names in column_list must be the same as the number\nof columns retrieved by the SELECT statement.\n\nMySQL until 5.1.28\n------------------\nPrior to MySQL 5.1.29, When you modify an existing view, the current view\ndefinition is backed up and saved. It is stored in that table\'s database\ndirectory, in a subdirectory named arc. The backup file for a view v is named\nv.frm-00001. If you alter the view again, the next backup is named\nv.frm-00002. The three latest view backup definitions are stored. Backed up\nview definitions are not preserved by mysqldump, or any other such programs,\nbut you can retain them using a file copy operation. However, they are not\nneeded for anything but to provide you with a backup of your previous view\ndefinition. It is safe to remove these backup definitions, but only while\nmysqld is not running. If you delete the arc subdirectory or its files while\nmysqld is running, you will receive an error the next time you try to alter\nthe view:\n\nMariaDB [test]> ALTER VIEW v AS SELECT * FROM t; \nERROR 6 (HY000): Error on delete of \'.\\test\\arc/v.frm-0004\' (Errcode: 2)\n\nColumns retrieved by the SELECT statement can be simple references to table\ncolumns. They can also be expressions that use functions, constant values,\noperators, and so forth.\n\nUnqualified table or view names in the SELECT statement are interpreted with\nrespect to the default database. A view can refer to tables or views in other\ndatabases by qualifying the table or view name with the proper database name.\n\nA view can be created from many kinds of SELECT statements. It can refer to\nbase tables or other views. It can use joins, UNION, and subqueries. The\nSELECT need not even refer to any tables. The following example defines a view\nthat selects two columns from another table, as well as an expression\ncalculated from those columns:\n\nCREATE TABLE t (qty INT, price INT);\n\nINSERT INTO t VALUES(3, 50);\n\nCREATE VIEW v AS SELECT qty, price, qty*price AS value FROM t;\n\nSELECT * FROM v;\n+------+-------+-------+\n| qty  | price | value |\n+------+-------+-------+\n|    3 |    50 |   150 |\n+------+-------+-------+\n\nA view definition is subject to the following restrictions:\n\n* The SELECT statement cannot contain a subquery in the FROM clause.\n* The SELECT statement cannot refer to system or user variables.\n* Within a stored program, the definition cannot refer to program parameters\nor local variables.\n* The SELECT statement cannot refer to prepared statement parameters.\n* Any table or view referred to in the definition must exist. However, after a\nview has been created, it is possible to drop a table or view that the\ndefinition refers to. In this case, use of the view results in an error. To\ncheck a view definition for problems of this kind, use the CHECK TABLE\nstatement.\n* The definition cannot refer to a TEMPORARY table, and you cannot create a\nTEMPORARY view.\n* Any tables named in the view definition must exist at definition time.\n* You cannot associate a trigger with a view.\n* For valid identifiers to use as view names, see Identifier Names.\n\nORDER BY is allowed in a view definition, but it is ignored if you select from\na view using a statement that has its own ORDER BY.\n\nFor other options or clauses in the definition, they are added to the options\nor clauses of the statement that references the view, but the effect is\nundefined. For example, if a view definition includes a LIMIT clause, and you\nselect from the view using a statement that has its own LIMIT clause, it is\nundefined which limit applies. This same principle applies to options such as\nALL, DISTINCT, or SQL_SMALL_RESULT that follow the SELECT keyword, and to\nclauses such as INTO, FOR UPDATE, and LOCK IN SHARE MODE.\n\nThe PROCEDURE clause cannot be used in a view definition, and it cannot be\nused if a view is referenced in the FROM clause.\n\nIf you create a view and then change the query processing environment by\nchanging system variables, that may affect the results that you get from the\nview:\n\nCREATE VIEW v (mycol) AS SELECT \'abc\';\n\nSET sql_mode = \'\';\n\nSELECT \"mycol\" FROM v;\n+-------+\n| mycol |\n+-------+\n| mycol | \n+-------+\n\nSET sql_mode = \'ANSI_QUOTES\';\n\nSELECT \"mycol\" FROM v;\n+-------+\n| mycol |\n+-------+\n| abc   | \n+-------+\n\nThe DEFINER and SQL SECURITY clauses determine which MariaDB account to use\nwhen checking access privileges for the view when a statement is executed that\nreferences the view. They were added in MySQL 5.1.2. The legal 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 view,\nrespectively. The default SQL SECURITY value is DEFINER.\n\nIf a user value is given for the DEFINER clause, it should be a MariaDB\naccount in \'user_name\'@\'host_name\' format (the same format used in the GRANT\nstatement). The user_name and host_name values both are required. The definer\ncan also be given as CURRENT_USER or CURRENT_USER(). The default DEFINER value\nis the user who executes the CREATE VIEW statement. This is the same as\nspecifying DEFINER = CURRENT_USER explicitly.\n\nIf you specify the DEFINER clause, these rules determine the legal DEFINER\nuser values:\n\n* If you do not have the SUPER privilege, or, from MariaDB 10.5.2, the SET\nUSER privilege, the only legal user value is your own account, either\nspecified literally or by using CURRENT_USER. You cannot set the definer to\nsome other account.\n* If you have the SUPER privilege, or, from MariaDB 10.5.2, the SET USER\nprivilege, you can specify any syntactically legal account name. If the\naccount does not actually exist, a warning is generated.\n* If the SQL SECURITY value is DEFINER but the definer account does not exist\nwhen the view is referenced, an error occurs.\n\nWithin a view definition, CURRENT_USER returns the view\'s DEFINER value by\ndefault. For views defined with the SQL SECURITY INVOKER characteristic,\nCURRENT_USER returns the account for the view\'s invoker. For information about\nuser auditing within views, see\nhttp://dev.mysql.com/doc/refman/5.1/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 also\naffects a view defined within such a program, if the view definition contains\na DEFINER value of CURRENT_USER.\n\nView privileges are checked like this:\n\n* At view definition time, the view creator must have the privileges needed to\nuse the top-level objects accessed by the view. For example, if the view\ndefinition refers to table columns, the creator must have privileges for the\ncolumns, as described previously. If the definition refers to a stored\nfunction, only the privileges needed to invoke the function can be checked.\nThe privileges required when the function runs can be checked only as it\nexecutes: For different invocations of the function, different execution paths\nwithin the function might be taken.\n* When a view is referenced, privileges for objects accessed by the view are\nchecked against the privileges held by the view creator or invoker, depending\non whether the SQL SECURITY characteristic is DEFINER or INVOKER, respectively.\n* If reference to a view causes execution of a stored function, privilege\nchecking for statements executed within the function depend on whether the\nfunction is defined with a SQL SECURITY characteristic of DEFINER or INVOKER.\nIf the security characteristic is DEFINER, the function runs with the\nprivileges of its creator. If the characteristic is INVOKER, the function runs\nwith the privileges determined by the view\'s SQL SECURITY characteristic.\n\nExample: A view might depend on a stored function, and that function might\ninvoke other stored routines. For example, the following view invokes a stored\nfunction 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 checked\nwhen f() executes. This might mean that privileges are needed for p1() or\np2(), depending on the execution path within f(). Those privileges must be\nchecked at runtime, and the user who must possess the privileges is determined\nby the SQL SECURITY values of the view v and the function f().\n\nThe DEFINER and SQL SECURITY clauses for views are extensions to standard SQL.\nIn standard SQL, views are handled using the rules for SQL SECURITY INVOKER.\n\nIf you invoke a view that was created before MySQL 5.1.2, it is treated as\nthough it was created with a SQL SECURITY DEFINER clause and with a DEFINER\nvalue that is the same as your account. However, because the actual definer is\nunknown, MySQL issues a warning. To make the warning go away, it is sufficient\nto re-create the view so that the view definition includes a DEFINER clause.\n\nThe optional ALGORITHM clause is an extension to standard SQL. It affects how\nMariaDB processes the view. ALGORITHM takes three values: MERGE, TEMPTABLE, or\nUNDEFINED. The default algorithm is UNDEFINED if no ALGORITHM clause is\npresent. See View Algorithms for more information.\n\nSome views are updatable. That is, you can use them in statements such as\nUPDATE, DELETE, or INSERT to update the contents of the underlying table. For\na view to be updatable, there must be a one-to-one relationship between the\nrows in the view and the rows in the underlying table. There are also certain\nother constructs that make a view non-updatable. See Inserting and Updating\nwith Views.\n\nWITH CHECK OPTION\n-----------------\n\nThe WITH CHECK OPTION clause can be given for an updatable view to prevent\ninserts or updates to rows except those for which the WHERE clause in the\nselect_statement is true.\n\nIn a WITH CHECK OPTION clause for an updatable view, the LOCAL and CASCADED\nkeywords determine the scope of check testing when the view is defined in\nterms of another view. The LOCAL keyword restricts the CHECK OPTION only to\nthe view being defined. CASCADED causes the checks for underlying views to be\nevaluated as well. When neither keyword is given, the default is CASCADED.\n\nFor more information about updatable views and the WITH CHECK OPTION clause,\nsee Inserting and Updating with Views.\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 view already exists. Cannot be used together with\nthe OR REPLACE clause.\n\nAtomic DDL\n----------\n\nMariaDB starting with 10.6.1\n----------------------------\nMariaDB 10.6.1 supports Atomic DDL and CREATE VIEW is atomic.\n\nExamples\n--------\n\nCREATE TABLE t (a INT, b INT) ENGINE = InnoDB;\n\nINSERT INTO t VALUES (1,1), (2,2), (3,3);\n\nCREATE VIEW v AS SELECT a, a*2 AS a2 FROM t;\n\nSELECT * FROM v;\n+------+------+\n| a    | a2   |\n+------+------+\n|    1 |    2 |\n|    2 |    4 |\n|    3 |    6 |\n+------+------+\n\nOR REPLACE and IF NOT EXISTS:\n\nCREATE VIEW v AS SELECT a, a*2 AS a2 FROM t;\nERROR 1050 (42S01): Table \'v\' already exists\n\nCREATE OR REPLACE VIEW v AS SELECT a, a*2 AS a2 FROM t;\nQuery OK, 0 rows affected (0.04 sec)\n\nCREATE VIEW IF NOT EXISTS v AS SELECT a, a*2 AS a2 FROM t;\nQuery OK, 0 rows affected, 1 warning (0.01 sec)\n\nSHOW WARNINGS;\n+-------+------+--------------------------+\n| Level | Code | Message                  |\n+-------+------+--------------------------+\n| Note  | 1050 | Table \'v\' already exists |\n+-------+------+--------------------------+\n\nURL: https://mariadb.com/kb/en/create-view/','','https://mariadb.com/kb/en/create-view/'),(704,'Generated (Virtual and Persistent/Stored) Columns',38,'Syntax\n------\n\n<type>  [GENERATED ALWAYS]  AS   ( <expression> )\n[VIRTUAL | PERSISTENT | STORED]  [UNIQUE] [UNIQUE KEY] [COMMENT <text>]\n\nMariaDB\'s generated columns syntax is designed to be similar to the syntax for\nMicrosoft SQL Server\'s computed columns and Oracle Database\'s virtual columns.\nIn MariaDB 10.2 and later, the syntax is also compatible with the syntax for\nMySQL\'s generated columns.\n\nDescription\n-----------\n\nA generated column is a column in a table that cannot explicitly be set to a\nspecific value in a DML query. Instead, its value is automatically generated\nbased on an expression. This expression might generate the value based on the\nvalues of other columns in the table, or it might generate the value by\ncalling built-in functions or user-defined functions (UDFs).\n\nThere are two types of generated columns:\n\n* PERSISTENT (a.k.a. STORED): This type\'s value is actually stored in the\ntable.\n* VIRTUAL: This type\'s value is not stored at all. Instead, the value is\ngenerated dynamically when the table is queried. This type is the default.\n\nGenerated columns are also sometimes called computed columns or virtual\ncolumns.\n\nSupported Features\n------------------\n\nStorage Engine Support\n----------------------\n\n* Generated columns can only be used with storage engines which support them.\nIf you try to use a storage engine that does not support them, then you will\nsee an error similar to the following:\n\nERROR 1910 (HY000): TokuDB storage engine does not support computed columns\n\n* InnoDB, Aria, MyISAM and CONNECT support generated columns.\n\n* A column in a MERGE table can be built on a PERSISTENT generated column.\nHowever, a column in a MERGE table can not be defined as a VIRTUAL and\nPERSISTENT generated column.\n\nData Type Support\n-----------------\n\n* All data types are supported when defining generated columns.\n\n* Using the ZEROFILL column option is supported when defining generated\ncolumns.\n\n* Using the AUTO_INCREMENT column option is not supported when defining\ngenerated columns. Until MariaDB 10.2.25, it was supported, but this support\nwas removed, because it would not work correctly. See MDEV-11117.\n\nIndex Support\n-------------\n\n* Using a generated column as a table\'s primary key is not supported. See\nMDEV-5590 for more information. If you try to use one as a primary key, then\nyou will see an error similar to the following:\n\nERROR 1903 (HY000): Primary key cannot be defined upon a computed column\n\n* Using PERSISTENT generated columns as part of a foreign key is supported.\n\n* Referencing PERSISTENT generated columns as part of a foreign key is also\nsupported.\nHowever, using the ON UPDATE CASCADE, ON UPDATE SET NULL, or ON DELETE SET\nNULL clauses is not supported. If you try to use an unsupported clause, then\nyou will see an error similar to the following:\n\nERROR 1905 (HY000): Cannot define foreign key with ON UPDATE SET NULL clause\non a computed column\n\n* Defining indexes on both VIRTUAL and PERSISTENT generated columns is\nsupported.\nIf an index is defined on a generated column, then the optimizer considers\nusing it in the same way as indexes based on \"real\" columns.\n\nStatement Support\n-----------------\n\n* Generated columns are used in DML queries just as if they were \"real\"\ncolumns.\nHowever, VIRTUAL and PERSISTENT generated columns differ in how their data is\nstored.\nValues for PERSISTENT generated columns are generated whenever a DML queries\ninserts or updates the row with the special DEFAULT value. This generates the\ncolumns value, and it is stored in the table like the other \"real\" columns.\nThis value can be read by other DML queries just like the other \"real\" columns.\nValues for VIRTUAL generated columns are not stored in the table. Instead, the\nvalue is generated dynamically whenever the column is queried. If other\ncolumns in a row are queried, but the VIRTUAL generated column is not one of\nthe queried columns, then the column\'s value is not generated.\n\n* The SELECT statement supports generated columns.\n\n* Generated columns can be referenced in the INSERT, UPDATE, and DELETE\nstatements.\nHowever, VIRTUAL or PERSISTENT generated columns cannot be explicitly set to\nany other values than NULL or DEFAULT. If a generated column is explicitly set\nto any other value, then the outcome depends on whether strict mode is enabled\nin sql_mode. If it is not enabled, then a warning will be raised and the\ndefault generated value will be used instead. If it is enabled, then an error\nwill be raised instead.\n\n* The CREATE TABLE statement has limited support for generated columns.\nIt supports defining generated columns in a new table.\nIt supports using generated columns to partition tables.\nIt does not support using the versioning clauses with generated columns.\n\n* The ALTER TABLE statement has limited support for generated columns.\nIt supports the MODIFY and CHANGE clauses for PERSISTENT generated columns.\nIt does not support the MODIFY clause for VIRTUAL generated columns if\nALGORITHM is not set to COPY. See MDEV-15476 for more information.\nIt does not support the  CHANGE clause for VIRTUAL generated columns if\nALGORITHM is not set to COPY. See MDEV-17035 for more information.\nIt does not support altering a table if ALGORITHM is not set to COPY if the\ntable has a VIRTUAL generated column that is indexed. See MDEV-14046 for more\ninformation.\nIt does not support adding a VIRTUAL generated column with the ADD clause if\nthe same statement is also adding other columns if ALGORITHM is not set to\nCOPY. See MDEV-17468 for more information.\nIt also does not support altering an existing column into a VIRTUAL generated\ncolumn.\nIt supports using generated columns to partition tables.\nIt does not support using the versioning clauses with generated columns.\n\n* The SHOW CREATE TABLE statement supports generated columns.\n\n* The DESCRIBE statement can be used to check whether a table has generated\ncolumns.\nYou can tell which columns are generated by looking for the ones where the\nExtra column is set to either VIRTUAL or PERSISTENT. For example:\n\nDESCRIBE table1;\n+-------+-------------+------+-----+---------+------------+\n| Field | Type        | Null | Key | Default | Extra      |\n+-------+-------------+------+-----+---------+------------+\n| a     | int(11)     | NO   |     | NULL    |            |\n| b     | varchar(32) | YES  |     | NULL    |            |\n| c     | int(11)     | YES  |     | NULL    | VIRTUAL    |\n| d     | varchar(5)  | YES  |     | NULL    | PERSISTENT |\n+-------+-------------+------+-----+---------+------------+\n\n* Generated columns can be properly referenced in the NEW and OLD rows in\ntriggers.\n\n* Stored procedures support generated columns.\n\n* The HANDLER statement supports generated columns.\n\nExpression Support\n------------------\n\n* Most legal, deterministic expressions which can be calculated are supported\nin expressions for generated columns.\n\n* Most built-in functions are supported in expressions for generated columns.\nHowever, some built-in functions can\'t be supported for technical reasons. For\nexample,  If you try to use an unsupported function in an expression, an error\nis generated similar to the following:\n\nERROR 1901 (HY000): Function or expression \'dayname()\' cannot be used in the\nGENERATED ALWAYS AS clause of `v`\n\n* Subqueries are not supported in expressions for generated columns because\nthe underlying data can change.\n\n* Using anything that depends on data outside the row is not supported in\nexpressions for generated columns.\n\n* Stored functions are not supported in expressions for generated columns. See\nMDEV-17587 for more information.\n\n* Non-deterministic built-in functions are supported in expressions for not\nindexed VIRTUAL generated columns.\n\n* Non-deterministic built-in functions are not supported in expressions for\nPERSISTENT or indexed VIRTUAL generated columns.\n\n* User-defined functions (UDFs) are supported in expressions for generated\ncolumns.\nHowever, MariaDB can\'t check whether a UDF is deterministic, so it is up to\nthe user to be sure that they do not use non-deterministic UDFs with VIRTUAL\ngenerated columns.\n\n* Defining a generated column based on other generated columns defined before\nit in the table definition is supported. For example:\n\nCREATE TABLE t1 (a int as (1), b int as (a));\n\n* However, defining a generated column based on other generated columns\ndefined after in the table definition is not supported in expressions for\ngeneration columns because generated columns are calculated in the order they\nare defined.\n\n* Using an expression that exceeds 255 characters in length is supported in\nexpressions for generated columns. The new limit for the entire table\ndefinition, including all expressions for generated columns, is 65,535 bytes.\n\n* Using constant expressions is supported in expressions for generated\ncolumns. For example:\n\nCREATE TABLE t1 (a int as (1));\n\nMaking Stored Values Consistent\n-------------------------------\n\nWhen a generated column is PERSISTENT or indexed, the value of the expression\nneeds to be consistent regardless of the SQL Mode flags in the current\nsession. If it is not, then the table will be seen as corrupted when the value\nthat should actually be returned by the computed expression and the value that\nwas previously stored and/or indexed using a different sql_mode setting\ndisagree.\n\nThere are currently two affected classes of inconsistencies: character padding\nand unsigned subtraction:\n\n* For a VARCHAR or TEXT generated column the length of the value returned can\nvary depending on the PAD_CHAR_TO_FULL_LENGTH sql_mode flag.  To make the\nvalue consistent, create the generated column using an RTRIM() or RPAD()\nfunction.  Alternately, create the generated column as a CHAR column so that\nits data is always fully padded.\n\n* If a SIGNED generated column is based on the subtraction of an UNSIGNED\nvalue, the resulting value can vary depending on how large the value is and\nthe NO_UNSIGNED_SUBTRACTION sql_mode flag.  To make the value consistent, use\nCAST() to ensure that each UNSIGNED operand is SIGNED before the subtraction.\n\nMariaDB starting with 10.5\n--------------------------\nBeginning in MariaDB 10.5, there is a fatal error generated when trying to\ncreate a generated column whose value can change depending on the SQL Mode\nwhen its data is PERSISTENT or indexed.\n\nFor an existing generated column that has a potentially inconsistent value, a\nwarning about a bad expression is generated the first time it is used (if\nwarnings are enabled).\n\nBeginning in MariaDB 10.4.8, MariaDB 10.3.18, and MariaDB 10.2.27 a\npotentially inconsistent generated column outputs a warning when created or\nfirst used (without restricting their creation).\n\nHere is an example of two tables that would be rejected in MariaDB 10.5 and\nwarned about in the other listed versions:\n\nCREATE TABLE bad_pad (\n txt CHAR(5),\n -- CHAR -> VARCHAR or CHAR -> TEXT can\'t be persistent or indexed:\n vtxt VARCHAR(5) AS (txt) PERSISTENT\n);\n\nCREATE TABLE bad_sub (\n num1 BIGINT UNSIGNED,\n num2 BIGINT UNSIGNED,\n -- The resulting value can vary for some large values\n vnum BIGINT AS (num1 - num2) VIRTUAL,\n KEY(vnum)\n);\n\nThe warnings for the above tables look like this:\n\nWarning (Code 1901): Function or expression \'`txt`\' cannot be used in the\nGENERATED ALWAYS AS clause of `vtxt`\nWarning (Code 1105): Expression depends on the @@sql_mode value\nPAD_CHAR_TO_FULL_LENGTH\n\nWarning (Code 1901): Function or expression \'`num1` - `num2`\' cannot be used\nin the GENERATED ALWAYS AS clause of `vnum`\nWarning (Code 1105): Expression depends on the @@sql_mode value\nNO_UNSIGNED_SUBTRACTION\n\nTo work around the issue, force the padding or type to make the generated\ncolumn\'s expression return a consistent value. For example:\n\nCREATE TABLE good_pad (\n txt CHAR(5),\n -- Using RTRIM() or RPAD() makes the value consistent:\n vtxt VARCHAR(5) AS (RTRIM(txt)) PERSISTENT,\n -- When not persistent or indexed, it is OK for the value to vary by mode:\n vtxt2 VARCHAR(5) AS (txt) VIRTUAL,\n -- CHAR -> CHAR is always OK:\n txt2 CHAR(5) AS (txt) PERSISTENT\n);\n\nCREATE TABLE good_sub (\n num1 BIGINT UNSIGNED,\n num2 BIGINT UNSIGNED,\n -- The indexed value will always be consistent in this expression:\n vnum BIGINT AS (CAST(num1 AS SIGNED) - CAST(num2 AS SIGNED)) VIRTUAL,\n KEY(vnum)\n);\n\nMySQL Compatibility Support\n---------------------------\n\n* The STORED keyword is supported as an alias for the PERSISTENT keyword.\n\n* Tables created with MySQL 5.7 or later that contain MySQL\'s generated\ncolumns can be imported into MariaDB without a dump and restore.\n\nImplementation Differences\n--------------------------\n\nGenerated columns are subject to various constraints in other DBMSs that are\nnot present in MariaDB\'s implementation. Generated columns may also be called\ncomputed columns or virtual columns in different implementations. The various\ndetails for a specific implementation can be found in the documentation for\neach specific DBMS.\n\nImplementation Differences Compared to Microsoft SQL Server\n-----------------------------------------------------------\n\nMariaDB\'s generated columns implementation does not enforce the following\nrestrictions that are present in Microsoft SQL Server\'s computed columns\nimplementation:\n\n* MariaDB allows server variables in generated column expressions, including\nthose that change dynamically, such as warning_count.\n* MariaDB allows the CONVERT_TZ() function to be called with a named time zone\nas an argument, even though time zone names and time offsets are configurable.\n* MariaDB allows the CAST() function to be used with non-unicode character\nsets, even though character sets are configurable and differ between\nbinaries/versions.\n* MariaDB allows FLOAT expressions to be used in generated columns. Microsoft\nSQL Server considers these expressions to be \"imprecise\" due to potential\ncross-platform differences in floating-point implementations and precision.\n* Microsoft SQL Server requires the ARITHABORT mode to be set, so that\ndivision by zero returns an error, and not a NULL.\n* Microsoft SQL Server requires QUOTED_IDENTIFIER to be set in sql_mode. In\nMariaDB, if data is inserted without ANSI_QUOTES set in sql_mode, then it will\nbe processed and stored differently in a generated column that contains quoted\nidentifiers.\n\nMicrosoft SQL Server enforces the above restrictions by doing one of the\nfollowing things:\n\n* Refusing to create computed columns.\n* Refusing to allow updates to a table containing them.\n* Refusing to use an index over such a column if it can not be guaranteed that\nthe expression is fully deterministic.\n\nIn MariaDB, as long as the sql_mode, language, and other settings that were in\neffect during the CREATE TABLE remain unchanged, the generated column\nexpression will always be evaluated the same. If any of these things change,\nthen please be aware that the generated column expression might not be\nevaluated the same way as it previously was.\n\nIf you try to update a virtual column, you will get an error if the default\nstrict mode is enabled in sql_mode, or a warning otherwise.\n\nDevelopment History\n-------------------\n\nGenerated columns was originally developed by Andrey Zhakov. It was then\nmodified by Sanja Byelkin and Igor Babaev at Monty Program for inclusion in\nMariaDB. Monty did the work on MariaDB 10.2 to lift a some of the old\nlimitations.\n\nExamples\n--------\n\nHere is an example table that uses both VIRTUAL and PERSISTENT virtual columns:\n\nUSE TEST;\n\nCREATE TABLE table1 (\n  a INT NOT NULL,\n  b VARCHAR(32),\n  c INT AS (a mod 10) VIRTUAL,\n  d VARCHAR(5) AS (left(b,5)) PERSISTENT);\n\nIf you describe the table, you can easily see which columns are virtual by\nlooking in the \"Extra\" column:\n\nDESCRIBE table1;\n+-------+-------------+------+-----+---------+------------+\n| Field | Type        | Null | Key | Default | Extra      |\n+-------+-------------+------+-----+---------+------------+\n| a     | int(11)     | NO   |     | NULL    |            |\n| b     | varchar(32) | YES  |     | NULL    |            |\n| c     | int(11)     | YES  |     | NULL    | VIRTUAL    |\n| d     | varchar(5)  | YES  |     | NULL    | PERSISTENT |\n+-------+-------------+------+-----+---------+------------+\n\nTo find out what function(s) generate the value of the virtual column you can\nuse SHOW CREATE TABLE:\n\nSHOW CREATE TABLE table1;\n\n| table1 | CREATE TABLE `table1` (\n `a` int(11) NOT NULL,\n `b` varchar(32) DEFAULT NULL,\n `c` int(11) AS (a mod 10) VIRTUAL,\n `d` varchar(5) AS (left(b,5)) PERSISTENT\n) ENGINE=MyISAM DEFAULT CHARSET=latin1 |\n\nIf you try to insert non-default values into a virtual column, you will\nreceive a warning and what you tried to insert will be ignored and the derived\nvalue inserted instead:\n\nWARNINGS;\nShow warnings enabled.\n\nINSERT INTO table1 VALUES (1, \'some text\',default,default);\nQuery OK, 1 row affected (0.00 sec)\n\nINSERT INTO table1 VALUES (2, \'more text\',5,default);\nQuery OK, 1 row affected, 1 warning (0.00 sec)\n\nWarning (Code 1645): The value specified for computed column \'c\' in table\n\'table1\' has been ignored.\n\nINSERT INTO table1 VALUES (123, \'even more text\',default,\'something\');\nQuery OK, 1 row affected, 2 warnings (0.00 sec)\n\nWarning (Code 1645): The value specified for computed column \'d\' in table\n\'table1\' has been ignored.\nWarning (Code 1265): Data truncated for column \'d\' at row 1\n\nSELECT * FROM table1;\n+-----+----------------+------+-------+\n| a   | b              | c    | d     |\n+-----+----------------+------+-------+\n|   1 | some text      |    1 | some  |\n|   2 | more text      |    2 | more  |\n| 123 | even more text |    3 | even  |\n+-----+----------------+------+-------+\n3 rows in set (0.00 sec)\n\nIf the ZEROFILL clause is specified, it should be placed directly after the\ntype definition, before the AS (<expression>):\n\nCREATE TABLE table2 (a INT, b INT ZEROFILL AS (a*2) VIRTUAL);\nINSERT INTO table2 (a) VALUES (1);\n\nSELECT * FROM table2;\n+------+------------+\n| a    | b          |\n+------+------------+\n|    1 | 0000000002 |\n+------+------------+\n1 row in set (0.00 sec)\n\nYou can also use virtual columns to implement a \"poor man\'s partial index\".\nSee example at the end of Unique Index.\n\nURL: https://mariadb.com/kb/en/generated-columns/','','https://mariadb.com/kb/en/generated-columns/'),(705,'Invisible Columns',38,'MariaDB starting with 10.3.3\n----------------------------\nInvisible columns (sometimes also called hidden columns) first appeared in\nMariaDB 10.3.3.\n\nColumns can be given an INVISIBLE attribute in a CREATE TABLE or ALTER TABLE\nstatement. These columns will then not be listed in the results of a SELECT *\nstatement, nor do they need to be assigned a value in an INSERT statement,\nunless INSERT explicitly mentions them by name.\n\nSince SELECT * does not return the invisible columns, new tables or views\ncreated in this manner will have no trace of the invisible columns. If\nspecifically referenced in the SELECT statement, the columns will be brought\ninto the view/new table, but the INVISIBLE attribute will not.\n\nInvisible columns can be declared as NOT NULL, but then require a DEFAULT\nvalue.\n\nIt is not possible for all columns in a table to be invisible.\n\nExamples\n--------\n\nCREATE TABLE t (x INT INVISIBLE);\nERROR 1113 (42000): A table must have at least 1 column\n\nCREATE TABLE t (x INT, y INT INVISIBLE, z INT INVISIBLE NOT NULL);\nERROR 4106 (HY000): Invisible column `z` must have a default value\n\nCREATE TABLE t (x INT, y INT INVISIBLE, z INT INVISIBLE NOT NULL DEFAULT 4);\n\nINSERT INTO t VALUES (1),(2);\n\nINSERT INTO t (x,y) VALUES (3,33);\n\nSELECT * FROM t;\n+------+\n| x    |\n+------+\n|    1 |\n|    2 |\n|    3 |\n+------+\n\nSELECT x,y,z FROM t;\n+------+------+---+\n| x    | y    | z |\n+------+------+---+\n|    1 | NULL | 4 |\n|    2 | NULL | 4 |\n|    3 |   33 | 4 |\n+------+------+---+\n\nDESC t;\n+-------+---------+------+-----+---------+-----------+\n| Field | Type    | Null | Key | Default | Extra     |\n+-------+---------+------+-----+---------+-----------+\n| x     | int(11) | YES  |     | NULL    |           |\n| y     | int(11) | YES  |     | NULL    | INVISIBLE |\n| z     | int(11) | NO   |     | 4       | INVISIBLE |\n+-------+---------+------+-----+---------+-----------+\n\nALTER TABLE t MODIFY x INT INVISIBLE, MODIFY y INT, MODIFY z INT NOT NULL\nDEFAULT 4;\n\nDESC t;\n+-------+---------+------+-----+---------+-----------+\n| Field | Type    | Null | Key | Default | Extra     |\n+-------+---------+------+-----+---------+-----------+\n| x     | int(11) | YES  |     | NULL    | INVISIBLE |\n| y     | int(11) | YES  |     | NULL    |           |\n| z     | int(11) | NO   |     | 4       |           |\n+-------+---------+------+-----+---------+-----------+\n\nCreating a view from a table with hidden columns:\n\nCREATE VIEW v1 AS SELECT * FROM t;\n\nDESC v1;\n+-------+---------+------+-----+---------+-------+\n| Field | Type    | Null | Key | Default | Extra |\n+-------+---------+------+-----+---------+-------+\n| y     | int(11) | YES  |     | NULL    |       |\n| z     | int(11) | NO   |     | 4       |       |\n+-------+---------+------+-----+---------+-------+\n\nCREATE VIEW v2 AS SELECT x,y,z FROM t;\n\nDESC v2;\n+-------+---------+------+-----+---------+-------+\n| Field | Type    | Null | Key | Default | Extra |\n+-------+---------+------+-----+---------+-------+\n| x     | int(11) | YES  |     | NULL    |       |\n| y     | int(11) | YES  |     | NULL    |       |\n| z     | int(11) | NO   |     | 4       |       |\n+-------+---------+------+-----+---------+-------+\n\nAdding a Surrogate Primary Key:\n\ncreate table t1 (x bigint unsigned not null, y varchar(16), z text);\n\ninsert into t1 values (123, \'qq11\', \'ipsum\');\n\ninsert into t1 values (123, \'qq22\', \'lorem\');\n\nalter table t1 add pkid serial primary key invisible first;\n\ninsert into t1 values (123, \'qq33\', \'amet\');\n\nselect * from t1;\n+-----+------+-------+\n| x   | y    | z     |\n+-----+------+-------+\n| 123 | qq11 | ipsum |\n| 123 | qq22 | lorem |\n| 123 | qq33 | amet  |\n+-----+------+-------+\n\nselect pkid, z from t1;\n+------+-------+\n| pkid | z     |\n+------+-------+\n|    1 | ipsum |\n|    2 | lorem |\n|    3 | amet  |\n+------+-------+\n\nURL: https://mariadb.com/kb/en/invisible-columns/','','https://mariadb.com/kb/en/invisible-columns/'),(706,'DROP DATABASE',38,'Syntax\n------\n\nDROP {DATABASE | SCHEMA} [IF EXISTS] db_name\n\nDescription\n-----------\n\nDROP DATABASE drops all tables in the database and deletes the database. Be\nvery careful with this statement! To use DROP DATABASE, you need the DROP\nprivilege on the database. DROP SCHEMA is a synonym for DROP DATABASE.\n\nImportant: When a database is dropped, user privileges on the database are not\nautomatically dropped. See GRANT.\n\nIF EXISTS\n---------\n\nUse IF EXISTS to prevent an error from occurring for databases that do not\nexist. A NOTE is generated for each non-existent database when using IF\nEXISTS. See SHOW WARNINGS.\n\nAtomic DDL\n----------\n\nMariaDB starting with 10.6.1\n----------------------------\nMariaDB 10.6.1 supports Atomic DDL.\n\nDROP DATABASE is implemented as\n\nloop over all tables\n DROP TABLE table\n\nEach individual DROP TABLE is atomic while DROP DATABASE as a whole is\ncrash-safe.\n\nExamples\n--------\n\nDROP DATABASE bufg;\nQuery OK, 0 rows affected (0.39 sec)\n\nDROP DATABASE bufg;\nERROR 1008 (HY000): Can\'t drop database \'bufg\'; database doesn\'t exist\n\n\\W\nShow warnings enabled.\n\nDROP DATABASE IF EXISTS bufg;\nQuery OK, 0 rows affected, 1 warning (0.00 sec)\nNote (Code 1008): Can\'t drop database \'bufg\'; database doesn\'t exist\n\nURL: https://mariadb.com/kb/en/drop-database/','','https://mariadb.com/kb/en/drop-database/'),(707,'DROP EVENT',38,'Syntax\n------\n\nDROP EVENT [IF EXISTS] event_name\n\nDescription\n-----------\n\nThis statement drops the event named event_name. The event immediately ceases\nbeing active, and is deleted completely from the server.\n\nIf the event does not exist, the error ERROR 1517 (HY000): Unknown event\n\'event_name\' results. You can override this and cause the statement to\ngenerate a NOTE for non-existent events instead by using IF EXISTS. See SHOW\nWARNINGS.\n\nThis statement requires the EVENT privilege. In MySQL 5.1.11 and earlier, an\nevent could be dropped only by its definer, or by a user having the SUPER\nprivilege.\n\nExamples\n--------\n\nDROP EVENT myevent3;\n\nUsing the IF EXISTS clause:\n\nDROP EVENT IF EXISTS myevent3;\nQuery OK, 0 rows affected, 1 warning (0.01 sec)\n\nSHOW WARNINGS;\n+-------+------+-------------------------------+\n| Level | Code | Message                       |\n+-------+------+-------------------------------+\n| Note  | 1305 | Event myevent3 does not exist |\n+-------+------+-------------------------------+\n\nURL: https://mariadb.com/kb/en/drop-event/','','https://mariadb.com/kb/en/drop-event/'),(708,'DROP FUNCTION',38,'Syntax\n------\n\nDROP FUNCTION [IF EXISTS] f_name\n\nDescription\n-----------\n\nThe DROP FUNCTION statement is used to drop a stored function or a\nuser-defined function (UDF). That is, the specified routine is removed from\nthe server, along with all privileges specific to the function. You must have\nthe ALTER ROUTINE privilege for the routine in order to drop it. If the\nautomatic_sp_privileges server system variable is set, both the ALTER ROUTINE\nand EXECUTE privileges are granted automatically to the routine creator - see\nStored Routine Privileges.\n\nIF EXISTS\n---------\n\nThe IF EXISTS clause is a MySQL/MariaDB extension. It prevents an error from\noccurring if the function does not exist. A NOTE is produced that can be\nviewed with SHOW WARNINGS.\n\nFor dropping a user-defined functions (UDF), see DROP FUNCTION UDF.\n\nExamples\n--------\n\nDROP FUNCTION hello;\nQuery OK, 0 rows affected (0.042 sec)\n\nDROP FUNCTION hello;\nERROR 1305 (42000): FUNCTION test.hello does not exist\n\nDROP FUNCTION IF EXISTS hello;\nQuery OK, 0 rows affected, 1 warning (0.000 sec)\n\nSHOW WARNINGS;\n+-------+------+------------------------------------+\n| Level | Code | Message                            |\n+-------+------+------------------------------------+\n| Note  | 1305 | FUNCTION test.hello does not exist |\n+-------+------+------------------------------------+\n\nURL: https://mariadb.com/kb/en/drop-function/','','https://mariadb.com/kb/en/drop-function/'),(709,'DROP INDEX',38,'Syntax\n------\n\nDROP INDEX [IF EXISTS] index_name ON tbl_name \n  [WAIT n |NOWAIT]\n\nDescription\n-----------\n\nDROP INDEX drops the index named index_name from the table tbl_name. This\nstatement is mapped to an ALTER TABLE statement to drop the index.\n\nIf another connection is using the table, a metadata lock is active, and this\nstatement will wait until the lock is released. This is also true for\nnon-transactional tables.\n\nSee ALTER TABLE.\n\nAnother shortcut, CREATE INDEX, allows the creation of an index.\n\nTo remove the primary key, `PRIMARY` must be specified as index_name. Note\nthat the quotes are necessary, because PRIMARY is a keyword.\n\nPrivileges\n----------\n\nExecuting the DROP INDEX statement requires the INDEX privilege for the table\nor the database.\n\nOnline DDL\n----------\n\nOnline DDL is used by default with InnoDB, when the drop index operation\nsupports it.\n\nSee InnoDB Online DDL Overview for more information on online DDL with InnoDB.\n\nDROP INDEX IF EXISTS ...\n------------------------\n\nIf the IF EXISTS clause is used, then MariaDB will return a warning instead of\nan error if the index does not exist.\n\nWAIT/NOWAIT\n-----------\n\nMariaDB starting with 10.3.0\n----------------------------\nSet the lock wait timeout. See WAIT and NOWAIT.\n\nProgress Reporting\n------------------\n\nMariaDB provides progress reporting for DROP INDEX statement for clients that\nsupport the new progress reporting protocol. For example, if you were using\nthe mysql client, then the progress report might look like this::\n\nURL: https://mariadb.com/kb/en/drop-index/','','https://mariadb.com/kb/en/drop-index/'),(710,'DROP PACKAGE',38,'MariaDB starting with 10.3.5\n----------------------------\nOracle-style packages were introduced in MariaDB 10.3.5.\n\nSyntax\n------\n\nDROP PACKAGE [IF EXISTS]  [ db_name . ] package_name\n\nDescription\n-----------\n\nThe DROP PACKAGE statement can be used when Oracle SQL_MODE is set.\n\nThe DROP PACKAGE statement drops a stored package entirely:\n\n* Drops the package specification (earlier created using the CREATE PACKAGE\nstatement).\n* Drops the package implementation, if the implementation was already created\nusing the CREATE PACKAGE BODY statement.\n\nURL: https://mariadb.com/kb/en/drop-package/','','https://mariadb.com/kb/en/drop-package/'),(711,'DROP PACKAGE BODY',38,'MariaDB starting with 10.3.5\n----------------------------\nOracle-style packages were introduced in MariaDB 10.3.5.\n\nSyntax\n------\n\nDROP PACKAGE BODY [IF EXISTS]  [ db_name . ] package_name\n\nDescription\n-----------\n\nThe DROP PACKAGE BODY statement can be used when Oracle SQL_MODE is set.\n\nThe DROP PACKAGE BODY statement drops the package body (i.e the\nimplementation), previously created using the CREATE PACKAGE BODY statement.\n\nNote, DROP PACKAGE BODY drops only the package implementation, but does not\ndrop the package specification. Use DROP PACKAGE to drop the package entirely\n(i.e. both implementation and specification).\n\nURL: https://mariadb.com/kb/en/drop-package-body/','','https://mariadb.com/kb/en/drop-package-body/'),(712,'DROP PROCEDURE',38,'Syntax\n------\n\nDROP PROCEDURE [IF EXISTS] sp_name\n\nDescription\n-----------\n\nThis statement is used to drop a stored procedure. That is, the specified\nroutine is removed from the server along with all privileges specific to the\nprocedure. You must have the ALTER ROUTINE privilege for the routine. If the\nautomatic_sp_privileges server system variable is set, that privilege and\nEXECUTE are granted automatically to the routine creator - see Stored Routine\nPrivileges.\n\nThe IF EXISTS clause is a MySQL/MariaDB extension. It prevents an error from\noccurring if the procedure or function does not exist. A NOTE is produced that\ncan be viewed with SHOW WARNINGS.\n\nWhile this statement takes effect immediately, threads which are executing a\nprocedure can continue execution.\n\nExamples\n--------\n\nDROP PROCEDURE simpleproc;\n\nIF EXISTS:\n\nDROP PROCEDURE simpleproc;\nERROR 1305 (42000): PROCEDURE test.simpleproc does not exist\n\nDROP PROCEDURE IF EXISTS simpleproc;\nQuery OK, 0 rows affected, 1 warning (0.00 sec)\n\nSHOW WARNINGS;\n+-------+------+------------------------------------------+\n| Level | Code | Message                                  |\n+-------+------+------------------------------------------+\n| Note  | 1305 | PROCEDURE test.simpleproc does not exist |\n+-------+------+------------------------------------------+\n\nURL: https://mariadb.com/kb/en/drop-procedure/','','https://mariadb.com/kb/en/drop-procedure/'),(713,'DROP SERVER',38,'Syntax\n------\n\nDROP SERVER [ IF EXISTS ] server_name\n\nDescription\n-----------\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 or, from MariaDB 10.5.2, the FEDERATED\nADMIN privilege.\n\nDropping a server for a table does not affect any FederatedX, FEDERATED,\nConnect or Spider tables that used this connection information when they were\ncreated.\n\nDROP SERVER is not written to the binary log, irrespective of the binary log\nformat being used. From MariaDB 10.1.13, Galera replicates the CREATE SERVER,\nALTER SERVER and DROP SERVER statements.\n\nIF EXISTS\n---------\n\nIf the IF EXISTS clause is used, MariaDB will not return an error if the\nserver does not exist. Unlike all other statements, DROP SERVER IF EXISTS does\nnot issue a note if the server does not exist. See MDEV-9400.\n\nExamples\n--------\n\nDROP SERVER s;\n\nIF EXISTS:\n\nDROP SERVER s;\nERROR 1477 (HY000): The foreign server name you are trying to reference \n does not exist. Data source error:  s\n\nDROP SERVER IF EXISTS s;\nQuery OK, 0 rows affected (0.00 sec)\n\nURL: https://mariadb.com/kb/en/drop-server/','','https://mariadb.com/kb/en/drop-server/'),(714,'DROP TABLESPACE',38,'The DROP TABLESPACE statement is not supported by MariaDB. It was originally\ninherited from MySQL NDB Cluster. In MySQL 5.7 and later, the statement is\nalso supported for InnoDB. However, MariaDB has chosen not to include that\nspecific feature. See MDEV-19294 for more information.\n\nURL: https://mariadb.com/kb/en/drop-tablespace/','','https://mariadb.com/kb/en/drop-tablespace/'),(715,'DROP TRIGGER',38,'Syntax\n------\n\nDROP TRIGGER [IF EXISTS] [schema_name.]trigger_name\n\nDescription\n-----------\n\nThis statement drops a trigger. The schema (database) name is optional. If the\nschema is omitted, the trigger is dropped from the default schema. Its use\nrequires the TRIGGER privilege for the table associated with the trigger.\n\nUse IF EXISTS to prevent an error from occurring for a trigger that does not\nexist. A NOTE is generated for a non-existent trigger when using IF EXISTS.\nSee SHOW WARNINGS.\n\nNote: Triggers for a table are also dropped if you drop the table.\n\nAtomic DDL\n----------\n\nMariaDB starting with 10.6.1\n----------------------------\nMariaDB 10.6.1 supports Atomic DDL and DROP TRIGGER is atomic.\n\nExamples\n--------\n\nDROP TRIGGER test.example_trigger;\n\nUsing the IF EXISTS clause:\n\nDROP TRIGGER IF EXISTS test.example_trigger;\nQuery OK, 0 rows affected, 1 warning (0.01 sec)\n\nSHOW WARNINGS;\n+-------+------+------------------------+\n| Level | Code | Message                |\n+-------+------+------------------------+\n| Note  | 1360 | Trigger does not exist |\n+-------+------+------------------------+\n\nURL: https://mariadb.com/kb/en/drop-trigger/','','https://mariadb.com/kb/en/drop-trigger/'),(716,'DROP VIEW',38,'Syntax\n------\n\nDROP VIEW [IF EXISTS]\n  view_name [, view_name] ...\n  [RESTRICT | CASCADE]\n\nDescription\n-----------\n\nDROP VIEW removes one or more views. You must have the DROP privilege for each\nview. If any of the views named in the argument list do not exist, MariaDB\nreturns an error indicating by name which non-existing views it was unable to\ndrop, but it also drops all of the views in the list that do exist.\n\nThe IF EXISTS clause prevents an error from occurring for views that don\'t\nexist. When this clause is given, a NOTE is generated for each non-existent\nview. See SHOW WARNINGS.\n\nRESTRICT and CASCADE, if given, are parsed and ignored.\n\nIt is possible to specify view names as db_name.view_name. This is useful to\ndelete views from multiple databases with one statement. See Identifier\nQualifiers for details.\n\nThe DROP privilege is required to use DROP TABLE on non-temporary tables. For\ntemporary tables, no privilege is required, because such tables are only\nvisible for the current session.\n\nIf a view references another view, it will be possible to drop the referenced\nview. However, the other view will reference a view which does not exist any\nmore. Thus, querying it will produce an error similar to the following:\n\nERROR 1356 (HY000): View \'db_name.view_name\' references invalid table(s) or \ncolumn(s) or function(s) or definer/invoker of view lack rights to use them\n\nThis problem is reported in the output of CHECK TABLE.\n\nNote that it is not necessary to use DROP VIEW to replace an existing view,\nbecause CREATE VIEW has an OR REPLACE clause.\n\nAtomic DDL\n----------\n\nMariaDB starting with 10.6.1\n----------------------------\nMariaDB 10.6.1 supports Atomic DDL and DROP VIEW for a singular view is\natomic. Dropping multiple views is crash-safe.\n\nExamples\n--------\n\nDROP VIEW v,v2;\n\nGiven views v and v2, but no view v3\n\nDROP VIEW v,v2,v3;\nERROR 1051 (42S02): Unknown table \'v3\'\n\nDROP VIEW IF EXISTS v,v2,v3;\nQuery OK, 0 rows affected, 1 warning (0.01 sec)\n\nSHOW WARNINGS;\n+-------+------+-------------------------+\n| Level | Code | Message                 |\n+-------+------+-------------------------+\n| Note  | 1051 | Unknown table \'test.v3\' |\n+-------+------+-------------------------+\n\nURL: https://mariadb.com/kb/en/drop-view/','','https://mariadb.com/kb/en/drop-view/'),(717,'CONSTRAINT',38,'MariaDB supports the implementation of constraints at the table-level using\neither CREATE TABLE or ALTER TABLE statements. A table constraint restricts\nthe data you can add to the table. If you attempt to insert invalid data on a\ncolumn, MariaDB throws an error.\n\nSyntax\n------\n\n[CONSTRAINT [symbol]] constraint_expression\n\nconstraint_expression:\n | PRIMARY KEY [index_type] (index_col_name, ...) [index_option] ...\n | FOREIGN KEY [index_name] (index_col_name, ...)\n   REFERENCES tbl_name (index_col_name, ...)\n   [ON DELETE reference_option]\n   [ON UPDATE reference_option]\n | UNIQUE [INDEX|KEY] [index_name]\n   [index_type] (index_col_name, ...) [index_option] ...\n | CHECK (check_constraints)\n\nindex_type:\n USING {BTREE | HASH | RTREE}\n\nindex_col_name:\n col_name [(length)] [ASC | DESC]\n\nindex_option:\n | KEY_BLOCK_SIZE [=] value\n | index_type\n | WITH PARSER parser_name\n | COMMENT \'string\'\n | CLUSTERING={YES|NO}\n\nreference_option:\n RESTRICT | CASCADE | SET NULL | NO ACTION | SET DEFAULT\n\nDescription\n-----------\n\nConstraints provide restrictions on the data you can add to a table. This\nallows you to enforce data integrity from MariaDB, rather than through\napplication logic. When a statement violates a constraint, MariaDB throws an\nerror.\n\nThere are four types of table constraints:\n\n+------------------------------------+---------------------------------------+\n| Constraint                         | Description                           |\n+------------------------------------+---------------------------------------+\n| PRIMARY KEY                        | Sets the column for referencing       |\n|                                    | rows.  Values must be unique and not  |\n|                                    | null.                                 |\n+------------------------------------+---------------------------------------+\n| FOREIGN KEY                        | Sets the column to reference the      |\n|                                    | primary key on another table.         |\n+------------------------------------+---------------------------------------+\n| UNIQUE                             | Requires values in column or columns  |\n|                                    | only occur once in the table.         |\n+------------------------------------+---------------------------------------+\n| CHECK                              | Checks whether the data meets the     |\n|                                    | given condition.                      |\n+------------------------------------+---------------------------------------+\n\nThe Information Schema TABLE_CONSTRAINTS Table contains information about\ntables that have constraints.\n\nFOREIGN KEY Constraints\n-----------------------\n\nInnoDB supports foreign key constraints. The syntax for a foreign key\nconstraint definition in InnoDB looks 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\nThe Information Schema REFERENTIAL_CONSTRAINTS table has more information\nabout foreign keys.\n\nCHECK Constraints\n-----------------\n\nMariaDB starting with 10.2.1\n----------------------------\nFrom MariaDB 10.2.1, constraints are enforced. Before MariaDB 10.2.1\nconstraint expressions were accepted in the syntax but ignored.\n\nIn MariaDB 10.2.1 you can define constraints in 2 different ways:\n\n* CHECK(expression) given as part of a column definition.\n* CONSTRAINT [constraint_name] CHECK (expression)\n\nBefore a row is inserted or updated, all constraints are evaluated in the\norder they are defined. If any constraint expression returns false, then the\nrow will not be inserted or updated. One can use most deterministic functions\nin a constraint, including UDFs.\n\nCREATE TABLE t1 (a INT CHECK (a>2), b INT CHECK (b>2), CONSTRAINT a_greater\nCHECK (a>b));\n\nIf you use the second format and you don\'t give a name to the constraint, then\nthe constraint will get an automatically generated name. This is done so that\nyou can later delete the constraint with ALTER TABLE DROP constraint_name.\n\nOne can disable all constraint expression checks by setting the\ncheck_constraint_checks variable to OFF. This is useful for example when\nloading a table that violates some constraints that you want to later find and\nfix in SQL.\n\nReplication\n-----------\n\nIn row-based replication, only the master checks constraints, and failed\nstatements will not be replicated. In statement-based replication, the slaves\nwill also check constraints. Constraints should therefore be identical, as\nwell as deterministic, in a replication environment.\n\nAuto_increment\n--------------\n\nMariaDB starting with 10.2.6\n----------------------------\n* From MariaDB 10.2.6, auto_increment columns are no longer permitted in check\nconstraints. Previously they were permitted, but would not work correctly. See\nMDEV-11117.\n\nExamples\n--------\n\nCREATE 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\nMariaDB starting with 10.2.1\n----------------------------\nThe following examples will work from MariaDB 10.2.1 onwards.\n\nNumeric constraints and comparisons:\n\nCREATE TABLE t1 (a INT CHECK (a>2), b INT CHECK (b>2), CONSTRAINT a_greater\nCHECK (a>b));\n\nINSERT INTO t1(a) VALUES (1);\nERROR 4022 (23000): CONSTRAINT `a` failed for `test`.`t1`\n\nINSERT INTO t1(a,b) VALUES (3,4);\nERROR 4022 (23000): CONSTRAINT `a_greater` failed for `test`.`t1`\n\nINSERT INTO t1(a,b) VALUES (4,3);\nQuery OK, 1 row affected (0.04 sec)\n\nDropping a constraint:\n\nALTER TABLE t1 DROP CONSTRAINT a_greater;\n\nAdding a constraint:\n\nALTER TABLE t1 ADD CONSTRAINT a_greater CHECK (a>b);\n\nDate comparisons and character length:\n\nCREATE TABLE t2 (name VARCHAR(30) CHECK (CHAR_LENGTH(name)>2), start_date\nDATE, \n end_date DATE CHECK (start_date IS NULL OR end_date IS NULL OR\nstart_date<end_date));\n\nINSERT INTO t2(name, start_date, end_date) VALUES(\'Ione\', \'2003-12-15\',\n\'2014-11-09\');\nQuery OK, 1 row affected (0.04 sec)\n\nINSERT INTO t2(name, start_date, end_date) VALUES(\'Io\', \'2003-12-15\',\n\'2014-11-09\');\nERROR 4022 (23000): CONSTRAINT `name` failed for `test`.`t2`\n\nINSERT INTO t2(name, start_date, end_date) VALUES(\'Ione\', NULL, \'2014-11-09\');\nQuery OK, 1 row affected (0.04 sec)\n\nINSERT INTO t2(name, start_date, end_date) VALUES(\'Ione\', \'2015-12-15\',\n\'2014-11-09\');\nERROR 4022 (23000): CONSTRAINT `end_date` failed for `test`.`t2`\n\nA misplaced parenthesis:\n\nCREATE TABLE t3 (name VARCHAR(30) CHECK (CHAR_LENGTH(name>2)), start_date\nDATE, \n end_date DATE CHECK (start_date IS NULL OR end_date IS NULL OR\nstart_date<end_date));\nQuery OK, 0 rows affected (0.32 sec)\n\nINSERT INTO t3(name, start_date, end_date) VALUES(\'Io\', \'2003-12-15\',\n\'2014-11-09\');\nQuery OK, 1 row affected, 1 warning (0.04 sec)\n\nSHOW WARNINGS;\n+---------+------+----------------------------------------+\n| Level   | Code | Message                                |\n+---------+------+----------------------------------------+\n| Warning | 1292 | Truncated incorrect DOUBLE value: \'Io\' |\n+---------+------+----------------------------------------+\n\nCompare the definition of table t2 to table t3. CHAR_LENGTH(name)>2 is very\ndifferent to CHAR_LENGTH(name>2) as the latter mistakenly performs a numeric\ncomparison on the name field, leading to unexpected results.\n\nURL: https://mariadb.com/kb/en/constraint/','','https://mariadb.com/kb/en/constraint/'),(718,'Dynamic Columns',38,'Dynamic columns allow one to store different sets of columns for each row in a\ntable. It works by storing a set of columns in a blob and having a small set\nof functions to manipulate it. Dynamic columns should be used when it is not\npossible to use regular columns. A typical use case is when one needs to store\nitems that may have many different attributes (like size, color, weight, etc),\nand the set of possible attributes is very large and/or unknown in advance. In\nthat case, attributes can be put into dynamic columns.\n\nDynamic Columns Basics\n----------------------\n\nThe table should have a blob column which will be used as storage for dynamic\ncolumns:\n\ncreate table assets (\n item_name varchar(32) primary key, -- A common attribute for all items\n dynamic_cols  blob  -- Dynamic columns will be stored here\n);\n\nOnce created, one can access dynamic columns via dynamic column functions:\n\nInsert a row with two dynamic columns: color=blue, size=XL\n\nINSERT INTO assets VALUES \n (\'MariaDB T-shirt\', COLUMN_CREATE(\'color\', \'blue\', \'size\', \'XL\'));\n\nInsert another row with dynamic columns: color=black, price=500\n\nINSERT INTO assets VALUES\n (\'Thinkpad Laptop\', COLUMN_CREATE(\'color\', \'black\', \'price\', 500));\n\nSelect dynamic column \'color\' for all items:\n\nSELECT item_name, COLUMN_GET(dynamic_cols, \'color\' as char) \n AS color FROM assets;\n+-----------------+-------+\n| item_name       | color |\n+-----------------+-------+\n| MariaDB T-shirt | blue  |\n| Thinkpad Laptop | black |\n+-----------------+-------+\n\nIt is possible to add and remove dynamic columns from a row:\n\n-- Remove a column:\nUPDATE assets SET dynamic_cols=COLUMN_DELETE(dynamic_cols, \"price\") \nWHERE COLUMN_GET(dynamic_cols, \'color\' as char)=\'black\';\n\n-- Add a column:\nUPDATE assets SET dynamic_cols=COLUMN_ADD(dynamic_cols, \'warranty\', \'3 years\')\nWHERE item_name=\'Thinkpad Laptop\';\n\nYou can also list all columns, or get them together with their values in JSON\nformat:\n\nSELECT item_name, column_list(dynamic_cols) FROM assets;\n+-----------------+---------------------------+\n| item_name       | column_list(dynamic_cols) |\n+-----------------+---------------------------+\n| MariaDB T-shirt | `size`,`color`            |\n| Thinkpad Laptop | `color`,`warranty`        |\n+-----------------+---------------------------+\n\nSELECT item_name, COLUMN_JSON(dynamic_cols) FROM assets;\n+-----------------+----------------------------------------+\n| item_name       | COLUMN_JSON(dynamic_cols)              |\n+-----------------+----------------------------------------+\n| MariaDB T-shirt | {\"size\":\"XL\",\"color\":\"blue\"}           |\n| Thinkpad Laptop | {\"color\":\"black\",\"warranty\":\"3 years\"} |\n+-----------------+----------------------------------------+\n\nDynamic Columns Reference\n-------------------------\n\nThe rest of this page is a complete reference of dynamic columns in MariaDB\n\nDynamic Columns Functions\n-------------------------\n\nCOLUMN_CREATE\n-------------\n\nCOLUMN_CREATE(column_nr, value [as type], [column_nr, value \n [as type]]...);\nCOLUMN_CREATE(column_name, value [as type], [column_name, value \n [as type]]...);\n\nReturn a dynamic columns blob that stores the specified columns with values.\n\nThe return value is suitable for\n\n* \nstoring in a table\nfurther modification with other dynamic columns functions\n\nThe as type part allows one to specify the value type. In most cases, this is\nredundant because MariaDB will be able to deduce the type of the value.\nExplicit type specification may be needed when the type of the value is not\napparent. For example, a literal \'2012-12-01\' has a CHAR type by default, one\nwill need to specify \'2012-12-01\' AS DATE to have it stored as a date. See the\nDatatypes section for further details. Note also MDEV-597.\n\nTypical usage:\n\n-- MariaDB 5.3+:\nINSERT INTO tbl SET dyncol_blob=COLUMN_CREATE(1 /*column id*/, \"value\");\n-- MariaDB 10.0.1+:\nINSERT INTO tbl SET dyncol_blob=COLUMN_CREATE(\"column_name\", \"value\");\n\nCOLUMN_ADD\n----------\n\nCOLUMN_ADD(dyncol_blob, column_nr, value [as type], \n [column_nr, value [as type]]...);\nCOLUMN_ADD(dyncol_blob, column_name, value [as type], \n [column_name, value [as type]]...);\n\nAdds or updates dynamic columns.\n\n* \ndyncol_blob must be either a valid dynamic columns blob (for example,\nCOLUMN_CREATE returns such blob), or an empty string.\ncolumn_name specifies the name of the column to be added. If dyncol_blob\nalready has a column with this name, it will be overwritten.\nvalue specifies the new value for the column.  Passing a NULL value will cause\nthe column to be deleted.\nas type is optional. See #datatypes section for a discussion about types.\n\nThe return value is a dynamic column blob after the modifications.\n\nTypical usage:\n\n-- MariaDB 5.3+:\nUPDATE tbl SET dyncol_blob=COLUMN_ADD(dyncol_blob, 1 /*column id*/, \"value\") \n WHERE id=1;\n-- MariaDB 10.0.1+:\nUPDATE t1 SET dyncol_blob=COLUMN_ADD(dyncol_blob, \"column_name\", \"value\") \n WHERE id=1;\n\nNote: COLUMN_ADD() is a regular function (just like CONCAT()), hence, in order\nto update the value in the table you have to use the UPDATE ... SET\ndynamic_col=COLUMN_ADD(dynamic_col, ....) pattern.\n\nCOLUMN_GET\n----------\n\nCOLUMN_GET(dyncol_blob, column_nr as type);\nCOLUMN_GET(dyncol_blob, column_name as type);\n\nGet the value of a dynamic column by its name. If no column with the given\nname exists, NULL will be returned.\n\ncolumn_name as type requires that one specify the datatype of the dynamic\ncolumn they are reading.\n\nThis may seem counter-intuitive: why would one need to specify which datatype\nthey\'re retrieving? Can\'t the dynamic columns system figure the datatype from\nthe data being stored?\n\nThe answer is: SQL is a statically-typed language. The SQL interpreter needs\nto know the datatypes of all expressions before the query is run (for example,\nwhen one is using prepared statements and runs \"select COLUMN_GET(...)\", the\nprepared statement API requires the server to inform the client about the\ndatatype of the column being read before the query is executed and the server\ncan see what datatype the column actually has).\n\nSee the Datatypes section for more information about datatypes.\n\nCOLUMN_DELETE\n-------------\n\nCOLUMN_DELETE(dyncol_blob, column_nr, column_nr...);\nCOLUMN_DELETE(dyncol_blob, column_name, column_name...);\n\nDelete a dynamic column with the specified name. Multiple names can be given.\n\nThe return value is a dynamic column blob after the modification.\n\nCOLUMN_EXISTS\n-------------\n\nCOLUMN_EXISTS(dyncol_blob, column_nr);\nCOLUMN_EXISTS(dyncol_blob, column_name);\n\nCheck if a column with name column_name exists in dyncol_blob. If yes, return\n1, otherwise return 0.\n\nCOLUMN_LIST\n-----------\n\nCOLUMN_LIST(dyncol_blob);\n\nReturn a comma-separated list of column names. The names are quoted with\nbackticks.\n\nSELECT column_list(column_create(\'col1\',\'val1\',\'col2\',\'val2\'));\n+---------------------------------------------------------+\n| column_list(column_create(\'col1\',\'val1\',\'col2\',\'val2\')) |\n+---------------------------------------------------------+\n| `col1`,`col2`                                           |\n+---------------------------------------------------------+\n\nCOLUMN_CHECK\n------------\n\nCOLUMN_CHECK(dyncol_blob);\n\nCheck if dyncol_blob is a valid packed dynamic columns blob. Return value of 1\nmeans the blob is valid, return value of 0 means it is not.\n\nRationale: Normally, one works with valid dynamic column blobs. Functions like\nCOLUMN_CREATE, COLUMN_ADD, COLUMN_DELETE always return valid dynamic column\nblobs. However, if a dynamic column blob is accidentally truncated, or\ntranscoded from one character set to another, it will be corrupted. This\nfunction can be used to check if a value in a blob field is a valid dynamic\ncolumn blob.\n\nNote: It is possible that a truncation cut a Dynamic Column \"clearly\" so that\nCOLUMN_CHECK will not notice the corruption, but in any case of truncation a\nwarning is issued during value storing.\n\nCOLUMN_JSON\n-----------\n\nCOLUMN_JSON(dyncol_blob);\n\nReturn a JSON representation of data in dyncol_blob.\n\nExample:\n\nSELECT item_name, COLUMN_JSON(dynamic_cols) FROM assets;\n+-----------------+----------------------------------------+\n| item_name       | COLUMN_JSON(dynamic_cols)              |\n+-----------------+----------------------------------------+\n| MariaDB T-shirt | {\"size\":\"XL\",\"color\":\"blue\"}           |\n| Thinkpad Laptop | {\"color\":\"black\",\"warranty\":\"3 years\"} |\n+-----------------+----------------------------------------+\n\nLimitation: COLUMN_JSON will decode nested dynamic columns at a nesting level\nof not more than 10 levels deep. Dynamic columns that are nested deeper than\n10 levels will be shown as BINARY string, without encoding.\n\nNesting Dynamic Columns\n-----------------------\n\nIt is possible to use nested dynamic columns by putting one dynamic column\nblob inside another. The COLUMN_JSON function will display nested columns.\n\nSET @tmp= column_create(\'parent_column\', \n column_create(\'child_column\', 12345));\nQuery OK, 0 rows affected (0.00 sec)\n\nSELECT column_json(@tmp);\n+------------------------------------------+\n| column_json(@tmp)                        |\n+------------------------------------------+\n| {\"parent_column\":{\"child_column\":12345}} |\n+------------------------------------------+\n\nSELECT column_get(column_get(@tmp, \'parent_column\' AS char), \n \'child_column\' AS int);\n+------------------------------------------------------------------------------\n\n| column_get(column_get(@tmp, \'parent_column\' as char), \'child_column\' as int)\n|\n+------------------------------------------------------------------------------\n\n|                                                                        12345\n|\n+------------------------------------------------------------------------------\n\nIf you are trying to get a nested dynamic column as a string use \'as BINARY\'\nas the last argument of COLUMN_GET (otherwise problems with character set\nconversion and illegal symbols are possible):\n\nselect column_json( column_get(\n column_create(\'test1\',\n  column_create(\'key1\',\'value1\',\'key2\',\'value2\',\'key3\',\'value3\')),\n \'test1\' as BINARY));\n\nDatatypes\n---------\n\nIn SQL, one needs to define the type of each column in a table. Dynamic\ncolumns do not provide any way to declare a type in advance (\"whenever there\nis a column \'weight\', it should be integer\" is not possible). However, each\nparticular dynamic column value is stored together with its datatype.\n\nThe set of possible datatypes is mostly the same as that used by the SQL CAST\nand CONVERT functions. However, note that there are currently some differences\n- see MDEV-597.\n\n+--------+----------------------------------------------+-------------------+\n| type   | dynamic column internal type                 | description       |\n+--------+----------------------------------------------+-------------------+\n| BINARY | DYN_COL_STRING                               | (variable length  |\n| (N)]   |                                              | string with       |\n|        |                                              | binary charset)   |\n+--------+----------------------------------------------+-------------------+\n| CHAR[( | DYN_COL_STRING                               | (variable length  |\n| )]     |                                              | string with       |\n|        |                                              | charset)          |\n+--------+----------------------------------------------+-------------------+\n| DATE   | DYN_COL_DATE                                 | (date - 3 bytes)  |\n+--------+----------------------------------------------+-------------------+\n| DATETI | DYN_COL_DATETIME                             | (date and time    |\n| E[(D)] |                                              | (with             |\n|        |                                              | microseconds) -   |\n|        |                                              | 9 bytes)          |\n+--------+----------------------------------------------+-------------------+\n| DECIMA | DYN_COL_DECIMAL                              | (variable length  |\n| [(M[,D |                                              | binary decimal    |\n| )]     |                                              | representation    |\n|        |                                              | with MariaDB      |\n|        |                                              | limitation)       |\n+--------+----------------------------------------------+-------------------+\n| DOUBLE | DYN_COL_DOUBLE                               | (64 bit           |\n| (M,D)] |                                              | double-precision  |\n|        |                                              | floating point)   |\n+--------+----------------------------------------------+-------------------+\n| INTEGE | DYN_COL_INT                                  | (variable         |\n|        |                                              | length, up to 64  |\n|        |                                              | bit signed        |\n|        |                                              | integer)          |\n+--------+----------------------------------------------+-------------------+\n| SIGNED | DYN_COL_INT                                  | (variable         |\n| [INTEG |                                              | length, up to 64  |\n| R]     |                                              | bit signed        |\n|        |                                              | integer)          |\n+--------+----------------------------------------------+-------------------+\n| TIME[( | DYN_COL_TIME                                 | (time (with       |\n| )]     |                                              | microseconds,     |\n|        |                                              | may be negative)  |\n|        |                                              | - 6 bytes)        |\n+--------+----------------------------------------------+-------------------+\n| UNSIGN | DYN_COL_UINT                                 | (variable         |\n| D      |                                              | length, up to     |\n| [INTEG |                                              | 64bit unsigned    |\n| R]     |                                              | integer)          |\n+--------+----------------------------------------------+-------------------+\n\nA Note About Lengths\n--------------------\n\nIf you\'re running queries like\n\nSELECT COLUMN_GET(blob, \'colname\' as CHAR) ...\n\nwithout specifying a maximum length (i.e. using #as CHAR#, not as CHAR(n)),\nMariaDB will report the maximum length of the resultset column to be\n53,6870,911 (bytes or characters?) for MariaDB 5.3-10.0.0 and 16,777,216 for\nMariaDB 10.0.1+. This may cause excessive memory usage in some client\nlibraries, because they try to pre-allocate a buffer of maximum resultset\nwidth. If you suspect you\'re hitting this problem, use CHAR(n) whenever you\'re\nusing COLUMN_GET in the select list.\n\nMariaDB 5.3 vs MariaDB 10.0\n---------------------------\n\nThe dynamic columns feature was introduced into MariaDB in two steps:\n\n* MariaDB 5.3 was the first version to support dynamic columns. Only numbers\n could be used as column names in this version.\n* In MariaDB 10.0.1, column names can be either numbers or strings.\n Also, the COLUMN_JSON and COLUMN_CHECK functions were added.\n\nSee also Dynamic Columns in MariaDB 10.\n\nClient-side API\n---------------\n\nIt is also possible to create or parse dynamic columns blobs on the client\nside. libmysql client library now includes an API for writing/reading dynamic\ncolumn blobs. See dynamic-columns-api for details.\n\nLimitations\n-----------\n\n+---------------------------------------------------+------------------------+\n| Description                                       | Limit                  |\n+---------------------------------------------------+------------------------+\n| Max number of columns                             | 65535                  |\n+---------------------------------------------------+------------------------+\n| Max total length of packed dynamic column         | max_allowed_packet     |\n|                                                   | (1G)                   |\n+---------------------------------------------------+------------------------+\n\nURL: https://mariadb.com/kb/en/dynamic-columns/','','https://mariadb.com/kb/en/dynamic-columns/'),(719,'Dynamic Columns from MariaDB 10',38,'MariaDB starting with 10.0.1\n----------------------------\nMariaDB 10.0.1 introduced the following improvements to the dynamic columns\nfeature.\n\nColumn Name Support\n-------------------\n\nIt is possible to refer to column by names. Names can be used everywhere where\nin MariaDB 5.3 one could use only strings:\n\n* Create a dynamic column blob:\n\nCOLUMN_CREATE(\'int_col\', 123 as int, \'double_col\', 3.14 as double,\n\'string_col\', \'text-data\' as char);\n\n* Set a column value:\n\nCOLUMN_ADD(dyncol_blob, \'intcol\', 1234);\n\n* Get a column value:\n\nCOLUMN_GET(dynstr, \'column1\' as char(10));\n\n* Check whether a column exists\n\nCOLUMN_EXISTS(dyncol_blob, \'column_name\');\n\nChanges in Behavior\n-------------------\n\n* Column list output now includes quoting:\n\nselect column_list(column_create(1, 22, 2, 23));\n+------------------------------------------+\n| column_list(column_create(1, 22, 2, 23)) |\n+------------------------------------------+\n| `1`,`2`                                  |\n+------------------------------------------+\nselect column_list(column_create(\'column1\', 22, \'column2\', 23)); \n+----------------------------------------------------------+\n| column_list(column_create(\'column1\', 22, \'column2\', 23)) |\n+----------------------------------------------------------+\n| `column1`,`column2`                                      |\n+----------------------------------------------------------+\n\n* Column name interpretation has been changed so that the string now is not\nconverted to a number. So some \"magic\" tricks will not work any more, for\nexample, \"1test\" and \"1\" now become different column names:\n\nselect column_list(column_add(column_create(\'1a\', 22), \'1b\', 23));\n+------------------------------------------------------------+\n| column_list(column_add(column_create(\'1a\', 22), \'1b\', 23)) |\n+------------------------------------------------------------+\n| `1a`,`1b`                                                  |\n+------------------------------------------------------------+\n\n* Old behavior:\n\nselect column_list(column_add(column_create(\'1a\', 22), \'1b\', 23));\n+------------------------------------------------------------+\n| column_list(column_add(column_create(\'1a\', 22), \'1b\', 23)) |\n+------------------------------------------------------------+\n| 1                                                          |\n+------------------------------------------------------------+\n\nNew Functions\n-------------\n\nThe following new functions have been added to dynamic columns in MariaDB 10\n\nCOLUMN_CHECK\n------------\n\nCOLUMN_CHECK is used to check a column\'s integrity. When it encounters an\nerror it does not return illegal format errors but returns false instead. It\nalso checks integrity more thoroughly and finds errors in the dynamic column\ninternal structures which might not be found by other functions.\n\nselect column_check(column_create(\'column1\', 22));\n+--------------------------------------------+\n| column_check(column_create(\'column1\', 22)) |\n+--------------------------------------------+\n|                                          1 |\n+--------------------------------------------+\nselect column_check(\'abracadabra\');\n+-----------------------------+\n| column_check(\'abracadabra\') |\n+-----------------------------+\n|                           0 |\n+-----------------------------+\n\nCOLUMN_JSON\n-----------\n\nCOLUMN_JSON converts all dynamic column record content to a JSON object.\n\nselect column_json(column_create(\'column1\', 1, \'column2\', \"two\"));\n+------------------------------------------------------------+\n| column_json(column_create(\'column1\', 1, \'column2\', \"two\")) |\n+------------------------------------------------------------+\n| {\"column1\":1,\"column2\":\"two\"}                              |\n+------------------------------------------------------------+\n\nOther Changes\n-------------\n\n* All API functions has prefix mariadb_dyncol_ (old prefix dynamic_column_ is\ndepricated\n* API changed to be able to work with the new format (*_named functions).\n* Removed \'delete\' function because deleting could be done by adding NULL\nvalue.\n* \'Time\' and \'datetime\' in the new format are stored without microseconds if\nthey are 0.\n* New function added to API (except that two which are representing SQL level\nfunctions):\n\'Unpack\' the dynamic columns content to an arrays of values and names.\n3 functions to get any column value as string, integer (long long) or floating\npoint (double).\n\n* New type of \"dynamic column\" row added on the API level (in SQL level output\nit is a string but if you use dynamic column functions to construct object it\nwill be added as dynamic column value) which allow to add dynamic columns\ninside dynamic columns. JSON function represent such recursive constructions\ncorrectly but limit depth of representation as current implementation limit\n(internally depth of dynamic columns embedding is not limited).\n\nInterface with Cassandra\n------------------------\n\nCassandraSE is no longer actively being developed and has been removed in\nMariaDB 10.6. See MDEV-23024.\n\nSome internal changes were added to dynamic columns to allow them to serve as\nan interface to Apache Cassandra dynamic columns. The Cassandra engine may\npack all columns which were not mentioned in the MariaDB interface table\ndefinition and even bring changes in the dynamic column contents back to the\ncassandra columns family (the table analog in cassandra).\n\nURL: https://mariadb.com/kb/en/dynamic-columns-from-mariadb-10/','','https://mariadb.com/kb/en/dynamic-columns-from-mariadb-10/'),(720,'MERGE',38,'Description\n-----------\n\nThe MERGE storage engine, also known as the MRG_MyISAM engine, is a collection\nof identical MyISAM tables that can be used as one. \"Identical\" means that all\ntables have identical column and index information. You cannot merge MyISAM\ntables in which the columns are listed in a different order, do not have\nexactly the same columns, or have the indexes in different order. However, any\nor all of the MyISAM tables can be compressed with myisampack. Columns names\nand indexes names can be different, as long as data types and NULL/NOT NULL\nclauses are the same. Differences in table options such as AVG_ROW_LENGTH,\nMAX_ROWS, or PACK_KEYS do not matter.\n\nEach index in a MERGE table must match an index in underlying MyISAM tables,\nbut the opposite is not true. Also, a MERGE table cannot have a PRIMARY KEY or\nUNIQUE indexes, because it cannot enforce uniqueness over all underlying\ntables.\n\nThe following options are meaningful for MERGE tables:\n\n* UNION. This option specifies the list of the underlying MyISAM tables. The\nlist is enclosed between parentheses and separated with commas.\n* INSERT_METHOD. This options specifies whether, and how, INSERTs are allowed\nfor the table. Allowed values are: NO (INSERTs are not allowed), FIRST (new\nrows will be written into the first table specified in the UNION list), LAST\n(new rows will be written into the last table specified in the UNION list).\nThe default value is NO.\n\nIf you define a MERGE table with a definition which is different from the\nunderlying MyISAM tables, or one of the underlying tables is not MyISAM, the\nCREATE TABLE statement will not return any error. But any statement which\ninvolves the table will produce an error like the following:\n\nERROR 1168 (HY000): Unable to open underlying table which is differently\ndefined \n or of non-MyISAM type or doesn\'t exist\n\nA CHECK TABLE will show more information about the problem.\n\nThe error is also produced if the table is properly define, but an underlying\ntable\'s definition changes at some point in time.\n\nIf you try to insert a new row into a MERGE table with INSERT_METHOD=NO, you\nwill get an error like the following:\n\nERROR 1036 (HY000): Table \'tbl_name\' is read only\n\nIt is possible to build a MERGE table on MyISAM tables which have one or more\nvirtual columns. MERGE itself does not support virtual columns, thus such\ncolumns will be seen as regular columns. The data types and sizes will still\nneed to be identical, and they cannot be NOT NULL.\n\nExamples\n--------\n\nCREATE TABLE t1 (\n  a INT NOT NULL AUTO_INCREMENT PRIMARY KEY,\n  message CHAR(20)) ENGINE=MyISAM;\n\nCREATE TABLE t2 (\n  a INT NOT NULL AUTO_INCREMENT PRIMARY KEY,\n  message CHAR(20)) ENGINE=MyISAM;\n\nINSERT INTO t1 (message) VALUES (\'Testing\'),(\'table\'),(\'t1\');\n\nINSERT INTO t2 (message) VALUES (\'Testing\'),(\'table\'),(\'t2\');\n\nCREATE 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\nSELECT * FROM total;\n+---+---------+\n| a | message |\n+---+---------+\n| 1 | Testing |\n| 2 | table   |\n| 3 | t1      |\n| 1 | Testing |\n| 2 | table   |\n| 3 | t2      |\n+---+---------+\n\nIn the following example, we\'ll create three MyISAM tables, and then a MERGE\ntable on them. However, one of them uses a different data type for the column\nb, so a SELECT will produce an error:\n\nCREATE TABLE t1 (\n a INT,\n b INT\n) ENGINE = MyISAM;\n\nCREATE TABLE t2 (\n a INT,\n b INT\n) ENGINE = MyISAM;\n\nCREATE TABLE t3 (\n a INT,\n b TINYINT\n) ENGINE = MyISAM;\n\nCREATE TABLE t_mrg (\n a INT,\n b INT\n) ENGINE = MERGE,UNION=(t1,t2,t3);\n\nSELECT * FROM t_mrg;\nERROR 1168 (HY000): Unable to open underlying table which is differently\ndefined\n or of non-MyISAM type or doesn\'t exist\n\nTo find out what\'s wrong, we\'ll use a CHECK TABLE:\n\nCHECK TABLE t_mrg\\G\n*************************** 1. row ***************************\n Table: test.t_mrg\n   Op: check\nMsg_type: Error\nMsg_text: Table \'test.t3\' is differently defined or of non-MyISAM type or\ndoesn\'t exist\n*************************** 2. row ***************************\n Table: test.t_mrg\n   Op: check\nMsg_type: Error\nMsg_text: Unable to open underlying table which is differently defined or of\nnon-MyISAM type or doesn\'t exist\n*************************** 3. row ***************************\n Table: test.t_mrg\n   Op: check\nMsg_type: error\nMsg_text: Corrupt\n\nNow, we know that the problem is in t3\'s definition.\n\nURL: https://mariadb.com/kb/en/merge/','','https://mariadb.com/kb/en/merge/'),(721,'Sequence Overview',39,'MariaDB starting with 10.3\n--------------------------\nSequences were introduced in MariaDB 10.3.\n\nIntroduction\n------------\n\nA sequence is an object that generates a sequence of numeric values, as\nspecified by the CREATE SEQUENCE statement.\n\nCREATE SEQUENCE will create a sequence that generates new values when called\nwith NEXT VALUE FOR sequence_name. It\'s an alternative to AUTO INCREMENT when\none wants to have more control of how the numbers are generated. As the\nSEQUENCE caches values (up to the CACHE value in the CREATE SEQUENCE\nstatement, by default 1000) it can in some cases be much faster than AUTO\nINCREMENT. Another benefit is that one can access the last value generated by\nall used sequences, which solves one of the limitations with LAST_INSERT_ID().\n\nCreating a Sequence\n-------------------\n\nThe CREATE SEQUENCE statement is used to create a sequence. Here is an example\nof a sequence starting at 100, incrementing by 10 each time:\n\nCREATE SEQUENCE s START WITH 100 INCREMENT BY 10;\n\nThe CREATE SEQUENCE statement, along with defaults, can be viewd with the SHOW\nCREATE SEQUENCE STATEMENT, for example:\n\nSHOW CREATE SEQUENCE s\\G\n*************************** 1. row ***************************\n   Table: s\nCreate Table: CREATE SEQUENCE `s` start with 100 minvalue 1 maxvalue\n9223372036854775806 \n increment by 10 cache 1000 nocycle ENGINE=InnoDB\n\nUsing Sequence Objects\n----------------------\n\nTo get the next value from a sequence, use\n\nNEXT VALUE FOR sequence_name\n\nor\n\nNEXTVAL(sequence_name)\n\nor in Oracle mode (SQL_MODE=ORACLE)\n\nsequence_name.nextval\n\nFor retrieving the last value used by the current connection from a sequence\nuse:\n\nPREVIOUS VALUE FOR sequence_name\n\nor\n\nLASTVAL(sequence_name)\n\nor in Oracle mode (SQL_MODE=ORACLE)\n\nsequence_name.currval\n\nFor example:\n\nSELECT NEXTVAL(s);\n+------------+\n| NEXTVAL(s) |\n+------------+\n|        100 |\n+------------+\n\nSELECT NEXTVAL(s);\n+------------+\n| NEXTVAL(s) |\n+------------+\n|        110 |\n+------------+\n\nSELECT LASTVAL(s);\n+------------+\n| LASTVAL(s) |\n+------------+\n|        110 |\n+------------+\n\nUsing Sequences in DEFAULT\n--------------------------\n\nMariaDB starting with 10.3.3\n----------------------------\nStarting from 10.3.3 you can use Sequences in DEFAULT:\n\ncreate sequence s1;\ncreate table t1 (a int primary key default (next value for s1), b int);\ninsert into t1 (b) values (1),(2);\nselect * from t1;\n+---+------+\n| a | b    |\n+---+------+\n| 1 |    1 |\n| 2 |    2 |\n+---+------+\n\nChanging a Sequence\n-------------------\n\nThe ALTER SEQUENCE statement is used for changing sequences. For example, to\nrestart the sequence at another value:\n\nALTER SEQUENCE s RESTART 50;\n\nSELECT NEXTVAL(s);\n+------------+\n| NEXTVAL(s) |\n+------------+\n|         50 |\n+------------+\n\nThe SETVAL function can also be used to set the next value to be returned for\na SEQUENCE, for example:\n\nSELECT SETVAL(s, 100);\n+----------------+\n| SETVAL(s, 100) |\n+----------------+\n|            100 |\n+----------------+\n\nSETVAL can only be used to increase the sequence value. Attempting to set a\nlower value will fail, returning NULL:\n\nSELECT SETVAL(s, 50);\n+---------------+\n| SETVAL(s, 50) |\n+---------------+\n|          NULL |\n+---------------+\n\nDropping a Sequence\n-------------------\n\nThe DROP SEQUENCE statement is used to drop a sequence, for example:\n\nDROP SEQUENCE s;\n\nReplication\n-----------\n\nIf one wants to use Sequences in a master-master setup or with Galera one\nshould use INCREMENT=0. This will tell the Sequence to use\nauto_increment_increment and auto_increment_offset to generate unique values\nfor each server.\n\nStandards Compliance\n--------------------\n\nMariaDB 10.3 supports both ANSI SQL and Oracle syntax for sequences.\n\nHowever as SEQUENCE is implemented as a special kind of table, it uses the\nsame namespace as tables. The benefits are that sequences show up in SHOW\nTABLES, and one can also create a sequence with CREATE TABLE and drop it with\nDROP TABLE. One can SELECT from it as from any other table. This ensures that\nall old tools that work with tables should work with sequences.\n\nSince sequence objects act as regular tables in many contexts, they will be\naffected by LOCK TABLES. This is not the case in other DBMS, such as Oracle,\nwhere LOCK TABLE does not affect sequences.\n\nNotes\n-----\n\nOne of the goals with the Sequence implementation is that all old tools, such\nas mysqldump, should work unchanged, while still keeping the normal usage of\nsequence standard compatibly.\n\nTo make this possible, sequence is currently implemented as a table with a few\nexclusive properties.\n\nThe special properties for sequence tables are:\n\n* A sequence table has always one row.\n* When one creates a sequence, either with CREATE TABLE or CREATE SEQUENCE,\none row will be inserted.\n* If one tries to insert into a sequence table, the single row will be\nupdated.  This allows mysqldump to work but also gives the additional benefit\nthat one can change all properties of a sequence with a single insert. New\napplications should of course also use ALTER SEQUENCE.\n* UPDATE or DELETE can\'t be performed on Sequence objects.\n* Doing a select on the sequence shows the current state of the sequence,\nexcept the values that are reserved in the cache.  The next_value column shows\nthe next value not reserved by the cache.\n* FLUSH TABLES will close the sequence and the next sequence number generated\nwill be according to what\'s stored in the Sequence object. In effect, this\nwill discard the cached values.\n* A number of normal table operations work on Sequence tables. See next\nsection.\n\nTable Operations that Work with Sequences\n-----------------------------------------\n\n* SHOW CREATE TABLE sequence_name. This shows the table structure that is\nbehind the SEQUENCE including the field names that can be used with SELECT or\neven CREATE TABLE.\n* CREATE TABLE sequence-structure ... SEQUENCE=1\n* ALTER TABLE sequence RENAME TO sequence2\n* RENAME TABLE sequence_name TO new_sequence_name\n* DROP TABLE sequence_name. This is allowed mainly to get old tools like\nmysqldump to work with sequence tables.\n* SHOW TABLES\n\nImplementation\n--------------\n\nInternally, sequence tables are created as a normal table without rollback\n(the InnoDB, Aria and MySAM engines support this), wrapped by a sequence\nengine object. This allowed us to create sequences with almost no performance\nimpact for normal tables. (The cost is one \'if\' per insert if the binary log\nis enabled).\n\nUnderlying Table Structure\n--------------------------\n\nThe following example shows the table structure of sequences and how it can be\nused as a table. (Output of results are slightly edited to make them easier to\nread)\n\ncreate sequence t1;\nshow create sequence t1\\G\n*************************** 1. row ***************************\n CREATE SEQUENCE `t1` start with 1 minvalue 1 maxvalue 9223372036854775806\n increment by 1 cache 1000 nocycle ENGINE=InnoDB\n\nshow create table t1\\G\n*************************** 1. row ***************************\nCreate Table: CREATE TABLE `t1` (\n `next_not_cached_value` bigint(21) NOT NULL,\n `minimum_value` bigint(21) NOT NULL,\n `maximum_value` bigint(21) NOT NULL,\n `start_value` bigint(21) NOT NULL COMMENT \'start value when sequences is\ncreated or value if RESTART is used\',\n `increment` bigint(21) NOT NULL COMMENT \'increment value\',\n `cache_size` bigint(21) unsigned NOT NULL,\n `cycle_option` tinyint(1) unsigned NOT NULL COMMENT \'0 if no cycles are\nallowed, 1 if the sequence should begin a new cycle when maximum_value is\npassed\',\n `cycle_count` bigint(21) NOT NULL COMMENT \'How many cycles have been done\'\n) ENGINE=InnoDB SEQUENCE=1\n\nselect * from t1\\G\nnext_not_cached_value: 1\n minimum_value: 1\n maximum_value: 9223372036854775806\n start_value: 1\n increment: 1\n cache_size: 1000\n cycle_option: 0\n cycle_count: 0\n\nThe cycle_count column is incremented every time the sequence wraps around.\n\nCredits\n-------\n\n* Thanks to Jianwe Zhao from Aliyun for his work on SEQUENCE in AliSQL, which\ngave ideas and inspiration for this work.\n* Thanks to Peter Gulutzan,who helped test and gave useful comments about the\nimplementation.\n\nURL: https://mariadb.com/kb/en/sequence-overview/','','https://mariadb.com/kb/en/sequence-overview/'),(722,'CREATE SEQUENCE',39,'MariaDB starting with 10.3\n--------------------------\nCREATE SEQUENCE was introduced in MariaDB 10.3.\n\nSyntax\n------\n\nCREATE [OR REPLACE] [TEMPORARY] SEQUENCE [IF NOT EXISTS] sequence_name\n[ INCREMENT [ BY | = ] increment ]\n[ MINVALUE [=] minvalue | NO MINVALUE | NOMINVALUE ]\n[ MAXVALUE [=] maxvalue | NO MAXVALUE | NOMAXVALUE ]\n[ START [ WITH | = ] start ] \n[ CACHE [=] cache | NOCACHE ] [ CYCLE | NOCYCLE] \n[table_options]\nThe options for CREATE SEQUENCE can be given in any order, optionally followed\nby table_options.\n\ntable_options can be any of the normal table options in CREATE TABLE but the\nmost usable ones are ENGINE=... and COMMENT=.\n\nNOMAXVALUE and NOMINVALUE are there to allow one to create SEQUENCEs using the\nOracle syntax.\n\nDescription\n-----------\n\nCREATE SEQUENCE will create a sequence that generates new values when called\nwith NEXT VALUE FOR sequence_name. It\'s an alternative to AUTO INCREMENT when\none wants to have more control of how the numbers are generated. As the\nSEQUENCE caches values (up to CACHE) it can in some cases be much faster than\nAUTO INCREMENT. Another benefit is that one can access the last value\ngenerated by all used sequences, which solves one of the limitations with\nLAST_INSERT_ID().\n\nCREATE SEQUENCE requires the CREATE privilege.\n\nDROP SEQUENCE can be used to drop a sequence, and ALTER SEQUENCE to change it.\n\nArguments to Create\n-------------------\n\nThe following options may be used:\n\n+---------------+------------------------------+----------------------------+\n| Option        | Default value                | Description                |\n+---------------+------------------------------+----------------------------+\n| INCREMENT     | 1                            | Increment to use for       |\n|               |                              | values. May be negative.   |\n|               |                              | Setting an increment of 0  |\n|               |                              | causes the sequence to     |\n|               |                              | use the value of the       |\n|               |                              | auto_increment_increment   |\n|               |                              | system variable at the     |\n|               |                              | time of creation, which    |\n|               |                              | is always a positive       |\n|               |                              | number. (see MDEV-16035).  |\n+---------------+------------------------------+----------------------------+\n| MINVALUE      | 1 if INCREMENT > 0 and       | Minimum value for the      |\n|               | -9223372036854775807 if      | sequence                   |\n|               | INCREMENT < 0                |                            |\n+---------------+------------------------------+----------------------------+\n| MAXVALUE      | 9223372036854775806 if       | Max value for sequence     |\n|               | INCREMENT > 0 and -1 if      |                            |\n|               | INCREMENT < 0                |                            |\n+---------------+------------------------------+----------------------------+\n| START         | MINVALUE if INCREMENT > 0    | First value that the       |\n|               | and MAX_VALUE if INCREMENT<  | sequence will generate     |\n|               | 0                            |                            |\n+---------------+------------------------------+----------------------------+\n| CACHE         | 1000                         | Number of values that      |\n|               |                              | should be cached. 0 if no  |\n|               |                              | CACHE.  The underlying     |\n|               |                              | table will be updated      |\n|               |                              | first time a new sequence  |\n|               |                              | number is generated and    |\n|               |                              | each time the cache runs   |\n|               |                              | out.                       |\n+---------------+------------------------------+----------------------------+\n\nIf CYCLE is used then the sequence should start again from MINVALUE after it\nhas run out of values. Default value is NOCYCLE.\n\nConstraints on Create Arguments\n-------------------------------\n\nTo be able to create a legal sequence, the following must hold:\n\n* MAXVALUE >= start\n* MAXVALUE > MINVALUE\n* START >= MINVALUE\n* MAXVALUE <= 9223372036854775806  (LONGLONG_MAX-1)\n* MINVALUE >= -9223372036854775807 (LONGLONG_MIN+1)\n\nNote that sequences can\'t generate the maximum/minimum 64 bit number because\nof the constraint of MINVALUE and MAXVALUE.\n\nAtomic DDL\n----------\n\nMariaDB starting with 10.6.1\n----------------------------\nMariaDB 10.6.1 supports Atomic DDL and CREATE SEQUENCE is atomic.\n\nExamples\n--------\n\nCREATE SEQUENCE s START WITH 100 INCREMENT BY 10;\n\nCREATE SEQUENCE s2 START WITH -100 INCREMENT BY -10;\n\nThe following statement fails, as the increment conflicts with the defaults\n\nCREATE SEQUENCE s3 START WITH -100 INCREMENT BY 10;\nERROR 4082 (HY000): Sequence \'test.s3\' values are conflicting\n\nThe sequence can be created by specifying workable minimum and maximum values:\n\nCREATE SEQUENCE s3 START WITH -100 INCREMENT BY 10 MINVALUE=-100 MAXVALUE=1000;\n\nURL: https://mariadb.com/kb/en/create-sequence/','','https://mariadb.com/kb/en/create-sequence/'),(723,'ALTER SEQUENCE',39,'MariaDB starting with 10.3.1\n----------------------------\nALTER SEQUENCE was introduced in MariaDB 10.3.\n\nSyntax\n------\n\nALTER SEQUENCE [IF EXISTS] sequence_name\n[ INCREMENT [ BY | = ] increment ]\n[ MINVALUE [=] minvalue | NO MINVALUE | NOMINVALUE ]\n[ MAXVALUE [=] maxvalue | NO MAXVALUE | NOMAXVALUE ]\n[ START [ WITH | = ] start ] [ CACHE [=] cache ] [ [ NO ] CYCLE ]\n[ RESTART [[WITH | =] restart]\n\nALTER SEQUENCE allows one to change any values for a SEQUENCE created with\nCREATE SEQUENCE.\n\nThe options for ALTER SEQUENCE can be given in any order.\n\nDescription\n-----------\n\nALTER SEQUENCE changes the parameters of an existing sequence generator. Any\nparameters not specifically set in the ALTER SEQUENCE command retain their\nprior settings.\n\nALTER SEQUENCE requires the ALTER privilege.\n\nArguments to ALTER SEQUENCE\n---------------------------\n\nThe following options may be used:\n\n+---------------+-------------------------------+---------------------------+\n| Option        | Default value                 | Description               |\n+---------------+-------------------------------+---------------------------+\n| INCREMENT     | 1                             | Increment to use for      |\n|               |                               | values. May be negative.  |\n+---------------+-------------------------------+---------------------------+\n| MINVALUE      | 1 if INCREMENT > 0 and        | Minimum value for the     |\n|               | -9223372036854775807 if       | sequence.                 |\n|               | INCREMENT < 0                 |                           |\n+---------------+-------------------------------+---------------------------+\n| MAXVALUE      | 9223372036854775806 if        | Max value for sequence.   |\n|               | INCREMENT > 0 and -1 if       |                           |\n|               | INCREMENT < 0                 |                           |\n+---------------+-------------------------------+---------------------------+\n| START         | MINVALUE if INCREMENT > 0     | First value that the      |\n|               | and MAX_VALUE if INCREMENT< 0 | sequence will generate.   |\n+---------------+-------------------------------+---------------------------+\n| CACHE         | 1000                          | Number of values that     |\n|               |                               | should be cached. 0 if    |\n|               |                               | no CACHE.  The            |\n|               |                               | underlying table will be  |\n|               |                               | updated first time a new  |\n|               |                               | sequence number is        |\n|               |                               | generated and each time   |\n|               |                               | the cache runs out.       |\n+---------------+-------------------------------+---------------------------+\n| CYCLE         | 0 (= NO CYCLE)                | 1 if the sequence should  |\n|               |                               | start again from          |\n|               |                               | MINVALUE# after it has    |\n|               |                               | run out of values.        |\n+---------------+-------------------------------+---------------------------+\n| RESTART       | START if restart value not    | If  RESTART option is     |\n|               | is given                      | used, NEXT VALUE will     |\n|               |                               | return the restart value. |\n+---------------+-------------------------------+---------------------------+\n\nThe optional clause RESTART [ WITH restart ] sets the next value for the\nsequence. This is equivalent to calling the SETVAL() function with the is_used\nargument as 0. The specified value will be returned by the next call of\nnextval. Using RESTART with no restart value is equivalent to supplying the\nstart value that was recorded by CREATE SEQUENCE or last set by ALTER SEQUENCE\nSTART WITH.\n\nALTER SEQUENCE will not allow you to change the sequence so that it\'s\ninconsistent. For example:\n\nCREATE SEQUENCE s1;\nALTER SEQUENCE s1 MINVALUE 10;\nERROR 4061 (HY000): Sequence \'test.t1\' values are conflicting\n\nALTER SEQUENCE s1 MINVALUE 10 RESTART 10;\nERROR 4061 (HY000): Sequence \'test.t1\' values are conflicting\n\nALTER SEQUENCE s1 MINVALUE 10 START 10 RESTART 10;\n\nINSERT\n------\n\nTo allow SEQUENCE objects to be backed up by old tools, like mysqldump, one\ncan use SELECT to read the current state of a SEQUENCE object and use an\nINSERT to update the SEQUENCE object. INSERT is only allowed if all fields are\nspecified:\n\nCREATE SEQUENCE s1;\nINSERT INTO s1 VALUES(1000,10,2000,1005,1,1000,0,0);\nSELECT * FROM s1;\n\n+------------+-----------+-----------+-------+-----------+-------+-------+-----\n-+\n| next_value | min_value | max_value | start | increment | cache | cycle |\nround |\n+------------+-----------+-----------+-------+-----------+-------+-------+-----\n-+\n|       1000 |        10 |      2000 |  1005 |         1 |  1000 |     0 |    \n0 |\n+------------+-----------+-----------+-------+-----------+-------+-------+-----\n-+\n\nSHOW CREATE SEQUENCE s1;\n+-------+----------------------------------------------------------------------\n---------------------------------------+\n| Table | Create Table                                                        \n                    |\n+-------+----------------------------------------------------------------------\n---------------------------------------+\n| s1    | CREATE SEQUENCE `s1` start with 1005 minvalue 10 maxvalue 2000\nincrement by 1 cache 1000 nocycle ENGINE=Aria |\n+-------+----------------------------------------------------------------------\n---------------------------------------+\n\nNotes\n-----\n\nALTER SEQUENCE will instantly affect all future SEQUENCE operations. This is\nin contrast to some other databases where the changes requested by ALTER\nSEQUENCE will not be seen until the sequence cache has run out.\n\nALTER SEQUENCE will take a full table lock of the sequence object during its\n(brief) operation. This ensures that ALTER SEQUENCE is replicated correctly.\nIf you only want to set the next sequence value to a higher value than\ncurrent, then you should use SETVAL() instead, as this is not blocking.\n\nIf you want to change storage engine, sequence comment or rename the sequence,\nyou can use ALTER TABLE for this.\n\nURL: https://mariadb.com/kb/en/alter-sequence/','','https://mariadb.com/kb/en/alter-sequence/'),(724,'DROP SEQUENCE',39,'MariaDB starting with 10.3\n--------------------------\nDROP SEQUENCE was introduced in MariaDB 10.3.\n\nSyntax\n------\n\nDROP [TEMPORARY] SEQUENCE [IF EXISTS] [/*COMMENT TO SAVE*/]\n  sequence_name [, sequence_name] ...\n\nDescription\n-----------\n\nDROP SEQUENCE removes one or more sequences created with CREATE SEQUENCE. You\nmust have the DROP privilege for each sequence. MariaDB returns an error\nindicating by name which non-existing tables it was unable to drop, but it\nalso drops all of the tables in the list that do exist.\n\nImportant: When a table is dropped, user privileges on the table are not\nautomatically dropped. See GRANT.\n\nIf another connection is using the sequence, a metadata lock is active, and\nthis statement will wait until the lock is released. This is also true for\nnon-transactional tables.\n\nFor each referenced sequence, DROP SEQUENCE drops a temporary sequence with\nthat name, if it exists. If it does not exist, and the TEMPORARY keyword is\nnot used, it drops a non-temporary sequence with the same name, if it exists.\nThe TEMPORARY keyword ensures that a non-temporary sequence will not\naccidentally be dropped.\n\nUse IF EXISTS to prevent an error from occurring for sequences that do not\nexist. A NOTE is generated for each non-existent sequence when using IF\nEXISTS. See SHOW WARNINGS.\n\nDROP SEQUENCE requires the DROP privilege.\n\nNotes\n-----\n\nDROP SEQUENCE only removes sequences, not tables. However, DROP TABLE can\nremove both sequences and tables.\n\nURL: https://mariadb.com/kb/en/drop-sequence/','','https://mariadb.com/kb/en/drop-sequence/'),(725,'NEXT VALUE for sequence_name',39,'MariaDB starting with 10.3\n--------------------------\nSEQUENCEs were introduced in MariaDB 10.3\n\nSyntax\n------\n\nNEXT VALUE FOR sequence\n\nor\n\nNEXTVAL(sequence_name)\n\nor in Oracle mode (SQL_MODE=ORACLE)\n\nsequence_name.nextval\n\nNEXT VALUE FOR is ANSI SQL syntax while NEXTVAL() is PostgreSQL syntax.\n\nDescription\n-----------\n\nGenerate next value for a SEQUENCE.\n\n* You can greatly speed up NEXT VALUE by creating the sequence with the CACHE\noption. If not, every NEXT VALUE usage will cause changes in the stored\nSEQUENCE table.\n* When using NEXT VALUE the value will be reserved at once and will not be\nreused, except if the SEQUENCE was created with CYCLE. This means that when\nyou are using SEQUENCEs you have to expect gaps in the generated sequence\nnumbers.\n* If one updates the SEQUENCE with SETVAL() or ALTER SEQUENCE ... RESTART,\nNEXT VALUE FOR will notice this and start from the next requested value.\n* FLUSH TABLES will close the sequence and the next sequence number generated\nwill be according to what\'s stored in the SEQUENCE object. In effect, this\nwill discard the cached values.\n* A server restart (or closing the current connection) also causes a drop of\nall cached values. The cached sequence numbers are reserved only for the\ncurrent connection.\n* NEXT VALUE requires the INSERT privilege.\n\nMariaDB starting with 10.3.3\n----------------------------\n* You can also use NEXT VALUE FOR sequence for column DEFAULT.\n\nURL: https://mariadb.com/kb/en/next-value-for-sequence_name/','','https://mariadb.com/kb/en/next-value-for-sequence_name/'),(726,'PREVIOUS VALUE FOR sequence_name',39,'MariaDB starting with 10.3\n--------------------------\nSEQUENCEs were introduced in MariaDB 10.3.\n\nSyntax\n------\n\nPREVIOUS VALUE FOR sequence_name\n\nor\n\nLASTVAL(sequence_name)\n\nor in Oracle mode (SQL_MODE=ORACLE)\n\nsequence_name.currval\n\nPREVIOUS VALUE FOR is IBM DB2 syntax while LASTVAL() is PostgreSQL syntax.\n\nDescription\n-----------\n\nGet last value in the current connection generated from a sequence.\n\n* If the sequence has not yet been used by the connection, PREVIOUS VALUE FOR\nreturns NULL (the same thing applies with a new connection which doesn\'t see a\nlast value for an existing sequence).\n* If a SEQUENCE has been dropped and re-created then it\'s treated as a new\nSEQUENCE and PREVIOUS VALUE FOR will return NULL.\n* FLUSH TABLES has no effect on PREVIOUS VALUE FOR.\n* Previous values for all used sequences are stored per connection until\nconnection ends.\n* PREVIOUS VALUE FOR requires the SELECT privilege.\n\nExample\n-------\n\nCREATE SEQUENCE s START WITH 100 INCREMENT BY 10;\n\nSELECT PREVIOUS VALUE FOR s;\n+----------------------+\n| PREVIOUS VALUE FOR s |\n+----------------------+\n|                 NULL |\n+----------------------+\n\n# The function works for sequences only, if the table is used an error is\ngenerated\nSELECT PREVIOUS VALUE FOR t;\nERROR 4089 (42S02): \'test.t\' is not a SEQUENCE\n\n# Call the NEXT VALUE FOR s:\nSELECT NEXT VALUE FOR s;\n+------------------+\n| NEXT VALUE FOR s |\n+------------------+\n|              100 |\n+------------------+\n\nSELECT PREVIOUS VALUE FOR s;\n+----------------------+\n| PREVIOUS VALUE FOR s |\n+----------------------+\n|                  100 |\n+----------------------+\n\nNow try to start the new connection and check that the last value is still\nNULL, before updating the value in the new connection after the output of the\nnew connection gets current value (110 in the example below). Note that first\nconnection cannot see this change and the result of last value still remains\nthe same (100 in the example above).\n\n$ .mysql -uroot test -e\"SELECT PREVIOUS VALUE FOR s; SELECT NEXT VALUE FOR s;\nSELECT PREVIOUS VALUE FOR s;\"\n+----------------------+\n| PREVIOUS VALUE FOR s |\n+----------------------+\n|                 NULL |\n+----------------------+\n+------------------+\n| NEXT VALUE FOR s |\n+------------------+\n|              110 |\n+------------------+\n+----------------------+\n| PREVIOUS VALUE FOR s |\n+----------------------+\n|                  110 |\n+----------------------+\n\nURL: https://mariadb.com/kb/en/previous-value-for-sequence_name/','','https://mariadb.com/kb/en/previous-value-for-sequence_name/'),(727,'SETVAL',39,'MariaDB starting with 10.3.1\n----------------------------\nSEQUENCEs were introduced in MariaDB 10.3.\n\nSyntax\n------\n\nSETVAL(sequence_name, next_value, [is_used, [round]])\n\nDescription\n-----------\n\nSet the next value to be returned for a SEQUENCE.\n\nThis function is compatible with PostgreSQL syntax, extended with the round\nargument.\n\nIf the is_used argument is not given or is 1 or true, then the next used value\nwill one after the given value. If is_used is 0 or false then the next\ngenerated value will be the given value.\n\nIf round is used then it will set the round value (or the internal cycle\ncount, starting at zero) for the sequence. If round is not used, it\'s assumed\nto be 0.\n\nnext_value must be an integer literal.\n\nFor SEQUENCE tables defined with CYCLE (see CREATE SEQUENCE) one should use\nboth next_value and round to define the next value. In this case the current\nsequence value is defined to be round, next_value.\n\nThe result returned by SETVAL() is next_value or NULL if the given next_value\nand round is smaller than the current value.\n\nSETVAL() will not set the SEQUENCE value to a something that is less than its\ncurrent value. This is needed to ensure that SETVAL() is replication safe. If\nyou want to set the SEQUENCE to a smaller number use ALTER SEQUENCE.\n\nIf CYCLE is used, first round and then next_value are compared to see if the\nvalue is bigger than the current value.\n\nInternally, in the MariaDB server, SETVAL() is used to inform slaves that a\nSEQUENCE has changed value. The slave may get SETVAL() statements out of\norder, but this is ok as only the biggest one will have an effect.\n\nSETVAL requires the INSERT privilege.\n\nExamples\n--------\n\nSELECT setval(foo, 42);           -- Next nextval will return 43\nSELECT setval(foo, 42, true);     -- Same as above\nSELECT setval(foo, 42, false);    -- Next nextval will return 42\n\nSETVAL setting higher and lower values on a sequence with an increment of 10:\n\nSELECT NEXTVAL(s);\n+------------+\n| NEXTVAL(s) |\n+------------+\n|         50 |\n+------------+\n\nSELECT SETVAL(s, 100);\n+----------------+\n| SETVAL(s, 100) |\n+----------------+\n|            100 |\n+----------------+\n\nSELECT NEXTVAL(s);\n+------------+\n| NEXTVAL(s) |\n+------------+\n|        110 |\n+------------+\n\nSELECT SETVAL(s, 50);\n+---------------+\n| SETVAL(s, 50) |\n+---------------+\n|          NULL |\n+---------------+\n\nSELECT NEXTVAL(s);\n+------------+\n| NEXTVAL(s) |\n+------------+\n|        120 |\n+------------+\n\nExample demonstrating round:\n\nCREATE OR REPLACE SEQUENCE s1\n START WITH 1\n MINVALUE 1\n MAXVALUE 99\n INCREMENT BY 1\n CACHE 20\n CYCLE;\n\nSELECT SETVAL(s1, 99, 1, 0);\n+----------------------+\n| SETVAL(s1, 99, 1, 0) |\n+----------------------+\n|                   99 |\n+----------------------+\n\nSELECT NEXTVAL(s1);\n+-------------+\n| NEXTVAL(s1) |\n+-------------+\n|           1 |\n+-------------+\n\nThe following statement returns NULL, as the given next_value and round is\nsmaller than the current value.\n\nSELECT SETVAL(s1, 99, 1, 0);\n+----------------------+\n| SETVAL(s1, 99, 1, 0) |\n+----------------------+\n|                 NULL |\n+----------------------+\n\nSELECT NEXTVAL(s1);\n+-------------+\n| NEXTVAL(s1) |\n+-------------+\n|           2 |\n+-------------+\n\nIncreasing the round from zero to 1 will allow next_value to be returned.\n\nSELECT SETVAL(s1, 99, 1, 1);\n+----------------------+\n| SETVAL(s1, 99, 1, 1) |\n+----------------------+\n|                   99 |\n+----------------------+\n\nSELECT NEXTVAL(s1);\n+-------------+\n| NEXTVAL(s1) |\n+-------------+\n|           1 |\n+-------------+\n\nURL: https://mariadb.com/kb/en/setval/','','https://mariadb.com/kb/en/setval/'),(728,'JSONPath Expressions',40,'A number of JSON functions accept JSON Path expressions. MariaDB defines this\npath as follows:\n\nJSON Path Syntax\n----------------\n\npath : [\'lax\'] \'$\' [step]*\n\nThe path starts with an optional path mode. At the moment, MariaDB supports\nonly the \"lax\" mode, which is also the mode that is used when it is not\nexplicitly specified.\n\nThe $ symbol represents the context item. The search always starts from the\ncontext item; because of that, the path always starts with $.\n\nThen, it is followed by zero or more steps, which select element(s) in the\nJSON document. A step may be one of the following:\n\n* Object member selector\n* Array element selector\n* Wildcard selector\n\nObject Member Selector\n----------------------\n\nTo select member(s) in a JSON object, one can use one of the following:\n\n* .memberName selects the value of the member with name memberName.\n* .\"memberName\" - the same as above but allows one to select a member with a\nname that\'s not a valid identifier (that is, has space, dot, and/or other\ncharacters)\n* .* - selects the values of all members of the object.\n\nIf the current item is an array (instead of an object), nothing will be\nselected.\n\nArray Element Selector\n----------------------\n\nTo select elements of an array, one can use one of the following:\n\n* [N] selects element number N in the array. The elements are counted from\nzero.\n* [*] selects all elements in the array.\n\nIf the current item is an object (instead of an array), nothing will be\nselected.\n\nStarting from MariaDB server 10.9, JSON path also supports negative index in\narray, \'last\' keyword and range notation (\'to\' keyword) for accessing array\nelements. Negative index starts from -1.\n\n* [-N] selects n th element from end.\n* [last-N] selects n th element from the last element.\n* [M to N] selects range of elements starting from index M to N.\n\nExample:\n\nSET @json=\'{\n      \"A\": [0,\n         [1, 2, 3],\n         [4, 5, 6],\n         \"seven\",\n         0.8,\n         true,\n         false,\n         \"eleven\",\n         [12, [13, 14], {\"key1\":\"value1\"},[15]],\n         true],\n      \"B\": {\"C\": 1},\n      \"D\": 2\n     }\';\nSELECT JSON_EXTRACT(@json, \'$.A[-8][1]\');\n+--------------------------------------------------+\n| JSON_EXTRACT(@json, \'$.A[-8][1]\')                |\n+--------------------------------------------------+\n| 5                                                |\n+--------------------------------------------------+\n\nSELECT JSON_EXTRACT(@json, \'$.A[last-7][1]\');\n+-----------------------------------------------+\n| SELECT JSON_EXTRACT(@json, \'$.A[last-7][1]\'); |\n+-----------------------------------------------+\n| 5                                             |\n+-----------------------------------------------+\n\nSET @json= \'[\n      [1, {\"key1\": \"value1\"}, 3],\n      [false, 5, 6],\n      [7, 8, [9, {\"key2\": 2}, 11]],\n      [15, 1.34, [14], [\"string1\", [16, {\"key1\":[1,2,3,[4,5,6]]}, 18]]],\n      [19, 20],\n      21, 22\n      ]\';\n\nSELECT JSON_EXTRACT(@json, \'$[0 to 3][2]\');\n+-----------------------------------------------+\n| JSON_EXTRACT(@json, \'$[0 to 3][2]\')           |\n+-----------------------------------------------+\n| [3, 6, [9, {\"key2\": 2}, 11], [14]]            |\n+-----------------------------------------------+\n\nThis will produce output for first index of eighth from last element of a two\ndimensional array.\n\nNote: In range notation, when M > N ( when M,N are greater than or equal to 0)\nor (size of array - M or size of array - N when M, N are less than 0), then it\nis treated as an impossible range and NULL is returned.\n\nSET @json= \'[1, 2, 3, 4, 5]\';\nSELECT JSON_EXTRACT(@json, \'$[4 to 2]\');\n+-----------------------------------+\n| JSON_EXTRACT(@json, \'$[4 to 2]\')  |\n+-----------------------------------+\n| NULL                              |\n+-----------------------------------+\n\nWildcard\n--------\n\nThe wildcard step, **, recursively selects all child elements of the current\nelement. Both array elements and object members are selected.\n\nThe wildcard step must not be the last step in the JSONPath expression. It\nmust be followed by an array or object member selector step.\n\nFor example:\n\nselect json_extract(@json_doc, \'$**.price\');\n\nwill select all object members in the document that are named price, while\n\nselect json_extract(@json_doc, \'$**[2]\');\n\nwill select the second element in each of the arrays present in the document.\n\nCompatibility\n-------------\n\nMariaDB\'s JSONPath syntax supports a subset of JSON Path\'s definition in the\nSQL Standard. The most notable things not supported are the strict mode and\nfilters.\n\nMariaDB\'s JSONPath is close to MySQL\'s JSONPath. The wildcard step ( ** ) is a\nnon-standard extension that has the same meaning as in MySQL. The differences\nbetween MariaDB and MySQL\'s JSONPath are: MySQL supports [last] and [M to N]\nas array element selectors; MySQL doesn\'t allow one to specify the mode\nexplicitly (but uses lax mode implicitly).\n\nURL: https://mariadb.com/kb/en/jsonpath-expressions/','','https://mariadb.com/kb/en/jsonpath-expressions/'),(729,'JSON_ARRAY',40,'Syntax\n------\n\nJSON_ARRAY([value[, value2] ...])\n\nDescription\n-----------\n\nReturns a JSON array containing the listed values. The list can be empty.\n\nExample\n-------\n\nSELECT Json_Array(56, 3.1416, \'My name is \"Foo\"\', NULL);\n+--------------------------------------------------+\n| Json_Array(56, 3.1416, \'My name is \"Foo\"\', NULL) |\n+--------------------------------------------------+\n| [56, 3.1416, \"My name is \\\"Foo\\\"\", null]         |\n+--------------------------------------------------+\n\nURL: https://mariadb.com/kb/en/json_array/','','https://mariadb.com/kb/en/json_array/'),(730,'JSON_ARRAY_APPEND',40,'Syntax\n------\n\nJSON_ARRAY_APPEND(json_doc, path, value[, path, value] ...)\n\nDescription\n-----------\n\nAppends values to the end of the specified arrays within a JSON document,\nreturning the result, or NULL if any of the arguments are NULL.\n\nEvaluation is performed from left to right, with the resulting document from\nthe previous pair becoming the new value against which the next pair is\nevaluated.\n\nIf the json_doc is not a valid JSON document, or if any of the paths are not\nvalid, or contain a * or ** wildcard, an error is returned.\n\nExamples\n--------\n\nSET @json = \'[1, 2, [3, 4]]\';\n\nSELECT JSON_ARRAY_APPEND(@json, \'$[0]\', 5)\n+-------------------------------------+\n| JSON_ARRAY_APPEND(@json, \'$[0]\', 5) |\n+-------------------------------------+\n| [[1, 5], 2, [3, 4]]                 |\n+-------------------------------------+\n\nSELECT JSON_ARRAY_APPEND(@json, \'$[1]\', 6);\n+-------------------------------------+\n| JSON_ARRAY_APPEND(@json, \'$[1]\', 6) |\n+-------------------------------------+\n| [1, [2, 6], [3, 4]]                 |\n+-------------------------------------+\n\nSELECT JSON_ARRAY_APPEND(@json, \'$[1]\', 6, \'$[2]\', 7);\n+------------------------------------------------+\n| JSON_ARRAY_APPEND(@json, \'$[1]\', 6, \'$[2]\', 7) |\n+------------------------------------------------+\n| [1, [2, 6], [3, 4, 7]]                         |\n+------------------------------------------------+\n\nSELECT JSON_ARRAY_APPEND(@json, \'$\', 5);\n+----------------------------------+\n| JSON_ARRAY_APPEND(@json, \'$\', 5) |\n+----------------------------------+\n| [1, 2, [3, 4], 5]                |\n+----------------------------------+\n\nSET @json = \'{\"A\": 1, \"B\": [2], \"C\": [3, 4]}\';\n\nSELECT JSON_ARRAY_APPEND(@json, \'$.B\', 5);\n+------------------------------------+\n| JSON_ARRAY_APPEND(@json, \'$.B\', 5) |\n+------------------------------------+\n| {\"A\": 1, \"B\": [2, 5], \"C\": [3, 4]} |\n+------------------------------------+\n\nURL: https://mariadb.com/kb/en/json_array_append/','','https://mariadb.com/kb/en/json_array_append/'),(731,'JSON_ARRAY_INSERT',40,'Syntax\n------\n\nJSON_ARRAY_INSERT(json_doc, path, value[, path, value] ...)\n\nDescription\n-----------\n\nInserts a value into a JSON document, returning the modified document, or NULL\nif any of the arguments are NULL.\n\nEvaluation is performed from left to right, with the resulting document from\nthe previous pair becoming the new value against which the next pair is\nevaluated.\n\nIf the json_doc is not a valid JSON document, or if any of the paths are not\nvalid, or contain a * or ** wildcard, an error is returned.\n\nExamples\n--------\n\nSET @json = \'[1, 2, [3, 4]]\';\n\nSELECT JSON_ARRAY_INSERT(@json, \'$[0]\', 5);\n+-------------------------------------+\n| JSON_ARRAY_INSERT(@json, \'$[0]\', 5) |\n+-------------------------------------+\n| [5, 1, 2, [3, 4]]                   |\n+-------------------------------------+\n\nSELECT JSON_ARRAY_INSERT(@json, \'$[1]\', 6);\n+-------------------------------------+\n| JSON_ARRAY_INSERT(@json, \'$[1]\', 6) |\n+-------------------------------------+\n| [1, 6, 2, [3, 4]]                   |\n+-------------------------------------+\n\nSELECT JSON_ARRAY_INSERT(@json, \'$[1]\', 6, \'$[2]\', 7);\n+------------------------------------------------+\n| JSON_ARRAY_INSERT(@json, \'$[1]\', 6, \'$[2]\', 7) |\n+------------------------------------------------+\n| [1, 6, 7, 2, [3, 4]]                           |\n+------------------------------------------------+\n\nURL: https://mariadb.com/kb/en/json_array_insert/','','https://mariadb.com/kb/en/json_array_insert/'),(732,'JSON_COMPACT',40,'Syntax\n------\n\nJSON_COMPACT(json_doc)\n\nDescription\n-----------\n\nRemoves all unnecessary spaces so the json document is as short as possible.\n\nExample\n-------\n\nSET @j = \'{ \"A\": 1, \"B\": [2, 3]}\';\n\nSELECT JSON_COMPACT(@j), @j;\n+-------------------+------------------------+\n| JSON_COMPACT(@j)  | @j                     |\n+-------------------+------------------------+\n| {\"A\":1,\"B\":[2,3]} | { \"A\": 1, \"B\": [2, 3]} |\n+-------------------+------------------------+\n\nURL: https://mariadb.com/kb/en/json_compact/','','https://mariadb.com/kb/en/json_compact/'),(733,'JSON_CONTAINS',40,'Syntax\n------\n\nJSON_CONTAINS(json_doc, val[, path])\n\nDescription\n-----------\n\nReturns whether or not the specified value is found in the given JSON document\nor, optionally, at the specified path within the document. Returns 1 if it\ndoes, 0 if not and NULL if any of the arguments are null. An error occurs if\nthe document or path is not valid, or contains the * or ** wildcards.\n\nExamples\n--------\n\nSET @json = \'{\"A\": 0, \"B\": {\"C\": 1}, \"D\": 2}\';\n\nSELECT JSON_CONTAINS(@json, \'2\', \'$.A\');\n+----------------------------------+\n| JSON_CONTAINS(@json, \'2\', \'$.A\') |\n+----------------------------------+\n|                                0 |\n+----------------------------------+\n\nSELECT JSON_CONTAINS(@json, \'2\', \'$.D\');\n+----------------------------------+\n| JSON_CONTAINS(@json, \'2\', \'$.D\') |\n+----------------------------------+\n|                                1 |\n+----------------------------------+\n\nSELECT JSON_CONTAINS(@json, \'{\"C\": 1}\', \'$.A\');\n+-----------------------------------------+\n| JSON_CONTAINS(@json, \'{\"C\": 1}\', \'$.A\') |\n+-----------------------------------------+\n|                                       0 |\n+-----------------------------------------+\n\nSELECT JSON_CONTAINS(@json, \'{\"C\": 1}\', \'$.B\');\n+-----------------------------------------+\n| JSON_CONTAINS(@json, \'{\"C\": 1}\', \'$.B\') |\n+-----------------------------------------+\n|                                       1 |\n+-----------------------------------------+\n\nURL: https://mariadb.com/kb/en/json_contains/','','https://mariadb.com/kb/en/json_contains/'),(734,'JSON_CONTAINS_PATH',40,'Syntax\n------\n\nJSON_CONTAINS_PATH(json_doc, return_arg, path[, path] ...)\n\nDescription\n-----------\n\nIndicates whether the given JSON document contains data at the specified path\nor paths. Returns 1 if it does, 0 if not and NULL if any of the arguments are\nnull.\n\nThe return_arg can be one or all:\n\n* one - Returns 1 if at least one path exists within the JSON document. \n* all - Returns 1 only if all paths exist within the JSON document.\n\nExamples\n--------\n\nSET @json = \'{\"A\": 1, \"B\": [2], \"C\": [3, 4]}\';\n\nSELECT JSON_CONTAINS_PATH(@json, \'one\', \'$.A\', \'$.D\');\n+------------------------------------------------+\n| JSON_CONTAINS_PATH(@json, \'one\', \'$.A\', \'$.D\') |\n+------------------------------------------------+\n|                                              1 |\n+------------------------------------------------+\n1 row in set (0.00 sec)\n\nSELECT JSON_CONTAINS_PATH(@json, \'all\', \'$.A\', \'$.D\');\n+------------------------------------------------+\n| JSON_CONTAINS_PATH(@json, \'all\', \'$.A\', \'$.D\') |\n+------------------------------------------------+\n|                                              0 |\n+------------------------------------------------+\n\nURL: https://mariadb.com/kb/en/json_contains_path/','','https://mariadb.com/kb/en/json_contains_path/'),(735,'JSON_DEPTH',40,'Syntax\n------\n\nJSON_DEPTH(json_doc)\n\nDescription\n-----------\n\nReturns the maximum depth of the given JSON document, or NULL if the argument\nis null. An error will occur if the argument is an invalid JSON document.\n\n* Scalar values or empty arrays or objects have a depth of 1.\n* Arrays or objects that are not empty but contain only elements or member\nvalues of depth 1 will have a depth of 2.\n* In other cases, the depth will be greater than 2.\n\nExamples\n--------\n\nSELECT JSON_DEPTH(\'[]\'), JSON_DEPTH(\'true\'), JSON_DEPTH(\'{}\');\n+------------------+--------------------+------------------+\n| JSON_DEPTH(\'[]\') | JSON_DEPTH(\'true\') | JSON_DEPTH(\'{}\') |\n+------------------+--------------------+------------------+\n|                1 |                  1 |                1 |\n+------------------+--------------------+------------------+\n\nSELECT JSON_DEPTH(\'[1, 2, 3]\'), JSON_DEPTH(\'[[], {}, []]\');\n+-------------------------+----------------------------+\n| JSON_DEPTH(\'[1, 2, 3]\') | JSON_DEPTH(\'[[], {}, []]\') |\n+-------------------------+----------------------------+\n|                       2 |                          2 |\n+-------------------------+----------------------------+\n\nSELECT JSON_DEPTH(\'[1, 2, [3, 4, 5, 6], 7]\');\n+---------------------------------------+\n| JSON_DEPTH(\'[1, 2, [3, 4, 5, 6], 7]\') |\n+---------------------------------------+\n|                                     3 |\n+---------------------------------------+\n\nURL: https://mariadb.com/kb/en/json_depth/','','https://mariadb.com/kb/en/json_depth/'),(736,'JSON_DETAILED',40,'Syntax\n------\n\nJSON_DETAILED(json_doc[, tab_size])\n\nDescription\n-----------\n\nRepresents JSON in the most understandable way emphasizing nested structures.\n\nExample\n-------\n\nSET @j = \'{ \"A\":1,\"B\":[2,3]}\';\n\nSELECT @j;\n+--------------------+\n| @j                 |\n+--------------------+\n| { \"A\":1,\"B\":[2,3]} |\n+--------------------+\n\nSELECT JSON_DETAILED(@j);\n+------------------------------------------------------------+\n| JSON_DETAILED(@j)                                          |\n+------------------------------------------------------------+\n| {\n  \"A\": 1,\n  \"B\":\n  [\n    2,\n    3\n  ]\n} |\n+------------------------------------------------------------+\n\nURL: https://mariadb.com/kb/en/json_detailed/','','https://mariadb.com/kb/en/json_detailed/'),(737,'JSON_EXISTS',40,'Syntax\n------\n\nDescription\n-----------\n\nDetermines whether a specified JSON value exists in the given data. Returns 1\nif found, 0 if not, or NULL if any of the inputs were NULL.\n\nExamples\n--------\n\nSELECT JSON_EXISTS(\'{\"key1\":\"xxxx\", \"key2\":[1, 2, 3]}\', \"$.key2\");\n+------------------------------------------------------------+\n| JSON_EXISTS(\'{\"key1\":\"xxxx\", \"key2\":[1, 2, 3]}\', \"$.key2\") |\n+------------------------------------------------------------+\n|                                                          1 |\n+------------------------------------------------------------+\n\nSELECT JSON_EXISTS(\'{\"key1\":\"xxxx\", \"key2\":[1, 2, 3]}\', \"$.key3\");\n+------------------------------------------------------------+\n| JSON_EXISTS(\'{\"key1\":\"xxxx\", \"key2\":[1, 2, 3]}\', \"$.key3\") |\n+------------------------------------------------------------+\n|                                                          0 |\n+------------------------------------------------------------+\n\nSELECT JSON_EXISTS(\'{\"key1\":\"xxxx\", \"key2\":[1, 2, 3]}\', \"$.key2[1]\");\n+---------------------------------------------------------------+\n| JSON_EXISTS(\'{\"key1\":\"xxxx\", \"key2\":[1, 2, 3]}\', \"$.key2[1]\") |\n+---------------------------------------------------------------+\n|                                                             1 |\n+---------------------------------------------------------------+\n\nSELECT JSON_EXISTS(\'{\"key1\":\"xxxx\", \"key2\":[1, 2, 3]}\', \"$.key2[10]\");\n+----------------------------------------------------------------+\n| JSON_EXISTS(\'{\"key1\":\"xxxx\", \"key2\":[1, 2, 3]}\', \"$.key2[10]\") |\n+----------------------------------------------------------------+\n|                                                              0 |\n+----------------------------------------------------------------+\n\nURL: https://mariadb.com/kb/en/json_exists/','','https://mariadb.com/kb/en/json_exists/'),(738,'JSON_EXTRACT',40,'Syntax\n------\n\nJSON_EXTRACT(json_doc, path[, path] ...)\n\nDescription\n-----------\n\nExtracts data from a JSON document. The extracted data is selected from the\nparts matching the path arguments. Returns all matched values; either as a\nsingle matched value, or, if the arguments could return multiple values, a\nresult autowrapped as an array in the matching order.\n\nReturns NULL if no paths match or if any of the arguments are NULL.\n\nAn error will occur if any path argument is not a valid path, or if the\njson_doc argument is not a valid JSON document.\n\nThe path expression be a JSONPath expression as supported by MariaDB\n\nExamples\n--------\n\nSET @json = \'[1, 2, [3, 4]]\';\n\nSELECT JSON_EXTRACT(@json, \'$[1]\');\n+-----------------------------+\n| JSON_EXTRACT(@json, \'$[1]\') |\n+-----------------------------+\n| 2                           |\n+-----------------------------+\n\nSELECT JSON_EXTRACT(@json, \'$[2]\');\n+-----------------------------+\n| JSON_EXTRACT(@json, \'$[2]\') |\n+-----------------------------+\n| [3, 4]                      |\n+-----------------------------+\n\nSELECT JSON_EXTRACT(@json, \'$[2][1]\');\n+--------------------------------+\n| JSON_EXTRACT(@json, \'$[2][1]\') |\n+--------------------------------+\n| 4                              |\n+--------------------------------+\n\nURL: https://mariadb.com/kb/en/json_extract/','','https://mariadb.com/kb/en/json_extract/'),(739,'JSON_INSERT',40,'Syntax\n------\n\nJSON_INSERT(json_doc, path, val[, path, val] ...)\n\nDescription\n-----------\n\nInserts data into a JSON document, returning the resulting document or NULL if\nany argument is null.\n\nAn error will occur if the JSON document is not invalid, or if any of the\npaths are invalid or contain a * or ** wildcard.\n\nJSON_INSERT can only insert data while JSON_REPLACE can only update. JSON_SET\ncan update or insert data.\n\nExamples\n--------\n\nSET @json = \'{ \"A\": 0, \"B\": [1, 2]}\';\n\nSELECT JSON_INSERT(@json, \'$.C\', \'[3, 4]\');\n+--------------------------------------+\n| JSON_INSERT(@json, \'$.C\', \'[3, 4]\')  |\n+--------------------------------------+\n| { \"A\": 0, \"B\": [1, 2], \"C\":\"[3, 4]\"} |\n+--------------------------------------+\n\nURL: https://mariadb.com/kb/en/json_insert/','','https://mariadb.com/kb/en/json_insert/'),(740,'JSON_KEYS',40,'Syntax\n------\n\nJSON_KEYS(json_doc[, path])\n\nDescription\n-----------\n\nReturns the keys as a JSON array from the top-level value of a JSON object or,\nif the optional path argument is provided, the top-level keys from the path.\n\nExcludes keys from nested sub-objects in the top level value. The resulting\narray will be empty if the selected object is empty.\n\nReturns NULL if any of the arguments are null, a given path does not locate an\nobject, or if the json_doc argument is not an object.\n\nAn error will occur if JSON document is invalid, the path is invalid or if the\npath contains a * or ** wildcard.\n\nExamples\n--------\n\nSELECT JSON_KEYS(\'{\"A\": 1, \"B\": {\"C\": 2}}\');\n+--------------------------------------+\n| JSON_KEYS(\'{\"A\": 1, \"B\": {\"C\": 2}}\') |\n+--------------------------------------+\n| [\"A\", \"B\"]                           |\n+--------------------------------------+\n\nSELECT JSON_KEYS(\'{\"A\": 1, \"B\": 2, \"C\": {\"D\": 3}}\', \'$.C\');\n+-----------------------------------------------------+\n| JSON_KEYS(\'{\"A\": 1, \"B\": 2, \"C\": {\"D\": 3}}\', \'$.C\') |\n+-----------------------------------------------------+\n| [\"D\"]                                               |\n+-----------------------------------------------------+\n\nURL: https://mariadb.com/kb/en/json_keys/','','https://mariadb.com/kb/en/json_keys/'),(741,'JSON_LENGTH',40,'Syntax\n------\n\nJSON_LENGTH(json_doc[, path])\n\nDescription\n-----------\n\nReturns the length of a JSON document, or, if the optional path argument is\ngiven, the length of the value within the document specified by the path.\n\nReturns NULL if any of the arguments argument are null or the path argument\ndoes not identify a value in the document.\n\nAn error will occur if the JSON document is invalid, the path is invalid or if\nthe path contains a * or ** wildcard.\n\nLength will be determined as follow:\n\n* A scalar\'s length is always 1.\n* If an array, the number of elements in the array.\n* If an object, the number of members in the object.\n\nThe length of nested arrays or objects are not counted.\n\nExamples\n--------\n\nURL: https://mariadb.com/kb/en/json_length/','','https://mariadb.com/kb/en/json_length/'),(742,'JSON_LOOSE',40,'Syntax\n------\n\nJSON_LOOSE(json_doc)\n\nDescription\n-----------\n\nAdds spaces to a JSON document to make it look more readable.\n\nExample\n-------\n\nSET @j = \'{ \"A\":1,\"B\":[2,3]}\';\n\nSELECT JSON_LOOSE(@j), @j;\n+-----------------------+--------------------+\n| JSON_LOOSE(@j)        | @j                 |\n+-----------------------+--------------------+\n| {\"A\": 1, \"B\": [2, 3]} | { \"A\":1,\"B\":[2,3]} |\n+-----------------------+--------------------+\n\nURL: https://mariadb.com/kb/en/json_loose/','','https://mariadb.com/kb/en/json_loose/'),(743,'JSON_MERGE',40,'Syntax\n------\n\nJSON_MERGE(json_doc, json_doc[, json_doc] ...)\n\nDescription\n-----------\n\nMerges the given JSON documents.\n\nReturns the merged result,or NULL if any argument is NULL.\n\nAn error occurs if any of the arguments are not valid JSON documents.\n\nJSON_MERGE has been deprecated since MariaDB 10.2.25, MariaDB 10.3.16 and\nMariaDB 10.4.5. JSON_MERGE_PATCH is an RFC 7396-compliant replacement, and\nJSON_MERGE_PRESERVE is a synonym.\n\nExample\n-------\n\nSET @json1 = \'[1, 2]\';\nSET @json2 = \'[3, 4]\';\n\nSELECT JSON_MERGE(@json1,@json2);\n+---------------------------+\n| JSON_MERGE(@json1,@json2) |\n+---------------------------+\n| [1, 2, 3, 4]              |\n+---------------------------+\n\nURL: https://mariadb.com/kb/en/json_merge/','','https://mariadb.com/kb/en/json_merge/'),(744,'JSON_MERGE_PATCH',40,'MariaDB starting with 10.2.25\n-----------------------------\nJSON_MERGE_PATCH was introduced in MariaDB 10.2.25, MariaDB 10.3.16 and\nMariaDB 10.4.5.\n\nSyntax\n------\n\nJSON_MERGE_PATCH(json_doc, json_doc[, json_doc] ...)\n\nDescription\n-----------\n\nMerges the given JSON documents, returning the merged result, or NULL if any\nargument is NULL.\n\nJSON_MERGE_PATCH is an RFC 7396-compliant replacement for JSON_MERGE, which\nhas been deprecated.\n\nExample\n-------\n\nSET @json1 = \'[1, 2]\';\nSET @json2 = \'[2, 3]\';\nSELECT JSON_MERGE_PATCH(@json1,@json2),JSON_MERGE_PRESERVE(@json1,@json2);\n+---------------------------------+------------------------------------+\n| JSON_MERGE_PATCH(@json1,@json2) | JSON_MERGE_PRESERVE(@json1,@json2) |\n+---------------------------------+------------------------------------+\n| [2, 3]                          | [1, 2, 2, 3]                       |\n+---------------------------------+------------------------------------+\n\nURL: https://mariadb.com/kb/en/json_merge_patch/','','https://mariadb.com/kb/en/json_merge_patch/'),(745,'JSON_MERGE_PRESERVE',40,'MariaDB starting with 10.2.25\n-----------------------------\nJSON_MERGE_PRESERVE was introduced in MariaDB 10.2.25, MariaDB 10.3.16 and\nMariaDB 10.4.5.\n\nSyntax\n------\n\nJSON_MERGE_PRESERVE(json_doc, json_doc[, json_doc] ...)\n\nDescription\n-----------\n\nMerges the given JSON documents, returning the merged result, or NULL if any\nargument is NULL.\n\nJSON_MERGE_PRESERVE was introduced in MariaDB 10.2.25, MariaDB 10.3.16 and\nMariaDB 10.4.5 as a synonym for JSON_MERGE, which has been deprecated.\n\nExample\n-------\n\nSET @json1 = \'[1, 2]\';\nSET @json2 = \'[2, 3]\';\nSELECT JSON_MERGE_PATCH(@json1,@json2),JSON_MERGE_PRESERVE(@json1,@json2);\n+---------------------------------+------------------------------------+\n| JSON_MERGE_PATCH(@json1,@json2) | JSON_MERGE_PRESERVE(@json1,@json2) |\n+---------------------------------+------------------------------------+\n| [2, 3]                          | [1, 2, 2, 3]                       |\n+---------------------------------+------------------------------------+\n\nURL: https://mariadb.com/kb/en/json_merge_preserve/','','https://mariadb.com/kb/en/json_merge_preserve/'),(746,'JSON_OBJECT',40,'Syntax\n------\n\nJSON_OBJECT([key, value[, key, value] ...])\n\nDescription\n-----------\n\nReturns a JSON object containing the given key/value pairs. The key/value list\ncan be empty.\n\nAn error will occur if there are an odd number of arguments, or any key name\nis NULL.\n\nExample\n-------\n\nSELECT JSON_OBJECT(\"id\", 1, \"name\", \"Monty\");\n+---------------------------------------+\n| JSON_OBJECT(\"id\", 1, \"name\", \"Monty\") |\n+---------------------------------------+\n| {\"id\": 1, \"name\": \"Monty\"}            |\n+---------------------------------------+\n\nURL: https://mariadb.com/kb/en/json_object/','','https://mariadb.com/kb/en/json_object/'),(747,'JSON_QUERY',40,'Syntax\n------\n\nJSON_QUERY(json_doc, path)\n\nDescription\n-----------\n\nGiven a JSON document, returns an object or array specified by the path.\nReturns NULL if not given a valid JSON document, or if there is no match.\n\nExamples\n--------\n\nselect json_query(\'{\"key1\":{\"a\":1, \"b\":[1,2]}}\', \'$.key1\');\n+-----------------------------------------------------+\n| json_query(\'{\"key1\":{\"a\":1, \"b\":[1,2]}}\', \'$.key1\') |\n+-----------------------------------------------------+\n| {\"a\":1, \"b\":[1,2]}                                  |\n+-----------------------------------------------------+\n\nselect json_query(\'{\"key1\":123, \"key1\": [1,2,3]}\', \'$.key1\');\n+-------------------------------------------------------+\n| json_query(\'{\"key1\":123, \"key1\": [1,2,3]}\', \'$.key1\') |\n+-------------------------------------------------------+\n| [1,2,3]                                               |\n+-------------------------------------------------------+\n\nURL: https://mariadb.com/kb/en/json_query/','','https://mariadb.com/kb/en/json_query/'),(748,'JSON_QUOTE',40,'Syntax\n------\n\nJSON_QUOTE(json_value)\n\nDescription\n-----------\n\nQuotes a string as a JSON value, usually for producing valid JSON string\nliterals for inclusion in JSON documents. Wraps the string with double quote\ncharacters and escapes interior quotes and other special characters, returning\na utf8mb4 string.\n\nReturns NULL if the argument is NULL.\n\nExamples\n--------\n\nSELECT JSON_QUOTE(\'A\'), JSON_QUOTE(\"B\"), JSON_QUOTE(\'\"C\"\');\n+-----------------+-----------------+-------------------+\n| JSON_QUOTE(\'A\') | JSON_QUOTE(\"B\") | JSON_QUOTE(\'\"C\"\') |\n+-----------------+-----------------+-------------------+\n| \"A\"             | \"B\"             | \"\\\"C\\\"\"           |\n+-----------------+-----------------+-------------------+\n\nURL: https://mariadb.com/kb/en/json_quote/','','https://mariadb.com/kb/en/json_quote/'),(749,'JSON_REMOVE',40,'Syntax\n------\n\nJSON_REMOVE(json_doc, path[, path] ...)\n\nDescription\n-----------\n\nRemoves data from a JSON document returning the result, or NULL if any of the\narguments are null. If the element does not exist in the document, no changes\nare made.\n\nAn error will occur if JSON document is invalid, the path is invalid or if the\npath contains a * or ** wildcard.\n\nPath arguments are evaluated from left to right, with the result from the\nearlier evaluation being used as the value for the next.\n\nExamples\n--------\n\nSELECT JSON_REMOVE(\'{\"A\": 1, \"B\": 2, \"C\": {\"D\": 3}}\', \'$.C\');\n+-------------------------------------------------------+\n| JSON_REMOVE(\'{\"A\": 1, \"B\": 2, \"C\": {\"D\": 3}}\', \'$.C\') |\n+-------------------------------------------------------+\n| {\"A\": 1, \"B\": 2}                                      |\n+-------------------------------------------------------+\n\nSELECT JSON_REMOVE(\'[\"A\", \"B\", [\"C\", \"D\"], \"E\"]\', \'$[1]\');\n+----------------------------------------------------+\n| JSON_REMOVE(\'[\"A\", \"B\", [\"C\", \"D\"], \"E\"]\', \'$[1]\') |\n+----------------------------------------------------+\n| [\"A\", [\"C\", \"D\"], \"E\"]                             |\n+----------------------------------------------------+\n\nURL: https://mariadb.com/kb/en/json_remove/','','https://mariadb.com/kb/en/json_remove/'),(750,'JSON_REPLACE',40,'Syntax\n------\n\nJSON_REPLACE(json_doc, path, val[, path, val] ...)\n\nDescription\n-----------\n\nReplaces existing values in a JSON document, returning the result, or NULL if\nany of the arguments are NULL.\n\nAn error will occur if the JSON document is invalid, the path is invalid or if\nthe path contains a * or ** wildcard.\n\nPaths and values are evaluated from left to right, with the result from the\nearlier evaluation being used as the value for the next.\n\nJSON_REPLACE can only update data, while JSON_INSERT can only insert. JSON_SET\ncan update or insert data.\n\nExamples\n--------\n\nSELECT JSON_REPLACE(\'{ \"A\": 1, \"B\": [2, 3]}\', \'$.B[1]\', 4);\n+-----------------------------------------------------+\n| JSON_REPLACE(\'{ \"A\": 1, \"B\": [2, 3]}\', \'$.B[1]\', 4) |\n+-----------------------------------------------------+\n| { \"A\": 1, \"B\": [2, 4]}                              |\n+-----------------------------------------------------+\n\nURL: https://mariadb.com/kb/en/json_replace/','','https://mariadb.com/kb/en/json_replace/'),(751,'JSON_SEARCH',40,'Syntax\n------\n\nJSON_SEARCH(json_doc, return_arg, search_str[, escape_char[, path] ...])\n\nDescription\n-----------\n\nReturns the path to the given string within a JSON document, or NULL if any of\njson_doc, search_str or a path argument is NULL; if the search string is not\nfound, or if no path exists within the document.\n\nA warning will occur if the JSON document is not valid, any of the path\narguments are not valid, if return_arg is neither one nor all, or if the\nescape character is not a constant. NULL will be returned.\n\nreturn_arg can be one of two values:\n\n* \'one: Terminates after finding the first match, so will return one path\nstring. If there is more than one match, it is undefined which is considered\nfirst.\n* all: Returns all matching path strings, without duplicates. Multiple strings\nare autowrapped as an array. The order is undefined.\n\nExamples\n--------\n\nSET @json = \'[\"A\", [{\"B\": \"1\"}], {\"C\":\"AB\"}, {\"D\":\"BC\"}]\';\n\nSELECT JSON_SEARCH(@json, \'one\', \'AB\');\n+---------------------------------+\n| JSON_SEARCH(@json, \'one\', \'AB\') |\n+---------------------------------+\n| \"$[2].C\"                        |\n+---------------------------------+\n\nURL: https://mariadb.com/kb/en/json_search/','','https://mariadb.com/kb/en/json_search/'),(752,'JSON_SET',40,'Syntax\n------\n\nJSON_SET(json_doc, path, val[, path, val] ...)\n\nDescription\n-----------\n\nUpdates or inserts data into a JSON document, returning the result, or NULL if\nany of the arguments are NULL or the optional path fails to find an object.\n\nAn error will occur if the JSON document is invalid, the path is invalid or if\nthe path contains a * or wildcard.\n\nJSON_SET can update or insert data, while JSON_REPLACE can only update, and\nJSON_INSERT only insert.\n\nExamples\n--------\n\nSELECT JSON_SET(Priv, \'$.locked\', \'true\') FROM mysql.global_priv\n\nURL: https://mariadb.com/kb/en/json_set/','','https://mariadb.com/kb/en/json_set/'),(753,'JSON_TYPE',40,'Syntax\n------\n\nJSON_TYPE(json_val)\n\nDescription\n-----------\n\nReturns the type of a JSON value (as a string), or NULL if the argument is\nnull.\n\nAn error will occur if the argument is an invalid JSON value.\n\nThe following is a complete list of the possible return types:\n\n+-----------------------------------+-----------------+-----------------------+\n| Return type                       | Value           | Example               |\n+-----------------------------------+-----------------+-----------------------+\n| ARRAY                             | JSON array      | [1, 2, {\"key\":        |\n|                                   |                 | \"value\"}]             |\n+-----------------------------------+-----------------+-----------------------+\n| OBJECT                            | JSON object     | {\"key\":\"value\"}       |\n+-----------------------------------+-----------------+-----------------------+\n| BOOLEAN                           | JSON            | true, false           |\n|                                   | true/false      |                       |\n|                                   | literals        |                       |\n+-----------------------------------+-----------------+-----------------------+\n| DOUBLE                            | A number with   | 1.2                   |\n|                                   | at least one    |                       |\n|                                   | floating point  |                       |\n|                                   | decimal.        |                       |\n+-----------------------------------+-----------------+-----------------------+\n| INTEGER                           | A number        | 1                     |\n|                                   | without a       |                       |\n|                                   | floating point  |                       |\n|                                   | decimal.        |                       |\n+-----------------------------------+-----------------+-----------------------+\n| NULL                              | JSON null       | null                  |\n|                                   | literal (this   |                       |\n|                                   | is returned as  |                       |\n|                                   | a string, not   |                       |\n|                                   | to be confused  |                       |\n|                                   | with the SQL    |                       |\n|                                   | NULL value!)    |                       |\n+-----------------------------------+-----------------+-----------------------+\n| STRING                            | JSON String     | \"a sample string\"     |\n+-----------------------------------+-----------------+-----------------------+\n\nExamples\n--------\n\nSELECT JSON_TYPE(\'{\"A\": 1, \"B\": 2, \"C\": 3}\');\n+---------------------------------------+\n| JSON_TYPE(\'{\"A\": 1, \"B\": 2, \"C\": 3}\') |\n+---------------------------------------+\n| OBJECT                                |\n+---------------------------------------+\n\nURL: https://mariadb.com/kb/en/json_type/','','https://mariadb.com/kb/en/json_type/'),(754,'JSON_UNQUOTE',40,'Syntax\n------\n\nJSON_UNQUOTE(val)\n\nDescription\n-----------\n\nUnquotes a JSON value, returning a string, or NULL if the argument is null.\n\nAn error will occur if the given value begins and ends with double quotes and\nis an invalid JSON string literal.\n\nIf the given value is not a JSON string, value is passed through unmodified.\n\nCertain character sequences have special meanings within a string. Usually, a\nbackslash is ignored, but the escape sequences in the table below are\nrecognised by MariaDB, unless the SQL Mode is set to NO_BACKSLASH_ESCAPES SQL.\n\n+-----------------------------------------------+-----------------------------+\n| Escape sequence                               | Character                   |\n+-----------------------------------------------+-----------------------------+\n| \\\"                                            | Double quote (\")            |\n+-----------------------------------------------+-----------------------------+\n| \\b                                            | Backslash                   |\n+-----------------------------------------------+-----------------------------+\n| \\f                                            | Formfeed                    |\n+-----------------------------------------------+-----------------------------+\n| \\n                                            | Newline (linefeed)          |\n+-----------------------------------------------+-----------------------------+\n| \\r                                            | Carriage return             |\n+-----------------------------------------------+-----------------------------+\n| \\t                                            | Tab                         |\n+-----------------------------------------------+-----------------------------+\n| \\\\                                            | Backslash (\\)               |\n+-----------------------------------------------+-----------------------------+\n| \\uXXXX                                        | UTF-8 bytes for Unicode     |\n|                                               | value XXXX                  |\n+-----------------------------------------------+-----------------------------+\n\nExamples\n--------\n\nSELECT JSON_UNQUOTE(\'\"Monty\"\');\n+-------------------------+\n| JSON_UNQUOTE(\'\"Monty\"\') |\n+-------------------------+\n| Monty                   |\n+-------------------------+\n\nWith the default SQL Mode:\n\nSELECT JSON_UNQUOTE(\'Si\\bng\\ting\');\n+-----------------------------+\n| JSON_UNQUOTE(\'Si\\bng\\ting\') |\n+-----------------------------+\n| Sng	ing                   |\n+-----------------------------+\n\nSetting NO_BACKSLASH_ESCAPES:\n\nSET @@sql_mode = \'NO_BACKSLASH_ESCAPES\';\n\nSELECT JSON_UNQUOTE(\'Si\\bng\\ting\');\n+-----------------------------+\n| JSON_UNQUOTE(\'Si\\bng\\ting\') |\n+-----------------------------+\n| Si\\bng\\ting                 |\n+-----------------------------+\n\nURL: https://mariadb.com/kb/en/json_unquote/','','https://mariadb.com/kb/en/json_unquote/'),(755,'JSON_VALID',40,'Syntax\n------\n\nJSON_VALID(value)\n\nDescription\n-----------\n\nIndicates whether the given value is a valid JSON document or not. Returns 1\nif valid, 0 if not, and NULL if the argument is NULL.\n\nFrom MariaDB 10.4.3, the JSON_VALID function is automatically used as a CHECK\nconstraint for the JSON data type alias in order to ensure that a valid json\ndocument is inserted.\n\nExamples\n--------\n\nSELECT JSON_VALID(\'{\"id\": 1, \"name\": \"Monty\"}\');\n+------------------------------------------+\n| JSON_VALID(\'{\"id\": 1, \"name\": \"Monty\"}\') |\n+------------------------------------------+\n|                                        1 |\n+------------------------------------------+\n\nSELECT JSON_VALID(\'{\"id\": 1, \"name\": \"Monty\", \"oddfield\"}\');\n+------------------------------------------------------+\n| JSON_VALID(\'{\"id\": 1, \"name\": \"Monty\", \"oddfield\"}\') |\n+------------------------------------------------------+\n|                                                    0 |\n+------------------------------------------------------+\n\nURL: https://mariadb.com/kb/en/json_valid/','','https://mariadb.com/kb/en/json_valid/'),(756,'JSON_VALUE',40,'Syntax\n------\n\nJSON_VALUE(json_doc, path)\n\nDescription\n-----------\n\nGiven a JSON document, returns the scalar specified by the path. Returns NULL\nif not given a valid JSON document, or if there is no match.\n\nExamples\n--------\n\nselect json_value(\'{\"key1\":123}\', \'$.key1\');\n+--------------------------------------+\n| json_value(\'{\"key1\":123}\', \'$.key1\') |\n+--------------------------------------+\n| 123                                  |\n+--------------------------------------+\n\nselect json_value(\'{\"key1\": [1,2,3], \"key1\":123}\', \'$.key1\');\n+-------------------------------------------------------+\n| json_value(\'{\"key1\": [1,2,3], \"key1\":123}\', \'$.key1\') |\n+-------------------------------------------------------+\n| 123                                                   |\n+-------------------------------------------------------+\n\nIn the SET statement below, two escape characters are needed, as a single\nescape character would be applied by the SQL parser in the SET statement, and\nthe escaped character would not form part of the saved value.\n\nSET @json = \'{\"key1\":\"60\\\\\" Table\", \"key2\":\"1\"}\';\n\nSELECT JSON_VALUE(@json,\'$.key1\') AS Name , json_value(@json,\'$.key2\') as ID;\n+-----------+------+\n| Name      | ID   |\n+-----------+------+\n| 60\" Table | 1    |\n+-----------+------+\n\nURL: https://mariadb.com/kb/en/json_value/','','https://mariadb.com/kb/en/json_value/'),(757,'Window Functions Overview',41,'Introduction\n------------\n\nWindow functions allow calculations to be performed across a set of rows\nrelated to the current row.\n\nSyntax\n------\n\nfunction (expression) OVER (\n [ PARTITION BY expression_list ]\n [ ORDER BY order_list [ frame_clause ] ] )\n\nfunction:\n A valid window function\n\nexpression_list:\n expression | column_name [, expr_list ]\n\norder_list:\n expression | column_name [ ASC | DESC ]\n [, ... ]\n\nframe_clause:\n {ROWS | RANGE} {frame_border | BETWEEN frame_border AND frame_border}\n\nframe_border:\n | UNBOUNDED PRECEDING\n | UNBOUNDED FOLLOWING\n | CURRENT ROW\n | expr PRECEDING\n | expr FOLLOWING\n\nDescription\n-----------\n\nIn some ways, window functions are similar to aggregate functions in that they\nperform calculations across a set of rows. However, unlike aggregate\nfunctions, the output is not grouped into a single row.\n\nNon-aggregate window functions include\n\n* CUME_DIST\n* DENSE_RANK\n* FIRST_VALUE\n* LAG\n* LAST_VALUE\n* LEAD\n* MEDIAN\n* NTH_VALUE\n* NTILE\n* PERCENT_RANK\n* PERCENTILE_CONT\n* PERCENTILE_DISC\n* RANK, ROW_NUMBER\n\nAggregate functions that can also be used as window functions include\n\n* AVG\n* BIT_AND\n* BIT_OR\n* BIT_XOR\n* COUNT\n* MAX\n* MIN\n* STD\n* STDDEV\n* STDDEV_POP\n* STDDEV_SAMP\n* SUM\n* VAR_POP\n* VAR_SAMP\n* VARIANCE\n\nWindow function queries are characterised by the OVER keyword, following which\nthe set of rows used for the calculation is specified. By default, the set of\nrows used for the calculation (the \"window) is the entire dataset, which can\nbe ordered with the ORDER BY clause. The PARTITION BY clause is used to reduce\nthe window to a particular group within the dataset.\n\nFor example, given the following data:\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\nthe following two queries return the average partitioned by test and by name\nrespectively:\n\nSELECT name, test, score, AVG(score) OVER (PARTITION BY test) \n AS average_by_test FROM student;\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\nSELECT name, test, score, AVG(score) OVER (PARTITION BY name) \n AS average_by_name FROM student;\n+---------+--------+-------+-----------------+\n| name    | test   | score | average_by_name |\n+---------+--------+-------+-----------------+\n| Chun    | SQL    |    75 |         74.0000 |\n| Chun    | Tuning |    73 |         74.0000 |\n| Esben   | SQL    |    43 |         37.0000 |\n| Esben   | Tuning |    31 |         37.0000 |\n| Kaolin  | SQL    |    56 |         72.0000 |\n| Kaolin  | Tuning |    88 |         72.0000 |\n| Tatiana | SQL    |    87 |         85.0000 |\n| Tatiana | Tuning |    83 |         85.0000 |\n+---------+--------+-------+-----------------+\n\nIt is also possible to specify which rows to include for the window function\n(for example, the current row and all preceding rows). See Window Frames for\nmore details.\n\nScope\n-----\n\nWindow functions were introduced in SQL:2003, and their definition was\nexpanded in subsequent versions of the standard. The last expansion was in the\nlatest version of the standard, SQL:2011.\n\nMost database products support a subset of the standard, they implement some\nfunctions defined as late as in SQL:2011, and at the same time leave some\nparts of SQL:2008 unimplemented.\n\nMariaDB:\n\n* Supports ROWS and RANGE-type frames\nAll kinds of frame bounds are supported, including RANGE PRECEDING|FOLLOWING n\nframe bounds (unlike PostgreSQL or MS SQL Server)\nDoes not yet support DATE[TIME] datatype and arithmetic for RANGE-type frames\n(MDEV-9727)\n\n* Does not support GROUPS-type frames (it seems that no popular database\nsupports it, either)\n\n* Does not support frame exclusion (no other database seems to support it,\neither) (MDEV-9724)\n* Does not support explicit NULLS FIRST or NULLS LAST.\n* Does not support nested navigation in window functions (this is\nVALUE_OF(expr AT row_marker [, default_value) syntax)\n\n* The following window functions are supported:\n\"Streamable\" window functions: ROW_NUMBER, RANK, DENSE_RANK, \nWindow functions that can be streamed once the number of rows in partition is\nknown: PERCENT_RANK, CUME_DIST, NTILE\n\n* Aggregate functions that are currently supported as window functions are:\nCOUNT, SUM, AVG, BIT_OR, BIT_AND, BIT_XOR.\n* Aggregate functions with the DISTINCT specifier (e.g. COUNT( DISTINCT x))\nare not supported as window functions.\n\nLinks\n-----\n\n* MDEV-6115 is the main jira task for window functions development. Other\ntasks are are attached as sub-tasks\n* bb-10.2-mdev9543 is the feature tree for window functions. Development is\nongoing, and this tree has the newest changes.\n* Testcases are in mysql-test/t/win*.test\n\nExamples\n--------\n\nGiven the following sample data:\n\nCREATE TABLE users (\n email VARCHAR(30),\n first_name VARCHAR(30),\n last_name VARCHAR(30),\n account_type VARCHAR(30)\n);\n\nINSERT INTO users VALUES \n (\'admin@boss.org\', \'Admin\', \'Boss\', \'admin\'),\n (\'bob.carlsen@foo.bar\', \'Bob\', \'Carlsen\', \'regular\'),\n (\'eddie.stevens@data.org\', \'Eddie\', \'Stevens\', \'regular\'),\n (\'john.smith@xyz.org\', \'John\', \'Smith\', \'regular\'),\n (\'root@boss.org\', \'Root\', \'Chief\', \'admin\')\n\nFirst, let\'s order the records by email alphabetically, giving each an\nascending rnum value starting with 1. This will make use of the ROW_NUMBER\nwindow function:\n\nSELECT row_number() OVER (ORDER BY email) AS rnum,\n  email, first_name, last_name, account_type\nFROM users ORDER BY email;\n+------+------------------------+------------+-----------+--------------+\n| rnum | email                  | first_name | last_name | account_type |\n+------+------------------------+------------+-----------+--------------+\n|    1 | admin@boss.org         | Admin      | Boss      | admin        |\n|    2 | bob.carlsen@foo.bar    | Bob        | Carlsen   | regular      |\n|    3 | eddie.stevens@data.org | Eddie      | Stevens   | regular      |\n|    4 | john.smith@xyz.org     | John       | Smith     | regular      |\n|    5 | root@boss.org          | Root       | Chief     | admin        |\n+------+------------------------+------------+-----------+--------------\n\nWe can generate separate sequences based on account type, using the PARTITION\nBY clause:\n\nSELECT row_number() OVER (PARTITION BY account_type ORDER BY email) AS rnum, \n email, first_name, last_name, account_type\nFROM users ORDER BY account_type,email;\n+------+------------------------+------------+-----------+--------------+\n| rnum | email                  | first_name | last_name | account_type |\n+------+------------------------+------------+-----------+--------------+\n|    1 | admin@boss.org         | Admin      | Boss      | admin        |\n|    2 | root@boss.org          | Root       | Chief     | admin        |\n|    1 | bob.carlsen@foo.bar    | Bob        | Carlsen   | regular      |\n|    2 | eddie.stevens@data.org | Eddie      | Stevens   | regular      |\n|    3 | john.smith@xyz.org     | John       | Smith     | regular      |\n+------+------------------------+------------+-----------+--------------+\n\nGiven the following structure and data, we want to find the top 5 salaries\nfrom each department.\n\nCREATE TABLE employee_salaries (dept VARCHAR(20), name VARCHAR(20), salary\nINT(11));\n\nINSERT INTO employee_salaries VALUES\n(\'Engineering\', \'Dharma\', 3500),\n(\'Engineering\', \'Binh\', 3000),\n(\'Engineering\', \'Adalynn\', 2800),\n(\'Engineering\', \'Samuel\', 2500),\n(\'Engineering\', \'Cveta\', 2200),\n(\'Engineering\', \'Ebele\', 1800),\n(\'Sales\', \'Carbry\', 500),\n(\'Sales\', \'Clytemnestra\', 400),\n(\'Sales\', \'Juraj\', 300),\n(\'Sales\', \'Kalpana\', 300),\n(\'Sales\', \'Svantepolk\', 250),\n(\'Sales\', \'Angelo\', 200);\n\nWe could do this without using window functions, as follows:\n\nselect dept, name, salary\nfrom employee_salaries as t1\nwhere (select count(t2.salary)\n   from employee_salaries as t2\n   where t1.name != t2.name and\n      t1.dept = t2.dept and\n      t2.salary > t1.salary) < 5\norder by dept, salary desc;\n\n+-------------+--------------+--------+\n| dept        | name         | salary |\n+-------------+--------------+--------+\n| Engineering | Dharma       |   3500 |\n| Engineering | Binh         |   3000 |\n| Engineering | Adalynn      |   2800 |\n| Engineering | Samuel       |   2500 |\n| Engineering | Cveta        |   2200 |\n| Sales       | Carbry       |    500 |\n| Sales       | Clytemnestra |    400 |\n| Sales       | Juraj        |    300 |\n| Sales       | Kalpana      |    300 |\n| Sales       | Svantepolk   |    250 |\n+-------------+--------------+--------+\n\nThis has a number of disadvantages:\n\n* if there is no index, the query could take a long time if the\nemployee_salary_table is large\n* Adding and maintaining indexes adds overhead, and even with indexes on dept\nand salary, each subquery execution adds overhead by performing a lookup\nthrough the index.\n\nLet\'s try achieve the same with window functions. First, generate a rank for\nall employees, using the RANK function.\n\nselect rank() over (partition by dept order by salary desc) as ranking,\n  dept, name, salary\n  from employee_salaries\n  order by dept, ranking;\n+---------+-------------+--------------+--------+\n| ranking | dept        | name         | salary |\n+---------+-------------+--------------+--------+\n|       1 | Engineering | Dharma       |   3500 |\n|       2 | Engineering | Binh         |   3000 |\n|       3 | Engineering | Adalynn      |   2800 |\n|       4 | Engineering | Samuel       |   2500 |\n|       5 | Engineering | Cveta        |   2200 |\n|       6 | Engineering | Ebele        |   1800 |\n|       1 | Sales       | Carbry       |    500 |\n|       2 | Sales       | Clytemnestra |    400 |\n|       3 | Sales       | Juraj        |    300 |\n|       3 | Sales       | Kalpana      |    300 |\n|       5 | Sales       | Svantepolk   |    250 |\n|       6 | Sales       | Angelo       |    200 |\n+---------+-------------+--------------+--------+\n\nEach department has a separate sequence of ranks due to the PARTITION BY\nclause. This particular sequence of values for rank() is given by the ORDER BY\nclause inside the window function’s OVER clause. Finally, to get our results\nin a readable format we order the data by dept and the newly generated ranking\ncolumn.\n\nNow, we need to reduce the results to find only the top 5 per department. Here\nis a common mistake:\n\nselect\nrank() over (partition by dept order by salary desc) as ranking,\ndept, name, salary\nfrom employee_salaries\nwhere ranking <= 5\norder by dept, ranking;\n\nERROR 1054 (42S22): Unknown column \'ranking\' in \'where clause\'\n\nTrying to filter only the first 5 values per department by putting a where\nclause in the statement does not work, due to the way window functions are\ncomputed. The computation of window functions happens after all WHERE, GROUP\nBY and HAVING clauses have been completed, right before ORDER BY, so the WHERE\nclause has no idea that the ranking column exists. It is only present after we\nhave filtered and grouped all the rows.\n\nTo counteract this problem, we need to wrap our query into a derived table. We\ncan then attach a where clause to it:\n\nselect *from (select rank() over (partition by dept order by salary desc) as\nranking,\n dept, name, salary\nfrom employee_salaries) as salary_ranks\nwhere (salary_ranks.ranking <= 5)\n order by dept, ranking;\n+---------+-------------+--------------+--------+\n| ranking | dept        | name         | salary |\n+---------+-------------+--------------+--------+\n|       1 | Engineering | Dharma       |   3500 |\n|       2 | Engineering | Binh         |   3000 |\n|       3 | Engineering | Adalynn      |   2800 |\n|       4 | Engineering | Samuel       |   2500 |\n|       5 | Engineering | Cveta        |   2200 |\n|       1 | Sales       | Carbry       |    500 |\n|       2 | Sales       | Clytemnestra |    400 |\n|       3 | Sales       | Juraj        |    300 |\n|       3 | Sales       | Kalpana      |    300 |\n|       5 | Sales       | Svantepolk   |    250 |\n+---------+-------------+--------------+--------+\n\nURL: https://mariadb.com/kb/en/window-functions-overview/','','https://mariadb.com/kb/en/window-functions-overview/'),(758,'CUME_DIST',41,'Syntax\n------\n\nCUME_DIST() OVER ( \n [ PARTITION BY partition_expression ]\n [ ORDER BY order_list ]\n)\n\nDescription\n-----------\n\nCUME_DIST() is a window function that returns the cumulative distribution of a\ngiven row. The following formula is used to calculate the value:\n\n(number of rows <= current row) / (total rows)\n\nExamples\n--------\n\ncreate table t1 (\n pk int primary key,\n a int,\n b int\n);\n\ninsert into t1 values\n( 1 , 0, 10),\n( 2 , 0, 10),\n( 3 , 1, 10),\n( 4 , 1, 10),\n( 8 , 2, 10),\n( 5 , 2, 20),\n( 6 , 2, 20),\n( 7 , 2, 20),\n( 9 , 4, 20),\n(10 , 4, 20);\n\nselect pk, a, b,\n  rank() over (order by a) as rank,\n  percent_rank() over (order by a) as pct_rank,\n  cume_dist() over (order by a) as cume_dist\nfrom t1;\n+----+------+------+------+--------------+--------------+\n| pk | a    | b    | rank | pct_rank     | cume_dist    |\n+----+------+------+------+--------------+--------------+\n|  1 |    0 |   10 |    1 | 0.0000000000 | 0.2000000000 |\n|  2 |    0 |   10 |    1 | 0.0000000000 | 0.2000000000 |\n|  3 |    1 |   10 |    3 | 0.2222222222 | 0.4000000000 |\n|  4 |    1 |   10 |    3 | 0.2222222222 | 0.4000000000 |\n|  5 |    2 |   20 |    5 | 0.4444444444 | 0.8000000000 |\n|  6 |    2 |   20 |    5 | 0.4444444444 | 0.8000000000 |\n|  7 |    2 |   20 |    5 | 0.4444444444 | 0.8000000000 |\n|  8 |    2 |   10 |    5 | 0.4444444444 | 0.8000000000 |\n|  9 |    4 |   20 |    9 | 0.8888888889 | 1.0000000000 |\n| 10 |    4 |   20 |    9 | 0.8888888889 | 1.0000000000 |\n+----+------+------+------+--------------+--------------+\n\nselect pk, a, b,\n   percent_rank() over (order by pk) as pct_rank,\n   cume_dist() over (order by pk) as cume_dist\nfrom t1 order by pk;\n+----+------+------+--------------+--------------+\n| pk | a    | b    | pct_rank     | cume_dist    |\n+----+------+------+--------------+--------------+\n|  1 |    0 |   10 | 0.0000000000 | 0.1000000000 |\n|  2 |    0 |   10 | 0.1111111111 | 0.2000000000 |\n|  3 |    1 |   10 | 0.2222222222 | 0.3000000000 |\n|  4 |    1 |   10 | 0.3333333333 | 0.4000000000 |\n|  5 |    2 |   20 | 0.4444444444 | 0.5000000000 |\n|  6 |    2 |   20 | 0.5555555556 | 0.6000000000 |\n|  7 |    2 |   20 | 0.6666666667 | 0.7000000000 |\n|  8 |    2 |   10 | 0.7777777778 | 0.8000000000 |\n|  9 |    4 |   20 | 0.8888888889 | 0.9000000000 |\n| 10 |    4 |   20 | 1.0000000000 | 1.0000000000 |\n+----+------+------+--------------+--------------+\n\nselect pk, a, b,\n    percent_rank() over (partition by a order by a) as pct_rank,\n    cume_dist() over (partition by a order by a) as cume_dist\nfrom t1;\n+----+------+------+--------------+--------------+\n| pk | a    | b    | pct_rank     | cume_dist    |\n+----+------+------+--------------+--------------+\n|  1 |    0 |   10 | 0.0000000000 | 1.0000000000 |\n|  2 |    0 |   10 | 0.0000000000 | 1.0000000000 |\n|  3 |    1 |   10 | 0.0000000000 | 1.0000000000 |\n|  4 |    1 |   10 | 0.0000000000 | 1.0000000000 |\n|  5 |    2 |   20 | 0.0000000000 | 1.0000000000 |\n|  6 |    2 |   20 | 0.0000000000 | 1.0000000000 |\n|  7 |    2 |   20 | 0.0000000000 | 1.0000000000 |\n|  8 |    2 |   10 | 0.0000000000 | 1.0000000000 |\n|  9 |    4 |   20 | 0.0000000000 | 1.0000000000 |\n| 10 |    4 |   20 | 0.0000000000 | 1.0000000000 |\n+----+------+------+--------------+--------------+\n\nURL: https://mariadb.com/kb/en/cume_dist/','','https://mariadb.com/kb/en/cume_dist/'),(759,'DENSE_RANK',41,'Syntax\n------\n\nDENSE_RANK() OVER (\n [ PARTITION BY partition_expression ]\n [ ORDER BY order_list ]\n)\n\nDescription\n-----------\n\nDENSE_RANK() is a window function that displays the number of a given row,\nstarting at one and following the ORDER BY sequence of the window function,\nwith identical values receiving the same result. Unlike the RANK() function,\nthere are no skipped values if the preceding results are identical. It is also\nsimilar to the ROW_NUMBER() function except that in that function, identical\nvalues will receive a different row number for each result.\n\nExamples\n--------\n\nThe distinction between DENSE_RANK(), RANK() and ROW_NUMBER():\n\nCREATE TABLE student(course VARCHAR(10), mark int, name varchar(10));\n\nINSERT INTO student VALUES \n (\'Maths\', 60, \'Thulile\'),\n (\'Maths\', 60, \'Pritha\'),\n (\'Maths\', 70, \'Voitto\'),\n (\'Maths\', 55, \'Chun\'),\n (\'Biology\', 60, \'Bilal\'),\n (\'Biology\', 70, \'Roger\');\n\nSELECT \n RANK() OVER (PARTITION BY course ORDER BY mark DESC) AS rank,\n DENSE_RANK() OVER (PARTITION BY course ORDER BY mark DESC) AS dense_rank,\n ROW_NUMBER() OVER (PARTITION BY course ORDER BY mark DESC) AS row_num,\n course, mark, name\nFROM student ORDER BY course, mark DESC;\n+------+------------+---------+---------+------+---------+\n| rank | dense_rank | row_num | course  | mark | name    |\n+------+------------+---------+---------+------+---------+\n|    1 |          1 |       1 | Biology |   70 | Roger   |\n|    2 |          2 |       2 | Biology |   60 | Bilal   |\n|    1 |          1 |       1 | Maths   |   70 | Voitto  |\n|    2 |          2 |       2 | Maths   |   60 | Thulile |\n|    2 |          2 |       3 | Maths   |   60 | Pritha  |\n|    4 |          3 |       4 | Maths   |   55 | Chun    |\n+------+------------+---------+---------+------+---------+\n\nURL: https://mariadb.com/kb/en/dense_rank/','','https://mariadb.com/kb/en/dense_rank/'),(760,'FIRST_VALUE',41,'Syntax\n------\n\nFIRST_VALUE(expr) OVER (\n [ PARTITION BY partition_expression ]\n [ ORDER BY order_list ]\n)\n\nDescription\n-----------\n\nFIRST_VALUE returns the first result from an ordered set, or NULL if no such\nresult exists.\n\nExamples\n--------\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/first_value/','','https://mariadb.com/kb/en/first_value/'),(761,'LAG',41,'Syntax\n------\n\nLAG (expr[, offset]) OVER ( \n [ PARTITION BY partition_expression ]\n < ORDER BY order_list >\n)\n\nDescription\n-----------\n\nThe LAG function accesses data from a previous row according to the ORDER BY\nclause without the need for a self-join. The specific row is determined by the\noffset (default 1), which specifies the number of rows behind the current row\nto use. An offset of 0 is the current row.\n\nExamples\n--------\n\nCREATE TABLE t1 (pk int primary key, a int, b int, c char(10), d decimal(10,\n3), e real);\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, LAG(pk) OVER (ORDER BY pk) AS l,\n LAG(pk,1) OVER (ORDER BY pk) AS l1,\n LAG(pk,2) OVER (ORDER BY pk) AS l2,\n LAG(pk,0) OVER (ORDER BY pk) AS l0,\n LAG(pk,-1) OVER (ORDER BY pk) AS lm1,\n LAG(pk,-2) OVER (ORDER BY pk) AS lm2\nFROM t1;\n+----+------+------+------+------+------+------+\n| pk | l    | l1   | l2   | l0   | lm1  | lm2  |\n+----+------+------+------+------+------+------+\n|  1 | NULL | NULL | NULL |    1 |    2 |    3 |\n|  2 |    1 |    1 | NULL |    2 |    3 |    4 |\n|  3 |    2 |    2 |    1 |    3 |    4 |    5 |\n|  4 |    3 |    3 |    2 |    4 |    5 |    6 |\n|  5 |    4 |    4 |    3 |    5 |    6 |    7 |\n|  6 |    5 |    5 |    4 |    6 |    7 |    8 |\n|  7 |    6 |    6 |    5 |    7 |    8 |    9 |\n|  8 |    7 |    7 |    6 |    8 |    9 |   10 |\n|  9 |    8 |    8 |    7 |    9 |   10 |   11 |\n| 10 |    9 |    9 |    8 |   10 |   11 | NULL |\n| 11 |   10 |   10 |    9 |   11 | NULL | NULL |\n+----+------+------+------+------+------+------+\n\nURL: https://mariadb.com/kb/en/lag/','','https://mariadb.com/kb/en/lag/'),(762,'LEAD',41,'Syntax\n------\n\nLEAD (expr[, offset]) OVER ( \n [ PARTITION BY partition_expression ]\n [ ORDER BY order_list ]\n)\n\nDescription\n-----------\n\nThe LEAD function accesses data from a following row in the same result set\nwithout the need for a self-join. The specific row is determined by the offset\n(default 1), which specifies the number of rows ahead the current row to use.\nAn offset of 0 is the current row.\n\nExample\n-------\n\nCREATE TABLE t1 (pk int primary key, a int, b int, c char(10), d decimal(10,\n3), e real);\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, LEAD(pk) OVER (ORDER BY pk) AS l,\n LEAD(pk,1) OVER (ORDER BY pk) AS l1,\n LEAD(pk,2) OVER (ORDER BY pk) AS l2,\n LEAD(pk,0) OVER (ORDER BY pk) AS l0,\n LEAD(pk,-1) OVER (ORDER BY pk) AS lm1,\n LEAD(pk,-2) OVER (ORDER BY pk) AS lm2\nFROM t1;\n+----+------+------+------+------+------+------+\n| pk | l    | l1   | l2   | l0   | lm1  | lm2  |\n+----+------+------+------+------+------+------+\n|  1 |    2 |    2 |    3 |    1 | NULL | NULL |\n|  2 |    3 |    3 |    4 |    2 |    1 | NULL |\n|  3 |    4 |    4 |    5 |    3 |    2 |    1 |\n|  4 |    5 |    5 |    6 |    4 |    3 |    2 |\n|  5 |    6 |    6 |    7 |    5 |    4 |    3 |\n|  6 |    7 |    7 |    8 |    6 |    5 |    4 |\n|  7 |    8 |    8 |    9 |    7 |    6 |    5 |\n|  8 |    9 |    9 |   10 |    8 |    7 |    6 |\n|  9 |   10 |   10 |   11 |    9 |    8 |    7 |\n| 10 |   11 |   11 | NULL |   10 |    9 |    8 |\n| 11 | NULL | NULL | NULL |   11 |   10 |    9 |\n+----+------+------+------+------+------+------+\n\nURL: https://mariadb.com/kb/en/lead/','','https://mariadb.com/kb/en/lead/'),(763,'Median Window Function',41,'MariaDB starting with 10.3.3\n----------------------------\nThe MEDIAN() window function was first introduced with in MariaDB 10.3.3.\n\nSyntax\n------\n\nMEDIAN(median expression) OVER (\n [ PARTITION BY partition_expression ]\n)\n\nDescription\n-----------\n\nMEDIAN() is a window function that returns the median value of a range of\nvalues.\n\nIt is a specific case of PERCENTILE_CONT, with an argument of 0.5 and the\nORDER BY column the one in MEDIAN\'s argument.\n\nMEDIAN(<median-arg>) OVER ( [ PARTITION BY partition_expression] )\n\nIs equivalent to:\n\nPERCENTILE_CONT(0.5) WITHIN \n GROUP (ORDER BY <median-arg>) OVER ( [ PARTITION BY partition_expression ])\n\nExamples\n--------\n\nCREATE TABLE book_rating (name CHAR(30), star_rating TINYINT);\n\nINSERT INTO book_rating VALUES (\'Lord of the Ladybirds\', 5);\nINSERT INTO book_rating VALUES (\'Lord of the Ladybirds\', 3);\nINSERT INTO book_rating VALUES (\'Lady of the Flies\', 1);\nINSERT INTO book_rating VALUES (\'Lady of the Flies\', 2);\nINSERT INTO book_rating VALUES (\'Lady of the Flies\', 5);\n\nSELECT name, median(star_rating) OVER (PARTITION BY name) FROM book_rating;\n+-----------------------+----------------------------------------------+\n| name                  | median(star_rating) OVER (PARTITION BY name) |\n+-----------------------+----------------------------------------------+\n| Lord of the Ladybirds |                                 4.0000000000 |\n| Lord of the Ladybirds |                                 4.0000000000 |\n| Lady of the Flies     |                                 2.0000000000 |\n| Lady of the Flies     |                                 2.0000000000 |\n| Lady of the Flies     |                                 2.0000000000 |\n+-----------------------+----------------------------------------------+\n\nURL: https://mariadb.com/kb/en/median/','','https://mariadb.com/kb/en/median/'),(764,'NTH_VALUE',41,'Syntax\n------\n\nNTH_VALUE (expr[, num_row]) OVER ( \n [ PARTITION BY partition_expression ]\n [ ORDER BY order_list ]\n)\n\nDescription\n-----------\n\nThe NTH_VALUE function returns the value evaluated at row number num_row of\nthe window frame, starting from 1, or NULL if the row does not exist.\n\nURL: https://mariadb.com/kb/en/nth_value/','','https://mariadb.com/kb/en/nth_value/'),