????

Your IP : 216.73.216.136


Current Path : C:/opt/mariadb/data/mysql/
Upload File :
Current File : C:/opt/mariadb/data/mysql/help_topic.MAD

$I�?�����'I�$I��O�$��?��?���O��y�$I�$I�������$�����￷m۶m۶m۶m۶m۶m۶m۶m۶q۶m۶m۶m۶m�m�m۶�۶m�6
KD��	H	HELP_DATEHelp Contents generated from the MariaDB Knowledge Base on 25 July 2023.Y	HELP_VERSIONHelp Contents generated for MariaDB 11.0 from the MariaDB Knowledge Base on 25 July 2023.O2AREAA synonym for ST_AREA.

URL: https://mariadb.com/kb/en/polygon-properties-area/https://mariadb.com/kb/en/polygon-properties-area/D#CENTROIDA synonym for ST_CENTROID.

URL: https://mariadb.com/kb/en/centroid/https://mariadb.com/kb/en/centroid/_:ExteriorRingA synonym for ST_ExteriorRing.

URL: https://mariadb.com/kb/en/polygon-properties-exteriorring/https://mariadb.com/kb/en/polygon-properties-exteriorring/
a;InteriorRingNA synonym for ST_InteriorRingN.

URL: https://mariadb.com/kb/en/polygon-properties-interiorringn/https://mariadb.com/kb/en/polygon-properties-interiorringn/g>NumInteriorRingsA synonym for ST_NumInteriorRings.

URL: https://mariadb.com/kb/en/polygon-properties-numinteriorrings/https://mariadb.com/kb/en/polygon-properties-numinteriorrings/
"ST_AREASyntax
------

ST_Area(poly)
Area(poly)

Description
-----------

Returns as a double-precision number the area of the Polygon value poly, as
measured in its spatial reference system.

ST_Area() and Area() are synonyms.

Examples
--------

SET @poly = 'Polygon((0 0,0 3,3 0,0 0),(1 1,1 2,2 1,1 1))';

SELECT Area(GeomFromText(@poly));
+---------------------------+
| Area(GeomFromText(@poly)) |
+---------------------------+
|                         4 |
+---------------------------+

URL: https://mariadb.com/kb/en/st_area/https://mariadb.com/kb/en/st_area/	%&ST_CENTROIDSyntax
------

ST_Centroid(mpoly)
Centroid(mpoly)

Description
-----------

Returns a point reflecting the mathematical centroid (geometric center) for
the MultiPolygon mpoly. The resulting point will not necessarily be on the
MultiPolygon.

ST_Centroid() and Centroid() are synonyms.

Examples
--------

SET @poly = ST_GeomFromText('POLYGON((0 0,20 0,20 20,0 20,0 0))');
SELECT ST_AsText(ST_Centroid(@poly)) AS center;
+--------------+
| center       |
+--------------+
| POINT(10 10) |
+--------------+

URL: https://mariadb.com/kb/en/st_centroid/https://mariadb.com/kb/en/st_centroid/
l*ST_ExteriorRingSyntax
------

ST_ExteriorRing(poly)
ExteriorRing(poly)

Description
-----------

Returns the exterior ring of the Polygon value poly as a LineString.

ST_ExteriorRing() and ExteriorRing() are synonyms.

Examples
--------

SET @poly = 'Polygon((0 0,0 3,3 3,3 0,0 0),(1 1,1 2,2 2,2 1,1 1))';

SELECT AsText(ExteriorRing(GeomFromText(@poly)));
+-------------------------------------------+
| AsText(ExteriorRing(GeomFromText(@poly))) |
+-------------------------------------------+
| LINESTRING(0 0,0 3,3 3,3 0,0 0)           |
+-------------------------------------------+

URL: https://mariadb.com/kb/en/st_exteriorring/https://mariadb.com/kb/en/st_exteriorring/�+ST_InteriorRingNSyntax
------

ST_InteriorRingN(poly,N)
InteriorRingN(poly,N)

Description
-----------

Returns the N-th interior ring for the Polygon value poly as a LineString.
Rings are numbered beginning with 1.

ST_InteriorRingN() and InteriorRingN() are synonyms.

Examples
--------

SET @poly = 'Polygon((0 0,0 3,3 3,3 0,0 0),(1 1,1 2,2 2,2 1,1 1))';

SELECT AsText(InteriorRingN(GeomFromText(@poly),1));
+----------------------------------------------+
| AsText(InteriorRingN(GeomFromText(@poly),1)) |
+----------------------------------------------+
| LINESTRING(1 1,1 2,2 2,2 1,1 1)              |
+----------------------------------------------+

URL: https://mariadb.com/kb/en/st_interiorringn/https://mariadb.com/kb/en/st_interiorringn/.ST_NumInteriorRingsSyntax
------

ST_NumInteriorRings(poly)
NumInteriorRings(poly)

Description
-----------

Returns an integer containing the number of interior rings in the Polygon
value poly.

Note that according the the OpenGIS standard, a POLYGON should have exactly
one ExteriorRing and all other rings should lie within that ExteriorRing and
thus be the InteriorRings. Practically, however, some systems, including
MariaDB's, permit polygons to have several 'ExteriorRings'. In the case of
there being multiple, non-overlapping exterior rings ST_NumInteriorRings()
will return 1.

ST_NumInteriorRings() and NumInteriorRings() are synonyms.

Examples
--------

SET @poly = 'Polygon((0 0,0 3,3 3,3 0,0 0),(1 1,1 2,2 2,2 1,1 1))';

SELECT NumInteriorRings(GeomFromText(@poly));
+---------------------------------------+
| NumInteriorRings(GeomFromText(@poly)) |
+---------------------------------------+
|                                     1 |
+---------------------------------------+

Non-overlapping 'polygon':

SELECT ST_NumInteriorRings(ST_PolyFromText('POLYGON((0 0,10 0,10 10,0 10,0 0),
 (-1 -1,-5 -1,-5 -5,-1 -5,-1 -1))')) AS NumInteriorRings;
+------------------+
| NumInteriorRings |
+------------------+
|                1 |
+------------------+

URL: https://mariadb.com/kb/en/st_numinteriorrings/https://mariadb.com/kb/en/st_numinteriorrings/F%AsTextA synonym for ST_AsText().

URL: https://mariadb.com/kb/en/wkt-astext/https://mariadb.com/kb/en/wkt-astext/E$AsWKTA synonym for ST_AsText().

URL: https://mariadb.com/kb/en/wkt-aswkt/https://mariadb.com/kb/en/wkt-aswkt/X/GeomCollFromTextA synonym for ST_GeomCollFromText.

URL: https://mariadb.com/kb/en/wkt-geomcollfromtext/https://mariadb.com/kb/en/wkt-geomcollfromtext/^5GeometryCollectionFromTextA synonym for ST_GeomCollFromText.

URL: https://mariadb.com/kb/en/geometrycollectionfromtext/https://mariadb.com/kb/en/geometrycollectionfromtext/P+GeometryFromTextA synonym for ST_GeomFromText.

URL: https://mariadb.com/kb/en/geometryfromtext/https://mariadb.com/kb/en/geometryfromtext/P+GeomFromTextA synonym for ST_GeomFromText.

URL: https://mariadb.com/kb/en/wkt-geomfromtext/https://mariadb.com/kb/en/wkt-geomfromtext/P+LineFromTextA synonym for ST_LineFromText.

URL: https://mariadb.com/kb/en/wkt-linefromtext/https://mariadb.com/kb/en/wkt-linefromtext/R-LineStringFromTextA synonym for ST_LineFromText.

URL: https://mariadb.com/kb/en/linestringfromtext/https://mariadb.com/kb/en/linestringfromtext/
�(MLineFromTextSyntax
------

MLineFromText(wkt[,srid])
MultiLineStringFromText(wkt[,srid])

Description
-----------

Constructs a MULTILINESTRING value using its WKT representation and SRID.

MLineFromText() and MultiLineStringFromText() are synonyms.

Examples
--------

CREATE TABLE gis_multi_line (g MULTILINESTRING);
SHOW FIELDS FROM gis_multi_line;
INSERT INTO gis_multi_line VALUES
  (MultiLineStringFromText('MULTILINESTRING((10 48,10 21,10 0),(16 0,16
23,16 48))')),
  (MLineFromText('MULTILINESTRING((10 48,10 21,10 0))')),
  (MLineFromWKB(AsWKB(MultiLineString(
   LineString(Point(1, 2), Point(3, 5)),
   LineString(Point(2, 5), Point(5, 8), Point(21, 7))))));

URL: https://mariadb.com/kb/en/mlinefromtext/https://mariadb.com/kb/en/mlinefromtext/M)MPointFromTextSyntax
------

MPointFromText(wkt[,srid])
MultiPointFromText(wkt[,srid])

Description
-----------

Constructs a MULTIPOINT value using its WKT representation and SRID.

MPointFromText() and MultiPointFromText() are synonyms.

Examples
--------

CREATE TABLE gis_multi_point (g MULTIPOINT);
SHOW FIELDS FROM gis_multi_point;
INSERT INTO gis_multi_point VALUES
  (MultiPointFromText('MULTIPOINT(0 0,10 10,10 20,20 20)')),
  (MPointFromText('MULTIPOINT(1 1,11 11,11 21,21 21)')),
  (MPointFromWKB(AsWKB(MultiPoint(Point(3, 6), Point(4, 10)))));

URL: https://mariadb.com/kb/en/mpointfromtext/https://mariadb.com/kb/en/mpointfromtext/�����U���'�l���K|�m_r���[dDT�����m}��iq]yt�}�N
�)WKT DefinitionDescription
-----------

The Well-Known Text (WKT) representation of Geometry is designed to exchange
geometry data in ASCII form. Examples of the basic geometry types include:

+-----------------------------------------------------------------------------+
| Geometry Types                                                              |
+-----------------------------------------------------------------------------+
| POINT                                                                       |
+-----------------------------------------------------------------------------+
| LINESTRING                                                                  |
+-----------------------------------------------------------------------------+
| POLYGON                                                                     |
+-----------------------------------------------------------------------------+
| MULTIPOINT                                                                  |
+-----------------------------------------------------------------------------+
| MULTILINESTRING                                                             |
+-----------------------------------------------------------------------------+
| MULTIPOLYGON                                                                |
+-----------------------------------------------------------------------------+
| GEOMETRYCOLLECTION                                                          |
+-----------------------------------------------------------------------------+
| GEOMETRY                                                                    |
+-----------------------------------------------------------------------------+

URL: https://mariadb.com/kb/en/wkt-definition/https://mariadb.com/kb/en/wkt-definition/
5(MPolyFromTextSyntax
------

MPolyFromText(wkt[,srid])
MultiPolygonFromText(wkt[,srid])

Description
-----------

Constructs a MULTIPOLYGON value using its WKT representation and SRID.

MPolyFromText() and MultiPolygonFromText() are synonyms.

Examples
--------

CREATE TABLE gis_multi_polygon  (g MULTIPOLYGON);
SHOW FIELDS FROM gis_multi_polygon;
INSERT INTO gis_multi_polygon VALUES
  (MultiPolygonFromText('MULTIPOLYGON(
   ((28 26,28 0,84 0,84 42,28 26),(52 18,66 23,73 9,48 6,52 18)),
   ((59 18,67 18,67 13,59 13,59 18)))')),
  (MPolyFromText('MULTIPOLYGON(
   ((28 26,28 0,84 0,84 42,28 26),(52 18,66 23,73 9,48 6,52 18)),
   ((59 18,67 18,67 13,59 13,59 18)))')),
  (MPolyFromWKB(AsWKB(MultiPolygon(Polygon(
   LineString(Point(0, 3), Point(3, 3), Point(3, 0), Point(0, 3)))))));

URL: https://mariadb.com/kb/en/mpolyfromtext/https://mariadb.com/kb/en/mpolyfromtext/U2MultiLineStringFromTextA synonym for MLineFromText.

URL: https://mariadb.com/kb/en/multilinestringfromtext/https://mariadb.com/kb/en/multilinestringfromtext/Q-MultiPointFromTextA synonym for MPointFromText.

URL: https://mariadb.com/kb/en/multipointfromtext/https://mariadb.com/kb/en/multipointfromtext/R/MultiPolygonFromTextA synonym for MPolyFromText.

URL: https://mariadb.com/kb/en/multipolygonfromtext/https://mariadb.com/kb/en/multipolygonfromtext/
R,PointFromTextA synonym for ST_PointFromText.

URL: https://mariadb.com/kb/en/wkt-pointfromtext/https://mariadb.com/kb/en/wkt-pointfromtext/P+PolyFromTextA synonym for ST_PolyFromText.

URL: https://mariadb.com/kb/en/wkt-polyfromtext/https://mariadb.com/kb/en/wkt-polyfromtext/O*PolygonFromTextA synonym for ST_PolyFromText.

URL: https://mariadb.com/kb/en/polygonfromtext/https://mariadb.com/kb/en/polygonfromtext/	5$ST_AsTextSyntax
------

ST_AsText(g)
AsText(g)
ST_AsWKT(g)
AsWKT(g)

Description
-----------

Converts a value in internal geometry format to its WKT representation and
returns the string result.

ST_AsText(), AsText(), ST_AsWKT() and AsWKT() are all synonyms.

Examples
--------

SET @g = 'LineString(1 1,4 4,6 6)';

SELECT ST_AsText(ST_GeomFromText(@g));
+--------------------------------+
| ST_AsText(ST_GeomFromText(@g)) |
+--------------------------------+
| LINESTRING(1 1,4 4,6 6)        |
+--------------------------------+

URL: https://mariadb.com/kb/en/st_astext/https://mariadb.com/kb/en/st_astext/ D#ST_ASWKTA synonym for ST_ASTEXT().

URL: https://mariadb.com/kb/en/st_aswkt/https://mariadb.com/kb/en/st_aswkt/!d.ST_GeomCollFromTextSyntax
------

ST_GeomCollFromText(wkt[,srid])
ST_GeometryCollectionFromText(wkt[,srid])
GeomCollFromText(wkt[,srid])
GeometryCollectionFromText(wkt[,srid])

Description
-----------

Constructs a GEOMETRYCOLLECTION value using its WKT representation and SRID.

ST_GeomCollFromText(), ST_GeometryCollectionFromText(), GeomCollFromText() and
GeometryCollectionFromText() are all synonyms.

Example
-------

CREATE TABLE gis_geometrycollection  (g GEOMETRYCOLLECTION);
SHOW FIELDS FROM gis_geometrycollection;
INSERT INTO gis_geometrycollection VALUES
  (GeomCollFromText('GEOMETRYCOLLECTION(POINT(0 0), LINESTRING(0 0,10
10))')),
  (GeometryFromWKB(AsWKB(GeometryCollection(Point(44, 6),
LineString(Point(3, 6), Point(7, 9)))))),
  (GeomFromText('GeometryCollection()')),
  (GeomFromText('GeometryCollection EMPTY'));

URL: https://mariadb.com/kb/en/st_geomcollfromtext/https://mariadb.com/kb/en/st_geomcollfromtext/"a8ST_GeometryCollectionFromTextA synonym for ST_GeomCollFromText.

URL: https://mariadb.com/kb/en/st_geometrycollectionfromtext/https://mariadb.com/kb/en/st_geometrycollectionfromtext/#S.ST_GeometryFromTextA synonym for ST_GeomFromText.

URL: https://mariadb.com/kb/en/st_geometryfromtext/https://mariadb.com/kb/en/st_geometryfromtext/$�*ST_GeomFromTextSyntax
------

ST_GeomFromText(wkt[,srid])
ST_GeometryFromText(wkt[,srid])
GeomFromText(wkt[,srid])
GeometryFromText(wkt[,srid])

Description
-----------

Constructs a geometry value of any type using its WKT representation and SRID.

GeomFromText(), GeometryFromText(), ST_GeomFromText() and
ST_GeometryFromText() are all synonyms.

Example
-------

SET @g = ST_GEOMFROMTEXT('POLYGON((1 1,1 5,4 9,6 9,9 3,7 2,1 1))');

URL: https://mariadb.com/kb/en/st_geomfromtext/https://mariadb.com/kb/en/st_geomfromtext/%�*ST_LineFromTextSyntax
------

ST_LineFromText(wkt[,srid])
ST_LineStringFromText(wkt[,srid])
LineFromText(wkt[,srid])
LineStringFromText(wkt[,srid])

Description
-----------

Constructs a LINESTRING value using its WKT representation and SRID.

ST_LineFromText(), ST_LineStringFromText(), ST_LineFromText() and
ST_LineStringFromText() are all synonyms.

Examples
--------

CREATE TABLE gis_line  (g LINESTRING);
SHOW FIELDS FROM gis_line;
INSERT INTO gis_line VALUES
  (LineFromText('LINESTRING(0 0,0 10,10 0)')),
  (LineStringFromText('LINESTRING(10 10,20 10,20 20,10 20,10 10)')),
  (LineStringFromWKB(AsWKB(LineString(Point(10, 10), Point(40, 10)))));

URL: https://mariadb.com/kb/en/st_linefromtext/https://mariadb.com/kb/en/st_linefromtext/&U0ST_LineStringFromTextA synonym for ST_LineFromText.

URL: https://mariadb.com/kb/en/st_linestringfromtext/https://mariadb.com/kb/en/st_linestringfromtext/'+ST_PointFromTextSyntax
------

ST_PointFromText(wkt[,srid])
PointFromText(wkt[,srid])

Description
-----------

Constructs a POINT value using its WKT representation and SRID.

ST_PointFromText() and PointFromText() are synonyms.

Examples
--------

CREATE TABLE gis_point  (g POINT);
SHOW FIELDS FROM gis_point;
INSERT INTO gis_point VALUES
  (PointFromText('POINT(10 10)')),
  (PointFromText('POINT(20 10)')),
  (PointFromText('POINT(20 20)')),
  (PointFromWKB(AsWKB(PointFromText('POINT(10 20)'))));

URL: https://mariadb.com/kb/en/st_pointfromtext/https://mariadb.com/kb/en/st_pointfromtext/	aa�k�Q����8��}Kp�
� 
�����F��
�"xJŒ�(d*ST_PolyFromTextSyntax
------

ST_PolyFromText(wkt[,srid])
ST_PolygonFromText(wkt[,srid])
PolyFromText(wkt[,srid])
PolygonFromText(wkt[,srid])

Description
-----------

Constructs a POLYGON value using its WKT representation and SRID.

ST_PolyFromText(), ST_PolygonFromText(), PolyFromText() and
ST_PolygonFromText() are all synonyms.

Examples
--------

CREATE TABLE gis_polygon   (g POLYGON);
INSERT INTO gis_polygon VALUES
  (PolygonFromText('POLYGON((10 10,20 10,20 20,10 20,10 10))')),
  (PolyFromText('POLYGON((0 0,50 0,50 50,0 50,0 0), (10 10,20 10,20 20,10
20,10 10))'));

URL: https://mariadb.com/kb/en/st_polyfromtext/https://mariadb.com/kb/en/st_polyfromtext/)R-ST_PolygonFromTextA synonym for ST_PolyFromText.

URL: https://mariadb.com/kb/en/st_polygonfromtext/https://mariadb.com/kb/en/st_polygonfromtext/*fDIVSyntax
------

DIV

Description
-----------

Integer division. Similar to FLOOR(), but is safe with BIGINT values.
Incorrect results may occur for non-integer operands that exceed BIGINT range.

If the ERROR_ON_DIVISION_BY_ZERO SQL_MODE is used, a division by zero produces
an error. Otherwise, it returns NULL.

The remainder of a division can be obtained using the MOD operator.

Examples
--------

SELECT 300 DIV 7;
+-----------+
| 300 DIV 7 |
+-----------+
|        42 |
+-----------+

SELECT 300 DIV 0;
+-----------+
| 300 DIV 0 |
+-----------+
|      NULL |
+-----------+

URL: https://mariadb.com/kb/en/div/https://mariadb.com/kb/en/div/+ABSSyntax
------

ABS(X)

Description
-----------

Returns the absolute (non-negative) value of X. If X is not a number, it is
converted to a numeric type.

Examples
--------

SELECT ABS(42);
+---------+
| ABS(42) |
+---------+
|      42 |
+---------+

SELECT ABS(-42);
+----------+
| ABS(-42) |
+----------+
|       42 |
+----------+

SELECT ABS(DATE '1994-01-01');
+------------------------+
| ABS(DATE '1994-01-01') |
+------------------------+
|               19940101 |
+------------------------+

URL: https://mariadb.com/kb/en/abs/https://mariadb.com/kb/en/abs/,�ACOSSyntax
------

ACOS(X)

Description
-----------

Returns the arc cosine of X, that is, the value whose cosine is X. Returns
NULL if X is not in the range -1 to 1.

Examples
--------

SELECT ACOS(1);
+---------+
| ACOS(1) |
+---------+
|       0 |
+---------+

SELECT ACOS(1.0001);
+--------------+
| ACOS(1.0001) |
+--------------+
|         NULL |
+--------------+

SELECT ACOS(0);
+-----------------+
| ACOS(0)         |
+-----------------+
| 1.5707963267949 |
+-----------------+

SELECT ACOS(0.234);
+------------------+
| ACOS(0.234)      |
+------------------+
| 1.33460644244679 |
+------------------+

URL: https://mariadb.com/kb/en/acos/https://mariadb.com/kb/en/acos/-ASINSyntax
------

ASIN(X)

Description
-----------

Returns the arc sine of X, that is, the value whose sine is X. Returns NULL if
X is not in the range -1 to 1.

Examples
--------

SELECT ASIN(0.2);
+--------------------+
| ASIN(0.2)          |
+--------------------+
| 0.2013579207903308 |
+--------------------+

SELECT ASIN('foo');
+-------------+
| ASIN('foo') |
+-------------+
|           0 |
+-------------+

SHOW WARNINGS;
+---------+------+-----------------------------------------+
| Level   | Code | Message                                 |
+---------+------+-----------------------------------------+
| Warning | 1292 | Truncated incorrect DOUBLE value: 'foo' |
+---------+------+-----------------------------------------+

URL: https://mariadb.com/kb/en/asin/https://mariadb.com/kb/en/asin/.�ATANSyntax
------

ATAN(X)

Description
-----------

Returns the arc tangent of X, that is, the value whose tangent is X.

Examples
--------

SELECT ATAN(2);
+--------------------+
| ATAN(2)            |
+--------------------+
| 1.1071487177940904 |
+--------------------+

SELECT ATAN(-2);
+---------------------+
| ATAN(-2)            |
+---------------------+
| -1.1071487177940904 |
+---------------------+

URL: https://mariadb.com/kb/en/atan/https://mariadb.com/kb/en/atan//U ATAN2Syntax
------

ATAN(Y,X), ATAN2(Y,X)

Description
-----------

Returns the arc tangent of the two variables X and Y. It is similar to
calculating the arc tangent of Y / X, except that the signs of both arguments
are used to determine the quadrant of the result.

Examples
--------

SELECT ATAN(-2,2);
+---------------------+
| ATAN(-2,2)          |
+---------------------+
| -0.7853981633974483 |
+---------------------+

SELECT ATAN2(PI(),0);
+--------------------+
| ATAN2(PI(),0)      |
+--------------------+
| 1.5707963267948966 |
+--------------------+

URL: https://mariadb.com/kb/en/atan2/https://mariadb.com/kb/en/atan2/0yCEILSyntax
------

CEIL(X)

Description
-----------

CEIL() is a synonym for CEILING().

URL: https://mariadb.com/kb/en/ceil/https://mariadb.com/kb/en/ceil/1�"CEILINGSyntax
------

CEILING(X)

Description
-----------

Returns the smallest integer value not less than X.

Examples
--------

SELECT CEILING(1.23);
+---------------+
| CEILING(1.23) |
+---------------+
|             2 |
+---------------+

SELECT CEILING(-1.23);
+----------------+
| CEILING(-1.23) |
+----------------+
|             -1 |
+----------------+

URL: https://mariadb.com/kb/en/ceiling/https://mariadb.com/kb/en/ceiling/3�COSSyntax
------

COS(X)

Description
-----------

Returns the cosine of X, where X is given in radians.

Examples
--------

SELECT COS(PI());
+-----------+
| COS(PI()) |
+-----------+
|        -1 |
+-----------+

URL: https://mariadb.com/kb/en/cos/https://mariadb.com/kb/en/cos/4�COTSyntax
------

COT(X)

Description
-----------

Returns the cotangent of X.

Examples
--------

SELECT COT(42);
+--------------------+
| COT(42)            |
+--------------------+
| 0.4364167060752729 |
+--------------------+

SELECT COT(12);
+---------------------+
| COT(12)             |
+---------------------+
| -1.5726734063976893 |
+---------------------+

SELECT COT(0);
ERROR 1690 (22003): DOUBLE value is out of range in 'cot(0)'

URL: https://mariadb.com/kb/en/cot/https://mariadb.com/kb/en/cot/7N"DEGREESSyntax
------

DEGREES(X)

Description
-----------

Returns the argument X, converted from radians to degrees.

This is the converse of the RADIANS() function.

Examples
--------

SELECT DEGREES(PI());
+---------------+
| DEGREES(PI()) |
+---------------+
|           180 |
+---------------+

SELECT DEGREES(PI() / 2);
+-------------------+
| DEGREES(PI() / 2) |
+-------------------+
|                90 |
+-------------------+

SELECT DEGREES(45);
+-----------------+
| DEGREES(45)     |
+-----------------+
| 2578.3100780887 |
+-----------------+

URL: https://mariadb.com/kb/en/degrees/https://mariadb.com/kb/en/degrees/8�EXPSyntax
------

EXP(X)

Description
-----------

Returns the value of e (the base of natural logarithms) raised to the power of
X. The inverse of this function is LOG() (using a single argument only) or
LN().

If X is NULL, this function returns NULL.

Examples
--------

SELECT EXP(2);
+------------------+
| EXP(2)           |
+------------------+
| 7.38905609893065 |
+------------------+

SELECT EXP(-2);
+--------------------+
| EXP(-2)            |
+--------------------+
| 0.1353352832366127 |
+--------------------+

SELECT EXP(0);
+--------+
| EXP(0) |
+--------+
|      1 |
+--------+

SELECT EXP(NULL);
+-----------+
| EXP(NULL) |
+-----------+
|      NULL |
+-----------+

URL: https://mariadb.com/kb/en/exp/https://mariadb.com/kb/en/exp/��.�"�%;���	���
41��FV����96o
�D2qCONVSyntax
------

CONV(N,from_base,to_base)

Description
-----------

Converts numbers between different number bases. Returns a string
representation of the number N, converted from base from_base to base to_base.

Returns NULL if any argument is NULL, or if the second or third argument are
not in the allowed range.

The argument N is interpreted as an integer, but may be specified as an
integer or a string. The minimum base is 2 and the maximum base is 36. If
to_base is a negative number, N is regarded as a signed number. Otherwise, N
is treated as unsigned. CONV() works with 64-bit precision.

Some shortcuts for this function are also available: BIN(), OCT(), HEX(),
UNHEX(). Also, MariaDB allows binary literal values and hexadecimal literal
values.

Examples
--------

SELECT CONV('a',16,2);
+----------------+
| CONV('a',16,2) |
+----------------+
| 1010           |
+----------------+

SELECT CONV('6E',18,8);
+-----------------+
| CONV('6E',18,8) |
+-----------------+
| 172             |
+-----------------+

SELECT CONV(-17,10,-18);
+------------------+
| CONV(-17,10,-18) |
+------------------+
| -H               |
+------------------+

SELECT CONV(12+'10'+'10'+0xa,10,10);
+------------------------------+
| CONV(12+'10'+'10'+0xa,10,10) |
+------------------------------+
| 42                           |
+------------------------------+

URL: https://mariadb.com/kb/en/conv/https://mariadb.com/kb/en/conv/5� CRC32Syntax
------

<= MariaDB 10.7

CRC32(expr)

From MariaDB 10.8

CRC32([par,]expr)

Description
-----------

Computes a cyclic redundancy check (CRC) value and returns a 32-bit unsigned
value. The result is NULL if the argument is NULL. The argument is expected to
be a string and (if possible) is treated as one if it is not.

Uses the ISO 3309 polynomial that used by zlib and many others. MariaDB 10.8
introduced the CRC32C() function, which uses the alternate Castagnoli
polynomia.

MariaDB starting with 10.8
--------------------------
Often, CRC is computed in pieces. To facilitate this, MariaDB 10.8.0
introduced an optional parameter: CRC32('MariaDB')=CRC32(CRC32('Maria'),'DB').

Examples
--------

SELECT CRC32('MariaDB');
+------------------+
| CRC32('MariaDB') |
+------------------+
|       4227209140 |
+------------------+

SELECT CRC32('mariadb');
+------------------+
| CRC32('mariadb') |
+------------------+
|       2594253378 |
+------------------+

From MariaDB 10.8.0

SELECT CRC32(CRC32('Maria'),'DB');
+----------------------------+
| CRC32(CRC32('Maria'),'DB') |
+----------------------------+
|                 4227209140 |
+----------------------------+

URL: https://mariadb.com/kb/en/crc32/https://mariadb.com/kb/en/crc32/6R!CRC32CMariaDB starting with 10.8
--------------------------
Introduced in MariaDB 10.8.0 to compute a cyclic redundancy check (CRC) value
using the Castagnoli polynomial.

Syntax
------

CRC32C([par,]expr)

Description
-----------

MariaDB has always included a native unary function CRC32() that computes the
CRC-32 of a string using the ISO 3309 polynomial that used by zlib and many
others.

InnoDB and MyRocks use a different polynomial, which was implemented in SSE4.2
instructions that were introduced in the Intel Nehalem microarchitecture. This
is commonly called CRC-32C (Castagnoli).

The CRC32C function uses the Castagnoli polynomial.

This allows SELECT…INTO DUMPFILE to be used for the creation of files with
valid checksums, such as a logically empty InnoDB redo log file ib_logfile0
corresponding to a particular log sequence number.

The optional parameter allows the checksum to be computed in pieces:
CRC32C('MariaDB')=CRC32C(CRC32C('Maria'),'DB').

Examples
--------

SELECT CRC32C('MariaDB');
+-------------------+
| CRC32C('MariaDB') |
+-------------------+
|         809606978 |
+-------------------+

SELECT CRC32C(CRC32C('Maria'),'DB');
+------------------------------+
| CRC32C(CRC32C('Maria'),'DB') |
+------------------------------+
|                    809606978 |
+------------------------------+

URL: https://mariadb.com/kb/en/crc32c/https://mariadb.com/kb/en/crc32c/9q FLOORSyntax
------

FLOOR(X)

Description
-----------

Returns the largest integer value not greater than X.

Examples
--------

SELECT FLOOR(1.23);
+-------------+
| FLOOR(1.23) |
+-------------+
|           1 |
+-------------+

SELECT FLOOR(-1.23);
+--------------+
| FLOOR(-1.23) |
+--------------+
|           -2 |
+--------------+

URL: https://mariadb.com/kb/en/floor/https://mariadb.com/kb/en/floor/:�LNSyntax
------

LN(X)

Description
-----------

Returns the natural logarithm of X; that is, the base-e logarithm of X. If X
is less than or equal to 0, or NULL, then NULL is returned.

The inverse of this function is EXP().

Examples
--------

SELECT LN(2);
+-------------------+
| LN(2)             |
+-------------------+
| 0.693147180559945 |
+-------------------+

SELECT LN(-2);
+--------+
| LN(-2) |
+--------+
|   NULL |
+--------+

URL: https://mariadb.com/kb/en/ln/https://mariadb.com/kb/en/ln/<� LOG10Syntax
------

LOG10(X)

Description
-----------

Returns the base-10 logarithm of X.

Examples
--------

SELECT LOG10(2);
+-------------------+
| LOG10(2)          |
+-------------------+
| 0.301029995663981 |
+-------------------+

SELECT LOG10(100);
+------------+
| LOG10(100) |
+------------+
|          2 |
+------------+

SELECT LOG10(-100);
+-------------+
| LOG10(-100) |
+-------------+
|        NULL |
+-------------+

URL: https://mariadb.com/kb/en/log10/https://mariadb.com/kb/en/log10/=�LOG2Syntax
------

LOG2(X)

Description
-----------

Returns the base-2 logarithm of X.

Examples
--------

SELECT LOG2(4398046511104);
+---------------------+
| LOG2(4398046511104) |
+---------------------+
|                  42 |
+---------------------+

SELECT LOG2(65536);
+-------------+
| LOG2(65536) |
+-------------+
|          16 |
+-------------+

SELECT LOG2(-100);
+------------+
| LOG2(-100) |
+------------+
|       NULL |
+------------+

URL: https://mariadb.com/kb/en/log2/https://mariadb.com/kb/en/log2/?�OCTSyntax
------

OCT(N)

Description
-----------

Returns a string representation of the octal value of N, where N is a longlong
(BIGINT) number. This is equivalent to CONV(N,10,8). Returns NULL if N is NULL.

Examples
--------

SELECT OCT(34);
+---------+
| OCT(34) |
+---------+
| 42      |
+---------+

SELECT OCT(12);
+---------+
| OCT(12) |
+---------+
| 14      |
+---------+

URL: https://mariadb.com/kb/en/oct/https://mariadb.com/kb/en/oct/@PISyntax
------

PI()

Description
-----------

Returns the value of π (pi). The default number of decimal places displayed is
six, but MariaDB uses the full double-precision value internally.

Examples
--------

SELECT PI();
+----------+
| PI()     |
+----------+
| 3.141593 |
+----------+

SELECT PI()+0.0000000000000000000000;
+-------------------------------+
| PI()+0.0000000000000000000000 |
+-------------------------------+
|      3.1415926535897931159980 |
+-------------------------------+

URL: https://mariadb.com/kb/en/pi/https://mariadb.com/kb/en/pi/A]POWSyntax
------

POW(X,Y)

Description
-----------

Returns the value of X raised to the power of Y.

POWER() is a synonym.

Examples
--------

SELECT POW(2,3);
+----------+
| POW(2,3) |
+----------+
|        8 |
+----------+

SELECT POW(2,-2);
+-----------+
| POW(2,-2) |
+-----------+
|      0.25 |
+-----------+

URL: https://mariadb.com/kb/en/pow/https://mariadb.com/kb/en/pow/��C�����+��
����G��	��;>LOGSyntax
------

LOG(X), LOG(B,X)

Description
-----------

If called with one parameter, this function returns the natural logarithm of
X. If X is less than or equal to 0, then NULL is returned.

If called with two parameters, it returns the logarithm of X to the base B. If
B is <= 1 or X <= 0, the function returns NULL.

If any argument is NULL, the function returns NULL.

The inverse of this function (when called with a single argument) is the EXP()
function.

Examples
--------

LOG(X):

SELECT LOG(2);
+-------------------+
| LOG(2)            |
+-------------------+
| 0.693147180559945 |
+-------------------+

SELECT LOG(-2);
+---------+
| LOG(-2) |
+---------+
|    NULL |
+---------+

LOG(B,X)

SELECT LOG(2,16);
+-----------+
| LOG(2,16) |
+-----------+
|         4 |
+-----------+

SELECT LOG(3,27);
+-----------+
| LOG(3,27) |
+-----------+
|         3 |
+-----------+

SELECT LOG(3,1);
+----------+
| LOG(3,1) |
+----------+
|        0 |
+----------+

SELECT LOG(3,0);
+----------+
| LOG(3,0) |
+----------+
|     NULL |
+----------+

URL: https://mariadb.com/kb/en/log/https://mariadb.com/kb/en/log/>AMODSyntax
------

MOD(N,M), N % M, N MOD M

Description
-----------

Modulo operation. Returns the remainder of N divided by M. See also Modulo
Operator.

If the ERROR_ON_DIVISION_BY_ZERO SQL_MODE is used, any number modulus zero
produces an error. Otherwise, it returns NULL.

The integer part of a division can be obtained using DIV.

Examples
--------

SELECT 1042 % 50;
+-----------+
| 1042 % 50 |
+-----------+
|        42 |
+-----------+

SELECT MOD(234, 10);
+--------------+
| MOD(234, 10) |
+--------------+
|            4 |
+--------------+

SELECT 253 % 7;
+---------+
| 253 % 7 |
+---------+
|       1 |
+---------+

SELECT MOD(29,9);
+-----------+
| MOD(29,9) |
+-----------+
|         2 |
+-----------+

SELECT 29 MOD 9;
+----------+
| 29 MOD 9 |
+----------+
|        2 |
+----------+

URL: https://mariadb.com/kb/en/mod/https://mariadb.com/kb/en/mod/B� POWERSyntax
------

POWER(X,Y)

Description
-----------

This is a synonym for POW(), which returns the value of X raised to the power
of Y.

URL: https://mariadb.com/kb/en/power/https://mariadb.com/kb/en/power/C	"RADIANSSyntax
------

RADIANS(X)

Description
-----------

Returns the argument X, converted from degrees to radians. Note that π radians
equals 180 degrees.

This is the converse of the DEGREES() function.

Examples
--------

SELECT RADIANS(45);
+-------------------+
| RADIANS(45)       |
+-------------------+
| 0.785398163397448 |
+-------------------+

SELECT RADIANS(90);
+-----------------+
| RADIANS(90)     |
+-----------------+
| 1.5707963267949 |
+-----------------+

SELECT RADIANS(PI());
+--------------------+
| RADIANS(PI())      |
+--------------------+
| 0.0548311355616075 |
+--------------------+

SELECT RADIANS(180);
+------------------+
| RADIANS(180)     |
+------------------+
| 3.14159265358979 |
+------------------+

URL: https://mariadb.com/kb/en/radians/https://mariadb.com/kb/en/radians/D�RANDSyntax
------

RAND(), RAND(N)

Description
-----------

Returns a random DOUBLE precision floating point value v in the range 0 <= v <
1.0. If a constant integer argument N is specified, it is used as the seed
value, which produces a repeatable sequence of column values. In the example
below, note that the sequences of values produced by RAND(3) is the same both
places where it occurs.

In a WHERE clause, RAND() is evaluated each time the WHERE is executed.

Statements using the RAND() function are not safe for statement-based
replication.

Practical uses
--------------

The expression to get a random integer from a given range is the following:

FLOOR(min_value + RAND() * (max_value - min_value +1))

RAND() is often used to read random rows from a table, as follows:

SELECT * FROM my_table ORDER BY RAND() LIMIT 10;

Note, however, that this technique should never be used on a large table as it
will be extremely slow. MariaDB will read all rows in the table, generate a
random value for each of them, order them, and finally will apply the LIMIT
clause.

Examples
--------

CREATE TABLE t (i INT);

INSERT INTO t VALUES(1),(2),(3);

SELECT i, RAND() FROM t;
+------+-------------------+
| i    | RAND()            |
+------+-------------------+
|    1 | 0.255651095188829 |
|    2 | 0.833920199269355 |
|    3 |  0.40264774151393 |
+------+-------------------+

SELECT i, RAND(3) FROM t;
+------+-------------------+
| i    | RAND(3)           |
+------+-------------------+
|    1 |  0.90576975597606 |
|    2 | 0.373079058130345 |
|    3 | 0.148086053457191 |
+------+-------------------+

SELECT i, RAND() FROM t;
+------+-------------------+
| i    | RAND()            |
+------+-------------------+
|    1 | 0.511478140495232 |
|    2 | 0.349447508668012 |
|    3 | 0.212803152588013 |
+------+-------------------+

Using the same seed, the same sequence will be returned:

SELECT i, RAND(3) FROM t;
+------+-------------------+
| i    | RAND(3)           |
+------+-------------------+
|    1 |  0.90576975597606 |
|    2 | 0.373079058130345 |
|    3 | 0.148086053457191 |
+------+-------------------+

Generating a random number from 5 to 15:

SELECT FLOOR(5 + (RAND() * 11));

URL: https://mariadb.com/kb/en/rand/https://mariadb.com/kb/en/rand/F�SIGNSyntax
------

SIGN(X)

Description
-----------

Returns the sign of the argument as -1, 0, or 1, depending on whether X is
negative, zero, or positive.

Examples
--------

SELECT SIGN(-32);
+-----------+
| SIGN(-32) |
+-----------+
|        -1 |
+-----------+

SELECT SIGN(0);
+---------+
| SIGN(0) |
+---------+
|       0 |
+---------+

SELECT SIGN(234);
+-----------+
| SIGN(234) |
+-----------+
|         1 |
+-----------+

URL: https://mariadb.com/kb/en/sign/https://mariadb.com/kb/en/sign/G[SINSyntax
------

SIN(X)

Description
-----------

Returns the sine of X, where X is given in radians.

Examples
--------

SELECT SIN(1.5707963267948966);
+-------------------------+
| SIN(1.5707963267948966) |
+-------------------------+
|                       1 |
+-------------------------+

SELECT SIN(PI());
+----------------------+
| SIN(PI())            |
+----------------------+
| 1.22460635382238e-16 |
+----------------------+

SELECT ROUND(SIN(PI()));
+------------------+
| ROUND(SIN(PI())) |
+------------------+
|                0 |
+------------------+

URL: https://mariadb.com/kb/en/sin/https://mariadb.com/kb/en/sin/H+SQRTSyntax
------

SQRT(X)

Description
-----------

Returns the square root of X. If X is negative, NULL is returned.

Examples
--------

SELECT SQRT(4);
+---------+
| SQRT(4) |
+---------+
|       2 |
+---------+

SELECT SQRT(20);
+------------------+
| SQRT(20)         |
+------------------+
| 4.47213595499958 |
+------------------+

SELECT SQRT(-16);
+-----------+
| SQRT(-16) |
+-----------+
|      NULL |
+-----------+

SELECT SQRT(1764);
+------------+
| SQRT(1764) |
+------------+
|         42 |
+------------+

URL: https://mariadb.com/kb/en/sqrt/https://mariadb.com/kb/en/sqrt/I�TANSyntax
------

TAN(X)

Description
-----------

Returns the tangent of X, where X is given in radians.

Examples
--------

SELECT TAN(0.7853981633974483);
+-------------------------+
| TAN(0.7853981633974483) |
+-------------------------+
|      0.9999999999999999 |
+-------------------------+

SELECT TAN(PI());
+-----------------------+
| TAN(PI())             |
+-----------------------+
| -1.22460635382238e-16 |
+-----------------------+

SELECT TAN(PI()+1);
+-----------------+
| TAN(PI()+1)     |
+-----------------+
| 1.5574077246549 |
+-----------------+

SELECT TAN(RADIANS(PI()));
+--------------------+
| TAN(RADIANS(PI())) |
+--------------------+
| 0.0548861508080033 |
+--------------------+

URL: https://mariadb.com/kb/en/tan/https://mariadb.com/kb/en/tan/��\���
��@��ypm�)Q?��E@ ROUNDSyntax
------

ROUND(X), ROUND(X,D)

Description
-----------

Rounds the argument X to D decimal places. D defaults to 0 if not specified. D
can be negative to cause D digits left of the decimal point of the value X to
become zero.

The rounding algorithm depends on the data type of X:

* for floating point types (FLOAT, DOUBLE) the C libraries rounding function
is used, so the behavior *may* differ between operating systems
* for fixed point types (DECIMAL, DEC/NUMBER/FIXED) the "round half up" rule
is used, meaning that e.g. a value ending in exactly .5 is always rounded up.

Examples
--------

SELECT ROUND(-1.23);
+--------------+
| ROUND(-1.23) |
+--------------+
|           -1 |
+--------------+

SELECT ROUND(-1.58);
+--------------+
| ROUND(-1.58) |
+--------------+
|           -2 |
+--------------+

SELECT ROUND(1.58); 
+-------------+
| ROUND(1.58) |
+-------------+
|           2 |
+-------------+

SELECT ROUND(1.298, 1);
+-----------------+
| ROUND(1.298, 1) |
+-----------------+
|             1.3 |
+-----------------+

SELECT ROUND(1.298, 0);
+-----------------+
| ROUND(1.298, 0) |
+-----------------+
|               1 |
+-----------------+

SELECT ROUND(23.298, -1);
+-------------------+
| ROUND(23.298, -1) |
+-------------------+
|                20 |
+-------------------+

URL: https://mariadb.com/kb/en/round/https://mariadb.com/kb/en/round/J�#TRUNCATEThis page documents the TRUNCATE function. See TRUNCATE TABLE for the DDL
statement.

Syntax
------

TRUNCATE(X,D)

Description
-----------

Returns the number X, truncated to D decimal places. If D is 0, the result has
no decimal point or fractional part. D can be negative to cause D digits left
of the decimal point of the value X to become zero.

Examples
--------

SELECT TRUNCATE(1.223,1);
+-------------------+
| TRUNCATE(1.223,1) |
+-------------------+
|               1.2 |
+-------------------+

SELECT TRUNCATE(1.999,1);
+-------------------+
| TRUNCATE(1.999,1) |
+-------------------+
|               1.9 |
+-------------------+

SELECT TRUNCATE(1.999,0); 
+-------------------+
| TRUNCATE(1.999,0) |
+-------------------+
|                 1 |
+-------------------+

SELECT TRUNCATE(-1.999,1);
+--------------------+
| TRUNCATE(-1.999,1) |
+--------------------+
|               -1.9 |
+--------------------+

SELECT TRUNCATE(122,-2);
+------------------+
| TRUNCATE(122,-2) |
+------------------+
|              100 |
+------------------+

SELECT TRUNCATE(10.28*100,0);
+-----------------------+
| TRUNCATE(10.28*100,0) |
+-----------------------+
|                  1028 |
+-----------------------+

URL: https://mariadb.com/kb/en/truncate/https://mariadb.com/kb/en/truncate/L�+UNINSTALL PLUGINSyntax
------

UNINSTALL PLUGIN [IF EXISTS] plugin_name

Description
-----------

This statement removes a single installed plugin. To uninstall the whole
library which contains the plugin, use UNINSTALL SONAME. You cannot uninstall
a plugin if any table that uses it is open.

plugin_name must be the name of some plugin that is listed in the mysql.plugin
table. The server executes the plugin's deinitialization function and removes
the row for the plugin from the mysql.plugin table, so that subsequent server
restarts will not load and initialize the plugin. UNINSTALL PLUGIN does not
remove the plugin's shared library file.

To use UNINSTALL PLUGIN, you must have the DELETE privilege for the
mysql.plugin table.

MariaDB starting with 10.4.0
----------------------------

IF EXISTS
---------

If the IF EXISTS clause is used, MariaDB will return a note instead of an
error if the plugin does not exist. See SHOW WARNINGS.

Examples
--------

UNINSTALL PLUGIN example;

From MariaDB 10.4.0:

UNINSTALL PLUGIN IF EXISTS example;
Query OK, 0 rows affected (0.099 sec)

UNINSTALL PLUGIN IF EXISTS example;
Query OK, 0 rows affected, 1 warning (0.000 sec)

SHOW WARNINGS;
+-------+------+-------------------------------+
| Level | Code | Message                       |
+-------+------+-------------------------------+
| Note  | 1305 | PLUGIN example does not exist |
+-------+------+-------------------------------+

URL: https://mariadb.com/kb/en/uninstall-plugin/https://mariadb.com/kb/en/uninstall-plugin/M)INSTALL SONAMESyntax
------

INSTALL SONAME 'plugin_library'

Description
-----------

This statement is a variant of INSTALL PLUGIN. It installs all plugins from a
given plugin_library. See INSTALL PLUGIN for details.

plugin_library is the name of the shared library that contains the plugin
code. The file name extension (for example, libmyplugin.so or libmyplugin.dll)
can be omitted (which makes the statement look the same on all architectures).

The shared library must be located in the plugin directory (that is, the
directory named by the plugin_dir system variable). The library must be in the
plugin directory itself, not in a subdirectory. By default, plugin_dir is
plugin directory under the directory named by the pkglibdir configuration
variable, but it can be changed by setting the value of plugin_dir at server
startup. For example, set its value in a my.cnf file:

[mysqld]
plugin_dir=/path/to/plugin/directory
If the value of plugin_dir is a relative path name, it is taken to be relative
to the MySQL base directory (the value of the basedir system variable).

INSTALL SONAME adds one or more lines to the mysql.plugin table that describes
the plugin. This table contains the plugin name and library file name.

INSTALL SONAME causes the server to read option (my.cnf) files just as during
server startup. This enables the plugin to pick up any relevant options from
those files. It is possible to add plugin options to an option file even
before loading a plugin (if the loose prefix is used). It is also possible to
uninstall a plugin, edit my.cnf, and install the plugin again. Restarting the
plugin this way enables it to the new option values without a server restart.

INSTALL SONAME also loads and initializes the plugin code to make the plugin
available for use. A plugin is initialized by executing its initialization
function, which handles any setup that the plugin must perform before it can
be used.

To use INSTALL SONAME, you must have the INSERT privilege for the mysql.plugin
table.

At server startup, the server loads and initializes any plugin that is listed
in the mysql.plugin table. This means that a plugin is installed with INSTALL
SONAME only once, not every time the server starts. Plugin loading at startup
does not occur if the server is started with the --skip-grant-tables option.

When the server shuts down, it executes the de-initialization function for
each plugin that is loaded so that the plugin has a chance to perform any
final cleanup.

If you need to load plugins for a single server startup when the
--skip-grant-tables option is given (which tells the server not to read system
tables), use the --plugin-load mysqld option.

If you need to install only one plugin from a library, use the INSTALL PLUGIN
statement.

Examples
--------

To load the XtraDB storage engine and all of its information_schema tables
with one statement, use

INSTALL SONAME 'ha_xtradb';

This statement can be used instead of INSTALL PLUGIN even when the library
contains only one plugin:

INSTALL SONAME 'ha_sequence';

URL: https://mariadb.com/kb/en/install-soname/https://mariadb.com/kb/en/install-soname/�[�
"s�d�
�sK�)INSTALL PLUGINSyntax
------

INSTALL PLUGIN [IF NOT EXISTS] plugin_name SONAME 'plugin_library'

Description
-----------

This statement installs an individual plugin from the specified library. To
install the whole library (which could be required), use INSTALL SONAME. See
also Installing a Plugin.

plugin_name is the name of the plugin as defined in the plugin declaration
structure contained in the library file. Plugin names are not case sensitive.
For maximal compatibility, plugin names should be limited to ASCII letters,
digits, and underscore, because they are used in C source files, shell command
lines, M4 and Bourne shell scripts, and SQL environments.

plugin_library is the name of the shared library that contains the plugin
code. The file name extension can be omitted (which makes the statement look
the same on all architectures).

The shared library must be located in the plugin directory (that is, the
directory named by the plugin_dir system variable). The library must be in the
plugin directory itself, not in a subdirectory. By default, plugin_dir is
plugin directory under the directory named by the pkglibdir configuration
variable, but it can be changed by setting the value of plugin_dir at server
startup. For example, set its value in a my.cnf file:

[mysqld]
plugin_dir=/path/to/plugin/directory
If the value of plugin_dir is a relative path name, it is taken to be relative
to the MySQL base directory (the value of the basedir system variable).

INSTALL PLUGIN adds a line to the mysql.plugin table that describes the
plugin. This table contains the plugin name and library file name.

INSTALL PLUGIN causes the server to read option (my.cnf) files just as during
server startup. This enables the plugin to pick up any relevant options from
those files. It is possible to add plugin options to an option file even
before loading a plugin (if the loose prefix is used). It is also possible to
uninstall a plugin, edit my.cnf, and install the plugin again. Restarting the
plugin this way enables it to the new option values without a server restart.

INSTALL PLUGIN also loads and initializes the plugin code to make the plugin
available for use. A plugin is initialized by executing its initialization
function, which handles any setup that the plugin must perform before it can
be used.

To use INSTALL PLUGIN, you must have the INSERT privilege for the mysql.plugin
table.

At server startup, the server loads and initializes any plugin that is listed
in the mysql.plugin table. This means that a plugin is installed with INSTALL
PLUGIN only once, not every time the server starts. Plugin loading at startup
does not occur if the server is started with the --skip-grant-tables option.

When the server shuts down, it executes the de-initialization function for
each plugin that is loaded so that the plugin has a chance to perform any
final cleanup.

If you need to load plugins for a single server startup when the
--skip-grant-tables option is given (which tells the server not to read system
tables), use the --plugin-load mysqld option.

MariaDB starting with 10.4.0
----------------------------

IF NOT EXISTS
-------------

When the IF NOT EXISTS clause is used, MariaDB will return a note instead of
an error if the specified plugin already exists. See SHOW WARNINGS.

Examples
--------

INSTALL PLUGIN sphinx SONAME 'ha_sphinx.so';

The extension can also be omitted:

INSTALL PLUGIN innodb SONAME 'ha_xtradb';

From MariaDB 10.4.0:

INSTALL PLUGIN IF NOT EXISTS example SONAME 'ha_example';
Query OK, 0 rows affected (0.104 sec)

INSTALL PLUGIN IF NOT EXISTS example SONAME 'ha_example';
Query OK, 0 rows affected, 1 warning (0.000 sec)

SHOW WARNINGS;
+-------+------+------------------------------------+
| Level | Code | Message                            |
+-------+------+------------------------------------+
| Note  | 1968 | Plugin 'example' already installed |
+-------+------+------------------------------------+

URL: https://mariadb.com/kb/en/install-plugin/https://mariadb.com/kb/en/install-plugin/N�+UNINSTALL SONAMESyntax
------

UNINSTALL SONAME  [IF EXISTS] 'plugin_library'

Description
-----------

This statement is a variant of UNINSTALL PLUGIN statement, that removes all
plugins belonging to a specified plugin_library. See UNINSTALL PLUGIN for
details.

plugin_library is the name of the shared library that contains the plugin
code. The file name extension (for example, libmyplugin.so or libmyplugin.dll)
can be omitted (which makes the statement look the same on all architectures).

To use UNINSTALL SONAME, you must have the DELETE privilege for the
mysql.plugin table.

MariaDB starting with 10.4.0
----------------------------

IF EXISTS
---------

If the IF EXISTS clause is used, MariaDB will return a note instead of an
error if the plugin library does not exist. See SHOW WARNINGS.

Examples
--------

To uninstall the XtraDB plugin and all of its information_schema tables with
one statement, use

UNINSTALL SONAME 'ha_xtradb';

From MariaDB 10.4.0:

UNINSTALL SONAME IF EXISTS 'ha_example';
Query OK, 0 rows affected (0.099 sec)

UNINSTALL SONAME IF EXISTS 'ha_example';
Query OK, 0 rows affected, 1 warning (0.000 sec)

SHOW WARNINGS;
+-------+------+-------------------------------------+
| Level | Code | Message                             |
+-------+------+-------------------------------------+
| Note  | 1305 | SONAME ha_example.so does not exist |
+-------+------+-------------------------------------+

URL: https://mariadb.com/kb/en/uninstall-soname/https://mariadb.com/kb/en/uninstall-soname/�@
�O�>*Plugin OverviewP)MBR DefinitionDescription
-----------

The MBR (Minimum Bounding Rectangle), or Envelope is the bounding geometry,
formed by the minimum and maximum (X,Y) coordinates:

Examples
--------

((MINX MINY, MAXX MINY, MAXX MAXY, MINX MAXY, MINX MINY))

URL: https://mariadb.com/kb/en/mbr-definition/https://mariadb.com/kb/en/mbr-definition/Q�&MBRContainsSyntax
------

MBRContains(g1,g2)

Description
-----------

Returns 1 or 0 to indicate whether the Minimum Bounding Rectangle of g1
contains the Minimum Bounding Rectangle of g2. This tests the opposite
relationship as MBRWithin().

Examples
--------

SET @g1 = GeomFromText('Polygon((0 0,0 3,3 3,3 0,0 0))');

SET @g2 = GeomFromText('Point(1 1)');

SELECT MBRContains(@g1,@g2), MBRContains(@g2,@g1);
+----------------------+----------------------+
| MBRContains(@g1,@g2) | MBRContains(@g2,@g1) |
+----------------------+----------------------+
|                    1 |                    0 |
+----------------------+----------------------+

URL: https://mariadb.com/kb/en/mbrcontains/https://mariadb.com/kb/en/mbrcontains/S�#MBREqualSyntax
------

MBREqual(g1,g2)

Description
-----------

Returns 1 or 0 to indicate whether the Minimum Bounding Rectangles of the two
geometries g1 and g2 are the same.

Examples
--------

SET @g1=GEOMFROMTEXT('LINESTRING(0 0, 1 2)');
SET @g2=GEOMFROMTEXT('POLYGON((0 0, 0 2, 1 2, 1 0, 0 0))');
SELECT MbrEqual(@g1,@g2);
+-------------------+
| MbrEqual(@g1,@g2) |
+-------------------+
|                 1 |
+-------------------+

SET @g1=GEOMFROMTEXT('LINESTRING(0 0, 1 3)');
SET @g2=GEOMFROMTEXT('POLYGON((0 0, 0 2, 1 4, 1 0, 0 0))');
SELECT MbrEqual(@g1,@g2);
+-------------------+
| MbrEqual(@g1,@g2) |
+-------------------+
|                 0 |
+-------------------+

URL: https://mariadb.com/kb/en/mbrequal/https://mariadb.com/kb/en/mbrequal/l��$\�,��m�ʿPlugins are server components that enhance MariaDB in some way. These can be
anything from new storage engines, plugins for enhancing full-text parsing, or
even small enhancements, such as a plugin to get a timestamp as an integer.

Querying Plugin Information
---------------------------

There are a number of ways to see which plugins are currently active.

A server almost always has a large number of active plugins, because the
server contains a large number of built-in plugins, which are active by
default and cannot be uninstalled.

Querying Plugin Information with SHOW PLUGINS
---------------------------------------------

The SHOW PLUGINS statement can be used to query information about all active
plugins.

For example:

SHOW PLUGINS\G;
********************** 1. row **********************
 Name: binlog
 Status: ACTIVE
 Type: STORAGE ENGINE
Library: NULL
License: GPL
********************** 2. row **********************
 Name: mysql_native_password
 Status: ACTIVE
 Type: AUTHENTICATION
Library: NULL
License: GPL
********************** 3. row **********************
 Name: mysql_old_password
 Status: ACTIVE
 Type: AUTHENTICATION
Library: NULL
License: GPL
...

If a plugin's Library column has a NULL value, then the plugin is built-in,
and it cannot be uninstalled.

Querying Plugin Information with information_schema.PLUGINS
-----------------------------------------------------------

The information_schema.PLUGINS table can be queried to get more detailed
information about plugins.

For example:

SELECT * FROM information_schema.PLUGINS\G
...
*************************** 6. row ***************************
     PLUGIN_NAME: CSV
    PLUGIN_VERSION: 1.0
    PLUGIN_STATUS: ACTIVE
     PLUGIN_TYPE: STORAGE ENGINE
 PLUGIN_TYPE_VERSION: 100003.0
    PLUGIN_LIBRARY: NULL
PLUGIN_LIBRARY_VERSION: NULL
    PLUGIN_AUTHOR: Brian Aker, MySQL AB
  PLUGIN_DESCRIPTION: CSV storage engine
    PLUGIN_LICENSE: GPL
     LOAD_OPTION: FORCE
   PLUGIN_MATURITY: Stable
 PLUGIN_AUTH_VERSION: 1.0
*************************** 7. row ***************************
     PLUGIN_NAME: MEMORY
    PLUGIN_VERSION: 1.0
    PLUGIN_STATUS: ACTIVE
     PLUGIN_TYPE: STORAGE ENGINE
 PLUGIN_TYPE_VERSION: 100003.0
    PLUGIN_LIBRARY: NULL
PLUGIN_LIBRARY_VERSION: NULL
    PLUGIN_AUTHOR: MySQL AB
  PLUGIN_DESCRIPTION: Hash based, stored in memory, useful for temporary
tables
    PLUGIN_LICENSE: GPL
     LOAD_OPTION: FORCE
   PLUGIN_MATURITY: Stable
 PLUGIN_AUTH_VERSION: 1.0
...

If a plugin's PLUGIN_LIBRARY column has the NULL value, then the plugin is
built-in, and it cannot be uninstalled.

Querying Plugin Information with mysql.plugin
---------------------------------------------

The mysql.plugin table can be queried to get information about installed
plugins.

This table only contains information about plugins that have been installed
via the following methods:

* The INSTALL SONAME statement.
* The INSTALL PLUGIN statement.
* The mariadb-plugin utility.

This table does not contain information about:

* Built-in plugins.
* Plugins loaded with the --plugin-load-add option.
* Plugins loaded with the --plugin-load option.

This table only contains enough information to reload the plugin when the
server is restarted, which means it only contains the plugin name and the
plugin library.

For example:

SELECT * FROM mysql.plugin;

+------+------------+
| name | dl         |
+------+------------+
| PBXT | libpbxt.so |
+------+------------+

Installing a Plugin
-------------------

There are three primary ways to install a plugin:

* A plugin can be installed dynamically with an SQL statement.
* A plugin can be installed with a mariadbd option, but it requires a server
restart.
* A plugin can be installed with the mariadb-plugin utility, while the server
is completely offline.

When you are installing a plugin, you also have to ensure that:

* The server's plugin directory is properly configured, and the plugin's
library is in the plugin directory.
* The server's minimum plugin maturity is properly configured, and the plugin
is mature enough to be installed.

Installing a Plugin Dynamically
-------------------------------

A plugin can be installed dynamically by executing either the INSTALL SONAME
or the INSTALL PLUGIN statement.

If a plugin is installed with one of these statements, then a record will be
added to the mysql.plugins table for the plugin. This means that the plugin
will automatically be loaded every time the server restarts, unless
specifically uninstalled or deactivated.

Installing a Plugin with INSTALL SONAME
---------------------------------------

You can install a plugin dynamically by executing the INSTALL SONAME
statement. INSTALL SONAME installs all plugins from the given plugin library.
This could be required for some plugin libraries.

For example, to install all plugins in the server_audit plugin library (which
is currently only the server_audit audit plugin), you could execute the
following:

INSTALL SONAME 'server_audit';

Installing a Plugin with INSTALL PLUGIN
---------------------------------------

You can install a plugin dynamically by executing the INSTALL PLUGIN
statement. INSTALL PLUGIN installs a single plugin from the given plugin
library.

For example, to install the server_audit audit plugin from the server_audit
plugin library, you could execute the following:

INSTALL PLUGIN server_audit SONAME 'server_audit';

Installing a Plugin with Plugin Load Options
--------------------------------------------

A plugin can be installed with a mariadbd option by providing either the
--plugin-load-add or the --plugin-load option.

If a plugin is installed with one of these options, then a record will not be
added to the mysql.plugins table for the plugin. This means that if the server
is restarted without the same option set, then the plugin will not
automatically be loaded.

Installing a Plugin with --plugin-load-add
------------------------------------------

You can install a plugin with the --plugin-load-add option by specifying the
option as a command-line argument to mariadbd or by specifying the option in a
relevant server option group in an option file.

The --plugin-load-add option uses the following format:

* Plugins can be specified in the format name=library, where name is the
plugin name and library is the plugin library. This format installs a single
plugin from the given plugin library.
* Plugins can also be specified in the format library, where library is the
plugin library. This format installs all plugins from the given plugin library.
* Multiple plugins can be specified by separating them with semicolons.

For example, to install all plugins in the server_audit plugin library (which
is currently only the server_audit audit plugin) and also the ed25519
authentication plugin from the auth_ed25519 plugin library, you could set the
option to the following values on the command-line:

$ mariadbd --user=mysql --plugin-load-add='server_audit'
--plugin-load-add='ed25519=auth_ed25519'

You could also set the option to the same values in an option file:

[mariadb]
...
plugin_load_add = server_audit
plugin_load_add = ed25519=auth_ed25519

Special care must be taken when specifying both the --plugin-load option and
the --plugin-load-add option together. The --plugin-load option resets the
plugin load list, and this can cause unexpected problems if you are not aware.
The --plugin-load-add option does not reset the plugin load list, so it is
much safer to use. See Specifying Multiple Plugin Load Options for more
information.

Installing a Plugin with --plugin-load
--------------------------------------

You can install a plugin with the --plugin-load option by specifying the
option as a command-line argument to mariadbd or by specifying the option in a
relevant server option group in an option file.

The --plugin-load option uses the following format:

* Plugins can be specified in the format name=library, where name is the
plugin name and library is the plugin library. This format installs a single
plugin from the given plugin library.
* Plugins can also be specified in the format library, where library is the
plugin library. This for�Tmat installs all plugins from the given plugin library.
* Multiple plugins can be specified by separating them with semicolons.

For example, to install all plugins in the server_audit plugin library (which
is currently only the server_audit audit plugin) and also the ed25519
authentication plugin from the auth_ed25519 plugin library, you could set the
option to the following values on the command-line:

$ mariadbd --user=mysql --plugin-load='server_audit;ed25519=auth_ed25519'

You could also set the option to the same values in an option file:

[mariadb]
...
plugin_load = server_audit;ed25519=auth_ed25519

Special care must be taken when specifying the --plugin-load option multiple
times, or when specifying both the --plugin-load option and the
--plugin-load-add option together. The --plugin-load option resets the plugin
load list, and this can cause unexpected problems if you are not aware. The
--plugin-load-add option does not reset the plugin load list, so it is much
safer to use. See Specifying Multiple Plugin Load Options for more information.

Specifying Multiple Plugin Load Options
---------------------------------------

Special care must be taken when specifying the --plugin-load option multiple
times, or when specifying both the --plugin-load option and the
--plugin-load-add option. The --plugin-load option resets the plugin load
list, and this can cause unexpected problems if you are not aware. The
--plugin-load-add option does not reset the plugin load list, so it is much
safer to use.

This can have the following consequences:

* If the --plugin-load option is specified multiple times, then only the last
instance will have any effect. For example, in the following case, the first
instance of the option is reset:

[mariadb]
...
plugin_load = server_audit
plugin_load = ed25519=auth_ed25519

* If the --plugin-load option is specified after the --plugin-load-add option,
then it will also reset the changes made by that option. For example, in the
following case, the --plugin-load-add option does not do anything, because the
subsequent --plugin-load option resets the plugin load list:

[mariadb]
...
plugin_load_add = server_audit
plugin_load = ed25519=auth_ed25519

* In contrast, if the --plugin-load option is specified before the
--plugin-load-add option, then it will work fine, because the
--plugin-load-add option does not reset the plugin load list. For example, in
the following case, both plugins are properly loaded:

[mariadb]
...
plugin_load = server_audit
plugin_load_add = ed25519=auth_ed25519

Installing a Plugin with mariadb-plugin
---------------------------------------

A plugin can be installed with the mariadb-plugin utility if the server is
completely offline.

The syntax is:

mariadb-plugin [options] <plugin> ENABLE|DISABLE

For example, to install the server_audit audit plugin, you could execute the
following:

mariadb-plugin server_audit ENABLE

If a plugin is installed with this utility, then a record will be added to the
mysql.plugins table for the plugin. This means that the plugin will
automatically be loaded every time the server restarts, unless specifically
uninstalled or deactivated.

Configuring the Plugin Directory
--------------------------------

When a plugin is being installed, the server looks for the plugin's library in
the server's plugin directory. This directory is configured by the plugin_dir
system variable. This can be specified as a command-line argument to mariadbd
or it can be specified in a relevant server option group in an option file.
For example:

[mariadb]
...
plugin_dir = /usr/lib64/mysql/plugin

Configuring the Minimum Plugin Maturity
---------------------------------------

When a plugin is being installed, the server compares the plugin's maturity
level against the server's minimum allowed plugin maturity. This can help
prevent users from using unstable plugins on production servers. This minimum
plugin maturity is configured by the plugin_maturity system variable. This can
be specified as a command-line argument to mariadbd or it can be specified in
a relevant server option group in an option file. For example:

[mariadb]
...
plugin_maturity = stable

Configuring Plugin Activation at Server Startup
-----------------------------------------------

A plugin will be loaded by default when the server starts if:

* The plugin was installed with the INSTALL SONAME statement.
* The plugin was installed with the INSTALL PLUGIN statement.
* The plugin was installed with the mariadb-plugin utility.
* The server is configured to load the plugin with the --plugin-load-add
option.
* The server is configured to load the plugin with the --plugin-load option.

This behavior can be changed with special options that take the form
--plugin-name. For example, for the server_audit audit plugin, the special
option is called --server-audit.

The possible values for these special options are:

+---------------------------------------+------------------------------------+
| Option Value                          | Description                        |
+---------------------------------------+------------------------------------+
| OFF                                   | Disables the plugin without        |
|                                       | removing it from the               |
|                                       | mysql.plugins table.               |
+---------------------------------------+------------------------------------+
| ON                                    | Enables the plugin. If the plugin  |
|                                       | cannot be initialized, then the    |
|                                       | server will still continue         |
|                                       | starting up, but the plugin will   |
|                                       | be disabled.                       |
+---------------------------------------+------------------------------------+
| FORCE                                 | Enables the plugin. If the plugin  |
|                                       | cannot be initialized, then the    |
|                                       | server will fail to start with an  |
|                                       | error.                             |
+---------------------------------------+------------------------------------+
| FORCE_PLUS_PERMANENT                  | Enables the plugin. If the plugin  |
|                                       | cannot be initialized, then the    |
|                                       | server will fail to start with an  |
|                                       | error. In addition, the plugin     |
|                                       | cannot be uninstalled with         |
|                                       | UNINSTALL SONAME or UNINSTALL      |
|                                       | PLUGIN while the server is         |
|                                       | running.                           |
+---------------------------------------+------------------------------------+

A plugin's status can be found by looking at the PLUGIN_STATUS column of the
information_schema.PLUGINS table.

Uninstalling Plugins
--------------------

Plugins that are found in the mysql.plugin table, that is those that were
installed with INSTALL SONAME, INSTALL PLUGIN or mariadb-plugin can be
uninstalled in one of two ways:

* The UNINSTALL SONAME or the UNINSTALL PLUGIN statement while the server is
running
* With mariadb-plugin while the server is offline.

Plugins that were enabled as a --plugin-load option do not need to be
uninstalled. If --plugin-load is omitted the next time the server starts, or
the plugin is not listed as one of the --plugin-load entries, the plugin will
not be loaded.

UNINSTALL PLUGIN uninstalls a single installed plugin, while UNINSTALL SONAME
uninstalls all plugins belonging to a given library.

URL: https://mariadb.com/kb/en/plugin-overview/k�	��https://mariadb.com/kb/en/plugin-overview/builds include a built-in plugin called wsrep.
Prior to MariaDB 10.4.3, this plugin was internally considered an XA-capable
storage engine. Consequently, these MariaDB Galera Cluster builds have
multiple XA-capable storage engines by default, even if the only "real"
storage engine that supports external XA transactions enabled on these builds
by default is InnoDB. Therefore, when using one these builds MariaDB would be
forced to use a transaction coordinator log by default, which could have
performance implications.

See Transaction Coordinator Log Overview: MariaDB Galera Cluster for more
information.

URL: https://mariadb.com/kb/en/xa-transactions/https://mariadb.com/kb/en/create-user/https://mariadb.com/kb/en/alter-user/cified via the    |
|                           | string issuer. This option implies REQUIRE     |
|                           | X509. This option can be combined with the     |
|                           | SUBJECT, and CIPHER options in any order.      |
+---------------------------+------------------------------------------------+
| REQUIRE SUBJECT 'subject' | The account must use TLS and must have a       |
|                           | valid X509 certificate. Also, the              |
|                           | certificate's Subject must be the one          |
|                           | specified via the string subject. This option  |
|                           | implies REQUIRE X509. This option can be       |
|                           | combined with the ISSUER, and CIPHER options   |
|                           | in any order.                                  |
+---------------------------+------------------------------------------------+
| REQUIRE CIPHER 'cipher'   | The account must use TLS, but no valid X509    |
|                           | certificate is required. Also, the encryption  |
|                           | used for the connection must use a specific    |
|                           | cipher method specified in the string cipher.  |
|                           | This option implies REQUIRE SSL. This option   |
|                           | can be combined with the ISSUER, and SUBJECT   |
|                           | options in any order.                          |
+---------------------------+------------------------------------------------+

The REQUIRE keyword must be used only once for all specified options, and the
AND keyword can be used to separate individual options, but it is not required.

For example, you can create a user account that requires these TLS options
with the following:

GRANT USAGE ON *.* TO 'alice'@'%'
 REQUIRE SUBJECT '/CN=alice/O=My Dom, Inc./C=US/ST=Oregon/L=Portland'
 AND ISSUER '/C=FI/ST=Somewhere/L=City/ O=Some Company/CN=Peter
Parker/emailAddress=p.parker@marvel.com'
 AND CIPHER 'SHA-DES-CBC3-EDH-RSA';

If any of these options are set for a specific user account, then any client
who tries to connect with that user account will have to be configured to
connect with TLS.

See Securing Connections for Client and Server for information on how to
enable TLS on the client and server.

Roles
-----

Syntax
------

GRANT role TO grantee [, grantee ... ]
[ WITH ADMIN OPTION ]

grantee:
  rolename
  username [authentication_option]

The GRANT statement is also used to grant the use of a role to one or more
users or other roles. In order to be able to grant a role, the grantor doing
so must have permission to do so (see WITH ADMIN in the CREATE ROLE article).

Specifying the WITH ADMIN OPTION permits the grantee to in turn grant the role
to another.

For example, the following commands show how to grant the same role to a
couple different users.

GRANT journalist TO hulda;

GRANT journalist TO berengar WITH ADMIN OPTION;

If a user has been granted a role, they do not automatically obtain all
permissions associated with that role. These permissions are only in use when
the user activates the role with the SET ROLE statement.

TO PUBLIC
---------

MariaDB starting with 10.11
---------------------------

Syntax
------

GRANT <privilege> ON <database>.<object> TO PUBLIC;
REVOKE <privilege> ON <database>.<object> FROM PUBLIC;

GRANT ... TO PUBLIC grants privileges to all users with access to the server.
The privileges also apply to users created after the privileges are granted.
This can be useful when one only wants to state once that all users need to
have a certain set of privileges.

When running SHOW GRANTS, a user will also see all privileges inherited from
PUBLIC. SHOW GRANTS FOR PUBLIC will only show TO PUBLIC grants.

Grant Examples
--------------

Granting Root-like Privileges
-----------------------------

You can create a user that has privileges similar to the default root accounts
by executing the following:

CREATE USER 'alexander'@'localhost';
GRANT ALL PRIVILEGES ON  *.* to 'alexander'@'localhost' WITH GRANT OPTION;

URL: https://mariadb.com/kb/en/grant/ion file and if mariadb-install-db is executed,
then mariadb-install-db will read this option from the option file, and it
will automatically set this option.

Altering the User Account to Revert to the Previous Authentication Method
-------------------------------------------------------------------------

If you have already installed MariaDB, and if the root@localhost user account
is already using unix_socket authentication, then you can revert to the old
mysql_native_password authentication method for the user account by executing
the following:

ALTER USER root@localhost IDENTIFIED VIA mysql_native_password USING
PASSWORD("verysecret")

URL: https://mariadb.com/kb/en/authentication-from-mariadb-104/https://mariadb.com/kb/en/inet6/https://mariadb.com/kb/en/timestamp/are marked as
closed.
* Check that all tables supports FOR EXPORT
* No changes to these tables allowed until UNLOCK TABLES

This is basically the same behavior as in old MariaDB version if one first
lock the tables, then do FLUSH TABLES. The tables will be copyable until
UNLOCK TABLES.

FLUSH SSL
---------

MariaDB starting with 10.4
--------------------------
The FLUSH SSL command was first added in MariaDB 10.4.

In MariaDB 10.4 and later, the FLUSH SSL command can be used to dynamically
reinitialize the server's TLS context. This is most useful if you need to
replace a certificate that is about to expire without restarting the server.

This operation is performed by reloading the files defined by the following
TLS system variables:

* ssl_cert
* ssl_key
* ssl_ca
* ssl_capath
* ssl_crl
* ssl_crlpath

These TLS system variables are not dynamic, so their values can not be changed
without restarting the server.

If you want to dynamically reinitialize the server's TLS context, then you
need to change the certificate and key files at the relevant paths defined by
these TLS system variables, without actually changing the values of the
variables. See MDEV-19341 for more information.

Reducing Memory Usage
---------------------

To flush some of the global caches that take up memory, you could execute the
following command:

FLUSH LOCAL HOSTS,
 QUERY CACHE,
 TABLE_STATISTICS,
 INDEX_STATISTICS,
 USER_STATISTICS;

URL: https://mariadb.com/kb/en/flush/��^$> u�b�%�&6�*��
��RY&MBRDisjointSyntax
------

MBRDisjoint(g1,g2)

Description
-----------

Returns 1 or 0 to indicate whether the Minimum Bounding Rectangles of the two
geometries g1 and g2 are disjoint. Two geometries are disjoint if they do not
intersect, that is touch or overlap.

Examples
--------

SET @g1 = GeomFromText('Polygon((0 0,0 3,3 3,3 0,0 0))');
SET @g2 = GeomFromText('Polygon((4 4,4 7,7 7,7 4,4 4))');
SELECTmbrdisjoint(@g1,@g2);
+----------------------+
| mbrdisjoint(@g1,@g2) |
+----------------------+
|                    1 |
+----------------------+

SET @g1 = GeomFromText('Polygon((0 0,0 3,3 3,3 0,0 0))');
SET @g2 = GeomFromText('Polygon((3 3,3 6,6 6,6 3,3 3))');
SELECT mbrdisjoint(@g1,@g2);
+----------------------+
| mbrdisjoint(@g1,@g2) |
+----------------------+
|                    0 |
+----------------------+

URL: https://mariadb.com/kb/en/mbrdisjoint/https://mariadb.com/kb/en/mbrdisjoint/T
#(MBRIntersectsSyntax
------

MBRIntersects(g1,g2)

Description
-----------

Returns 1 or 0 to indicate whether the Minimum Bounding Rectangles of the two
geometries g1 and g2 intersect.

Examples
--------

SET @g1 = GeomFromText('Polygon((0 0,0 3,3 3,3 0,0 0))');
SET @g2 = GeomFromText('Polygon((3 3,3 6,6 6,6 3,3 3))');
SELECT mbrintersects(@g1,@g2);
+------------------------+
| mbrintersects(@g1,@g2) |
+------------------------+
|                      1 |
+------------------------+

SET @g1 = GeomFromText('Polygon((0 0,0 3,3 3,3 0,0 0))');
SET @g2 = GeomFromText('Polygon((4 4,4 7,7 7,7 4,4 4))');
SELECT mbrintersects(@g1,@g2);
+------------------------+
| mbrintersects(@g1,@g2) |
+------------------------+
|                      0 |
+------------------------+

URL: https://mariadb.com/kb/en/mbrintersects/https://mariadb.com/kb/en/mbrintersects/U�&MBROverlapsSyntax
------

MBROverlaps(g1,g2)

Description
-----------

Returns 1 or 0 to indicate whether the Minimum Bounding Rectangles of the two
geometries g1 and g2 overlap. The term spatially overlaps is used if two
geometries intersect and their intersection results in a geometry of the same
dimension but not equal to either of the given geometries.

Examples
--------

SET @g1 = GeomFromText('Polygon((0 0,0 3,3 3,3 0,0 0))');
SET @g2 = GeomFromText('Polygon((4 4,4 7,7 7,7 4,4 4))');
SELECT mbroverlaps(@g1,@g2);
+----------------------+
| mbroverlaps(@g1,@g2) |
+----------------------+
|                    0 |
+----------------------+

SET @g1 = GeomFromText('Polygon((0 0,0 3,3 3,3 0,0 0))');
SET @g2 = GeomFromText('Polygon((3 3,3 6,6 6,6 3,3 3))');
SELECT mbroverlaps(@g1,@g2);
+----------------------+
| mbroverlaps(@g1,@g2) |
+----------------------+
|                    0 |
+----------------------+

SET @g1 = GeomFromText('Polygon((0 0,0 4,4 4,4 0,0 0))');
SET @g2 = GeomFromText('Polygon((3 3,3 6,6 6,6 3,3 3))');
SELECT mbroverlaps(@g1,@g2);
+----------------------+
| mbroverlaps(@g1,@g2) |
+----------------------+
|                    1 |
+----------------------+

URL: https://mariadb.com/kb/en/mbroverlaps/https://mariadb.com/kb/en/mbroverlaps/V
�%MBRTouchesSyntax
------

MBRTouches(g1,g2)

Description
-----------

Returns 1 or 0 to indicate whether the Minimum Bounding Rectangles of the two
geometries g1 and g2 touch. Two geometries spatially touch if the interiors of
the geometries do not intersect, but the boundary of one of the geometries
intersects either the boundary or the interior of the other.

Examples
--------

SET @g1 = GeomFromText('Polygon((0 0,0 3,3 3,3 0,0 0))');
SET @g2 = GeomFromText('Polygon((4 4,4 7,7 7,7 4,4 4))');
SELECT mbrtouches(@g1,@g2);
+---------------------+
| mbrtouches(@g1,@g2) |
+---------------------+
|                   0 |
+---------------------+

SET @g1 = GeomFromText('Polygon((0 0,0 3,3 3,3 0,0 0))');
SET @g2 = GeomFromText('Polygon((3 3,3 6,6 6,6 3,3 3))');
SELECT mbrtouches(@g1,@g2);
+---------------------+
| mbrtouches(@g1,@g2) |
+---------------------+
|                   1 |
+---------------------+

SET @g1 = GeomFromText('Polygon((0 0,0 4,4 4,4 0,0 0))');
SET @g2 = GeomFromText('Polygon((3 3,3 6,6 6,6 3,3 3))');
SELECT mbrtouches(@g1,@g2);
+---------------------+
| mbrtouches(@g1,@g2) |
+---------------------+
|                   0 |
+---------------------+

URL: https://mariadb.com/kb/en/mbrtouches/https://mariadb.com/kb/en/mbrtouches/W	�$MBRWithinSyntax
------

MBRWithin(g1,g2)

Description
-----------

Returns 1 or 0 to indicate whether the Minimum Bounding Rectangle of g1 is
within the Minimum Bounding Rectangle of g2. This tests the opposite
relationship as MBRContains().

Examples
--------

SET @g1 = GeomFromText('Polygon((0 0,0 3,3 3,3 0,0 0))');
SET @g2 = GeomFromText('Polygon((0 0,0 5,5 5,5 0,0 0))');
SELECT MBRWithin(@g1,@g2), MBRWithin(@g2,@g1);
+--------------------+--------------------+
| MBRWithin(@g1,@g2) | MBRWithin(@g2,@g1) |
+--------------------+--------------------+
|                  1 |                  0 |
+--------------------+--------------------+

URL: https://mariadb.com/kb/en/mbrwithin/https://mariadb.com/kb/en/mbrwithin/[�!NULLIFSyntax
------

NULLIF(expr1,expr2)

Description
-----------

Returns NULL if expr1 = expr2 is true, otherwise returns expr1. This is the
same as CASE WHEN expr1 = expr2 THEN NULL ELSE expr1 END.

Examples
--------

SELECT NULLIF(1,1);
+-------------+
| NULLIF(1,1) |
+-------------+
|        NULL |
+-------------+

SELECT NULLIF(1,2);
+-------------+
| NULLIF(1,2) |
+-------------+
|           1 |
+-------------+

URL: https://mariadb.com/kb/en/nullif/https://mariadb.com/kb/en/nullif/\�NVLMariaDB starting with 10.3
--------------------------
From MariaDB 10.3, NVL is a synonym for IFNULL.

URL: https://mariadb.com/kb/en/nvl/https://mariadb.com/kb/en/nvl/]�NVL2MariaDB starting with 10.3
--------------------------
The NLV2 function was introduced in MariaDB 10.3.0.

Syntax
------

NVL2(expr1,expr2,expr3)

Description
-----------

The NVL2 function returns a value based on whether a specified expression is
NULL or not. If expr1 is not NULL, then NVL2 returns expr2. If expr1 is NULL,
then NVL2 returns expr3.

Examples
--------

SELECT NVL2(NULL,1,2);
+----------------+
| NVL2(NULL,1,2) |
+----------------+
|              2 |
+----------------+

SELECT NVL2('x',1,2);
+---------------+
| NVL2('x',1,2) |
+---------------+
|             1 |
+---------------+

URL: https://mariadb.com/kb/en/nvl2/https://mariadb.com/kb/en/nvl2/f
=5UNLOCK TABLESSyntax
------

UNLOCK TABLES

Description
-----------

UNLOCK TABLES explicitly releases any table locks held by the current session.
See LOCK TABLES for more information.

In addition to releasing table locks acquired by the LOCK TABLES statement,
the UNLOCK TABLES statement also releases the global read lock acquired by the
FLUSH TABLES WITH READ LOCK statement. The FLUSH TABLES WITH READ LOCK
statement is very useful for performing backups. See FLUSH for more
information about FLUSH TABLES WITH READ LOCK.

URL: https://mariadb.com/kb/en/transactions-unlock-tables/https://mariadb.com/kb/en/transactions-unlock-tables/�@
�
�h�"*XA Transactions�@�
�iV&
CREATE USER�@�
�j
�?%
ALTER USER�@
��l� 
GRANT�@
��v �":
Authentication from MariaDB 10.4�Dk)=./�3N���������
�f�]j�Overview
--------

The MariaDB XA implementation is based on the X/Open CAE document Distributed
Transaction Processing: The XA Specification. This document is published by
The Open Group and available at
http://www.opengroup.org/public/pubs/catalog/c193.htm.

XA transactions are designed to allow distributed transactions, where a
transaction manager (the application) controls a transaction which involves
multiple resources. Such resources are usually DBMSs, but could be resources
of any type. The whole set of required transactional operations is called a
global transaction. Each subset of operations which involve a single resource
is called a local transaction. XA used a 2-phases commit (2PC). With the first
commit, the transaction manager tells each resource to prepare an effective
commit, and waits for a confirm message. The changes are not still made
effective at this point. If any of the resources encountered an error, the
transaction manager will rollback the global transaction. If all resources
communicate that the first commit is successful, the transaction manager can
require a second commit, which makes the changes effective.

In MariaDB, XA transactions can only be used with storage engines that support
them. At least InnoDB, TokuDB, SPIDER and MyRocks support them. For InnoDB,
until MariaDB 10.2, XA transactions can be disabled by setting the
innodb_support_xa server system variable to 0. From MariaDB 10.3, XA
transactions are always supported.

Like regular transactions, XA transactions create metadata locks on accessed
tables.

XA transactions require REPEATABLE READ as a minimum isolation level. However,
distributed transactions should always use SERIALIZABLE.

Trying to start more than one XA transaction at the same time produces a 1400
error (SQLSTATE 'XAE09'). The same error is produced when attempting to start
an XA transaction while a regular transaction is in effect. Trying to start a
regular transaction while an XA transaction is in effect produces a 1399 error
(SQLSTATE 'XAE07').

The statements that cause an implicit COMMIT for regular transactions produce
a 1400 error (SQLSTATE 'XAE09') if a XA transaction is in effect.

Internal XA vs External XA
--------------------------

XA transactions are an overloaded term in MariaDB. If a storage engine is
XA-capable, it can mean one or both of these:

* It supports MariaDB's internal two-phase commit API. This is transparent to
the user. Sometimes this is called "internal XA", since MariaDB's internal
transaction coordinator log can handle coordinating these transactions.

* It supports XA transactions, with the XA START, XA PREPARE, XA COMMIT, etc.
statements. Sometimes this is called "external XA", since it requires the use
of an external transaction coordinator to use this feature properly.

Transaction Coordinator Log
---------------------------

If you have two or more XA-capable storage engines enabled, then a transaction
coordinator log must be available.

There are currently two implementations of the transaction coordinator log:

* Binary log-based transaction coordinator log
* Memory-mapped file-based transaction coordinator log

If the binary log is enabled on a server, then the server will use the binary
log-based transaction coordinator log. Otherwise, it will use the
memory-mapped file-based transaction coordinator log.

See Transaction Coordinator Log for more information.

Syntax
------

XA {START|BEGIN} xid [JOIN|RESUME]

XA END xid [SUSPEND [FOR MIGRATE]]

XA PREPARE xid

XA COMMIT xid [ONE PHASE]

XA ROLLBACK xid

XA RECOVER [FORMAT=['RAW'|'SQL']]

xid: gtrid [, bqual [, formatID ]]

The interface to XA transactions is a set of SQL statements starting with XA.
Each statement changes a transaction's state, determining which actions it can
perform. A transaction which does not exist is in the NON-EXISTING state.

XA START (or BEGIN) starts a transaction and defines its xid (a transaction
identifier). The JOIN or RESUME keywords have no effect. The new transaction
will be in ACTIVE state.

The xid can have 3 components, though only the first one is mandatory. gtrid
is a quoted string representing a global transaction identifier. bqual is a
quoted string representing a local transaction identifier. formatID is an
unsigned integer indicating the format used for the first two components; if
not specified, defaults to 1. MariaDB does not interpret in any way these
components, and only uses them to identify a transaction. xids of transactions
in effect must be unique.

XA END declares that the specified ACTIVE transaction is finished and it
changes its state to IDLE. SUSPEND [FOR MIGRATE] has no effect.

XA PREPARE prepares an IDLE transaction for commit, changing its state to
PREPARED. This is the first commit.

XA COMMIT definitely commits and terminates a transaction which has already
been PREPARED. If the ONE PHASE clause is specified, this statements performs
a 1-phase commit on an IDLE transaction.

XA ROLLBACK rolls back and terminates an IDLE or PREPARED transaction.

XA RECOVER shows information about all PREPARED transactions.

When trying to execute an operation which is not allowed for the transaction's
current state, an error is produced:

XA COMMIT 'test' ONE PHASE;
ERROR 1399 (XAE07): XAER_RMFAIL: The command cannot be executed when global
transaction is in the  ACTIVE state

XA COMMIT 'test2';
ERROR 1399 (XAE07): XAER_RMFAIL: The command cannot be executed when global
transaction is in the  NON-EXISTING state

XA RECOVER
----------

The XA RECOVER statement shows information about all transactions which are in
the PREPARED state. It does not matter which connection created the
transaction: if it has been PREPARED, it appears. But this does not mean that
a connection can commit or rollback a transaction which was started by another
connection. Note that transactions using a 1-phase commit are never in the
PREPARED state, so they cannot be shown by XA RECOVER.

XA RECOVER produces four columns:

XA RECOVER;
+----------+--------------+--------------+------+
| formatID | gtrid_length | bqual_length | data |
+----------+--------------+--------------+------+
|        1 |            4 |            0 | test |
+----------+--------------+--------------+------+

MariaDB starting with 10.3.3
----------------------------
You can use XA RECOVER FORMAT='SQL' to get the data in a human readable form
that can be directly copy-pasted into XA COMMIT or XA ROLLBACK. This is
particularly useful for binary xid generated by some transaction coordinators.

formatID is the formatID part of xid.

data are the gtrid and bqual parts of xid, concatenated.

gtrid_length and bqual_length are the lengths of gtrid and bqual, respectevely.

Examples
--------

2-phases commit:

XA START 'test';

INSERT INTO t VALUES (1,2);

XA END 'test';

XA PREPARE 'test';

XA COMMIT 'test';

1-phase commit:

XA START 'test';

INSERT INTO t VALUES (1,2);

XA END 'test';

XA COMMIT 'test' ONE PHASE;

Human-readable:

xa start '12\r34\t67\v78', 'abc\ndef', 3;

insert t1 values (40);

xa end '12\r34\t67\v78', 'abc\ndef', 3;

xa prepare '12\r34\t67\v78', 'abc\ndef', 3;

xa recover format='RAW';
+----------+--------------+--------------+--------------------+
| formatID | gtrid_length | bqual_length | data               |
+----------+--------------+--------------+--------------------+
34      67v78abc       11 |            7 | 12
def |
+----------+--------------+--------------+--------------------+

xa recover format='SQL';
+----------+--------------+--------------+-------------------------------------
---------+
| formatID | gtrid_length | bqual_length | data                               
     |
+----------+--------------+--------------+-------------------------------------
---------+
|        3 |           11 |            7 |
X'31320d3334093637763738',X'6162630a646566',3 |
+----------+--------------+--------------+-------------------------------------
---------+

xa rollback X'31320d3334093637763738',X'6162630a646566',3;

Known Issues
------------

MariaDB Galera Cluster
----------------------

MariaDB Galera Cluster does not support XA transactions.

However, MariaDB Galera Cluster  ����https://mariadb.com/kb/en/xa-transactions/:50:05 |
|    3 | 2013-07-22 12:51:56 |
|    4 | 2001-07-22 12:12:12 |
+------+---------------------+

Converting to Unix epoch:

SELECT ts, UNIX_TIMESTAMP(ts) FROM t;
+---------------------+--------------------+
| ts                  | UNIX_TIMESTAMP(ts) |
+---------------------+--------------------+
| 2013-07-22 12:50:05 |         1374490205 |
| 2013-07-22 12:50:05 |         1374490205 |
| 2013-07-22 12:51:56 |         1374490316 |
| 2001-07-22 12:12:12 |          995796732 |
+---------------------+--------------------+

Update also changes the timestamp:

UPDATE t set id=5 WHERE id=1;

SELECT * FROM t;
+------+---------------------+
| id   | ts                  |
+------+---------------------+
|    5 | 2013-07-22 14:52:33 |
|    2 | 2013-07-22 12:50:05 |
|    3 | 2013-07-22 12:51:56 |
|    4 | 2001-07-22 12:12:12 |
+------+---------------------+

Default NULL:

CREATE TABLE t2 (id INT, ts TIMESTAMP NULL ON UPDATE CURRENT_TIMESTAMP);

INSERT INTO t(id)  VALUES (1),(2);

SELECT * FROM t2;

INSERT INTO t2(id)  VALUES (1),(2);

SELECT * FROM t2;
+------+------+
| id   | ts   |
+------+------+
|    1 | NULL |
|    2 | NULL |
+------+------+

UPDATE t2 SET id=3 WHERE id=1;

SELECT * FROM t2;
+------+---------------------+
| id   | ts                  |
+------+---------------------+
|    3 | 2013-07-22 15:32:22 |
|    2 | NULL                |
+------+---------------------+

Only the first timestamp is automatically inserted and updated:

CREATE TABLE t3 (id INT, ts1 TIMESTAMP, ts2 TIMESTAMP);

INSERT INTO t3(id)  VALUES (1),(2);

SELECT * FROM t3;
+------+---------------------+---------------------+
| id   | ts1                 | ts2                 |
+------+---------------------+---------------------+
|    1 | 2013-07-22 15:35:07 | 0000-00-00 00:00:00 |
|    2 | 2013-07-22 15:35:07 | 0000-00-00 00:00:00 |
+------+---------------------+---------------------+

DESC t3;
+-------+-----------+------+-----+---------------------+-----------------------
-----+
| Field | Type      | Null | Key | Default             | Extra                
   |
+-------+-----------+------+-----+---------------------+-----------------------
-----+
| id    | int(11)   | YES  |     | NULL                |                      
   |
| ts1   | timestamp | NO   |     | CURRENT_TIMESTAMP   | on update
CURRENT_TIMESTAMP |
| ts2   | timestamp | NO   |     | 0000-00-00 00:00:00 |                      
   |
+-------+-----------+------+-----+---------------------+-----------------------
-----+

Explicitly setting a timestamp with the CURRENT_TIMESTAMP function:

INSERT INTO t3(id,ts2)  VALUES (3,CURRENT_TIMESTAMP());

SELECT * FROM t3;
+------+---------------------+---------------------+
| id   | ts1                 | ts2                 |
+------+---------------------+---------------------+
|    1 | 2013-07-22 15:35:07 | 0000-00-00 00:00:00 |
|    2 | 2013-07-22 15:35:07 | 0000-00-00 00:00:00 |
|    3 | 2013-07-22 15:38:52 | 2013-07-22 15:38:52 |
+------+---------------------+---------------------+

Specifying the timestamp as NOT NULL:

CREATE TABLE t4 (id INT, ts TIMESTAMP NOT NULL);

INSERT INTO t4(id)  VALUES (1);
SELECT SLEEP(1);
INSERT INTO t4(id,ts) VALUES (2,NULL);

SELECT * FROM t4;

URL: https://mariadb.com/kb/en/timestamp/https://mariadb.com/kb/en/flush/https://mariadb.com/kb/en/show-replica-status/   3 |    3 |    6 |
|    4 |    4 |    8 |
|    5 |    5 |   10 |
|    6 |    8 |   14 |
+------+------+------+

Another example, given the following data (the separator is a tab):

1       a
2       b

The value of the first column is doubled before loading:

LOAD DATA INFILE 'ld.txt' INTO TABLE ld (@i,v) SET i=@i*2;

SELECT * FROM ld;
+------+------+
| i    | v    |
+------+------+
|    2 | a    |
|    4 | b    |
+------+------+

URL: https://mariadb.com/kb/en/load-data-infile/ AND t1.id=(
  SELECT MAX(id) FROM t tab WHERE tab.f1=t1.f1
 )
);
Query OK, 2 rows affected (0.120 sec)

SELECT * FROM t;
+------+------+
| id   | f1   |
+------+------+
|    3 | b    |
|    4 | a    |
+------+------

URL: https://mariadb.com/kb/en/useful-mariadb-queries/https://mariadb.com/kb/en/explain/https://mariadb.com/kb/en/reserved-words/https://mariadb.com/kb/en/sql_modeoracle/https://mariadb.com/kb/en/date_format/ OS function to convert the data using the system time zone. At least
on Linux, the corresponding function (localtime_r) uses a global mutex inside
glibc that can cause contention under high concurrent load.

Set your time zone to a named time zone to avoid this issue. See mysql time
zone tables for details on how to do this.

Examples
--------

SELECT FROM_UNIXTIME(1196440219);
+---------------------------+
| FROM_UNIXTIME(1196440219) |
+---------------------------+
| 2007-11-30 11:30:19       |
+---------------------------+

SELECT FROM_UNIXTIME(1196440219) + 0;
+-------------------------------+
| FROM_UNIXTIME(1196440219) + 0 |
+-------------------------------+
|         20071130113019.000000 |
+-------------------------------+

SELECT FROM_UNIXTIME(UNIX_TIMESTAMP(), '%Y %D %M %h:%i:%s %x');
+---------------------------------------------------------+
| FROM_UNIXTIME(UNIX_TIMESTAMP(), '%Y %D %M %h:%i:%s %x') |
+---------------------------------------------------------+
| 2010 27th March 01:03:47 2010                           |
+---------------------------------------------------------+

URL: https://mariadb.com/kb/en/from_unixtime/               |
+---------------------------------------------------------+

SELECT STR_TO_DATE('Wednesday23423, June 2, 2014', '%W, %M %e, %Y');
+--------------------------------------------------------------+
| STR_TO_DATE('Wednesday23423, June 2, 2014', '%W, %M %e, %Y') |
+--------------------------------------------------------------+
| NULL                                                         |
+--------------------------------------------------------------+
1 row in set, 1 warning (0.00 sec)

SHOW WARNINGS;
+---------+------+-------------------------------------------------------------
---------------------+
| Level   | Code | Message                                                    
           |
+---------+------+-------------------------------------------------------------
---------------------+
| Warning | 1411 | Incorrect datetime value: 'Wednesday23423, June 2, 2014'
for function str_to_date |
+---------+------+-------------------------------------------------------------
---------------------+

SELECT STR_TO_DATE('Wednesday23423, June 2, 2014', '%W%#, %M %e, %Y');
+----------------------------------------------------------------+
| STR_TO_DATE('Wednesday23423, June 2, 2014', '%W%#, %M %e, %Y') |
+----------------------------------------------------------------+
| 2014-06-02                                                     |
+----------------------------------------------------------------+

URL: https://mariadb.com/kb/en/str_to_date/J����&{)R)0" ;
�

.� 6�*i7�USyntax
------

CREATE [OR REPLACE] USER [IF NOT EXISTS] 
 user_specification [,user_specification ...] 
 [REQUIRE {NONE | tls_option [[AND] tls_option ...] }]
 [WITH resource_option [resource_option ...] ]
 [lock_option] [password_option]

user_specification:
 username [authentication_option]

authentication_option:
 IDENTIFIED BY 'password'
 | IDENTIFIED BY PASSWORD 'password_hash'
 | IDENTIFIED {VIA|WITH} authentication_rule [OR authentication_rule  ...]

authentication_rule:
  authentication_plugin
 | authentication_plugin {USING|AS} 'authentication_string'
 | authentication_plugin {USING|AS} PASSWORD('password')

tls_option:
 SSL
 | X509
 | CIPHER 'cipher'
 | ISSUER 'issuer'
 | SUBJECT 'subject'

resource_option:
 MAX_QUERIES_PER_HOUR count
 | MAX_UPDATES_PER_HOUR count
 | MAX_CONNECTIONS_PER_HOUR count
 | MAX_USER_CONNECTIONS count
 | MAX_STATEMENT_TIME time

password_option:
 PASSWORD EXPIRE
 | PASSWORD EXPIRE DEFAULT
 | PASSWORD EXPIRE NEVER
 | PASSWORD EXPIRE INTERVAL N DAY

lock_option:
  ACCOUNT LOCK
 | ACCOUNT UNLOCK
}

Description
-----------

The CREATE USER statement creates new MariaDB accounts. To use it, you must
have the global CREATE USER privilege or the INSERT privilege for the mysql
database. For each account, CREATE USER creates a new row in mysql.user (until
MariaDB 10.3 this is a table, from MariaDB 10.4 it's a view) or
mysql.global_priv_table (from MariaDB 10.4) that has no privileges.

If any of the specified accounts, or any permissions for the specified
accounts, already exist, then the server returns ERROR 1396 (HY000). If an
error occurs, CREATE USER will still create the accounts that do not result in
an error. Only one error is produced for all users which have not been created:

ERROR 1396 (HY000): 
 Operation CREATE USER failed for 'u1'@'%','u2'@'%'

CREATE USER, DROP USER, CREATE ROLE, and DROP ROLE all produce the same error
code when they fail.

See Account Names below for details on how account names are specified.

OR REPLACE
----------

If the optional OR REPLACE clause is used, it is basically a shortcut for:

DROP USER IF EXISTS name;
CREATE USER name ...;

For example:

CREATE USER foo2@test IDENTIFIED BY 'password';
ERROR 1396 (HY000): Operation CREATE USER failed for 'foo2'@'test'

CREATE OR REPLACE USER foo2@test IDENTIFIED BY 'password';
Query OK, 0 rows affected (0.00 sec)

IF NOT EXISTS
-------------

When the IF NOT EXISTS clause is used, MariaDB will return a warning instead
of an error if the specified user already exists.

For example:

CREATE USER foo2@test IDENTIFIED BY 'password';
ERROR 1396 (HY000): Operation CREATE USER failed for 'foo2'@'test'

CREATE USER IF NOT EXISTS foo2@test IDENTIFIED BY 'password';
Query OK, 0 rows affected, 1 warning (0.00 sec)

SHOW WARNINGS;
+-------+------+----------------------------------------------------+
| Level | Code | Message                                            |
+-------+------+----------------------------------------------------+
| Note  | 1973 | Can't create user 'foo2'@'test'; it already exists |
+-------+------+----------------------------------------------------+

Authentication Options
----------------------

IDENTIFIED BY 'password'
------------------------

The optional IDENTIFIED BY clause can be used to provide an account with a
password. The password should be specified in plain text. It will be hashed by
the PASSWORD function prior to being stored in the
mysql.user/mysql.global_priv_table table.

For example, if our password is mariadb, then we can create the user with:

CREATE USER foo2@test IDENTIFIED BY 'mariadb';

If you do not specify a password with the IDENTIFIED BY clause, the user will
be able to connect without a password. A blank password is not a wildcard to
match any password. The user must connect without providing a password if no
password is set.

The only authentication plugins that this clause supports are
mysql_native_password and mysql_old_password.

IDENTIFIED BY PASSWORD 'password_hash'
--------------------------------------

The optional IDENTIFIED BY PASSWORD clause can be used to provide an account
with a password that has already been hashed. The password should be specified
as a hash that was provided by the PASSWORD function. It will be stored in the
mysql.user/mysql.global_priv_table table as-is.

For example, if our password is mariadb, then we can find the hash with:

SELECT PASSWORD('mariadb');
+-------------------------------------------+
| PASSWORD('mariadb')                       |
+-------------------------------------------+
| *54958E764CE10E50764C2EECBB71D01F08549980 |
+-------------------------------------------+
1 row in set (0.00 sec)

And then we can create a user with the hash:

CREATE USER foo2@test IDENTIFIED BY PASSWORD
'*54958E764CE10E50764C2EECBB71D01F08549980';

If you do not specify a password with the IDENTIFIED BY clause, the user will
be able to connect without a password. A blank password is not a wildcard to
match any password. The user must connect without providing a password if no
password is set.

The only authentication plugins that this clause supports are
mysql_native_password and mysql_old_password.

IDENTIFIED {VIA|WITH} authentication_plugin
-------------------------------------------

The optional IDENTIFIED VIA authentication_plugin allows you to specify that
the account should be authenticated by a specific authentication plugin. The
plugin name must be an active authentication plugin as per SHOW PLUGINS. If it
doesn't show up in that output, then you will need to install it with INSTALL
PLUGIN or INSTALL SONAME.

For example, this could be used with the PAM authentication plugin:

CREATE USER foo2@test IDENTIFIED VIA pam;

Some authentication plugins allow additional arguments to be specified after a
USING or AS keyword. For example, the PAM authentication plugin accepts a
service name:

CREATE USER foo2@test IDENTIFIED VIA pam USING 'mariadb';

The exact meaning of the additional argument would depend on the specific
authentication plugin.

MariaDB starting with 10.4.0
----------------------------
The USING or AS keyword can also be used to provide a plain-text password to a
plugin if it's provided as an argument to the PASSWORD() function. This is
only valid for authentication plugins that have implemented a hook for the
PASSWORD() function. For example, the ed25519 authentication plugin supports
this:

CREATE USER safe@'%' IDENTIFIED VIA ed25519 USING PASSWORD('secret');

MariaDB starting with 10.4.3
----------------------------
One can specify many authentication plugins, they all work as alternatives
ways of authenticating a user:

CREATE USER safe@'%' IDENTIFIED VIA ed25519 USING PASSWORD('secret') OR
unix_socket;

By default, when you create a user without specifying an authentication
plugin, MariaDB uses the mysql_native_password plugin.

TLS Options
-----------

By default, MariaDB transmits data between the server and clients without
encrypting it. This is generally acceptable when the server and client run on
the same host or in networks where security is guaranteed through other means.
However, in cases where the server and client exist on separate networks or
they are in a high-risk network, the lack of encryption does introduce
security concerns as a malicious actor could potentially eavesdrop on the
traffic as it is sent over the network between them.

To mitigate this concern, MariaDB allows you to encrypt data in transit
between the server and clients using the Transport Layer Security (TLS)
protocol. TLS was formerly known as Secure Socket Layer (SSL), but strictly
speaking the SSL protocol is a predecessor to TLS and, that version of the
protocol is now considered insecure. The documentation still uses the term SSL
often and for compatibility reasons TLS-related server system and status
variables still use the prefix ssl_, but internally, MariaDB only supports its
secure successors.

See Secure Connections Overview for more information about how to determine
whether your MariaDB server has TLS support.

You can set certain TLS-related restrictions for specific user accounts. For
instance, you might use this with user account��s that require access to
sensitive data while sending it across networks that you do not control. These
restrictions can be enabled for a user account with the CREATE USER, ALTER
USER, or GRANT statements. The following options are available:

+---------------------------+------------------------------------------------+
| Option                    | Description                                    |
+---------------------------+------------------------------------------------+
| REQUIRE NONE              | TLS is not required for this account, but can  |
|                           | still be used.                                 |
+---------------------------+------------------------------------------------+
| REQUIRE SSL               | The account must use TLS, but no valid X509    |
|                           | certificate is required. This option cannot    |
|                           | be combined with other TLS options.            |
+---------------------------+------------------------------------------------+
| REQUIRE X509              | The account must use TLS and must have a       |
|                           | valid X509 certificate. This option implies    |
|                           | REQUIRE SSL. This option cannot be combined    |
|                           | with other TLS options.                        |
+---------------------------+------------------------------------------------+
| REQUIRE ISSUER 'issuer'   | The account must use TLS and must have a       |
|                           | valid X509 certificate. Also, the Certificate  |
|                           | Authority must be the one specified via the    |
|                           | string issuer. This option implies REQUIRE     |
|                           | X509. This option can be combined with the     |
|                           | SUBJECT, and CIPHER options in any order.      |
+---------------------------+------------------------------------------------+
| REQUIRE SUBJECT 'subject' | The account must use TLS and must have a       |
|                           | valid X509 certificate. Also, the              |
|                           | certificate's Subject must be the one          |
|                           | specified via the string subject. This option  |
|                           | implies REQUIRE X509. This option can be       |
|                           | combined with the ISSUER, and CIPHER options   |
|                           | in any order.                                  |
+---------------------------+------------------------------------------------+
| REQUIRE CIPHER 'cipher'   | The account must use TLS, but no valid X509    |
|                           | certificate is required. Also, the encryption  |
|                           | used for the connection must use a specific    |
|                           | cipher method specified in the string cipher.  |
|                           | This option implies REQUIRE SSL. This option   |
|                           | can be combined with the ISSUER, and SUBJECT   |
|                           | options in any order.                          |
+---------------------------+------------------------------------------------+

The REQUIRE keyword must be used only once for all specified options, and the
AND keyword can be used to separate individual options, but it is not required.

For example, you can create a user account that requires these TLS options
with the following:

CREATE USER 'alice'@'%'
 REQUIRE SUBJECT '/CN=alice/O=My Dom, Inc./C=US/ST=Oregon/L=Portland'
 AND ISSUER '/C=FI/ST=Somewhere/L=City/ O=Some Company/CN=Peter
Parker/emailAddress=p.parker@marvel.com'
 AND CIPHER 'SHA-DES-CBC3-EDH-RSA';

If any of these options are set for a specific user account, then any client
who tries to connect with that user account will have to be configured to
connect with TLS.

See Securing Connections for Client and Server for information on how to
enable TLS on the client and server.

Resource Limit Options
----------------------

It is possible to set per-account limits for certain server resources. The
following table shows the values that can be set per account:

+--------------------------------------+--------------------------------------+
| Limit Type                           | Decription                           |
+--------------------------------------+--------------------------------------+
| MAX_QUERIES_PER_HOUR                 | Number of statements that the        |
|                                      | account can issue per hour           |
|                                      | (including updates)                  |
+--------------------------------------+--------------------------------------+
| MAX_UPDATES_PER_HOUR                 | Number of updates (not queries)      |
|                                      | that the account can issue per hour  |
+--------------------------------------+--------------------------------------+
| MAX_CONNECTIONS_PER_HOUR             | Number of connections that the       |
|                                      | account can start per hour           |
+--------------------------------------+--------------------------------------+
| MAX_USER_CONNECTIONS                 | Number of simultaneous connections   |
|                                      | that can be accepted from the same   |
|                                      | account; if it is 0,                 |
|                                      | max_connections will be used         |
|                                      | instead; if max_connections is 0,    |
|                                      | there is no limit for this           |
|                                      | account's simultaneous connections.  |
+--------------------------------------+--------------------------------------+
| MAX_STATEMENT_TIME                   | Timeout, in seconds, for statements  |
|                                      | executed by the user. See also       |
|                                      | Aborting Statements that Exceed a    |
|                                      | Certain Time to Execute.             |
+--------------------------------------+--------------------------------------+

If any of these limits are set to 0, then there is no limit for that resource
for that user.

Here is an example showing how to create a user with resource limits:

CREATE USER 'someone'@'localhost' WITH
  MAX_USER_CONNECTIONS 10
  MAX_QUERIES_PER_HOUR 200;

The resources are tracked per account, which means 'user'@'server'; not per
user name or per connection.

The count can be reset for all users using FLUSH USER_RESOURCES, FLUSH
PRIVILEGES or mariadb-admin reload.

Per account resource limits are stored in the user table, in the mysql
database. Columns used for resources limits are named max_questions,
max_updates, max_connections (for MAX_CONNECTIONS_PER_HOUR), and
max_user_connections (for MAX_USER_CONNECTIONS).

Account Names
-------------

Account names have both a user name component and a host name component, and
are specified as 'user_name'@'host_name'.

The user name and host name may be unquoted, quoted as strings using double
quotes (") or single quotes ('), or quoted as identifiers using backticks (`).
You must use quotes when using special characters (such as a hyphen) or
wildcard characters. If you quote, you must quote the user name and host name
separately (for example 'user_name'@'host_name').

Host Name Component
-------------------

If the host name is not provided, it is assumed to be '%'.

Host names may contain the wildcard characters % and _. They are matched as if
by the LIKE clause. If you need to use a wildcard character literally (for
example, to match a domain name with an underscore), prefix the character with
a backslash. See LIKE for more information on escaping wildcard characters.

Host name matches are case-insensitive. Host names can match either domain
names or IP addresses. Use 'localhost' as the host name to allow only local
client connections. On Linux, the loopback interface (127.0.0.1) will not
match 'localhost' as it isR��
�3 not considered a local connection: this means that
only connections via UNIX-domain sockets will match 'localhost'.

You can use a netmask to match a range of IP addresses using 'base_ip/netmask'
as the host name. A user with an IP address ip_addr will be allowed to connect
if the following condition is true:

ip_addr & netmask = base_ip

For example, given a user:

CREATE USER 'maria'@'247.150.130.0/255.255.255.0';

the IP addresses satisfying this condition range from 247.150.130.0 to
247.150.130.255.

Using 255.255.255.255 is equivalent to not using a netmask at all. Netmasks
cannot be used for IPv6 addresses.

Note that the credentials added when creating a user with the '%' wildcard
host will not grant access in all cases. For example, some systems come with
an anonymous localhost user, and when connecting from localhost this will take
precedence.

Before MariaDB 10.6, the host name component could be up to 60 characters in
length. Starting from MariaDB 10.6, it can be up to 255 characters.

User Name Component
-------------------

User names must match exactly, including case. A user name that is empty is
known as an anonymous account and is allowed to match a login attempt with any
user name component. These are described more in the next section.

For valid identifiers to use as user names, see Identifier Names.

It is possible for more than one account to match when a user connects.
MariaDB selects the first matching account after sorting according to the
following criteria:

* Accounts with an exact host name are sorted before accounts using a wildcard
in the
host name. Host names using a netmask are considered to be exact for sorting.
* Accounts with a wildcard in the host name are sorted according to the
position of
the first wildcard character. Those with a wildcard character later in the
host name
sort before those with a wildcard character earlier in the host name.
* Accounts with a non-empty user name sort before accounts with an empty user
name.
* Accounts with an empty user name are sorted last. As mentioned previously,
these are known as anonymous accounts. These are described more in the next
section.

The following table shows a list of example account as sorted by these
criteria:

+---------+-------------+
| User    | Host        |
+---------+-------------+
| joffrey | 192.168.0.3 |
|         | 192.168.0.% |
| joffrey | 192.168.%   |
|         | 192.168.%   |
+---------+-------------+

Once connected, you only have the privileges granted to the account that
matched, not all accounts that could have matched. For example, consider the
following commands:

CREATE USER 'joffrey'@'192.168.0.3';
CREATE USER 'joffrey'@'%';
GRANT SELECT ON test.t1 to 'joffrey'@'192.168.0.3';
GRANT SELECT ON test.t2 to 'joffrey'@'%';

If you connect as joffrey from 192.168.0.3, you will have the SELECT privilege
on the table test.t1, but not on the table test.t2. If you connect as joffrey
from any other IP address, you will have the SELECT privilege on the table
test.t2, but not on the table test.t1.

Usernames can be up to 80 characters long before 10.6 and starting from 10.6
it can be 128 characters long.

Anonymous Accounts
------------------

Anonymous accounts are accounts where the user name portion of the account
name is empty. These accounts act as special catch-all accounts. If a user
attempts to log into the system from a host, and an anonymous account exists
with a host name portion that matches the user's host, then the user will log
in as the anonymous account if there is no more specific account match for the
user name that the user entered.

For example, here are some anonymous accounts:

CREATE USER ''@'localhost';
CREATE USER ''@'192.168.0.3';

Fixing a Legacy Default Anonymous Account
-----------------------------------------

On some systems, the mysql.db table has some entries for the ''@'%' anonymous
account by default. Unfortunately, there is no matching entry in the
mysql.user/mysql.global_priv_table table, which means that this anonymous
account doesn't exactly exist, but it does have privileges--usually on the
default test database created by mariadb-install-db. These account-less
privileges are a legacy that is leftover from a time when MySQL's privilege
system was less advanced.

This situation means that you will run into errors if you try to create a
''@'%' account. For example:

CREATE USER ''@'%';
ERROR 1396 (HY000): Operation CREATE USER failed for ''@'%'

The fix is to DELETE the row in the mysql.db table and then execute FLUSH
PRIVILEGES:

DELETE FROM mysql.db WHERE User='' AND Host='%';
FLUSH PRIVILEGES;

And then the account can be created:

CREATE USER ''@'%';
Query OK, 0 rows affected (0.01 sec)

See MDEV-13486 for more information.

Password Expiry
---------------

MariaDB starting with 10.4.3
----------------------------
Besides automatic password expiry, as determined by default_password_lifetime,
password expiry times can be set on an individual user basis, overriding the
global setting, for example:

CREATE USER 'monty'@'localhost' PASSWORD EXPIRE INTERVAL 120 DAY;

See User Password Expiry for more details.

Account Locking
---------------

MariaDB starting with 10.4.2
----------------------------
Account locking permits privileged administrators to lock/unlock user
accounts. No new client connections will be permitted if an account is locked
(existing connections are not affected). For example:

CREATE USER 'marijn'@'localhost' ACCOUNT LOCK;

See Account Locking for more details.

From MariaDB 10.4.7 and MariaDB 10.5.8, the lock_option and password_option
clauses can occur in either order.

URL: https://mariadb.com/kb/en/create-user/om/kb/en/alter-user/https://mariadb.com/kb/en/grant/https://mariadb.com/kb/en/authentication-from-mariadb-104/https://mariadb.com/kb/en/load-data-infile/https://mariadb.com/kb/en/useful-mariadb-queries/https://mariadb.com/kb/en/from_unixtime/https://mariadb.com/kb/en/str_to_date/https://mariadb.com/kb/en/alter-table/ll not be
created.  There will not be any error for the client, just a warning.
* How to create a PRIMARY KEY that is automatically generated.
* How to specify a table-specific character set and another for a column.
* How to create an index (name) that is only partly indexed (to save space).

The following clauses will work from MariaDB 10.2.1 only.

CREATE TABLE t1(
 a int DEFAULT (1+1),
 b int DEFAULT (a+1),
 expires DATETIME DEFAULT(NOW() + INTERVAL 1 YEAR),
 x BLOB DEFAULT USER()
);

URL: https://mariadb.com/kb/en/create-table/�a&;&(�1�+}:] = 1�C�Syntax
------

ALTER USER [IF EXISTS] 
 user_specification [,user_specification] ...
 [REQUIRE {NONE | tls_option [[AND] tls_option] ...}]
 [WITH resource_option [resource_option] ...]
 [lock_option] [password_option]

user_specification:
 username [authentication_option]

authentication_option:
 IDENTIFIED BY 'password'
 | IDENTIFIED BY PASSWORD 'password_hash'
 | IDENTIFIED {VIA|WITH} authentication_rule [OR authentication_rule] ...

authentication_rule:
 authentication_plugin
 | authentication_plugin {USING|AS} 'authentication_string'
 | authentication_plugin {USING|AS} PASSWORD('password')

tls_option
 SSL
 | X509
 | CIPHER 'cipher'
 | ISSUER 'issuer'
 | SUBJECT 'subject'

resource_option
 MAX_QUERIES_PER_HOUR count
 | MAX_UPDATES_PER_HOUR count
 | MAX_CONNECTIONS_PER_HOUR count
 | MAX_USER_CONNECTIONS count
 | MAX_STATEMENT_TIME time

password_option:
 PASSWORD EXPIRE
 | PASSWORD EXPIRE DEFAULT
 | PASSWORD EXPIRE NEVER
 | PASSWORD EXPIRE INTERVAL N DAY

lock_option:
  ACCOUNT LOCK
 | ACCOUNT UNLOCK
}

Description
-----------

The ALTER USER statement modifies existing MariaDB accounts. To use it, you
must have the global CREATE USER privilege or the UPDATE privilege for the
mysql database. The global SUPER privilege is also required if the read_only
system variable is enabled.

If any of the specified user accounts do not yet exist, an error results. If
an error occurs, ALTER USER will still modify the accounts that do not result
in an error. Only one error is produced for all users which have not been
modified.

IF EXISTS
---------

When the IF EXISTS clause is used, MariaDB will return a warning instead of an
error for each specified user that does not exist.

Account Names
-------------

For ALTER USER statements, account names are specified as the username
argument in the same way as they are for CREATE USER statements. See account
names from the CREATE USER page for details on how account names are specified.

CURRENT_USER or CURRENT_USER() can also be used to alter the account logged
into the current session. For example, to change the current user's password
to mariadb:

ALTER USER CURRENT_USER() IDENTIFIED BY 'mariadb';

Authentication Options
----------------------

MariaDB starting with 10.4
--------------------------
From MariaDB 10.4, it is possible to use more than one authentication plugin
for each user account. For example, this can be useful to slowly migrate users
to the more secure ed25519 authentication plugin over time, while allowing the
old mysql_native_password authentication plugin as an alternative for the
transitional period. See Authentication from MariaDB 10.4 for more.

When running ALTER USER, not specifying an authentication option in the
IDENTIFIED VIA clause will remove that authentication method. (However this
was not the case before MariaDB 10.4.13, see MDEV-21928)

For example, a user is created with the ability to authenticate via both a
password and unix_socket:

CREATE USER 'bob'@'localhost' 
 IDENTIFIED VIA mysql_native_password USING PASSWORD('pwd')
 OR unix_socket;

SHOW CREATE USER 'bob'@'localhost'\G
*************************** 1. row ***************************
CREATE USER for bob@localhost: CREATE USER `bob`@`localhost` 
 IDENTIFIED VIA mysql_native_password
 USING '*975B2CD4FF9AE554FE8AD33168FBFC326D2021DD'
 OR unix_socket

If the user's password is updated, but unix_socket authentication is not
specified in the IDENTIFIED VIA clause, unix_socket authentication will no
longer be permitted.

ALTER USER 'bob'@'localhost' IDENTIFIED VIA mysql_native_password 
 USING PASSWORD('pwd2');

SHOW CREATE USER 'bob'@'localhost'\G
*************************** 1. row ***************************
CREATE USER for bob@localhost: CREATE USER `bob`@`localhost` 
 IDENTIFIED BY PASSWORD '*38366FDA01695B6A5A9DD4E428D9FB8F7EB75512'

IDENTIFIED BY 'password'
------------------------

The optional IDENTIFIED BY clause can be used to provide an account with a
password. The password should be specified in plain text. It will be hashed by
the PASSWORD function prior to being stored to the mysql.user table.

For example, if our password is mariadb, then we can set the account's
password with:

ALTER USER foo2@test IDENTIFIED BY 'mariadb';

If you do not specify a password with the IDENTIFIED BY clause, the user will
be able to connect without a password. A blank password is not a wildcard to
match any password. The user must connect without providing a password if no
password is set.

The only authentication plugins that this clause supports are
mysql_native_password and mysql_old_password.

IDENTIFIED BY PASSWORD 'password_hash'
--------------------------------------

The optional IDENTIFIED BY PASSWORD clause can be used to provide an account
with a password that has already been hashed. The password should be specified
as a hash that was provided by the PASSWORD#function. It will be stored to the
mysql.user table as-is.

For example, if our password is mariadb, then we can find the hash with:

SELECT PASSWORD('mariadb');
+-------------------------------------------+
| PASSWORD('mariadb')                       |
+-------------------------------------------+
| *54958E764CE10E50764C2EECBB71D01F08549980 |
+-------------------------------------------+

And then we can set an account's password with the hash:

ALTER USER foo2@test 
 IDENTIFIED BY PASSWORD '*54958E764CE10E50764C2EECBB71D01F08549980';

If you do not specify a password with the IDENTIFIED BY clause, the user will
be able to connect without a password. A blank password is not a wildcard to
match any password. The user must connect without providing a password if no
password is set.

The only authentication plugins that this clause supports are
mysql_native_password and mysql_old_password.

IDENTIFIED {VIA|WITH} authentication_plugin
-------------------------------------------

The optional IDENTIFIED VIA authentication_plugin allows you to specify that
the account should be authenticated by a specific authentication plugin. The
plugin name must be an active authentication plugin as per SHOW PLUGINS. If it
doesn't show up in that output, then you will need to install it with INSTALL
PLUGIN or INSTALL SONAME.

For example, this could be used with the PAM authentication plugin:

ALTER USER foo2@test IDENTIFIED VIA pam;

Some authentication plugins allow additional arguments to be specified after a
USING or AS keyword. For example, the PAM authentication plugin accepts a
service name:

ALTER USER foo2@test IDENTIFIED VIA pam USING 'mariadb';

The exact meaning of the additional argument would depend on the specific
authentication plugin.

In MariaDB 10.4 and later, the USING or AS keyword can also be used to provide
a plain-text password to a plugin if it's provided as an argument to the
PASSWORD() function. This is only valid for authentication plugins that have
implemented a hook for the PASSWORD() function. For example, the ed25519
authentication plugin supports this:

ALTER USER safe@'%' IDENTIFIED VIA ed25519 USING PASSWORD('secret');

TLS Options
-----------

By default, MariaDB transmits data between the server and clients without
encrypting it. This is generally acceptable when the server and client run on
the same host or in networks where security is guaranteed through other means.
However, in cases where the server and client exist on separate networks or
they are in a high-risk network, the lack of encryption does introduce
security concerns as a malicious actor could potentially eavesdrop on the
traffic as it is sent over the network between them.

To mitigate this concern, MariaDB allows you to encrypt data in transit
between the server and clients using the Transport Layer Security (TLS)
protocol. TLS was formerly known as Secure Socket Layer (SSL), but strictly
speaking the SSL protocol is a predecessor to TLS and, that version of the
protocol is now considered insecure. The documentation still uses the term SSL
often and for compatibility reasons TLS-related server system and status
variables still use the prefix ssl_, but internally, MariaDB only supports its
secure successors.

See Secure Connections Overview for more information��� about how to determine
whether your MariaDB server has TLS support.

You can set certain TLS-related restrictions for specific user accounts. For
instance, you might use this with user accounts that require access to
sensitive data while sending it across networks that you do not control. These
restrictions can be enabled for a user account with the CREATE USER, ALTER
USER, or GRANT statements. The following options are available:

+---------------------------+------------------------------------------------+
| Option                    | Description                                    |
+---------------------------+------------------------------------------------+
| REQUIRE NONE              | TLS is not required for this account, but can  |
|                           | still be used.                                 |
+---------------------------+------------------------------------------------+
| REQUIRE SSL               | The account must use TLS, but no valid X509    |
|                           | certificate is required. This option cannot    |
|                           | be combined with other TLS options.            |
+---------------------------+------------------------------------------------+
| REQUIRE X509              | The account must use TLS and must have a       |
|                           | valid X509 certificate. This option implies    |
|                           | REQUIRE SSL. This option cannot be combined    |
|                           | with other TLS options.                        |
+---------------------------+------------------------------------------------+
| REQUIRE ISSUER 'issuer'   | The account must use TLS and must have a       |
|                           | valid X509 certificate. Also, the Certificate  |
|                           | Authority must be the one specified via the    |
|                           | string issuer. This option implies REQUIRE     |
|                           | X509. This option can be combined with the     |
|                           | SUBJECT, and CIPHER options in any order.      |
+---------------------------+------------------------------------------------+
| REQUIRE SUBJECT 'subject' | The account must use TLS and must have a       |
|                           | valid X509 certificate. Also, the              |
|                           | certificate's Subject must be the one          |
|                           | specified via the string subject. This option  |
|                           | implies REQUIRE X509. This option can be       |
|                           | combined with the ISSUER, and CIPHER options   |
|                           | in any order.                                  |
+---------------------------+------------------------------------------------+
| REQUIRE CIPHER 'cipher'   | The account must use TLS, but no valid X509    |
|                           | certificate is required. Also, the encryption  |
|                           | used for the connection must use a specific    |
|                           | cipher method specified in the string cipher.  |
|                           | This option implies REQUIRE SSL. This option   |
|                           | can be combined with the ISSUER, and SUBJECT   |
|                           | options in any order.                          |
+---------------------------+------------------------------------------------+

The REQUIRE keyword must be used only once for all specified options, and the
AND keyword can be used to separate individual options, but it is not required.

For example, you can alter a user account to require these TLS options with
the following:

ALTER USER 'alice'@'%'
 REQUIRE SUBJECT '/CN=alice/O=My Dom, Inc./C=US/ST=Oregon/L=Portland' AND
 ISSUER '/C=FI/ST=Somewhere/L=City/ O=Some Company/CN=Peter
Parker/emailAddress=p.parker@marvel.com'
 AND CIPHER 'SHA-DES-CBC3-EDH-RSA';

If any of these options are set for a specific user account, then any client
who tries to connect with that user account will have to be configured to
connect with TLS.

See Securing Connections for Client and Server for information on how to
enable TLS on the client and server.

Resource Limit Options
----------------------

It is possible to set per-account limits for certain server resources. The
following table shows the values that can be set per account:

+------------------------------------+---------------------------------------+
| Limit Type                         | Description                           |
+------------------------------------+---------------------------------------+
| MAX_QUERIES_PER_HOUR               | Number of statements that the         |
|                                    | account can issue per hour            |
|                                    | (including updates)                   |
+------------------------------------+---------------------------------------+
| MAX_UPDATES_PER_HOUR               | Number of updates (not queries) that  |
|                                    | the account can issue per hour        |
+------------------------------------+---------------------------------------+
| MAX_CONNECTIONS_PER_HOUR           | Number of connections that the        |
|                                    | account can start per hour            |
+------------------------------------+---------------------------------------+
| MAX_USER_CONNECTIONS               | Number of simultaneous connections    |
|                                    | that can be accepted from the same    |
|                                    | account; if it is 0, max_connections  |
|                                    | will be used instead; if              |
|                                    | max_connections is 0, there is no     |
|                                    | limit for this account's              |
|                                    | simultaneous connections.             |
+------------------------------------+---------------------------------------+
| MAX_STATEMENT_TIME                 | Timeout, in seconds, for statements   |
|                                    | executed by the user. See also        |
|                                    | Aborting Statements that Exceed a     |
|                                    | Certain Time to Execute.              |
+------------------------------------+---------------------------------------+

If any of these limits are set to 0, then there is no limit for that resource
for that user.

Here is an example showing how to set an account's resource limits:

ALTER USER 'someone'@'localhost' WITH
  MAX_USER_CONNECTIONS 10
  MAX_QUERIES_PER_HOUR 200;

The resources are tracked per account, which means 'user'@'server'; not per
user name or per connection.

The count can be reset for all users using FLUSH USER_RESOURCES, FLUSH
PRIVILEGES or mysqladmin reload.

Per account resource limits are stored in the user table, in the mysql
database. Columns used for resources limits are named max_questions,
max_updates, max_connections (for MAX_CONNECTIONS_PER_HOUR), and
max_user_connections (for MAX_USER_CONNECTIONS).

Password Expiry
---------------

MariaDB starting with 10.4.3
----------------------------
Besides automatic password expiry, as determined by default_password_lifetime,
password expiry times can be set on an individual user basis, overriding the
global setting, for example:

ALTER USER 'monty'@'localhost' PASSWORD EXPIRE INTERVAL 120 DAY;
ALTER USER 'monty'@'localhost' PASSWORD EXPIRE NEVER;
ALTER USER 'monty'@'localhost' PASSWORD EXPIRE DEFAULT;

See User Password Expiry for more details.

Account Locking
---------------

MariaDB starting with 10.4.2
----------------------------
Account locking permits privileged administrators to lock/unlock user
accounts. No new client connections will be permitted if an account is locked
(existing connections are not affected). For example:

ALTER USER 'marijn'@'localhost' ACCOUNT LOCK;

See Account Locking for more details.

From MariaDB 10.4.7 and MariaDB 10.5.8, the lock_option and password_option
clauses can occur in either order.

URL: https://mariadb.c����Syntax
------

GRANT
  priv_type [(column_list)]
   [, priv_type [(column_list)]] ...
  ON [object_type] priv_level
  TO user_specification [ user_options ...]

user_specification:
 username [authentication_option]
 | PUBLIC
authentication_option:
 IDENTIFIED BY 'password'
 | IDENTIFIED BY PASSWORD 'password_hash'
 | IDENTIFIED {VIA|WITH} authentication_rule [OR authentication_rule  ...]

authentication_rule:
  authentication_plugin
 | authentication_plugin {USING|AS} 'authentication_string'
 | authentication_plugin {USING|AS} PASSWORD('password')

GRANT PROXY ON username
  TO user_specification [, user_specification ...]
  [WITH GRANT OPTION]

GRANT rolename TO grantee [, grantee ...]
  [WITH ADMIN OPTION]

grantee:
  rolename
  username [authentication_option]

user_options:
  [REQUIRE {NONE | tls_option [[AND] tls_option] ...}]
  [WITH with_option [with_option] ...]

object_type:
  TABLE
 | FUNCTION
 | PROCEDURE
 | PACKAGE

priv_level:
  *
 | *.*
 | db_name.*
 | db_name.tbl_name
 | tbl_name
 | db_name.routine_name

with_option:
  GRANT OPTION
 | resource_option

resource_option:
 MAX_QUERIES_PER_HOUR count
 | MAX_UPDATES_PER_HOUR count
 | MAX_CONNECTIONS_PER_HOUR count
 | MAX_USER_CONNECTIONS count
 | MAX_STATEMENT_TIME time

tls_option:
 SSL
 | X509
 | CIPHER 'cipher'
 | ISSUER 'issuer'
 | SUBJECT 'subject'

Description
-----------

The GRANT statement allows you to grant privileges or roles to accounts. To
use GRANT, you must have the GRANT OPTION privilege, and you must have the
privileges that you are granting.

Use the REVOKE statement to revoke privileges granted with the GRANT statement.

Use the SHOW GRANTS statement to determine what privileges an account has.

Account Names
-------------

For GRANT statements, account names are specified as the username argument in
the same way as they are for CREATE USER statements. See account names from
the CREATE USER page for details on how account names are specified.

Implicit Account Creation
-------------------------

The GRANT statement also allows you to implicitly create accounts in some
cases.

If the account does not yet exist, then GRANT can implicitly create it. To
implicitly create an account with GRANT, a user is required to have the same
privileges that would be required to explicitly create the account with the
CREATE USER statement.

If the NO_AUTO_CREATE_USER SQL_MODE is set, then accounts can only be created
if authentication information is specified, or with a CREATE USER statement.
If no authentication information is provided, GRANT will produce an error when
the specified account does not exist, for example:

show variables like '%sql_mode%' ;
+---------------+--------------------------------------------+
| Variable_name | Value                                      |
+---------------+--------------------------------------------+
| sql_mode      | NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION |
+---------------+--------------------------------------------+

GRANT USAGE ON *.* TO 'user123'@'%' IDENTIFIED BY '';
ERROR 1133 (28000): Can't find any matching row in the user table

GRANT USAGE ON *.* TO 'user123'@'%' 
 IDENTIFIED VIA PAM using 'mariadb' require ssl ;
Query OK, 0 rows affected (0.00 sec)

select host, user from mysql.user where user='user123' ;

+------+----------+
| host | user     |
+------+----------+
| %    | user123 |
+------+----------+

Privilege Levels
----------------

Privileges can be set globally, for an entire database, for a table or
routine, or for individual columns in a table. Certain privileges can only be
set at certain levels.

Global privileges do not take effect immediately and are only applied to
connections created after the GRANT statement was executed.

* Global privileges priv_type are granted using *.* for
priv_level. Global privileges include privileges to administer the database
and manage user accounts, as well as privileges for all tables, functions, and
procedures. Global privileges are stored in the mysql.user table prior to
MariaDB 10.4, and in  mysql.global_priv table afterwards.
* Database privileges priv_type are granted using db_name.*
for priv_level, or using just * to use default database. Database
privileges include privileges to create tables and functions, as well as
privileges for all tables, functions, and procedures in the database. Database
privileges are stored in the mysql.db table.
* Table privileges priv_type are granted using db_name.tbl_name
for priv_level, or using just tbl_name to specify a table in the default
database. The TABLE keyword is optional. Table privileges include the
ability to select and change data in the table. Certain table privileges can
be granted for individual columns.
* Column privileges priv_type are granted by specifying a table for
priv_level and providing a column list after the privilege type. They allow
you to control exactly which columns in a table users can select and change.
* Function privileges priv_type are granted using FUNCTION db_name.routine_name
for priv_level, or using just  FUNCTION routine_name to specify a function
in the default database.
* Procedure privileges priv_type are granted using PROCEDURE
db_name.routine_name
for priv_level, or using just PROCEDURE routine_name to specify a procedure
in the default database.

The USAGE Privilege
-------------------

The USAGE privilege grants no real privileges. The SHOW GRANTS statement will
show a global USAGE privilege for a newly-created user. You can use USAGE with
the GRANT statement to change options like GRANT OPTION and
MAX_USER_CONNECTIONS without changing any account privileges.

The ALL PRIVILEGES Privilege
----------------------------

The ALL PRIVILEGES privilege grants all available privileges. Granting all
privileges only affects the given privilege level. For example, granting all
privileges on a table does not grant any privileges on the database or
globally.

Using ALL PRIVILEGES does not grant the special GRANT OPTION privilege.

You can use ALL instead of ALL PRIVILEGES.

The GRANT OPTION Privilege
--------------------------

Use the WITH GRANT OPTION clause to give users the ability to grant privileges
to other users at the given privilege level. Users with the GRANT OPTION
privilege can only grant privileges they have. They cannot grant privileges at
a higher privilege level than they have the GRANT OPTION privilege.

The GRANT OPTION privilege cannot be set for individual columns. If you use
WITH GRANT OPTION when specifying column privileges, the GRANT OPTION
privilege will be granted for the entire table.

Using the WITH GRANT OPTION clause is equivalent to listing GRANT OPTION as a
privilege.

Global Privileges
-----------------

The following table lists the privileges that can be granted globally. You can
also grant all database, table, and function privileges globally. When granted
globally, these privileges apply to all databases, tables, or functions,
including those created later.

To set a global privilege, use *.* for priv_level.

BINLOG ADMIN
------------

Enables administration of the binary log, including the PURGE BINARY LOGS
statement and setting the system variables:

* binlog_annotate_row_events
* binlog_cache_size
* binlog_commit_wait_count
* binlog_commit_wait_usec
* binlog_direct_non_transactional_updates
* binlog_expire_logs_seconds
* binlog_file_cache_size
* binlog_format
* binlog_row_image
* binlog_row_metadata
* binlog_stmt_cache_size
* expire_logs_days
* log_bin_compress
* log_bin_compress_min_len
* log_bin_trust_function_creators
* max_binlog_cache_size
* max_binlog_size
* max_binlog_stmt_cache_size
* sql_log_bin and
* sync_binlog.

Added in MariaDB 10.5.2.

BINLOG MONITOR
--------------

New name for REPLICATION CLIENT from MariaDB 10.5.2, (REPLICATION CLIENT still
supported as an alias for compatibility purposes). Permits running SHOW
commands related to the binary log, in particular the SHOW BINLOG STATUS and
SHOW BINARY LOGS statements. Unlike REPLICATION CLIENT prior to MariaDB 10.5,
SHOW REPLICA STATUS isn't included in this privilege, and REPLICA MONITOR is
required.

BINLOG REPLAY
-------------

Enables replaying the binary log with the BINLOG sta��ܤtement (generated by
mariadb-binlog), executing SET timestamp when secure_timestamp is set to
replication, and setting the session values of system variables usually
included in BINLOG output, in particular:

* gtid_domain_id
* gtid_seq_no
* pseudo_thread_id
* server_id.

Added in MariaDB 10.5.2

CONNECTION ADMIN
----------------

Enables administering connection resource limit options. This includes
ignoring the limits specified by:

* max_connections
* max_user_connections and
* max_password_errors.

The statements specified in init_connect are not executed, killing connections
and queries owned by other users is permitted. The following
connection-related system variables can be changed:

* connect_timeout
* disconnect_on_expired_password
* extra_max_connections
* init_connect
* max_connections
* max_connect_errors
* max_password_errors
* proxy_protocol_networks
* secure_auth
* slow_launch_time
* thread_pool_exact_stats
* thread_pool_dedicated_listener
* thread_pool_idle_timeout
* thread_pool_max_threads
* thread_pool_min_threads
* thread_pool_oversubscribe
* thread_pool_prio_kickup_timer
* thread_pool_priority
* thread_pool_size, and
* thread_pool_stall_limit.

Added in MariaDB 10.5.2.

CREATE USER
-----------

Create a user using the CREATE USER statement, or implicitly create a user
with the GRANT statement.

FEDERATED ADMIN
---------------

Execute CREATE SERVER, ALTER SERVER, and DROP SERVER statements. Added in
MariaDB 10.5.2.

FILE
----

Read and write files on the server, using statements like LOAD DATA INFILE or
functions like LOAD_FILE(). Also needed to create CONNECT outward tables.
MariaDB server must have the permissions to access those files.

GRANT OPTION
------------

Grant global privileges. You can only grant privileges that you have.

PROCESS
-------

Show information about the active processes, for example via SHOW PROCESSLIST
or mariadb-admin processlist. If you have the PROCESS privilege, you can see
all threads. Otherwise, you can see only your own threads (that is, threads
associated with the MariaDB account that you are using).

READ_ONLY ADMIN
---------------

User can set the read_only system variable and allows the user to perform
write operations, even when the read_only option is active. Added in MariaDB
10.5.2.

From MariaDB 10.11.0, the READ_ONLY ADMIN privilege has been removed from
SUPER. The benefit of this is that one can remove the READ_ONLY ADMIN
privilege from all users and ensure that no one can make any changes on any
non-temporary tables. This is useful on replicas when one wants to ensure that
the replica is kept identical to the primary.

RELOAD
------

Execute FLUSH statements or equivalent mariadb-admin commands.

REPLICATION CLIENT
------------------

Execute SHOW MASTER STATUS and SHOW BINARY LOGS informative statements.
Renamed to BINLOG MONITOR in MariaDB 10.5.2 (but still supported as an alias
for compatibility reasons). SHOW SLAVE STATUS was part of REPLICATION CLIENT
prior to MariaDB 10.5.

REPLICATION MASTER ADMIN
------------------------

Permits administration of primary servers, including the SHOW REPLICA HOSTS
statement, and setting the gtid_binlog_state, gtid_domain_id,
master_verify_checksum and server_id system variables. Added in MariaDB 10.5.2.

REPLICA MONITOR
---------------

Permit SHOW REPLICA STATUS and SHOW RELAYLOG EVENTS. From MariaDB 10.5.9.

When a user would upgrade from an older major release to a MariaDB 10.5 minor
release prior to MariaDB 10.5.9, certain user accounts would lose
capabilities. For example, a user account that had the REPLICATION CLIENT
privilege in older major releases could run SHOW REPLICA STATUS, but after
upgrading to a MariaDB 10.5 minor release prior to MariaDB 10.5.9, they could
no longer run SHOW REPLICA STATUS, because that statement was changed to
require the REPLICATION REPLICA ADMIN privilege.

This issue is fixed in MariaDB 10.5.9 with this new privilege, which now
grants the user the ability to execute SHOW [ALL] (SLAVE | REPLICA) STATUS.

When a database is upgraded from an older major release to MariaDB Server
10.5.9 or later, any user accounts with the REPLICATION CLIENT or REPLICATION
SLAVE privileges will automatically be granted the new REPLICA MONITOR
privilege. The privilege fix occurs when the server is started up, not when
mariadb-upgrade is performed.

However, when a database is upgraded from an early 10.5 minor release to
10.5.9 and later, the user will have to fix any user account privileges
manually.

REPLICATION REPLICA
-------------------

Synonym for REPLICATION SLAVE. From MariaDB 10.5.1.

REPLICATION SLAVE
-----------------

Accounts used by replica servers on the primary need this privilege. This is
needed to get the updates made on the master. From MariaDB 10.5.1, REPLICATION
REPLICA is an alias for REPLICATION SLAVE.

REPLICATION SLAVE ADMIN
-----------------------

Permits administering replica servers, including START REPLICA/SLAVE, STOP
REPLICA/SLAVE, CHANGE MASTER, SHOW REPLICA/SLAVE STATUS, SHOW RELAYLOG EVENTS
statements, replaying the binary log with the BINLOG statement (generated by
mariadb-binlog), and setting the system variables:

* gtid_cleanup_batch_size
* gtid_ignore_duplicates
* gtid_pos_auto_engines
* gtid_slave_pos
* gtid_strict_mode
* init_slave
* read_binlog_speed_limit
* relay_log_purge
* relay_log_recovery
* replicate_do_db
* replicate_do_table
* replicate_events_marked_for_skip
* replicate_ignore_db
* replicate_ignore_table
* replicate_wild_do_table
* replicate_wild_ignore_table
* slave_compressed_protocol
* slave_ddl_exec_mode
* slave_domain_parallel_threads
* slave_exec_mode
* slave_max_allowed_packet
* slave_net_timeout
* slave_parallel_max_queued
* slave_parallel_mode
* slave_parallel_threads
* slave_parallel_workers
* slave_run_triggers_for_rbr
* slave_sql_verify_checksum
* slave_transaction_retry_interval
* slave_type_conversions
* sync_master_info
* sync_relay_log, and
* sync_relay_log_info.

Added in MariaDB 10.5.2.

SET USER
--------

Enables setting the DEFINER when creating triggers, views, stored functions
and stored procedures. Added in MariaDB 10.5.2.

SHOW DATABASES
--------------

List all databases using the SHOW DATABASES statement. Without the SHOW
DATABASES privilege, you can still issue the SHOW DATABASES statement, but it
will only list databases containing tables on which you have privileges.

SHUTDOWN
--------

Shut down the server using SHUTDOWN or the mariadb-admin shutdown command.

SUPER
-----

Execute superuser statements: CHANGE MASTER TO, KILL (users who do not have
this privilege can only KILL their own threads), PURGE LOGS, SET global system
variables, or the mariadb-admin debug command. Also, this permission allows
the user to write data even if the read_only startup option is set, enable or
disable logging, enable or disable replication on replica, specify a DEFINER
for statements that support that clause, connect once reaching the
MAX_CONNECTIONS. If a statement has been specified for the init-connect mysqld
option, that command will not be executed when a user with SUPER privileges
connects to the server.

The SUPER privilege has been split into multiple smaller privileges from
MariaDB 10.5.2 to allow for more fine-grained privileges (MDEV-21743). The
privileges are:

* SET USER
* FEDERATED ADMIN
* CONNECTION ADMIN
* REPLICATION SLAVE ADMIN
* BINLOG ADMIN
* BINLOG REPLAY
* REPLICA MONITOR
* BINLOG MONITOR
* REPLICATION MASTER ADMIN
* READ_ONLY ADMIN

However, the smaller privileges are still a part of the SUPER grant in MariaDB
10.5.2. From MariaDB 11.0.1 onwards, these grants are no longer a part of
SUPER and need to be granted separately (MDEV-29668).

From MariaDB 10.11.0, the READ_ONLY ADMIN privilege has been removed from
SUPER. The benefit of this is that one can remove the READ_ONLY ADMIN
privilege from all users and ensure that no one can make any changes on any
non-temporary tables. This is useful on replicas when one wants to ensure that
the replica is kept identical to the primary (MDEV-29596).

Database Privileges
-------------------

The following table lists the privileges that can be granted at the database
level. You ca�:�n also grant all table and function privileges at the database
level. Table and function privileges on a database apply to all tables or
functions in that database, including those created later.

To set a privilege for a database, specify the database using db_name.* for
priv_level, or just use * to specify the default database.

+----------------------------------+-----------------------------------------+
| Privilege                        | Description                             |
+----------------------------------+-----------------------------------------+
| CREATE                           | Create a database using the CREATE      |
|                                  | DATABASE statement, when the privilege  |
|                                  | is granted for a database. You can      |
|                                  | grant the CREATE privilege on           |
|                                  | databases that do not yet exist. This   |
|                                  | also grants the CREATE privilege on     |
|                                  | all tables in the database.             |
+----------------------------------+-----------------------------------------+
| CREATE ROUTINE                   | Create Stored Programs using the        |
|                                  | CREATE PROCEDURE and CREATE FUNCTION    |
|                                  | statements.                             |
+----------------------------------+-----------------------------------------+
| CREATE TEMPORARY TABLES          | Create temporary tables with the        |
|                                  | CREATE TEMPORARY TABLE statement. This  |
|                                  | privilege enable writing and dropping   |
|                                  | those temporary tables                  |
+----------------------------------+-----------------------------------------+
| DROP                             | Drop a database using the DROP          |
|                                  | DATABASE statement, when the privilege  |
|                                  | is granted for a database. This also    |
|                                  | grants the DROP privilege on all        |
|                                  | tables in the database.                 |
+----------------------------------+-----------------------------------------+
| EVENT                            | Create, drop and alter EVENTs.          |
+----------------------------------+-----------------------------------------+
| GRANT OPTION                     | Grant database privileges. You can      |
|                                  | only grant privileges that you have.    |
+----------------------------------+-----------------------------------------+
| LOCK TABLES                      | Acquire explicit locks using the LOCK   |
|                                  | TABLES statement; you also need to      |
|                                  | have the SELECT privilege on a table,   |
|                                  | in order to lock it.                    |
+----------------------------------+-----------------------------------------+

Table Privileges
----------------

+----------------------------------+-----------------------------------------+
| Privilege                        | Description                             |
+----------------------------------+-----------------------------------------+
| ALTER                            | Change the structure of an existing     |
|                                  | table using the ALTER TABLE statement.  |
+----------------------------------+-----------------------------------------+
| CREATE                           | Create a table using the CREATE TABLE   |
|                                  | statement.  You can grant the CREATE    |
|                                  | privilege on tables that do not yet     |
|                                  | exist.                                  |
+----------------------------------+-----------------------------------------+
| CREATE VIEW                      | Create a view using the CREATE_VIEW     |
|                                  | statement.                              |
+----------------------------------+-----------------------------------------+
| DELETE                           | Remove rows from a table using the      |
|                                  | DELETE statement.                       |
+----------------------------------+-----------------------------------------+
| DELETE HISTORY                   | Remove historical rows from a table     |
|                                  | using the DELETE HISTORY statement.     |
|                                  | Displays as DELETE VERSIONING ROWS      |
|                                  | when running SHOW GRANTS until MariaDB  |
|                                  | 10.3.15 and until MariaDB 10.4.5        |
|                                  | (MDEV-17655), or when running SHOW      |
|                                  | PRIVILEGES until MariaDB 10.5.2,        |
|                                  | MariaDB 10.4.13 and MariaDB 10.3.23     |
|                                  | (MDEV-20382). From MariaDB 10.3.4.      |
|                                  | From MariaDB 10.3.5, if a user has the  |
|                                  | SUPER privilege but not this            |
|                                  | privilege, running mariadb-upgrade      |
|                                  | will grant this privilege as well.      |
+----------------------------------+-----------------------------------------+
| DROP                             | Drop a table using the DROP TABLE       |
|                                  | statement or a view using the DROP      |
|                                  | VIEW statement. Also required to        |
|                                  | execute the TRUNCATE TABLE statement.   |
+----------------------------------+-----------------------------------------+
| GRANT OPTION                     | Grant table privileges. You can only    |
|                                  | grant privileges that you have.         |
+----------------------------------+-----------------------------------------+
| INDEX                            | Create an index on a table using the    |
|                                  | CREATE INDEX statement. Without the     |
|                                  | INDEX privilege, you can still create   |
|                                  | indexes when creating a table using     |
|                                  | the CREATE TABLE statement if the you   |
|                                  | have the CREATE privilege, and you can  |
|                                  | create indexes using the ALTER TABLE    |
|                                  | statement if you have the ALTER         |
|                                  | privilege.                              |
+----------------------------------+-----------------------------------------+
| INSERT                           | Add rows to a table using the INSERT    |
|                                  | statement.  The INSERT privilege can    |
|                                  | also be set on individual columns; see  |
|                                  | Column Privileges below for details.    |
+----------------------------------+-----------------------------------------+
| REFERENCES                       | Unused.                                 |
+----------------------------------+-----------------------------------------+
| SELECT                           | Read data from a table using the        |
|                                  | SELECT statement. The SELECT privilege  |
|                                  | can also be set on individual columns;  |
|                                  | see Column Privileges below for         |
|                                  | details.                                |
+----------------------------------+-----------------------------------------+
| SHOW VIEW                        | Show the CREATE VIEW statement t�TR\o       |
|                                  | create a view using the SHOW CREATE     |
|                                  | VIEW statement.                         |
+----------------------------------+-----------------------------------------+
| TRIGGER                          | Execute triggers associated to tables   |
|                                  | you update, execute the CREATE          |
|                                  | TRIGGER, DROP TRIGGER, and SHOW CREATE  |
|                                  | TRIGGER statements.                     |
+----------------------------------+-----------------------------------------+
| UPDATE                           | Update existing rows in a table using   |
|                                  | the UPDATE statement. UPDATE            |
|                                  | statements usually include a WHERE      |
|                                  | clause to update only certain rows.     |
|                                  | You must have SELECT privileges on the  |
|                                  | table or the appropriate columns for    |
|                                  | the WHERE clause. The UPDATE privilege  |
|                                  | can also be set on individual columns;  |
|                                  | see Column Privileges below for         |
|                                  | details.                                |
+----------------------------------+-----------------------------------------+

Column Privileges
-----------------

Some table privileges can be set for individual columns of a table. To use
column privileges, specify the table explicitly and provide a list of column
names after the privilege type. For example, the following statement would
allow the user to read the names and positions of employees, but not other
information from the same table, such as salaries.

GRANT SELECT (name, position) on Employee to 'jeffrey'@'localhost';

+----------------------------------+-----------------------------------------+
| Privilege                        | Description                             |
+----------------------------------+-----------------------------------------+
| INSERT (column_list)             | Add rows specifying values in columns   |
|                                  | using the INSERT statement. If you      |
|                                  | only have column-level INSERT           |
|                                  | privileges, you must specify the        |
|                                  | columns you are setting in the INSERT   |
|                                  | statement. All other columns will be    |
|                                  | set to their default values, or NULL.   |
+----------------------------------+-----------------------------------------+
| REFERENCES (column_list)         | Unused.                                 |
+----------------------------------+-----------------------------------------+
| SELECT (column_list)             | Read values in columns using the        |
|                                  | SELECT statement. You cannot access or  |
|                                  | query any columns for which you do not  |
|                                  | have SELECT privileges, including in    |
|                                  | WHERE, ON, GROUP BY, and ORDER BY       |
|                                  | clauses.                                |
+----------------------------------+-----------------------------------------+
| UPDATE (column_list)             | Update values in columns of existing    |
|                                  | rows using the UPDATE statement.        |
|                                  | UPDATE statements usually include a     |
|                                  | WHERE clause to update only certain     |
|                                  | rows. You must have SELECT privileges   |
|                                  | on the table or the appropriate         |
|                                  | columns for the WHERE clause.           |
+----------------------------------+-----------------------------------------+

Function Privileges
-------------------

+----------------------------------+-----------------------------------------+
| Privilege                        | Description                             |
+----------------------------------+-----------------------------------------+
| ALTER ROUTINE                    | Change the characteristics of a stored  |
|                                  | function using the ALTER FUNCTION       |
|                                  | statement.                              |
+----------------------------------+-----------------------------------------+
| EXECUTE                          | Use a stored function. You need SELECT  |
|                                  | privileges for any tables or columns    |
|                                  | accessed by the function.               |
+----------------------------------+-----------------------------------------+
| GRANT OPTION                     | Grant function privileges. You can      |
|                                  | only grant privileges that you have.    |
+----------------------------------+-----------------------------------------+

Procedure Privileges
--------------------

+----------------------------------+-----------------------------------------+
| Privilege                        | Description                             |
+----------------------------------+-----------------------------------------+
| ALTER ROUTINE                    | Change the characteristics of a stored  |
|                                  | procedure using the ALTER PROCEDURE     |
|                                  | statement.                              |
+----------------------------------+-----------------------------------------+
| EXECUTE                          | Execute a stored procedure using the    |
|                                  | CALL statement. The privilege to call   |
|                                  | a procedure may allow you to perform    |
|                                  | actions you wouldn't otherwise be able  |
|                                  | to do, such as insert rows into a       |
|                                  | table.                                  |
+----------------------------------+-----------------------------------------+
| GRANT OPTION                     | Grant procedure privileges. You can     |
|                                  | only grant privileges that you have.    |
+----------------------------------+-----------------------------------------+

GRANT EXECUTE ON PROCEDURE mysql.create_db TO maintainer;

Proxy Privileges
----------------

+----------------------------------+-----------------------------------------+
| Privilege                        | Description                             |
+----------------------------------+-----------------------------------------+
| PROXY                            | Permits one user to be a proxy for      |
|                                  | another.                                |
+----------------------------------+-----------------------------------------+

The PROXY privilege allows one user to proxy as another user, which means
their privileges change to that of the proxy user, and the CURRENT_USER()
function returns the user name of the proxy user.

The PROXY privilege only works with authentication plugins that support it.
The default mysql_native_password authentication plugin does not support proxy
users.

The pam authentication plugin is the only plugin included with MariaDB that
currently supports proxy users. The PROXY privilege is commonly used with the
pam authentication plugin to enable user and group mapping with PAM.

For example, to grant the PROXY privilege to an anonymous account that
authenticates with the pam authentication plugin, you could execute the
following:

CREATE USER 'dba'@'%' IDENTIFIED BY 'strongpassword';
GRANT ALL PRIVILEGES ON *.* TO 'dba'@'%' ;

CREATE USER ''@'%' IDENTIFIED VIA pam USING 'mariadbzu<�';
GRANT PROXY ON 'dba'@'%' TO ''@'%';

A user account can only grant the PROXY privilege for a specific user account
if the granter also has the PROXY privilege for that specific user account,
and if that privilege is defined WITH GRANT OPTION. For example, the following
example fails because the granter does not have the PROXY privilege for that
specific user account at all:

SELECT USER(), CURRENT_USER();
+-----------------+-----------------+
| USER()          | CURRENT_USER()  |
+-----------------+-----------------+
| alice@localhost | alice@localhost |
+-----------------+-----------------+

SHOW GRANTS;
+------------------------------------------------------------------------------
----------------------------------------+
| Grants for alice@localhost                                                  
                    |
+------------------------------------------------------------------------------
----------------------------------------+
| GRANT ALL PRIVILEGES ON *.* TO 'alice'@'localhost' IDENTIFIED BY PASSWORD
'*2470C0C06DEE42FD1618BB99005ADCA2EC9D1E19' |
+------------------------------------------------------------------------------
----------------------------------------+

GRANT PROXY ON 'dba'@'localhost' TO 'bob'@'localhost';
ERROR 1698 (28000): Access denied for user 'alice'@'localhost'

And the following example fails because the granter does have the PROXY
privilege for that specific user account, but it is not defined WITH GRANT
OPTION:

SELECT USER(), CURRENT_USER();
+-----------------+-----------------+
| USER()          | CURRENT_USER()  |
+-----------------+-----------------+
| alice@localhost | alice@localhost |
+-----------------+-----------------+

SHOW GRANTS;
+------------------------------------------------------------------------------
----------------------------------------+
| Grants for alice@localhost                                                  
                    |
+------------------------------------------------------------------------------
----------------------------------------+
| GRANT ALL PRIVILEGES ON *.* TO 'alice'@'localhost' IDENTIFIED BY PASSWORD
'*2470C0C06DEE42FD1618BB99005ADCA2EC9D1E19' |
| GRANT PROXY ON 'dba'@'localhost' TO 'alice'@'localhost'                     
                    |
+------------------------------------------------------------------------------
----------------------------------------+

GRANT PROXY ON 'dba'@'localhost' TO 'bob'@'localhost';
ERROR 1698 (28000): Access denied for user 'alice'@'localhost'

But the following example succeeds because the granter does have the PROXY
privilege for that specific user account, and it is defined WITH GRANT OPTION:

SELECT USER(), CURRENT_USER();
+-----------------+-----------------+
| USER()          | CURRENT_USER()  |
+-----------------+-----------------+
| alice@localhost | alice@localhost |
+-----------------+-----------------+

SHOW GRANTS;
+------------------------------------------------------------------------------
----------------------------------------------------------+
| Grants for alice@localhost                                                  
                             |
+------------------------------------------------------------------------------
----------------------------------------------------------+
| GRANT ALL PRIVILEGES ON *.* TO 'alice'@'localhost' IDENTIFIED BY PASSWORD
'*2470C0C06DEE42FD1618BB99005ADCA2EC9D1E19' WITH GRANT OPTION |
| GRANT PROXY ON 'dba'@'localhost' TO 'alice'@'localhost' WITH GRANT OPTION   
                             |
+------------------------------------------------------------------------------
----------------------------------------------------------+

GRANT PROXY ON 'dba'@'localhost' TO 'bob'@'localhost';

A user account can grant the PROXY privilege for any other user account if the
granter has the PROXY privilege for the ''@'%' anonymous user account, like
this:

GRANT PROXY ON ''@'%' TO 'dba'@'localhost' WITH GRANT OPTION;

For example, the following example succeeds because the user can grant the
PROXY privilege for any other user account:

SELECT USER(), CURRENT_USER();
+-----------------+-----------------+
| USER()          | CURRENT_USER()  |
+-----------------+-----------------+
| alice@localhost | alice@localhost |
+-----------------+-----------------+

SHOW GRANTS;
+------------------------------------------------------------------------------
----------------------------------------------------------+
| Grants for alice@localhost                                                  
                             |
+------------------------------------------------------------------------------
----------------------------------------------------------+
| GRANT ALL PRIVILEGES ON *.* TO 'alice'@'localhost' IDENTIFIED BY PASSWORD
'*2470C0C06DEE42FD1618BB99005ADCA2EC9D1E19' WITH GRANT OPTION |
| GRANT PROXY ON ''@'%' TO 'alice'@'localhost' WITH GRANT OPTION              
                             |
+------------------------------------------------------------------------------
----------------------------------------------------------+

GRANT PROXY ON 'app1_dba'@'localhost' TO 'bob'@'localhost';
Query OK, 0 rows affected (0.004 sec)

GRANT PROXY ON 'app2_dba'@'localhost' TO 'carol'@'localhost';
Query OK, 0 rows affected (0.004 sec)

The default root user accounts created by mariadb-install-db have this
privilege. For example:

GRANT ALL PRIVILEGES ON *.* TO 'root'@'localhost' WITH GRANT OPTION;
GRANT PROXY ON ''@'%' TO 'root'@'localhost' WITH GRANT OPTION;

This allows the default root user accounts to grant the PROXY privilege for
any other user account, and it also allows the default root user accounts to
grant others the privilege to do the same.

Authentication Options
----------------------

The authentication options for the GRANT statement are the same as those for
the CREATE USER statement.

IDENTIFIED BY 'password'
------------------------

The optional IDENTIFIED BY clause can be used to provide an account with a
password. The password should be specified in plain text. It will be hashed by
the PASSWORD function prior to being stored.

For example, if our password is mariadb, then we can create the user with:

GRANT USAGE ON *.* TO foo2@test IDENTIFIED BY 'mariadb';

If you do not specify a password with the IDENTIFIED BY clause, the user will
be able to connect without a password. A blank password is not a wildcard to
match any password. The user must connect without providing a password if no
password is set.

If the user account already exists and if you provide the IDENTIFIED BY
clause, then the user's password will be changed. You must have the privileges
needed for the SET PASSWORD statement to change a user's password with GRANT.

The only authentication plugins that this clause supports are
mysql_native_password and mysql_old_password.

IDENTIFIED BY PASSWORD 'password_hash'
--------------------------------------

The optional IDENTIFIED BY PASSWORD clause can be used to provide an account
with a password that has already been hashed. The password should be specified
as a hash that was provided by the PASSWORD function. It will be stored as-is.

For example, if our password is mariadb, then we can find the hash with:

SELECT PASSWORD('mariadb');
+-------------------------------------------+
| PASSWORD('mariadb')                       |
+-------------------------------------------+
| *54958E764CE10E50764C2EECBB71D01F08549980 |
+-------------------------------------------+
1 row in set (0.00 sec)

And then we can create a user with the hash:

GRANT USAGE ON *.* TO foo2@test IDENTIFIED BY 
 PASSWORD '*54958E764CE10E50764C2EECBB71D01F08549980';

If you do not specify a password with the IDENTIFIED BY clause, the user will
be able to connect without a password. A blank password is not a wildcard to
match any password. The user must connect without providing a password if no
password is set.

If the user account already exists and if you provide the IDENTIFIED BY
clause, then the user's password will be changed. You must have the privileges
needed for the SET PASSWORD statement to change a user's password with GRANT.

The only auth);ċentication plugins that this clause supports are
mysql_native_password and mysql_old_password.

IDENTIFIED {VIA|WITH} authentication_plugin
-------------------------------------------

The optional IDENTIFIED VIA authentication_plugin allows you to specify that
the account should be authenticated by a specific authentication plugin. The
plugin name must be an active authentication plugin as per SHOW PLUGINS. If it
doesn't show up in that output, then you will need to install it with INSTALL
PLUGIN or INSTALL SONAME.

For example, this could be used with the PAM authentication plugin:

GRANT USAGE ON *.* TO foo2@test IDENTIFIED VIA pam;

Some authentication plugins allow additional arguments to be specified after a
USING or AS keyword. For example, the PAM authentication plugin accepts a
service name:

GRANT USAGE ON *.* TO foo2@test IDENTIFIED VIA pam USING 'mariadb';

The exact meaning of the additional argument would depend on the specific
authentication plugin.

MariaDB starting with 10.4.0
----------------------------
The USING or AS keyword can also be used to provide a plain-text password to a
plugin if it's provided as an argument to the PASSWORD() function. This is
only valid for authentication plugins that have implemented a hook for the
PASSWORD() function. For example, the ed25519 authentication plugin supports
this:

CREATE USER safe@'%' IDENTIFIED VIA ed25519 
 USING PASSWORD('secret');

MariaDB starting with 10.4.3
----------------------------
One can specify many authentication plugins, they all work as alternatives
ways of authenticating a user:

CREATE USER safe@'%' IDENTIFIED VIA ed25519 
 USING PASSWORD('secret') OR unix_socket;

By default, when you create a user without specifying an authentication
plugin, MariaDB uses the mysql_native_password plugin.

Resource Limit Options
----------------------

It is possible to set per-account limits for certain server resources. The
following table shows the values that can be set per account:

+--------------------------------------+--------------------------------------+
| Limit Type                           | Decription                           |
+--------------------------------------+--------------------------------------+
| MAX_QUERIES_PER_HOUR                 | Number of statements that the        |
|                                      | account can issue per hour           |
|                                      | (including updates)                  |
+--------------------------------------+--------------------------------------+
| MAX_UPDATES_PER_HOUR                 | Number of updates (not queries)      |
|                                      | that the account can issue per hour  |
+--------------------------------------+--------------------------------------+
| MAX_CONNECTIONS_PER_HOUR             | Number of connections that the       |
|                                      | account can start per hour           |
+--------------------------------------+--------------------------------------+
| MAX_USER_CONNECTIONS                 | Number of simultaneous connections   |
|                                      | that can be accepted from the same   |
|                                      | account; if it is 0,                 |
|                                      | max_connections will be used         |
|                                      | instead; if max_connections is 0,    |
|                                      | there is no limit for this           |
|                                      | account's simultaneous connections.  |
+--------------------------------------+--------------------------------------+
| MAX_STATEMENT_TIME                   | Timeout, in seconds, for statements  |
|                                      | executed by the user. See also       |
|                                      | Aborting Statements that Exceed a    |
|                                      | Certain Time to Execute.             |
+--------------------------------------+--------------------------------------+

If any of these limits are set to 0, then there is no limit for that resource
for that user.

To set resource limits for an account, if you do not want to change that
account's privileges, you can issue a GRANT statement with the USAGE
privilege, which has no meaning. The statement can name some or all limit
types, in any order.

Here is an example showing how to set resource limits:

GRANT USAGE ON *.* TO 'someone'@'localhost' WITH
  MAX_USER_CONNECTIONS 0
  MAX_QUERIES_PER_HOUR 200;

The resources are tracked per account, which means 'user'@'server'; not per
user name or per connection.

The count can be reset for all users using FLUSH USER_RESOURCES, FLUSH
PRIVILEGES or mariadb-admin reload.

Users with the CONNECTION ADMIN privilege (in MariaDB 10.5.2 and later) or the
SUPER privilege are not restricted by max_user_connections, max_connections,
or max_password_errors.

Per account resource limits are stored in the user table, in the mysql
database. Columns used for resources limits are named max_questions,
max_updates, max_connections (for MAX_CONNECTIONS_PER_HOUR), and
max_user_connections (for MAX_USER_CONNECTIONS).

TLS Options
-----------

By default, MariaDB transmits data between the server and clients without
encrypting it. This is generally acceptable when the server and client run on
the same host or in networks where security is guaranteed through other means.
However, in cases where the server and client exist on separate networks or
they are in a high-risk network, the lack of encryption does introduce
security concerns as a malicious actor could potentially eavesdrop on the
traffic as it is sent over the network between them.

To mitigate this concern, MariaDB allows you to encrypt data in transit
between the server and clients using the Transport Layer Security (TLS)
protocol. TLS was formerly known as Secure Socket Layer (SSL), but strictly
speaking the SSL protocol is a predecessor to TLS and, that version of the
protocol is now considered insecure. The documentation still uses the term SSL
often and for compatibility reasons TLS-related server system and status
variables still use the prefix ssl_, but internally, MariaDB only supports its
secure successors.

See Secure Connections Overview for more information about how to determine
whether your MariaDB server has TLS support.

You can set certain TLS-related restrictions for specific user accounts. For
instance, you might use this with user accounts that require access to
sensitive data while sending it across networks that you do not control. These
restrictions can be enabled for a user account with the CREATE USER, ALTER
USER, or GRANT statements. The following options are available:

+---------------------------+------------------------------------------------+
| Option                    | Description                                    |
+---------------------------+------------------------------------------------+
| REQUIRE NONE              | TLS is not required for this account, but can  |
|                           | still be used.                                 |
+---------------------------+------------------------------------------------+
| REQUIRE SSL               | The account must use TLS, but no valid X509    |
|                           | certificate is required. This option cannot    |
|                           | be combined with other TLS options.            |
+---------------------------+------------------------------------------------+
| REQUIRE X509              | The account must use TLS and must have a       |
|                           | valid X509 certificate. This option implies    |
|                           | REQUIRE SSL. This option cannot be combined    |
|                           | with other TLS options.                        |
+---------------------------+------------------------------------------------+
| REQUIRE ISSUER 'issuer'   | The account must use TLS and must have a       |
|                           | valid X509 certificate. Also, the Certificate  |
|                           | Authority must be the one spe�[�}MariaDB starting with 10.4
--------------------------
MariaDB 10.4 introduced a number of changes to the authentication process,
intended to make things easier and more intuitive.

Overview
--------

There are four new main features in 10.4 relating to authentication:

* It is possible to use more than one authentication plugin for each user
account. For example, this can be useful to slowly migrate users to the more
secure ed25519 authentication plugin over time, while allowing the old
mysql_native_password authentication plugin as an alternative for the
transitional period.
* The root@localhost user account created by mariadb-install-db is created
with the ability to use two authentication plugins.
First, it is configured to try to use the unix_socket authentication plugin.
This allows the root@localhost user to login without a password via the local
Unix socket file defined by the socket system variable, as long as the login
is attempted from a process owned by the operating system root user account.
Second, if authentication fails with the unix_socket authentication plugin,
then it is configured to try to use the mysql_native_password authentication
plugin. However, an invalid password is initially set, so in order to
authenticate this way, a password must be set with SET PASSWORD.
However, just using the unix_socket authentication plugin may be fine for many
users, and it is very secure. You may want to try going without password
authentication to see how well it works for you. Remember, the best way to
keep your password safe is not to have one!

* All user accounts, passwords, and global privileges are now stored in the
mysql.global_priv table. The mysql.user table still exists and has exactly the
same set of columns as before, but it’s now a view that references the
mysql.global_priv table. Tools that analyze the mysql.user table should
continue to work as before. From MariaDB 10.4.13, the dedicated mariadb.sys
user is created as the definer of this view. Previously root was the definer,
which resulted in privilege problems when this username was changed.
* MariaDB 10.4 adds supports for User Password Expiry, which is not active by
default.

Description
-----------

As a result of the above changes, the open-for-everyone all-powerful root
account is finally gone. And installation scripts will no longer demand that
you "PLEASE REMEMBER TO SET A PASSWORD FOR THE MariaDB root USER !", because
the root account is securely created automatically.

Two all-powerful accounts are created by default — root and the OS user that
owns the data directory, typically mysql. They are created as:

CREATE USER root@localhost IDENTIFIED VIA unix_socket OR mysql_native_password
USING 'invalid'
CREATE USER mysql@localhost IDENTIFIED VIA unix_socket OR
mysql_native_password USING 'invalid'

Using unix_socket means that if you are the system root user, you can login as
root@locahost without a password. This technique was pioneered by Otto
Kekäläinen in Debian MariaDB packages and has been successfully used in Debian
since as early as MariaDB 10.0.

It is based on a simple fact that asking the system root for a password adds
no extra security — root has full access to all the data files and all process
memory anyway. But not asking for a password means, there is no root password
to forget (no need for the numerous tutorials on "how to reset MariaDB root
password"). And if you want to script some tedious database work, there is no
need to store the root password in plain text for the script to use (no need
for debian-sys-maint user).

Still, some users may wish to log in as MariaDB root without using sudo. Hence
the old authentication method — conventional MariaDB password — is still
available. By default it is disabled ("invalid" is not a valid password hash),
but one can set the password with a usual SET PASSWORD statement. And still
retain the password-less access via sudo.

If you install MariaDB locally (say from a tarball), you would not want to use
sudo to be able to login. This is why MariaDB creates a second all-powerful
user with the same name as a system user that owns the data directory. In
local (not system-wide) installations, this will be the user who installed
MariaDB — they automatically get convenient password-less root-like access,
because they can access all the data files anyway.

Even if MariaDB is installed system-wide, you may not want to run your
database maintenance scripts as system root — now you can run them as system
mysql user. And you will know that they will never destroy your entire system,
even if you make a typo in a shell script.

However, seasoned MariaDB DBAs who are used to the old ways do need to make
some changes. See the examples below for common tasks.

Cookbook
--------

After installing MariaDB system-wide the first thing you’ve got used to doing
is logging in into the unprotected root account and protecting it, that is,
setting the root password:

$ sudo dnf install MariaDB-server
$ mysql -uroot
...
MariaDB> set password = password("XH4VmT3_jt");

This is not only unnecessary now, it will simply not work — there is no
unprotected root account. To login as root use

$ sudo dnf install MariaDB-server
$ sudo mysql

Note that it implies you are connecting via the unix socket, not tcp. If you
happen to have protocol=tcp in a system-wide /etc/my.cnf file, use sudo mysql
--protocol=socket.

After installing MariaDB locally you’ve also used to connect to the
unprotected root account using mysql -uroot. This will not work either, simply
use mysql without specifying a username.

If you've forgotten your root password, no problem — you can still connect
using sudo and change the password. And if you've also removed unix_socket
authentication, to restore access do as follows:

* restart MariaDB with --skip-grant-tables
* login into the unprotected server
* run FLUSH PRIVILEGES (note, before 10.4 this would’ve been the last step,
not anymore). This disables --skip-grant-tables and allows you to change the
stored authentication method
* run SET PASSWORD FOR root@localhost to change the root password.

To view inside privilege tables, the old mysql.user table still exists. You
can select from it as before, although you cannot update it anymore. It
doesn’t show alternative authentication plugins and this was one of the
reasons for switching to the mysql.global_priv table — complex authentication
rules did not fit into rigid structure of a relational table. You can select
from the new table, for example:

select concat(user, '@', host, ' => ', json_detailed(priv)) from
mysql.global_priv;

Reverting to the Previous Authentication Method for root@localhost
------------------------------------------------------------------

If you don't want the root@localhost user account created by
mariadb-install-db to use unix_socket authentication by default, then there
are a few ways to revert to the previous mysql_native_password authentication
method for this user account.

Configuring mariadb-install-db to Revert to the Previous Authentication Method
------------------------------------------------------------------------------

One way to revert to the previous mysql_native_password authentication method
for the root@localhost user account is to execute mariadb-install-db with a
special option. If mariadb-install-db is executed while
--auth-root-authentication-method=normal is specified, then it will create the
default user accounts using the default behavior of MariaDB 10.3 and before.

This means that the root@localhost user account will use mysql_native_password
authentication by default. There are some other differences as well. See
mariadb-install-db: User Accounts Created by Default for more information.

For example, the option can be set on the command-line while running
mariadb-install-db:

mariadb-install-db --user=mysql --datadir=/var/lib/mysql
--auth-root-authentication-method=normal

The option can also be set in an option file in an option group supported by
mariadb-install-db. For example:

[mysql_install_db]
auth_root_authentication_method=normal

If the option is set in an opt�y��
�VX
h(CASE OPERATORSyntax
------

CASE value WHEN [compare_value] THEN result [WHEN [compare_value] THEN
result ...] [ELSE result] END

CASE WHEN [condition] THEN result [WHEN [condition] THEN result ...]
[ELSE result] END

Description
-----------

The first version returns the result where value=compare_value. The second
version returns the result for the first condition that is true. If there was
no matching result value, the result after ELSE is returned, or NULL if there
is no ELSE part.

There is also a CASE statement, which differs from the CASE operator described
here.

Examples
--------

SELECT CASE 1 WHEN 1 THEN 'one' WHEN 2 THEN 'two' ELSE 'more' END;
+------------------------------------------------------------+
| CASE 1 WHEN 1 THEN 'one' WHEN 2 THEN 'two' ELSE 'more' END |
+------------------------------------------------------------+
| one                                                        |
+------------------------------------------------------------+

SELECT CASE WHEN 1>0 THEN 'true' ELSE 'false' END;
+--------------------------------------------+
| CASE WHEN 1>0 THEN 'true' ELSE 'false' END |
+--------------------------------------------+
| true                                       |
+--------------------------------------------+

SELECT CASE BINARY 'B' WHEN 'a' THEN 1 WHEN 'b' THEN 2 END;
+-----------------------------------------------------+
| CASE BINARY 'B' WHEN 'a' THEN 1 WHEN 'b' THEN 2 END |
+-----------------------------------------------------+
|                                                NULL |
+-----------------------------------------------------+

URL: https://mariadb.com/kb/en/case-operator/https://mariadb.com/kb/en/case-operator/Y�&IF FunctionSyntax
------

IF(expr1,expr2,expr3)

Description
-----------

If expr1 is TRUE (expr1 <> 0 and expr1 <> NULL) then IF() returns expr2;
otherwise it returns expr3. IF() returns a numeric or string value, depending
on the context in which it is used.

Note: There is also an IF statement which differs from the IF() function
described here.

Examples
--------

SELECT IF(1>2,2,3);
+-------------+
| IF(1>2,2,3) |
+-------------+
|           3 |
+-------------+

SELECT IF(1<2,'yes','no');
+--------------------+
| IF(1<2,'yes','no') |
+--------------------+
| yes                |
+--------------------+

SELECT IF(STRCMP('test','test1'),'no','yes');
+---------------------------------------+
| IF(STRCMP('test','test1'),'no','yes') |
+---------------------------------------+
| no                                    |
+---------------------------------------+

URL: https://mariadb.com/kb/en/if-function/https://mariadb.com/kb/en/if-function/ZC!IFNULLSyntax
------

IFNULL(expr1,expr2)
NVL(expr1,expr2)

Description
-----------

If expr1 is not NULL, IFNULL() returns expr1; otherwise it returns expr2.
IFNULL() returns a numeric or string value, depending on the context in which
it is used.

From MariaDB 10.3, NVL() is an alias for IFNULL().

Examples
--------

SELECT IFNULL(1,0); 
+-------------+
| IFNULL(1,0) |
+-------------+
|           1 |
+-------------+

SELECT IFNULL(NULL,10);
+-----------------+
| IFNULL(NULL,10) |
+-----------------+
|              10 |
+-----------------+

SELECT IFNULL(1/0,10);
+----------------+
| IFNULL(1/0,10) |
+----------------+
|        10.0000 |
+----------------+

SELECT IFNULL(1/0,'yes');
+-------------------+
| IFNULL(1/0,'yes') |
+-------------------+
| yes               |
+-------------------+

URL: https://mariadb.com/kb/en/ifnull/https://mariadb.com/kb/en/ifnull/_�!COMMITThe COMMIT statement ends a transaction, saving any changes to the data so
that they become visible to subsequent transactions. Also, unlocks metadata
changed by current transaction. If autocommit is set to 1, an implicit commit
is performed after each statement. Otherwise, all transactions which don't end
with an explicit COMMIT are implicitly rollbacked and the changes are lost.
The ROLLBACK statement can be used to do this explicitly.

The required syntax for the COMMIT statement is as follows:

COMMIT [WORK] [AND [NO] CHAIN] [[NO] RELEASE]

COMMIT is the more important transaction terminator, as well as the more
interesting one. The basic form of the COMMIT statement is simply the keyword
COMMIT (the keyword WORK is simply noise and can be omitted without changing
the effect).

The optional AND CHAIN clause is a convenience for initiating a new
transaction as soon as the old transaction terminates. If AND CHAIN is
specified, then there is effectively nothing between the old and new
transactions, although they remain separate. The characteristics of the new
transaction will be the same as the characteristics of the old one — that is,
the new transaction will have the same access mode, isolation level and
diagnostics area size (we'll discuss all of these shortly) as the transaction
just terminated.

RELEASE tells the server to disconnect the client immediately after the
current transaction.

There are NO RELEASE and AND NO CHAIN options. By default, commits do not
RELEASE or CHAIN, but it's possible to change this default behavior with the
completion_type server system variable. In this case, the AND NO CHAIN and NO
RELEASE options override the server default.

URL: https://mariadb.com/kb/en/commit/https://mariadb.com/kb/en/commit/x�ST_XSyntax
------

ST_X(p)
X(p)

Description
-----------

Returns the X-coordinate value for the point p as a double-precision number.

ST_X() and X() are synonyms.

Examples
--------

SET @pt = 'Point(56.7 53.34)';

SELECT X(GeomFromText(@pt));
+----------------------+
| X(GeomFromText(@pt)) |
+----------------------+
|                 56.7 |
+----------------------+

URL: https://mariadb.com/kb/en/st_x/https://mariadb.com/kb/en/st_x/y�ST_YSyntax
------

ST_Y(p)
Y(p)

Description
-----------

Returns the Y-coordinate value for the point p as a double-precision number.

ST_Y() and Y() are synonyms.

Examples
--------

SET @pt = 'Point(56.7 53.34)';

SELECT Y(GeomFromText(@pt));
+----------------------+
| Y(GeomFromText(@pt)) |
+----------------------+
|                53.34 |
+----------------------+

URL: https://mariadb.com/kb/en/st_y/https://mariadb.com/kb/en/st_y/zG-XA synonym for ST_X.

URL: https://mariadb.com/kb/en/point-properties-x/https://mariadb.com/kb/en/point-properties-x/{G-YA synonym for ST_Y.

URL: https://mariadb.com/kb/en/point-properties-y/https://mariadb.com/kb/en/point-properties-y/~
�(DECODE_ORACLEMariaDB starting with 10.3.2
----------------------------
DECODE_ORACLE is a synonym for the Oracle mode version of the DECODE function,
and is available in all modes.

URL: https://mariadb.com/kb/en/decode_oracle/https://mariadb.com/kb/en/decode_oracle/��MD5Syntax
------

MD5(str)

Description
-----------

Calculates an MD5 128-bit checksum for the string.

The return value is a 32-hex digit string, and as of MariaDB 5.5, is a
nonbinary string in the connection character set and collation, determined by
the values of the character_set_connection and collation_connection system
variables. Before 5.5, the return value was a binary string.

NULL is returned if the argument was NULL.

Examples
--------

SELECT MD5('testing');
+----------------------------------+
| MD5('testing')                   |
+----------------------------------+
| ae2b1fca515949e5d54fb22b8ed95575 |
+----------------------------------+

URL: https://mariadb.com/kb/en/md5/https://mariadb.com/kb/en/md5/����y������
�~
x����YM��^�,START TRANSACTIONSyntax
------

START TRANSACTION [transaction_property [, transaction_property] ...] | BEGIN
[WORK]
COMMIT [WORK] [AND [NO] CHAIN] [[NO] RELEASE]
ROLLBACK [WORK] [AND [NO] CHAIN] [[NO] RELEASE]
SET autocommit = {0 | 1}

transaction_property:
  WITH CONSISTENT SNAPSHOT
 | READ WRITE
 | READ ONLY

Description
-----------

The START TRANSACTION or BEGIN statement begins a new transaction. COMMIT
commits the current transaction, making its changes permanent. ROLLBACK rolls
back the current transaction, canceling its changes. The SET autocommit
statement disables or enables the default autocommit mode for the current
session.

START TRANSACTION and SET autocommit = 1 implicitly commit the current
transaction, if any.

The optional WORK keyword is supported for COMMIT and ROLLBACK, as are the
CHAIN and RELEASE clauses. CHAIN and RELEASE can be used for additional
control over transaction completion. The value of the completion_type system
variable determines the default completion behavior.

The AND CHAIN clause causes a new transaction to begin as soon as the current
one ends, and the new transaction has the same isolation level as the
just-terminated transaction. The RELEASE clause causes the server to
disconnect the current client session after terminating the current
transaction. Including the NO keyword suppresses CHAIN or RELEASE completion,
which can be useful if the completion_type system variable is set to cause
chaining or release completion by default.

Access Mode
-----------

The access mode specifies whether the transaction is allowed to write data or
not. By default, transactions are in READ WRITE mode (see the tx_read_only
system variable). READ ONLY mode allows the storage engine to apply
optimizations that cannot be used for transactions which write data. Note that
unlike the global read_only mode, READ_ONLY ADMIN (and SUPER before MariaDB
10.11.0) privilege doesn't allow writes and DDL statements on temporary tables
are not allowed either.

It is not permitted to specify both READ WRITE and READ ONLY in the same
statement.

READ WRITE and READ ONLY can also be specified in the SET TRANSACTION
statement, in which case the specified mode is valid for all sessions, or for
all subsequent transaction used by the current session.

autocommit
----------

By default, MariaDB runs with autocommit mode enabled. This means that as soon
as you execute a statement that updates (modifies) a table, MariaDB stores the
update on disk to make it permanent. To disable autocommit mode, use the
following statement:

SET autocommit=0;

After disabling autocommit mode by setting the autocommit variable to zero,
changes to transaction-safe tables (such as those for InnoDB or NDBCLUSTER)
are not made permanent immediately. You must use COMMIT to store your changes
to disk or ROLLBACK to ignore the changes.

To disable autocommit mode for a single series of statements, use the START
TRANSACTION statement.

DDL Statements
--------------

DDL statements (CREATE, ALTER, DROP) and administrative statements (FLUSH,
RESET, OPTIMIZE, ANALYZE, CHECK, REPAIR, CACHE INDEX), transaction management
statements (BEGIN, START TRANSACTION) and LOAD DATA INFILE, cause an implicit
COMMIT and start a new transaction. An exception to this rule are the DDL that
operate on temporary tables: you can CREATE, ALTER and DROP them without
causing any COMMIT, but those actions cannot be rolled back. This means that
if you call ROLLBACK, the temporary tables you created in the transaction will
remain, while the rest of the transaction will be rolled back.

Transactions cannot be used in Stored Functions or Triggers. In Stored
Procedures and Events BEGIN is not allowed, so you should use START
TRANSACTION instead.

A transaction acquires a metadata lock on every table it accesses to prevent
other connections from altering their structure. The lock is released at the
end of the transaction. This happens even with non-transactional storage
engines (like MEMORY or CONNECT), so it makes sense to use transactions with
non-transactional tables.

in_transaction
--------------

The in_transaction system variable is a session-only, read-only variable that
returns 1 inside a transaction, and 0 if not in a transaction.

WITH CONSISTENT SNAPSHOT
------------------------

The WITH CONSISTENT SNAPSHOT option starts a consistent read for storage
engines such as InnoDB that can do so, the same as if a START TRANSACTION
followed by a SELECT from any InnoDB table was issued.

See Enhancements for START TRANSACTION WITH CONSISTENT SNAPSHOT.

Examples
--------

START TRANSACTION;
SELECT @A:=SUM(salary) FROM table1 WHERE type=1;
UPDATE table2 SET summary=@A WHERE type=1;
COMMIT;

URL: https://mariadb.com/kb/en/start-transaction/https://mariadb.com/kb/en/start-transaction/c	�$SAVEPOINTSyntax
------

SAVEPOINT identifier
ROLLBACK [WORK] TO [SAVEPOINT] identifier
RELEASE SAVEPOINT identifier

Description
-----------

InnoDB supports the SQL statements SAVEPOINT, ROLLBACK TO SAVEPOINT, RELEASE
SAVEPOINT and the optional WORK keyword for ROLLBACK.

Each savepoint must have a legal MariaDB identifier. A savepoint is a named
sub-transaction.

Normally ROLLBACK undoes the changes performed by the whole transaction. When
used with the TO clause, it undoes the changes performed after the specified
savepoint, and erases all subsequent savepoints. However, all locks that have
been acquired after the save point will survive. RELEASE SAVEPOINT does not
rollback or commit any changes, but removes the specified savepoint.

When the execution of a trigger or a stored function begins, it is not
possible to use statements which reference a savepoint which was defined from
out of that stored program.

When a COMMIT (including implicit commits) or a ROLLBACK statement (with no TO
clause) is performed, they act on the whole transaction, and all savepoints
are removed.

Errors
------

If COMMIT or ROLLBACK is issued and no transaction was started, no error is
reported.

If SAVEPOINT is issued and no transaction was started, no error is reported
but no savepoint is created. When ROLLBACK TO SAVEPOINT or RELEASE SAVEPOINT
is called for a savepoint that does not exist, an error like this is issued:

ERROR 1305 (42000): SAVEPOINT svp_name does not exist

URL: https://mariadb.com/kb/en/savepoint/https://mariadb.com/kb/en/savepoint/�Z9
ENDPOINTA synonym for ST_ENDPOINT.

URL: https://mariadb.com/kb/en/linestring-properties-endpoint/https://mariadb.com/kb/en/linestring-properties-endpoint/��"
GLENGTHSyntax
------

GLength(ls)

Description
-----------

Returns as a double-precision number the length of the LineString value ls in
its associated spatial reference.

Examples
--------

SET @ls = 'LineString(1 1,2 2,3 3)';

SELECT GLength(GeomFromText(@ls));
+----------------------------+
| GLength(GeomFromText(@ls)) |
+----------------------------+
|           2.82842712474619 |
+----------------------------+

URL: https://mariadb.com/kb/en/glength/https://mariadb.com/kb/en/glength/�	\:
NumPointsA synonym for ST_NumPoints.

URL: https://mariadb.com/kb/en/linestring-properties-numpoints/https://mariadb.com/kb/en/linestring-properties-numpoints/�V7
PointNA synonym for ST_PointN.

URL: https://mariadb.com/kb/en/linestring-properties-pointn/https://mariadb.com/kb/en/linestring-properties-pointn/`�������%�Ѐ����`V
#ROLLBACKThe ROLLBACK statement rolls back (ends) a transaction, destroying any changes
to SQL-data so that they never become visible to subsequent transactions. The
required syntax for the ROLLBACK statement is as follows.

ROLLBACK [ WORK ] [ AND [ NO ] CHAIN ] 
[ TO [ SAVEPOINT ] {<savepoint name> | <simple target specification>} ]

The ROLLBACK statement will either end a transaction, destroying all data
changes that happened during any of the transaction, or it will just destroy
any data changes that happened since you established a savepoint. The basic
form of the ROLLBACK statement is just the keyword ROLLBACK (the keyword WORK
is simply noise and can be omitted without changing the effect).

The optional AND CHAIN clause is a convenience for initiating a new
transaction as soon as the old transaction terminates. If AND CHAIN is
specified, then there is effectively nothing between the old and new
transactions, although they remain separate. The characteristics of the new
transaction will be the same as the characteristics of the old one — that is,
the new transaction will have the same access mode, isolation level and
diagnostics area size (we'll discuss all of these shortly) as the transaction
just terminated. The AND NO CHAIN option just tells your DBMS to end the
transaction — that is, these four SQL statements are equivalent:

ROLLBACK; 
ROLLBACK WORK; 
ROLLBACK AND NO CHAIN; 
ROLLBACK WORK AND NO CHAIN;

All of them end a transaction without saving any transaction characteristics.
The only other options, the equivalent statements:

ROLLBACK AND CHAIN;
ROLLBACK WORK AND CHAIN;

both tell your DBMS to end a transaction, but to save that transaction's
characteristics for the next transaction.

ROLLBACK is much simpler than COMMIT: it may involve no more than a few
deletions (of Cursors, locks, prepared SQL statements and log-file entries).
It's usually assumed that ROLLBACK can't fail, although such a thing is
conceivable (for example, an encompassing transaction might reject an attempt
to ROLLBACK because it's lining up for a COMMIT).

ROLLBACK cancels all effects of a transaction. It does not cancel effects on
objects outside the DBMS's control (for example the values in host program
variables or the settings made by some SQL/CLI function calls). But in
general, it is a convenient statement for those situations when you say "oops,
this isn't working" or when you simply don't care whether your temporary work
becomes permanent or not.

Here is a moot question. If all you've been doing is SELECTs, so that there
have been no data changes, should you end the transaction with ROLLBACK or
COMMIT? It shouldn't really matter because both ROLLBACK and COMMIT do the
same transaction-terminating job. However, the popular conception is that
ROLLBACK implies failure, so after a successful series of SELECT statements
the convention is to end the transaction with COMMIT rather than ROLLBACK.

MariaDB (and most other DBMSs) supports rollback of SQL-data change
statements, but not of SQL-Schema statements. This means that if you use any
of CREATE, ALTER, DROP, GRANT, REVOKE, you are implicitly committing at
execution time.

INSERT INTO Table_2 VALUES(5); 
DROP TABLE Table_3 CASCADE; 
ROLLBACK;

The result will be that both the INSERT and the DROP will go through as
separate transactions so the ROLLBACK will have no effect.

URL: https://mariadb.com/kb/en/rollback/https://mariadb.com/kb/en/rollback/d�+Metadata LockingMariaDB supports metadata locking. This means that when a transaction
(including XA transactions) uses a table, it locks its metadata until the end
of transaction. Non-transactional tables are also locked, as well as views and
objects which are related to locked tables/views (stored functions, triggers,
etc). When a connection tries to use a DDL statement (like an ALTER TABLE)
which modifies a table that is locked, that connection is queued, and has to
wait until it's unlocked. Using savepoints and performing a partial rollback
does not release metadata locks.

LOCK TABLES ... WRITE are also queued. Some wrong statements which produce an
error may not need to wait for the lock to be freed.

The metadata lock's timeout is determined by the value of the
lock_wait_timeout server system variable (in seconds). However, note that its
default value is 31536000 (1 year, MariaDB <= 10.2.3), or 86400 (1 day,
MariaDB >= 10.2.4). If this timeout is exceeded, the following error is
returned:

ERROR 1205 (HY000): Lock wait timeout exceeded; try restarting transaction

If the metadata_lock_info plugin is installed, the Information Schema
metadata_lock_info table stores information about existing metadata locks.

MariaDB starting with 10.5.2
----------------------------
From MariaDB 10.5, the Performance Schema metadata_locks table contains
metadata lock information.

Example
-------

Let's use the following MEMORY (non-transactional) table:

CREATE TABLE t (a INT) ENGINE = MEMORY;

Connection 1 starts a transaction, and INSERTs a row into t:

START TRANSACTION;

INSERT INTO t SET a=1;

t's metadata is now locked by connection 1. Connection 2 tries to alter t, but
has to wait:

ALTER TABLE t ADD COLUMN b INT;

Connection 2's prompt is blocked now.

Now connection 1 ends the transaction:

COMMIT;

...and connection 2 finally gets the output of its command:

Query OK, 1 row affected (35.23 sec)
Records: 1  Duplicates: 0  Warnings: 0

URL: https://mariadb.com/kb/en/metadata-locking/https://mariadb.com/kb/en/metadata-locking/�
^;
STARTPOINTA synonym for ST_STARTPOINT.

URL: https://mariadb.com/kb/en/linestring-properties-startpoint/https://mariadb.com/kb/en/linestring-properties-startpoint/�&
ST_ENDPOINTSyntax
------

ST_EndPoint(ls)
EndPoint(ls)

Description
-----------

Returns the Point that is the endpoint of the LineString value ls.

ST_EndPoint() and EndPoint() are synonyms.

Examples
--------

SET @ls = 'LineString(1 1,2 2,3 3)';

SELECT AsText(EndPoint(GeomFromText(@ls)));
+-------------------------------------+
| AsText(EndPoint(GeomFromText(@ls))) |
+-------------------------------------+
| POINT(3 3)                          |
+-------------------------------------+

URL: https://mariadb.com/kb/en/st_endpoint/https://mariadb.com/kb/en/st_endpoint/��'
ST_NUMPOINTSSyntax
------

ST_NumPoints(ls)
NumPoints(ls)

Description
-----------

Returns the number of Point objects in the LineString value ls.

ST_NumPoints() and NumPoints() are synonyms.

Examples
--------

SET @ls = 'LineString(1 1,2 2,3 3)';

SELECT NumPoints(GeomFromText(@ls));
+------------------------------+
| NumPoints(GeomFromText(@ls)) |
+------------------------------+
|                            3 |
+------------------------------+

URL: https://mariadb.com/kb/en/st_numpoints/https://mariadb.com/kb/en/st_numpoints/�	$
ST_POINTNSyntax
------

ST_PointN(ls,N)
PointN(ls,N)

Description
-----------

Returns the N-th Point in the LineString value ls. Points are numbered
beginning with 1.

ST_PointN() and PointN() are synonyms.

Examples
--------

SET @ls = 'LineString(1 1,2 2,3 3)';

SELECT AsText(PointN(GeomFromText(@ls),2));
+-------------------------------------+
| AsText(PointN(GeomFromText(@ls),2)) |
+-------------------------------------+
| POINT(2 2)                          |
+-------------------------------------+

URL: https://mariadb.com/kb/en/st_pointn/https://mariadb.com/kb/en/st_pointn/�Z�(cN���
�
����a?*SET TRANSACTIONSyntax
------

SET [GLOBAL | SESSION] TRANSACTION
  transaction_property [, transaction_property] ...

transaction_property:
  ISOLATION LEVEL level
 | READ WRITE
 | READ ONLY

level:
  REPEATABLE READ
 | READ COMMITTED
 | READ UNCOMMITTED
 | SERIALIZABLE

Description
-----------

This statement sets the transaction isolation level or the transaction access
mode globally, for the current session, or for the next transaction:

* With the GLOBAL keyword, the statement sets the default
 transaction level globally for all subsequent sessions. Existing sessions are
 unaffected.
* With the SESSION keyword, the statement sets the default
 transaction level for all subsequent transactions performed within the
 current session.
* Without any SESSION or GLOBAL keyword,
 the statement sets the isolation level for the next (not started) transaction
 performed within the current session.

A change to the global default isolation level requires the SUPER privilege.
Any session is free to change its session isolation level (even in the middle
of a transaction), or the isolation level for its next transaction.

Isolation Level
---------------

To set the global default isolation level at server startup, use the
--transaction-isolation=level option on the command line or in an option file.
Values of level for this option use dashes rather than spaces, so the
allowable values are READ_UNCOMMITTED, READ-COMMITTED, REPEATABLE-READ, or
SERIALIZABLE. For example, to set the default isolation level to REPEATABLE
READ, use these lines in the [mysqld] section of an option file:

[mysqld]
transaction-isolation = REPEATABLE-READ
To determine the global and session transaction isolation levels at runtime,
check the value of the tx_isolation system variable (note that the variable
has been renamed transaction_isolation from MariaDB 11.1.1, to match the
option, and the old name deprecated).

SELECT @@GLOBAL.tx_isolation, @@tx_isolation;

From MariaDB 11.1.1:

SELECT @@GLOBAL.transaction_isolation, @@transaction_isolation;

InnoDB supports each of the translation isolation levels described here using
different locking strategies. The default level is REPEATABLE READ. For
additional information about InnoDB record-level locks and how it uses them to
execute various types of statements, see InnoDB Lock Modes, and
http://dev.mysql.com/doc/refman/en/innodb-locks-set.html.

Isolation Levels
----------------

The following sections describe how MariaDB supports the different transaction
levels.

READ UNCOMMITTED
----------------

SELECT statements are performed in a non-locking fashion, but a possible
earlier version of a row might be used. Thus, using this isolation level, such
reads are not consistent. This is also called a "dirty read." Otherwise, this
isolation level works like READ COMMITTED.

READ COMMITTED
--------------

A somewhat Oracle-like isolation level with respect to consistent
(non-locking) reads: Each consistent read, even within the same transaction,
sets and reads its own fresh snapshot. See
http://dev.mysql.com/doc/refman/en/innodb-consistent-read.html.

For locking reads (SELECT with FOR UPDATE or LOCK IN SHARE MODE), InnoDB locks
only index records, not the gaps before them, and thus allows the free
insertion of new records next to locked records. For UPDATE and DELETE
statements, locking depends on whether the statement uses a unique index with
a unique search condition (such as WHERE id = 100), or a range-type search
condition (such as WHERE id > 100). For a unique index with a unique search
condition, InnoDB locks only the index record found, not the gap before it.
For range-type searches, InnoDB locks the index range scanned, using gap locks
or next-key (gap plus index-record) locks to block insertions by other
sessions into the gaps covered by the range. This is necessary because
"phantom rows" must be blocked for MySQL replication and recovery to work.

Note: If the READ COMMITTED isolation level is used or the
innodb_locks_unsafe_for_binlog system variable is enabled, there is no InnoDB
gap locking except for foreign-key constraint checking and duplicate-key
checking. Also, record locks for non-matching rows are released after MariaDB
has evaluated the WHERE condition.If you use READ COMMITTED or enable
innodb_locks_unsafe_for_binlog, you must use row-based binary logging.

REPEATABLE READ
---------------

This is the default isolation level for InnoDB. For consistent reads, there is
an important difference from the READ COMMITTED isolation level: All
consistent reads within the same transaction read the snapshot established by
the first read. This convention means that if you issue several plain
(non-locking) SELECT statements within the same transaction, these SELECT
statements are consistent also with respect to each other. See
http://dev.mysql.com/doc/refman/en/innodb-consistent-read.html.

For locking reads (SELECT with FOR UPDATE or LOCK IN SHARE MODE), UPDATE, and
DELETE statements, locking depends on whether the statement uses a unique
index with a unique search condition, or a range-type search condition. For a
unique index with a unique search condition, InnoDB locks only the index
record found, not the gap before it. For other search conditions, InnoDB locks
the index range scanned, using gap locks or next-key (gap plus index-record)
locks to block insertions by other sessions into the gaps covered by the range.

This is the minimum isolation level for non-distributed XA transactions.

SERIALIZABLE
------------

This level is like REPEATABLE READ, but InnoDB implicitly converts all plain
SELECT statements to SELECT ... LOCK IN SHARE MODE if autocommit is disabled.
If autocommit is enabled, the SELECT is its own transaction. It therefore is
known to be read only and can be serialized if performed as a consistent
(non-locking) read and need not block for other transactions. (This means that
to force a plain SELECT to block if other transactions have modified the
selected rows, you should disable autocommit.)

Distributed XA transactions should always use this isolation level.

Access Mode
-----------

The access mode specifies whether the transaction is allowed to write data or
not. By default, transactions are in READ WRITE mode (see the tx_read_only
system variable). READ ONLY mode allows the storage engine to apply
optimizations that cannot be used for transactions which write data. Note that
unlike the global read_only mode, READ_ONLY ADMIN (and SUPER before MariaDB
10.11.0) privilege doesn't allow writes and DDL statements on temporary tables
are not allowed either.

It is not permitted to specify both READ WRITE and READ ONLY in the same
statement.

READ WRITE and READ ONLY can also be specified in the START TRANSACTION
statement, in which case the specified mode is only valid for one transaction.

Examples
--------

SET GLOBAL TRANSACTION ISOLATION LEVEL SERIALIZABLE;

Attempting to set the isolation level within an existing transaction without
specifying GLOBAL or SESSION.

START TRANSACTION;

SET TRANSACTION ISOLATION LEVEL SERIALIZABLE;
ERROR 1568 (25001): Transaction characteristics can't be changed while a
transaction is in progress

URL: https://mariadb.com/kb/en/set-transaction/https://mariadb.com/kb/en/set-transaction/�
((
ST_STARTPOINTSyntax
------

ST_StartPoint(ls)
StartPoint(ls)

Description
-----------

Returns the Point that is the start point of the LineString value ls.

ST_StartPoint() and StartPoint() are synonyms.

Examples
--------

SET @ls = 'LineString(1 1,2 2,3 3)';

SELECT AsText(StartPoint(GeomFromText(@ls)));
+---------------------------------------+
| AsText(StartPoint(GeomFromText(@ls))) |
+---------------------------------------+
| POINT(1 1)                            |
+---------------------------------------+

URL: https://mariadb.com/kb/en/st_startpoint/https://mariadb.com/kb/en/st_startpoint/�k��E��b�&LOCK TABLESSyntax
------

LOCK TABLE[S]
  tbl_name [[AS] alias] lock_type
  [, tbl_name [[AS] alias] lock_type] ...
  [WAIT n|NOWAIT]

lock_type:
  READ [LOCAL]
 | [LOW_PRIORITY] WRITE
 | WRITE CONCURRENT

UNLOCK TABLES

Description
-----------

The lock_type can be one of:

+---------------------------+------------------------------------------------+
| Option                    | Description                                    |
+---------------------------+------------------------------------------------+
| READ                      | Read lock, no writes allowed                   |
+---------------------------+------------------------------------------------+
| READ LOCAL                | Read lock, but allow concurrent inserts        |
+---------------------------+------------------------------------------------+
| WRITE                     | Exclusive write lock. No other connections     |
|                           | can read or write to this table                |
+---------------------------+------------------------------------------------+
| LOW_PRIORITY WRITE        | Exclusive write lock, but allow new read       |
|                           | locks on the table until we get the write      |
|                           | lock.                                          |
+---------------------------+------------------------------------------------+
| WRITE CONCURRENT          | Exclusive write lock, but allow READ LOCAL     |
|                           | locks to the table.                            |
+---------------------------+------------------------------------------------+

MariaDB enables client sessions to acquire table locks explicitly for the
purpose of cooperating with other sessions for access to tables, or to prevent
other sessions from modifying tables during periods when a session requires
exclusive access to them. A session can acquire or release locks only for
itself. One session cannot acquire locks for another session or release locks
held by another session.

Locks may be used to emulate transactions or to get more speed when updating
tables.

LOCK TABLES explicitly acquires table locks for the current client session.
Table locks can be acquired for base tables or views. To use LOCK TABLES, you
must have the LOCK TABLES privilege, and the SELECT privilege for each object
to be locked. See GRANT

For view locking, LOCK TABLES adds all base tables used in the view to the set
of tables to be locked and locks them automatically. If you lock a table
explicitly with LOCK TABLES, any tables used in triggers are also locked
implicitly, as described in Triggers and Implicit Locks.

UNLOCK TABLES explicitly releases any table locks held by the current session.

MariaDB starting with 10.3.0
----------------------------

WAIT/NOWAIT
-----------

Set the lock wait timeout. See WAIT and NOWAIT.

Limitations
-----------

* LOCK TABLES doesn't work when using Galera cluster.   You may experience
crashes or locks when used with Galera.
* LOCK TABLES works on XtraDB/InnoDB tables only if the innodb_table_locks
system variable is set to 1 (the default) and autocommit is set to 0 (1 is
default). Please note that no error message will be returned on LOCK TABLES
with innodb_table_locks = 0.
* LOCK TABLES implicitly commits the active transaction, if any. Also,
starting a transaction always releases all table locks acquired with LOCK
TABLES. This means that there is no way to have table locks and an active
transaction at the same time. The only exceptions are the transactions in
autocommit mode. To preserve the data integrity between transactional and
non-transactional tables, the GET_LOCK() function can be used.
* When using LOCK TABLES on a TEMPORARY table, it will always be locked with a
WRITE lock.
* While a connection holds an explicit read lock on a table, it cannot modify
it. If you try, the following error will be produced:

ERROR 1099 (HY000): Table 'tab_name' was locked with a READ lock and can't be
updated

* While a connection holds an explicit lock on a table, it cannot access a
non-locked table. If you try, the following error will be produced:

ERROR 1100 (HY000): Table 'tab_name' was not locked with LOCK TABLES

* While a connection holds an explicit lock on a table, it cannot issue the
following: INSERT DELAYED, CREATE TABLE, CREATE TABLE ... LIKE, and DDL
statements involving stored programs and views (except for triggers). If you
try, the following error will be produced:

ERROR 1192 (HY000): Can't execute the given command because you have active
locked tables or an active transaction

* LOCK TABLES can not be used in stored routines - if you try, the following
error will be produced on creation:

ERROR 1314 (0A000): LOCK is not allowed in stored procedures

URL: https://mariadb.com/kb/en/lock-tables/https://mariadb.com/kb/en/lock-tables/e�/Transaction TimeoutsMariaDB has always had the wait_timeout and interactive_timeout settings,
which close connections after a certain period of inactivity.

However, these are by default set to a long wait period. In situations where
transactions may be started, but not committed or rolled back, more granular
control and a shorter timeout may be desirable so as to avoid locks being held
for too long.

MariaDB 10.3 introduced three new variables to handle this situation.

* idle_transaction_timeout (all transactions)
* idle_write_transaction_timeout (write transactions - called
idle_readwrite_transaction_timeout until MariaDB 10.3.2)
* idle_readonly_transaction_timeout (read transactions)

These accept a time in seconds to time out, by closing the connection,
transactions that are idle for longer than this period. By default all are set
to zero, or no timeout.

idle_transaction_timeout affects all transactions,
idle_write_transaction_timeout affects write transactions only and
idle_readonly_transaction_timeout affects read transactions only. The latter
two variables work independently. However, if either is set along with
idle_transaction_timeout, the settings for idle_write_transaction_timeout or
idle_readonly_transaction_timeout will take precedence.

Examples
--------

SET SESSION idle_transaction_timeout=2;
BEGIN;
SELECT * FROM t;
Empty set (0.000 sec)
## wait 3 seconds
SELECT * FROM t;
ERROR 2006 (HY000): MySQL server has gone away

SET SESSION idle_write_transaction_timeout=2;
BEGIN;
SELECT * FROM t;
Empty set (0.000 sec)
## wait 3 seconds
SELECT * FROM t;
Empty set (0.000 sec)
INSERT INTO t VALUES(1);
## wait 3 seconds
SELECT * FROM t;
ERROR 2006 (HY000): MySQL server has gone away

SET SESSION idle_transaction_timeout=2, SESSION
idle_readonly_transaction_timeout=10;
BEGIN;
SELECT * FROM t;
Empty set (0.000 sec)
 ## wait 3 seconds
SELECT * FROM t;
Empty set (0.000 sec)
## wait 11 seconds
SELECT * FROM t;
ERROR 2006 (HY000): MySQL server has gone away

URL: https://mariadb.com/kb/en/transaction-timeouts/https://mariadb.com/kb/en/transaction-timeouts/�	\$INET_ATONSyntax
------

INET_ATON(expr)

Description
-----------

Given the dotted-quad representation of an IPv4 network address as a string,
returns an integer that represents the numeric value of the address. Addresses
may be 4- or 8-byte addresses.

Returns NULL if the argument is not understood.

Examples
--------

SELECT INET_ATON('192.168.1.1');
+--------------------------+
| INET_ATON('192.168.1.1') |
+--------------------------+
|               3232235777 |
+--------------------------+

This is calculated as follows: 192 x 2563 + 168 x 256 2 + 1 x 256 + 1

URL: https://mariadb.com/kb/en/inet_aton/https://mariadb.com/kb/en/inet_aton/M�9�1|��gg*WAIT and NOWAITExtended syntax so that it is possible to set innodb_lock_wait_timeout and
lock_wait_timeout for the following statements:

Syntax
------

ALTER TABLE tbl_name [WAIT n|NOWAIT] ...
CREATE ... INDEX ON tbl_name (index_col_name, ...) [WAIT n|NOWAIT] ...
DROP INDEX ... [WAIT n|NOWAIT]
DROP TABLE tbl_name [WAIT n|NOWAIT] ...
LOCK TABLE ... [WAIT n|NOWAIT]
OPTIMIZE TABLE tbl_name [WAIT n|NOWAIT]
RENAME TABLE tbl_name [WAIT n|NOWAIT] ...
SELECT ... FOR UPDATE [WAIT n|NOWAIT]
SELECT ... LOCK IN SHARE MODE [WAIT n|NOWAIT]
TRUNCATE TABLE tbl_name [WAIT n|NOWAIT]

Description
-----------

The lock wait timeout can be explicitly set in the statement by using either
WAIT n (to set the wait in seconds) or NOWAIT, in which case the statement
will immediately fail if the lock cannot be obtained. WAIT 0 is equivalent to
NOWAIT.

URL: https://mariadb.com/kb/en/wait-and-nowait/https://mariadb.com/kb/en/wait-and-nowait/k	�$
DROP USERSyntax
------

DROP USER [IF EXISTS] user_name [, user_name] ...

Description
-----------

The DROP USER statement removes one or more MariaDB accounts. It removes
privilege rows for the account from all grant tables. To use this statement,
you must have the global CREATE USER privilege or the DELETE privilege for the
mysql database. Each account is named using the same format as for the CREATE
USER statement; for example, 'jeffrey'@'localhost'. If you specify only the
user name part of the account name, a host name part of '%' is used. For
additional information about specifying account names, see CREATE USER.

Note that, if you specify an account that is currently connected, it will not
be deleted until the connection is closed. The connection will not be
automatically closed.

If any of the specified user accounts do not exist, ERROR 1396 (HY000)
results. If an error occurs, DROP USER will still drop the accounts that do
not result in an error. Only one error is produced for all users which have
not been dropped:

ERROR 1396 (HY000): Operation DROP USER failed for 'u1'@'%','u2'@'%'

Failed CREATE or DROP operations, for both users and roles, produce the same
error code.

IF EXISTS
---------

If the IF EXISTS clause is used, MariaDB will return a note instead of an
error if the user does not exist.

Examples
--------

DROP USER bob;

DROP USER foo2@localhost,foo2@'127.%';

IF EXISTS:

DROP USER bob;
ERROR 1396 (HY000): Operation DROP USER failed for 'bob'@'%'

DROP USER IF EXISTS bob;
Query OK, 0 rows affected, 1 warning (0.00 sec)

SHOW WARNINGS;
+-------+------+---------------------------------------------+
| Level | Code | Message                                     |
+-------+------+---------------------------------------------+
| Note  | 1974 | Can't drop user 'bob'@'%'; it doesn't exist |
+-------+------+---------------------------------------------+

URL: https://mariadb.com/kb/en/drop-user/https://mariadb.com/kb/en/drop-user/md&
RENAME USERSyntax
------

RENAME USER old_user TO new_user
  [, old_user TO new_user] ...

Description
-----------

The RENAME USER statement renames existing MariaDB accounts. To use it, you
must have the global CREATE USER privilege or the UPDATE privilege for the
mysql database. Each account is named using the same format as for the CREATE
USER statement; for example, 'jeffrey'@'localhost'. If you specify only the
user name part of the account name, a host name part of '%' is used.

If any of the old user accounts do not exist or any of the new user accounts
already exist, ERROR 1396 (HY000) results. If an error occurs, RENAME USER
will still rename the accounts that do not result in an error.

Examples
--------

CREATE USER 'donald', 'mickey';
RENAME USER 'donald' TO 'duck'@'localhost', 'mickey' TO 'mouse'@'localhost';

URL: https://mariadb.com/kb/en/rename-user/https://mariadb.com/kb/en/rename-user/n�!
REVOKEPrivileges
----------

Syntax
------

REVOKE 
  priv_type [(column_list)]
   [, priv_type [(column_list)]] ...
  ON [object_type] priv_level
  FROM user [, user] ...

REVOKE ALL PRIVILEGES, GRANT OPTION
  FROM user [, user] ...

Description
-----------

The REVOKE statement enables system administrators to revoke privileges (or
roles - see section below) from MariaDB accounts. Each account is named using
the same format as for the GRANT statement; for example,
'jeffrey'@'localhost'. If you specify only the user name part of the account
name, a host name part of '%' is used. For details on the levels at which
privileges exist, the allowable priv_type and priv_level values, and the
syntax for specifying users and passwords, see GRANT.

To use the first REVOKE syntax, you must have the GRANT OPTION privilege, and
you must have the privileges that you are revoking.

To revoke all privileges, use the second syntax, which drops all global,
database, table, column, and routine privileges for the named user or users:

REVOKE ALL PRIVILEGES, GRANT OPTION FROM user [, user] ...

To use this REVOKE syntax, you must have the global CREATE USER privilege or
the UPDATE privilege for the mysql database. See GRANT.

Examples
--------

REVOKE SUPER ON *.* FROM 'alexander'@'localhost';

Roles
-----

Syntax
------

REVOKE role  [, role ...]
  FROM grantee [, grantee2 ... ]

REVOKE ADMIN OPTION FOR role FROM grantee [, grantee2]

Description
-----------

REVOKE is also used to remove a role from a user or another role that it's
previously been assigned to. If a role has previously been set as a default
role, REVOKE does not remove the record of the default role from the
mysql.user table. If the role is subsequently granted again, it will again be
the user's default. Use SET DEFAULT ROLE NONE to explicitly remove this.

Before MariaDB 10.1.13, the REVOKE role statement was not permitted in
prepared statements.

Example
-------

REVOKE journalist FROM hulda

URL: https://mariadb.com/kb/en/revoke/https://mariadb.com/kb/en/revoke/�	$INET_NTOASyntax
------

INET_NTOA(expr)

Description
-----------

Given a numeric IPv4 network address in network byte order (4 or 8 byte),
returns the dotted-quad representation of the address as a string.

Examples
--------

SELECT INET_NTOA(3232235777);
+-----------------------+
| INET_NTOA(3232235777) |
+-----------------------+
| 192.168.1.1           |
+-----------------------+

192.168.1.1 corresponds to 3232235777 since 192 x 2563 + 168 x 256 2 + 1 x 256
+ 1 = 3232235777

URL: https://mariadb.com/kb/en/inet_ntoa/https://mariadb.com/kb/en/inet_ntoa/�|'IS_FREE_LOCKSyntax
------

IS_FREE_LOCK(str)

Description
-----------

Checks whether the lock named str is free to use (that is, not locked).
Returns 1 if the lock is free (no one is using the lock), 0 if the lock is in
use, and NULL if an error occurs (such as an incorrect argument, like an empty
string or NULL). str is case insensitive.

If the metadata_lock_info plugin is installed, the Information Schema
metadata_lock_info table contains information about locks of this kind (as
well as metadata locks).

Statements using the IS_FREE_LOCK function are not safe for statement-based
replication.

URL: https://mariadb.com/kb/en/is_free_lock/https://mariadb.com/kb/en/is_free_lock/��"IS_IPV6Syntax
------

IS_IPV6(expr)

Description
-----------

Returns 1 if the expression is a valid IPv6 address specified as a string,
otherwise returns 0. Does not consider IPv4 addresses to be valid IPv6
addresses.

Examples
--------

SELECT IS_IPV6('48f3::d432:1431:ba23:846f');
+--------------------------------------+
| IS_IPV6('48f3::d432:1431:ba23:846f') |
+--------------------------------------+
|                                    1 |
+--------------------------------------+
1 row in set (0.02 sec)

SELECT IS_IPV6('10.0.1.1');
+---------------------+
| IS_IPV6('10.0.1.1') |
+---------------------+
|                   0 |
+---------------------+

URL: https://mariadb.com/kb/en/is_ipv6/https://mariadb.com/kb/en/is_ipv6/0�s�3@%�����4�0�eo"'
SET PASSWORDSyntax
------

SET PASSWORD [FOR user] =
  {
    PASSWORD('some password')
   | OLD_PASSWORD('some password')
   | 'encrypted password'
  }

Description
-----------

The SET PASSWORD statement assigns a password to an existing MariaDB user
account.

If the password is specified using the PASSWORD() or OLD_PASSWORD() function,
the literal text of the password should be given. If the password is specified
without using either function, the password should be the already-encrypted
password value as returned by PASSWORD().

OLD_PASSWORD() should only be used if your MariaDB/MySQL clients are very old
(< 4.0.0).

With no FOR clause, this statement sets the password for the current user. Any
client that has connected to the server using a non-anonymous account can
change the password for that account.

With a FOR clause, this statement sets the password for a specific account on
the current server host. Only clients that have the UPDATE privilege for the
mysql database can do this. The user value should be given in
user_name@host_name format, where user_name and host_name are exactly as they
are listed in the User and Host columns of the mysql.user table (or view in
MariaDB-10.4 onwards) entry.

The argument to PASSWORD() and the password given to MariaDB clients can be of
arbitrary length.

Authentication Plugin Support
-----------------------------

MariaDB starting with 10.4
--------------------------
In MariaDB 10.4 and later, SET PASSWORD (with or without PASSWORD()) works for
accounts authenticated via any authentication plugin that supports passwords
stored in the mysql.global_priv table.

The ed25519, mysql_native_password, and mysql_old_password authentication
plugins store passwords in the mysql.global_priv table.

If you run SET PASSWORD on an account that authenticates with one of these
authentication plugins that stores passwords in the mysql.global_priv table,
then the PASSWORD() function is evaluated by the specific authentication
plugin used by the account. The authentication plugin hashes the password with
a method that is compatible with that specific authentication plugin.

The unix_socket, named_pipe, gssapi, and pam authentication plugins do not
store passwords in the mysql.global_priv table. These authentication plugins
rely on other methods to authenticate the user.

If you attempt to run SET PASSWORD on an account that authenticates with one
of these authentication plugins that doesn't store a password in the
mysql.global_priv table, then MariaDB Server will raise a warning like the
following:

SET PASSWORD is ignored for users authenticating via unix_socket plugin

See Authentication from MariaDB 10.4 for an overview of authentication changes
in MariaDB 10.4.

MariaDB until 10.3
------------------
In MariaDB 10.3 and before, SET PASSWORD (with or without PASSWORD()) only
works for accounts authenticated via mysql_native_password or
mysql_old_password authentication plugins

Passwordless User Accounts
--------------------------

User accounts do not always require passwords to login.

The unix_socket , named_pipe and gssapi authentication plugins do not require
a password to authenticate the user.

The pam authentication plugin may or may not require a password to
authenticate the user, depending on the specific configuration.

The mysql_native_password and mysql_old_password authentication plugins
require passwords for authentication, but the password can be blank. In that
case, no password is required.

If you provide a password while attempting to log into the server as an
account that doesn't require a password, then MariaDB server will simply
ignore the password.

MariaDB starting with 10.4
--------------------------
In MariaDB 10.4 and later, a user account can be defined to use multiple
authentication plugins in a specific order of preference. This specific
scenario may be more noticeable in these versions, since an account could be
associated with some authentication plugins that require a password, and some
that do not.

Example
-------

For example, if you had an entry with User and Host column values of 'bob' and
'%.loc.gov', you would write the statement like this:

SET PASSWORD FOR 'bob'@'%.loc.gov' = PASSWORD('newpass');

If you want to delete a password for a user, you would do:

SET PASSWORD FOR 'bob'@localhost = PASSWORD("");

URL: https://mariadb.com/kb/en/set-password/https://mariadb.com/kb/en/set-password/q	�$
DROP ROLESyntax
------

DROP ROLE [IF EXISTS] role_name [,role_name ...]

Description
-----------

The DROP ROLE statement removes one or more MariaDB roles. To use this
statement, you must have the global CREATE USER privilege or the DELETE
privilege for the mysql database.

DROP ROLE does not disable roles for connections which selected them with SET
ROLE. If a role has previously been set as a default role, DROP ROLE does not
remove the record of the default role from the mysql.user table. If the role
is subsequently recreated and granted, it will again be the user's default.
Use SET DEFAULT ROLE NONE to explicitly remove this.

If any of the specified user accounts do not exist, ERROR 1396 (HY000)
results. If an error occurs, DROP ROLE will still drop the roles that do not
result in an error. Only one error is produced for all roles which have not
been dropped:

ERROR 1396 (HY000): Operation DROP ROLE failed for 'a','b','c'

Failed CREATE or DROP operations, for both users and roles, produce the same
error code.

IF EXISTS
---------

If the IF EXISTS clause is used, MariaDB will return a warning instead of an
error if the role does not exist.

Examples
--------

DROP ROLE journalist;

The same thing using the optional IF EXISTS clause:

DROP ROLE journalist;
ERROR 1396 (HY000): Operation DROP ROLE failed for 'journalist'

DROP ROLE IF EXISTS journalist;
Query OK, 0 rows affected, 1 warning (0.00 sec)

Note (Code 1975): Can't drop role 'journalist'; it doesn't exist

URL: https://mariadb.com/kb/en/drop-role/https://mariadb.com/kb/en/drop-role/�0'IS_USED_LOCKSyntax
------

IS_USED_LOCK(str)

Description
-----------

Checks whether the lock named str is in use (that is, locked). If so, it
returns the connection identifier of the client that holds the lock.
Otherwise, it returns NULL. str is case insensitive.

If the metadata_lock_info plugin is installed, the Information Schema
metadata_lock_info table contains information about locks of this kind (as
well as metadata locks).

Statements using the IS_USED_LOCK function are not safe for statement-based
replication.

URL: https://mariadb.com/kb/en/is_used_lock/https://mariadb.com/kb/en/is_used_lock/�
%NAME_CONSTSyntax
------

NAME_CONST(name,value)

Description
-----------

Returns the given value. When used to produce a result set column,
NAME_CONST() causes the column to have the given name. The arguments should be
constants.

This function is used internally when replicating stored procedures. It makes
little sense to use it explicitly in SQL statements, and it was not supposed
to be used like that.

SELECT NAME_CONST('myname', 14);
+--------+
| myname |
+--------+
|     14 |
+--------+

URL: https://mariadb.com/kb/en/name_const/https://mariadb.com/kb/en/name_const/�� SLEEPSyntax
------

SLEEP(duration)

Description
-----------

Sleeps (pauses) for the number of seconds given by the duration argument, then
returns 0. If SLEEP() is interrupted, it returns 1. The duration may have a
fractional part given in microseconds.

Statements using the SLEEP() function are not safe for replication.

Example
-------

SELECT SLEEP(5.5);
+------------+
| SLEEP(5.5) |
+------------+
|          0 |
+------------+
1 row in set (5.50 sec)

URL: https://mariadb.com/kb/en/sleep/https://mariadb.com/kb/en/sleep/b!P�qo2cˣp��Mp�&
CREATE ROLESyntax
------

CREATE [OR REPLACE] ROLE [IF NOT EXISTS] role 
 [WITH ADMIN
  {CURRENT_USER | CURRENT_ROLE | user | role}]

Description
-----------

The CREATE ROLE statement creates one or more MariaDB roles. To use it, you
must have the global CREATE USER privilege or the INSERT privilege for the
mysql database. For each account, CREATE ROLE creates a new row in the
mysql.user table that has no privileges, and with the corresponding is_role
field set to Y. It also creates a record in the mysql.roles_mapping table.

If any of the specified roles already exist, ERROR 1396 (HY000) results. If an
error occurs, CREATE ROLE will still create the roles that do not result in an
error. The maximum length for a role is 128 characters. Role names can be
quoted, as explained in the Identifier names page. Only one error is produced
for all roles which have not been created:

ERROR 1396 (HY000): Operation CREATE ROLE failed for 'a','b','c'

Failed CREATE or DROP operations, for both users and roles, produce the same
error code.

PUBLIC and NONE are reserved, and cannot be used as role names. NONE is used
to unset a role and PUBLIC has a special use in other systems, such as Oracle,
so is reserved for compatibility purposes.

For valid identifiers to use as role names, see Identifier Names.

WITH ADMIN
----------

The optional WITH ADMIN clause determines whether the current user, the
current role or another user or role has use of the newly created role. If the
clause is omitted, WITH ADMIN CURRENT_USER is treated as the default, which
means that the current user will be able to GRANT this role to users.

OR REPLACE
----------

If the optional OR REPLACE clause is used, it acts as a shortcut for:

DROP ROLE IF EXISTS name;
CREATE ROLE name ...;

IF NOT EXISTS
-------------

When the IF NOT EXISTS clause is used, MariaDB will return a warning instead
of an error if the specified role already exists. Cannot be used together with
the OR REPLACE clause.

Examples
--------

CREATE ROLE journalist;

CREATE ROLE developer WITH ADMIN lorinda@localhost;

Granting the role to another user. Only user lorinda@localhost has permission
to grant the developer role:

SELECT USER();
+-------------------+
| USER()            |
+-------------------+
| henning@localhost |
+-------------------+
...
GRANT developer TO ian@localhost;
Access denied for user 'henning'@'localhost'

SELECT USER();
+-------------------+
| USER()            |
+-------------------+
| lorinda@localhost |
+-------------------+

GRANT m_role TO ian@localhost;

The OR REPLACE and IF NOT EXISTS clauses. The journalist role already exists:

CREATE ROLE journalist;
ERROR 1396 (HY000): Operation CREATE ROLE failed for 'journalist'

CREATE OR REPLACE ROLE journalist;
Query OK, 0 rows affected (0.00 sec)

CREATE ROLE IF NOT EXISTS journalist;
Query OK, 0 rows affected, 1 warning (0.00 sec)

SHOW WARNINGS;
+-------+------+---------------------------------------------------+
| Level | Code | Message                                           |
+-------+------+---------------------------------------------------+
| Note  | 1975 | Can't create role 'journalist'; it already exists |
+-------+------+---------------------------------------------------+

URL: https://mariadb.com/kb/en/create-role/https://mariadb.com/kb/en/create-role/r�#
SET ROLESyntax
------

SET ROLE { role | NONE }

Description
-----------

The SET ROLE statement enables a role, along with all of its associated
permissions, for the current session. To unset a role, use NONE .

If a role that doesn't exist, or to which the user has not been assigned, is
specified, an ERROR 1959 (OP000): Invalid role specification error occurs.

An automatic SET ROLE is implicitly performed when a user connects if that
user has been assigned a default role. See SET DEFAULT ROLE.

Example
-------

SELECT CURRENT_ROLE;
+--------------+
| CURRENT_ROLE |
+--------------+
| NULL         |
+--------------+

SET ROLE staff;

SELECT CURRENT_ROLE;
+--------------+
| CURRENT_ROLE |
+--------------+
| staff        |
+--------------+

SET ROLE NONE;

SELECT CURRENT_ROLE();
+----------------+
| CURRENT_ROLE() |
+----------------+
| NULL           |
+----------------+

URL: https://mariadb.com/kb/en/set-role/https://mariadb.com/kb/en/set-role/s�+
SET DEFAULT ROLESyntax
------

SET DEFAULT ROLE { role | NONE } [ FOR user@host ]

Description
-----------

The SET DEFAULT ROLE statement sets a default role for a specified (or
current) user. A default role is automatically enabled when a user connects
(an implicit SET ROLE statement is executed immediately after a connection is
established).

To be able to set a role as a default, the role must already have been granted
to that user, and one needs the privileges to enable this role (if you cannot
do SET ROLE X, you won't be able to do SET DEFAULT ROLE X). To set a default
role for another user one needs to have write access to the mysql database.

To remove a user's default role, use SET DEFAULT ROLE NONE [ FOR user@host ].
The record of the default role is not removed if the role is dropped or
revoked, so if the role is subsequently re-created or granted, it will again
be the user's default role.

The default role is stored in the default_role column in the mysql.user
table/view, as well as in the Information Schema APPLICABLE_ROLES table, so
these can be viewed to see which role has been assigned to a user as the
default.

Examples
--------

Setting a default role for the current user:

SET DEFAULT ROLE journalist;

Removing a default role from the current user:

SET DEFAULT ROLE NONE;

Setting a default role for another user. The role has to have been granted to
the user before it can be set as default:

CREATE ROLE journalist;
CREATE USER taniel;

SET DEFAULT ROLE journalist FOR taniel;
ERROR 1959 (OP000): Invalid role specification `journalist`

GRANT journalist TO taniel;
SET DEFAULT ROLE journalist FOR taniel;

Viewing mysql.user:

select * from mysql.user where user='taniel'\G
*************************** 1. row ***************************
         Host: %
         User: taniel
...
       is_role: N
     default_role: journalist
...

Removing a default role for another user

SET DEFAULT ROLE NONE FOR taniel;

URL: https://mariadb.com/kb/en/set-default-role/https://mariadb.com/kb/en/set-default-role/�|#SYS_GUIDMariaDB starting with 10.6.1
----------------------------
The SYS_GUID function was introduced in MariaDB 10.6.1 to enhance Oracle
compatibility. Similar functionality can be achieved with the UUID function.

Syntax
------

SYS_GUID()

Description
-----------

Returns a 16-byte globally unique identifier (GUID), similar to the UUID
function, but without the - character.

Example
-------

SELECT SYS_GUID();
+----------------------------------+
| SYS_GUID()                       |
+----------------------------------+
| 2C574E45BA2811EBB265F859713E4BE4 |
+----------------------------------+

URL: https://mariadb.com/kb/en/sys_guid/https://mariadb.com/kb/en/sys_guid/��!Syntax
------

NOT, !

Description
-----------

Logical NOT. Evaluates to 1 if the operand is 0, to 0 if the operand is
non-zero, and NOT NULL returns NULL.

By default, the ! operator has a higher precedence. If the HIGH_NOT_PRECEDENCE
SQL_MODE flag is set, NOT and ! have the same precedence.

Examples
--------

SELECT NOT 10;
+--------+
| NOT 10 |
+--------+
|      0 |
+--------+

SELECT NOT 0;
+-------+
| NOT 0 |
+-------+
|     1 |
+-------+

SELECT NOT NULL;
+----------+
| NOT NULL |
+----------+
|     NULL |
+----------+

SELECT ! (1+1);
+---------+
| ! (1+1) |
+---------+
|       0 |
+---------+

SELECT ! 1+1;
+-------+
| ! 1+1 |
+-------+
|     1 |
+-------+

URL: https://mariadb.com/kb/en/not/https://mariadb.com/kb/en/not/�����

�

�����t�)
Roles OverviewDescription
-----------

A role bundles a number of privileges together. It assists larger
organizations where, typically, a number of users would have the same
privileges, and, previously, the only way to change the privileges for a group
of users was by changing each user's privileges individually.

Alternatively, multiple external users could have been assigned the same user,
and there would have been no way to see which actual user was responsible for
which action.

With roles, managing this is easy. For example, there could be a number of
users assigned to a journalist role, with identical privileges. Changing the
privileges for all the journalists is a matter of simply changing the role's
privileges, while the individual user is still linked with any changes that
take place.

Roles are created with the CREATE ROLE statement, and dropped with the DROP
ROLE statement. Roles are then assigned to a user with an extension to the
GRANT statement, while privileges are assigned to a role in the regular way
with GRANT. Similarly, the REVOKE statement can be used to both revoke a role
from a user, or revoke a privilege from a role.

Once a user has connected, he can obtain all privileges associated with a role
by setting a role with the SET ROLE statement. The CURRENT_ROLE function
returns the currently set role for the session, if any.

Only roles granted directly to a user can be set, roles granted to other roles
cannot. Instead the privileges granted to a role, which is, in turn, granted
to another role (grantee), will be immediately available to any user who sets
this second grantee role.

The SET DEFAULT ROLE statement allows one to set a default role for a user. A
default role is automatically enabled when a user connects (an implicit SET
ROLE statement is executed immediately after a connection is established).

Roles were implemented as a GSoC 2013 project by Vicentiu Ciorbaru.

System Tables
-------------

Information about roles and who they've been granted to can be found in the
Information Schema APPLICABLE_ROLES table as well as the mysql.ROLES_MAPPING
table.

The Information Schema ENABLED_ROLES table shows the enabled roles for the
current session.

Examples
--------

Creating a role and granting a privilege:

CREATE ROLE journalist;

GRANT SHOW DATABASES ON *.* TO journalist;

GRANT journalist to hulda;

Note, that hulda has no SHOW DATABASES privilege, even though she was granted
the journalist role. She needs to set the role first:

SHOW DATABASES;
+--------------------+
| Database           |
+--------------------+
| information_schema |
+--------------------+

SELECT CURRENT_ROLE;
+--------------+
| CURRENT_ROLE |
+--------------+
| NULL         |
+--------------+

SET ROLE journalist;

SELECT CURRENT_ROLE;
+--------------+
| CURRENT_ROLE |
+--------------+
| journalist   |
+--------------+

SHOW DATABASES;
+--------------------+
| Database           |
+--------------------+
| ...                |
| information_schema |
| mysql              |
| performance_schema |
| test               |
| ...                |
+--------------------+

SET ROLE NONE;

Roles can be granted to roles:

CREATE ROLE writer;

GRANT SELECT ON data.* TO writer;

GRANT writer TO journalist;

But one does not need to set a role granted to a role. For example, hulda will
automatically get all writer privileges when she sets the journalist role:

SELECT CURRENT_ROLE;
+--------------+
| CURRENT_ROLE |
+--------------+
| NULL         |
+--------------+

SHOW TABLES FROM data;
Empty set (0.01 sec)

SET ROLE journalist;

SELECT CURRENT_ROLE;
+--------------+
| CURRENT_ROLE |
+--------------+
| journalist   |
+--------------+

SHOW TABLES FROM data;
+------------------------------+
| Tables_in_data               |
+------------------------------+
| set1                         |
| ...                          |
+------------------------------+

Roles and Views (and Stored Routines)
-------------------------------------

When a user sets a role, he, in a sense, has two identities with two
associated sets of privileges. But a view (or a stored routine) can have only
one definer. So, when a view (or a stored routine) is created with the SQL
SECURITY DEFINER, one can specify whether the definer should be CURRENT_USER
(and the view will have none of the privileges of the user's role) or
CURRENT_ROLE (in this case, the view will use role's privileges, but none of
the user's privileges). As a result, sometimes one can create a view that is
impossible to use.

CREATE ROLE r1;

GRANT ALL ON db1.* TO r1;

GRANT r1 TO foo@localhost;

GRANT ALL ON db.* TO foo@localhost;

SELECT CURRENT_USER
+---------------+
| current_user  |
+---------------+
| foo@localhost |
+---------------+

SET ROLE r1;

CREATE TABLE db1.t1 (i int);

CREATE VIEW db.v1 AS SELECT * FROM db1.t1;

SHOW CREATE VIEW db.v1;
+------+-----------------------------------------------------------------------
------------------------------------------------------------------+------------
---------+----------------------+
| View | Create View                                                          
                                 |
character_set_client | collation_connection |
+------+-----------------------------------------------------------------------
------------------------------------------------------------------+------------
---------+----------------------+
| v1   | CREATE ALGORITHM=UNDEFINED DEFINER=`foo`@`localhost` SQL SECURITY
DEFINER VIEW `db`.`v1` AS SELECT `db1`.`t1`.`i` AS `i` from `db1`.`t1` | utf8 
       | utf8_general_ci      |
+------+-----------------------------------------------------------------------
------------------------------------------------------------------+------------
---------+----------------------+

CREATE DEFINER=CURRENT_ROLE VIEW db.v2 AS SELECT * FROM db1.t1;

SHOW CREATE VIEW db.b2;
+------+-----------------------------------------------------------------------
-----------------------------------------------------+----------------------+--
-------------------+
| View | Create View                                                          
                           | character_set_client |
collation_connection |
+------+-----------------------------------------------------------------------
-----------------------------------------------------+----------------------+--
-------------------+
| v2   | CREATE ALGORITHM=UNDEFINED DEFINER=`r1` SQL SECURITY DEFINER VIEW
`db`.`v2` AS select `db1`.`t1`.`a` AS `a` from `db1`.`t1` | utf8              
 | utf8_general_ci      |
+------+-----------------------------------------------------------------------
-----------------------------------------------------+----------------------+--
-------------------+

Other Resources
---------------

* Roles Review by Peter Gulutzan

URL: https://mariadb.com/kb/en/roles_overview/https://mariadb.com/kb/en/roles_overview/��&&Syntax
------

AND, &&

Description
-----------

Logical AND. Evaluates to 1 if all operands are non-zero and not NULL, to 0 if
one or more operands are 0, otherwise NULL is returned.

For this operator, short-circuit evaluation can be used.

Examples
--------

SELECT 1 && 1;
+--------+
| 1 && 1 |
+--------+
|      1 |
+--------+

SELECT 1 && 0;
+--------+
| 1 && 0 |
+--------+
|      0 |
+--------+

SELECT 1 && NULL;
+-----------+
| 1 && NULL |
+-----------+
|      NULL |
+-----------+

SELECT 0 && NULL;
+-----------+
| 0 && NULL |
+-----------+
|         0 |
+-----------+

SELECT NULL && 0;
+-----------+
| NULL && 0 |
+-----------+
|         0 |
+-----------+

URL: https://mariadb.com/kb/en/and/https://mariadb.com/kb/en/and/��d��u�*
Account LockingMariaDB starting with 10.4.2
----------------------------
Account locking was introduced in MariaDB 10.4.2.

Description
-----------

Account locking permits privileged administrators to lock/unlock user
accounts. No new client connections will be permitted if an account is locked
(existing connections are not affected).

User accounts can be locked at creation, with the CREATE USER statement, or
modified after creation with the ALTER USER statement. For example:

CREATE USER 'lorin'@'localhost' ACCOUNT LOCK;

or

ALTER USER 'marijn'@'localhost' ACCOUNT LOCK;

The server will return an ER_ACCOUNT_HAS_BEEN_LOCKED error when locked users
attempt to connect:

mysql -ulorin
 ERROR 4151 (HY000): Access denied, this account is locked

The ALTER USER statement is also used to unlock a user:

ALTER USER 'lorin'@'localhost' ACCOUNT UNLOCK;

The SHOW CREATE USER statement will show whether the account is locked:

SHOW CREATE USER 'marijn'@'localhost';
+-----------------------------------------------+
| CREATE USER for marijn@localhost              |
+-----------------------------------------------+
| CREATE USER 'marijn'@'localhost' ACCOUNT LOCK |
+-----------------------------------------------+

as well as querying the mysql.global_priv table:

SELECT CONCAT(user, '@', host, ' => ', JSON_DETAILED(priv)) FROM
mysql.global_priv 
 WHERE user='marijn';
+------------------------------------------------------------------------------
-------+
| CONCAT(user, '@', host, ' => ', JSON_DETAILED(priv))                        
    |
+------------------------------------------------------------------------------
-------+
| marijn@localhost => {
  "access": 0,
  "plugin": "mysql_native_password",
  "authentication_string": "",
  "account_locked": true,
  "password_last_changed": 1558017158
} |
+------------------------------------------------------------------------------
-------+

URL: https://mariadb.com/kb/en/account-locking/https://mariadb.com/kb/en/account-locking/wZ/
User Password ExpiryMariaDB starting with 10.4.3
----------------------------
User password expiry was introduced in MariaDB 10.4.3.

Password expiry permits administrators to expire user passwords, either
manually or automatically.

System Variables
----------------

There are two system variables which affect password expiry:
default_password_lifetime, which determines the amount of time between
requiring the user to change their password. 0, the default, means automatic
password expiry is not active.

The second variable, disconnect_on_expired_password determines whether a
client is permitted to connect if their password has expired, or whether they
are permitted to connect in sandbox mode, able to perform a limited subset of
queries related to resetting the password, in particular SET PASSWORD and SET.

Setting a Password Expiry Limit for a User
------------------------------------------

Besides automatic password expiry, as determined by default_password_lifetime,
password expiry times can be set on an individual user basis, overriding the
global using the CREATE USER or ALTER USER statements, for example:

CREATE USER 'monty'@'localhost' PASSWORD EXPIRE INTERVAL 120 DAY;

ALTER USER 'monty'@'localhost' PASSWORD EXPIRE INTERVAL 120 DAY;

Limits can be disabled by use of the NEVER keyword, for example:

CREATE USER 'monty'@'localhost' PASSWORD EXPIRE NEVER;

ALTER USER 'monty'@'localhost' PASSWORD EXPIRE NEVER;

A manually set limit can be restored the system default by use of DEFAULT, for
example:

CREATE USER 'monty'@'localhost' PASSWORD EXPIRE DEFAULT;

ALTER USER 'monty'@'localhost' PASSWORD EXPIRE DEFAULT;

SHOW CREATE USER
----------------

The SHOW CREATE USER statement will display information about the password
expiry status of the user. Unlike MySQL, it will not display if the user is
unlocked, or if the password expiry is set to default.

CREATE USER 'monty'@'localhost' PASSWORD EXPIRE INTERVAL 120 DAY;
CREATE USER 'konstantin'@'localhost' PASSWORD EXPIRE NEVER;
CREATE USER 'amse'@'localhost' PASSWORD EXPIRE DEFAULT;

SHOW CREATE USER 'monty'@'localhost';
+------------------------------------------------------------------+
| CREATE USER for monty@localhost                                  |
+------------------------------------------------------------------+
| CREATE USER 'monty'@'localhost' PASSWORD EXPIRE INTERVAL 120 DAY |
+------------------------------------------------------------------+

SHOW CREATE USER 'konstantin'@'localhost';
+------------------------------------------------------------+
| CREATE USER for konstantin@localhost                       |
+------------------------------------------------------------+
| CREATE USER 'konstantin'@'localhost' PASSWORD EXPIRE NEVER |
+------------------------------------------------------------+

SHOW CREATE USER 'amse'@'localhost';
+--------------------------------+
| CREATE USER for amse@localhost |
+--------------------------------+
| CREATE USER 'amse'@'localhost' |
+--------------------------------+

Checking When Passwords Expire
------------------------------

The following query can be used to check when the current passwords expire for
all users:

WITH password_expiration_info AS (
 SELECT User, Host,
 IF(
 IFNULL(JSON_EXTRACT(Priv, '$.password_lifetime'), -1) = -1,
 @@global.default_password_lifetime,
 JSON_EXTRACT(Priv, '$.password_lifetime')
 ) AS password_lifetime,
 JSON_EXTRACT(Priv, '$.password_last_changed') AS password_last_changed
 FROM mysql.global_priv
)
SELECT pei.User, pei.Host,
 pei.password_lifetime,
 FROM_UNIXTIME(pei.password_last_changed) AS password_last_changed_datetime,
 FROM_UNIXTIME(
 pei.password_last_changed +
 (pei.password_lifetime * 60 * 60 * 24)
 ) AS password_expiration_datetime
 FROM password_expiration_info pei
 WHERE pei.password_lifetime != 0
 AND pei.password_last_changed IS NOT NULL
UNION
SELECT pei.User, pei.Host,
 pei.password_lifetime,
 FROM_UNIXTIME(pei.password_last_changed) AS password_last_changed_datetime,
 0 AS password_expiration_datetime
 FROM password_expiration_info pei
 WHERE pei.password_lifetime = 0
 OR pei.password_last_changed IS NULL;

--connect-expired-password Client Option
----------------------------------------

The mariadb client --connect-expired-password option notifies the server that
the client is prepared to handle expired password sandbox mode (even if the
--batch option was specified).

URL: https://mariadb.com/kb/en/user-password-expiry/https://mariadb.com/kb/en/user-password-expiry/��XORSyntax
------

XOR

Description
-----------

XOR stands for eXclusive OR. Returns NULL if either operand is NULL. For
non-NULL operands, evaluates to 1 if an odd number of operands is non-zero,
otherwise 0 is returned.

Examples
--------

SELECT 1 XOR 1;
+---------+
| 1 XOR 1 |
+---------+
|       0 |
+---------+

SELECT 1 XOR 0;
+---------+
| 1 XOR 0 |
+---------+
|       1 |
+---------+

SELECT 1 XOR NULL;
+------------+
| 1 XOR NULL |
+------------+
|       NULL |
+------------+

In the following example, the right 1 XOR 1 is evaluated first, and returns 0.
Then, 1 XOR 0 is evaluated, and 1 is returned.

SELECT 1 XOR 1 XOR 1;
+---------------+
| 1 XOR 1 XOR 1 |
+---------------+
|             1 |
+---------------+

URL: https://mariadb.com/kb/en/xor/https://mariadb.com/kb/en/xor/�n&STDDEV_SAMPSyntax
------

STDDEV_SAMP(expr)

Description
-----------

Returns the sample standard deviation of expr (the square root of VAR_SAMP()).

It is an aggregate function, and so can be used with the GROUP BY clause.

STDDEV_SAMP() can be used as a window function.

STDDEV_SAMP() returns NULL if there were no matching rows.

URL: https://mariadb.com/kb/en/stddev_samp/https://mariadb.com/kb/en/stddev_samp/���*����v�E��|
u%UNCOMPRESSSyntax
------

UNCOMPRESS(string_to_uncompress)

Description
-----------

Uncompresses a string compressed by the COMPRESS() function. If the argument
is not a compressed value, the result is NULL. This function requires MariaDB
to have been compiled with a compression library such as zlib. Otherwise, the
return value is always NULL. The have_compress server system variable
indicates whether a compression library is present.

Examples
--------

SELECT UNCOMPRESS(COMPRESS('a string'));
+----------------------------------+
| UNCOMPRESS(COMPRESS('a string')) |
+----------------------------------+
| a string                         |
+----------------------------------+

SELECT UNCOMPRESS('a string');
+------------------------+
| UNCOMPRESS('a string') |
+------------------------+
| NULL                   |
+------------------------+

URL: https://mariadb.com/kb/en/uncompress/https://mariadb.com/kb/en/uncompress/}D
!DECODESyntax
------

DECODE(crypt_str,pass_str)

In Oracle mode from MariaDB 10.3.2:

DECODE(expr, search_expr, result_expr [, search_expr2, result_expr2 ...]
[default_expr])

In all modes from MariaDB 10.3.2:

DECODE_ORACLE(expr, search_expr, result_expr [, search_expr2, result_expr2
...] [default_expr])

Description
-----------

In the default mode, DECODE decrypts the encrypted string crypt_str using
pass_str as the password. crypt_str should be a string returned from ENCODE().
The resulting string will be the original string only if pass_str is the same.

In Oracle mode from MariaDB 10.3.2, DECODE compares expr to the search
expressions, in order. If it finds a match, the corresponding result
expression is returned. If no matches are found, the default expression is
returned, or NULL if no default is provided.

NULLs are treated as equivalent.

DECODE_ORACLE is a synonym for the Oracle-mode version of the function, and is
available in all modes.

Examples
--------

From MariaDB 10.3.2:

SELECT DECODE_ORACLE(2+1,3*1,'found1',3*2,'found2','default');
+--------------------------------------------------------+
| DECODE_ORACLE(2+1,3*1,'found1',3*2,'found2','default') |
+--------------------------------------------------------+
| found1                                                 |
+--------------------------------------------------------+

SELECT DECODE_ORACLE(2+4,3*1,'found1',3*2,'found2','default');
+--------------------------------------------------------+
| DECODE_ORACLE(2+4,3*1,'found1',3*2,'found2','default') |
+--------------------------------------------------------+
| found2                                                 |
+--------------------------------------------------------+

SELECT DECODE_ORACLE(2+2,3*1,'found1',3*2,'found2','default');
+--------------------------------------------------------+
| DECODE_ORACLE(2+2,3*1,'found1',3*2,'found2','default') |
+--------------------------------------------------------+
| default                                                |
+--------------------------------------------------------+

Nulls are treated as equivalent:

SELECT DECODE_ORACLE(NULL,NULL,'Nulls are equivalent','Nulls are not
equivalent');
+----------------------------------------------------------------------------+
| DECODE_ORACLE(NULL,NULL,'Nulls are equivalent','Nulls are not equivalent') |
+----------------------------------------------------------------------------+
| Nulls are equivalent                                                       |
+----------------------------------------------------------------------------+

URL: https://mariadb.com/kb/en/decode/https://mariadb.com/kb/en/decode/P&AES_DECRYPTSyntax
------

AES_DECRYPT(crypt_str,key_str)

From MariaDB 11.2.0

AES_ENCRYPT(crypt_str, key_str, [, iv [, mode]])

Description
-----------

This function allows decryption of data using the official AES (Advanced
Encryption Standard) algorithm. For more information, see the description of
AES_ENCRYPT().

MariaDB starting with 11.2
--------------------------
From MariaDB 11.2, the function supports an initialization vector, and control
of the block encryption mode. The default mode is specified by the
block_encryption_mode system variable, which can be changed when calling the
function with a mode. mode is aes-{128,192,256}-{ecb,cbc,ctr} for example:
"AES-128-cbc".

For modes that require it, the initialization_vector iv should be 16 bytes (it
can be longer, but the extra bytes are ignored). A shorter iv, where one is
required, results in the function returning NULL. Calling RANDOM_BYTES(16)
will generate a random series of bytes that can be used for the iv.

Examples
--------

From MariaDB 11.2.0:

SELECT HEX(AES_ENCRYPT('foo', 'bar', '0123456789abcdef', 'aes-128-ctr')) AS x; 
+--------+
| x      |
+--------+
| C57C4B |
+--------+

SELECT AES_DECRYPT(x'C57C4B', 'bar', '0123456789abcdef', 'aes-128-ctr'); 
+------------------------------------------------------------------+
| AES_DECRYPT(x'C57C4B', 'bar', '0123456789abcdef', 'aes-128-ctr') |
+------------------------------------------------------------------+
| foo                                                              |
+------------------------------------------------------------------+

URL: https://mariadb.com/kb/en/aes_decrypt/https://mariadb.com/kb/en/aes_decrypt/�	�$BENCHMARKSyntax
------

BENCHMARK(count,expr)

Description
-----------

The BENCHMARK() function executes the expression expr repeatedly count times.
It may be used to time how quickly MariaDB processes the expression. The
result value is always 0. The intended use is from within the mariadb client,
which reports query execution times.

Examples
--------

SELECT BENCHMARK(1000000,ENCODE('hello','goodbye'));
+----------------------------------------------+
| BENCHMARK(1000000,ENCODE('hello','goodbye')) |
+----------------------------------------------+
|                                            0 |
+----------------------------------------------+
1 row in set (0.21 sec)

URL: https://mariadb.com/kb/en/benchmark/https://mariadb.com/kb/en/benchmark/�	*BINLOG_GTID_POSSyntax
------

BINLOG_GTID_POS(binlog_filename,binlog_offset)

Description
-----------

The BINLOG_GTID_POS() function takes as input an old-style binary log position
in the form of a file name and a file offset. It looks up the position in the
current binlog, and returns a string representation of the corresponding GTID
position. If the position is not found in the current binlog, NULL is returned.

Examples
--------

SELECT BINLOG_GTID_POS("master-bin.000001", 600);

URL: https://mariadb.com/kb/en/binlog_gtid_pos/https://mariadb.com/kb/en/binlog_gtid_pos/�	�$COLLATIONSyntax
------

COLLATION(str)

Description
-----------

Returns the collation of the string argument. If str is not a string, it is
considered as a binary string (so the function returns 'binary'). This applies
to NULL, too. The return value is a string in the utf8 character set.

See Character Sets and Collations.

Examples
--------

SELECT COLLATION('abc');
+-------------------+
| COLLATION('abc')  |
+-------------------+
| latin1_swedish_ci |
+-------------------+

SELECT COLLATION(_utf8'abc');
+-----------------------+
| COLLATION(_utf8'abc') |
+-----------------------+
| utf8_general_ci       |
+-----------------------+

URL: https://mariadb.com/kb/en/collation/https://mariadb.com/kb/en/collation/��P�7��y
�T�>�n��&AES_ENCRYPTSyntax
------

AES_ENCRYPT(str,key_str)

From MariaDB 11.2.0

AES_ENCRYPT(str, key, [, iv [, mode]])

Description
-----------

AES_ENCRYPT() and AES_DECRYPT() allow encryption and decryption of data using
the official AES (Advanced Encryption Standard) algorithm, previously known as
"Rijndael." Encoding with a 128-bit key length is used (from MariaDB 11.2.0,
this is the default, and can be changed). 128 bits is much faster and is
secure enough for most purposes.

AES_ENCRYPT() encrypts a string str using the key key_str, and returns a
binary string.

AES_DECRYPT() decrypts the encrypted string and returns the original string.

The input arguments may be any length. If either argument is NULL, the result
of this function is also NULL.

Because AES is a block-level algorithm, padding is used to encode uneven
length strings and so the result string length may be calculated using this
formula:

16 x (trunc(string_length / 16) + 1)

If AES_DECRYPT() detects invalid data or incorrect padding, it returns NULL.
However, it is possible for AES_DECRYPT() to return a non-NULL value (possibly
garbage) if the input data or the key is invalid.

MariaDB starting with 11.2
--------------------------
From MariaDB 11.2, the function supports an initialization vector, and control
of the block encryption mode. The default mode is specified by the
block_encryption_mode system variable, which can be changed when calling the
function with a mode. mode is aes-{128,192,256}-{ecb,cbc,ctr} for example:
"AES-128-cbc".

AES_ENCRYPT(str, key) can no longer be used in persistent virtual columns (and
the like).

Examples
--------

INSERT INTO t VALUES (AES_ENCRYPT('text',SHA2('password',512)));

From MariaDB 11.2.0:

SELECT HEX(AES_ENCRYPT('foo', 'bar', '0123456789abcdef', 'aes-256-cbc')) AS x;
+----------------------------------+
| x                                |
+----------------------------------+
| 42A3EB91E6DFC40A900D278F99E0726E |
+----------------------------------+

URL: https://mariadb.com/kb/en/aes_encrypt/https://mariadb.com/kb/en/aes_encrypt/��#COMPRESSSyntax
------

COMPRESS(string_to_compress)

Description
-----------

Compresses a string and returns the result as a binary string. This function
requires MariaDB to have been compiled with a compression library such as
zlib. Otherwise, the return value is always NULL. The compressed string can be
uncompressed with UNCOMPRESS().

The have_compress server system variable indicates whether a compression
library is present.

Examples
--------

SELECT LENGTH(COMPRESS(REPEAT('a',1000)));
+------------------------------------+
| LENGTH(COMPRESS(REPEAT('a',1000))) |
+------------------------------------+
|                                 21 |
+------------------------------------+

SELECT LENGTH(COMPRESS(''));
+----------------------+
| LENGTH(COMPRESS('')) |
+----------------------+
|                    0 |
+----------------------+

SELECT LENGTH(COMPRESS('a'));
+-----------------------+
| LENGTH(COMPRESS('a')) |
+-----------------------+
|                    13 |
+-----------------------+

SELECT LENGTH(COMPRESS(REPEAT('a',16)));
+----------------------------------+
| LENGTH(COMPRESS(REPEAT('a',16))) |
+----------------------------------+
|                               15 |
+----------------------------------+

URL: https://mariadb.com/kb/en/compress/https://mariadb.com/kb/en/compress/��&DES_DECRYPTDES_DECRYPT has been deprecated from MariaDB 10.10.0, and will be removed in a
future release.

Syntax
------

DES_DECRYPT(crypt_str[,key_str])

Description
-----------

Decrypts a string encrypted with DES_ENCRYPT(). If an error occurs, this
function returns NULL.

This function works only if MariaDB has been configured with TLS support.

If no key_str argument is given, DES_DECRYPT() examines the first byte of the
encrypted string to determine the DES key number that was used to encrypt the
original string, and then reads the key from the DES key file to decrypt the
message. For this to work, the user must have the SUPER privilege. The key
file can be specified with the --des-key-file server option.

If you pass this function a key_str argument, that string is used as the key
for decrypting the message.

If the crypt_str argument does not appear to be an encrypted string, MariaDB
returns the given crypt_str.

URL: https://mariadb.com/kb/en/des_decrypt/https://mariadb.com/kb/en/des_decrypt/��&DES_ENCRYPTDES_ENCRYPT has been deprecated from MariaDB 10.10.0, and will be removed in a
future release.

Syntax
------

DES_ENCRYPT(str[,{key_num|key_str}])

Description
-----------

Encrypts the string with the given key using the Triple-DES algorithm.

This function works only if MariaDB has been configured with TLS support.

The encryption key to use is chosen based on the second argument to
DES_ENCRYPT(), if one was given. With no argument, the first key from the DES
key file is used. With a key_num argument, the given key number (0-9) from the
DES key file is used. With a key_str argument, the given key string is used to
encrypt str.

The key file can be specified with the --des-key-file server option.

The return string is a binary string where the first character is CHAR(128 |
key_num). If an error occurs, DES_ENCRYPT() returns NULL.

The 128 is added to make it easier to recognize an encrypted key. If you use a
string key, key_num is 127.

The string length for the result is given by this formula:

new_len = orig_len + (8 - (orig_len % 8)) + 1

Each line in the DES key file has the following format:

key_num des_key_str

Each key_num value must be a number in the range from 0 to 9. Lines in the
file may be in any order. des_key_str is the string that is used to encrypt
the message. There should be at least one space between the number and the
key. The first key is the default key that is used if you do not specify any
key argument to DES_ENCRYPT().

You can tell MariaDB to read new key values from the key file with the FLUSH
DES_KEY_FILE statement. This requires the RELOAD privilege.

One benefit of having a set of default keys is that it gives applications a
way to check for the existence of encrypted column values, without giving the
end user the right to decrypt those values.

Examples
--------

SELECT customer_address FROM customer_table 
 WHERE crypted_credit_card = DES_ENCRYPT('credit_card_number');

URL: https://mariadb.com/kb/en/des_encrypt/https://mariadb.com/kb/en/des_encrypt/�
E(CONNECTION_IDSyntax
------

CONNECTION_ID()

Description
-----------

Returns the connection ID for the connection. Every connection (including
events) has an ID that is unique among the set of currently connected clients.

Until MariaDB 10.3.1, returns MYSQL_TYPE_LONGLONG, or bigint(10), in all
cases. From MariaDB 10.3.1, returns MYSQL_TYPE_LONG, or int(10), when the
result would fit within 32-bits.

Examples
--------

SELECT CONNECTION_ID();
+-----------------+
| CONNECTION_ID() |
+-----------------+
|               3 |
+-----------------+

URL: https://mariadb.com/kb/en/connection_id/https://mariadb.com/kb/en/connection_id/��!SCHEMASyntax
------

SCHEMA()

Description
-----------

This function is a synonym for DATABASE().

URL: https://mariadb.com/kb/en/schema/https://mariadb.com/kb/en/schema/��'SESSION_USERSyntax
------

SESSION_USER()

Description
-----------

SESSION_USER() is a synonym for USER().

URL: https://mariadb.com/kb/en/session_user/https://mariadb.com/kb/en/session_user/����c�f�_
2-&�F����!ENCODESyntax
------

ENCODE(str,pass_str)

Description
-----------

ENCODE is not considered cryptographically secure, and should not be used for
password encryption.

Encrypt str using pass_str as the password. To decrypt the result, use
DECODE().

The result is a binary string of the same length as str.

The strength of the encryption is based on how good the random generator is.

It is not recommended to rely on the encryption performed by the ENCODE
function. Using a salt value (changed when a password is updated) will improve
matters somewhat, but for storing passwords, consider a more cryptographically
secure function, such as SHA2().

Examples
--------

ENCODE('not so secret text', CONCAT('random_salt','password'))

URL: https://mariadb.com/kb/en/encode/https://mariadb.com/kb/en/encode/��"ENCRYPTSyntax
------

ENCRYPT(str[,salt])

Description
-----------

Encrypts a string using the Unix crypt() system call, returning an encrypted
binary string. The salt argument should be a string with at least two
characters or the returned result will be NULL. If no salt argument is given,
a random value of sufficient length is used.

It is not recommended to use ENCRYPT() with utf16, utf32 or ucs2 multi-byte
character sets because the crypt() system call expects a string terminated
with a zero byte.

Note that the underlying crypt() system call may have some limitations, such
as ignoring all but the first eight characters.

If the have_crypt system variable is set to NO (because the crypt() system
call is not available), the ENCRYPT function will always return NULL.

Examples
--------

SELECT ENCRYPT('encrypt me');
+-----------------------+
| ENCRYPT('encrypt me') |
+-----------------------+
| 4I5BsEx0lqTDk         |
+-----------------------+

URL: https://mariadb.com/kb/en/encrypt/https://mariadb.com/kb/en/encrypt/�<'OLD_PASSWORDSyntax
------

OLD_PASSWORD(str)

Description
-----------

OLD_PASSWORD() was added to MySQL when the implementation of PASSWORD() was
changed to improve security. OLD_PASSWORD() returns the value of the old
(pre-MySQL 4.1) implementation of PASSWORD() as a string, and is intended to
permit you to reset passwords for any pre-4.1 clients that need to connect to
a more recent MySQL server version, or any version of MariaDB, without locking
them out.

As of MariaDB 5.5, the return value is a nonbinary string in the connection
character set and collation, determined by the values of the
character_set_connection and collation_connection system variables. Before
5.5, the return value was a binary string.

The return value is 16 bytes in length, or NULL if the argument was NULL.

URL: https://mariadb.com/kb/en/old_password/https://mariadb.com/kb/en/old_password/��	#PASSWORDSyntax
------

PASSWORD(str)

Description
-----------

The PASSWORD() function is used for hashing passwords for use in
authentication by the MariaDB server. It is not intended for use in other
applications.

Calculates and returns a hashed password string from the plaintext password
str. Returns an empty string (>= MariaDB 10.0.4) if the argument was NULL.

The return value is a nonbinary string in the connection character set and
collation, determined by the values of the character_set_connection and
collation_connection system variables.

This is the function that is used for hashing MariaDB passwords for storage in
the Password column of the user table (see privileges), usually used with the
SET PASSWORD statement. It is not intended for use in other applications.

Until MariaDB 10.3, the return value is 41-bytes in length, and the first
character is always '*'. From MariaDB 10.4, the function takes into account
the authentication plugin where applicable (A CREATE USER or SET PASSWORD
statement). For example, when used in conjunction with a user authenticated by
the ed25519 plugin, the statement will create a longer hash:

CREATE USER edtest@localhost IDENTIFIED VIA ed25519 USING PASSWORD('secret');

CREATE USER edtest2@localhost IDENTIFIED BY 'secret';

SELECT CONCAT(user, '@', host, ' => ', JSON_DETAILED(priv)) FROM
mysql.global_priv
 WHERE user LIKE 'edtest%'\G
*************************** 1. row ***************************
CONCAT(user, '@', host, ' => ', JSON_DETAILED(priv)): edtest@localhost => {
...
  "plugin": "ed25519",
  "authentication_string": "ZIgUREUg5PVgQ6LskhXmO+eZLS0nC8be6HPjYWR4YJY",
...
}
*************************** 2. row ***************************
CONCAT(user, '@', host, ' => ', JSON_DETAILED(priv)): edtest2@localhost => {
...
  "plugin": "mysql_native_password",
  "authentication_string": "*14E65567ABDB5135D0CFD9A70B3032C179A49EE7",
...
}

The behavior of this function is affected by the value of the old_passwords
system variable. If this is set to 1 (0 is default), MariaDB reverts to using
the mysql_old_password authentication plugin by default for newly created
users and passwords.

Examples
--------

SELECT PASSWORD('notagoodpwd');
+-------------------------------------------+
| PASSWORD('notagoodpwd')                   |
+-------------------------------------------+
| *3A70EE9FC6594F88CE9E959CD51C5A1C002DC937 |
+-------------------------------------------+

SET PASSWORD FOR 'bob'@'%.loc.gov' = PASSWORD('newpass');

URL: https://mariadb.com/kb/en/password/https://mariadb.com/kb/en/password/��&SYSTEM_USERSyntax
------

SYSTEM_USER()

Description
-----------

SYSTEM_USER() is a synonym for USER().

URL: https://mariadb.com/kb/en/system_user/https://mariadb.com/kb/en/system_user/��.Assignment Operator (:=)Syntax
------

var_name := expr

Description
-----------

Assignment operator for assigning a value. The value on the right is assigned
to the variable on left.

Unlike the = operator, := can always be used to assign a value to a variable.

This operator works with both user-defined variables and local variables.

When assigning the same value to several variables, LAST_VALUE() can be useful.

Examples
--------

SELECT @x := 10;
+----------+
| @x := 10 |
+----------+
|       10 |
+----------+

SELECT @x, @y := @x;
+------+----------+
| @x   | @y := @x |
+------+----------+
|   10 |       10 |
+------+----------+

URL: https://mariadb.com/kb/en/assignment-operator/https://mariadb.com/kb/en/assignment-operator/��#GREATESTSyntax
------

GREATEST(value1,value2,...)

Description
-----------

With two or more arguments, returns the largest (maximum-valued) argument. The
arguments are compared using the same rules as for LEAST().

Examples
--------

SELECT GREATEST(2,0);
+---------------+
| GREATEST(2,0) |
+---------------+
|             2 |
+---------------+

SELECT GREATEST(34.0,3.0,5.0,767.0);
+------------------------------+
| GREATEST(34.0,3.0,5.0,767.0) |
+------------------------------+
|                        767.0 |
+------------------------------+

SELECT GREATEST('B','A','C');
+-----------------------+
| GREATEST('B','A','C') |
+-----------------------+
| C                     |
+-----------------------+

URL: https://mariadb.com/kb/en/greatest/https://mariadb.com/kb/en/greatest/��&IS NOT NULLSyntax
------

IS NOT NULL

Description
-----------

Tests whether a value is not NULL. See also NULL Values in MariaDB.

Examples
--------

SELECT 1 IS NOT NULL, 0 IS NOT NULL, NULL IS NOT NULL;
+---------------+---------------+------------------+
| 1 IS NOT NULL | 0 IS NOT NULL | NULL IS NOT NULL |
+---------------+---------------+------------------+
|             1 |             1 |                0 |
+---------------+---------------+------------------+

URL: https://mariadb.com/kb/en/is-not-null/https://mariadb.com/kb/en/is-not-null/�8�"�����

V}>2���G
�m�
'RANDOM_BYTESMariaDB starting with 10.10.0
-----------------------------
The RANDOM_BYTES function generates a binary string of random bytes. It was
added in MariaDB 10.10.0.

Syntax
------

RANDOM_BYTES(length)

Description
-----------

Given a length from 1 to 1024, generates a binary string of length consisting
of random bytes generated by the SSL library's random number generator.

See the RAND_bytes() function documentation of your SSL library for
information on the random number generator. In the case of OpenSSL, a
cryptographically secure pseudo random generator (CSPRNG) is used.

Statements containing the RANDOM_BYTES function are unsafe for statement-based
replication.

An error occurs if length is outside the range 1 to 1024.

URL: https://mariadb.com/kb/en/random_bytes/https://mariadb.com/kb/en/random_bytes/�9SHA1Syntax
------

SHA1(str), SHA(str)

Description
-----------

Calculates an SHA-1 160-bit checksum for the string str, as described in RFC
3174 (Secure Hash Algorithm).

The value is returned as a string of 40 hex digits, or NULL if the argument
was NULL. As of MariaDB 5.5, the return value is a nonbinary string in the
connection character set and collation, determined by the values of the
character_set_connection and collation_connection system variables. Before
5.5, the return value was a binary string.

Examples
--------

SELECT SHA1('some boring text');
+------------------------------------------+
| SHA1('some boring text')                 |
+------------------------------------------+
| af969fc2085b1bb6d31e517d5c456def5cdd7093 |
+------------------------------------------+

URL: https://mariadb.com/kb/en/sha1/https://mariadb.com/kb/en/sha1/�SHA2Syntax
------

SHA2(str,hash_len)

Description
-----------

Given a string str, calculates an SHA-2 checksum, which is considered more
cryptographically secure than its SHA-1 equivalent. The SHA-2 family includes
SHA-224, SHA-256, SHA-384, and SHA-512, and the hash_len must correspond to
one of these, i.e. 224, 256, 384 or 512. 0 is equivalent to 256.

The return value is a nonbinary string in the connection character set and
collation, determined by the values of the character_set_connection and
collation_connection system variables.

NULL is returned if the hash length is not valid, or the string str is NULL.

SHA2 will only work if MariaDB was has been configured with TLS support.

Examples
--------

SELECT SHA2('Maria',224);
+----------------------------------------------------------+
| SHA2('Maria',224)                                        |
+----------------------------------------------------------+
| 6cc67add32286412efcab9d0e1675a43a5c2ef3cec8879f81516ff83 |
+----------------------------------------------------------+

SELECT SHA2('Maria',256);
+------------------------------------------------------------------+
| SHA2('Maria',256)                                                |
+------------------------------------------------------------------+
| 9ff18ebe7449349f358e3af0b57cf7a032c1c6b2272cb2656ff85eb112232f16 |
+------------------------------------------------------------------+

SELECT SHA2('Maria',0);
+------------------------------------------------------------------+
| SHA2('Maria',0)                                                  |
+------------------------------------------------------------------+
| 9ff18ebe7449349f358e3af0b57cf7a032c1c6b2272cb2656ff85eb112232f16 |
+------------------------------------------------------------------+

URL: https://mariadb.com/kb/en/sha2/https://mariadb.com/kb/en/sha2/�
�%INET6_ATONSyntax
------

INET6_ATON(expr)

Description
-----------

Given an IPv6 or IPv4 network address as a string, returns a binary string
that represents the numeric value of the address.

No trailing zone ID's or traling network masks are permitted. For IPv4
addresses, or IPv6 addresses with IPv4 address parts, no classful addresses or
trailing port numbers are permitted and octal numbers are not supported.

The returned binary string will be VARBINARY(16) or VARBINARY(4) for IPv6 and
IPv4 addresses respectively.

Returns NULL if the argument is not understood.

MariaDB starting with 10.5.0
----------------------------
From MariaDB 10.5.0, INET6_ATON can take INET6 as an argument.

Examples
--------

SELECT HEX(INET6_ATON('10.0.1.1'));
+-----------------------------+
| HEX(INET6_ATON('10.0.1.1')) |
+-----------------------------+
| 0A000101                    |
+-----------------------------+

SELECT HEX(INET6_ATON('48f3::d432:1431:ba23:846f'));
+----------------------------------------------+
| HEX(INET6_ATON('48f3::d432:1431:ba23:846f')) |
+----------------------------------------------+
| 48F3000000000000D4321431BA23846F             |
+----------------------------------------------+

URL: https://mariadb.com/kb/en/inet6_aton/https://mariadb.com/kb/en/inet6_aton/��!ISNULLSyntax
------

ISNULL(expr)

Description
-----------

If expr is NULL, ISNULL() returns 1, otherwise it returns 0.

See also NULL Values in MariaDB.

Examples
--------

SELECT ISNULL(1+1);
+-------------+
| ISNULL(1+1) |
+-------------+
|           0 |
+-------------+

SELECT ISNULL(1/0);
+-------------+
| ISNULL(1/0) |
+-------------+
|           1 |
+-------------+

URL: https://mariadb.com/kb/en/isnull/https://mariadb.com/kb/en/isnull/��&&Syntax
------

&

Description
-----------

Bitwise AND. Converts the values to binary and compares bits. Only if both the
corresponding bits are 1 is the resulting bit also 1.

See also bitwise OR.

Examples
--------

SELECT 2&1;
+-----+
| 2&1 |
+-----+
|   0 |
+-----+

SELECT 3&1;
+-----+
| 3&1 |
+-----+
|   1 |
+-----+

SELECT 29 & 15;
+---------+
| 29 & 15 |
+---------+
|      13 |
+---------+

URL: https://mariadb.com/kb/en/bitwise_and/https://mariadb.com/kb/en/bitwise_and/�%<<Syntax
------

value1 << value2

Description
-----------

Converts a longlong (BIGINT) number (value1) to binary and shifts value2 units
to the left.

Examples
--------

SELECT 1 << 2;
+--------+
| 1 << 2 |
+--------+
|      4 |
+--------+

URL: https://mariadb.com/kb/en/shift-left/https://mariadb.com/kb/en/shift-left/�&>>Syntax
------

value1 >> value2

Description
-----------

Converts a longlong (BIGINT) number (value1) to binary and shifts value2 units
to the right.

Examples
--------

SELECT 4 >> 2;
+--------+
| 4 >> 2 |
+--------+
|      1 |
+--------+

URL: https://mariadb.com/kb/en/shift-right/https://mariadb.com/kb/en/shift-right/�	�$BIT_COUNTSyntax
------

BIT_COUNT(N)

Description
-----------

Returns the number of bits that are set in the argument N.

Examples
--------

SELECT BIT_COUNT(29), BIT_COUNT(b'101010');
+---------------+----------------------+
| BIT_COUNT(29) | BIT_COUNT(b'101010') |
+---------------+----------------------+
|             4 |                    3 |
+---------------+----------------------+

URL: https://mariadb.com/kb/en/bit_count/https://mariadb.com/kb/en/bit_count/��&^Syntax
------

^

Description
-----------

Bitwise XOR. Converts the values to binary and compares bits. If one (and only
one) of the corresponding bits is 1 is the resulting bit also 1.

Examples
--------

SELECT 1 ^ 1;
+-------+
| 1 ^ 1 |
+-------+
|     0 |
+-------+

SELECT 1 ^ 0;
+-------+
| 1 ^ 0 |
+-------+
|     1 |
+-------+

SELECT 11 ^ 3;
+--------+
| 11 ^ 3 |
+--------+
|      8 |
+--------+

URL: https://mariadb.com/kb/en/bitwise-xor/https://mariadb.com/kb/en/bitwise-xor/o���9S�P��*��PWjK��\N���#GET_LOCKSyntax
------

GET_LOCK(str,timeout)

Description
-----------

Tries to obtain a lock with a name given by the string str, using a timeout of
timeout seconds. Returns 1 if the lock was obtained successfully, 0 if the
attempt timed out (for example, because another client has previously locked
the name), or NULL if an error occurred (such as running out of memory or the
thread was killed with mariadb-admin kill).

A lock is released with RELEASE_LOCK(), when the connection terminates (either
normally or abnormally). A connection can hold multiple locks at the same
time, so a lock that is no longer needed needs to be explicitly released.

The IS_FREE_LOCK function returns whether a specified lock a free or not, and
the IS_USED_LOCK whether the function is in use or not.

Locks obtained with GET_LOCK() do not interact with transactions. That is,
committing a transaction does not release any such locks obtained during the
transaction.

It is also possible to recursively set the same lock. If a lock with the same
name is set n times, it needs to be released n times as well.

str is case insensitive for GET_LOCK() and related functions. If str is an
empty string or NULL, GET_LOCK() returns NULL and does nothing. timeout
supports microseconds.

If the metadata_lock_info plugin is installed, locks acquired with this
function are visible in the Information Schema METADATA_LOCK_INFO table.

This function can be used to implement application locks or to simulate record
locks. Names are locked on a server-wide basis. If a name has been locked by
one client, GET_LOCK() blocks any request by another client for a lock with
the same name. This allows clients that agree on a given lock name to use the
name to perform cooperative advisory locking. But be aware that it also allows
a client that is not among the set of cooperating clients to lock a name,
either inadvertently or deliberately, and thus prevent any of the cooperating
clients from locking that name. One way to reduce the likelihood of this is to
use lock names that are database-specific or application-specific. For
example, use lock names of the form db_name.str or app_name.str.

Statements using the GET_LOCK function are not safe for statement-based
replication.

The patch to permit multiple locks was contributed by Konstantin "Kostja"
Osipov (MDEV-3917).

Examples
--------

SELECT GET_LOCK('lock1',10);
+----------------------+
| GET_LOCK('lock1',10) |
+----------------------+
|                    1 |
+----------------------+

SELECT IS_FREE_LOCK('lock1'), IS_USED_LOCK('lock1');
+-----------------------+-----------------------+
| IS_FREE_LOCK('lock1') | IS_USED_LOCK('lock1') |
+-----------------------+-----------------------+
|                     0 |                    46 |
+-----------------------+-----------------------+

SELECT IS_FREE_LOCK('lock2'), IS_USED_LOCK('lock2');
+-----------------------+-----------------------+
| IS_FREE_LOCK('lock2') | IS_USED_LOCK('lock2') |
+-----------------------+-----------------------+
|                     1 |                  NULL |
+-----------------------+-----------------------+

Multiple locks can be held:

SELECT GET_LOCK('lock2',10);
+----------------------+
| GET_LOCK('lock2',10) |
+----------------------+
|                    1 |
+----------------------+

SELECT IS_FREE_LOCK('lock1'), IS_FREE_LOCK('lock2');
+-----------------------+-----------------------+
| IS_FREE_LOCK('lock1') | IS_FREE_LOCK('lock2') |
+-----------------------+-----------------------+
|                     0 |                     0 |
+-----------------------+-----------------------+

SELECT RELEASE_LOCK('lock1'), RELEASE_LOCK('lock2');
+-----------------------+-----------------------+
| RELEASE_LOCK('lock1') | RELEASE_LOCK('lock2') |
+-----------------------+-----------------------+
|                     1 |                     1 |
+-----------------------+-----------------------+

It is possible to hold the same lock recursively. This example is viewed using
the metadata_lock_info plugin:

SELECT GET_LOCK('lock3',10);
+----------------------+
| GET_LOCK('lock3',10) |
+----------------------+
|                    1 |
+----------------------+

SELECT GET_LOCK('lock3',10);
+----------------------+
| GET_LOCK('lock3',10) |
+----------------------+
|                    1 |
+----------------------+

SELECT * FROM INFORMATION_SCHEMA.METADATA_LOCK_INFO;
+-----------+---------------------+---------------+-----------+--------------+-
----------+
| THREAD_ID | LOCK_MODE           | LOCK_DURATION | LOCK_TYPE | TABLE_SCHEMA |
TABLE_NAME |
+-----------+---------------------+---------------+-----------+--------------+-
----------+
|        46 | MDL_SHARED_NO_WRITE | NULL          | User lock | lock3        |
     |
+-----------+---------------------+---------------+-----------+--------------+-
----------+

SELECT RELEASE_LOCK('lock3');
+-----------------------+
| RELEASE_LOCK('lock3') |
+-----------------------+
|                     1 |
+-----------------------+

SELECT * FROM INFORMATION_SCHEMA.METADATA_LOCK_INFO;
+-----------+---------------------+---------------+-----------+--------------+-
----------+
| THREAD_ID | LOCK_MODE           | LOCK_DURATION | LOCK_TYPE | TABLE_SCHEMA |
TABLE_NAME |
+-----------+---------------------+---------------+-----------+--------------+-
----------+
|        46 | MDL_SHARED_NO_WRITE | NULL          | User lock | lock3        |
     |
+-----------+---------------------+---------------+-----------+--------------+-
----------+

SELECT RELEASE_LOCK('lock3');
+-----------------------+
| RELEASE_LOCK('lock3') |
+-----------------------+
|                     1 |
+-----------------------+

SELECT * FROM INFORMATION_SCHEMA.METADATA_LOCK_INFO;
Empty set (0.000 sec)

Timeout example: Connection 1:

SELECT GET_LOCK('lock4',10);
+----------------------+
| GET_LOCK('lock4',10) |
+----------------------+
|                    1 |
+----------------------+

Connection 2:

SELECT GET_LOCK('lock4',10);

After 10 seconds...

+----------------------+
| GET_LOCK('lock4',10) |
+----------------------+
|                    0 |
+----------------------+

Deadlocks are automatically detected and resolved. Connection 1:

SELECT GET_LOCK('lock5',10); 
+----------------------+
| GET_LOCK('lock5',10) |
+----------------------+
|                    1 |
+----------------------+

Connection 2:

SELECT GET_LOCK('lock6',10);
+----------------------+
| GET_LOCK('lock6',10) |
+----------------------+
|                    1 |
+----------------------+

Connection 1:

SELECT GET_LOCK('lock6',10); 
+----------------------+
| GET_LOCK('lock6',10) |
+----------------------+
|                    0 |
+----------------------+

Connection 2:

SELECT GET_LOCK('lock5',10);
ERROR 1213 (40001): Deadlock found when trying to get lock; try restarting
transaction

URL: https://mariadb.com/kb/en/get_lock/https://mariadb.com/kb/en/get_lock/��%|Syntax
------

|

Description
-----------

Bitwise OR. Converts the values to binary and compares bits. If either of the
corresponding bits has a value of 1, the resulting bit is also 1.

See also bitwise AND.

Examples
--------

SELECT 2|1;
+-----+
| 2|1 |
+-----+
|   3 |
+-----+

SELECT 29 | 15;
+---------+
| 29 | 15 |
+---------+
|      31 |
+---------+

URL: https://mariadb.com/kb/en/bitwise-or/https://mariadb.com/kb/en/bitwise-or/�
:����-�
%INET6_NTOASyntax
------

INET6_NTOA(expr)

Description
-----------

Given an IPv6 or IPv4 network address as a numeric binary string, returns the
address as a nonbinary string in the connection character set.

The return string is lowercase, and is platform independent, since it does not
use functions specific to the operating system. It has a maximum length of 39
characters.

Returns NULL if the argument is not understood.

Examples
--------

SELECT INET6_NTOA(UNHEX('0A000101'));
+-------------------------------+
| INET6_NTOA(UNHEX('0A000101')) |
+-------------------------------+
| 10.0.1.1                      |
+-------------------------------+

SELECT INET6_NTOA(UNHEX('48F3000000000000D4321431BA23846F'));
+-------------------------------------------------------+
| INET6_NTOA(UNHEX('48F3000000000000D4321431BA23846F')) |
+-------------------------------------------------------+
| 48f3::d432:1431:ba23:846f                             |
+-------------------------------------------------------+

URL: https://mariadb.com/kb/en/inet6_ntoa/https://mariadb.com/kb/en/inet6_ntoa/�r"IS_IPV4Syntax
------

IS_IPV4(expr)

Description
-----------

If the expression is a valid IPv4 address, returns 1, otherwise returns 0.

IS_IPV4() is stricter than INET_ATON(), but as strict as INET6_ATON(), in
determining the validity of an IPv4 address. This implies that if IS_IPV4
returns 1, the same expression will always return a non-NULL result when
passed to INET_ATON(), but that the reverse may not apply.

Examples
--------

SELECT IS_IPV4('1110.0.1.1');
+-----------------------+
| IS_IPV4('1110.0.1.1') |
+-----------------------+
|                     0 |
+-----------------------+

SELECT IS_IPV4('48f3::d432:1431:ba23:846f');
+--------------------------------------+
| IS_IPV4('48f3::d432:1431:ba23:846f') |
+--------------------------------------+
|                                    0 |
+--------------------------------------+

URL: https://mariadb.com/kb/en/is_ipv4/https://mariadb.com/kb/en/is_ipv4/��)IS_IPV4_COMPATSyntax
------

IS_IPV4_COMPAT(expr)

Description
-----------

Returns 1 if a given numeric binary string IPv6 address, such as returned by
INET6_ATON(), is IPv4-compatible, otherwise returns 0.

MariaDB starting with 10.5.0
----------------------------
From MariaDB 10.5.0, when the argument is not INET6, automatic implicit CAST
to INET6 is applied. As a consequence, IS_IPV4_COMPAT now understands
arguments in both text representation and binary(16) representation. Before
MariaDB 10.5.0, the function understood only binary(16) representation.

Examples
--------

SELECT IS_IPV4_COMPAT(INET6_ATON('::10.0.1.1'));
+------------------------------------------+
| IS_IPV4_COMPAT(INET6_ATON('::10.0.1.1')) |
+------------------------------------------+
|                                        1 |
+------------------------------------------+

SELECT IS_IPV4_COMPAT(INET6_ATON('::48f3::d432:1431:ba23:846f'));
+-----------------------------------------------------------+
| IS_IPV4_COMPAT(INET6_ATON('::48f3::d432:1431:ba23:846f')) |
+-----------------------------------------------------------+
|                                                         0 |
+-----------------------------------------------------------+

URL: https://mariadb.com/kb/en/is_ipv4_compat/https://mariadb.com/kb/en/is_ipv4_compat/��)IS_IPV4_MAPPEDSyntax
------

IS_IPV4_MAPPED(expr)

Description
-----------

Returns 1 if a given a numeric binary string IPv6 address, such as returned by
INET6_ATON(), is a valid IPv4-mapped address, otherwise returns 0.

MariaDB starting with 10.5.0
----------------------------
From MariaDB 10.5.0, when the argument is not INET6, automatic implicit CAST
to INET6 is applied. As a consequence, IS_IPV4_MAPPED now understands
arguments in both text representation and binary(16) representation. Before
MariaDB 10.5.0, the function understood only binary(16) representation.

Examples
--------

SELECT IS_IPV4_MAPPED(INET6_ATON('::10.0.1.1'));
+------------------------------------------+
| IS_IPV4_MAPPED(INET6_ATON('::10.0.1.1')) |
+------------------------------------------+
|                                        0 |
+------------------------------------------+

SELECT IS_IPV4_MAPPED(INET6_ATON('::ffff:10.0.1.1'));
+-----------------------------------------------+
| IS_IPV4_MAPPED(INET6_ATON('::ffff:10.0.1.1')) |
+-----------------------------------------------+
|                                             1 |
+-----------------------------------------------+

URL: https://mariadb.com/kb/en/is_ipv4_mapped/https://mariadb.com/kb/en/is_ipv4_mapped/�*MASTER_POS_WAITSyntax
------

MASTER_POS_WAIT(log_name,log_pos[,timeout,["connection_name"]])

Description
-----------

This function is useful in replication for controlling primary/replica
synchronization. It blocks until the replica has read and applied all updates
up to the specified position (log_name,log_pos) in the primary log. The return
value is the number of log events the replica had to wait for to advance to
the specified position. The function returns NULL if the replica SQL thread is
not started, the replica's primary information is not initialized, the
arguments are incorrect, or an error occurs. It returns -1 if the timeout has
been exceeded. If the replica SQL thread stops while MASTER_POS_WAIT() is
waiting, the function returns NULL. If the replica is past the specified
position, the function returns immediately.

If a timeout value is specified, MASTER_POS_WAIT() stops waiting when timeout
seconds have elapsed. timeout must be greater than 0; a zero or negative
timeout means no timeout.

The connection_name is used when you are using multi-source-replication. If
you don't specify it, it's set to the value of the default_master_connection
system variable.

Statements using the MASTER_POS_WAIT() function are not safe for replication.

URL: https://mariadb.com/kb/en/master_pos_wait/https://mariadb.com/kb/en/master_pos_wait/�@&~Syntax
------

~

Description
-----------

Bitwise NOT. Converts the value to 4 bytes binary and inverts all bits.

Examples
--------

SELECT 3 & ~1;
+--------+
| 3 & ~1 |
+--------+
|      2 |
+--------+

SELECT 5 & ~1;
+--------+
| 5 & ~1 |
+--------+
|      4 |
+--------+

URL: https://mariadb.com/kb/en/bitwise-not/https://mariadb.com/kb/en/bitwise-not/�
�%TRUE FALSEDescription
-----------

The constants TRUE and FALSE evaluate to 1 and 0, respectively. The constant
names can be written in any lettercase.

Examples
--------

SELECT TRUE, true, FALSE, false;
+------+------+-------+-------+
| TRUE | TRUE | FALSE | FALSE |
+------+------+-------+-------+
|    1 |    1 |     0 |     0 |
+------+------+-------+-------+

URL: https://mariadb.com/kb/en/true-false/https://mariadb.com/kb/en/true-false/�
�%CHECK VIEWSyntax
------

CHECK VIEW view_name

Description
-----------

The CHECK VIEW statement was introduced in MariaDB 10.0.18 to assist with
fixing MDEV-6916, an issue introduced in MariaDB 5.2 where the view algorithms
were swapped. It checks whether the view algorithm is correct. It is run as
part of mariadb-upgrade, and should not normally be required in regular use.

URL: https://mariadb.com/kb/en/check-view/https://mariadb.com/kb/en/check-view/����u8_;
�7[�O��1� �Y+MASTER_GTID_WAITSyntax
------

MASTER_GTID_WAIT(gtid-list[, timeout)

Description
-----------

This function takes a string containing a comma-separated list of global
transaction id's (similar to the value of, for example, gtid_binlog_pos). It
waits until the value of gtid_slave_pos has the same or higher seq_no within
all replication domains specified in the gtid-list; in other words, it waits
until the slave has reached the specified GTID position.

An optional second argument gives a timeout in seconds. If the timeout expires
before the specified GTID position is reached, then the function returns -1.
Passing NULL or a negative number for the timeout means no timeout, and the
function will wait indefinitely.

If the wait completes without a timeout, 0 is returned. Passing NULL for the
gtid-list makes the function return NULL immediately, without waiting.

The gtid-list may be the empty string, in which case MASTER_GTID_WAIT()
returns immediately. If the gtid-list contains fewer domains than
gtid_slave_pos, then only those domains are waited upon. If gtid-list contains
a domain that is not present in @@gtid_slave_pos, then MASTER_GTID_WAIT() will
wait until an event containing such domain_id arrives on the slave (or until
timed out or killed).

MASTER_GTID_WAIT() can be useful to ensure that a slave has caught up to a
master. Simply take the value of gtid_binlog_pos on the master, and use it in
a MASTER_GTID_WAIT() call on the slave; when the call completes, the slave
will have caught up with that master position.

MASTER_GTID_WAIT() can also be used in client applications together with the
last_gtid session variable. This is useful in a read-scaleout replication
setup, where the application writes to a single master but divides the reads
out to a number of slaves to distribute the load. In such a setup, there is a
risk that an application could first do an update on the master, and then a
bit later do a read on a slave, and if the slave is not fast enough, the data
read from the slave might not include the update just made, possibly confusing
the application and/or the end-user. One way to avoid this is to request the
value of last_gtid on the master just after the update. Then before doing the
read on the slave, do a MASTER_GTID_WAIT() on the value obtained from the
master; this will ensure that the read is not performed until the slave has
replicated sufficiently far for the update to have become visible.

Note that MASTER_GTID_WAIT() can be used even if the slave is configured not
to use GTID for connections (CHANGE MASTER TO master_use_gtid=no). This is
because from MariaDB 10, GTIDs are always logged on the master server, and
always recorded on the slave servers.

Differences to MASTER_POS_WAIT()
--------------------------------

* MASTER_GTID_WAIT() is global; it waits for any master connection to reach
 the specified GTID position. MASTER_POS_WAIT() works only against a
 specific connection. This also means that while MASTER_POS_WAIT() aborts if
 its master connection is terminated with STOP SLAVE or due to an error,
 MASTER_GTID_WAIT() continues to wait while slaves are stopped.

* MASTER_GTID_WAIT() can take its timeout as a floating-point value, so a
 timeout in fractional seconds is supported, eg. MASTER_GTID_WAIT("0-1-100",
 0.5). (The minimum wait is one microsecond, 0.000001 seconds).

* MASTER_GTID_WAIT() allows one to specify a timeout of zero in order to do a
 non-blocking check to see if the slaves have progressed to a specific GTID
position
 (MASTER_POS_WAIT() takes a zero timeout as meaning an infinite wait). To do
 an infinite MASTER_GTID_WAIT(), specify a negative timeout, or omit the
 timeout argument.

* MASTER_GTID_WAIT() does not return the number of events executed since the
 wait started, nor does it return NULL if a slave thread is stopped. It
 always returns either 0 for successful wait completed, or -1 for timeout
 reached (or NULL if the specified gtid-pos is NULL).

Since MASTER_GTID_WAIT() looks only at the seq_no part of the GTIDs, not the
server_id, care is needed if a slave becomes diverged from another server so
that two different GTIDs with the same seq_no (in the same domain) arrive at
the same server. This situation is in any case best avoided; setting
gtid_strict_mode is recommended, as this will prevent any such out-of-order
sequence numbers from ever being replicated on a slave.

URL: https://mariadb.com/kb/en/master_gtid_wait/https://mariadb.com/kb/en/master_gtid_wait/�v,RELEASE_ALL_LOCKSMariaDB until 10.5.2
--------------------
RELEASE_ALL_LOCKS was added in MariaDB 10.5.2.

Syntax
------

RELEASE_ALL_LOCKS()

Description
-----------

Releases all named locks held by the current session. Returns the number of
locks released, or 0 if none were held.

Statements using the RELEASE_ALL_LOCKS function are not safe for
statement-based replication.

Examples
--------

SELECT RELEASE_ALL_LOCKS();
+---------------------+
| RELEASE_ALL_LOCKS() | 
+---------------------+
|                   0 |
+---------------------+

SELECT GET_LOCK('lock1',10);
+----------------------+
| GET_LOCK('lock1',10) |
+----------------------+
|                    1 |
+----------------------+

SELECT RELEASE_ALL_LOCKS();
+---------------------+
| RELEASE_ALL_LOCKS() | 
+---------------------+
|                   1 |
+---------------------+

URL: https://mariadb.com/kb/en/release_all_locks/https://mariadb.com/kb/en/release_all_locks/�3BLOB and TEXT Data TypesDescription
-----------

A BLOB is a binary large object that can hold a variable amount of data. The
four BLOB types are

* TINYBLOB,
* BLOB, 
* MEDIUMBLOB, and
* LONGBLOB.

These differ only in the maximum length of the values they can hold.

The TEXT types are

* TINYTEXT,
* TEXT,
* MEDIUMTEXT, and
* LONGTEXT.
* JSON (alias for LONGTEXT)

These correspond to the four BLOB types and have the same maximum lengths and
storage requirements.

BLOB and TEXT columns can have a DEFAULT value.

MariaDB starting with 10.4.3
----------------------------
From MariaDB 10.4, it is possible to set a unique index on columns that use
the BLOB or TEXT data types.

URL: https://mariadb.com/kb/en/blob-and-text-data-types/https://mariadb.com/kb/en/blob-and-text-data-types/	�$CHAR BYTEDescription
-----------

The CHAR BYTE data type is an alias for the BINARY data type. This is a
compatibility feature.

URL: https://mariadb.com/kb/en/char-byte/https://mariadb.com/kb/en/char-byte/�+@
��; INET6
%MEDIUMBLOBSyntax
------

MEDIUMBLOB

Description
-----------

A BLOB column with a maximum length of 16,777,215 (224 - 1) bytes. Each
MEDIUMBLOB value is stored using a three-byte length prefix that indicates the
number of bytes in the value.

URL: https://mariadb.com/kb/en/mediumblob/https://mariadb.com/kb/en/mediumblob/
�%MEDIUMTEXTSyntax
------

MEDIUMTEXT [CHARACTER SET charset_name] [COLLATE collation_name]

Description
-----------

A TEXT column with a maximum length of 16,777,215 (224 - 1) characters. The
effective maximum length is less if the value contains multi-byte characters.
Each MEDIUMTEXT value is stored using a three-byte length prefix that
indicates the number of bytes in the value.

URL: https://mariadb.com/kb/en/mediumtext/https://mariadb.com/kb/en/mediumtext/���Qo"��o#���a��iMariaDB starting with 10.5.0
----------------------------
The INET6 data type was added in MariaDB 10.5.0

Syntax
------

INET6

Description
-----------

The INET6 data type is intended for storage of IPv6 addresses, as well as IPv4
addresses assuming conventional mapping of IPv4 addresses into IPv6 addresses.

Both short and long IPv6 notation are permitted, according to RFC-5952.

* Values are stored as a 16-byte fixed length binary string, with most
significant byte first.
* Storage engines see INET6 as BINARY(16).
* Clients see INET6 as CHAR(39) and get text representation on retrieval.

The IPv4-compatible notation is considered as deprecated. It is supported for
compatibility with the INET6_ATON function, which also understands this
format. It's recommended to use the mapped format to store IPv4 addresses in
INET6.

When an IPv4 mapped (or compatible) value is stored in INET6, it still
occupies 16 bytes:

Retrieval
---------

On retrieval, in the client-server text protocol, INET6 values are converted
to the short text representation, according to RFC-5952, that is with all
leading zeroes in each group removed and with consequent zero groups
compressed.

Besides creating one's own stored function, there is no a way to retrieve an
INET6 value using long text representation.

Casting
-------

* CAST from a character string to INET6 understands addresses in short or long
text notation (including IPv4 mapped and compatible addresses). NULL is
returned if the format is not understood.
* CAST from a binary string to INET6 requires a 16-byte string as an argument.
NULL is returned if the argument length is not equal to 16.
* CAST from other data types to INET6 first converts data to a character
string, then CAST from character string to INET6 is applied.
* CAST from INET6 to CHAR returns short text address notation.
* CAST from INET6 to BINARY returns its 16-byte binary string representation.
* CAST from INET6 to data types other than CHAR (e.g. SIGNED, UNSIGNED, TIME,
etc) returns an error.

Comparisons
-----------

An INET6 expression can be compared to:

* another INET6 expression
* a character string expression with a text (short or long) address
representation:
* a 16-byte binary string expression:

Attempting to compare INET6 to an expression of any other data type returns an
error.

Mixing INET6 Values for Result
------------------------------

An INET6 expression can be mixed for result (i.e. UNION, CASE..THEN, COALESCE
etc) with:

* another INET6 expression. The resulting data type is INET6.
* a character string in text (short or long) address representation. The
result data type is INET6. The character string counterpart is automatically
converted to INET6. If the string format is not understood, it's converted
with a warning to either NULL or to '::', depending on the NULL-ability of the
result.
* a 16-byte binary string. The resulting data type is INET6. The binary string
counterpart is automatically converted to INET6. If the length of the binary
string is not equal to 16, it's converted with a warning to NULL or to '::'
depending on the NULL-ability of the result.

Attempts to mix INET6 for result with other data types will return an error.

Mixing INET6 with other data types for LEAST and GREATEST, when mixing for
comparison and mixing for result are involved at the same time, uses the same
rules with mixing for result, described in the previous paragraphs.

Functions and Operators
-----------------------

* HEX() with an INET6 argument returns a hexadecimal representation of the
underlying 16-byte binary string
* Arithmetic operators (+,-,*,/,MOD,DIV) are not supported for INET6. This may
change in the future.
* The INET6_ATON function now understands INET6 values as an argument
* The prototypes of the IS_IPV4_COMPAT and IS_IPV4_MAPPED functions have
changed from a BINARY(16) to a INET6,
* When the argument for these two functions is not INET6, automatic implicit
CAST to INET6 is applied. As a consequence, both functions now understand
arguments in both text representation and binary(16) representation. Before
MariaDB 10.5.0, these functions understood only binary(16) representation.

Prepared Statement Parameters
-----------------------------

INET6 understands both text and binary(16) address representation in prepared
statement parameters (PREPARE..EXECUTE and EXECUTE IMMEDIATE statements).

Migration between  BINARY(16) and INET6
---------------------------------------

Before MariaDB 10.5.0, you may have used BINARY(16) as a storage for IPv6
internet addresses, in combination with INET6_ATON and INET6_NTOA to
respectively insert and retrieve data.

From 10.5, you can ALTER BINARY(16) columns storing IPv6 addresses to INET6.
After such an alter, there is no a need to use INET6_ATON() and INET6_NTOA().
Addresses can be inserted and retrieved directly.

It is also possible to convert INET6 columns to BINARY(16) and continue using
the data in combination with INET6_NTOA() and INET6_ATON().

Examples
--------

CREATE TABLE t1 (a INET6);

Inserting using short text address notation:

INSERT INTO t1 VALUES ('2001:db8::ff00:42:8329');

Long text address notation:

INSERT INTO t1 VALUES ('2001:0db8:0000:0000:0000:ff00:0042:8329');

16-byte binary string notation:

INSERT INTO t1 VALUES (0x20010DB8000000000000FF0000428329);
INSERT INTO t1 VALUES (UNHEX('20010DB8000000000000FF0000428329'));

IPv4 addresses, using IPv4-mapped and IPv4-compatible notations:

INSERT INTO t1 VALUES ('::ffff:192.0.2.128'); -- mapped
INSERT INTO t1 VALUES ('::192.0.2.128'); -- compatible

SELECT * FROM t1;
+------------------------+
| a                      |
+------------------------+
| 2001:db8::ff00:42:8329 |
| 2001:db8::ff00:42:8329 |
| 2001:db8::ff00:42:8329 |
| 2001:db8::ff00:42:8329 |
| ::ffff:192.0.2.128     |
| ::192.0.2.128          |
+------------------------+

IPv4 mapped (or compatible) values still occupy 16 bytes:

CREATE OR REPLACE TABLE t1 (a INET6);

INSERT INTO t1 VALUES ('::ffff:192.0.2.128');

SELECT * FROM t1;
+--------------------+
| a                  |
+--------------------+
| ::ffff:192.0.2.128 |
+--------------------+

SELECT HEX(a) FROM t1;
+----------------------------------+
| HEX(a)                           |
+----------------------------------+
| 00000000000000000000FFFFC0000280 |
+----------------------------------+

Casting from INET6 to anything other than CHAR returns an error:

SELECT CAST(a AS DECIMAL) FROM t1;

ERROR 4079 (HY000): Illegal parameter data type inet6 for operation
'decimal_typecast'

Comparison Examples
-------------------

Comparison with another INET6 expression:

CREATE OR REPLACE TABLE t1 (a INET6);
  CREATE OR REPLACE TABLE t2 (a INET6);

INSERT INTO t1 VALUES
('2001:db8::ff00:42:8328'),('2001:db8::ff00:42:8329');
  INSERT INTO t2 VALUES
('2001:db8::ff00:42:832a'),('2001:db8::ff00:42:8329');

SELECT t1.* FROM t1,t2 WHERE t1.a=t2.a;
  +------------------------+
  | a                      |
  +------------------------+
  | 2001:db8::ff00:42:8329 |
  +------------------------+

With a character string expression with a text (short or long) address
representation:

CREATE OR REPLACE TABLE t1 (a INET6);

INSERT INTO t1 VALUES ('2001:db8::ff00:42:8329');

SELECT * FROM t1 WHERE a='2001:db8::ff00:42:8329';
  +------------------------+
  | a                      |
  +------------------------+
  | 2001:db8::ff00:42:8329 |
  +------------------------+

With a 16-byte binary string expression:

CREATE OR REPLACE TABLE t1 (a INET6);

INSERT INTO t1 VALUES ('2001:db8::ff00:42:8329');

SELECT * FROM t1 WHERE a=X'20010DB8000000000000FF0000428329';
  +------------------------+
  | a                      |
  +------------------------+
  | 2001:db8::ff00:42:8329 |
  +------------------------+

With an expression of another data type:

SELECT * FROM t1 WHERE a=1;
ERROR 4078 (HY000): Illegal parameter data types inet6 and int for operation
'='

Mixing for Result Examples
--------------------------

Mixed with another INET6 expression, returning an INET6 data type:

CREATE OR REPLACE TABLE t1 (a INET6, b INET6);

INSERT INTO t1 VALUES (NULL,'2001:db8::ff00:42:8329');

SELECT a FROM t1 UNION SELECT b F��|ROM t1;
  +------------------------+
  | a                      |
  +------------------------+
  | NULL                   |
  | 2001:db8::ff00:42:8329 |
  +------------------------+

SELECT COALESCE(a, b) FROM t1;
  +------------------------+
  | COALESCE(a, b)         |
  +------------------------+
  | 2001:db8::ff00:42:8329 |
  +------------------------+

Mixed with a character string in text (short or long) address representation:

CREATE OR REPLACE TABLE t1 (a INET6, b VARCHAR(64));

INSERT INTO t1 VALUES (NULL,'2001:db8::ff00:42:8328');

INSERT INTO t1 VALUES (NULL,'2001:db8::ff00:42:832a garbage');

SELECT COALESCE(a,b) FROM t1;
  +------------------------+
  | COALESCE(a,b)          |
  +------------------------+
  | 2001:db8::ff00:42:8328 |
  | NULL                   |
  +------------------------+
  2 rows in set, 1 warning (0.001 sec)

SHOW WARNINGS;

+---------+------+---------------------------------------------------------+
  | Level   | Code | Message
|

+---------+------+---------------------------------------------------------+
  | Warning | 1292 | Incorrect inet6 value: '2001:db8::ff00:42:832a garbage'
|

+---------+------+---------------------------------------------------------+

Mixed with a 16-byte binary string:

CREATE OR REPLACE TABLE t1 (a INET6, b VARBINARY(16));

INSERT INTO t1 VALUES (NULL,CONCAT(0xFFFF,REPEAT(0x0000,6),0xFFFF));

INSERT INTO t1 VALUES (NULL,0x00/*garbage*/);

SELECT COALESCE(a,b) FROM t1;
  +---------------+
  | COALESCE(a,b) |
  +---------------+
  | ffff::ffff    |
  | NULL          |
  +---------------+
  2 rows in set, 1 warning (0.001 sec)

SHOW WARNINGS;
  +---------+------+-------------------------------+
  | Level   | Code | Message                       |
  +---------+------+-------------------------------+
  | Warning | 1292 | Incorrect inet6 value: '\x00' |
  +---------+------+-------------------------------+

Mixing with other data types:

SELECT CAST('ffff::ffff' AS INET6) UNION SELECT 1;
ERROR 4078 (HY000): Illegal parameter data types inet6 and int for operation
'UNION'

Functions and Operators Examples
--------------------------------

HEX with an INET6 argument returning a hexadecimal representation:

SELECT HEX(CAST('2001:db8::ff00:42:8329' AS INET6));
  +----------------------------------------------+
  | HEX(CAST('2001:db8::ff00:42:8329' AS INET6)) |
  +----------------------------------------------+
  | 20010DB8000000000000FF0000428329             |
  +----------------------------------------------+

INET6_ATON now understands INET6 values as an argument:

CREATE OR REPLACE TABLE t1 (a INET6);

INSERT INTO t1 VALUES ('2001:db8::ff00:42:8329');

SELECT a, HEX(INET6_ATON(a)) FROM t1;
  +------------------------+----------------------------------+
  | a                      | HEX(INET6_ATON(a))               |
  +------------------------+----------------------------------+
  | 2001:db8::ff00:42:8329 | 20010DB8000000000000FF0000428329 |
  +------------------------+----------------------------------+

IS_IPV4_COMPAT and IS_IPV4_MAPPED prototype now a BINARY(16)):

CREATE OR REPLACE TABLE t1 (a INET6);

INSERT INTO t1 VALUES ('2001:db8::ff00:42:8329');
  INSERT INTO t1 VALUES ('::ffff:192.168.0.1');
  INSERT INTO t1 VALUES ('::192.168.0.1');

SELECT a, IS_IPV4_MAPPED(a), IS_IPV4_COMPAT(a) FROM t1;
  +------------------------+-------------------+-------------------+
  | a                      | IS_IPV4_MAPPED(a) | IS_IPV4_COMPAT(a) |
  +------------------------+-------------------+-------------------+
  | 2001:db8::ff00:42:8329 |                 0 |                 0 |
  | ::ffff:192.168.0.1     |                 1 |                 0 |
  | ::192.168.0.1          |                 0 |                 1 |
  +------------------------+-------------------+-------------------+

Automatic implicit CAST to INET6:

CREATE OR REPLACE TABLE t1 (
   a INET6,
   b VARCHAR(39) DEFAULT a
  );

INSERT INTO t1 (a) VALUES ('ffff::ffff'),('::ffff:192.168.0.1');

SELECT a, IS_IPV4_MAPPED(a), b, IS_IPV4_MAPPED(b) FROM t1;

+--------------------+-------------------+--------------------+----------------
--+
  | a                  | IS_IPV4_MAPPED(a) | b                  |
IS_IPV4_MAPPED(b) |

+--------------------+-------------------+--------------------+----------------
--+
  | ffff::ffff         |                 0 | ffff::ffff         |
  0 |
  | ::ffff:192.168.0.1 |                 1 | ::ffff:192.168.0.1 |
  1 |

+--------------------+-------------------+--------------------+----------------
--+

CREATE OR REPLACE TABLE t1 (
   a INET6,
   b BINARY(16) DEFAULT UNHEX(HEX(a))
  );

INSERT INTO t1 (a) VALUES ('ffff::ffff'),('::ffff:192.168.0.1');

SELECT a, IS_IPV4_MAPPED(a), HEX(b), IS_IPV4_MAPPED(b) FROM t1;

+--------------------+-------------------+----------------------------------+--
----------------+
  | a                  | IS_IPV4_MAPPED(a) | HEX(b)
 | IS_IPV4_MAPPED(b) |

+--------------------+-------------------+----------------------------------+--
----------------+
  | ffff::ffff         |                 0 |
FFFF000000000000000000000000FFFF |                 0 |
  | ::ffff:192.168.0.1 |                 1 |
00000000000000000000FFFFC0A80001 |                 1 |

+--------------------+-------------------+----------------------------------+--
----------------+

Prepared Statement Parameters Examples
--------------------------------------

CREATE OR REPLACE TABLE t1 (a INET6);

EXECUTE IMMEDIATE 'INSERT INTO t1 VALUES (?)' USING 'ffff::fffe';
EXECUTE IMMEDIATE 'INSERT INTO t1 VALUES (?)' USING
X'FFFF000000000000000000000000FFFF';

SELECT * FROM t1;
+------------+
| a          |
+------------+
| ffff::fffe |
| ffff::ffff |
+------------+

EXECUTE IMMEDIATE 'SELECT * FROM t1 WHERE a=?' USING 'ffff::fffe';
+------------+
| a          |
+------------+
| ffff::fffe |
+------------+

EXECUTE IMMEDIATE 'SELECT * FROM t1 WHERE a=?' USING
X'FFFF000000000000000000000000FFFF';
+------------+
| a          |
+------------+
| ffff::ffff |
+------------+

Migration between BINARY(16) and INET6 Examples
-----------------------------------------------

Before MariaDB 10.5:

CREATE OR REPLACE TABLE t1 (a BINARY(16));

INSERT INTO t1 VALUES (INET6_ATON('ffff::ffff'));

SELECT INET6_NTOA(a) FROM t1;
+---------------+
| INET6_NTOA(a) |
+---------------+
| ffff::ffff    |
+---------------+

Migrating to INET6, from MariaDB 10.5:

ALTER TABLE t1 MODIFY a INET6;

INSERT INTO t1 VALUES ('ffff::fffe');

SELECT * FROM t1;
+------------+
| a          |
+------------+
| ffff::ffff |
| ffff::fffe |
+------------+

Migration from INET6 to BINARY(16):

CREATE OR REPLACE TABLE t1 (a INET6);

INSERT INTO t1 VALUES ('2001:db8::ff00:42:8329');
INSERT INTO t1 VALUES ('::ffff:192.168.0.1');
INSERT INTO t1 VALUES ('::192.168.0.1');

ALTER TABLE t1 MODIFY a BINARY(16);

SELECT INET6_NTOA(a) FROM t1;
+------------------------+
| INET6_NTOA(a)          |
+------------------------+
| 2001:db8::ff00:42:8329 |
| ::ffff:192.168.0.1     |
| ::192.168.0.1          |
+------------------------+

URL: https://mariadb.com/kb/en/inet6/��	���5
'RELEASE_LOCKSyntax
------

RELEASE_LOCK(str)

Description
-----------

Releases the lock named by the string str that was obtained with GET_LOCK().
Returns 1 if the lock was released, 0 if the lock was not established by this
thread (in which case the lock is not released), and NULL if the named lock
did not exist. The lock does not exist if it was never obtained by a call to
GET_LOCK() or if it has previously been released.

str is case insensitive. If str is an empty string or NULL, RELEASE_LOCK()
returns NULL and does nothing.

Statements using the RELEASE_LOCK() function are not safe for replication.

The DO statement is convenient to use with RELEASE_LOCK().

Examples
--------

Connection1:

SELECT GET_LOCK('lock1',10);
+----------------------+
| GET_LOCK('lock1',10) |
+----------------------+
|                    1 |
+----------------------+

Connection 2:

SELECT GET_LOCK('lock2',10);
+----------------------+
| GET_LOCK('lock2',10) |
+----------------------+
|                    1 |
+----------------------+

Connection 1:

SELECT RELEASE_LOCK('lock1'), RELEASE_LOCK('lock2'), RELEASE_LOCK('lock3');
+-----------------------+-----------------------+-----------------------+
| RELEASE_LOCK('lock1') | RELEASE_LOCK('lock2') | RELEASE_LOCK('lock3') |
+-----------------------+-----------------------+-----------------------+
|                     1 |                     0 |                  NULL |
+-----------------------+-----------------------+-----------------------+

From MariaDB 10.0.2, it is possible to hold the same lock recursively. This
example is viewed using the metadata_lock_info plugin:

SELECT GET_LOCK('lock3',10);
+----------------------+
| GET_LOCK('lock3',10) |
+----------------------+
|                    1 |
+----------------------+

SELECT GET_LOCK('lock3',10);
+----------------------+
| GET_LOCK('lock3',10) |
+----------------------+
|                    1 |
+----------------------+

SELECT * FROM INFORMATION_SCHEMA.METADATA_LOCK_INFO;
+-----------+---------------------+---------------+-----------+--------------+-
----------+
| THREAD_ID | LOCK_MODE           | LOCK_DURATION | LOCK_TYPE | TABLE_SCHEMA |
TABLE_NAME |
+-----------+---------------------+---------------+-----------+--------------+-
----------+
|        46 | MDL_SHARED_NO_WRITE | NULL          | User lock | lock3        |
     |
+-----------+---------------------+---------------+-----------+--------------+-
----------+

SELECT RELEASE_LOCK('lock3');
+-----------------------+
| RELEASE_LOCK('lock3') |
+-----------------------+
|                     1 |
+-----------------------+

SELECT * FROM INFORMATION_SCHEMA.METADATA_LOCK_INFO;
+-----------+---------------------+---------------+-----------+--------------+-
----------+
| THREAD_ID | LOCK_MODE           | LOCK_DURATION | LOCK_TYPE | TABLE_SCHEMA |
TABLE_NAME |
+-----------+---------------------+---------------+-----------+--------------+-
----------+
|        46 | MDL_SHARED_NO_WRITE | NULL          | User lock | lock3        |
     |
+-----------+---------------------+---------------+-----------+--------------+-
----------+

SELECT RELEASE_LOCK('lock3');
+-----------------------+
| RELEASE_LOCK('lock3') |
+-----------------------+
|                     1 |
+-----------------------+

SELECT * FROM INFORMATION_SCHEMA.METADATA_LOCK_INFO;
Empty set (0.000 sec)

URL: https://mariadb.com/kb/en/release_lock/https://mariadb.com/kb/en/release_lock/��UUIDSyntax
------

UUID()

Description
-----------

Returns a Universally Unique Identifier (UUID).

A UUID is designed as a number that is globally unique in space and time. Two
calls to UUID() are expected to generate two different values, even if these
calls are performed on two separate computers that are not connected to each
other.

UUID() results are intended to be unique, but cannot always be relied upon to
unpredictable and unguessable, so should not be relied upon for these purposes.

A UUID is a 128-bit number represented by a utf8 string of five hexadecimal
numbers in aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee format:

* The first three numbers are generated from a timestamp.
* The fourth number preserves temporal uniqueness in case the timestamp value
 loses monotonicity (for example, due to daylight saving time).
* The fifth number is an IEEE 802 node number that provides spatial uniqueness.
 A random number is substituted if the latter is not available (for example,
 because the host computer has no Ethernet card, or we do not know how to find
 the hardware address of an interface on your operating system). In this case,
 spatial uniqueness cannot be guaranteed. Nevertheless, a collision should
 have very low probability.

Currently, the MAC address of an interface is taken into account only on
FreeBSD and Linux. On other operating systems, MariaDB uses a randomly
generated 48-bit number.

Statements using the UUID() function are not safe for replication.

The results are generated according to the "DCE 1.1:Remote Procedure Call"
(Appendix A) CAE (Common Applications Environment) Specifications published by
The Open Group in October 1997 (Document Number C706).

Examples
--------

SELECT UUID();
+--------------------------------------+
| UUID()                               |
+--------------------------------------+
| cd41294a-afb0-11df-bc9b-00241dd75637 |
+--------------------------------------+

URL: https://mariadb.com/kb/en/uuid/https://mariadb.com/kb/en/uuid/<#LONGBLOBSyntax
------

LONGBLOB

Description
-----------

A BLOB column with a maximum length of 4,294,967,295 bytes or 4GB (232 - 1).
The effective maximum length of LONGBLOB columns depends on the configured
maximum packet size in the client/server protocol and available memory. Each
LONGBLOB value is stored using a four-byte length prefix that indicates the
number of bytes in the value.

Oracle Mode
-----------

MariaDB starting with 10.3
--------------------------
In Oracle mode from MariaDB 10.3, BLOB is a synonym for LONGBLOB.

URL: https://mariadb.com/kb/en/longblob/https://mariadb.com/kb/en/longblob/#TINYBLOBSyntax
------

TINYBLOB

Description
-----------

A BLOB column with a maximum length of 255 (28 - 1) bytes. Each TINYBLOB value
is stored using a one-byte length prefix that indicates the number of bytes in
the value.

URL: https://mariadb.com/kb/en/tinyblob/https://mariadb.com/kb/en/tinyblob/�#TINYTEXTSyntax
------

TINYTEXT [CHARACTER SET charset_name] [COLLATE collation_name]

Description
-----------

A TEXT column with a maximum length of 255 (28 - 1) characters. The effective
maximum length is less if the value contains multi-byte characters. Each
TINYTEXT value is stored using a one-byte length prefix that indicates the
number of bytes in the value.

URL: https://mariadb.com/kb/en/tinytext/https://mariadb.com/kb/en/tinytext/!
:(SET Data TypeSyntax
------

SET('value1','value2',...) [CHARACTER SET charset_name] [COLLATE
collation_name]

Description
-----------

A set. A string object that can have zero or more values, each of which must
be chosen from the list of values 'value1', 'value2', ... A SET column can
have a maximum of 64 members. SET values are represented internally as
integers.

SET values cannot contain commas.

If a SET contains duplicate values, an error will be returned if strict mode
is enabled, or a warning if strict mode is not enabled.

URL: https://mariadb.com/kb/en/set-data-type/https://mariadb.com/kb/en/set-data-type/�}��=gu�
�v
�Z��,�

%UUID_SHORTSyntax
------

UUID_SHORT()

Description
-----------

Returns a "short" universally unique identifier as a 64-bit unsigned integer
(rather than a string-form 128-bit identifier as returned by the UUID()
function).

The value of UUID_SHORT() is guaranteed to be unique if the following
conditions hold:

* The server_id of the current host is unique among your set of master and
 slave servers
* server_id is between 0 and 255
* You don't set back your system time for your server between mysqld restarts
* You do not invoke UUID_SHORT() on average more than 16
 million times per second between mysqld restarts

The UUID_SHORT() return value is constructed this way:

(server_id & 255) << 56
+ (server_startup_time_in_seconds << 24)
+ incremented_variable++;

Statements using the UUID_SHORT() function are not safe for statement-based
replication.

Examples
--------

SELECT UUID_SHORT();
+-------------------+
| UUID_SHORT()      |
+-------------------+
| 21517162376069120 |
+-------------------+

create table t1 (a bigint unsigned default(uuid_short()) primary key);
insert into t1 values(),();
select * from t1;
+-------------------+
| a                 |
+-------------------+
| 98113699159474176 |
| 98113699159474177 |
+-------------------+

URL: https://mariadb.com/kb/en/uuid_short/https://mariadb.com/kb/en/uuid_short/�U'VALUES / VALUESyntax
------

MariaDB starting with 10.3.3
----------------------------

VALUE(col_name)

MariaDB until 10.3.2
--------------------

VALUES(col_name)

Description
-----------

In an INSERT ... ON DUPLICATE KEY UPDATE statement, you can use the
VALUES(col_name) function in the UPDATE clause to refer to column values from
the INSERT portion of the statement. In other words, VALUES(col_name) in the
UPDATE clause refers to the value of col_name that would be inserted, had no
duplicate-key conflict occurred. This function is especially useful in
multiple-row inserts.

The VALUES() function is meaningful only in INSERT ... ON DUPLICATE KEY UPDATE
statements and returns NULL otherwise.

In MariaDB 10.3.3 this function was renamed to VALUE(), because it's
incompatible with the standard Table Value Constructors syntax, implemented in
MariaDB 10.3.3.

The VALUES() function can still be used even from MariaDB 10.3.3, but only in
INSERT ... ON DUPLICATE KEY UPDATE statements; it's a syntax error otherwise.

Examples
--------

MariaDB starting with 10.3.3
----------------------------

INSERT INTO t (a,b,c) VALUES (1,2,3),(4,5,6)
  ON DUPLICATE KEY UPDATE c=VALUE(a)+VALUE(b);

MariaDB until 10.3.2
--------------------

INSERT INTO t (a,b,c) VALUES (1,2,3),(4,5,6)
  ON DUPLICATE KEY UPDATE c=VALUES(a)+VALUES(b);

URL: https://mariadb.com/kb/en/values-value/https://mariadb.com/kb/en/values-value/��||Syntax
------

OR, ||

Description
-----------

Logical OR. When both operands are non-NULL, the result is 1 if any operand is
non-zero, and 0 otherwise. With a NULL operand, the result is 1 if the other
operand is non-zero, and NULL otherwise. If both operands are NULL, the result
is NULL.

For this operator, short-circuit evaluation can be used.

Note that, if the PIPES_AS_CONCAT SQL_MODE is set, || is used as a string
concatenation operator. This means that a || b is the same as CONCAT(a,b). See
CONCAT() for details.

Oracle Mode
-----------

MariaDB starting with 10.3
--------------------------
In Oracle mode from MariaDB 10.3, || ignores NULL.

Examples
--------

SELECT 1 || 1;
+--------+
| 1 || 1 |
+--------+
|      1 |
+--------+

SELECT 1 || 0;
+--------+
| 1 || 0 |
+--------+
|      1 |
+--------+

SELECT 0 || 0;
+--------+
| 0 || 0 |
+--------+
|      0 |
+--------+

SELECT 0 || NULL;
+-----------+
| 0 || NULL |
+-----------+
|      NULL |
+-----------+

SELECT 1 || NULL;
+-----------+
| 1 || NULL |
+-----------+
|         1 |
+-----------+

In Oracle mode, from MariaDB 10.3:

SELECT 0 || NULL;
+-----------+
| 0 || NULL |
+-----------+
| 0         |
+-----------+

URL: https://mariadb.com/kb/en/or/https://mariadb.com/kb/en/or/��
AVGSyntax
------

AVG([DISTINCT] expr)

Description
-----------

Returns the average value of expr. The DISTINCT option can be used to return
the average of the distinct values of expr. NULL values are ignored. It is an
aggregate function, and so can be used with the GROUP BY clause.

AVG() returns NULL if there were no matching rows.

AVG() can be used as a window function.

Examples
--------

CREATE TABLE sales (sales_value INT);

INSERT INTO sales VALUES(10),(20),(20),(40);

SELECT AVG(sales_value) FROM sales;
+------------------+
| AVG(sales_value) |
+------------------+
|          22.5000 |
+------------------+

SELECT AVG(DISTINCT(sales_value)) FROM sales;
+----------------------------+
| AVG(DISTINCT(sales_value)) |
+----------------------------+
|                    23.3333 |
+----------------------------+

Commonly, AVG() is used with a GROUP BY clause:

CREATE TABLE student (name CHAR(10), test CHAR(10), score TINYINT);

INSERT INTO student VALUES 
 ('Chun', 'SQL', 75), ('Chun', 'Tuning', 73),
 ('Esben', 'SQL', 43), ('Esben', 'Tuning', 31),
 ('Kaolin', 'SQL', 56), ('Kaolin', 'Tuning', 88),
 ('Tatiana', 'SQL', 87), ('Tatiana', 'Tuning', 83);

SELECT name, AVG(score) FROM student GROUP BY name;
+---------+------------+
| name    | AVG(score) |
+---------+------------+
| Chun    |    74.0000 |
| Esben   |    37.0000 |
| Kaolin  |    72.0000 |
| Tatiana |    85.0000 |
+---------+------------+

Be careful to avoid this common mistake, not grouping correctly and returning
mismatched data:

SELECT name,test,AVG(score) FROM student;
+------+------+------------+
| name | test | MIN(score) |
+------+------+------------+
| Chun | SQL  |         31 |
+------+------+------------+

As a window function:

CREATE TABLE student_test (name CHAR(10), test CHAR(10), score TINYINT);

INSERT INTO student_test VALUES 
  ('Chun', 'SQL', 75), ('Chun', 'Tuning', 73),
  ('Esben', 'SQL', 43), ('Esben', 'Tuning', 31),
  ('Kaolin', 'SQL', 56), ('Kaolin', 'Tuning', 88),
  ('Tatiana', 'SQL', 87), ('Tatiana', 'Tuning', 83);

SELECT name, test, score, AVG(score) OVER (PARTITION BY test) 
  AS average_by_test FROM student_test;
+---------+--------+-------+-----------------+
| name    | test   | score | average_by_test |
+---------+--------+-------+-----------------+
| Chun    | SQL    |    75 |         65.2500 |
| Chun    | Tuning |    73 |         68.7500 |
| Esben   | SQL    |    43 |         65.2500 |
| Esben   | Tuning |    31 |         68.7500 |
| Kaolin  | SQL    |    56 |         65.2500 |
| Kaolin  | Tuning |    88 |         68.7500 |
| Tatiana | SQL    |    87 |         65.2500 |
| Tatiana | Tuning |    83 |         68.7500 |
+---------+--------+-------+-----------------+

URL: https://mariadb.com/kb/en/avg/https://mariadb.com/kb/en/avg/�/@
�
�&	�,$TIMESTAMP0�GOTOMariaDB starting with 10.3
--------------------------
The GOTO statement was introduced in MariaDB 10.3 for Oracle compatibility.

Syntax
------

GOTO label

Description
-----------

The GOTO statement causes the code to jump to the specified label, and
continue operating from there. It is only accepted when in Oracle mode.

Example
-------

SET sql_mode=ORACLE;

DELIMITER //

CREATE OR REPLACE PROCEDURE p1 AS

BEGIN

SELECT 1;
 GOTO label;
 SELECT 2;
 <<label>>
 SELECT 3;

END;

//

DELIMITER

call p1();
+---+
| 1 |
+---+
| 1 |
+---+
1 row in set (0.000 sec)

+---+
| 3 |
+---+
| 3 |
+---+
1 row in set (0.000 sec)

URL: https://mariadb.com/kb/en/goto/https://mariadb.com/kb/en/goto/���-��
�
�V�J�C�Syntax
------

TIMESTAMP [(<microsecond precision)]

Description
-----------

A timestamp in the format YYYY-MM-DD HH:MM:SS.ffffff.

The timestamp field is generally used to define at which moment in time a row
was added or updated and by default will automatically be assigned the current
datetime when a record is inserted or updated. The automatic properties only
apply to the first TIMESTAMP in the record; subsequent TIMESTAMP columns will
not be changed.

MariaDB includes the --mysql56-temporal-format option, on by default, which
allows MariaDB to store TIMESTAMPs using the same low-level format MySQL 5.6
uses.

For more information, see Internal Format.

Supported Values
----------------

MariaDB stores values that use the TIMESTAMP data type as the number of
seconds since '1970-01-01 00:00:00' (UTC). This means that the TIMESTAMP data
type can hold values between '1970-01-01 00:00:01' (UTC) and '2038-01-19
03:14:07' (UTC).

MariaDB can also store microseconds with a precision between 0 and 6. If no
microsecond precision is specified, then 0 is used by default.

Automatic Values
----------------

MariaDB has special behavior for the first column that uses the TIMESTAMP data
type in a specific table when the system variable
explicit_defaults_for_timestamp is not set (which is the default until MariaDB
10.10). For the first column that uses the TIMESTAMP data type in a specific
table, MariaDB automatically assigns the following properties to the column:

* DEFAULT CURRENT_TIMESTAMP
* ON UPDATE CURRENT_TIMESTAMP

This means that if the column is not explicitly assigned a value in an INSERT
or UPDATE query, then MariaDB will automatically initialize the column's value
with the current date and time.

This automatic initialization for INSERT and UPDATE queries can also be
explicitly enabled for a column that uses the TIMESTAMP data type by
specifying the DEFAULT CURRENT_TIMESTAMP and ON UPDATE CURRENT_TIMESTAMP
clauses for the column. In these clauses, any synonym of CURRENT_TIMESTAMP is
accepted, including CURRENT_TIMESTAMP(), NOW(), LOCALTIME, LOCALTIME(),
LOCALTIMESTAMP, and LOCALTIMESTAMP().

This automatic initialization for INSERT queries can also be explicitly
disabled for a column that uses the TIMESTAMP data type by specifying a
constant DEFAULT value. For example, DEFAULT 0.

This automatic initialization for UPDATE queries can also be explicitly
disabled for a column that uses the TIMESTAMP data type by specifying a
DEFAULT clause for the column, but no ON UPDATE clause. If a DEFAULT clause is
explicitly specified for a column that uses the TIMESTAMP data type, but an ON
UPDATE clause is not specified for the column, then the timestamp value will
not automatically change when an UPDATE statement is executed.

MariaDB also has special behavior if NULL is assigned to column that uses the
TIMESTAMP data type. If the column is assigned the NULL value in an INSERT or
UPDATE query, then MariaDB will automatically initialize the column's value
with the current date and time. For details, see NULL values in MariaDB.

This automatic initialization for NULL values can also be explicitly disabled
for a column that uses the TIMESTAMP data type by specifying the NULL
attribute for the column. In this case, if the column's value is set to NULL,
then the column's value will actually be set to NULL.

Time Zones
----------

If a column uses the TIMESTAMP data type, then any inserted values are
converted from the session's time zone to Coordinated Universal Time (UTC)
when stored, and converted back to the session's time zone when retrieved.

MariaDB validates TIMESTAMP literals against the session's time zone. For
example, if a specific time range never occurred in a specific time zone due
to daylight savings time, then TIMESTAMP values within that range would be
invalid for that time zone.

MariaDB does not currently store any time zone identifier with the value of
the TIMESTAMP data type. See MDEV-10018 for more information.

MariaDB does not currently support time zone literals that contain time zone
identifiers. See MDEV-11829 for more information.

Limitations
-----------

* Because the TIMESTAMP value is stored as Epoch Seconds, the timestamp value
'1970-01-01 00:00:00' (UTC) is reserved since the second #0 is used to
represent '0000-00-00 00:00:00'.
* In MariaDB 5.5 and before there could only be one TIMESTAMP column per table
that had CURRENT_TIMESTAMP defined as its default value. This limit has no
longer applied since MariaDB 10.0.

SQL_MODE=MAXDB
--------------

If the SQL_MODE is set to MAXDB, TIMESTAMP fields will be silently converted
to DATETIME.

Internal Format
---------------

In MariaDB 10.1.2 a new temporal format was introduced from MySQL 5.6 that
alters how the TIME, DATETIME and TIMESTAMP columns operate at lower levels.
These changes allow these temporal data types to have fractional parts and
negative values. You can disable this feature using the
mysql56_temporal_format system variable.

Tables that include TIMESTAMP values that were created on an older version of
MariaDB or that were created while the mysql56_temporal_format system variable
was disabled continue to store data using the older data type format.

In order to update table columns from the older format to the newer format,
execute an ALTER TABLE... MODIFY COLUMN statement that changes the column to
the *same* data type. This change may be needed if you want to export the
table's tablespace and import it onto a server that has
mysql56_temporal_format=ON set (see MDEV-15225).

For instance, if you have a TIMESTAMP column in your table:

SHOW VARIABLES LIKE 'mysql56_temporal_format';

+-------------------------+-------+
| Variable_name           | Value |
+-------------------------+-------+
| mysql56_temporal_format | ON    |
+-------------------------+-------+

ALTER TABLE example_table MODIFY ts_col TIMESTAMP;

When MariaDB executes the ALTER TABLE statement, it converts the data from the
older temporal format to the newer one.

In the event that you have several tables and columns using temporal data
types that you want to switch over to the new format, make sure the system
variable is enabled, then perform a dump and restore using mysqldump. The
columns using relevant temporal data types are restored using the new temporal
format.

Starting from MariaDB 10.5.1 columns with old temporal formats are marked with
a /* mariadb-5.3 */ comment in the output of SHOW CREATE TABLE, SHOW COLUMNS,
DESCRIBE statements, as well as in the COLUMN_TYPE column of the
INFORMATION_SCHEMA.COLUMNS Table.

SHOW CREATE TABLE mariadb5312_timestamp\G
*************************** 1. row ***************************
   Table: mariadb5312_timestamp
Create Table: CREATE TABLE `mariadb5312_timestamp` (
 `ts0` timestamp /* mariadb-5.3 */ NOT NULL DEFAULT current_timestamp() ON
UPDATE current_timestamp(),
 `ts6` timestamp(6) /* mariadb-5.3 */ NOT NULL DEFAULT '0000-00-00
00:00:00.000000'
) ENGINE=MyISAM DEFAULT CHARSET=latin1

Note: Prior to MySQL 4.1 a different format for the TIMESTAMP datatype was
used. This format is unsupported in MariaDB 5.1 and upwards.

Examples
--------

CREATE TABLE t (id INT, ts TIMESTAMP);

DESC t;
+-------+-----------+------+-----+-------------------+-------------------------
---+
| Field | Type      | Null | Key | Default           | Extra                  
  |
+-------+-----------+------+-----+-------------------+-------------------------
---+
| id    | int(11)   | YES  |     | NULL              |                        
  |
| ts    | timestamp | NO   |     | CURRENT_TIMESTAMP | on update
CURRENT_TIMESTAMP |
+-------+-----------+------+-----+-------------------+-------------------------
---+

INSERT INTO t(id)  VALUES (1),(2);

SELECT * FROM t;
+------+---------------------+
| id   | ts                  |
+------+---------------------+
|    1 | 2013-07-22 12:50:05 |
|    2 | 2013-07-22 12:50:05 |
+------+---------------------+

INSERT INTO t  VALUES (3,NULL),(4,'2001-07-22 12:12:12');

SELECT * FROM t;
+------+---------------------+
| id   | ts                  |
+------+---------------------+
|    1 | 2013-07-22 12:50:05 |
|    2 | 2013-07-22 12��M���5Stored Aggregate FunctionsMariaDB starting with 10.3.3
----------------------------
The ability to create stored aggregate functions was added in MariaDB 10.3.3.

Aggregate functions are functions that are computed over a sequence of rows
and return one result for the sequence of rows.

Creating a custom aggregate function is done using the CREATE FUNCTION
statement with two main differences:

* The addition of the AGGREGATE keyword, so CREATE AGGREGATE FUNCTION
* The FETCH GROUP NEXT ROW instruction inside the loop
* Oracle PL/SQL compatibility using SQL/PL is provided

Standard Syntax
---------------

CREATE AGGREGATE FUNCTION function_name (parameters) RETURNS return_type
BEGIN
   All types of declarations
   DECLARE CONTINUE HANDLER FOR NOT FOUND RETURN return_val;
   LOOP
     FETCH GROUP NEXT ROW; // fetches next row from table
     other instructions
   END LOOP;
END

Stored aggregate functions were a 2016 Google Summer of Code project by Varun
Gupta.

Using SQL/PL
------------

SET sql_mode=Oracle;
DELIMITER //

CREATE AGGREGATE FUNCTION function_name (parameters) RETURN return_type
 declarations
BEGIN
 LOOP
   FETCH GROUP NEXT ROW; -- fetches next row from table
   -- other instructions

END LOOP;
EXCEPTION
 WHEN NO_DATA_FOUND THEN
   RETURN return_val;
END //

DELIMITER ;

Examples
--------

First a simplified example:

CREATE TABLE marks(stud_id INT, grade_count INT);

INSERT INTO marks VALUES (1,6), (2,4), (3,7), (4,5), (5,8);

SELECT * FROM marks;
+---------+-------------+
| stud_id | grade_count |
+---------+-------------+
|       1 |           6 |
|       2 |           4 |
|       3 |           7 |
|       4 |           5 |
|       5 |           8 |
+---------+-------------+

DELIMITER //
CREATE AGGREGATE FUNCTION IF NOT EXISTS aggregate_count(x INT) RETURNS INT
BEGIN
 DECLARE count_students INT DEFAULT 0;
 DECLARE CONTINUE HANDLER FOR NOT FOUND
 RETURN count_students;
   LOOP
     FETCH GROUP NEXT ROW;
     IF x  THEN
      SET count_students = count_students+1;
     END IF;
   END LOOP;
END //
DELIMITER ;

A non-trivial example that cannot easily be rewritten using existing functions:

DELIMITER //
CREATE AGGREGATE FUNCTION medi_int(x INT) RETURNS DOUBLE
BEGIN
 DECLARE CONTINUE HANDLER FOR NOT FOUND
  BEGIN
   DECLARE res DOUBLE;
   DECLARE cnt INT DEFAULT (SELECT COUNT(*) FROM tt);
   DECLARE lim INT DEFAULT (cnt-1) DIV 2;
   IF cnt % 2 = 0 THEN
    SET res = (SELECT AVG(a) FROM (SELECT a FROM tt ORDER BY a LIMIT
lim,2) ttt);
   ELSE
    SET res = (SELECT a FROM tt ORDER BY a LIMIT lim,1);
   END IF;
   DROP TEMPORARY TABLE tt;
   RETURN res;
  END;
 CREATE TEMPORARY TABLE tt (a INT);
 LOOP
  FETCH GROUP NEXT ROW;
  INSERT INTO tt VALUES (x);
 END LOOP;
END //
DELIMITER ;

SQL/PL Example
--------------

This uses the same marks table as created above.

SET sql_mode=Oracle;
DELIMITER //

CREATE AGGREGATE FUNCTION aggregate_count(x INT) RETURN INT AS count_students
INT DEFAULT 0;
BEGIN
 LOOP
   FETCH GROUP NEXT ROW;
   IF x  THEN
    SET count_students := count_students+1;
   END IF;
 END LOOP;
EXCEPTION
 WHEN NO_DATA_FOUND THEN
   RETURN count_students;
END aggregate_count //
DELIMITER ;

SELECT aggregate_count(stud_id) FROM marks;

URL: https://mariadb.com/kb/en/stored-aggregate-functions/https://mariadb.com/kb/en/stored-aggregate-functions/�@"BIT_ANDSyntax
------

BIT_AND(expr) [over_clause]

Description
-----------

Returns the bitwise AND of all bits in expr. The calculation is performed with
64-bit (BIGINT) precision. It is an aggregate function, and so can be used
with the GROUP BY clause.

If no rows match, BIT_AND will return a value with all bits set to 1. NULL
values have no effect on the result unless all results are NULL, which is
treated as no match.

BIT_AND can be used as a window function with the addition of the over_clause.

Examples
--------

CREATE TABLE vals (x INT);

INSERT INTO vals VALUES(111),(110),(100);

SELECT BIT_AND(x), BIT_OR(x), BIT_XOR(x) FROM vals;
+------------+-----------+------------+
| BIT_AND(x) | BIT_OR(x) | BIT_XOR(x) |
+------------+-----------+------------+
|        100 |       111 |        101 |
+------------+-----------+------------+

As an aggregate function:

CREATE TABLE vals2 (category VARCHAR(1), x INT);

INSERT INTO vals2 VALUES
 ('a',111),('a',110),('a',100),
 ('b','000'),('b',001),('b',011);

SELECT category, BIT_AND(x), BIT_OR(x), BIT_XOR(x) 
 FROM vals GROUP BY category;
+----------+------------+-----------+------------+
| category | BIT_AND(x) | BIT_OR(x) | BIT_XOR(x) |
+----------+------------+-----------+------------+
| a        |        100 |       111 |        101 |
| b        |          0 |        11 |         10 |
+----------+------------+-----------+------------+

No match:

SELECT BIT_AND(NULL);
+----------------------+
| BIT_AND(NULL)        |
+----------------------+
| 18446744073709551615 |
+----------------------+

URL: https://mariadb.com/kb/en/bit_and/https://mariadb.com/kb/en/bit_and/1�IFSyntax
------

IF search_condition THEN statement_list
  [ELSEIF search_condition THEN statement_list] ...
  [ELSE statement_list]
END IF;

Description
-----------

IF implements a basic conditional construct. If the search_condition evaluates
to true, the corresponding SQL statement list is executed. If no
search_condition matches, the statement list in the ELSE clause is executed.
Each statement_list consists of one or more statements.

URL: https://mariadb.com/kb/en/if/https://mariadb.com/kb/en/if/5�LOOPSyntax
------

[begin_label:] LOOP
  statement_list
END LOOP [end_label]

Description
-----------

LOOP implements a simple loop construct, enabling repeated execution of the
statement list, which consists of one or more statements, each terminated by a
semicolon (i.e., ;) statement delimiter. The statements within the loop are
repeated until the loop is exited; usually this is accomplished with a LEAVE
statement.

A LOOP statement can be labeled. end_label cannot be given unless begin_label
also is present. If both are present, they must be the same.

See Delimiters in the mariadb client for more on delimiter usage in the client.

URL: https://mariadb.com/kb/en/loop/https://mariadb.com/kb/en/loop/8z!RETURNSyntax
------

RETURN expr

The RETURN statement terminates execution of a stored function and returns the
value expr to the function caller. There must be at least one RETURN statement
in a stored function. If the function has multiple exit points, all exit
points must have a RETURN.

This statement is not used in stored procedures, triggers, or events. LEAVE
can be used instead.

The following example shows that RETURN can return the result of a scalar
subquery:

CREATE FUNCTION users_count() RETURNS BOOL
 READS SQL DATA
BEGIN
 RETURN (SELECT COUNT(DISTINCT User) FROM mysql.user);
END;

URL: https://mariadb.com/kb/en/return/https://mariadb.com/kb/en/return/;� WHILESyntax
------

[begin_label:] WHILE search_condition DO
  statement_list
END WHILE [end_label]

Description
-----------

The statement list within a WHILE statement is repeated as long as the
search_condition is true. statement_list consists of one or more statements.
If the loop must be executed at least once, REPEAT ... LOOP can be used
instead.

A WHILE statement can be labeled. end_label cannot be given unless begin_label
also is present. If both are present, they must be the same.

Examples
--------

CREATE PROCEDURE dowhile()
BEGIN
 DECLARE v1 INT DEFAULT 5;

WHILE v1 > 0 DO
  ...
  SET v1 = v1 - 1;
 END WHILE;
END

URL: https://mariadb.com/kb/en/while/https://mariadb.com/kb/en/while/�g����

w
�r}	�-�!BIT_ORSyntax
------

BIT_OR(expr) [over_clause]

Description
-----------

Returns the bitwise OR of all bits in expr. The calculation is performed with
64-bit (BIGINT) precision. It is an aggregate function, and so can be used
with the GROUP BY clause.

If no rows match, BIT_OR will return a value with all bits set to 0. NULL
values have no effect on the result unless all results are NULL, which is
treated as no match.

BIT_OR can be used as a window function with the addition of the over_clause.

Examples
--------

CREATE TABLE vals (x INT);

INSERT INTO vals VALUES(111),(110),(100);

SELECT BIT_AND(x), BIT_OR(x), BIT_XOR(x) FROM vals;
+------------+-----------+------------+
| BIT_AND(x) | BIT_OR(x) | BIT_XOR(x) |
+------------+-----------+------------+
|        100 |       111 |        101 |
+------------+-----------+------------+

As an aggregate function:

CREATE TABLE vals2 (category VARCHAR(1), x INT);

INSERT INTO vals2 VALUES
 ('a',111),('a',110),('a',100),
 ('b','000'),('b',001),('b',011);

SELECT category, BIT_AND(x), BIT_OR(x), BIT_XOR(x) 
 FROM vals GROUP BY category;
+----------+------------+-----------+------------+
| category | BIT_AND(x) | BIT_OR(x) | BIT_XOR(x) |
+----------+------------+-----------+------------+
| a        |        100 |       111 |        101 |
| b        |          0 |        11 |         10 |
+----------+------------+-----------+------------+

No match:

SELECT BIT_OR(NULL);
+--------------+
| BIT_OR(NULL) |
+--------------+
|            0 |
+--------------+

URL: https://mariadb.com/kb/en/bit_or/https://mariadb.com/kb/en/bit_or/�"BIT_XORSyntax
------

BIT_XOR(expr) [over_clause]

Description
-----------

Returns the bitwise XOR of all bits in expr. The calculation is performed with
64-bit (BIGINT) precision. It is an aggregate function, and so can be used
with the GROUP BY clause.

If no rows match, BIT_XOR will return a value with all bits set to 0. NULL
values have no effect on the result unless all results are NULL, which is
treated as no match.

BIT_XOR can be used as a window function with the addition of the over_clause.

Examples
--------

CREATE TABLE vals (x INT);

INSERT INTO vals VALUES(111),(110),(100);

SELECT BIT_AND(x), BIT_OR(x), BIT_XOR(x) FROM vals;
+------------+-----------+------------+
| BIT_AND(x) | BIT_OR(x) | BIT_XOR(x) |
+------------+-----------+------------+
|        100 |       111 |        101 |
+------------+-----------+------------+

As an aggregate function:

CREATE TABLE vals2 (category VARCHAR(1), x INT);

INSERT INTO vals2 VALUES
 ('a',111),('a',110),('a',100),
 ('b','000'),('b',001),('b',011);

SELECT category, BIT_AND(x), BIT_OR(x), BIT_XOR(x) 
 FROM vals GROUP BY category;
+----------+------------+-----------+------------+
| category | BIT_AND(x) | BIT_OR(x) | BIT_XOR(x) |
+----------+------------+-----------+------------+
| a        |        100 |       111 |        101 |
| b        |          0 |        11 |         10 |
+----------+------------+-----------+------------+

No match:

SELECT BIT_XOR(NULL);
+---------------+
| BIT_XOR(NULL) |
+---------------+
|             0 |
+---------------+

URL: https://mariadb.com/kb/en/bit_xor/https://mariadb.com/kb/en/bit_xor/�� COUNTSyntax
------

COUNT(expr)

Description
-----------

Returns a count of the number of non-NULL values of expr in the rows retrieved
by a SELECT statement. The result is a BIGINT value. It is an aggregate
function, and so can be used with the GROUP BY clause.

COUNT(*) counts the total number of rows in a table.

COUNT() returns 0 if there were no matching rows.

COUNT() can be used as a window function.

Examples
--------

CREATE TABLE student (name CHAR(10), test CHAR(10), score TINYINT);

INSERT INTO student VALUES 
 ('Chun', 'SQL', 75), ('Chun', 'Tuning', 73),
 ('Esben', 'SQL', 43), ('Esben', 'Tuning', 31),
 ('Kaolin', 'SQL', 56), ('Kaolin', 'Tuning', 88),
 ('Tatiana', 'SQL', 87), ('Tatiana', 'Tuning', 83);

SELECT COUNT(*) FROM student;
+----------+
| COUNT(*) |
+----------+
|        8 |
+----------+

COUNT(DISTINCT) example:

SELECT COUNT(DISTINCT (name)) FROM student;
+------------------------+
| COUNT(DISTINCT (name)) |
+------------------------+
|                      4 |
+------------------------+

As a window function

CREATE OR REPLACE TABLE student_test (name CHAR(10), test CHAR(10), score
TINYINT);

INSERT INTO student_test VALUES 
  ('Chun', 'SQL', 75), ('Chun', 'Tuning', 73),
  ('Esben', 'SQL', 43), ('Esben', 'Tuning', 31),
  ('Kaolin', 'SQL', 56), ('Kaolin', 'Tuning', 88),
  ('Tatiana', 'SQL', 87);

SELECT name, test, score, COUNT(score) OVER (PARTITION BY name) 
  AS tests_written FROM student_test;
+---------+--------+-------+---------------+
| name    | test   | score | tests_written |
+---------+--------+-------+---------------+
| Chun    | SQL    |    75 |             2 |
| Chun    | Tuning |    73 |             2 |
| Esben   | SQL    |    43 |             2 |
| Esben   | Tuning |    31 |             2 |
| Kaolin  | SQL    |    56 |             2 |
| Kaolin  | Tuning |    88 |             2 |
| Tatiana | SQL    |    87 |             1 |
+---------+--------+-------+---------------+

URL: https://mariadb.com/kb/en/count/https://mariadb.com/kb/en/count/>OPENSyntax
------

<= MariaDB 10.2

OPEN cursor_name

From MariaDB 10.3

OPEN cursor_name [expression[,...]];

Description
-----------

This statement opens a cursor which was previously declared with DECLARE
CURSOR.

The query associated to the DECLARE CURSOR is executed when OPEN is executed.
It is important to remember this if the query produces an error, or calls
functions which have side effects.

This is necessary in order to FETCH rows from a cursor.

See Cursor Overview for an example.

URL: https://mariadb.com/kb/en/open/https://mariadb.com/kb/en/open/? FETCHSyntax
------

FETCH cursor_name INTO var_name [, var_name] ...

Description
-----------

This statement fetches the next row (if a row exists) using the specified open
cursor, and advances the cursor pointer.

var_name can be a local variable, but not a user-defined variable.

If no more rows are available, a No Data condition occurs with SQLSTATE value
02000. To detect this condition, you can set up a handler for it (or for a NOT
FOUND condition).

See Cursor Overview for an example.

URL: https://mariadb.com/kb/en/fetch/https://mariadb.com/kb/en/fetch/@j CLOSESyntax
------

CLOSE cursor_name

Description
-----------

This statement closes a previously opened cursor. The cursor must have been
previously opened or else an error occurs.

If not closed explicitly, a cursor is closed at the end of the compound
statement in which it was declared.

See Cursor Overview for an example.

URL: https://mariadb.com/kb/en/close/https://mariadb.com/kb/en/close/A@!BUFFERA synonym for ST_BUFFER.

URL: https://mariadb.com/kb/en/buffer/https://mariadb.com/kb/en/buffer/B
H%CONVEXHULLA synonym for ST_CONVEXHULL.

URL: https://mariadb.com/kb/en/convexhull/https://mariadb.com/kb/en/convexhull/C�-GEOMETRYCOLLECTIONSyntax
------

GeometryCollection(g1,g2,...)

Description
-----------

Constructs a WKB GeometryCollection. If any argument is not a well-formed WKB
representation of a geometry, the return value is NULL.

Examples
--------

CREATE TABLE gis_geometrycollection  (g GEOMETRYCOLLECTION);
SHOW FIELDS FROM gis_geometrycollection;
INSERT INTO gis_geometrycollection VALUES
  (GeomCollFromText('GEOMETRYCOLLECTION(POINT(0 0), LINESTRING(0 0,10
10))')),
  (GeometryFromWKB(AsWKB(GeometryCollection(Point(44, 6),
LineString(Point(3, 6), Point(7, 9)))))),
  (GeomFromText('GeometryCollection()')),
  (GeomFromText('GeometryCollection EMPTY'));

URL: https://mariadb.com/kb/en/geometrycollection/https://mariadb.com/kb/en/geometrycollection/��*��u��D�E��STG�������)COUNT DISTINCTSyntax
------

COUNT(DISTINCT expr,[expr...])

Description
-----------

Returns a count of the number of different non-NULL values.

COUNT(DISTINCT) returns 0 if there were no matching rows.

Although, from MariaDB 10.2.0, COUNT can be used as a window function, COUNT
DISTINCT cannot be.

Examples
--------

CREATE TABLE student (name CHAR(10), test CHAR(10), score TINYINT);

INSERT INTO student VALUES 
 ('Chun', 'SQL', 75), ('Chun', 'Tuning', 73),
 ('Esben', 'SQL', 43), ('Esben', 'Tuning', 31),
 ('Kaolin', 'SQL', 56), ('Kaolin', 'Tuning', 88),
 ('Tatiana', 'SQL', 87), ('Tatiana', 'Tuning', 83);

SELECT COUNT(*) FROM student;
+----------+
| COUNT(*) |
+----------+
|        8 |
+----------+

SELECT COUNT(DISTINCT (name)) FROM student;
+------------------------+
| COUNT(DISTINCT (name)) |
+------------------------+
|                      4 |
+------------------------+

URL: https://mariadb.com/kb/en/count-distinct/https://mariadb.com/kb/en/count-distinct/��'GROUP_CONCATSyntax
------

GROUP_CONCAT(expr)

Description
-----------

This function returns a string result with the concatenated non-NULL values
from a group. It returns NULL if there are no non-NULL values.

The maximum returned length in bytes is determined by the group_concat_max_len
server system variable, which defaults to 1M (>= MariaDB 10.2.4) or 1K (<=
MariaDB 10.2.3).

If group_concat_max_len <= 512, the return type is VARBINARY or VARCHAR;
otherwise, the return type is BLOB or TEXT. The choice between binary or
non-binary types depends from the input.

The full syntax is as follows:

GROUP_CONCAT([DISTINCT] expr [,expr ...]
      [ORDER BY {unsigned_integer | col_name | expr}
        [ASC | DESC] [,col_name ...]]
      [SEPARATOR str_val]
      [LIMIT {[offset,] row_count | row_count OFFSET offset}])

DISTINCT eliminates duplicate values from the output string.

ORDER BY determines the order of returned values.

SEPARATOR specifies a separator between the values. The default separator is a
comma (,). It is possible to avoid using a separator by specifying an empty
string.

LIMIT
-----

MariaDB starting with 10.3.3
----------------------------
Until MariaDB 10.3.2, it was not possible to use the LIMIT clause with
GROUP_CONCAT. This restriction was lifted in MariaDB 10.3.3.

Examples
--------

SELECT student_name,
   GROUP_CONCAT(test_score)
   FROM student
   GROUP BY student_name;

Get a readable list of MariaDB users from the mysql.user table:

SELECT GROUP_CONCAT(DISTINCT User ORDER BY User SEPARATOR '\n')
 FROM mysql.user;

In the former example, DISTINCT is used because the same user may occur more
than once. The new line (\n) used as a SEPARATOR makes the results easier to
read.

Get a readable list of hosts from which each user can connect:

SELECT User, GROUP_CONCAT(Host ORDER BY Host SEPARATOR ', ') 
 FROM mysql.user GROUP BY User ORDER BY User;

The former example shows the difference between the GROUP_CONCAT's ORDER BY
(which sorts the concatenated hosts), and the SELECT's ORDER BY (which sorts
the rows).

From MariaDB 10.3.3, LIMIT can be used with GROUP_CONCAT, so, for example,
given the following table:

CREATE TABLE d (dd DATE, cc INT);

INSERT INTO d VALUES ('2017-01-01',1);
INSERT INTO d VALUES ('2017-01-02',2);
INSERT INTO d VALUES ('2017-01-04',3);

the following query:

SELECT SUBSTRING_INDEX(GROUP_CONCAT(CONCAT_WS(":",dd,cc) ORDER BY cc
DESC),",",1) FROM d;
+----------------------------------------------------------------------------+
| SUBSTRING_INDEX(GROUP_CONCAT(CONCAT_WS(":",dd,cc) ORDER BY cc DESC),",",1) |
+----------------------------------------------------------------------------+
| 2017-01-04:3                                                               |
+----------------------------------------------------------------------------+

can be more simply rewritten as:

SELECT GROUP_CONCAT(CONCAT_WS(":",dd,cc) ORDER BY cc DESC LIMIT 1) FROM d;
+-------------------------------------------------------------+
| GROUP_CONCAT(CONCAT_WS(":",dd,cc) ORDER BY cc DESC LIMIT 1) |
+-------------------------------------------------------------+
| 2017-01-04:3                                                |
+-------------------------------------------------------------+

URL: https://mariadb.com/kb/en/group_concat/https://mariadb.com/kb/en/group_concat/��MAXSyntax
------

MAX([DISTINCT] expr)

Description
-----------

Returns the largest, or maximum, value of expr. MAX() can also take a string
argument in which case it returns the maximum string value. The DISTINCT
keyword can be used to find the maximum of the distinct values of expr,
however, this produces the same result as omitting DISTINCT.

Note that SET and ENUM fields are currently compared by their string value
rather than their relative position in the set, so MAX() may produce a
different highest result than ORDER BY DESC.

It is an aggregate function, and so can be used with the GROUP BY clause.

MAX() can be used as a window function.

MAX() returns NULL if there were no matching rows.

Examples
--------

CREATE TABLE student (name CHAR(10), test CHAR(10), score TINYINT);

INSERT INTO student VALUES 
 ('Chun', 'SQL', 75), ('Chun', 'Tuning', 73),
 ('Esben', 'SQL', 43), ('Esben', 'Tuning', 31),
 ('Kaolin', 'SQL', 56), ('Kaolin', 'Tuning', 88),
 ('Tatiana', 'SQL', 87), ('Tatiana', 'Tuning', 83);

SELECT name, MAX(score) FROM student GROUP BY name;
+---------+------------+
| name    | MAX(score) |
+---------+------------+
| Chun    |         75 |
| Esben   |         43 |
| Kaolin  |         88 |
| Tatiana |         87 |
+---------+------------+

MAX string:

SELECT MAX(name) FROM student;
+-----------+
| MAX(name) |
+-----------+
| Tatiana   |
+-----------+

Be careful to avoid this common mistake, not grouping correctly and returning
mismatched data:

SELECT name,test,MAX(SCORE) FROM student;
+------+------+------------+
| name | test | MAX(SCORE) |
+------+------+------------+
| Chun | SQL  |         88 |
+------+------+------------+

Difference between ORDER BY DESC and MAX():

CREATE TABLE student2(name CHAR(10),grade ENUM('b','c','a'));

INSERT INTO student2 VALUES('Chun','b'),('Esben','c'),('Kaolin','a');

SELECT MAX(grade) FROM student2;
+------------+
| MAX(grade) |
+------------+
| c          |
+------------+

SELECT grade FROM student2 ORDER BY grade DESC LIMIT 1;
+-------+
| grade |
+-------+
| a     |
+-------+

As a window function:

CREATE OR REPLACE TABLE student_test (name CHAR(10), test CHAR(10), score
TINYINT);
INSERT INTO student_test VALUES 
  ('Chun', 'SQL', 75), ('Chun', 'Tuning', 73),
  ('Esben', 'SQL', 43), ('Esben', 'Tuning', 31),
  ('Kaolin', 'SQL', 56), ('Kaolin', 'Tuning', 88),
  ('Tatiana', 'SQL', 87);

SELECT name, test, score, MAX(score) 
 OVER (PARTITION BY name) AS highest_score FROM student_test;
+---------+--------+-------+---------------+
| name    | test   | score | highest_score |
+---------+--------+-------+---------------+
| Chun    | SQL    |    75 |            75 |
| Chun    | Tuning |    73 |            75 |
| Esben   | SQL    |    43 |            43 |
| Esben   | Tuning |    31 |            43 |
| Kaolin  | SQL    |    56 |            88 |
| Kaolin  | Tuning |    88 |            88 |
| Tatiana | SQL    |    87 |            87 |
+---------+--------+-------+---------------+

URL: https://mariadb.com/kb/en/max/https://mariadb.com/kb/en/max/
��
��37A����MINSyntax
------

MIN([DISTINCT] expr)

Description
-----------

Returns the minimum value of expr. MIN() may take a string argument, in which
case it returns the minimum string value. The DISTINCT keyword can be used to
find the minimum of the distinct values of expr, however, this produces the
same result as omitting DISTINCT.

Note that SET and ENUM fields are currently compared by their string value
rather than their relative position in the set, so MIN() may produce a
different lowest result than ORDER BY ASC.

It is an aggregate function, and so can be used with the GROUP BY clause.

MIN() can be used as a window function.

MIN() returns NULL if there were no matching rows.

Examples
--------

CREATE TABLE student (name CHAR(10), test CHAR(10), score TINYINT);

INSERT INTO student VALUES 
 ('Chun', 'SQL', 75), ('Chun', 'Tuning', 73),
 ('Esben', 'SQL', 43), ('Esben', 'Tuning', 31),
 ('Kaolin', 'SQL', 56), ('Kaolin', 'Tuning', 88),
 ('Tatiana', 'SQL', 87), ('Tatiana', 'Tuning', 83);

SELECT name, MIN(score) FROM student GROUP BY name;
+---------+------------+
| name    | MIN(score) |
+---------+------------+
| Chun    |         73 |
| Esben   |         31 |
| Kaolin  |         56 |
| Tatiana |         83 |
+---------+------------+

MIN() with a string:

SELECT MIN(name) FROM student;
+-----------+
| MIN(name) |
+-----------+
| Chun      |
+-----------+

Be careful to avoid this common mistake, not grouping correctly and returning
mismatched data:

SELECT name,test,MIN(score) FROM student;
+------+------+------------+
| name | test | MIN(score) |
+------+------+------------+
| Chun | SQL  |         31 |
+------+------+------------+

Difference between ORDER BY ASC and MIN():

CREATE TABLE student2(name CHAR(10),grade ENUM('b','c','a'));

INSERT INTO student2 VALUES('Chun','b'),('Esben','c'),('Kaolin','a');

SELECT MIN(grade) FROM student2;
+------------+
| MIN(grade) |
+------------+
| a          |
+------------+

SELECT grade FROM student2 ORDER BY grade ASC LIMIT 1;
+-------+
| grade |
+-------+
| b     |
+-------+

As a window function:

CREATE OR REPLACE TABLE student_test (name CHAR(10), test CHAR(10), score
TINYINT);
INSERT INTO student_test VALUES 
  ('Chun', 'SQL', 75), ('Chun', 'Tuning', 73),
  ('Esben', 'SQL', 43), ('Esben', 'Tuning', 31),
  ('Kaolin', 'SQL', 56), ('Kaolin', 'Tuning', 88),
  ('Tatiana', 'SQL', 87);

SELECT name, test, score, MIN(score) 
 OVER (PARTITION BY name) AS lowest_score FROM student_test;
+---------+--------+-------+--------------+
| name    | test   | score | lowest_score |
+---------+--------+-------+--------------+
| Chun    | SQL    |    75 |           73 |
| Chun    | Tuning |    73 |           73 |
| Esben   | SQL    |    43 |           31 |
| Esben   | Tuning |    31 |           31 |
| Kaolin  | SQL    |    56 |           56 |
| Kaolin  | Tuning |    88 |           56 |
| Tatiana | SQL    |    87 |           87 |
+---------+--------+-------+--------------+

URL: https://mariadb.com/kb/en/min/https://mariadb.com/kb/en/min/��STDSyntax
------

STD(expr)

Description
-----------

Returns the population standard deviation of expr. This is an extension to
standard SQL. The standard SQL function STDDEV_POP() can be used instead.

It is an aggregate function, and so can be used with the GROUP BY clause.

STD() can be used as a window function.

This function returns NULL if there were no matching rows.

Examples
--------

As an aggregate function:

CREATE OR REPLACE TABLE stats (category VARCHAR(2), x INT);

INSERT INTO stats VALUES 
 ('a',1),('a',2),('a',3),
 ('b',11),('b',12),('b',20),('b',30),('b',60);

SELECT category, STDDEV_POP(x), STDDEV_SAMP(x), VAR_POP(x) 
 FROM stats GROUP BY category;
+----------+---------------+----------------+------------+
| category | STDDEV_POP(x) | STDDEV_SAMP(x) | VAR_POP(x) |
+----------+---------------+----------------+------------+
| a        |        0.8165 |         1.0000 |     0.6667 |
| b        |       18.0400 |        20.1693 |   325.4400 |
+----------+---------------+----------------+------------+

As a window function:

CREATE OR REPLACE TABLE student_test (name CHAR(10), test CHAR(10), score
TINYINT);

INSERT INTO student_test VALUES 
  ('Chun', 'SQL', 75), ('Chun', 'Tuning', 73),
  ('Esben', 'SQL', 43), ('Esben', 'Tuning', 31),
  ('Kaolin', 'SQL', 56), ('Kaolin', 'Tuning', 88),
  ('Tatiana', 'SQL', 87);

SELECT name, test, score, STDDEV_POP(score) 
 OVER (PARTITION BY test) AS stddev_results FROM student_test;
+---------+--------+-------+----------------+
| name    | test   | score | stddev_results |
+---------+--------+-------+----------------+
| Chun    | SQL    |    75 |        16.9466 |
| Chun    | Tuning |    73 |        24.1247 |
| Esben   | SQL    |    43 |        16.9466 |
| Esben   | Tuning |    31 |        24.1247 |
| Kaolin  | SQL    |    56 |        16.9466 |
| Kaolin  | Tuning |    88 |        24.1247 |
| Tatiana | SQL    |    87 |        16.9466 |
+---------+--------+-------+----------------+

URL: https://mariadb.com/kb/en/std/https://mariadb.com/kb/en/std/Ex*MULTILINESTRINGSyntax
------

MultiLineString(ls1,ls2,...)

Description
-----------

Constructs a WKB MultiLineString value using WKB LineString arguments. If any
argument is not a WKB LineString, the return value is NULL.

Example
-------

CREATE TABLE gis_multi_line (g MULTILINESTRING);
INSERT INTO gis_multi_line VALUES
 (MultiLineStringFromText('MULTILINESTRING((10 48,10 21,10 0),(16 0,16 23,16
48))')),
 (MLineFromText('MULTILINESTRING((10 48,10 21,10 0))')),
 (MLineFromWKB(AsWKB(MultiLineString(LineString(Point(1, 2), 
  Point(3, 5)), LineString(Point(2, 5),Point(5, 8),Point(21, 7))))));

URL: https://mariadb.com/kb/en/multilinestring/https://mariadb.com/kb/en/multilinestring/F
_%MULTIPOINTSyntax
------

MultiPoint(pt1,pt2,...)

Description
-----------

Constructs a WKB MultiPoint value using WKB Point arguments. If any argument
is not a WKB Point, the return value is NULL.

Examples
--------

SET @g = ST_GEOMFROMTEXT('MultiPoint( 1 1, 2 2, 5 3, 7 2, 9 3, 8 4, 6 6, 6 9,
4 9, 1 5 )');

CREATE TABLE gis_multi_point (g MULTIPOINT);
INSERT INTO gis_multi_point VALUES
  (MultiPointFromText('MULTIPOINT(0 0,10 10,10 20,20 20)')),
  (MPointFromText('MULTIPOINT(1 1,11 11,11 21,21 21)')),
  (MPointFromWKB(AsWKB(MultiPoint(Point(3, 6), Point(4, 10)))));

URL: https://mariadb.com/kb/en/multipoint/https://mariadb.com/kb/en/multipoint/H� POINTSyntax
------

Point(x,y)

Description
-----------

Constructs a WKB Point using the given coordinates.

Examples
--------

SET @g = ST_GEOMFROMTEXT('Point(1 1)');

CREATE TABLE gis_point  (g POINT);
INSERT INTO gis_point VALUES
  (PointFromText('POINT(10 10)')),
  (PointFromText('POINT(20 10)')),
  (PointFromText('POINT(20 20)')),
  (PointFromWKB(AsWKB(PointFromText('POINT(10 20)'))));

URL: https://mariadb.com/kb/en/point/https://mariadb.com/kb/en/point/IP)PointOnSurfaceA synonym for ST_PointOnSurface.

URL: https://mariadb.com/kb/en/pointonsurface/https://mariadb.com/kb/en/pointonsurface/M$*ST_INTERSECTIONSyntax
------

ST_INTERSECTION(g1,g2)

Description
-----------

Returns a geometry that is the intersection, or shared portion, of geometry g1
and geometry g2.

Examples
--------

SET @g1 = ST_GEOMFROMTEXT('POINT(2 1)');

SET @g2 = ST_GEOMFROMTEXT('LINESTRING(2 1, 0 2)');

SELECT ASTEXT(ST_INTERSECTION(@g1,@g2));
+----------------------------------+
| ASTEXT(ST_INTERSECTION(@g1,@g2)) |
+----------------------------------+
| POINT(2 1)                       |
+----------------------------------+

URL: https://mariadb.com/kb/en/st_intersection/https://mariadb.com/kb/en/st_intersection/�k�;��������3������!STDDEVSyntax
------

STDDEV(expr)

Description
-----------

Returns the population standard deviation of expr. This function is provided
for compatibility with Oracle. The standard SQL function STDDEV_POP() can be
used instead.

It is an aggregate function, and so can be used with the GROUP BY clause.

STDDEV() can be used as a window function.

This function returns NULL if there were no matching rows.

Examples
--------

As an aggregate function:

CREATE OR REPLACE TABLE stats (category VARCHAR(2), x INT);

INSERT INTO stats VALUES 
 ('a',1),('a',2),('a',3),
 ('b',11),('b',12),('b',20),('b',30),('b',60);

SELECT category, STDDEV_POP(x), STDDEV_SAMP(x), VAR_POP(x) 
 FROM stats GROUP BY category;
+----------+---------------+----------------+------------+
| category | STDDEV_POP(x) | STDDEV_SAMP(x) | VAR_POP(x) |
+----------+---------------+----------------+------------+
| a        |        0.8165 |         1.0000 |     0.6667 |
| b        |       18.0400 |        20.1693 |   325.4400 |
+----------+---------------+----------------+------------+

As a window function:

CREATE OR REPLACE TABLE student_test (name CHAR(10), test CHAR(10), score
TINYINT);

INSERT INTO student_test VALUES 
  ('Chun', 'SQL', 75), ('Chun', 'Tuning', 73),
  ('Esben', 'SQL', 43), ('Esben', 'Tuning', 31),
  ('Kaolin', 'SQL', 56), ('Kaolin', 'Tuning', 88),
  ('Tatiana', 'SQL', 87);

SELECT name, test, score, STDDEV_POP(score) 
 OVER (PARTITION BY test) AS stddev_results FROM student_test;
+---------+--------+-------+----------------+
| name    | test   | score | stddev_results |
+---------+--------+-------+----------------+
| Chun    | SQL    |    75 |        16.9466 |
| Chun    | Tuning |    73 |        24.1247 |
| Esben   | SQL    |    43 |        16.9466 |
| Esben   | Tuning |    31 |        24.1247 |
| Kaolin  | SQL    |    56 |        16.9466 |
| Kaolin  | Tuning |    88 |        24.1247 |
| Tatiana | SQL    |    87 |        16.9466 |
+---------+--------+-------+----------------+

URL: https://mariadb.com/kb/en/stddev/https://mariadb.com/kb/en/stddev/�
�%STDDEV_POPSyntax
------

STDDEV_POP(expr)

Description
-----------

Returns the population standard deviation of expr (the square root of
VAR_POP()). You can also use STD() or STDDEV(), which are equivalent but not
standard SQL.

It is an aggregate function, and so can be used with the GROUP BY clause.

STDDEV_POP() can be used as a window function.

STDDEV_POP() returns NULL if there were no matching rows.

Examples
--------

As an aggregate function:

CREATE OR REPLACE TABLE stats (category VARCHAR(2), x INT);

INSERT INTO stats VALUES 
 ('a',1),('a',2),('a',3),
 ('b',11),('b',12),('b',20),('b',30),('b',60);

SELECT category, STDDEV_POP(x), STDDEV_SAMP(x), VAR_POP(x) 
 FROM stats GROUP BY category;
+----------+---------------+----------------+------------+
| category | STDDEV_POP(x) | STDDEV_SAMP(x) | VAR_POP(x) |
+----------+---------------+----------------+------------+
| a        |        0.8165 |         1.0000 |     0.6667 |
| b        |       18.0400 |        20.1693 |   325.4400 |
+----------+---------------+----------------+------------+

As a window function:

CREATE OR REPLACE TABLE student_test (name CHAR(10), test CHAR(10), score
TINYINT);

INSERT INTO student_test VALUES 
  ('Chun', 'SQL', 75), ('Chun', 'Tuning', 73),
  ('Esben', 'SQL', 43), ('Esben', 'Tuning', 31),
  ('Kaolin', 'SQL', 56), ('Kaolin', 'Tuning', 88),
  ('Tatiana', 'SQL', 87);

SELECT name, test, score, STDDEV_POP(score) 
 OVER (PARTITION BY test) AS stddev_results FROM student_test;
+---------+--------+-------+----------------+
| name    | test   | score | stddev_results |
+---------+--------+-------+----------------+
| Chun    | SQL    |    75 |        16.9466 |
| Chun    | Tuning |    73 |        24.1247 |
| Esben   | SQL    |    43 |        16.9466 |
| Esben   | Tuning |    31 |        24.1247 |
| Kaolin  | SQL    |    56 |        16.9466 |
| Kaolin  | Tuning |    88 |        24.1247 |
| Tatiana | SQL    |    87 |        16.9466 |
+---------+--------+-------+----------------+

URL: https://mariadb.com/kb/en/stddev_pop/https://mariadb.com/kb/en/stddev_pop/�
SUMSyntax
------

SUM([DISTINCT] expr)

Description
-----------

Returns the sum of expr. If the return set has no rows, SUM() returns NULL.
The DISTINCT keyword can be used to sum only the distinct values of expr.

SUM() can be used as a window function, although not with the DISTINCT
specifier.

Examples
--------

CREATE TABLE sales (sales_value INT);
INSERT INTO sales VALUES(10),(20),(20),(40);

SELECT SUM(sales_value) FROM sales;
+------------------+
| SUM(sales_value) |
+------------------+
|               90 |
+------------------+

SELECT SUM(DISTINCT(sales_value)) FROM sales;
+----------------------------+
| SUM(DISTINCT(sales_value)) |
+----------------------------+
|                         70 |
+----------------------------+

Commonly, SUM is used with a GROUP BY clause:

CREATE TABLE sales (name CHAR(10), month CHAR(10), units INT);

INSERT INTO sales VALUES 
 ('Chun', 'Jan', 75), ('Chun', 'Feb', 73),
 ('Esben', 'Jan', 43), ('Esben', 'Feb', 31),
 ('Kaolin', 'Jan', 56), ('Kaolin', 'Feb', 88),
 ('Tatiana', 'Jan', 87), ('Tatiana', 'Feb', 83);

SELECT name, SUM(units) FROM sales GROUP BY name;
+---------+------------+
| name    | SUM(units) |
+---------+------------+
| Chun    |        148 |
| Esben   |         74 |
| Kaolin  |        144 |
| Tatiana |        170 |
+---------+------------+

The GROUP BY clause is required when using an aggregate function along with
regular column data, otherwise the result will be a mismatch, as in the
following common type of mistake:

SELECT name,SUM(units) FROM sales
;+------+------------+
| name | SUM(units) |
+------+------------+
| Chun |        536 |
+------+------------+

As a window function:

CREATE OR REPLACE TABLE student_test (name CHAR(10), test CHAR(10), score
TINYINT);
INSERT INTO student_test VALUES 
  ('Chun', 'SQL', 75), ('Chun', 'Tuning', 73),
  ('Esben', 'SQL', 43), ('Esben', 'Tuning', 31),
  ('Kaolin', 'SQL', 56), ('Kaolin', 'Tuning', 88),
  ('Tatiana', 'SQL', 87);

SELECT name, test, score, SUM(score) OVER (PARTITION BY name) AS total_score
FROM student_test;
+---------+--------+-------+-------------+
| name    | test   | score | total_score |
+---------+--------+-------+-------------+
| Chun    | SQL    |    75 |         148 |
| Chun    | Tuning |    73 |         148 |
| Esben   | SQL    |    43 |          74 |
| Esben   | Tuning |    31 |          74 |
| Kaolin  | SQL    |    56 |         144 |
| Kaolin  | Tuning |    88 |         144 |
| Tatiana | SQL    |    87 |          87 |
+---------+--------+-------+-------------+

URL: https://mariadb.com/kb/en/sum/https://mariadb.com/kb/en/sum/N�,ST_POINTONSURFACEMariaDB starting with 10.1.2
----------------------------
ST_POINTONSURFACE() was introduced in MariaDB 10.1.2

Syntax
------

ST_PointOnSurface(g)
PointOnSurface(g)

Description
-----------

Given a geometry, returns a POINT guaranteed to intersect a surface. However,
see MDEV-7514.

ST_PointOnSurface() and PointOnSurface() are synonyms.

URL: https://mariadb.com/kb/en/st_pointonsurface/https://mariadb.com/kb/en/st_pointonsurface/�5@
�
�Y�E FLUSHZg,FLUSH QUERY CACHEDescription
-----------

You can defragment the query cache to better utilize its memory with the FLUSH
QUERY CACHE statement. The statement does not remove any queries from the
cache.

The RESET QUERY CACHE statement removes all query results from the query
cache. The FLUSH TABLES statement also does this.

URL: https://mariadb.com/kb/en/flush-query-cache/https://mariadb.com/kb/en/flush-query-cache/~�U)��P3
((��|Syntax
------

FLUSH [NO_WRITE_TO_BINLOG | LOCAL]
  flush_option [, flush_option] ...

or when flushing tables:

FLUSH [NO_WRITE_TO_BINLOG | LOCAL] TABLES [table_list]  [table_flush_option]

where table_list is a list of tables separated by , (comma).

Description
-----------

The FLUSH statement clears or reloads various internal caches used by MariaDB.
To execute FLUSH, you must have the RELOAD privilege. See GRANT.

The RESET statement is similar to FLUSH. See RESET.

You cannot issue a FLUSH statement from within a stored function or a trigger.
Doing so within a stored procedure is permitted, as long as it is not called
by a stored function or trigger. See Stored Routine Limitations, Stored
Function Limitations and Trigger Limitations.

If a listed table is a view, an error like the following will be produced:

ERROR 1347 (HY000): 'test.v' is not BASE TABLE

By default, FLUSH statements are written to the binary log and will be
replicated. The NO_WRITE_TO_BINLOG keyword (LOCAL is an alias) will ensure the
statement is not written to the binary log.

The different flush options are:

+---------------------------+------------------------------------------------+
| Option                    | Description                                    |
+---------------------------+------------------------------------------------+
| CHANGED_PAGE_BITMAPS      | XtraDB only. Internal command used for backup  |
|                           | purposes. See the Information Schema           |
|                           | CHANGED_PAGE_BITMAPS Table.                    |
+---------------------------+------------------------------------------------+
| CLIENT_STATISTICS         | Reset client statistics (see SHOW              |
|                           | CLIENT_STATISTICS).                            |
+---------------------------+------------------------------------------------+
| DES_KEY_FILE              | Reloads the DES key file (Specified with the   |
|                           | --des-key-file startup option).                |
+---------------------------+------------------------------------------------+
| HOSTS                     | Flush the hostname cache (used for converting  |
|                           | ip to host names and for unblocking blocked    |
|                           | hosts. See max_connect_errors and              |
|                           | performance_schema.host_cache                  |
+---------------------------+------------------------------------------------+
| INDEX_STATISTICS          | Reset index statistics (see SHOW               |
|                           | INDEX_STATISTICS).                             |
+---------------------------+------------------------------------------------+
| [ERROR | ENGINE |         | Close and reopen the specified log type, or    |
| GENERAL | SLOW | BINARY   | all log types if none are specified. FLUSH     |
| | RELAY] LOGS             | RELAY LOGS [connection-name] can be used to    |
|                           | flush the relay logs for a specific            |
|                           | connection. Only one connection can be         |
|                           | specified per FLUSH command. See Multi-source  |
|                           | replication. FLUSH ENGINE LOGS will delete     |
|                           | all unneeded Aria redo logs. FLUSH BINARY      |
|                           | LOGS DELETE_DOMAIN_ID=(list-of-domains) can    |
|                           | be used to discard obsolete GTID domains from  |
|                           | the server's binary log state. In order for    |
|                           | this to be successful, no event group from     |
|                           | the listed GTID domains can be present in      |
|                           | existing binary log files. If some still       |
|                           | exist, then they must be purged prior to       |
|                           | executing this command. If the command         |
|                           | completes successfully, then it also rotates   |
|                           | the binary log.                                |
+---------------------------+------------------------------------------------+
| MASTER                    | Deprecated option, use RESET MASTER instead.   |
+---------------------------+------------------------------------------------+
| PRIVILEGES                | Reload all privileges from the privilege       |
|                           | tables in the mysql database. If the server    |
|                           | is started with --skip-grant-table option,     |
|                           | this will activate the privilege tables again. |
+---------------------------+------------------------------------------------+
| QUERY CACHE               | Defragment the query cache to better utilize   |
|                           | its memory. If you want to reset the query     |
|                           | cache, you can do it with RESET QUERY CACHE.   |
+---------------------------+------------------------------------------------+
| QUERY_RESPONSE_TIME       | See the QUERY_RESPONSE_TIME plugin.            |
+---------------------------+------------------------------------------------+
| SLAVE                     | Deprecated option, use RESET REPLICA or RESET  |
|                           | SLAVE instead.                                 |
+---------------------------+------------------------------------------------+
| SSL                       | Used to dynamically reinitialize the server's  |
|                           | TLS context by reloading the files defined by  |
|                           | several TLS system variables. See FLUSH SSL    |
|                           | for more information.                          |
+---------------------------+------------------------------------------------+
| STATUS                    | Resets all server status variables that can    |
|                           | be reset to 0. Not all global status           |
|                           | variables support this, so not all global      |
|                           | values are reset. See FLUSH STATUS for more    |
|                           | information.                                   |
+---------------------------+------------------------------------------------+
| TABLE                     | Close tables given as options or all open      |
|                           | tables if no table list was used. From         |
|                           | MariaDB 10.4.1, using without any table list   |
|                           | will only close tables not in use, and tables  |
|                           | not locked by the FLUSH TABLES connection. If  |
|                           | there are no locked tables, FLUSH TABLES will  |
|                           | be instant and will not cause any waits, as    |
|                           | it no longer waits for tables in use. When a   |
|                           | table list is provided, from MariaDB 10.4.1,   |
|                           | the server will wait for the end of any        |
|                           | transactions that are using the tables.        |
|                           | Previously, FLUSH TABLES only waited for the   |
|                           | statements to complete.                        |
+---------------------------+------------------------------------------------+
| TABLES                    | Same as FLUSH TABLE.                           |
+---------------------------+------------------------------------------------+
| TABLES ... FOR EXPORT     | For InnoDB tables, flushes table changes to    |
|                           | disk to permit binary table copies while the   |
|                           | server is running. See FLUSH TABLES ... FOR    |
|                           | EXPORT for more.                               |
+---------------------------+------------------------------------------------+
| TABLES WITH READ LOCK     | Closes all open tables. New tables are only    |
|                           | allowed to be o�àpened with read locks until an  |
|                           | UNLOCK TABLES is given.                        |
+---------------------------+------------------------------------------------+
| TABLES WITH READ LOCK     | As TABLES WITH READ LOCK but also disable all  |
| AND DISABLE CHECKPOINT    | checkpoint writes by transactional table       |
|                           | engines. This is useful when doing a disk      |
|                           | snapshot of all tables.                        |
+---------------------------+------------------------------------------------+
| TABLE_STATISTICS          | Reset table statistics (see SHOW               |
|                           | TABLE_STATISTICS).                             |
+---------------------------+------------------------------------------------+
| USER_RESOURCES            | Resets all per hour user resources. This       |
|                           | enables clients that have exhausted their      |
|                           | resources to connect again.                    |
+---------------------------+------------------------------------------------+
| USER_STATISTICS           | Reset user statistics (see SHOW                |
|                           | USER_STATISTICS).                              |
+---------------------------+------------------------------------------------+
| USER_VARIABLES            | Reset user variables (see User-defined         |
|                           | variables).                                    |
+---------------------------+------------------------------------------------+

You can also use the mariadb-admin client to flush things. Use mariadb-admin
--help to examine what flush commands it supports.

FLUSH RELAY LOGS
----------------

FLUSH RELAY LOGS 'connection_name';

Compatibility with MySQL
------------------------

MariaDB starting with 10.7.0
----------------------------
The FOR CHANNEL keyword was added for MySQL compatibility. This is identical
as using the channel_name directly after the FLUSH command.

For example, one can now use:

FLUSH RELAY LOGS FOR CHANNEL 'connection_name';

FLUSH STATUS
------------

Server status variables can be reset by executing the following:

FLUSH STATUS;

Global Status Variables that Support FLUSH STATUS
-------------------------------------------------

Not all global status variables support being reset by FLUSH STATUS.
Currently, the following status variables are reset by FLUSH STATUS:

* Aborted_clients
* Aborted_connects
* Binlog_cache_disk_use
* Binlog_cache_use
* Binlog_stmt_cache_disk_use
* Binlog_stmt_cache_use
* Connection_errors_accept
* Connection_errors_internal
* Connection_errors_max_connections
* Connection_errors_peer_address
* Connection_errors_select
* Connection_errors_tcpwrap
* Created_tmp_files
* Delayed_errors
* Delayed_writes
* Feature_check_constraint
* Feature_delay_key_write
* Max_used_connections
* Opened_plugin_libraries
* Performance_schema_accounts_lost
* Performance_schema_cond_instances_lost
* Performance_schema_digest_lost
* Performance_schema_file_handles_lost
* Performance_schema_file_instances_lost
* Performance_schema_hosts_lost
* Performance_schema_locker_lost
* Performance_schema_mutex_instances_lost
* Performance_schema_rwlock_instances_lost
* Performance_schema_session_connect_attrs_lost
* Performance_schema_socket_instances_lost
* Performance_schema_stage_classes_lost
* Performance_schema_statement_classes_lost
* Performance_schema_table_handles_lost
* Performance_schema_table_instances_lost
* Performance_schema_thread_instances_lost
* Performance_schema_users_lost
* Qcache_hits
* Qcache_inserts
* Qcache_lowmem_prunes
* Qcache_not_cached
* Rpl_semi_sync_master_no_times
* Rpl_semi_sync_master_no_tx
* Rpl_semi_sync_master_timefunc_failures
* Rpl_semi_sync_master_wait_pos_backtraverse
* Rpl_semi_sync_master_yes_tx
* Rpl_transactions_multi_engine
* Server_audit_writes_failed
* Slave_retried_transactions
* Slow_launch_threads
* Ssl_accept_renegotiates
* Ssl_accepts
* Ssl_callback_cache_hits
* Ssl_client_connects
* Ssl_connect_renegotiates
* Ssl_ctx_verify_depth
* Ssl_ctx_verify_mode
* Ssl_finished_accepts
* Ssl_finished_connects
* Ssl_session_cache_hits
* Ssl_session_cache_misses
* Ssl_session_cache_overflows
* Ssl_session_cache_size
* Ssl_session_cache_timeouts
* Ssl_sessions_reused
* Ssl_used_session_cache_entries
* Subquery_cache_hit
* Subquery_cache_miss
* Table_locks_immediate
* Table_locks_waited
* Tc_log_max_pages_used
* Tc_log_page_waits
* Transactions_gtid_foreign_engine
* Transactions_multi_engine

The different usage of FLUSH TABLES
-----------------------------------

The purpose of FLUSH TABLES
---------------------------

The purpose of FLUSH TABLES is to clean up the open table cache and table
definition cache from not in use tables. This frees up memory and file
descriptors. Normally this is not needed as the caches works on a FIFO bases,
but can be useful if the server seams to use up to much memory for some reason.

The purpose of FLUSH TABLES WITH READ LOCK 
-------------------------------------------

FLUSH TABLES WITH READ LOCK is useful if you want to take a backup of some
tables. When FLUSH TABLES WITH READ LOCK returns, all write access to tables
are blocked and all tables are marked as 'properly closed' on disk. The tables
can still be used for read operations.

The purpose of FLUSH TABLES table_list
--------------------------------------

FLUSH TABLES table_list is useful if you want to copy a table object/files to
or from the server. This command puts a lock that stops new users of the table
and will wait until everyone has stopped using the table. The table is then
removed from the table definition and table cache.

Note that it's up to the user to ensure that no one is accessing the table
between FLUSH TABLES and the table is copied to or from the server. This can
be secured by using LOCK TABLES.

If there are any tables locked by the connection that is using FLUSH TABLES
all the locked tables will be closed as part of the flush and reopened and
relocked before FLUSH TABLES returns. This allows one to copy the table after
FLUSH TABLES returns without having any writes on the table. For now this
works works with most tables, except InnoDB as InnoDB may do background purges
on the table even while it's write locked.

The purpose of FLUSH TABLES table_list WITH READ LOCK
-----------------------------------------------------

FLUSH TABLES table_list WITH READ LOCK should work as FLUSH TABLES WITH READ
LOCK, but only those tables that are listed will be properly closed. However
in practice this works exactly like FLUSH TABLES WITH READ LOCK as the FLUSH
command has anyway to wait for all WRITE operations to end because we are
depending on a global read lock for this code. In the future we should
consider fixing this to instead use meta data locks.

Implementation of FLUSH TABLES commands in MariaDB 10.4.8 and above
-------------------------------------------------------------------

Implementation of FLUSH TABLES
------------------------------

* Free memory and file descriptors not in use

Implementation of FLUSH TABLES WITH READ LOCK
---------------------------------------------

* Lock all tables read only for simple old style backup.
* All background writes are suspended and tables are marked as closed.
* No statement requiring table changes are allowed for any user until UNLOCK
TABLES.

Instead of using FLUSH TABLE WITH READ LOCK one should in most cases instead
use BACKUP STAGE BLOCK_COMMIT.

Implementation of FLUSH TABLES table_list
-----------------------------------------

* Free memory and file descriptors for tables not in use from table list.
* Lock given tables as read only.
* Wait until all translations has ended that uses any of the given tables.
* Wait until all background writes are suspended and tables are marked as
closed.

Implementation of FLUSH TABLES table_list FOR EXPORT
----------------------------------------------------

* Free memory and file descriptors for tables not in use from table list
* Lock given tables as read.
* Wait until all background writes are suspended and tables �+s�����	#VARIANCESyntax
------

VARIANCE(expr)

Description
-----------

Returns the population standard variance of expr. This is an extension to
standard SQL. The standard SQL function VAR_POP() can be used instead.

Variance is calculated by

* working out the mean for the set
* for each number, subtracting the mean and squaring the result
* calculate the average of the resulting differences

It is an aggregate function, and so can be used with the GROUP BY clause.

VARIANCE() can be used as a window function.

VARIANCE() returns NULL if there were no matching rows.

Examples
--------

CREATE TABLE v(i tinyint);

INSERT INTO v VALUES(101),(99);

SELECT VARIANCE(i) FROM v;
+-------------+
| VARIANCE(i) |
+-------------+
|      1.0000 |
+-------------+

INSERT INTO v VALUES(120),(80);

SELECT VARIANCE(i) FROM v;
+-------------+
| VARIANCE(i) |
+-------------+
|    200.5000 |
+-------------+

As an aggregate function:

CREATE OR REPLACE TABLE stats (category VARCHAR(2), x INT);

INSERT INTO stats VALUES 
 ('a',1),('a',2),('a',3),
 ('b',11),('b',12),('b',20),('b',30),('b',60);

SELECT category, STDDEV_POP(x), STDDEV_SAMP(x), VAR_POP(x) 
 FROM stats GROUP BY category;
+----------+---------------+----------------+------------+
| category | STDDEV_POP(x) | STDDEV_SAMP(x) | VAR_POP(x) |
+----------+---------------+----------------+------------+
| a        |        0.8165 |         1.0000 |     0.6667 |
| b        |       18.0400 |        20.1693 |   325.4400 |
+----------+---------------+----------------+------------+

As a window function:

CREATE OR REPLACE TABLE student_test (name CHAR(10), test CHAR(10), score
TINYINT);

INSERT INTO student_test VALUES 
  ('Chun', 'SQL', 75), ('Chun', 'Tuning', 73),
  ('Esben', 'SQL', 43), ('Esben', 'Tuning', 31),
  ('Kaolin', 'SQL', 56), ('Kaolin', 'Tuning', 88),
  ('Tatiana', 'SQL', 87);

SELECT name, test, score, VAR_POP(score) 
 OVER (PARTITION BY test) AS variance_results FROM student_test;
+---------+--------+-------+------------------+
| name    | test   | score | variance_results |
+---------+--------+-------+------------------+
| Chun    | SQL    |    75 |         287.1875 |
| Chun    | Tuning |    73 |         582.0000 |
| Esben   | SQL    |    43 |         287.1875 |
| Esben   | Tuning |    31 |         582.0000 |
| Kaolin  | SQL    |    56 |         287.1875 |
| Kaolin  | Tuning |    88 |         582.0000 |
| Tatiana | SQL    |    87 |         287.1875 |
+---------+--------+-------+------------------+

URL: https://mariadb.com/kb/en/variance/https://mariadb.com/kb/en/variance/�
"VAR_POPSyntax
------

VAR_POP(expr)

Description
-----------

Returns the population standard variance of expr. It considers rows as the
whole population, not as a sample, so it has the number of rows as the
denominator. You can also use VARIANCE(), which is equivalent but is not
standard SQL.

Variance is calculated by

* working out the mean for the set
* for each number, subtracting the mean and squaring the result
* calculate the average of the resulting differences

It is an aggregate function, and so can be used with the GROUP BY clause.

VAR_POP() can be used as a window function.

VAR_POP() returns NULL if there were no matching rows.

Examples
--------

CREATE TABLE v(i tinyint);

INSERT INTO v VALUES(101),(99);

SELECT VAR_POP(i) FROM v;
+------------+
| VAR_POP(i) |
+------------+
|     1.0000 |
+------------+

INSERT INTO v VALUES(120),(80);

SELECT VAR_POP(i) FROM v;
+------------+
| VAR_POP(i) |
+------------+
|   200.5000 |
+------------+

As an aggregate function:

CREATE OR REPLACE TABLE stats (category VARCHAR(2), x INT);

INSERT INTO stats VALUES 
 ('a',1),('a',2),('a',3),
 ('b',11),('b',12),('b',20),('b',30),('b',60);

SELECT category, STDDEV_POP(x), STDDEV_SAMP(x), VAR_POP(x) 
 FROM stats GROUP BY category;
+----------+---------------+----------------+------------+
| category | STDDEV_POP(x) | STDDEV_SAMP(x) | VAR_POP(x) |
+----------+---------------+----------------+------------+
| a        |        0.8165 |         1.0000 |     0.6667 |
| b        |       18.0400 |        20.1693 |   325.4400 |
+----------+---------------+----------------+------------+

As a window function:

CREATE OR REPLACE TABLE student_test (name CHAR(10), test CHAR(10), score
TINYINT);

INSERT INTO student_test VALUES 
  ('Chun', 'SQL', 75), ('Chun', 'Tuning', 73),
  ('Esben', 'SQL', 43), ('Esben', 'Tuning', 31),
  ('Kaolin', 'SQL', 56), ('Kaolin', 'Tuning', 88),
  ('Tatiana', 'SQL', 87);

SELECT name, test, score, VAR_POP(score) 
 OVER (PARTITION BY test) AS variance_results FROM student_test;
+---------+--------+-------+------------------+
| name    | test   | score | variance_results |
+---------+--------+-------+------------------+
| Chun    | SQL    |    75 |         287.1875 |
| Esben   | SQL    |    43 |         287.1875 |
| Kaolin  | SQL    |    56 |         287.1875 |
| Tatiana | SQL    |    87 |         287.1875 |
| Chun    | Tuning |    73 |         582.0000 |
| Esben   | Tuning |    31 |         582.0000 |
| Kaolin  | Tuning |    88 |         582.0000 |
+---------+--------+-------+------------------+

URL: https://mariadb.com/kb/en/var_pop/https://mariadb.com/kb/en/var_pop/�8@
�]�].SHOW SLAVE STATUSe
*SET SQL_LOG_BINSyntax
------

SET [SESSION] sql_log_bin = {0|1}

Description
-----------

Sets the sql_log_bin system variable, which disables or enables binary logging
for the current connection, if the client has the SUPER privilege. The
statement is refused with an error if the client does not have that privilege.

Before MariaDB 5.5 and before MySQL 5.6 one could also set sql_log_bin as a
global variable. This was disabled as this was too dangerous as it could
damage replication.

URL: https://mariadb.com/kb/en/set-sql_log_bin/https://mariadb.com/kb/en/set-sql_log_bin/�
'(SHOW PROFILESSyntax
------

SHOW PROFILES

Description
-----------

The SHOW PROFILES statement displays profiling information that indicates
resource usage for statements executed during the course of the current
session. It is used together with SHOW PROFILE.

URL: https://mariadb.com/kb/en/show-profiles/https://mariadb.com/kb/en/show-profiles/�3SHOW QUERY_RESPONSE_TIMEIt is possible to use SHOW QUERY_RESPONSE_TIME as an alternative for
retrieving information from the QUERY_RESPONSE_TIME plugin.

This was introduced as part of the Information Schema plugin extension.

URL: https://mariadb.com/kb/en/show-query_response_time/https://mariadb.com/kb/en/show-query_response_time/��!BINLOGSyntax
------

BINLOG 'str'

Description
-----------

BINLOG is an internal-use statement. It is generated by the mariadb-binlog
program as the printable representation of certain events in binary log files.
The 'str' value is a base 64-encoded string that the server decodes to
determine the data change indicated by the corresponding event. This statement
requires the SUPER privilege (<= MariaDB 10.5.1) or the BINLOG REPLAY
privilege (>= MariaDB 10.5.2).

URL: https://mariadb.com/kb/en/binlog/https://mariadb.com/kb/en/binlog/�
I%LOAD INDEXSyntax
------

LOAD INDEX INTO CACHE
 tbl_index_list [, tbl_index_list] ...

tbl_index_list:
 tbl_name
  [[INDEX|KEY] (index_name[, index_name] ...)]
  [IGNORE LEAVES]

Description
-----------

The LOAD INDEX INTO CACHE statement preloads a table index into the key cache
to which it has been assigned by an explicit CACHE INDEX statement, or into
the default key cache otherwise. LOAD INDEX INTO CACHE is used only for MyISAM
or Aria tables.

The IGNORE LEAVES modifier causes only blocks for the nonleaf nodes of the
index to be preloaded.

URL: https://mariadb.com/kb/en/load-index/https://mariadb.com/kb/en/load-index/���'Q\�j�Qh.
Q

��i�Syntax
------

SHOW SLAVE ["connection_name"] STATUS [FOR CHANNEL "connection_name"]
SHOW REPLICA ["connection_name"] STATUS -- From MariaDB 10.5.1

or

SHOW ALL SLAVES STATUS
SHOW ALL REPLICAS STATUS -- From MariaDB 10.5.1

Description
-----------

This statement is to be run on a replica and provides status information on
essential parameters of the replica threads.

This statement requires the SUPER privilege, the REPLICATION_CLIENT privilege,
or, from MariaDB 10.5.2, the REPLICATION SLAVE ADMIN privilege, or, from
MariaDB 10.5.9, the REPLICA MONITOR privilege.

Multi-Source
------------

The ALL and "connection_name" options allow you to connect to many primaries
at the same time.

ALL SLAVES (or ALL REPLICAS from MariaDB 10.5.1) gives you a list of all
connections to the primary nodes.

The rows will be sorted according to Connection_name.

If you specify a connection_name, you only get the information about that
connection. If connection_name is not used, then the name set by
default_master_connection is used. If the connection name doesn't exist you
will get an error: There is no master connection for 'xxx'.

MariaDB starting with 10.7.0
----------------------------
The FOR CHANNEL keyword was added for MySQL compatibility. This is identical
to using the channel_name directly after SHOW SLAVE.

Column Descriptions
-------------------

+---------------------+------------------------------------------------------+
| Name                | Description                                          |
+---------------------+------------------------------------------------------+
| Connection_name     | Name of the primary connection. Returned with SHOW   |
|                     | ALL SLAVES STATUS (or SHOW ALL REPLICAS STATUS from  |
|                     | MariaDB 10.5.1) only.                                |
+---------------------+------------------------------------------------------+
| Slave_SQL_State     | State of SQL thread. Returned with SHOW ALL SLAVES   |
|                     | STATUS (or SHOW ALL REPLICAS STATUS from MariaDB     |
|                     | 10.5.1) only. See Slave SQL Thread States.           |
+---------------------+------------------------------------------------------+
| Slave_IO_State      | State of I/O thread. See Slave I/O Thread States.    |
+---------------------+------------------------------------------------------+
| Master_host         | Master host that the replica is connected to.        |
+---------------------+------------------------------------------------------+
| Master_user         | Account user name being used to connect to the       |
|                     | primary.                                             |
+---------------------+------------------------------------------------------+
| Master_port         | The port being used to connect to the primary.       |
+---------------------+------------------------------------------------------+
| Connect_Retry       | Time in seconds between retries to connect. The      |
|                     | default is 60. The CHANGE MASTER TO statement can    |
|                     | set this. The master-retry-count option determines   |
|                     | the maximum number of reconnection attempts.         |
+---------------------+------------------------------------------------------+
| Master_Log_File     | Name of the primary binary log file that the I/O     |
|                     | thread is currently reading from.                    |
+---------------------+------------------------------------------------------+
| Read_Master_Log_Pos | Position up to which the I/O thread has read in the  |
|                     | current primary binary log file.                     |
+---------------------+------------------------------------------------------+
| Relay_Log_File      | Name of the relay log file that the SQL thread is    |
|                     | currently processing.                                |
+---------------------+------------------------------------------------------+
| Relay_Log_Pos       | Position up to which the SQL thread has finished     |
|                     | processing in the current relay log file.            |
+---------------------+------------------------------------------------------+
| Relay_Master_Log_Fi | Name of the primary binary log file that contains    |
| e                   | the most recent event executed by the SQL thread.    |
+---------------------+------------------------------------------------------+
| Slave_IO_Running    | Whether the replica I/O thread is running and        |
|                     | connected (Yes), running but not connected to a      |
|                     | primary (Connecting) or not running (No).            |
+---------------------+------------------------------------------------------+
| Slave_SQL_Running   | Whether or not the SQL thread is running.            |
+---------------------+------------------------------------------------------+
| Replicate_Rewrite_D | Databases specified for replicating  and rewriting   |
|                     | with the replicate_rewrite_db option. Added in       |
|                     | MariaDB 10.11                                        |
+---------------------+------------------------------------------------------+
| Replicate_Do_DB     | Databases specified for replicating with the         |
|                     | replicate_do_db option.                              |
+---------------------+------------------------------------------------------+
| Replicate_Ignore_DB | Databases specified for ignoring with the            |
|                     | replicate_ignore_db option.                          |
+---------------------+------------------------------------------------------+
| Replicate_Do_Table  | Tables specified for replicating with the            |
|                     | replicate_do_table option.                           |
+---------------------+------------------------------------------------------+
| Replicate_Ignore_Ta | Tables specified for ignoring with the               |
| le                  | replicate_ignore_table option.                       |
+---------------------+------------------------------------------------------+
| Replicate_Wild_Do_T | Tables specified for replicating with the            |
| ble                 | replicate_wild_do_table option.                      |
+---------------------+------------------------------------------------------+
| Replicate_Wild_Igno | Tables specified for ignoring with the               |
| e_Table             | replicate_wild_ignore_table option.                  |
+---------------------+------------------------------------------------------+
| Last_Errno          | Alias for Last_SQL_Errno (see below)                 |
+---------------------+------------------------------------------------------+
| Last Error          | Alias for Last_SQL_Error (see below)                 |
+---------------------+------------------------------------------------------+
| Skip_Counter        | Number of events that a replica skips from the       |
|                     | master, as recorded in the sql_slave_skip_counter    |
|                     | system variable.                                     |
+---------------------+------------------------------------------------------+
| Exec_Master_Log_Pos | Position up to which the SQL thread has processed    |
|                     | in the current master binary log file. Can be used   |
|                     | to start a new replica from a current replica with   |
|                     | the CHANGE MASTER TO ... MASTER_LOG_POS option.      |
+---------------------+------------------------------------------------------+
| Relay_Log_Space     | Total size of all relay log files combined.          |
+---------------------+------------------------------------------------------+
| Until_Condition     |                                                      |
+---------------------+------------------------------------------------------+
| Until_Log_File      | The MASTER_LOG_FILE value of the START SLAVE UNTIL   |
|                     �9{`| condition.                                           |
+---------------------+------------------------------------------------------+
| Until_Log_Pos       | The MASTER_LOG_POS value of the START SLAVE UNTIL    |
|                     | condition.                                           |
+---------------------+------------------------------------------------------+
| Master_SSL_Allowed  | Whether an SSL connection is permitted (Yes), not    |
|                     | permitted (No) or permitted but without the replica  |
|                     | having SSL support enabled (Ignored)                 |
+---------------------+------------------------------------------------------+
| Master_SSL_CA_File  | The MASTER_SSL_CA option of the CHANGE MASTER TO     |
|                     | statement.                                           |
+---------------------+------------------------------------------------------+
| Master_SSL_CA_Path  | The MASTER_SSL_CAPATH option of the CHANGE MASTER    |
|                     | TO statement.                                        |
+---------------------+------------------------------------------------------+
| Master_SSL_Cert     | The MASTER_SSL_CERT option of the CHANGE MASTER TO   |
|                     | statement.                                           |
+---------------------+------------------------------------------------------+
| Master_SSL_Cipher   | The MASTER_SSL_CIPHER option of the CHANGE MASTER    |
|                     | TO statement.                                        |
+---------------------+------------------------------------------------------+
| Master_SSL_Key      | The MASTER_SSL_KEY option of the CHANGE MASTER TO    |
|                     | statement.                                           |
+---------------------+------------------------------------------------------+
| Seconds_Behind_Mast | Difference between the timestamp logged on the       |
| r                   | master for the event that the replica is currently   |
|                     | processing, and the current timestamp on the         |
|                     | replica. Zero if the replica is not currently        |
|                     | processing an event. With serial replication,        |
|                     | seconds_behind_master is updated when the SQL        |
|                     | thread begins executing a transaction. With          |
|                     | parallel replication, seconds_behind_master is       |
|                     | updated only after transactions commit. Starting in  |
|                     | MariaDB 10.3.38, 10.4.28, 10.5.19, 10.6.12, 10.8.7,  |
|                     | 10.9.5, 10.10.3, and 10.11.2, an exception is drawn  |
|                     | on the parallel replica to additionally update       |
|                     | seconds_behind_master when the first transaction     |
|                     | received after idling is queued to a worker for      |
|                     | execution, to provide a reliable initial value for   |
|                     | the duration until a transaction commits.            |
|                     | Additional behaviors to be aware of are as follows:  |
|                     | 1) Seconds_Behind_Master will update for ignored     |
|                     | events, e.g. those skipped due to                    |
|                     | sql_slave_skip_counter. 2) On the serial replica,    |
|                     | transactions with prior timestamps can update        |
|                     | Seconds_Behind_Master such that it can go            |
|                     | backwards, though this is not true for the parallel  |
|                     | replica. 3) When configured with MASTER_DELAY, as a  |
|                     | replicated transaction begins executing (i.e. on a   |
|                     | serial or post-idle parallel replica),               |
|                     | Seconds_Behind_Master will update before delaying,   |
|                     | and while delaying occurs will grow to encompass     |
|                     | the configured value. 4) There is a known issue,     |
|                     | tracked by MDEV-17516, such that                     |
|                     | Seconds_Behind_Master will initially present as 0    |
|                     | on replica restart until a replicated transaction    |
|                     | begins executing, even if the last replica session   |
|                     | was lagging behind when stopped.                     |
+---------------------+------------------------------------------------------+
| Master_SSL_Verify_S | The MASTER_SSL_VERIFY_SERVER_CERT option of the      |
| rver_Cert           | CHANGE MASTER TO statement.                          |
+---------------------+------------------------------------------------------+
| Last_IO_Errno       | Error code of the most recent error that caused the  |
|                     | I/O thread to stop (also recorded in the replica's   |
|                     | error log). 0 means no error. RESET SLAVE or RESET   |
|                     | MASTER will reset this value.                        |
+---------------------+------------------------------------------------------+
| Last_IO_Error       | Error message of the most recent error that caused   |
|                     | the I/O thread to stop (also recorded in the         |
|                     | replica's error log). An empty string means no       |
|                     | error. RESET SLAVE or RESET MASTER will reset this   |
|                     | value.                                               |
+---------------------+------------------------------------------------------+
| Last_SQL_Errno      | Error code of the most recent error that caused the  |
|                     | SQL thread to stop (also recorded in the replica's   |
|                     | error log). 0 means no error. RESET SLAVE or RESET   |
|                     | MASTER will reset this value.                        |
+---------------------+------------------------------------------------------+
| Last_SQL_Error      | Error message of the most recent error that caused   |
|                     | the SQL thread to stop (also recorded in the         |
|                     | replica's error log). An empty string means no       |
|                     | error. RESET SLAVE or RESET MASTER will reset this   |
|                     | value.                                               |
+---------------------+------------------------------------------------------+
| Replicate_Ignore_Se | List of server_ids that are currently being ignored  |
| ver_Ids             | for replication purposes, or an empty string for     |
|                     | none, as specified in the IGNORE_SERVER_IDS option   |
|                     | of the CHANGE MASTER TO statement.                   |
+---------------------+------------------------------------------------------+
| Master_Server_Id    | The master's server_id value.                        |
+---------------------+------------------------------------------------------+
| Master_SSL_Crl      | The MASTER_SSL_CRL option of the CHANGE MASTER TO    |
|                     | statement.                                           |
+---------------------+------------------------------------------------------+
| Master_SSL_Crlpath  | The MASTER_SSL_CRLPATH option of the CHANGE MASTER   |
|                     | TO statement.                                        |
+---------------------+------------------------------------------------------+
| Using_Gtid          | Whether or not global transaction ID's are being     |
|                     | used for replication (can be No, Slave_Pos, or       |
|                     | Current_Pos).                                        |
+---------------------+------------------------------------------------------+
| Gtid_IO_Pos         | Current global transaction ID value.                 |
+---------------------+------------------------------------------------------+
| Retried_transaction | Number of retried transactions for this c��"onnection.  |
|                     | Returned with SHOW ALL SLAVES STATUS only.           |
+---------------------+------------------------------------------------------+
| Max_relay_log_size  | Max relay log size for this connection. Returned     |
|                     | with SHOW ALL SLAVES STATUS only.                    |
+---------------------+------------------------------------------------------+
| Executed_log_entrie | How many log entries the replica has executed.       |
|                     | Returned with SHOW ALL SLAVES STATUS only.           |
+---------------------+------------------------------------------------------+
| Slave_received_hear | How many heartbeats we have got from the master.     |
| beats               | Returned with SHOW ALL SLAVES STATUS only.           |
+---------------------+------------------------------------------------------+
| Slave_heartbeat_per | How often to request a heartbeat packet from the     |
| od                  | master (in seconds). Returned with SHOW ALL SLAVES   |
|                     | STATUS only.                                         |
+---------------------+------------------------------------------------------+
| Gtid_Slave_Pos      | GTID of the last event group replicated on a         |
|                     | replica server, for each replication domain, as      |
|                     | stored in the gtid_slave_pos system variable.        |
|                     | Returned with SHOW ALL SLAVES STATUS only.           |
+---------------------+------------------------------------------------------+
| SQL_Delay           | Value specified by MASTER_DELAY in CHANGE MASTER     |
|                     | (or 0 if none).                                      |
+---------------------+------------------------------------------------------+
| SQL_Remaining_Delay | When the replica is delaying the execution of an     |
|                     | event due to MASTER_DELAY, this is the number of     |
|                     | seconds of delay remaining before the event will be  |
|                     | applied. Otherwise, the value is NULL.               |
+---------------------+------------------------------------------------------+
| Slave_SQL_Running_S | The state of the SQL driver threads, same as in      |
| ate                 | SHOW PROCESSLIST. When the replica is delaying the   |
|                     | execution of an event due to MASTER_DELAY, this      |
|                     | field displays: "Waiting until MASTER_DELAY seconds  |
|                     | after master executed event".                        |
+---------------------+------------------------------------------------------+
| Slave_DDL_Groups    | This status variable counts the occurrence of DDL    |
|                     | statements.  This is a replica-side counter for      |
|                     | optimistic parallel replication.                     |
+---------------------+------------------------------------------------------+
| Slave_Non_Transacti | This status variable counts the occurrence of        |
| nal_Groups          | non-transactional event groups.  This is a           |
|                     | replica-side counter for optimistic parallel         |
|                     | replication.                                         |
+---------------------+------------------------------------------------------+
| Slave_Transactional | This status variable counts the occurrence of        |
| Groups              | transactional event groups.  This is a replica-side  |
|                     | counter for optimistic parallel replication.         |
+---------------------+------------------------------------------------------+

SHOW REPLICA STATUS
-------------------

MariaDB starting with 10.5.1
----------------------------
SHOW REPLICA STATUS is an alias for SHOW SLAVE STATUS from MariaDB 10.5.1.

Examples
--------

If you issue this statement using the mariadb client, you can use a \G
statement terminator rather than a semicolon to obtain a more readable
vertical layout.

SHOW SLAVE STATUS\G
*************************** 1. row ***************************
       Slave_IO_State: Waiting for master to send event
         Master_Host: db01.example.com
         Master_User: replicant
         Master_Port: 3306
        Connect_Retry: 60
       Master_Log_File: mariadb-bin.000010
     Read_Master_Log_Pos: 548
       Relay_Log_File: relay-bin.000004
        Relay_Log_Pos: 837
    Relay_Master_Log_File: mariadb-bin.000010
      Slave_IO_Running: Yes
      Slave_SQL_Running: Yes
       Replicate_Do_DB:
     Replicate_Ignore_DB:
     Replicate_Do_Table:
   Replicate_Ignore_Table:
   Replicate_Wild_Do_Table:
 Replicate_Wild_Ignore_Table:
         Last_Errno: 0
         Last_Error:
        Skip_Counter: 0
     Exec_Master_Log_Pos: 548
       Relay_Log_Space: 1497
       Until_Condition: None
       Until_Log_File:
        Until_Log_Pos: 0
     Master_SSL_Allowed: No
     Master_SSL_CA_File:
     Master_SSL_CA_Path:
       Master_SSL_Cert:
      Master_SSL_Cipher:
       Master_SSL_Key:
    Seconds_Behind_Master: 0
Master_SSL_Verify_Server_Cert: No
        Last_IO_Errno: 0
        Last_IO_Error:
       Last_SQL_Errno: 0
       Last_SQL_Error:
 Replicate_Ignore_Server_Ids:
      Master_Server_Id: 101
       Master_SSL_Crl:
     Master_SSL_Crlpath:
         Using_Gtid: No
         Gtid_IO_Pos:

SHOW ALL SLAVES STATUS\G
*************************** 1. row ***************************
       Connection_name:
       Slave_SQL_State: Slave has read all relay log; waiting for the
slave I/O thread to update it
       Slave_IO_State: Waiting for master to send event
         Master_Host: db01.example.com
         Master_User: replicant
         Master_Port: 3306
        Connect_Retry: 60
       Master_Log_File: mariadb-bin.000010
     Read_Master_Log_Pos: 3608
       Relay_Log_File: relay-bin.000004
        Relay_Log_Pos: 3897
    Relay_Master_Log_File: mariadb-bin.000010
      Slave_IO_Running: Yes
      Slave_SQL_Running: Yes
       Replicate_Do_DB:
     Replicate_Ignore_DB:
     Replicate_Do_Table:
   Replicate_Ignore_Table:
   Replicate_Wild_Do_Table:
 Replicate_Wild_Ignore_Table:
         Last_Errno: 0
         Last_Error:
        Skip_Counter: 0
     Exec_Master_Log_Pos: 3608
       Relay_Log_Space: 4557
       Until_Condition: None
       Until_Log_File:
        Until_Log_Pos: 0
     Master_SSL_Allowed: No
     Master_SSL_CA_File:
     Master_SSL_CA_Path:
       Master_SSL_Cert:
      Master_SSL_Cipher:
       Master_SSL_Key:
    Seconds_Behind_Master: 0
Master_SSL_Verify_Server_Cert: No
        Last_IO_Errno: 0
        Last_IO_Error:
       Last_SQL_Errno: 0
       Last_SQL_Error:
 Replicate_Ignore_Server_Ids:
      Master_Server_Id: 101
       Master_SSL_Crl:
     Master_SSL_Crlpath:
         Using_Gtid: No
         Gtid_IO_Pos:
    Retried_transactions: 0
     Max_relay_log_size: 104857600
    Executed_log_entries: 40
  Slave_received_heartbeats: 11
   Slave_heartbeat_period: 1800.000
       Gtid_Slave_Pos: 0-101-2320

You can also access some of the variables directly from status variables:

SET @@default_master_connection="test" ;
show status like "%slave%"

Variable_name   Value
Com_show_slave_hosts    0
Com_show_slave_status   0
Com_start_all_slaves    0
Com_start_slave 0
Com_stop_all_slaves     0
Com_stop_slave  0
Rpl_semi_sync_slave_status      OFF
Slave_connections       0
Slave_heartbeat_period  1800.000
Slave_open_temp_tables  0
Slave_received_heartbeats       0
Slave_retried_transactions      0
Slave_running   OFF
Slaves_connected        0
Slaves_running  1

URL: https://mariadb.com/kb/en/show-replica-status/�-ݤ���#VAR_SAMPSyntax
------

VAR_SAMP(expr)

Description
-----------

Returns the sample variance of expr. That is, the denominator is the number of
rows minus one.

It is an aggregate function, and so can be used with the GROUP BY clause.

VAR_SAMP() can be used as a window function.

VAR_SAMP() returns NULL if there were no matching rows.

Examples
--------

As an aggregate function:

CREATE OR REPLACE TABLE stats (category VARCHAR(2), x INT);

INSERT INTO stats VALUES 
 ('a',1),('a',2),('a',3),
 ('b',11),('b',12),('b',20),('b',30),('b',60);

SELECT category, STDDEV_POP(x), STDDEV_SAMP(x), VAR_POP(x) 
 FROM stats GROUP BY category;
+----------+---------------+----------------+------------+
| category | STDDEV_POP(x) | STDDEV_SAMP(x) | VAR_POP(x) |
+----------+---------------+----------------+------------+
| a        |        0.8165 |         1.0000 |     0.6667 |
| b        |       18.0400 |        20.1693 |   325.4400 |
+----------+---------------+----------------+------------+

As a window function:

CREATE OR REPLACE TABLE student_test (name CHAR(10), test CHAR(10), score
TINYINT);

INSERT INTO student_test VALUES 
  ('Chun', 'SQL', 75), ('Chun', 'Tuning', 73),
  ('Esben', 'SQL', 43), ('Esben', 'Tuning', 31),
  ('Kaolin', 'SQL', 56), ('Kaolin', 'Tuning', 88),
  ('Tatiana', 'SQL', 87);

SELECT name, test, score, VAR_SAMP(score) 
 OVER (PARTITION BY test) AS variance_results FROM student_test;
+---------+--------+-------+------------------+
| name    | test   | score | variance_results |
+---------+--------+-------+------------------+
| Chun    | SQL    |    75 |         382.9167 |
| Chun    | Tuning |    73 |         873.0000 |
| Esben   | SQL    |    43 |         382.9167 |
| Esben   | Tuning |    31 |         873.0000 |
| Kaolin  | SQL    |    56 |         382.9167 |
| Kaolin  | Tuning |    88 |         873.0000 |
| Tatiana | SQL    |    87 |         382.9167 |
+---------+--------+-------+------------------+

URL: https://mariadb.com/kb/en/var_samp/https://mariadb.com/kb/en/var_samp/�9"CHARSETSyntax
------

CHARSET(str)

Description
-----------

Returns the character set of the string argument. If str is not a string, it
is considered as a binary string (so the function returns 'binary'). This
applies to NULL, too. The return value is a string in the utf8 character set.

Examples
--------

SELECT CHARSET('abc');
+----------------+
| CHARSET('abc') |
+----------------+
| latin1         |
+----------------+

SELECT CHARSET(CONVERT('abc' USING utf8));
+------------------------------------+
| CHARSET(CONVERT('abc' USING utf8)) |
+------------------------------------+
| utf8                               |
+------------------------------------+

SELECT CHARSET(USER());
+-----------------+
| CHARSET(USER()) |
+-----------------+
| utf8            |
+-----------------+

URL: https://mariadb.com/kb/en/charset/https://mariadb.com/kb/en/charset/�c
'COERCIBILITYSyntax
------

COERCIBILITY(str)

Description
-----------

Returns the collation coercibility value of the string argument. Coercibility
defines what will be converted to what in case of collation conflict, with an
expression with higher coercibility being converted to the collation of an
expression with lower coercibility.

+-----------------------------+---------------------------+------------------+
| Coercibility                | Description               | Example          |
+-----------------------------+---------------------------+------------------+
| 0                           | Explicit                  | Value using a    |
|                             |                           | COLLATE clause   |
+-----------------------------+---------------------------+------------------+
| 1                           | No collation              | Concatenated     |
|                             |                           | strings using    |
|                             |                           | different        |
|                             |                           | collations       |
+-----------------------------+---------------------------+------------------+
| 2                           | Implicit                  | Column value     |
+-----------------------------+---------------------------+------------------+
| 3                           | Constant                  | USER() return    |
|                             |                           | value            |
+-----------------------------+---------------------------+------------------+
| 4                           | Coercible                 | Literal string   |
+-----------------------------+---------------------------+------------------+
| 5                           | Ignorable                 | NULL or derived  |
|                             |                           | from NULL        |
+-----------------------------+---------------------------+------------------+

Examples
--------

SELECT COERCIBILITY('abc' COLLATE latin1_swedish_ci);
+-----------------------------------------------+
| COERCIBILITY('abc' COLLATE latin1_swedish_ci) |
+-----------------------------------------------+
|                                             0 |
+-----------------------------------------------+

SELECT COERCIBILITY(USER());
+----------------------+
| COERCIBILITY(USER()) |
+----------------------+
|                    3 |
+----------------------+

SELECT COERCIBILITY('abc');
+---------------------+
| COERCIBILITY('abc') |
+---------------------+
|                   4 |
+---------------------+

URL: https://mariadb.com/kb/en/coercibility/https://mariadb.com/kb/en/coercibility/�-SHOW FUNCTION CODESyntax
------

SHOW FUNCTION CODE func_name

Description
-----------

SHOW FUNCTION CODE shows a representation of the internal implementation of
the stored function.

It is similar to SHOW PROCEDURE CODE but for stored functions.

URL: https://mariadb.com/kb/en/show-function-code/https://mariadb.com/kb/en/show-function-code/��-LOCK IN SHARE MODEInnoDB supports row-level locking. Selected rows can be locked using LOCK IN
SHARE MODE or FOR UPDATE. In both cases, a lock is acquired on the rows read
by the query, and it will be released when the current transaction is
committed.

When LOCK IN SHARE MODE is specified in a SELECT statement, MariaDB will wait
until all transactions that have modified the rows are committed. Then, a
write lock is acquired. All transactions can read the rows, but if they want
to modify them, they have to wait until your transaction is committed.

If autocommit is set to 1 (the default), the LOCK IN SHARE MODE and FOR UPDATE
clauses have no effect.

URL: https://mariadb.com/kb/en/lock-in-share-mode/https://mariadb.com/kb/en/lock-in-share-mode/�	/$PROCEDUREThe PROCEDURE clause of SELECT passes the whole result set to a Procedure
which will process it. These Procedures are not Stored Procedures, and can
only be written in the C language, so it is necessary to recompile the server.

Currently, the only available procedure is ANALYSE, which examines the
resultset and suggests the optimal datatypes for each column. It is defined in
the sql/sql_analyse.cc file, and can be used as an example to create more
Procedures.

This clause cannot be used in a view's definition.

URL: https://mariadb.com/kb/en/procedure/https://mariadb.com/kb/en/procedure/wjwgl�
�p�����"'CURRENT_ROLESyntax
------

CURRENT_ROLE, CURRENT_ROLE()

Description
-----------

Returns the current role name. This determines your access privileges. The
return value is a string in the utf8 character set.

If there is no current role, NULL is returned.

The output of SELECT CURRENT_ROLE is equivalent to the contents of the
ENABLED_ROLES Information Schema table.

USER() returns the combination of user and host used to login. CURRENT_USER()
returns the account used to determine current connection's privileges.

Examples
--------

SELECT CURRENT_ROLE;
+--------------+
| CURRENT_ROLE |
+--------------+
| NULL         |
+--------------+

SET ROLE staff;

SELECT CURRENT_ROLE;
+--------------+
| CURRENT_ROLE |
+--------------+
| staff        |
+--------------+

URL: https://mariadb.com/kb/en/current_role/https://mariadb.com/kb/en/current_role/�i'CURRENT_USERSyntax
------

CURRENT_USER, CURRENT_USER()

Description
-----------

Returns the user name and host name combination for the MariaDB account that
the server used to authenticate the current client. This account determines
your access privileges. The return value is a string in the utf8 character set.

The value of CURRENT_USER() can differ from the value of USER().
CURRENT_ROLE() returns the current active role.

Examples
--------

shell> mysql --user="anonymous"

select user(),current_user();
+---------------------+----------------+
| user()              | current_user() |
+---------------------+----------------+
| anonymous@localhost | @localhost     |
+---------------------+----------------+

When calling CURRENT_USER() in a stored procedure, it returns the owner of the
stored procedure, as defined with DEFINER.

URL: https://mariadb.com/kb/en/current_user/https://mariadb.com/kb/en/current_user/�l#DATABASESyntax
------

DATABASE()
SCHEMA()

Description
-----------

Returns the default (current) database name as a string in the utf8 character
set. If there is no default database, DATABASE() returns NULL. Within a stored
routine, the default database is the database that the routine is associated
with, which is not necessarily the same as the database that is the default in
the calling context.

SCHEMA() is a synonym for DATABASE().

To select a default database, the USE statement can be run. Another way to set
the default database is specifying its name at mariadb command line client
startup.

Examples
--------

SELECT DATABASE();
+------------+
| DATABASE() |
+------------+
| NULL       |
+------------+

USE test;
Database changed

SELECT DATABASE();
+------------+
| DATABASE() |
+------------+
| test       |
+------------+

URL: https://mariadb.com/kb/en/database/https://mariadb.com/kb/en/database/�
�%FOUND_ROWSSyntax
------

FOUND_ROWS()

Description
-----------

A SELECT statement may include a LIMIT clause to restrict the number of rows
the server returns to the client. In some cases, it is desirable to know how
many rows the statement would have returned without the LIMIT, but without
running the statement again. To obtain this row count, include a
SQL_CALC_FOUND_ROWS option in the SELECT statement, and then invoke
FOUND_ROWS() afterwards.

You can also use FOUND_ROWS() to obtain the number of rows returned by a
SELECT which does not contain a LIMIT clause. In this case you don't need to
use the SQL_CALC_FOUND_ROWS option. This can be useful for example in a stored
procedure.

Also, this function works with some other statements which return a resultset,
including SHOW, DESC and HELP. For DELETE ... RETURNING you should use
ROW_COUNT(). It also works as a prepared statement, or after executing a
prepared statement.

Statements which don't return any results don't affect FOUND_ROWS() - the
previous value will still be returned.

Warning: When used after a CALL statement, this function returns the number of
rows selected by the last query in the procedure, not by the whole procedure.

Statements using the FOUND_ROWS() function are not safe for replication.

Examples
--------

SHOW ENGINES\G
*************************** 1. row ***************************
   Engine: CSV
  Support: YES
  Comment: Stores tables as CSV files
Transactions: NO
     XA: NO
 Savepoints: NO
*************************** 2. row ***************************
   Engine: MRG_MyISAM
  Support: YES
  Comment: Collection of identical MyISAM tables
Transactions: NO
     XA: NO
 Savepoints: NO

...

*************************** 8. row ***************************
   Engine: PERFORMANCE_SCHEMA
  Support: YES
  Comment: Performance Schema
Transactions: NO
     XA: NO
 Savepoints: NO
8 rows in set (0.000 sec)

SELECT FOUND_ROWS();
+--------------+
| FOUND_ROWS() |
+--------------+
|           8 |
+--------------+

SELECT SQL_CALC_FOUND_ROWS * FROM tbl_name WHERE id > 100 LIMIT 10;

SELECT FOUND_ROWS();
+--------------+
| FOUND_ROWS() |
+--------------+
|           23 |
+--------------+

URL: https://mariadb.com/kb/en/found_rows/https://mariadb.com/kb/en/found_rows/��DUALDescription
-----------

You are allowed to specify DUAL as a dummy table name in situations where no
tables are referenced, such as the following SELECT statement:

SELECT 1 + 1 FROM DUAL;
+-------+
| 1 + 1 |
+-------+
|     2 |
+-------+

DUAL is purely for the convenience of people who require that all SELECT
statements should have FROM and possibly other clauses. MariaDB ignores the
clauses. MariaDB does not require FROM DUAL if no tables are referenced.

FROM DUAL could be used when you only SELECT computed values, but require a
WHERE clause, perhaps to test that a script correctly handles empty resultsets:

SELECT 1 FROM DUAL WHERE FALSE;
Empty set (0.00 sec)

URL: https://mariadb.com/kb/en/dual/https://mariadb.com/kb/en/dual/�=@
����!+LOAD DATA INFILE��DOSyntax
------

DO expr [, expr] ...

Description
-----------

DO executes the expressions but does not return any results. In most respects,
DO is shorthand for SELECT expr, ..., but has the advantage that it is
slightly faster when you do not care about the result.

DO is useful primarily with functions that have side effects, such as
RELEASE_LOCK().

URL: https://mariadb.com/kb/en/do/https://mariadb.com/kb/en/do/�>@
���!1Useful MariaDB Queries�?@
��:{"EXPLAIN��*EXPLAIN ANALYZEThe syntax for the EXPLAIN ANALYZE feature was changed to ANALYZE statement,
available since MariaDB 10.1.0. See ANALYZE statement.

URL: https://mariadb.com/kb/en/explain-analyze/https://mariadb.com/kb/en/explain-analyze/��*Binary LiteralsBinary literals can be written in one of the following formats: b'value',
B'value' or 0bvalue, where value is a string composed by 0 and 1 digits.

Binary literals are interpreted as binary strings, and are convenient to
represent VARBINARY, BINARY or BIT values.

To convert a binary literal into an integer, just add 0.

Examples
--------

Printing the value as a binary string:

SELECT 0b1000001;
+-----------+
| 0b1000001 |
+-----------+
| A         |
+-----------+

Converting the same value into a number:

SELECT 0b1000001+0;
+-------------+
| 0b1000001+0 |
+-------------+
|          65 |
+-------------+

URL: https://mariadb.com/kb/en/binary-literals/https://mariadb.com/kb/en/binary-literals/�����$�:���4���
��o�c��ESyntax
------

LOAD DATA [LOW_PRIORITY | CONCURRENT] [LOCAL] INFILE 'file_name'
  [REPLACE | IGNORE]
  INTO TABLE tbl_name
  [CHARACTER SET charset_name]
  [{FIELDS | COLUMNS}
    [TERMINATED BY 'string']
    [[OPTIONALLY] ENCLOSED BY 'char']
    [ESCAPED BY 'char']
  ]
  [LINES
    [STARTING BY 'string']
    [TERMINATED BY 'string']
  ]
  [IGNORE number {LINES|ROWS}]
  [(col_name_or_user_var,...)]
  [SET col_name = expr,...]

Description
-----------

LOAD DATA INFILE is unsafe for statement-based replication.

Reads rows from a text file into the designated table on the database at a
very high speed. The file name must be given as a literal string.

Files are written to disk using the SELECT INTO OUTFILE statement. You can
then read the files back into a table using the LOAD DATA INFILE statement.
The FIELDS and LINES clauses are the same in both statements. These clauses
are optional, but if both are specified then the FIELDS clause must precede
LINES.

Executing this statement activates INSERT triggers.

One must have the FILE privilege to be able to execute LOAD DATA INFILE. This
is to ensure normal users cannot read system files. LOAD DATA LOCAL INFILE
does not have this requirement.

If the secure_file_priv system variable is set (by default it is not), the
loaded file must be present in the specified directory.

Note that MariaDB's systemd unit file restricts access to /home, /root, and
/run/user by default. See Configuring access to home directories.

LOAD DATA LOCAL INFILE
----------------------

When you execute the LOAD DATA INFILE statement, MariaDB Server attempts to
read the input file from its own file system. By contrast, when you execute
the LOAD DATA LOCAL INFILE statement, the client attempts to read the input
file from its file system, and it sends the contents of the input file to the
MariaDB Server. This allows you to load files from the client's local file
system into the database.

If you don't want to permit this operation (perhaps for security reasons), you
can disable the LOAD DATA LOCAL INFILE statement on either the server or the
client.

* The LOAD DATA LOCAL INFILE statement can be disabled on the server by
setting the local_infile system variable to 0.
* The LOAD DATA LOCAL INFILE statement can be disabled on the client. If you
are using MariaDB Connector/C, this can be done by unsetting the
CLIENT_LOCAL_FILES capability flag with the mysql_real_connect function or by
unsetting the MYSQL_OPT_LOCAL_INFILE option with mysql_optionsv function. If
you are using a different client or client library, then see the documentation
for your specific client or client library to determine how it handles the
LOAD DATA LOCAL INFILE statement.

If the LOAD DATA LOCAL INFILE statement is disabled by either the server or
the client and if the user attempts to execute it, then the server will cause
the statement to fail with the following error message:

The used command is not allowed with this MariaDB version

Note that it is not entirely accurate to say that the MariaDB version does not
support the command. It would be more accurate to say that the MariaDB
configuration does not support the command. See MDEV-20500 for more
information.

From MariaDB 10.5.2, the error message is more accurate:

The used command is not allowed because the MariaDB server or client 
 has disabled the local infile capability

REPLACE and IGNORE
------------------

If you load data from a file into a table that already contains data and has a
primary key, you may encounter issues where the statement attempts to insert a
row with a primary key that already exists. When this happens, the statement
fails with Error 1064, protecting the data already on the table. If you want
MariaDB to overwrite duplicates, use the REPLACE keyword.

The REPLACE keyword works like the REPLACE statement. Here, the statement
attempts to load the data from the file. If the row does not exist, it adds it
to the table. If the row contains an existing primary key, it replaces the
table data. That is, in the event of a conflict, it assumes the file contains
the desired row.

This operation can cause a degradation in load speed by a factor of 20 or more
if the part that has already been loaded is larger than the capacity of the
InnoDB Buffer Pool. This happens because it causes a lot of turnaround in the
buffer pool.

Use the IGNORE keyword when you want to skip any rows that contain a
conflicting primary key. Here, the statement attempts to load the data from
the file. If the row does not exist, it adds it to the table. If the row
contains an existing primary key, it ignores the addition request and moves on
to the next. That is, in the event of a conflict, it assumes the table
contains the desired row.

Character-sets
--------------

When the statement opens the file, it attempts to read the contents using the
default character-set, as defined by the character_set_database system
variable.

In the cases where the file was written using a character-set other than the
default, you can specify the character-set to use with the CHARACTER SET
clause in the statement. It ignores character-sets specified by the SET NAMES
statement and by the character_set_client system variable. Setting the
CHARACTER SET clause to a value of binary indicates "no conversion."

The statement interprets all fields in the file as having the same
character-set, regardless of the column data type. To properly interpret file
contents, you must ensure that it was written with the correct character-set.
If you write a data file with mariadb-dump -T or with the SELECT INTO OUTFILE
statement with the mariadb client, be sure to use the --default-character-set
option, so that the output is written with the desired character-set.

When using mixed character sets, use the CHARACTER SET clause in both SELECT
INTO OUTFILE and LOAD DATA INFILE to ensure that MariaDB correctly interprets
the escape sequences.

The character_set_filesystem system variable controls the interpretation of
the filename.

It is currently not possible to load data files that use the ucs2 character
set.

Preprocessing Inputs
--------------------

col_name_or_user_var can be a column name, or a user variable. In the case of
a variable, the SET statement can be used to preprocess the value before
loading into the table.

Priority and Concurrency
------------------------

In storage engines that perform table-level locking (MyISAM, MEMORY and
MERGE), using the LOW_PRIORITY keyword, MariaDB delays insertions until no
other clients are reading from the table. Alternatively, when using the MyISAM
storage engine, you can use the CONCURRENT keyword to perform concurrent
insertion.

The LOW_PRIORITY and CONCURRENT keywords are mutually exclusive. They cannot
be used in the same statement.

Progress Reporting
------------------

The LOAD DATA INFILE statement supports progress reporting. You may find this
useful when dealing with long-running operations. Using another client you can
issue a SHOW PROCESSLIST query to check the progress of the data load.

Using mariadb-import
--------------------

MariaDB ships with a separate utility for loading data from files:
mariadb-import (or mysqlimport before MariaDB 10.5). It operates by sending
LOAD DATA INFILE statements to the server.

Using mariadb-import you can compress the file using the --compress option, to
get better performance over slow networks, providing both the client and
server support the compressed protocol. Use the --local option to load from
the local file system.

Indexing
--------

In cases where the storage engine supports ALTER TABLE... DISABLE KEYS
statements (MyISAM and Aria), the LOAD DATA INFILE statement automatically
disables indexes during the execution.

Examples
--------

You have a file with this content (note the the separator is ',', not tab,
which is the default):

2,2
3,3
4,4
5,5
6,8

CREATE TABLE t1 (a int, b int, c int, d int, PRIMARY KEY (a));
LOAD DATA LOCAL INFILE 
 '/tmp/loaddata7.dat' INTO TABLE t1 FIELDS TERMINATED BY ',' (a,b) SET c=a+b;
SELECT * FROM t1;
+------+------+------+
| a    | b    | c    |
+------+------+------+
|    2 |    2 |    4 |
| D�6cThis page is intended to be a quick reference of commonly-used and/or useful
queries in MariaDB.

Creating a Table
----------------

CREATE TABLE t1 ( a INT );
CREATE TABLE t2 ( b INT );
CREATE TABLE student_tests (
 name CHAR(10), test CHAR(10), 
 score TINYINT, test_date DATE
);

See CREATE TABLE for more.

Inserting Records
-----------------

INSERT INTO t1 VALUES (1), (2), (3);
INSERT INTO t2 VALUES (2), (4);

INSERT INTO student_tests 
 (name, test, score, test_date) VALUES
 ('Chun', 'SQL', 75, '2012-11-05'), 
 ('Chun', 'Tuning', 73, '2013-06-14'),
 ('Esben', 'SQL', 43, '2014-02-11'), 
 ('Esben', 'Tuning', 31, '2014-02-09'), 
 ('Kaolin', 'SQL', 56, '2014-01-01'),
 ('Kaolin', 'Tuning', 88, '2013-12-29'), 
 ('Tatiana', 'SQL', 87, '2012-04-28'), 
 ('Tatiana', 'Tuning', 83, '2013-09-30');

See INSERT for more.

Using AUTO_INCREMENT
--------------------

The AUTO_INCREMENT attribute is used to automatically generate a unique
identity for new rows.

CREATE TABLE student_details (
 id INT NOT NULL AUTO_INCREMENT, name CHAR(10), 
 date_of_birth DATE, PRIMARY KEY (id)
);

When inserting, the id field can be omitted, and is automatically created.

INSERT INTO student_details (name,date_of_birth) VALUES 
 ('Chun', '1993-12-31'), 
 ('Esben','1946-01-01'),
 ('Kaolin','1996-07-16'),
 ('Tatiana', '1988-04-13');

SELECT * FROM student_details;
+----+---------+---------------+
| id | name    | date_of_birth |
+----+---------+---------------+
|  1 | Chun    | 1993-12-31    |
|  2 | Esben   | 1946-01-01    |
|  3 | Kaolin  | 1996-07-16    |
|  4 | Tatiana | 1988-04-13    |
+----+---------+---------------+

See AUTO_INCREMENT for more.

Querying from two tables on a common value
------------------------------------------

SELECT * FROM t1 INNER JOIN t2 ON t1.a = t2.b;

This kind of query is called a join - see JOINS for more.

Finding the Maximum Value
-------------------------

SELECT MAX(a) FROM t1;
+--------+
| MAX(a) |
+--------+
|      3 |
+--------+

See the MAX() function for more, as well as Finding the maximum value and
grouping the results below for a more practical example.

Finding the Minimum Value
-------------------------

SELECT MIN(a) FROM t1;
+--------+
| MIN(a) |
+--------+
|      1 |
+--------+

See the MIN() function for more.

Finding the Average Value
-------------------------

SELECT AVG(a) FROM t1;
+--------+
| AVG(a) |
+--------+
| 2.0000 |
+--------+

See the AVG() function for more.

Finding the Maximum Value and Grouping the Results
--------------------------------------------------

SELECT name, MAX(score) FROM student_tests GROUP BY name;
+---------+------------+
| name    | MAX(score) |
+---------+------------+
| Chun    |         75 |
| Esben   |         43 |
| Kaolin  |         88 |
| Tatiana |         87 |
+---------+------------+

See the MAX() function for more.

Ordering Results
----------------

SELECT name, test, score FROM student_tests ORDER BY score DESC;
+---------+--------+-------+
| name    | test   | score |
+---------+--------+-------+
| Kaolin  | Tuning |    88 |
| Tatiana | SQL    |    87 |
| Tatiana | Tuning |    83 |
| Chun    | SQL    |    75 |
| Chun    | Tuning |    73 |
| Kaolin  | SQL    |    56 |
| Esben   | SQL    |    43 |
| Esben   | Tuning |    31 |
+---------+--------+-------+

See ORDER BY for more.

Finding the Row with the Minimum of a Particular Column
-------------------------------------------------------

In this example, we want to find the lowest test score for any student.

SELECT name,test, score FROM student_tests WHERE score=(SELECT MIN(score) FROM
student);
+-------+--------+-------+
| name  | test   | score |
+-------+--------+-------+
| Esben | Tuning |    31 |
+-------+--------+-------+

Finding Rows with the Maximum Value of a Column by Group
--------------------------------------------------------

This example returns the best test results of each student:

SELECT name, test, score FROM student_tests st1 WHERE score = (
 SELECT MAX(score) FROM student st2 WHERE st1.name = st2.name
); 
+---------+--------+-------+
| name    | test   | score |
+---------+--------+-------+
| Chun    | SQL    |    75 |
| Esben   | SQL    |    43 |
| Kaolin  | Tuning |    88 |
| Tatiana | SQL    |    87 |
+---------+--------+-------+

Calculating Age
---------------

The TIMESTAMPDIFF function can be used to calculate someone's age:

SELECT CURDATE() AS today;
+------------+
| today      |
+------------+
| 2014-02-17 |
+------------+

SELECT name, date_of_birth, TIMESTAMPDIFF(YEAR,date_of_birth,'2014-08-02') AS
age 
 FROM student_details;
+---------+---------------+------+
| name    | date_of_birth | age  |
+---------+---------------+------+
| Chun    | 1993-12-31    |   20 |
| Esben   | 1946-01-01    |   68 |
| Kaolin  | 1996-07-16    |   18 |
| Tatiana | 1988-04-13    |   26 |
+---------+---------------+------+

See TIMESTAMPDIFF() for more.

Using User-defined Variables
----------------------------

This example sets a user-defined variable with the average test score, and
then uses it in a later query to return all results above the average.

SELECT @avg_score:= AVG(score) FROM student_tests;
+-------------------------+
| @avg_score:= AVG(score) |
+-------------------------+
|            67.000000000 |
+-------------------------+

SELECT * FROM student_tests WHERE score > @avg_score;
+---------+--------+-------+------------+
| name    | test   | score | test_date  |
+---------+--------+-------+------------+
| Chun    | SQL    |    75 | 2012-11-05 |
| Chun    | Tuning |    73 | 2013-06-14 |
| Kaolin  | Tuning |    88 | 2013-12-29 |
| Tatiana | SQL    |    87 | 2012-04-28 |
| Tatiana | Tuning |    83 | 2013-09-30 |
+---------+--------+-------+------------+

User-defined variables can also be used to add an incremental counter to a
resultset:

SET @count = 0;

SELECT @count := @count + 1 AS counter, name, date_of_birth FROM
student_details;
+---------+---------+---------------+
| counter | name    | date_of_birth |
+---------+---------+---------------+
|       1 | Chun    | 1993-12-31    |
|       2 | Esben   | 1946-01-01    |
|       3 | Kaolin  | 1996-07-16    |
|       4 | Tatiana | 1988-04-13    |
+---------+---------+---------------+

See User-defined Variables for more.

View Tables in Order of Size
----------------------------

Returns a list of all tables in the database, ordered by size:

SELECT table_schema as `DB`, table_name AS `Table`, 
 ROUND(((data_length + index_length) / 1024 / 1024), 2) `Size (MB)`
 FROM information_schema.TABLES
 ORDER BY (data_length + index_length) DESC;

+--------------------+---------------------------------------+-----------+
| DB                 | Table                                 | Size (MB) |
+--------------------+---------------------------------------+-----------+
| wordpress          | wp_simple_history_contexts            |      7.05 |
| wordpress          | wp_posts                              |      6.59 |
| wordpress          | wp_simple_history                     |      3.05 |
| wordpress          | wp_comments                           |      2.73 |
| wordpress          | wp_commentmeta                        |      2.47 |
| wordpress          | wp_simple_login_log                   |      2.03 |
...

Removing Duplicates
-------------------

MariaDB starting with 10.3
--------------------------
The following syntax is only valid MariaDB 10.3 and beyond:

This example assumes there's a unique ID, but that all other fields are
identical. In the example below, there are 4 records, 3 of which are
duplicates, so two of the three duplicates need to be removed. The
intermediate SELECT is not necessary, but demonstrates what is being returned.

CREATE TABLE t (id INT, f1 VARCHAR(2));

INSERT INTO t VALUES (1,'a'), (2,'a'), (3,'b'), (4,'a');

SELECT * FROM t t1, t t2 WHERE t1.f1=t2.f1 AND t1.id<>t2.id AND t1.id=(
 SELECT MAX(id) FROM t tab WHERE tab.f1=t1.f1
);
+------+------+------+------+
| id   | f1   | id   | f1   |
+------+------+------+------+
|    4 | a    |    1 | a    |
|    4 | a    |    2 | a    |
+------+------+------+------+

DELETE FROM t WHERE id IN (
 SELECT t2.id FROM t t1, t t2 WHERE t1.f1=t2.f1 AND t1.id<>t2.id}�GSyntax
------

EXPLAIN tbl_name [col_name | wild]

Or

EXPLAIN [EXTENDED | PARTITIONS | FORMAT=JSON] 
 {SELECT select_options | UPDATE update_options | DELETE delete_options}

Description
-----------

The EXPLAIN statement can be used either as a synonym for DESCRIBE or as a way
to obtain information about how MariaDB executes a SELECT, UPDATE or DELETE
statement:

* 'EXPLAIN tbl_name' is synonymous with 
 'DESCRIBE tbl_name' or
 'SHOW COLUMNS FROM tbl_name'.
* When you precede a SELECT, UPDATE or a DELETE statement with the keyword 
 EXPLAIN, MariaDB displays information from the optimizer
 about the query execution plan. That is, MariaDB explains how it would
 process the SELECT, UPDATE or DELETE, including information about how tables
 are joined and in which order. EXPLAIN EXTENDED can be
 used to provide additional information.
* EXPLAIN PARTITIONS is useful only when examining queries involving
partitioned tables. For details, see Partition pruning and selection.
* ANALYZE statement performs the query as well as producing EXPLAIN output,
and provides actual as well as estimated statistics.
* EXPLAIN output can be printed in the slow query log. See EXPLAIN in the Slow
Query Log for details.

SHOW EXPLAIN shows the output of a running statement. In some cases, its
output can be closer to reality than EXPLAIN.

The ANALYZE statement runs a statement and returns information about its
execution plan. It also shows additional columns, to check how much the
optimizer's estimation about filtering and found rows are close to reality.

There is an online EXPLAIN Analyzer that you can use to share EXPLAIN and
EXPLAIN EXTENDED output with others.

EXPLAIN can acquire metadata locks in the same way that SELECT does, as it
needs to know table metadata and, sometimes, data as well.

Columns in EXPLAIN ... SELECT
-----------------------------

+--------------------------------------+--------------------------------------+
| Column name                          | Description                          |
+--------------------------------------+--------------------------------------+
| id                                   | Sequence number that shows in which  |
|                                      | order tables are joined.             |
+--------------------------------------+--------------------------------------+
| select_type                          | What kind of SELECT the table comes  |
|                                      | from.                                |
+--------------------------------------+--------------------------------------+
| table                                | Alias name of table. Materialized    |
|                                      | temporary tables for sub queries     |
|                                      | are named <subquery#>                |
+--------------------------------------+--------------------------------------+
| type                                 | How rows are found from the table    |
|                                      | (join type).                         |
+--------------------------------------+--------------------------------------+
| possible_keys                        | keys in table that could be used to  |
|                                      | find rows in the table               |
+--------------------------------------+--------------------------------------+
| key                                  | The name of the key that is used to  |
|                                      | retrieve rows. NULL is no key was    |
|                                      | used.                                |
+--------------------------------------+--------------------------------------+
| key_len                              | How many bytes of the key that was   |
|                                      | used (shows if we are using only     |
|                                      | parts of the multi-column key).      |
+--------------------------------------+--------------------------------------+
| ref                                  | The reference that is used as the    |
|                                      | key value.                           |
+--------------------------------------+--------------------------------------+
| rows                                 | An estimate of how many rows we      |
|                                      | will find in the table for each key  |
|                                      | lookup.                              |
+--------------------------------------+--------------------------------------+
| Extra                                | Extra information about this join.   |
+--------------------------------------+--------------------------------------+

Here are descriptions of the values for some of the more complex columns in
EXPLAIN ... SELECT:

"Select_type" Column
--------------------

The select_type column can have the following values:

+-----------------+-----------------------------------+-----------------------+
| Value           | Description                       | Comment               |
+-----------------+-----------------------------------+-----------------------+
| DEPENDENT       | The SUBQUERY is DEPENDENT.        |                       |
| SUBQUERY        |                                   |                       |
+-----------------+-----------------------------------+-----------------------+
| DEPENDENT UNION | The UNION is DEPENDENT.           |                       |
+-----------------+-----------------------------------+-----------------------+
| DERIVED         | The SELECT is DERIVED from the    |                       |
|                 | PRIMARY.                          |                       |
+-----------------+-----------------------------------+-----------------------+
| MATERIALIZED    | The SUBQUERY is MATERIALIZED.     | Materialized tables   |
|                 |                                   | will be populated at  |
|                 |                                   | first access and      |
|                 |                                   | will be accessed by   |
|                 |                                   | the primary key (=    |
|                 |                                   | one key lookup).      |
|                 |                                   | Number of rows in     |
|                 |                                   | EXPLAIN shows the     |
|                 |                                   | cost of populating    |
|                 |                                   | the table             |
+-----------------+-----------------------------------+-----------------------+
| PRIMARY         | The SELECT is in the outermost    |                       |
|                 | query, but there is also a        |                       |
|                 | SUBQUERY within it.               |                       |
+-----------------+-----------------------------------+-----------------------+
| SIMPLE          | It is a simple SELECT query       |                       |
|                 | without any SUBQUERY or UNION.    |                       |
+-----------------+-----------------------------------+-----------------------+
| SUBQUERY        | The SELECT is a SUBQUERY of the   |                       |
|                 | PRIMARY.                          |                       |
+-----------------+-----------------------------------+-----------------------+
| UNCACHEABLE     | The SUBQUERY is UNCACHEABLE.      |                       |
| SUBQUERY        |                                   |                       |
+-----------------+-----------------------------------+-----------------------+
| UNCACHEABLE     | The UNION is UNCACHEABLE.         |                       |
| UNION           |                                   |                       |
+-----------------+-----------------------------------+-----------------------+
| UNION           | The SELECT is a UNION of the      |                       |
|                 | PRIMARY.                          |                       |
+-----------------+-------------------ΎDA----------------+-----------------------+
| UNION RESULT    | The result of the UNION.          |                       |
+-----------------+-----------------------------------+-----------------------+
| LATERAL DERIVED | The SELECT uses a Lateral         |                       |
|                 | Derived optimization              |                       |
+-----------------+-----------------------------------+-----------------------+

"Type" Column
-------------

This column contains information on how the table is accessed.

+------------------------+---------------------------------------------------+
| Value                  | Description                                       |
+------------------------+---------------------------------------------------+
| ALL                    | A full table scan is done for the table (all      |
|                        | rows are read). This is bad if the table is       |
|                        | large and the table is joined against a previous  |
|                        | table!  This happens when the optimizer could     |
|                        | not find any usable index to access rows.         |
+------------------------+---------------------------------------------------+
| const                  | There is only one possibly matching row in the    |
|                        | table. The row is read before the optimization    |
|                        | phase and all columns in the table are treated    |
|                        | as constants.                                     |
+------------------------+---------------------------------------------------+
| eq_ref                 | A unique index is used to find the rows. This is  |
|                        | the best possible plan to find the row.           |
+------------------------+---------------------------------------------------+
| fulltext               | A fulltext index is used to access the rows.      |
+------------------------+---------------------------------------------------+
| index_merge            | A 'range' access is done for for several index    |
|                        | and the found rows are merged. The key column     |
|                        | shows which keys are used.                        |
+------------------------+---------------------------------------------------+
| index_subquery         | This is similar as ref, but used for sub queries  |
|                        | that are transformed to key lookups.              |
+------------------------+---------------------------------------------------+
| index                  | A full scan over the used index.  Better than     |
|                        | ALL but still bad if index is large and the       |
|                        | table is joined against a previous table.         |
+------------------------+---------------------------------------------------+
| range                  | The table will be accessed with a key over one    |
|                        | or more value ranges.                             |
+------------------------+---------------------------------------------------+
| ref_or_null            | Like 'ref' but in addition another search for     |
|                        | the 'null' value is done if the first value was   |
|                        | not found. This happens usually with sub queries. |
+------------------------+---------------------------------------------------+
| ref                    | A non unique index or prefix of an unique index   |
|                        | is used to find the rows. Good if the prefix      |
|                        | doesn't match many rows.                          |
+------------------------+---------------------------------------------------+
| system                 | The table has 0 or 1 rows.                        |
+------------------------+---------------------------------------------------+
| unique_subquery        | This is similar as eq_ref, but used for sub       |
|                        | queries that are transformed to key lookups       |
+------------------------+---------------------------------------------------+

"Extra" Column
--------------

This column consists of one or more of the following values, separated by ';'

Note that some of these values are detected after the optimization phase.

The optimization phase can do the following changes to the WHERE clause:

* Add the expressions from the ON and USING clauses to the WHERE
 clause.
* Constant propagation:  If there is column=constant, replace all column
 instances with this constant.
* Replace all columns from 'const' tables with their values.
* Remove the used key columns from the WHERE (as this will be tested as
 part of the key lookup).
* Remove impossible constant sub expressions.
 For example WHERE '(a=1 and a=2) OR b=1' becomes 'b=1'.
* Replace columns with other columns that has identical values:
 Example:  WHERE a=b and a=c may be treated
 as 'WHERE a=b and a=c and b=c'.
* Add extra conditions to detect impossible row conditions earlier. This
 happens mainly with OUTER JOIN where we in some cases add detection
 of NULL values in the WHERE (Part of 'Not exists' optimization).
 This can cause an unexpected 'Using where' in the Extra column.
* For each table level we remove expressions that have already been tested when
 we read the previous row. Example: When joining tables t1 with t2
 using the following WHERE 't1.a=1 and t1.a=t2.b', we don't have to
 test 't1.a=1' when checking rows in t2 as we already know that this
 expression is true.

+------------------------+---------------------------------------------------+
| Value                  | Description                                       |
+------------------------+---------------------------------------------------+
| const row not found    | The table was a system table (a table with        |
|                        | should exactly one row), but no row was found.    |
+------------------------+---------------------------------------------------+
| Distinct               | If distinct optimization (remove duplicates) was  |
|                        | used. This is marked only for the last table in   |
|                        | the SELECT.                                       |
+------------------------+---------------------------------------------------+
| Full scan on NULL key  | The table is a part of the sub query and if the   |
|                        | value that is used to match the sub query will    |
|                        | be NULL, we will do a full table scan.            |
+------------------------+---------------------------------------------------+
| Impossible HAVING      | The used HAVING clause is always false so the     |
|                        | SELECT will return no rows.                       |
+------------------------+---------------------------------------------------+
| Impossible WHERE       | The used WHERE clause is always false so the      |
| noticed after reading  | SELECT will return no rows. This case was         |
| const tables.          | detected after we had read all 'const' tables     |
|                        | and used the column values as constant in the     |
|                        | WHERE clause. For example: WHERE const_column=5   |
|                        | and const_column had a value of 4.                |
+------------------------+---------------------------------------------------+
| Impossible WHERE       | The used WHERE clause is always false so the      |
|                        | SELECT will return no rows. For example: WHERE    |
|                        | 1=2                                               |
+------------------------+---------------------------------------------------+
| No matching min/max    | During early optimization of MIN()/MAX() values   |
| row                    | it was detected that no row could match the       |
|                        | WHERE clause. The MIN()/MAX() function will       |
|                        | return NULL.                                      |
+------------------------+------------------------------------o�---------------+
| no matching row in     | The table was a const table (a table with only    |
| const table            | one possible matching row), but no row was found. |
+------------------------+---------------------------------------------------+
| No tables used         | The SELECT was a sub query that did not use any   |
|                        | tables. For example a there was no FROM clause    |
|                        | or a FROM DUAL clause.                            |
+------------------------+---------------------------------------------------+
| Not exists             | Stop searching after more row if we find one      |
|                        | single matching row. This optimization is used    |
|                        | with LEFT JOIN where one is explicitly searching  |
|                        | for rows that doesn't exists in the LEFT JOIN     |
|                        | TABLE. Example: SELECT * FROM t1 LEFT JOIN t2 on  |
|                        | (...) WHERE t2.not_null_column IS NULL.  As       |
|                        | t2.not_null_column can only be NULL if there was  |
|                        | no matching row for on condition, we can stop     |
|                        | searching if we find a single matching row.       |
+------------------------+---------------------------------------------------+
| Open_frm_only          | For information_schema tables.  Only the frm      |
|                        | (table definition file was opened) was opened     |
|                        | for each matching row.                            |
+------------------------+---------------------------------------------------+
| Open_full_table        | For information_schema tables. A full table open  |
|                        | for each matching row is done to retrieve the     |
|                        | requested information. (Slow)                     |
+------------------------+---------------------------------------------------+
| Open_trigger_only      | For information_schema tables. Only the trigger   |
|                        | file definition was opened for each matching row. |
+------------------------+---------------------------------------------------+
| Range checked for      | This only happens when there was no good default  |
| each record (index     | index to use but there may some index that could  |
| map: ...)              | be used when we can treat all columns from        |
|                        | previous table as constants.  For each row        |
|                        | combination the optimizer will decide which       |
|                        | index to use (if any) to fetch a row from this    |
|                        | table. This is not fast, but faster than a full   |
|                        | table scan that is the only other choice. The     |
|                        | index map is a bitmask that shows which index     |
|                        | are considered for each row condition.            |
+------------------------+---------------------------------------------------+
| Scanned 0/1/all        | For information_schema tables. Shows how many     |
| databases              | times we had to do a directory scan.              |
+------------------------+---------------------------------------------------+
| Select tables          | All tables in the join was optimized away. This   |
| optimized away         | happens when we are only using COUNT(*), MIN()    |
|                        | and MAX() functions in the SELECT and we where    |
|                        | able to replace all of these with constants.      |
+------------------------+---------------------------------------------------+
| Skip_open_table        | For information_schema tables. The queried table  |
|                        | didn't need to be opened.                         |
+------------------------+---------------------------------------------------+
| unique row not found   | The table was detected to be a const table (a     |
|                        | table with only one possible matching row)        |
|                        | during the early optimization phase, but no row   |
|                        | was found.                                        |
+------------------------+---------------------------------------------------+
| Using filesort         | Filesort is needed to resolve the query. This     |
|                        | means an extra phase where we first collect all   |
|                        | columns to sort, sort them with a disk based      |
|                        | merge sort and then use the sorted set to         |
|                        | retrieve the rows in sorted order. If the column  |
|                        | set is small, we store all the columns in the     |
|                        | sort file to not have to go to the database to    |
|                        | retrieve them again.                              |
+------------------------+---------------------------------------------------+
| Using index            | Only the index is used to retrieve the needed     |
|                        | information from the table. There is no need to   |
|                        | perform an extra seek to retrieve the actual      |
|                        | record.                                           |
+------------------------+---------------------------------------------------+
| Using index condition  | Like 'Using where' but the where condition is     |
|                        | pushed down to the table engine for internal      |
|                        | optimization at the index level.                  |
+------------------------+---------------------------------------------------+
| Using index            | Like 'Using index condition' but in addition we   |
| condition(BKA)         | use batch key access to retrieve rows.            |
+------------------------+---------------------------------------------------+
| Using index for        | The index is being used to resolve a GROUP BY or  |
| group-by               | DISTINCT query. The rows are not read.  This is   |
|                        | very efficient if the table has a lot of          |
|                        | identical index entries as duplicates are         |
|                        | quickly jumped over.                              |
+------------------------+---------------------------------------------------+
| Using intersect(...)   | For index_merge joins. Shows which index are      |
|                        | part of the intersect.                            |
+------------------------+---------------------------------------------------+
| Using join buffer      | We store previous row combinations in a row       |
|                        | buffer to be able to match each row against all   |
|                        | of the rows combinations in the join buffer at    |
|                        | one go.                                           |
+------------------------+---------------------------------------------------+
| Using sort_union(...)  | For index_merge joins. Shows which index are      |
|                        | part of the union.                                |
+------------------------+---------------------------------------------------+
| Using temporary        | A temporary table is created to hold the result.  |
|                        | This typically happens if you are using GROUP     |
|                        | BY, DISTINCT or ORDER BY.                         |
+------------------------+---------------------------------------------------+
| Using where            | A WHERE expression (in additional to the          |
|                        | possible key lookup) is used to check if the row  |
|                        | should be accepted. If you don't have 'Using      |
|                        | where' together with a join type of ALL, you are  |
|                        | probably doing something wrong!                   |
+------------------------+---------------------------------------------------+
| Using where with       |h'�� Like 'Using where' but the where condition is     |
| pushed condition       | pushed down to the table engine for internal      |
|                        | optimization at the row level.                    |
+------------------------+---------------------------------------------------+
| Using buffer           | The UPDATE statement will first buffer the rows,  |
|                        | and then run the updates, rather than do updates  |
|                        | on the fly. See Using Buffer UPDATE Algorithm     |
|                        | for a detailed explanation.                       |
+------------------------+---------------------------------------------------+

EXPLAIN EXTENDED
----------------

The EXTENDED keyword adds another column, filtered, to the output. This is a
percentage estimate of the table rows that will be filtered by the condition.

An EXPLAIN EXTENDED will always throw a warning, as it adds extra Message
information to a subsequent SHOW WARNINGS statement. This includes what the
SELECT query would look like after optimizing and rewriting rules are applied
and how the optimizer qualifies columns and tables.

Examples
--------

As synonym for DESCRIBE or SHOW COLUMNS FROM:

DESCRIBE city;
+------------+----------+------+-----+---------+----------------+
| Field      | Type     | Null | Key | Default | Extra          |
+------------+----------+------+-----+---------+----------------+
| Id         | int(11)  | NO   | PRI | NULL    | auto_increment |
| Name       | char(35) | YES  |     | NULL    |                |
| Country    | char(3)  | NO   | UNI |         |                |
| District   | char(20) | YES  | MUL |         |                |
| Population | int(11)  | YES  |     | NULL    |                |
+------------+----------+------+-----+---------+----------------+

A simple set of examples to see how EXPLAIN can identify poor index usage:

CREATE TABLE IF NOT EXISTS `employees_example` (
 `id` int(11) NOT NULL AUTO_INCREMENT,
 `first_name` varchar(30) NOT NULL,
 `last_name` varchar(40) NOT NULL,
 `position` varchar(25) NOT NULL,
 `home_address` varchar(50) NOT NULL,
 `home_phone` varchar(12) NOT NULL,
 `employee_code` varchar(25) NOT NULL,
 PRIMARY KEY (`id`),
 UNIQUE KEY `employee_code` (`employee_code`),
 KEY `first_name` (`first_name`,`last_name`)
) ENGINE=Aria;

INSERT INTO `employees_example` (`first_name`, `last_name`, `position`,
`home_address`, `home_phone`, `employee_code`)
 VALUES
 ('Mustapha', 'Mond', 'Chief Executive Officer', '692 Promiscuous Plaza',
'326-555-3492', 'MM1'),
 ('Henry', 'Foster', 'Store Manager', '314 Savage Circle', '326-555-3847',
'HF1'),
 ('Bernard', 'Marx', 'Cashier', '1240 Ambient Avenue', '326-555-8456', 'BM1'),
 ('Lenina', 'Crowne', 'Cashier', '281 Bumblepuppy Boulevard', '328-555-2349',
'LC1'),
 ('Fanny', 'Crowne', 'Restocker', '1023 Bokanovsky Lane', '326-555-6329',
'FC1'),
 ('Helmholtz', 'Watson', 'Janitor', '944 Soma Court', '329-555-2478', 'HW1');

SHOW INDEXES FROM employees_example;
+-------------------+------------+---------------+--------------+--------------
+-----------+-------------+----------+--------+------+------------+---------+--
------------+
| Table             | Non_unique | Key_name      | Seq_in_index | Column_name 
 | Collation | Cardinality | Sub_part | Packed | Null | Index_type | Comment |
Index_comment |
+-------------------+------------+---------------+--------------+--------------
+-----------+-------------+----------+--------+------+------------+---------+--
------------+
| employees_example |          0 | PRIMARY       |            1 | id          
 | A         |           7 |     NULL | NULL   |      | BTREE      |         |
       |
| employees_example |          0 | employee_code |            1 |
employee_code | A         |           7 |     NULL | NULL   |      | BTREE    
 |         |               |
| employees_example |          1 | first_name    |            1 | first_name  
 | A         |        NULL |     NULL | NULL   |      | BTREE      |         |
       |
| employees_example |          1 | first_name    |            2 | last_name   
 | A         |        NULL |     NULL | NULL   |      | BTREE      |         |
       |
+-------------------+------------+---------------+--------------+--------------
+-----------+-------------+----------+--------+------+------------+---------+--
------------+

SELECT on a primary key:

EXPLAIN SELECT * FROM employees_example WHERE id=1;
+------+-------------+-------------------+-------+---------------+---------+---
-----+-------+------+-------+
| id   | select_type | table             | type  | possible_keys | key     |
key_len | ref   | rows | Extra |
+------+-------------+-------------------+-------+---------------+---------+---
-----+-------+------+-------+
|    1 | SIMPLE      | employees_example | const | PRIMARY       | PRIMARY | 4
   | const |    1 |       |
+------+-------------+-------------------+-------+---------------+---------+---
-----+-------+------+-------+

The type is const, which means that only one possible result could be
returned. Now, returning the same record but searching by their phone number:

EXPLAIN SELECT * FROM employees_example WHERE home_phone='326-555-3492';
+------+-------------+-------------------+------+---------------+------+-------
-+------+------+-------------+
| id   | select_type | table             | type | possible_keys | key  |
key_len | ref  | rows | Extra       |
+------+-------------+-------------------+------+---------------+------+-------
-+------+------+-------------+
|    1 | SIMPLE      | employees_example | ALL  | NULL          | NULL | NULL 
 | NULL |    6 | Using where |
+------+-------------+-------------------+------+---------------+------+-------
-+------+------+-------------+

Here, the type is All, which means no index could be used. Looking at the rows
count, a full table scan (all six rows) had to be performed in order to
retrieve the record. If it's a requirement to search by phone number, an index
will have to be created.

SHOW EXPLAIN example:

SHOW EXPLAIN FOR 1;
+------+-------------+-------+-------+---------------+------+---------+------+-
-------+-------------+
| id   | select_type | table | type  | possible_keys | key  | key_len | ref  |
rows    | Extra       |
+------+-------------+-------+-------+---------------+------+---------+------+-
-------+-------------+
|    1 | SIMPLE      | tbl   | index | NULL          | a    | 5       | NULL |
1000107 | Using index |
+------+-------------+-------+-------+---------------+------+---------+------+-
-------+-------------+
1 row in set, 1 warning (0.00 sec)

Example of ref_or_null Optimization
-----------------------------------

SELECT * FROM table_name
 WHERE key_column=expr OR key_column IS NULL;

ref_or_null is something that often happens when you use subqueries with NOT
IN as then one has to do an extra check for NULL values if the first value
didn't have a matching row.

URL: https://mariadb.com/kb/en/explain/Di;����v+DECODE_HISTOGRAMSyntax
------

DECODE_HISTOGRAM(hist_type,histogram)

Description
-----------

Returns a string of comma separated numeric values corresponding to a
probability distribution represented by the histogram of type hist_type
(SINGLE_PREC_HB or DOUBLE_PREC_HB). The hist_type and histogram would be
commonly used from the mysql.column_stats table.

See Histogram Based Statistics for details.

Examples
--------

CREATE TABLE origin (
 i INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY,
 v INT UNSIGNED NOT NULL
);

INSERT INTO origin(v) VALUES 
 (1),(2),(3),(4),(5),(10),(20),
 (30),(40),(50),(60),(70),(80),
 (90),(100),(200),(400),(800);

SET histogram_size=10,histogram_type=SINGLE_PREC_HB;

ANALYZE TABLE origin PERSISTENT FOR ALL;
+-------------+---------+----------+-----------------------------------------+
| Table       | Op      | Msg_type | Msg_text                                |
+-------------+---------+----------+-----------------------------------------+
| test.origin | analyze | status   | Engine-independent statistics collected |
| test.origin | analyze | status   | OK                                      |
+-------------+---------+----------+-----------------------------------------+

SELECT db_name,table_name,column_name,hist_type,
 hex(histogram),decode_histogram(hist_type,histogram)
 FROM mysql.column_stats WHERE db_name='test' and table_name='origin';
+---------+------------+-------------+----------------+----------------------+-
-----------------------------------------------------------------+
| db_name | table_name | column_name | hist_type      | hex(histogram)       |
decode_histogram(hist_type,histogram)                             |
+---------+------------+-------------+----------------+----------------------+-
-----------------------------------------------------------------+
| test    | origin     | i           | SINGLE_PREC_HB | 0F2D3C5A7887A5C3D2F0 |
0.059,0.118,0.059,0.118,0.118,0.059,0.118,0.118,0.059,0.118,0.059 |
| test    | origin     | v           | SINGLE_PREC_HB | 000001060C0F161C1F7F |
0.000,0.000,0.004,0.020,0.024,0.012,0.027,0.024,0.012,0.376,0.502 |
+---------+------------+-------------+----------------+----------------------+-
-----------------------------------------------------------------+

SET histogram_size=20,histogram_type=DOUBLE_PREC_HB;

ANALYZE TABLE origin PERSISTENT FOR ALL;
+-------------+---------+----------+-----------------------------------------+
| Table       | Op      | Msg_type | Msg_text                                |
+-------------+---------+----------+-----------------------------------------+
| test.origin | analyze | status   | Engine-independent statistics collected |
| test.origin | analyze | status   | OK                                      |
+-------------+---------+----------+-----------------------------------------+

SELECT db_name,table_name,column_name,
 hist_type,hex(histogram),decode_histogram(hist_type,histogram)
 FROM mysql.column_stats WHERE db_name='test' and table_name='origin';
+---------+------------+-------------+----------------+------------------------
-----------------+-------------------------------------------------------------
---------------------------+
| db_name | table_name | column_name | hist_type      | hex(histogram)        
         | decode_histogram(hist_type,histogram)
              |
+---------+------------+-------------+----------------+------------------------
-----------------+-------------------------------------------------------------
---------------------------+
| test    | origin     | i           | DOUBLE_PREC_HB |
0F0F2D2D3C3C5A5A78788787A5A5C3C3D2D2F0F0 |
0.05882,0.11765,0.05882,0.11765,0.11765,0.05882,0.11765,0.11765,0.05882,0.11765
0.05882 |
| test    | origin     | v           | DOUBLE_PREC_HB |
5200F600480116067E0CB30F1B16831CB81FD67F |
0.00125,0.00250,0.00125,0.01877,0.02502,0.01253,0.02502,0.02502,0.01253,0.37546
0.50063 |

URL: https://mariadb.com/kb/en/decode_histogram/https://mariadb.com/kb/en/decode_histogram/�`,PROCEDURE ANALYSESyntax
------

analyse([max_elements[,max_memory]])

Description
-----------

This procedure is defined in the sql/sql_analyse.cc file. It examines the
result from a query and returns an analysis of the results that suggests
optimal data types for each column. To obtain this analysis, append PROCEDURE
ANALYSE to the end of a SELECT statement:

SELECT ... FROM ... WHERE ... PROCEDURE ANALYSE([max_elements,[max_memory]])

For example:

SELECT col1, col2 FROM table1 PROCEDURE ANALYSE(10, 2000);

The results show some statistics for the values returned by the query, and
propose an optimal data type for the columns. This can be helpful for checking
your existing tables, or after importing new data. You may need to try
different settings for the arguments so that PROCEDURE ANALYSE() does not
suggest the ENUM data type when it is not appropriate.

The arguments are optional and are used as follows:

* max_elements (default 256) is the maximum number of distinct values that
analyse notices per column. This is used by analyse to check whether the
optimal data type should be of type ENUM; if there are more than max_elements
distinct values, then ENUM is not a suggested type.
* max_memory (default 8192) is the maximum amount of memory that analyse
should allocate per column while trying to find all distinct values.

URL: https://mariadb.com/kb/en/procedure-analyse/https://mariadb.com/kb/en/procedure-analyse/�BBoolean LiteralsIn MariaDB, FALSE is a synonym of 0 and TRUE is a synonym of 1. These
constants are case insensitive, so TRUE, True, and true are equivalent.

These terms are not synonyms of 0 and 1 when used with the IS operator. So,
for example, 10 IS TRUE returns 1, while 10 = TRUE returns 0 (because 1 != 10).

The IS operator accepts a third constant exists: UNKNOWN. It is always a
synonym of NULL.

TRUE and FALSE are reserved words, while UNKNOWN is not.

URL: https://mariadb.com/kb/en/sql-language-structure-boolean-literals/https://mariadb.com/kb/en/sql-language-structure-boolean-literals/�D@I�
���)Reserved Words�J@
��8[)SQL_MODE=ORACLE�m#CONTAINSSyntax
------

Contains(g1,g2)

Description
-----------

Returns 1 or 0 to indicate whether a geometry g1 completely contains geometry
g2. CONTAINS() is based on the original MySQL implementation and uses object
bounding rectangles, while ST_CONTAINS() uses object shapes.

This tests the opposite relationship to Within().

URL: https://mariadb.com/kb/en/contains/https://mariadb.com/kb/en/contains/��"CROSSESSyntax
------

Crosses(g1,g2)

Description
-----------

Returns 1 if g1 spatially crosses g2. Returns NULL if g1 is a Polygon or a
MultiPolygon, or if g2 is a Point or a MultiPoint. Otherwise, returns 0.

The term spatially crosses denotes a spatial relation between two given
geometries that has the following properties:

* The two geometries intersect
* Their intersection results in a geometry that has a dimension that is one
 less than the maximum dimension of the two given geometries
* Their intersection is not equal to either of the two given geometries

CROSSES() is based on the original MySQL implementation, and uses object
bounding rectangles, while ST_CROSSES() uses object shapes.

URL: https://mariadb.com/kb/en/crosses/https://mariadb.com/kb/en/crosses/�<�,�2vh����*d�The following is a list of all reserved words in MariaDB.

Reserved words cannot be used as Identifiers, unless they are quoted.

The definitive list of reserved words for each version can be found by
examining the sql/lex.h and sql/sql_yacc.yy files.

Reserved Words
--------------

+--------------------------------------------+--------------------------------+
| Keyword                                    | Notes                          |
+--------------------------------------------+--------------------------------+
| ACCESSIBLE                                 |                                |
+--------------------------------------------+--------------------------------+
| ADD                                        |                                |
+--------------------------------------------+--------------------------------+
| ALL                                        |                                |
+--------------------------------------------+--------------------------------+
| ALTER                                      |                                |
+--------------------------------------------+--------------------------------+
| ANALYZE                                    |                                |
+--------------------------------------------+--------------------------------+
| AND                                        |                                |
+--------------------------------------------+--------------------------------+
| AS                                         |                                |
+--------------------------------------------+--------------------------------+
| ASC                                        |                                |
+--------------------------------------------+--------------------------------+
| ASENSITIVE                                 |                                |
+--------------------------------------------+--------------------------------+
| BEFORE                                     |                                |
+--------------------------------------------+--------------------------------+
| BETWEEN                                    |                                |
+--------------------------------------------+--------------------------------+
| BIGINT                                     |                                |
+--------------------------------------------+--------------------------------+
| BINARY                                     |                                |
+--------------------------------------------+--------------------------------+
| BLOB                                       |                                |
+--------------------------------------------+--------------------------------+
| BOTH                                       |                                |
+--------------------------------------------+--------------------------------+
| BY                                         |                                |
+--------------------------------------------+--------------------------------+
| CALL                                       |                                |
+--------------------------------------------+--------------------------------+
| CASCADE                                    |                                |
+--------------------------------------------+--------------------------------+
| CASE                                       |                                |
+--------------------------------------------+--------------------------------+
| CHANGE                                     |                                |
+--------------------------------------------+--------------------------------+
| CHAR                                       |                                |
+--------------------------------------------+--------------------------------+
| CHARACTER                                  |                                |
+--------------------------------------------+--------------------------------+
| CHECK                                      |                                |
+--------------------------------------------+--------------------------------+
| COLLATE                                    |                                |
+--------------------------------------------+--------------------------------+
| COLUMN                                     |                                |
+--------------------------------------------+--------------------------------+
| CONDITION                                  |                                |
+--------------------------------------------+--------------------------------+
| CONSTRAINT                                 |                                |
+--------------------------------------------+--------------------------------+
| CONTINUE                                   |                                |
+--------------------------------------------+--------------------------------+
| CONVERT                                    |                                |
+--------------------------------------------+--------------------------------+
| CREATE                                     |                                |
+--------------------------------------------+--------------------------------+
| CROSS                                      |                                |
+--------------------------------------------+--------------------------------+
| CURRENT_DATE                               |                                |
+--------------------------------------------+--------------------------------+
| CURRENT_ROLE                               |                                |
+--------------------------------------------+--------------------------------+
| CURRENT_TIME                               |                                |
+--------------------------------------------+--------------------------------+
| CURRENT_TIMESTAMP                          |                                |
+--------------------------------------------+--------------------------------+
| CURRENT_USER                               |                                |
+--------------------------------------------+--------------------------------+
| CURSOR                                     |                                |
+--------------------------------------------+--------------------------------+
| DATABASE                                   |                                |
+--------------------------------------------+--------------------------------+
| DATABASES                                  |                                |
+--------------------------------------------+--------------------------------+
| DAY_HOUR                                   |                                |
+--------------------------------------------+--------------------------------+
| DAY_MICROSECOND                            |                                |
+--------------------------------------------+--------------------------------+
| DAY_MINUTE                                 |                                |
+--------------------------------------------+--------------------------------+
| DAY_SECOND                                 |                                |
+--------------------------------------------+--------------------------------+
| DEC                                        |                                |
+--------------------------------------------+--------------------------------+
| DECIMAL                                    |                                |
+--------------------------------------------+--------------------------------+
| DECLARE                                    |                                |
+--------------------------------------------+--------------------------------+
| DEFAULT                                    |                                |
+--------------------------------------------+--------------------------------+
| DELAYED                                    |                                |
+--------------------------------------------+----------~�----------------------+
| DELETE                                     |                                |
+--------------------------------------------+--------------------------------+
| DELETE_DOMAIN_ID                           |                                |
+--------------------------------------------+--------------------------------+
| DESC                                       |                                |
+--------------------------------------------+--------------------------------+
| DESCRIBE                                   |                                |
+--------------------------------------------+--------------------------------+
| DETERMINISTIC                              |                                |
+--------------------------------------------+--------------------------------+
| DISTINCT                                   |                                |
+--------------------------------------------+--------------------------------+
| DISTINCTROW                                |                                |
+--------------------------------------------+--------------------------------+
| DIV                                        |                                |
+--------------------------------------------+--------------------------------+
| DO_DOMAIN_IDS                              |                                |
+--------------------------------------------+--------------------------------+
| DOUBLE                                     |                                |
+--------------------------------------------+--------------------------------+
| DROP                                       |                                |
+--------------------------------------------+--------------------------------+
| DUAL                                       |                                |
+--------------------------------------------+--------------------------------+
| EACH                                       |                                |
+--------------------------------------------+--------------------------------+
| ELSE                                       |                                |
+--------------------------------------------+--------------------------------+
| ELSEIF                                     |                                |
+--------------------------------------------+--------------------------------+
| ENCLOSED                                   |                                |
+--------------------------------------------+--------------------------------+
| ESCAPED                                    |                                |
+--------------------------------------------+--------------------------------+
| EXCEPT                                     | Added in MariaDB 10.3.0        |
+--------------------------------------------+--------------------------------+
| EXISTS                                     |                                |
+--------------------------------------------+--------------------------------+
| EXIT                                       |                                |
+--------------------------------------------+--------------------------------+
| EXPLAIN                                    |                                |
+--------------------------------------------+--------------------------------+
| FALSE                                      |                                |
+--------------------------------------------+--------------------------------+
| FETCH                                      |                                |
+--------------------------------------------+--------------------------------+
| FLOAT                                      |                                |
+--------------------------------------------+--------------------------------+
| FLOAT4                                     |                                |
+--------------------------------------------+--------------------------------+
| FLOAT8                                     |                                |
+--------------------------------------------+--------------------------------+
| FOR                                        |                                |
+--------------------------------------------+--------------------------------+
| FORCE                                      |                                |
+--------------------------------------------+--------------------------------+
| FOREIGN                                    |                                |
+--------------------------------------------+--------------------------------+
| FROM                                       |                                |
+--------------------------------------------+--------------------------------+
| FULLTEXT                                   |                                |
+--------------------------------------------+--------------------------------+
| GENERAL                                    |                                |
+--------------------------------------------+--------------------------------+
| GRANT                                      |                                |
+--------------------------------------------+--------------------------------+
| GROUP                                      |                                |
+--------------------------------------------+--------------------------------+
| HAVING                                     |                                |
+--------------------------------------------+--------------------------------+
| HIGH_PRIORITY                              |                                |
+--------------------------------------------+--------------------------------+
| HOUR_MICROSECOND                           |                                |
+--------------------------------------------+--------------------------------+
| HOUR_MINUTE                                |                                |
+--------------------------------------------+--------------------------------+
| HOUR_SECOND                                |                                |
+--------------------------------------------+--------------------------------+
| IF                                         |                                |
+--------------------------------------------+--------------------------------+
| IGNORE                                     |                                |
+--------------------------------------------+--------------------------------+
| IGNORE_DOMAIN_IDS                          |                                |
+--------------------------------------------+--------------------------------+
| IGNORE_SERVER_IDS                          |                                |
+--------------------------------------------+--------------------------------+
| IN                                         |                                |
+--------------------------------------------+--------------------------------+
| INDEX                                      |                                |
+--------------------------------------------+--------------------------------+
| INFILE                                     |                                |
+--------------------------------------------+--------------------------------+
| INNER                                      |                                |
+--------------------------------------------+--------------------------------+
| INOUT                                      |                                |
+--------------------------------------------+--------------------------------+
| INSENSITIVE                                |                                |
+--------------------------------------------+--------------------------------+
| INSERT                                     |                                |
+--------------------------------------------+--------------------------------+
| INT                                        |                                |
+--------------------------------------------+------------------------------����--+
| INT1                                       |                                |
+--------------------------------------------+--------------------------------+
| INT2                                       |                                |
+--------------------------------------------+--------------------------------+
| INT3                                       |                                |
+--------------------------------------------+--------------------------------+
| INT4                                       |                                |
+--------------------------------------------+--------------------------------+
| INT8                                       |                                |
+--------------------------------------------+--------------------------------+
| INTEGER                                    |                                |
+--------------------------------------------+--------------------------------+
| INTERSECT                                  | Added in MariaDB 10.3.0        |
+--------------------------------------------+--------------------------------+
| INTERVAL                                   |                                |
+--------------------------------------------+--------------------------------+
| INTO                                       |                                |
+--------------------------------------------+--------------------------------+
| IS                                         |                                |
+--------------------------------------------+--------------------------------+
| ITERATE                                    |                                |
+--------------------------------------------+--------------------------------+
| JOIN                                       |                                |
+--------------------------------------------+--------------------------------+
| KEY                                        |                                |
+--------------------------------------------+--------------------------------+
| KEYS                                       |                                |
+--------------------------------------------+--------------------------------+
| KILL                                       |                                |
+--------------------------------------------+--------------------------------+
| LEADING                                    |                                |
+--------------------------------------------+--------------------------------+
| LEAVE                                      |                                |
+--------------------------------------------+--------------------------------+
| LEFT                                       |                                |
+--------------------------------------------+--------------------------------+
| LIKE                                       |                                |
+--------------------------------------------+--------------------------------+
| LIMIT                                      |                                |
+--------------------------------------------+--------------------------------+
| LINEAR                                     |                                |
+--------------------------------------------+--------------------------------+
| LINES                                      |                                |
+--------------------------------------------+--------------------------------+
| LOAD                                       |                                |
+--------------------------------------------+--------------------------------+
| LOCALTIME                                  |                                |
+--------------------------------------------+--------------------------------+
| LOCALTIMESTAMP                             |                                |
+--------------------------------------------+--------------------------------+
| LOCK                                       |                                |
+--------------------------------------------+--------------------------------+
| LONG                                       |                                |
+--------------------------------------------+--------------------------------+
| LONGBLOB                                   |                                |
+--------------------------------------------+--------------------------------+
| LONGTEXT                                   |                                |
+--------------------------------------------+--------------------------------+
| LOOP                                       |                                |
+--------------------------------------------+--------------------------------+
| LOW_PRIORITY                               |                                |
+--------------------------------------------+--------------------------------+
| MASTER_HEARTBEAT_PERIOD                    |                                |
+--------------------------------------------+--------------------------------+
| MASTER_SSL_VERIFY_SERVER_CERT              |                                |
+--------------------------------------------+--------------------------------+
| MATCH                                      |                                |
+--------------------------------------------+--------------------------------+
| MAXVALUE                                   |                                |
+--------------------------------------------+--------------------------------+
| MEDIUMBLOB                                 |                                |
+--------------------------------------------+--------------------------------+
| MEDIUMINT                                  |                                |
+--------------------------------------------+--------------------------------+
| MEDIUMTEXT                                 |                                |
+--------------------------------------------+--------------------------------+
| MIDDLEINT                                  |                                |
+--------------------------------------------+--------------------------------+
| MINUTE_MICROSECOND                         |                                |
+--------------------------------------------+--------------------------------+
| MINUTE_SECOND                              |                                |
+--------------------------------------------+--------------------------------+
| MOD                                        |                                |
+--------------------------------------------+--------------------------------+
| MODIFIES                                   |                                |
+--------------------------------------------+--------------------------------+
| NATURAL                                    |                                |
+--------------------------------------------+--------------------------------+
| NOT                                        |                                |
+--------------------------------------------+--------------------------------+
| NO_WRITE_TO_BINLOG                         |                                |
+--------------------------------------------+--------------------------------+
| NULL                                       |                                |
+--------------------------------------------+--------------------------------+
| NUMERIC                                    |                                |
+--------------------------------------------+--------------------------------+
| OFFSET                                     | Added in MariaDB 10.6.0        |
+--------------------------------------------+--------------------------------+
| ON                                         |                                |
+--------------------------------------------+--------------------------------+
| OPTIMIZE                                   |                                |
+--------------------------------------------+--------------------------------+
| OPTION        ʘ��                             |                                |
+--------------------------------------------+--------------------------------+
| OPTIONALLY                                 |                                |
+--------------------------------------------+--------------------------------+
| OR                                         |                                |
+--------------------------------------------+--------------------------------+
| ORDER                                      |                                |
+--------------------------------------------+--------------------------------+
| OUT                                        |                                |
+--------------------------------------------+--------------------------------+
| OUTER                                      |                                |
+--------------------------------------------+--------------------------------+
| OUTFILE                                    |                                |
+--------------------------------------------+--------------------------------+
| OVER                                       |                                |
+--------------------------------------------+--------------------------------+
| PAGE_CHECKSUM                              |                                |
+--------------------------------------------+--------------------------------+
| PARSE_VCOL_EXPR                            |                                |
+--------------------------------------------+--------------------------------+
| PARTITION                                  |                                |
+--------------------------------------------+--------------------------------+
| POSITION                                   |                                |
+--------------------------------------------+--------------------------------+
| PRECISION                                  |                                |
+--------------------------------------------+--------------------------------+
| PRIMARY                                    |                                |
+--------------------------------------------+--------------------------------+
| PROCEDURE                                  |                                |
+--------------------------------------------+--------------------------------+
| PURGE                                      |                                |
+--------------------------------------------+--------------------------------+
| RANGE                                      |                                |
+--------------------------------------------+--------------------------------+
| READ                                       |                                |
+--------------------------------------------+--------------------------------+
| READS                                      |                                |
+--------------------------------------------+--------------------------------+
| READ_WRITE                                 |                                |
+--------------------------------------------+--------------------------------+
| REAL                                       |                                |
+--------------------------------------------+--------------------------------+
| RECURSIVE                                  |                                |
+--------------------------------------------+--------------------------------+
| REF_SYSTEM_ID                              |                                |
+--------------------------------------------+--------------------------------+
| REFERENCES                                 |                                |
+--------------------------------------------+--------------------------------+
| REGEXP                                     |                                |
+--------------------------------------------+--------------------------------+
| RELEASE                                    |                                |
+--------------------------------------------+--------------------------------+
| RENAME                                     |                                |
+--------------------------------------------+--------------------------------+
| REPEAT                                     |                                |
+--------------------------------------------+--------------------------------+
| REPLACE                                    |                                |
+--------------------------------------------+--------------------------------+
| REQUIRE                                    |                                |
+--------------------------------------------+--------------------------------+
| RESIGNAL                                   |                                |
+--------------------------------------------+--------------------------------+
| RESTRICT                                   |                                |
+--------------------------------------------+--------------------------------+
| RETURN                                     |                                |
+--------------------------------------------+--------------------------------+
| RETURNING                                  |                                |
+--------------------------------------------+--------------------------------+
| REVOKE                                     |                                |
+--------------------------------------------+--------------------------------+
| RIGHT                                      |                                |
+--------------------------------------------+--------------------------------+
| RLIKE                                      |                                |
+--------------------------------------------+--------------------------------+
| ROW_NUMBER                                 | From MariaDB 10.7              |
+--------------------------------------------+--------------------------------+
| ROWS                                       |                                |
+--------------------------------------------+--------------------------------+
| SCHEMA                                     |                                |
+--------------------------------------------+--------------------------------+
| SCHEMAS                                    |                                |
+--------------------------------------------+--------------------------------+
| SECOND_MICROSECOND                         |                                |
+--------------------------------------------+--------------------------------+
| SELECT                                     |                                |
+--------------------------------------------+--------------------------------+
| SENSITIVE                                  |                                |
+--------------------------------------------+--------------------------------+
| SEPARATOR                                  |                                |
+--------------------------------------------+--------------------------------+
| SET                                        |                                |
+--------------------------------------------+--------------------------------+
| SHOW                                       |                                |
+--------------------------------------------+--------------------------------+
| SIGNAL                                     |                                |
+--------------------------------------------+--------------------------------+
| SLOW                                       |                                |
+--------------------------------------------+--------------------------------+
| SMALLINT                                   |                                |
+--------------------------------------------+--------------------------------+
| SPATIAL                                    |                                |
+--------------------------------------------+--------------------------------+
| SPECIFIC                          �m�B         |                                |
+--------------------------------------------+--------------------------------+
| SQL                                        |                                |
+--------------------------------------------+--------------------------------+
| SQLEXCEPTION                               |                                |
+--------------------------------------------+--------------------------------+
| SQLSTATE                                   |                                |
+--------------------------------------------+--------------------------------+
| SQLWARNING                                 |                                |
+--------------------------------------------+--------------------------------+
| SQL_BIG_RESULT                             |                                |
+--------------------------------------------+--------------------------------+
| SQL_CALC_FOUND_ROWS                        |                                |
+--------------------------------------------+--------------------------------+
| SQL_SMALL_RESULT                           |                                |
+--------------------------------------------+--------------------------------+
| SSL                                        |                                |
+--------------------------------------------+--------------------------------+
| STARTING                                   |                                |
+--------------------------------------------+--------------------------------+
| STATS_AUTO_RECALC                          |                                |
+--------------------------------------------+--------------------------------+
| STATS_PERSISTENT                           |                                |
+--------------------------------------------+--------------------------------+
| STATS_SAMPLE_PAGES                         |                                |
+--------------------------------------------+--------------------------------+
| STRAIGHT_JOIN                              |                                |
+--------------------------------------------+--------------------------------+
| TABLE                                      |                                |
+--------------------------------------------+--------------------------------+
| TERMINATED                                 |                                |
+--------------------------------------------+--------------------------------+
| THEN                                       |                                |
+--------------------------------------------+--------------------------------+
| TINYBLOB                                   |                                |
+--------------------------------------------+--------------------------------+
| TINYINT                                    |                                |
+--------------------------------------------+--------------------------------+
| TINYTEXT                                   |                                |
+--------------------------------------------+--------------------------------+
| TO                                         |                                |
+--------------------------------------------+--------------------------------+
| TRAILING                                   |                                |
+--------------------------------------------+--------------------------------+
| TRIGGER                                    |                                |
+--------------------------------------------+--------------------------------+
| TRUE                                       |                                |
+--------------------------------------------+--------------------------------+
| UNDO                                       |                                |
+--------------------------------------------+--------------------------------+
| UNION                                      |                                |
+--------------------------------------------+--------------------------------+
| UNIQUE                                     |                                |
+--------------------------------------------+--------------------------------+
| UNLOCK                                     |                                |
+--------------------------------------------+--------------------------------+
| UNSIGNED                                   |                                |
+--------------------------------------------+--------------------------------+
| UPDATE                                     |                                |
+--------------------------------------------+--------------------------------+
| USAGE                                      |                                |
+--------------------------------------------+--------------------------------+
| USE                                        |                                |
+--------------------------------------------+--------------------------------+
| USING                                      |                                |
+--------------------------------------------+--------------------------------+
| UTC_DATE                                   |                                |
+--------------------------------------------+--------------------------------+
| UTC_TIME                                   |                                |
+--------------------------------------------+--------------------------------+
| UTC_TIMESTAMP                              |                                |
+--------------------------------------------+--------------------------------+
| VALUES                                     |                                |
+--------------------------------------------+--------------------------------+
| VARBINARY                                  |                                |
+--------------------------------------------+--------------------------------+
| VARCHAR                                    |                                |
+--------------------------------------------+--------------------------------+
| VARCHARACTER                               |                                |
+--------------------------------------------+--------------------------------+
| VARYING                                    |                                |
+--------------------------------------------+--------------------------------+
| WHEN                                       |                                |
+--------------------------------------------+--------------------------------+
| WHERE                                      |                                |
+--------------------------------------------+--------------------------------+
| WHILE                                      |                                |
+--------------------------------------------+--------------------------------+
| WINDOW                                     | Only disallowed for table      |
|                                            | aliases.                       |
+--------------------------------------------+--------------------------------+
| WITH                                       |                                |
+--------------------------------------------+--------------------------------+
| WRITE                                      |                                |
+--------------------------------------------+--------------------------------+
| XOR                                        |                                |
+--------------------------------------------+--------------------------------+
| YEAR_MONTH                                 |                                |
+--------------------------------------------+--------------------------------+
| ZEROFILL                                   |                                |
+--------------------------------------------+--------------------------------+

Exceptions
----------

Some keywords are exceptions for historical reasons, and are permitted as
unquoted identifiers. These include:

��y��3+-----------------------------------------------------------------------------+
| Keyword                                                                     |
+-----------------------------------------------------------------------------+
| ACTION                                                                      |
+-----------------------------------------------------------------------------+
| BIT                                                                         |
+-----------------------------------------------------------------------------+
| DATE                                                                        |
+-----------------------------------------------------------------------------+
| ENUM                                                                        |
+-----------------------------------------------------------------------------+
| NO                                                                          |
+-----------------------------------------------------------------------------+
| TEXT                                                                        |
+-----------------------------------------------------------------------------+
| TIME                                                                        |
+-----------------------------------------------------------------------------+
| TIMESTAMP                                                                   |
+-----------------------------------------------------------------------------+

Oracle Mode
-----------

In Oracle mode, from MariaDB 10.3, there are a number of extra reserved words:

+--------------------------------------------+--------------------------------+
| Keyword                                    | Notes                          |
+--------------------------------------------+--------------------------------+
| BODY                                       |                                |
+--------------------------------------------+--------------------------------+
| ELSIF                                      |                                |
+--------------------------------------------+--------------------------------+
| GOTO                                       |                                |
+--------------------------------------------+--------------------------------+
| HISTORY                                    | <= MariaDB 10.3.6 only         |
+--------------------------------------------+--------------------------------+
| MINUS                                      | From MariaDB 10.6.1            |
+--------------------------------------------+--------------------------------+
| OTHERS                                     |                                |
+--------------------------------------------+--------------------------------+
| PACKAGE                                    |                                |
+--------------------------------------------+--------------------------------+
| PERIOD                                     | <= MariaDB 10.3.6 only         |
+--------------------------------------------+--------------------------------+
| RAISE                                      |                                |
+--------------------------------------------+--------------------------------+
| ROWNUM                                     | From MariaDB 10.6.1            |
+--------------------------------------------+--------------------------------+
| ROWTYPE                                    |                                |
+--------------------------------------------+--------------------------------+
| SYSDATE                                    | From MariaDB 10.6.1            |
+--------------------------------------------+--------------------------------+
| SYSTEM                                     | <= MariaDB 10.3.6 only. Note   |
|                                            | however that SYSTEM sometimes  |
|                                            | needs to be quoted to avoid    |
|                                            | confusion with                 |
|                                            | System-versioned tables.       |
+--------------------------------------------+--------------------------------+
| SYSTEM_TIME                                | <= MariaDB 10.3.6 only         |
+--------------------------------------------+--------------------------------+
| VERSIONING                                 | <= MariaDB 10.3.6 only         |
+--------------------------------------------+--------------------------------+
| WITHOUT                                    | <= MariaDB 10.3.6 only         |
+--------------------------------------------+--------------------------------+

Function Names
--------------

If the IGNORE_SPACE SQL_MODE flag is set, function names become reserved words.

URL: https://mariadb.com/kb/en/reserved-words/https://mariadb.com/kb/en/create-table/https://mariadb.com/kb/en/create-function/PLACE:

DELIMITER //

CREATE PROCEDURE simpleproc2 (
 OUT param1 CHAR(10) CHARACTER SET 'utf8' COLLATE 'utf8_bin'
)
 BEGIN
 SELECT CONCAT('a'),f1 INTO param1 FROM t;
 END;
//
ERROR 1304 (42000): PROCEDURE simpleproc2 already exists

DELIMITER ;

DELIMITER //

CREATE OR REPLACE PROCEDURE simpleproc2 (
 OUT param1 CHAR(10) CHARACTER SET 'utf8' COLLATE 'utf8_bin'
)
 BEGIN
 SELECT CONCAT('a'),f1 INTO param1 FROM t;
 END;
//
ERROR 1304 (42000): PROCEDURE simpleproc2 already exists

DELIMITER ;
Query OK, 0 rows affected (0.03 sec)

URL: https://mariadb.com/kb/en/create-procedure/https://mariadb.com/kb/en/create-view/https://mariadb.com/kb/en/generated-columns/https://mariadb.com/kb/en/dynamic-columns/https://mariadb.com/kb/en/sequence-overview/https://mariadb.com/kb/en/window-functions-overview/https://mariadb.com/kb/en/window-functions-columnstore-window-functions/https://mariadb.com/kb/en/system-versioned-tables/2020-10-03', '2020-10-07'),
 (2, 'Eusebius', '2020-10-04', '2020-10-06');
ERROR 1062 (23000): Duplicate entry '2-2020-10-06-2020-10-04' for key
'room_number'

Further Examples
----------------

The implicit change from NULL to NOT NULL:

CREATE TABLE `t2` (
 `id` int(11) DEFAULT NULL,
 `d1` datetime DEFAULT NULL,
 `d2` datetime DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=latin1;

ALTER TABLE t2 ADD PERIOD FOR p(d1,d2);

SHOW CREATE TABLE t2\G
*************************** 1. row ***************************
   Table: t2
Create Table: CREATE TABLE `t2` (
 `id` int(11) DEFAULT NULL,
 `d1` datetime NOT NULL,
 `d2` datetime NOT NULL,
 PERIOD FOR `p` (`d1`, `d2`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1

Due to this constraint, trying to add a time period where null data already
exists will fail.

CREATE OR REPLACE TABLE `t2` (
 `id` int(11) DEFAULT NULL,
 `d1` datetime DEFAULT NULL,
 `d2` datetime DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=latin1;

INSERT INTO t2(id) VALUES(1);

ALTER TABLE t2 ADD PERIOD FOR p(d1,d2);
ERROR 1265 (01000): Data truncated for column 'd1' at row 1

URL: https://mariadb.com/kb/en/application-time-periods/ y�2�Hr4F,*�,�&�D\*5')�`��From MariaDB 10.3, setting the sql_mode system variable to Oracle allows the
server to understand a subset of Oracle's PL/SQL language. For example:

SET SQL_MODE='ORACLE';

All traditional MariaDB SQL/PSM syntax should work as before, as long as it
does not conflict with Oracle's PL/SQL syntax. All MariaDB functions should be
supported in both normal and Oracle modes.

Prior to MariaDB 10.3, MariaDB does not support Oracle's PL/SQL language, and
SET SQL_MODE=ORACLE is only an alias for the following sql_mode in those
versions:

SET SQL_MODE='PIPES_AS_CONCAT, ANSI_QUOTES, IGNORE_SPACE, NO_KEY_OPTIONS,
NO_TABLE_OPTIONS, NO_FIELD_OPTIONS, NO_AUTO_CREATE_USER';

From MariaDB 10.3, SET SQL_MODE=ORACLE is same as:

SET SQL_MODE='PIPES_AS_CONCAT,ANSI_QUOTES,IGNORE_SPACE,ORACLE,NO_KEY_OPTIONS,
NO_TABLE_OPTIONS,NO_FIELD_OPTIONS,NO_AUTO_CREATE_USER,SIMULTANEOUS_ASSIGNMENT';

Supported Syntax in Oracle Mode
-------------------------------

Stored Procedures and Stored Functions
--------------------------------------

Oracle mode makes the following changes to Stored Procedures and Stored
Functions:

+-----------------------------------------+-----------------------------------+
| Oracle syntax                           | Description                       |
+-----------------------------------------+-----------------------------------+
| CREATE PROCEDURE p1 (param OUT INT)     | ANSI uses (OUT param INT)         |
+-----------------------------------------+-----------------------------------+
| CREATE PROCEDURE p1 (a IN OUT INT)      | ANSI uses (INOUT param INT)       |
+-----------------------------------------+-----------------------------------+
| AS before function body                 | CREATE FUNCTION f1 RETURN NUMBER  |
|                                         | AS BEGIN...                       |
+-----------------------------------------+-----------------------------------+
| IS before function body                 | CREATE FUNCTION f1 RETURN NUMBER  |
|                                         | IS BEGIN...                       |
+-----------------------------------------+-----------------------------------+
| If function has no parameters then      | Example: CREATE PROCEDURE p1 AS   |
| parentheses must be omitted             | BEGIN NULL; END;                  |
+-----------------------------------------+-----------------------------------+
| CREATE PROCEDURE p1 AS BEGIN END p1;    | Optional routine name after END   |
|                                         | keyword. MDEV-12089               |
+-----------------------------------------+-----------------------------------+
| CREATE FUNCTION f1(a VARCHAR)           | VARCHAR can be used without       |
|                                         | length for routine parameters     |
|                                         | and RETURN clause. The length is  |
|                                         | inherited from the argument at    |
|                                         | call time. MDEV-10596             |
+-----------------------------------------+-----------------------------------+
| CREATE AGGREGATE FUNCTION f1( )         | Creates an aggregate function,    |
|                                         | which performs the function       |
|                                         | against a set of rows and         |
|                                         | returns one aggregate result.     |
+-----------------------------------------+-----------------------------------+
| No CALL needed in Stored Procedures     | In Oracle mode one can call       |
|                                         | other stored procedures with      |
|                                         | name only. MDEV-12107             |
+-----------------------------------------+-----------------------------------+
| RETURN. Can also be used in stored      | ANSI uses RETURNS. MariaDB mode   |
| procedures                              | only supports RETURNS in stored   |
|                                         | functions                         |
+-----------------------------------------+-----------------------------------+

Cursors
-------

Oracle mode makes the following changes to Cursors:

+-----------------------------------------+-----------------------------------+
| Oracle syntax                           | Description                       |
+-----------------------------------------+-----------------------------------+
| CREATE PROCEDURE p1 AS CURSOR cur IS    | Explicit cursor with FOR loop.    |
| (SELECT a, b FROM t1); BEGIN  FOR rec   | MDEV-10581                        |
| IN cur ...                              |                                   |
+-----------------------------------------+-----------------------------------+
| CREATE PROCEDURE p1 AS rec IN (SELECT   | Implicit cursor with FOR loop.    |
| a, b FROM t1)                           | MDEV-12098                        |
+-----------------------------------------+-----------------------------------+
| CURSOR c(prm_a VARCHAR2, prm_b          | Cursor with parameters.           |
| VARCHAR2) ... OPEN c(1,2)               | MDEV-10597                        |
+-----------------------------------------+-----------------------------------+
| CURSOR c(prm_a VARCHAR2, prm_b          | Cursor with parameters and FOR    |
| VARCHAR2) ... FOR rec in c(1,2)         | loop. MDEV-12314                  |
+-----------------------------------------+-----------------------------------+
| s %ISOPEN, %ROWCOUNT, %FOUND, %NOTFOUND | Explicit cursor attributes.       |
|                                         | MDEV-10582                        |
+-----------------------------------------+-----------------------------------+

LOOP
----

Oracle mode makes the following changes to LOOP:

+-----------------------------------------+-----------------------------------+
| Oracle syntax                           | Description                       |
+-----------------------------------------+-----------------------------------+
| FOR i IN 1..10 LOOP ... END LOOP        | Numeric FOR loop. MDEV-10580      |
+-----------------------------------------+-----------------------------------+
| GOTO                                    | GOTO statement.  MDEV-10697       |
+-----------------------------------------+-----------------------------------+
| <<label>> used with GOTO                | ANSI uses label:. MDEV-10697      |
+-----------------------------------------+-----------------------------------+
| To leave loop block: EXIT [ label ] [   | ANSI syntax is IF bool_expr THEN  |
| WHEN bool_expr ]                        | LEAVE label                       |
+-----------------------------------------+-----------------------------------+
| [<<label>>] WHILE boolean_expression    | Oracle style WHILE loop           |
| LOOP statement... END LOOP [ label ] ;  |                                   |
+-----------------------------------------+-----------------------------------+
| CONTINUE [ label ] [ WHEN               | CONTINUE is only valid inside a   |
| boolean_expression]                     | loop                              |
+-----------------------------------------+-----------------------------------+

Variables
---------

+------------------------------+-----------------+--------------------------+
| Oracle syntax                | Version         | Description              |
+------------------------------+-----------------+--------------------------+
| var:= 10; Can also be used   | 10.3            | MariaDB uses SET var=    |
| with MariaDB systemvariables |                 | 10;                      |
+------------------------------+-----------------+--------------------------+
| var INT := 10                | 10.3            | Default variable value   |
+------------------------------+-----------------+--------------------------+
| var1                         | 10.3            | Take data type from a    |
| table_name.column_name%TYPE  |                 | table column. MDEV-10577 |
+------------------------------+-----------------+--------------------------+
| var2 var1%TYPE               | 10.3            | Take data+!ƥ type from      |
|                              |                 | another variable         |
+------------------------------+-----------------+--------------------------+
| rec1 table_name%ROWTYPE      | 10.3            | Take ROW structure from  |
|                              |                 | a table. MDEV-12133      |
+------------------------------+-----------------+--------------------------+
| rec2 rec1%ROWTYPE            | 10.3            | Take ROW structure from  |
|                              |                 | ROW variable             |
+------------------------------+-----------------+--------------------------+
| CURSOR c1 IS SELECT a,b      | 10.3            | Take ROW structure from  |
| FROM t1; rec1 c1%ROWTYPE;    |                 | a cursor. MDEV-12011     |
+------------------------------+-----------------+--------------------------+
| Variables can be declared    | 10.3            | In MariaDB mode,         |
| after cursor declarations    |                 | variables must be        |
|                              |                 | declared before          |
|                              |                 | cursors. MDEV-10598      |
+------------------------------+-----------------+--------------------------+
| Triggers uses :NEW and :OLD  | 10.3            | ANSI uses NEW and OLD.   |
|                              |                 | MDEV-10579               |
+------------------------------+-----------------+--------------------------+
| SQLCODE                      | 10.3            | Returns the number code  |
|                              |                 | of the most recent       |
|                              |                 | exception. Can only be   |
|                              |                 | used in Stored           |
|                              |                 | Procedures. MDEV-10578   |
+------------------------------+-----------------+--------------------------+
| SQLERRM                      | 10.3            | Returns the error        |
|                              |                 | message associdated to   |
|                              |                 | it's error number        |
|                              |                 | argument or SQLCODE if   |
|                              |                 | no argument is given.    |
|                              |                 | Can only be used in      |
|                              |                 | Stored Procedures.       |
|                              |                 | MDEV-10578               |
+------------------------------+-----------------+--------------------------+
| SQL%ROWCOUNT                 | 10.3            | Almost same as           |
|                              |                 | ROW_COUNT(). MDEV-10583  |
+------------------------------+-----------------+--------------------------+
| ROWNUM                       | 10.6.1          | Returns number of        |
|                              |                 | accepted rows            |
+------------------------------+-----------------+--------------------------+

Exceptions
----------

+-----------------------------------------+-----------------------------------+
| Oracle syntax                           | Description                       |
+-----------------------------------------+-----------------------------------+
| BEGIN ... EXCEPTION WHEN OTHERS THEN    | Exception handlers are declared   |
| BEGIN ..  END; END;                     | at the end of a block             |
+-----------------------------------------+-----------------------------------+
| TOO_MANY_ROWS, NO_DATA_FOUND,           | Predefined exceptions. MDEV-10839 |
| DUP_VAL_ON_INDEX                        |                                   |
+-----------------------------------------+-----------------------------------+
| RAISE TOO_MANY_ROWS ; .... EXCEPTION    | Exception can be used with RAISE  |
| WHEN TOO_MANY_ROWS THEN ...             | and EXCEPTION...WHEN. MDEV-10840  |
+-----------------------------------------+-----------------------------------+
| CREATE OR REPLACE FUNCTION f1 (a INT)   | User defined exceptions.          |
| RETURN INT AS e1 EXCEPTION...           | MDEV-10587                        |
+-----------------------------------------+-----------------------------------+

BEGIN Blocks
------------

+-----------------------------------------+-----------------------------------+
| Oracle syntax                           | Description                       |
+-----------------------------------------+-----------------------------------+
| BEGIN to start a block                  | MariaDB uses BEGIN NOT ATOMIC     |
|                                         | for anyonymous blocks. MDEV-10655 |
+-----------------------------------------+-----------------------------------+
| DECLARE is used before BEGIN            | DECLARE a INT; b VARCHAR(10);     |
|                                         | BEGIN v:= 10; END;                |
+-----------------------------------------+-----------------------------------+
| WHEN DUP_VAL_ON_INDEX THEN NULL ;       | Do not require BEGIN..END in      |
| NULL; WHEN OTHERS THEN NULL             | multi-statement exception         |
|                                         | handlers in THEN clause.          |
|                                         | MDEV-12088                        |
+-----------------------------------------+-----------------------------------+

Simple Syntax Compatibility
---------------------------

+------------------------------+-----------------+--------------------------+
| Oracle syntax                | Version         | Description              |
+------------------------------+-----------------+--------------------------+
| ELSIF                        | 10.3            | ANSI uses ELSEIF         |
+------------------------------+-----------------+--------------------------+
| SELECT UNIQUE                | 10.3            | Same as SELECT           |
|                              |                 | DISTINCT. MDEV-12086     |
+------------------------------+-----------------+--------------------------+
| TRUNCATE TABLE t1 [DROP      | 10.3            | DROP STORAGE and REUSE   |
| STORAGE] or [REUSE STORAGE]  |                 | STORAGE are allowed as   |
|                              |                 | optional keywords for    |
|                              |                 | TRUNCATE TABLE.          |
|                              |                 | MDEV-10588               |
+------------------------------+-----------------+--------------------------+
| Subqueries in a FROM clause  | 10.6            | SELECT * FROM (SELECT 1  |
| without an alias             |                 | FROM DUAL), (SELECT 2    |
|                              |                 | FROM DUAL)               |
+------------------------------+-----------------+--------------------------+
| UNION, EXCEPT and INTERSECT  | 10.3            | INTERSECT has higher     |
| all have the same            |                 | precedence than UNION    |
| precedence.                  |                 | and EXCEPT in            |
|                              |                 | non-Oracle modes.        |
+------------------------------+-----------------+--------------------------+
| MINUS                        | 10.6            | MINUS is a synonym for   |
|                              |                 | EXCEPT.                  |
+------------------------------+-----------------+--------------------------+

Functions
---------

+------------------------------+-----------------+--------------------------+
| Oracle syntax                | Version         | Description              |
+------------------------------+-----------------+--------------------------+
| ADD_MONTHS()                 | 10.6.1          | Added as a wrapper for   |
|                              |                 | DATE_ADD() to enhance    |
|                              |                 | Oracle compatibility.    |
|                              |                 | All modes.               |
+---------------���Y---------------+-----------------+--------------------------+
| CAST(expr as VARCHAR(N))     | 10.3            | Cast expression to a     |
|                              |                 | VARCHAR(N). MDEV-11275   |
+------------------------------+-----------------+--------------------------+
| DECODE                       | 10.3            | In Oracle mode,          |
|                              |                 | compares and matches     |
|                              |                 | search expressions       |
+------------------------------+-----------------+--------------------------+
| LENGTH() is same as          | 10.3            | MariaDB translates       |
| CHAR_LENGTH()                |                 | LENGTH() to              |
|                              |                 | OCTET_LENGTH(). In all   |
|                              |                 | modes one can use        |
|                              |                 | LENGTHB() as a synonym   |
|                              |                 | to OCTET_LENGTH()        |
+------------------------------+-----------------+--------------------------+
| CHR(num)                     | 10.3            | Returns a VARCHAR(1)     |
|                              |                 | with character set and   |
|                              |                 | collation according to   |
|                              |                 | @@character_set_database |
|                              |                 | and @@collation_database |
+------------------------------+-----------------+--------------------------+
| substr('abc',0 ,3) same as   | 10.3            | Position 0 for substr()  |
| substr('abc', 1 ,3)          |                 | is same as position 1    |
+------------------------------+-----------------+--------------------------+
| SYS_GUID                     | 10.6.1          | Generates a globally     |
|                              |                 | unique identifier.       |
|                              |                 | Similar to UUID but      |
|                              |                 | without the -. All       |
|                              |                 | modes.                   |
+------------------------------+-----------------+--------------------------+
| TO_CHAR                      | 10.6.1          | Added to enhance Oracle  |
|                              |                 | compatibility. All       |
|                              |                 | modes.                   |
+------------------------------+-----------------+--------------------------+
| TRIM, LTRIM, RTRIM, LPAD     | 10.3            | Returns NULL instead of  |
| and RPAD                     |                 | an empty string if       |
|                              |                 | returning an empty       |
|                              |                 | result. These functions  |
|                              |                 | can also be accessed     |
|                              |                 | outside of ORACLE mode   |
|                              |                 | by suffixing _ORACLE     |
|                              |                 | onto the end of the      |
|                              |                 | function name, such as   |
|                              |                 | TRIM_ORACLE.             |
+------------------------------+-----------------+--------------------------+

Prepared Statements
-------------------

Oracle mode makes the following changes to Prepared Statements:

+-----------------------------------------+-----------------------------------+
| Oracle syntax                           | Description                       |
+-----------------------------------------+-----------------------------------+
| PREPARE stmt FROM 'SELECT :1, :2'       | ANSI uses ?. MDEV-10801           |
+-----------------------------------------+-----------------------------------+
| EXECUTE IMMEDIATE 'INSERT INTO t1       | Dynamic placeholders. MDEV-10801  |
| SELECT (:x,:y) FROM DUAL' USING 10,20   |                                   |
+-----------------------------------------+-----------------------------------+

Synonyms for Basic SQL Types
----------------------------

+--------------------------------+-------------------------------------------+
| Oracle type                    | MariaDB synonym                           |
+--------------------------------+-------------------------------------------+
| VARCHAR2                       | VARCHAR                                   |
+--------------------------------+-------------------------------------------+
| NUMBER                         | DECIMAL                                   |
+--------------------------------+-------------------------------------------+
| DATE (with time portion)       | MariaDB DATETIME                          |
+--------------------------------+-------------------------------------------+
| RAW                            | VARBINARY                                 |
+--------------------------------+-------------------------------------------+
| CLOB                           | LONGTEXT                                  |
+--------------------------------+-------------------------------------------+
| BLOB                           | LONGBLOB                                  |
+--------------------------------+-------------------------------------------+

This was implemented as part of MDEV-10343.

If one does a SHOW CREATE TABLE in ORACLE mode on a table that has a native
MariaDB DATE column, it will be displayed as mariadb_schema.date to not
conflict with the Oracle DATE type.

Packages
--------

The following syntax has been supported since MariaDB 10.3.5:

* CREATE PACKAGE
* CREATE PACKAGE BODY
* DROP PACKAGE
* DROP PACKAGE BODY
* SHOW CREATE PACKAGE
* SHOW CREATE PACKAGE BODY

NULL Handling
-------------

Oracle mode makes the following changes to NULL handling:

NULL As a Statement
-------------------

NULL can be used as a statement:

IF a=10 THEN NULL; ELSE NULL; END IF

Translating Empty String Literals to NULL
-----------------------------------------

In Oracle, empty string ('') and NULL are the same thing,

By using sql_mode=EMPTY_STRING_IS_NULL you can get a similar experience in
MariaDB:

SET sql_mode=EMPTY_STRING_IS_NULL;
SELECT '' IS NULL; -- returns TRUE
INSERT INTO t1 VALUES (''); -- inserts NULL

Concat Operator Ignores NULL
----------------------------

CONCAT() and || ignore NULL in Oracle mode. Can also be accessed outside of
ORACLE mode by using CONCAT_OPERATOR_ORACLE. MDEV-11880 and MDEV-12143.

Reserved Words
--------------

There are a number of extra reserved words in Oracle mode.

SHOW CREATE TABLE
-----------------

The SHOW CREATE TABLE statement will not display MariaDB-specific table
options, such as AUTO_INCREMENT or CHARSET, when Oracle mode is set.

URL: https://mariadb.com/kb/en/sql_modeoracle/ٝ�2�9�p
"DEFAULTSyntax
------

DEFAULT(col_name)

Description
-----------

Returns the default value for a table column. If the column has no default
value (and is not NULLABLE - NULLABLE fields have a NULL default), an error is
returned.

For integer columns using AUTO_INCREMENT, 0 is returned.

When using DEFAULT as a value to set in an INSERT or UPDATE statement, you can
use the bare keyword DEFAULT without the parentheses and argument to refer to
the column in context. You can only use DEFAULT as a bare keyword if you are
using it alone without a surrounding expression or function.

Examples
--------

Select only non-default values for a column:

SELECT i FROM t WHERE i != DEFAULT(i);

Update values to be one greater than the default value:

UPDATE t SET i = DEFAULT(i)+1 WHERE i < 100;

When referring to the default value exactly in UPDATE or INSERT, you can omit
the argument:

INSERT INTO t (i) VALUES (DEFAULT);
UPDATE t SET i = DEFAULT WHERE i < 100;

CREATE OR REPLACE TABLE t (
 i INT NOT NULL AUTO_INCREMENT,
 j INT NOT NULL,
 k INT DEFAULT 3,
 l INT NOT NULL DEFAULT 4,
 m INT,
 PRIMARY KEY (i)
);

DESC t;
+-------+---------+------+-----+---------+----------------+
| Field | Type    | Null | Key | Default | Extra          |
+-------+---------+------+-----+---------+----------------+
| i     | int(11) | NO   | PRI | NULL    | auto_increment |
| j     | int(11) | NO   |     | NULL    |                |
| k     | int(11) | YES  |     | 3       |                |
| l     | int(11) | NO   |     | 4       |                |
| m     | int(11) | YES  |     | NULL    |                |
+-------+---------+------+-----+---------+----------------+

INSERT INTO t (j) VALUES (1);
INSERT INTO t (j,m) VALUES (2,2);
INSERT INTO t (j,l,m) VALUES (3,3,3);

SELECT * FROM t;
+---+---+------+---+------+
| i | j | k    | l | m    |
+---+---+------+---+------+
| 1 | 1 |    3 | 4 | NULL |
| 2 | 2 |    3 | 4 |    2 |
| 3 | 3 |    3 | 3 |    3 |
+---+---+------+---+------+

SELECT DEFAULT(i), DEFAULT(k), DEFAULT (l), DEFAULT(m) FROM t;
+------------+------------+-------------+------------+
| DEFAULT(i) | DEFAULT(k) | DEFAULT (l) | DEFAULT(m) |
+------------+------------+-------------+------------+
|          0 |          3 |           4 |       NULL |
|          0 |          3 |           4 |       NULL |
|          0 |          3 |           4 |       NULL |
+------------+------------+-------------+------------+

SELECT DEFAULT(i), DEFAULT(k), DEFAULT (l), DEFAULT(m), DEFAULT(j)  FROM t;
ERROR 1364 (HY000): Field 'j' doesn't have a default value

SELECT * FROM t WHERE i = DEFAULT(i);
Empty set (0.001 sec)

SELECT * FROM t WHERE j = DEFAULT(j);
ERROR 1364 (HY000): Field 'j' doesn't have a default value

SELECT * FROM t WHERE k = DEFAULT(k);
+---+---+------+---+------+
| i | j | k    | l | m    |
+---+---+------+---+------+
| 1 | 1 |    3 | 4 | NULL |
| 2 | 2 |    3 | 4 |    2 |
| 3 | 3 |    3 | 3 |    3 |
+---+---+------+---+------+

SELECT * FROM t WHERE l = DEFAULT(l);
+---+---+------+---+------+
| i | j | k    | l | m    |
+---+---+------+---+------+
| 1 | 1 |    3 | 4 | NULL |
| 2 | 2 |    3 | 4 |    2 |
+---+---+------+---+------+

SELECT * FROM t WHERE m = DEFAULT(m);
Empty set (0.001 sec)

SELECT * FROM t WHERE m <=> DEFAULT(m);
+---+---+------+---+------+
| i | j | k    | l | m    |
+---+---+------+---+------+
| 1 | 1 |    3 | 4 | NULL |
+---+---+------+---+------+

URL: https://mariadb.com/kb/en/default/https://mariadb.com/kb/en/default/�	�
$ROW_COUNTSyntax
------

ROW_COUNT()

Description
-----------

ROW_COUNT() returns the number of rows updated, inserted or deleted by the
preceding statement. This is the same as the row count that the mariadb client
displays and the value from the mysql_affected_rows() C API function.

Generally:

* For statements which return a result set (such as SELECT, SHOW, DESC or
HELP), returns -1, even when the result set is empty. This is also true for
administrative statements, such as OPTIMIZE.
* For DML statements other than SELECT and for ALTER TABLE, returns the number
of affected rows.
* For DDL statements (including TRUNCATE) and for other statements which don't
return any result set (such as USE, DO, SIGNAL or DEALLOCATE PREPARE), returns
0.

For UPDATE, affected rows is by default the number of rows that were actually
changed. If the CLIENT_FOUND_ROWS flag to mysql_real_connect() is specified
when connecting to mysqld, affected rows is instead the number of rows matched
by the WHERE clause.

For REPLACE, deleted rows are also counted. So, if REPLACE deletes a row and
adds a new row, ROW_COUNT() returns 2.

For INSERT ... ON DUPLICATE KEY, updated rows are counted twice. So, if INSERT
adds a new rows and modifies another row, ROW_COUNT() returns 3.

ROW_COUNT() does not take into account rows that are not directly
deleted/updated by the last statement. This means that rows deleted by foreign
keys or triggers are not counted.

Warning: You can use ROW_COUNT() with prepared statements, but you need to
call it after EXECUTE, not after DEALLOCATE PREPARE, because the row count for
allocate prepare is always 0.

Warning: When used after a CALL statement, this function returns the number of
rows affected by the last statement in the procedure, not by the whole
procedure.

Warning: After INSERT DELAYED, ROW_COUNT() returns the number of the rows you
tried to insert, not the number of the successful writes.

This information can also be found in the diagnostics area.

Statements using the ROW_COUNT() function are not safe for replication.

Examples
--------

CREATE TABLE t (A INT);

INSERT INTO t VALUES(1),(2),(3);

SELECT ROW_COUNT();
+-------------+
| ROW_COUNT() |
+-------------+
|           3 |
+-------------+

DELETE FROM t WHERE A IN(1,2);

SELECT ROW_COUNT(); 
+-------------+
| ROW_COUNT() |
+-------------+
|           2 |
+-------------+

Example with prepared statements:

SET @q = 'INSERT INTO t VALUES(1),(2),(3);';

PREPARE stmt FROM @q;

EXECUTE stmt;
Query OK, 3 rows affected (0.39 sec)
Records: 3  Duplicates: 0  Warnings: 0

SELECT ROW_COUNT();
+-------------+
| ROW_COUNT() |
+-------------+
|           3 |
+-------------+

URL: https://mariadb.com/kb/en/row_count/https://mariadb.com/kb/en/row_count/��#DISJOINTSyntax
------

Disjoint(g1,g2)

Description
-----------

Returns 1 or 0 to indicate whether g1 is spatially disjoint from (does not
intersect) g2.

DISJOINT() tests the opposite relationship to INTERSECTS().

DISJOINT() is based on the original MySQL implementation and uses object
bounding rectangles, while ST_DISJOINT() uses object shapes.

URL: https://mariadb.com/kb/en/disjoint/https://mariadb.com/kb/en/disjoint/��!EQUALSSyntax
------

Equals(g1,g2)

From MariaDB 10.2.3:

MBREQUALS(g1,g2)

Description
-----------

Returns 1 or 0 to indicate whether g1 is spatially equal to g2.

EQUALS() is based on the original MySQL implementation and uses object
bounding rectangles, while ST_EQUALS() uses object shapes.

From MariaDB 10.2.3, MBREQUALS is a synonym for Equals.

URL: https://mariadb.com/kb/en/equals/https://mariadb.com/kb/en/equals/�
%INTERSECTSSyntax
------

INTERSECTS(g1,g2)

Description
-----------

Returns 1 or 0 to indicate whether geometry g1 spatially intersects geometry
g2.

INTERSECTS() is based on the original MySQL implementation and uses object
bounding rectangles, while ST_INTERSECTS() uses object shapes.

INTERSECTS() tests the opposite relationship to DISJOINT().

URL: https://mariadb.com/kb/en/intersects/https://mariadb.com/kb/en/intersects/��<����
�
�
�Ƨ����)LAST_INSERT_IDSyntax
------

LAST_INSERT_ID(), LAST_INSERT_ID(expr)

Description
-----------

LAST_INSERT_ID() (no arguments) returns the first automatically generated
value successfully inserted for an AUTO_INCREMENT column as a result of the
most recently executed INSERT statement. The value of LAST_INSERT_ID() remains
unchanged if no rows are successfully inserted.

If one gives an argument to LAST_INSERT_ID(), then it will return the value of
the expression and the next call to LAST_INSERT_ID() will return the same
value. The value will also be sent to the client and can be accessed by the
mysql_insert_id function.

For example, after inserting a row that generates an AUTO_INCREMENT value, you
can get the value like this:

SELECT LAST_INSERT_ID();
+------------------+
| LAST_INSERT_ID() |
+------------------+
|                9 |
+------------------+

You can also use LAST_INSERT_ID() to delete the last inserted row:

DELETE FROM product WHERE id = LAST_INSERT_ID();

If no rows were successfully inserted, LAST_INSERT_ID() returns 0.

The value of LAST_INSERT_ID() will be consistent across all versions if all
rows in the INSERT or UPDATE statement were successful.

The currently executing statement does not affect the value of
LAST_INSERT_ID(). Suppose that you generate an AUTO_INCREMENT value with one
statement, and then refer to LAST_INSERT_ID() in a multiple-row INSERT
statement that inserts rows into a table with its own AUTO_INCREMENT column.
The value of LAST_INSERT_ID() will remain stable in the second statement; its
value for the second and later rows is not affected by the earlier row
insertions. (However, if you mix references to LAST_INSERT_ID() and
LAST_INSERT_ID(expr), the effect is undefined.)

If the previous statement returned an error, the value of LAST_INSERT_ID() is
undefined. For transactional tables, if the statement is rolled back due to an
error, the value of LAST_INSERT_ID() is left undefined. For manual ROLLBACK,
the value of LAST_INSERT_ID() is not restored to that before the transaction;
it remains as it was at the point of the ROLLBACK.

Within the body of a stored routine (procedure or function) or a trigger, the
value of LAST_INSERT_ID() changes the same way as for statements executed
outside the body of these kinds of objects. The effect of a stored routine or
trigger upon the value of LAST_INSERT_ID() that is seen by following
statements depends on the kind of routine:

* If a stored procedure executes statements that change the value of
LAST_INSERT_ID(), the new value will be seen by statements that follow the
procedure call.

* For stored functions and triggers that change the value, the value is
restored when the function or trigger ends, so following statements will not
see a changed value.

Examples
--------

CREATE TABLE t (
 id INTEGER UNSIGNED AUTO_INCREMENT PRIMARY KEY,
 f VARCHAR(1))
ENGINE = InnoDB;

INSERT INTO t(f) VALUES('a');

SELECT LAST_INSERT_ID();
+------------------+
| LAST_INSERT_ID() |
+------------------+
|                1 |
+------------------+

INSERT INTO t(f) VALUES('b');

INSERT INTO t(f) VALUES('c');

SELECT LAST_INSERT_ID();
+------------------+
| LAST_INSERT_ID() |
+------------------+
|                3 |
+------------------+

INSERT INTO t(f) VALUES('d'),('e');

SELECT LAST_INSERT_ID();
+------------------+
| LAST_INSERT_ID() |
+------------------+
|                4 |
+------------------+

SELECT * FROM t;
+----+------+
| id | f    |
+----+------+
|  1 | a    |
|  2 | b    |
|  3 | c    |
|  4 | d    |
|  5 | e    |
+----+------+

SELECT LAST_INSERT_ID(12);
+--------------------+
| LAST_INSERT_ID(12) |
+--------------------+
|                 12 |
+--------------------+

SELECT LAST_INSERT_ID();
+------------------+
| LAST_INSERT_ID() |
+------------------+
|               12 |
+------------------+

INSERT INTO t(f) VALUES('f');

SELECT LAST_INSERT_ID();
+------------------+
| LAST_INSERT_ID() |
+------------------+
|                6 |
+------------------+

SELECT * FROM t;
+----+------+
| id | f    |
+----+------+
|  1 | a    |
|  2 | b    |
|  3 | c    |
|  4 | d    |
|  5 | e    |
|  6 | f    |
+----+------+

SELECT LAST_INSERT_ID(12);
+--------------------+
| LAST_INSERT_ID(12) |
+--------------------+
|                 12 |
+--------------------+

INSERT INTO t(f) VALUES('g');

SELECT * FROM t;
+----+------+
| id | f    |
+----+------+
|  1 | a    |
|  2 | b    |
|  3 | c    |
|  4 | d    |
|  5 | e    |
|  6 | f    |
|  7 | g    |
+----+------+

URL: https://mariadb.com/kb/en/last_insert_id/https://mariadb.com/kb/en/last_insert_id/�lUSERSyntax
------

USER()

Description
-----------

Returns the current MariaDB user name and host name, given when authenticating
to MariaDB, as a string in the utf8 character set.

Note that the value of USER() may differ from the value of CURRENT_USER(),
which is the user used to authenticate the current client. CURRENT_ROLE()
returns the current active role.

SYSTEM_USER() and SESSION_USER are synonyms for USER().

Statements using the USER() function or one of its synonyms are not safe for
statement level replication.

Examples
--------

shell> mysql --user="anonymous"

SELECT USER(),CURRENT_USER();
+---------------------+----------------+
| USER()              | CURRENT_USER() |
+---------------------+----------------+
| anonymous@localhost | @localhost     |
+---------------------+----------------+

To select only the IP address, use SUBSTRING_INDEX(),

SELECT SUBSTRING_INDEX(USER(), '@', -1);
+----------------------------------+
| SUBSTRING_INDEX(USER(), '@', -1) |
+----------------------------------+
| 192.168.0.101                    |
+----------------------------------+

URL: https://mariadb.com/kb/en/user/https://mariadb.com/kb/en/user/��#OVERLAPSSyntax
------

OVERLAPS(g1,g2)

Description
-----------

Returns 1 or 0 to indicate whether g1 spatially overlaps g2. The term
spatially overlaps is used if two geometries intersect and their intersection
results in a geometry of the same dimension but not equal to either of the
given geometries.

OVERLAPS() is based on the original MySQL implementation and uses object
bounding rectangles, while ST_OVERLAPS() uses object shapes.

URL: https://mariadb.com/kb/en/overlaps/https://mariadb.com/kb/en/overlaps/�
�(ST_DIFFERENCESyntax
------

ST_DIFFERENCE(g1,g2)

Description
-----------

Returns a geometry representing the point set difference of the given geometry
values.

Example
-------

SET @g1 = POINT(10,10), @g2 = POINT(20,20);

SELECT ST_AsText(ST_Difference(@g1, @g2));
+------------------------------------+
| ST_AsText(ST_Difference(@g1, @g2)) |
+------------------------------------+
| POINT(10 10)                       |
+------------------------------------+

URL: https://mariadb.com/kb/en/st_difference/https://mariadb.com/kb/en/st_difference/��&ST_DISTANCESyntax
------

ST_DISTANCE(g1,g2)

Description
-----------

Returns the distance between two geometries, or null if not given valid inputs.

Example
-------

SELECT ST_Distance(POINT(1,2),POINT(2,2));
+------------------------------------+
| ST_Distance(POINT(1,2),POINT(2,2)) |
+------------------------------------+
|                                  1 |
+------------------------------------+

URL: https://mariadb.com/kb/en/st_distance/https://mariadb.com/kb/en/st_distance/���3�
��A��x�0�
�%LAST_VALUESyntax
------

LAST_VALUE(expr,[expr,...])

LAST_VALUE(expr) OVER (
 [ PARTITION BY partition_expression ]
 [ ORDER BY order_list ]
)

Description
-----------

LAST_VALUE() evaluates all expressions and returns the last.

This is useful together with setting user variables to a value with
@var:=expr, for example when you want to get data of rows updated/deleted
without having to do two queries against the table.

LAST_VALUE can be used as a window function.

Returns NULL if no last value exists.

Examples
--------

CREATE TABLE t1 (a int, b int);
INSERT INTO t1 VALUES(1,10),(2,20);
DELETE FROM t1 WHERE a=1 AND last_value(@a:=a,@b:=b,1);
SELECT @a,@b;
+------+------+
| @a   | @b   |
+------+------+
|    1 |   10 |
+------+------+

As a window function:

CREATE TABLE t1 (
 pk int primary key,
 a int,
 b int,
 c char(10),
 d decimal(10, 3),
 e real
);

INSERT INTO t1 VALUES
( 1, 0, 1,    'one',    0.1,  0.001),
( 2, 0, 2,    'two',    0.2,  0.002),
( 3, 0, 3,    'three',  0.3,  0.003),
( 4, 1, 2,    'three',  0.4,  0.004),
( 5, 1, 1,    'two',    0.5,  0.005),
( 6, 1, 1,    'one',    0.6,  0.006),
( 7, 2, NULL, 'n_one',  0.5,  0.007),
( 8, 2, 1,    'n_two',  NULL, 0.008),
( 9, 2, 2,    NULL,     0.7,  0.009),
(10, 2, 0,    'n_four', 0.8,  0.010),
(11, 2, 10,   NULL,     0.9,  NULL);

SELECT pk, FIRST_VALUE(pk) OVER (ORDER BY pk) AS first_asc,
     LAST_VALUE(pk) OVER (ORDER BY pk) AS last_asc,
     FIRST_VALUE(pk) OVER (ORDER BY pk DESC) AS first_desc,
     LAST_VALUE(pk) OVER (ORDER BY pk DESC) AS last_desc
FROM t1
ORDER BY pk DESC;

+----+-----------+----------+------------+-----------+
| pk | first_asc | last_asc | first_desc | last_desc |
+----+-----------+----------+------------+-----------+
| 11 |         1 |       11 |         11 |        11 |
| 10 |         1 |       10 |         11 |        10 |
|  9 |         1 |        9 |         11 |         9 |
|  8 |         1 |        8 |         11 |         8 |
|  7 |         1 |        7 |         11 |         7 |
|  6 |         1 |        6 |         11 |         6 |
|  5 |         1 |        5 |         11 |         5 |
|  4 |         1 |        4 |         11 |         4 |
|  3 |         1 |        3 |         11 |         3 |
|  2 |         1 |        2 |         11 |         2 |
|  1 |         1 |        1 |         11 |         1 |
+----+-----------+----------+------------+-----------+

CREATE OR REPLACE TABLE t1 (i int);
INSERT INTO t1 VALUES (1),(2),(3),(4),(5),(6),(7),(8),(9),(10);

SELECT i,
 FIRST_VALUE(i) OVER (ORDER BY i ROWS BETWEEN CURRENT ROW and 1 FOLLOWING) AS
f_1f,
 LAST_VALUE(i) OVER (ORDER BY i ROWS BETWEEN CURRENT ROW and 1 FOLLOWING) AS
l_1f,
 FIRST_VALUE(i) OVER (ORDER BY i ROWS BETWEEN 1 PRECEDING AND 1 FOLLOWING) AS
f_1p1f,
 LAST_VALUE(i) OVER (ORDER BY i ROWS BETWEEN 1 PRECEDING AND 1 FOLLOWING) AS
l_1p1f,
 FIRST_VALUE(i) OVER (ORDER BY i ROWS BETWEEN 2 PRECEDING AND 1 PRECEDING) AS
f_2p1p,
 LAST_VALUE(i) OVER (ORDER BY i ROWS BETWEEN 2 PRECEDING AND 1 PRECEDING) AS
l_2p1p,
 FIRST_VALUE(i) OVER (ORDER BY i ROWS BETWEEN 1 FOLLOWING AND 2 FOLLOWING) AS
f_1f2f,
 LAST_VALUE(i) OVER (ORDER BY i ROWS BETWEEN 1 FOLLOWING AND 2 FOLLOWING) AS
l_1f2f
FROM t1;

+------+------+------+--------+--------+--------+--------+--------+--------+
| i    | f_1f | l_1f | f_1p1f | l_1p1f | f_2p1p | l_2p1p | f_1f2f | l_1f2f |
+------+------+------+--------+--------+--------+--------+--------+--------+
|    1 |    1 |    2 |      1 |      2 |   NULL |   NULL |      2 |      3 |
|    2 |    2 |    3 |      1 |      3 |      1 |      1 |      3 |      4 |
|    3 |    3 |    4 |      2 |      4 |      1 |      2 |      4 |      5 |
|    4 |    4 |    5 |      3 |      5 |      2 |      3 |      5 |      6 |
|    5 |    5 |    6 |      4 |      6 |      3 |      4 |      6 |      7 |
|    6 |    6 |    7 |      5 |      7 |      4 |      5 |      7 |      8 |
|    7 |    7 |    8 |      6 |      8 |      5 |      6 |      8 |      9 |
|    8 |    8 |    9 |      7 |      9 |      6 |      7 |      9 |     10 |
|    9 |    9 |   10 |      8 |     10 |      7 |      8 |     10 |     10 |
|   10 |   10 |   10 |      9 |     10 |      8 |      9 |   NULL |   NULL |
+------+------+------+--------+--------+--------+--------+--------+--------+

URL: https://mariadb.com/kb/en/last_value/https://mariadb.com/kb/en/last_value/�="VERSIONSyntax
------

VERSION()

Description
-----------

Returns a string that indicates the MariaDB server version. The string uses
the utf8 character set.

Examples
--------

SELECT VERSION();
+----------------+
| VERSION()      |
+----------------+
| 10.4.7-MariaDB |
+----------------+

The VERSION() string may have one or more of the following suffixes:

+---------------------------+------------------------------------------------+
| Suffix                    | Description                                    |
+---------------------------+------------------------------------------------+
| -embedded                 | The server is an embedded server               |
|                           | (libmariadbd).                                 |
+---------------------------+------------------------------------------------+
| -log                      | General logging, slow logging or binary        |
|                           | (replication) logging is enabled.              |
+---------------------------+------------------------------------------------+
| -debug                    | The server is compiled for debugging.          |
+---------------------------+------------------------------------------------+
| -valgrind                 | The server is compiled to be instrumented      |
|                           | with valgrind.                                 |
+---------------------------+------------------------------------------------+

Changing the Version String
---------------------------

Some old legacy code may break because they are parsing the VERSION string and
expecting a MySQL string or a simple version string like Joomla til API17, see
MDEV-7780.

One can fool these applications by setting the version string from the command
line or the my.cnf files with --version=....

URL: https://mariadb.com/kb/en/version/https://mariadb.com/kb/en/version/��-ST_DISTANCE_SPHEREMariaDB starting with 10.2.38
-----------------------------
ST_DISTANCE_SPHERE was introduced in MariaDB 10.2.38, MariaDB 10.3.29, MariaDB
10.4.19 and MariaDB 10.5.10.

Syntax
------

ST_DISTANCE_SPHERE(g1,g2,[r])

Description
-----------

Returns the spherical distance between two geometries (point or multipoint) on
a sphere with the optional radius r (default is the Earth radius if r is not
specified), or NULL if not given valid inputs.

Example
-------

set @zenica   = ST_GeomFromText('POINT(17.907743 44.203438)');
set @sarajevo = ST_GeomFromText('POINT(18.413076 43.856258)');
SELECT ST_Distance_Sphere(@zenica, @sarajevo);
55878.59337591705

URL: https://mariadb.com/kb/en/st_distance_sphere/https://mariadb.com/kb/en/st_distance_sphere/�	�$ST_LENGTHSyntax
------

ST_LENGTH(ls)

Description
-----------

Returns as a double-precision number the length of the LineString value ls in
its associated spatial reference.

Examples
--------

SET @ls = 'LineString(1 1,2 2,3 3)';

SELECT ST_LENGTH(ST_GeomFromText(@ls));
+---------------------------------+
| ST_LENGTH(ST_GeomFromText(@ls)) |
+---------------------------------+
|                2.82842712474619 |
+---------------------------------+

URL: https://mariadb.com/kb/en/st_length/https://mariadb.com/kb/en/st_length/�"�t����A��!ROWNUMMariaDB starting with 10.6.1
----------------------------
From MariaDB 10.6.1, the ROWNUM() function is supported.

Syntax
------

ROWNUM()

In Oracle mode one can just use ROWNUM, without the parentheses.

Description
-----------

ROWNUM() returns the current number of accepted rows in the current context.
It main purpose is to emulate the ROWNUM pseudo column in Oracle. For MariaDB
native applications, we recommend the usage of LIMIT, as it is easier to use
and gives more predictable results than the usage of ROWNUM().

The main difference between using LIMIT and ROWNUM() to limit the rows in the
result is that LIMIT works on the result set while ROWNUM works on the number
of accepted rows (before any ORDER or GROUP BY clauses).

The following queries will return the same results:

SELECT * from t1 LIMIT 10;
SELECT * from t1 WHERE ROWNUM() <= 10;

While the following may return different results based on in which orders the
rows are found:

SELECT * from t1 ORDER BY a LIMIT 10;
SELECT * from t1 ORDER BY a WHERE ROWNUM() <= 10;

The recommended way to use ROWNUM to limit the number of returned rows and get
predictable results is to have the query in a subquery and test for ROWNUM()
in the outer query:

SELECT * FROM (select * from t1 ORDER BY a) WHERE ROWNUM() <= 10;

ROWNUM() can be used in the following contexts:

* SELECT
* INSERT
* UPDATE
* DELETE
* LOAD DATA INFILE

Used in other contexts, ROWNUM() will return 0.

Examples
--------

INSERT INTO t1 VALUES (1,ROWNUM()),(2,ROWNUM()),(3,ROWNUM());

INSERT INTO t1 VALUES (1),(2) returning a, ROWNUM();

UPDATE t1 SET row_num_column=ROWNUM();

DELETE FROM t1 WHERE a < 10 AND ROWNUM() < 2;

LOAD DATA INFILE 'filename' into table t1 fields terminated by ',' 
 lines terminated by "\r\n" (a,b) set c=ROWNUM();

Optimizations
-------------

In many cases where ROWNUM() is used, MariaDB will use the same optimizations
it uses with LIMIT.

LIMIT optimization is possible when using ROWNUM in the following manner:

* When one is in a top level WHERE clause comparing ROWNUM() with a numerical
constant using any of the following expressions:
ROWNUM() < number
ROWNUM() <= number
ROWNUM() = 1
ROWNUM() can be also be the right argument to the comparison function.

In the above cases, LIMIT optimization can be done in the following cases:

* For the current sub query when the ROWNUM comparison is done on the top
level:

SELECT * from t1 WHERE ROWNUM() <= 2 AND t1.a > 0

* For an inner sub query, when the upper level has only a ROWNUM() comparison
in the WHERE clause:

SELECT * from (select * from t1) as t WHERE ROWNUM() <= 2

Other Changes Related to ROWNUM
-------------------------------

When ROWNUM() is used anywhere in a query, the optimization to ignore ORDER BY
in subqueries are disabled.

This was done to get the following common Oracle query to work as expected:

select * from (select * from t1 order by a desc) as t where rownum() <= 2;

By default MariaDB ignores any ORDER BY in subqueries both because the SQL
standard defines results sets in subqueries to be un-ordered and because of
performance reasons (especially when using views in subqueries). See MDEV-3926
"Wrong result with GROUP BY ... WITH ROLLUP" for a discussion of this topic.

Other Considerations
--------------------

While MariaDB tries to emulate Oracle's usage of ROWNUM() as closely as
possible, there are cases where the result is different:

* When the optimizer finds rows in a different order (because of different
storage methods or optimization). This may also happen in Oracle if one adds
or deletes an index, in which case the rows may be found in a different order.

Note that usage of ROWNUM() in functions or stored procedures will use their
own context, not the caller's context.

URL: https://mariadb.com/kb/en/rownum/https://mariadb.com/kb/en/rownum/��CAssignment Operator (=)Syntax
------

identifier = expr

Description
-----------

The equal sign is used as both an assignment operator in certain contexts, and
as a comparison operator. When used as assignment operator, the value on the
right is assigned to the variable (or column, in some contexts) on the left.

Since its use can be ambiguous, unlike the := assignment operator, the =
assignment operator cannot be used in all contexts, and is only valid as part
of a SET statement, or the SET clause of an UPDATE statement

This operator works with both user-defined variables and local variables.

Examples
--------

UPDATE table_name SET x = 2 WHERE x > 100;

SET @x = 1, @y := 2;

URL: https://mariadb.com/kb/en/assignment-operators-assignment-operator/https://mariadb.com/kb/en/assignment-operators-assignment-operator/��$Not Equal OperatorSyntax
------

<>, !=

Description
-----------

Not equal operator. Evaluates both SQL expressions and returns 1 if they are
not equal and 0 if they are equal, or NULL if either expression is NULL. If
the expressions return different data types, (for instance, a number and a
string), performs type conversion.

When used in row comparisons these two queries return the same results:

SELECT (t1.a, t1.b) != (t2.x, t2.y) 
FROM t1 INNER JOIN t2;

SELECT (t1.a != t2.x) OR (t1.b != t2.y)
FROM t1 INNER JOIN t2;

Examples
--------

SELECT '.01' <> '0.01';
+-----------------+
| '.01' <> '0.01' |
+-----------------+
|               1 |
+-----------------+

SELECT .01 <> '0.01';
+---------------+
| .01 <> '0.01' |
+---------------+
|             0 |
+---------------+

SELECT 'zapp' <> 'zappp';
+-------------------+
| 'zapp' <> 'zappp' |
+-------------------+
|                 1 |
+-------------------+

URL: https://mariadb.com/kb/en/not-equal/https://mariadb.com/kb/en/not-equal/��&ST_OVERLAPSSyntax
------

ST_OVERLAPS(g1,g2)

Description
-----------

Returns 1 or 0 to indicate whether geometry g1 spatially overlaps geometry g2.

The term spatially overlaps is used if two geometries intersect and their
intersection results in a geometry of the same dimension but not equal to
either of the given geometries.

ST_OVERLAPS() uses object shapes, while OVERLAPS(), based on the original
MySQL implementation, uses object bounding rectangles.

URL: https://mariadb.com/kb/en/st-overlaps/https://mariadb.com/kb/en/st-overlaps/��"TOUCHESSyntax
------

Touches(g1,g2)

Description
-----------

Returns 1 or 0 to indicate whether g1 spatially touches g2. Two geometries
spatially touch if the interiors of the geometries do not intersect, but the
boundary of one of the geometries intersects either the boundary or the
interior of the other.

TOUCHES() is based on the original MySQL implementation and uses object
bounding rectangles, while ST_TOUCHES() uses object shapes.

URL: https://mariadb.com/kb/en/touches/https://mariadb.com/kb/en/touches/�'CURRENT_DATESyntax
------

CURRENT_DATE, CURRENT_DATE()

Description
-----------

CURRENT_DATE and CURRENT_DATE() are synonyms for CURDATE().

URL: https://mariadb.com/kb/en/current_date/https://mariadb.com/kb/en/current_date/�'CURRENT_TIMESyntax
------

CURRENT_TIME
CURRENT_TIME([precision])

Description
-----------

CURRENT_TIME and CURRENT_TIME() are synonyms for CURTIME().

URL: https://mariadb.com/kb/en/current_time/https://mariadb.com/kb/en/current_time/�,CURRENT_TIMESTAMPSyntax
------

CURRENT_TIMESTAMP
CURRENT_TIMESTAMP([precision])

Description
-----------

CURRENT_TIMESTAMP and CURRENT_TIMESTAMP() are synonyms for NOW().

URL: https://mariadb.com/kb/en/current_timestamp/https://mariadb.com/kb/en/current_timestamp/������X-c�J
	H>���t$<Syntax
------

<

Description
-----------

Less than operator. Evaluates both SQL expressions and returns 1 if the left
value is less than the right value and 0 if it is not, or NULL if either
expression is NULL. If the expressions return different data types, (for
instance, a number and a string), performs type conversion.

When used in row comparisons these two queries return the same results:

SELECT (t1.a, t1.b) < (t2.x, t2.y) 
FROM t1 INNER JOIN t2;

SELECT (t1.a < t2.x) OR ((t1.a = t2.x) AND (t1.b < t2.y))
FROM t1 INNER JOIN t2;

Examples
--------

SELECT 2 < 2;
+-------+
| 2 < 2 |
+-------+
|     0 |
+-------+

Type conversion:

SELECT 3<'4';
+-------+
| 3<'4' |
+-------+
|     1 |
+-------+

Case insensitivity - see Character Sets and Collations:

SELECT 'a'<'A';
+---------+
| 'a'<'A' |
+---------+
|       0 |
+---------+

URL: https://mariadb.com/kb/en/less-than/https://mariadb.com/kb/en/less-than/�!-<=Syntax
------

<=

Description
-----------

Less than or equal operator. Evaluates both SQL expressions and returns 1 if
the left value is less than or equal to the right value and 0 if it is not, or
NULL if either expression is NULL. If the expressions return different data
types, (for instance, a number and a string), performs type conversion.

When used in row comparisons these two queries return the same results:

SELECT (t1.a, t1.b) <= (t2.x, t2.y) 
FROM t1 INNER JOIN t2;

SELECT (t1.a < t2.x) OR ((t1.a = t2.x) AND (t1.b <= t2.y))
FROM t1 INNER JOIN t2;

Examples
--------

SELECT 0.1 <= 2;
+----------+
| 0.1 <= 2 |
+----------+
|        1 |
+----------+

SELECT 'a'<='A';
+----------+
| 'a'<='A' |
+----------+
|        1 |
+----------+

URL: https://mariadb.com/kb/en/less-than-or-equal/https://mariadb.com/kb/en/less-than-or-equal/�#*<=>Syntax
------

<=>

Description
-----------

NULL-safe equal operator. It performs an equality comparison like the =
operator, but returns 1 rather than NULL if both operands are NULL, and 0
rather than NULL if one operand is NULL.

a <=> b is equivalent to a = b OR (a IS NULL AND b IS NULL).

When used in row comparisons these two queries return the same results:

SELECT (t1.a, t1.b) <=> (t2.x, t2.y) 
FROM t1 INNER JOIN t2;

SELECT (t1.a <=> t2.x) AND (t1.b <=> t2.y)
FROM t1 INNER JOIN t2;

See also NULL Values in MariaDB.

Examples
--------

SELECT 1 <=> 1, NULL <=> NULL, 1 <=> NULL;
+---------+---------------+------------+
| 1 <=> 1 | NULL <=> NULL | 1 <=> NULL |
+---------+---------------+------------+
|       1 |             1 |          0 |
+---------+---------------+------------+

SELECT 1 = 1, NULL = NULL, 1 = NULL;
+-------+-------------+----------+
| 1 = 1 | NULL = NULL | 1 = NULL |
+-------+-------------+----------+
|     1 |        NULL |     NULL |
+-------+-------------+----------+

URL: https://mariadb.com/kb/en/null-safe-equal/https://mariadb.com/kb/en/null-safe-equal/�� =Syntax
------

left_expr = right_expr

Description
-----------

Equal operator. Evaluates both SQL expressions and returns 1 if they are
equal, 0 if they are not equal, or NULL if either expression is NULL. If the
expressions return different data types (for example, a number and a string),
a type conversion is performed.

When used in row comparisons these two queries are synonymous and return the
same results:

SELECT (t1.a, t1.b) = (t2.x, t2.y) FROM t1 INNER JOIN t2;

SELECT (t1.a = t2.x) AND (t1.b = t2.y) FROM t1 INNER JOIN t2;

To perform a NULL-safe comparison, use the <=> operator.

= can also be used as an assignment operator.

Examples
--------

SELECT 1 = 0;
+-------+
| 1 = 0 |
+-------+
|     0 |
+-------+

SELECT '0' = 0;
+---------+
| '0' = 0 |
+---------+
|       1 |
+---------+

SELECT '0.0' = 0;
+-----------+
| '0.0' = 0 |
+-----------+
|         1 |
+-----------+

SELECT '0.01' = 0;
+------------+
| '0.01' = 0 |
+------------+
|          0 |
+------------+

SELECT '.01' = 0.01;
+--------------+
| '.01' = 0.01 |
+--------------+
|            1 |
+--------------+

SELECT (5 * 2) = CONCAT('1', '0');
+----------------------------+
| (5 * 2) = CONCAT('1', '0') |
+----------------------------+
|                          1 |
+----------------------------+

SELECT 1 = NULL;
+----------+
| 1 = NULL |
+----------+
|     NULL |
+----------+

SELECT NULL = NULL;
+-------------+
| NULL = NULL |
+-------------+
|        NULL |
+-------------+

URL: https://mariadb.com/kb/en/equal/https://mariadb.com/kb/en/equal/��'>Syntax
------

>

Description
-----------

Greater than operator. Evaluates both SQL expressions and returns 1 if the
left value is greater than the right value and 0 if it is not, or NULL if
either expression is NULL. If the expressions return different data types,
(for instance, a number and a string), performs type conversion.

When used in row comparisons these two queries return the same results:

SELECT (t1.a, t1.b) > (t2.x, t2.y) 
FROM t1 INNER JOIN t2;

SELECT (t1.a > t2.x) OR ((t1.a = t2.x) AND (t1.b > t2.y))
FROM t1 INNER JOIN t2;

Examples
--------

SELECT 2 > 2;
+-------+
| 2 > 2 |
+-------+
|     0 |
+-------+

SELECT 'b' > 'a';
+-----------+
| 'b' > 'a' |
+-----------+
|         1 |
+-----------+

URL: https://mariadb.com/kb/en/greater-than/https://mariadb.com/kb/en/greater-than/�"CURTIMESyntax
------

CURTIME([precision])

Description
-----------

Returns the current time as a value in 'HH:MM:SS' or HHMMSS.uuuuuu format,
depending on whether the function is used in a string or numeric context. The
value is expressed in the current time zone.

The optional precision determines the microsecond precision. See Microseconds
in MariaDB.

Examples
--------

SELECT CURTIME();
+-----------+
| CURTIME() |
+-----------+
| 12:45:39  |
+-----------+

SELECT CURTIME() + 0;
+---------------+
| CURTIME() + 0 |
+---------------+
| 124545.000000 |
+---------------+

With precision:

SELECT CURTIME(2);
+-------------+
| CURTIME(2)  |
+-------------+
| 09:49:08.09 |
+-------------+

URL: https://mariadb.com/kb/en/curtime/https://mariadb.com/kb/en/curtime/
�(DATE FUNCTIONSyntax
------

DATE(expr)

Description
-----------

Extracts the date part of the date or datetime expression expr. Returns NULL
and throws a warning when passed an invalid date.

Examples
--------

SELECT DATE('2013-07-18 12:21:32');
+-----------------------------+
| DATE('2013-07-18 12:21:32') |
+-----------------------------+
| 2013-07-18                  |
+-----------------------------+

URL: https://mariadb.com/kb/en/date-function/https://mariadb.com/kb/en/date-function/�R@S�
	��&&DATE_FORMAT
|DAYSyntax
------

DAY(date)

Description
-----------

DAY() is a synonym for DAYOFMONTH().

URL: https://mariadb.com/kb/en/day/https://mariadb.com/kb/en/day/	`$DAYOFYEARSyntax
------

DAYOFYEAR(date)

Description
-----------

Returns the day of the year for date, in the range 1 to 366.

Examples
--------

SELECT DAYOFYEAR('2018-02-16');
+-------------------------+
| DAYOFYEAR('2018-02-16') |
+-------------------------+
|                      47 |
+-------------------------+

URL: https://mariadb.com/kb/en/dayofyear/https://mariadb.com/kb/en/dayofyear/	�$FROM_DAYSSyntax
------

FROM_DAYS(N)

Description
-----------

Given a day number N, returns a DATE value. The day count is based on the
number of days from the start of the standard calendar (0000-00-00).

The function is not designed for use with dates before the advent of the
Gregorian calendar in October 1582. Results will not be reliable since it
doesn't account for the lost days when the calendar changed from the Julian
calendar.

This is the converse of the TO_DAYS() function.

Examples
--------

SELECT FROM_DAYS(730669);
+-------------------+
| FROM_DAYS(730669) |
+-------------------+
| 2000-07-03        |
+-------------------+

URL: https://mariadb.com/kb/en/from_days/https://mariadb.com/kb/en/from_days/6������/����3o^�^��̜�Syntax
------

DATE_FORMAT(date, format[, locale])

Description
-----------

Formats the date value according to the format string.

The language used for the names is controlled by the value of the
lc_time_names system variable. See server locale for more on the supported
locales.

The options that can be used by DATE_FORMAT(), as well as its inverse
STR_TO_DATE() and the FROM_UNIXTIME() function, are:

+---------------------------+------------------------------------------------+
| Option                    | Description                                    |
+---------------------------+------------------------------------------------+
| %a                        | Short weekday name in current locale           |
|                           | (Variable lc_time_names).                      |
+---------------------------+------------------------------------------------+
| %b                        | Short form month name in current locale. For   |
|                           | locale en_US this is one of:                   |
|                           | Jan,Feb,Mar,Apr,May,Jun,Jul,Aug,Sep,Oct,Nov    |
|                           | or Dec.                                        |
+---------------------------+------------------------------------------------+
| %c                        | Month with 1 or 2 digits.                      |
+---------------------------+------------------------------------------------+
| %D                        | Day with English suffix 'th', 'nd', 'st' or    |
|                           | 'rd''. (1st, 2nd, 3rd...).                     |
+---------------------------+------------------------------------------------+
| %d                        | Day with 2 digits.                             |
+---------------------------+------------------------------------------------+
| %e                        | Day with 1 or 2 digits.                        |
+---------------------------+------------------------------------------------+
| %f                        | Microseconds 6 digits.                         |
+---------------------------+------------------------------------------------+
| %H                        | Hour with 2 digits between 00-23.              |
+---------------------------+------------------------------------------------+
| %h                        | Hour with 2 digits between 01-12.              |
+---------------------------+------------------------------------------------+
| %I                        | Hour with 2 digits between 01-12.              |
+---------------------------+------------------------------------------------+
| %i                        | Minute with 2 digits.                          |
+---------------------------+------------------------------------------------+
| %j                        | Day of the year (001-366)                      |
+---------------------------+------------------------------------------------+
| %k                        | Hour with 1 digits between 0-23.               |
+---------------------------+------------------------------------------------+
| %l                        | Hour with 1 digits between 1-12.               |
+---------------------------+------------------------------------------------+
| %M                        | Full month name in current locale (Variable    |
|                           | lc_time_names).                                |
+---------------------------+------------------------------------------------+
| %m                        | Month with 2 digits.                           |
+---------------------------+------------------------------------------------+
| %p                        | AM/PM according to current locale (Variable    |
|                           | lc_time_names).                                |
+---------------------------+------------------------------------------------+
| %r                        | Time in 12 hour format, followed by AM/PM.     |
|                           | Short for '%I:%i:%S %p'.                       |
+---------------------------+------------------------------------------------+
| %S                        | Seconds with 2 digits.                         |
+---------------------------+------------------------------------------------+
| %s                        | Seconds with 2 digits.                         |
+---------------------------+------------------------------------------------+
| %T                        | Time in 24 hour format. Short for '%H:%i:%S'.  |
+---------------------------+------------------------------------------------+
| %U                        | Week number (00-53), when first day of the     |
|                           | week is Sunday.                                |
+---------------------------+------------------------------------------------+
| %u                        | Week number (00-53), when first day of the     |
|                           | week is Monday.                                |
+---------------------------+------------------------------------------------+
| %V                        | Week number (01-53), when first day of the     |
|                           | week is Sunday. Used with %X.                  |
+---------------------------+------------------------------------------------+
| %v                        | Week number (01-53), when first day of the     |
|                           | week is Monday. Used with %x.                  |
+---------------------------+------------------------------------------------+
| %W                        | Full weekday name in current locale (Variable  |
|                           | lc_time_names).                                |
+---------------------------+------------------------------------------------+
| %w                        | Day of the week. 0 = Sunday, 6 = Saturday.     |
+---------------------------+------------------------------------------------+
| %X                        | Year with 4 digits when first day of the week  |
|                           | is Sunday. Used with %V.                       |
+---------------------------+------------------------------------------------+
| %x                        | Year with 4 digits when first day of the week  |
|                           | is Monday. Used with %v.                       |
+---------------------------+------------------------------------------------+
| %Y                        | Year with 4 digits.                            |
+---------------------------+------------------------------------------------+
| %y                        | Year with 2 digits.                            |
+---------------------------+------------------------------------------------+
| %#                        | For str_to_date(), skip all numbers.           |
+---------------------------+------------------------------------------------+
| %.                        | For str_to_date(), skip all punctation         |
|                           | characters.                                    |
+---------------------------+------------------------------------------------+
| %@                        | For str_to_date(), skip all alpha characters.  |
+---------------------------+------------------------------------------------+
| %%                        | A literal % character.                         |
+---------------------------+------------------------------------------------+

To get a date in one of the standard formats, GET_FORMAT() can be used.

Examples
--------

SELECT DATE_FORMAT('2009-10-04 22:23:00', '%W %M %Y');
+------------------------------------------------+
| DATE_FORMAT('2009-10-04 22:23:00', '%W %M %Y') |
+------------------------------------------------+
| Sunday October 2009                            |
+------------------------------------------------+

SELECT DATE_FORMAT('2007-10-04 22:23:00', '%H:%i:%s');
+------------------------------------------------+
| DATE_FORMAT('2007-10-04 22:23:00', '%H:%i:%s') |
+------------------------------------------------+
| 22:23:00                                       |
+------------------------------------------------+

SELECT DATE_FORMAT('1900-1)�֟��
0-04 22:23:00', '%D %y %a %d %m %b %j');
+------------------------------------------------------------+
| DATE_FORMAT('1900-10-04 22:23:00', '%D %y %a %d %m %b %j') |
+------------------------------------------------------------+
| 4th 00 Thu 04 10 Oct 277                                   |
+------------------------------------------------------------+

SELECT DATE_FORMAT('1997-10-04 22:23:00', '%H %k %I %r %T %S %w');
+------------------------------------------------------------+
| DATE_FORMAT('1997-10-04 22:23:00', '%H %k %I %r %T %S %w') |
+------------------------------------------------------------+
| 22 22 10 10:23:00 PM 22:23:00 00 6                         |
+------------------------------------------------------------+

SELECT DATE_FORMAT('1999-01-01', '%X %V');
+------------------------------------+
| DATE_FORMAT('1999-01-01', '%X %V') |
+------------------------------------+
| 1998 52                            |
+------------------------------------+

SELECT DATE_FORMAT('2006-06-00', '%d');
+---------------------------------+
| DATE_FORMAT('2006-06-00', '%d') |
+---------------------------------+
| 00                              |
+---------------------------------+

Optionally, the locale can be explicitly specified as the third DATE_FORMAT()
argument. Doing so makes the function independent from the session settings,
and the three argument version of DATE_FORMAT() can be used in virtual indexed
and persistent generated-columns:

SELECT DATE_FORMAT('2006-01-01', '%W', 'el_GR');
+------------------------------------------+
| DATE_FORMAT('2006-01-01', '%W', 'el_GR') |
+------------------------------------------+
| Κυριακή                                  |
+------------------------------------------+

URL: https://mariadb.com/kb/en/date_format/e function. Use the DEFINER clause to
specify a different account as the definer. You must have the SUPER privilege,
or, from MariaDB 10.5.2, the SET USER privilege, to use the DEFINER clause.
See Account Names for details on specifying accounts.

The SQL SECURITY clause specifies what privileges are used when a function is
called. If SQL SECURITY is INVOKER, the function body will be evaluated using
the privileges of the user calling the function. If SQL SECURITY is DEFINER,
the function body is always evaluated using the privileges of the definer
account. DEFINER is the default.

This allows you to create functions that grant limited access to certain data.
For example, say you have a table that stores some employee information, and
that you've granted SELECT privileges only on certain columns to the user
account roger.

CREATE TABLE employees (name TINYTEXT, dept TINYTEXT, salary INT);
GRANT SELECT (name, dept) ON employees TO roger;

To allow the user the get the maximum salary for a department, define a
function and grant the EXECUTE privilege:

CREATE FUNCTION max_salary (dept TINYTEXT) RETURNS INT RETURN
 (SELECT MAX(salary) FROM employees WHERE employees.dept = dept);
GRANT EXECUTE ON FUNCTION max_salary TO roger;

Since SQL SECURITY defaults to DEFINER, whenever the user roger calls this
function, the subselect will execute with your privileges. As long as you have
privileges to select the salary of each employee, the caller of the function
will be able to get the maximum salary for each department without being able
to see individual salaries.

Character sets and collations
-----------------------------

Function return types can be declared to use any valid character set and
collation. If used, the COLLATE attribute needs to be preceded by a CHARACTER
SET attribute.

If the character set and collation are not specifically set in the statement,
the database defaults at the time of creation will be used. If the database
defaults change at a later stage, the stored function character set/collation
will not be changed at the same time; the stored function needs to be dropped
and recreated to ensure the same character set/collation as the database is
used.

Examples
--------

The following example function takes a parameter, performs an operation using
an SQL function, and returns the result.

CREATE FUNCTION hello (s CHAR(20))
  RETURNS CHAR(50) DETERMINISTIC
  RETURN CONCAT('Hello, ',s,'!');

SELECT hello('world');
+----------------+
| hello('world') |
+----------------+
| Hello, world!  |
+----------------+

You can use a compound statement in a function to manipulate data with
statements like INSERT and UPDATE. The following example creates a counter
function that uses a temporary table to store the current value. Because the
compound statement contains statements terminated with semicolons, you have to
first change the statement delimiter with the DELIMITER statement to allow the
semicolon to be used in the function body. See Delimiters in the mariadb
client for more.

CREATE TEMPORARY TABLE counter (c INT);
INSERT INTO counter VALUES (0);
DELIMITER //
CREATE FUNCTION counter () RETURNS INT
 BEGIN
  UPDATE counter SET c = c + 1;
  RETURN (SELECT c FROM counter LIMIT 1);
 END //
DELIMITER ;

Character set and collation:

CREATE FUNCTION hello2 (s CHAR(20))
 RETURNS CHAR(50) CHARACTER SET 'utf8' COLLATE 'utf8_bin' DETERMINISTIC
 RETURN CONCAT('Hello, ',s,'!');

URL: https://mariadb.com/kb/en/create-function/https://mariadb.com/kb/en/create-procedure/https://mariadb.com/kb/en/application-time-periods/https://mariadb.com/kb/en/change-master-to/+�3�+�
�,6��_�*0>=Syntax
------

>=

Description
-----------

Greater than or equal operator. Evaluates both SQL expressions and returns 1
if the left value is greater than or equal to the right value and 0 if it is
not, or NULL if either expression is NULL. If the expressions return different
data types, (for instance, a number and a string), performs type conversion.

When used in row comparisons these two queries return the same results:

SELECT (t1.a, t1.b) >= (t2.x, t2.y) 
FROM t1 INNER JOIN t2;

SELECT (t1.a > t2.x) OR ((t1.a = t2.x) AND (t1.b >= t2.y))
FROM t1 INNER JOIN t2;

Examples
--------

SELECT 2 >= 2;
+--------+
| 2 >= 2 |
+--------+
|      1 |
+--------+

SELECT 'A' >= 'a';
+------------+
| 'A' >= 'a' |
+------------+
|          1 |
+------------+

URL: https://mariadb.com/kb/en/greater-than-or-equal/https://mariadb.com/kb/en/greater-than-or-equal/�&BETWEEN ANDSyntax
------

expr BETWEEN min AND max

Description
-----------

If expr is greater than or equal to min and expr is less than or equal to max,
BETWEEN returns 1, otherwise it returns 0. This is equivalent to the
expression (min <= expr AND expr <= max) if all the arguments are of the same
type. Otherwise type conversion takes place according to the rules described
at Type Conversion, but applied to all the three arguments.

Examples
--------

SELECT 1 BETWEEN 2 AND 3;
+-------------------+
| 1 BETWEEN 2 AND 3 |
+-------------------+
|                 0 |
+-------------------+

SELECT 'b' BETWEEN 'a' AND 'c';
+-------------------------+
| 'b' BETWEEN 'a' AND 'c' |
+-------------------------+
|                       1 |
+-------------------------+

SELECT 2 BETWEEN 2 AND '3';
+---------------------+
| 2 BETWEEN 2 AND '3' |
+---------------------+
|                   1 |
+---------------------+

SELECT 2 BETWEEN 2 AND 'x-3';
+-----------------------+
| 2 BETWEEN 2 AND 'x-3' |
+-----------------------+
|                     0 |
+-----------------------+
1 row in set, 1 warning (0.00 sec)

Warning (Code 1292): Truncated incorrect DOUBLE value: 'x-3'

NULL:

SELECT 1 BETWEEN 1 AND NULL;
+----------------------+
| 1 BETWEEN 1 AND NULL |
+----------------------+
|                 NULL |
+----------------------+

DATE, DATETIME and TIMESTAMP examples. Omitting the time component compares
against 00:00, so later times on the same date are not returned:

CREATE TABLE `x` (
 a date ,
 b datetime,
 c timestamp
)

INSERT INTO x VALUES 
 ('2018-11-11', '2018-11-11 05:15', '2018-11-11 05:15'), 
 ('2018-11-12', '2018-11-12 05:15', '2018-11-12 05:15');

SELECT * FROM x WHERE a BETWEEN '2018-11-11' AND '2018-11-12';
+------------+---------------------+---------------------+
| a          | b                   | c                   |
+------------+---------------------+---------------------+
| 2018-11-11 | 2018-11-11 05:15:00 | 2018-11-11 05:15:00 |
| 2018-11-12 | 2018-11-12 05:15:00 | 2018-11-12 05:15:00 |
+------------+---------------------+---------------------+

SELECT * FROM x WHERE b BETWEEN '2018-11-11' AND '2018-11-12';
+------------+---------------------+---------------------+
| a          | b                   | c                   |
+------------+---------------------+---------------------+
| 2018-11-11 | 2018-11-11 05:15:00 | 2018-11-11 05:15:00 |
+------------+---------------------+---------------------+

SELECT * FROM x WHERE c BETWEEN '2018-11-11' AND '2018-11-12';
+------------+---------------------+---------------------+
| a          | b                   | c                   |
+------------+---------------------+---------------------+
| 2018-11-11 | 2018-11-11 05:15:00 | 2018-11-11 05:15:00 |
+------------+---------------------+---------------------+

URL: https://mariadb.com/kb/en/between-and/https://mariadb.com/kb/en/between-and/��#COALESCESyntax
------

COALESCE(value,...)

Description
-----------

Returns the first non-NULL value in the list, or NULL if there are no non-NULL
values. At least one parameter must be passed.

The function is useful when substituting a default value for null values when
displaying data.

See also NULL Values in MariaDB.

Examples
--------

SELECT COALESCE(NULL,1);
+------------------+
| COALESCE(NULL,1) |
+------------------+
|                1 |
+------------------+

SELECT COALESCE(NULL,NULL,NULL);
+--------------------------+
| COALESCE(NULL,NULL,NULL) |
+--------------------------+
|                     NULL |
+--------------------------+

When two arguments are given, COALESCE() is the same as IFNULL():

SET @a=NULL, @b=1;

SELECT COALESCE(@a, @b), IFNULL(@a, @b);
+------------------+----------------+
| COALESCE(@a, @b) | IFNULL(@a, @b) |
+------------------+----------------+
|                1 |              1 |
+------------------+----------------+

Hex type confusion:

CREATE TABLE t1 (a INT, b VARCHAR(10));
INSERT INTO t1 VALUES (0x31, 0x61),(COALESCE(0x31), COALESCE(0x61));

SELECT * FROM t1;
+------+------+
| a    | b    |
+------+------+
|   49 | a    |
|    1 | a    |
+------+------+

The reason for the differing results above is that when 0x31 is inserted
directly to the column, it's treated as a number (see Hexadecimal Literals),
while when 0x31 is passed to COALESCE(), it's treated as a string, because:

* HEX values have a string data type by default.
* COALESCE() has the same data type as the argument.

Substituting zero for NULL (in this case when the aggregate function returns
NULL after finding no rows):

SELECT SUM(score) FROM student;
+------------+
| SUM(score) |
+------------+
|       NULL |
+------------+

SELECT COALESCE(SUM(score),0) FROM student;
+------------------------+
| COALESCE(SUM(score),0) |
+------------------------+
|                      0 |
+------------------------+

URL: https://mariadb.com/kb/en/coalesce/https://mariadb.com/kb/en/coalesce/�U@

��
t$(FROM_UNIXTIME	�$LOCALTIMESyntax
------

LOCALTIME
LOCALTIME([precision])

Description
-----------

LOCALTIME and LOCALTIME() are synonyms for NOW().

URL: https://mariadb.com/kb/en/localtime/https://mariadb.com/kb/en/localtime/�)LOCALTIMESTAMPSyntax
------

LOCALTIMESTAMP
LOCALTIMESTAMP([precision])

Description
-----------

LOCALTIMESTAMP and LOCALTIMESTAMP() are synonyms for NOW().

URL: https://mariadb.com/kb/en/localtimestamp/https://mariadb.com/kb/en/localtimestamp/	!MINUTESyntax
------

MINUTE(time)

Description
-----------

Returns the minute for time, in the range 0 to 59.

Examples
--------

SELECT MINUTE('2013-08-03 11:04:03');
+-------------------------------+
| MINUTE('2013-08-03 11:04:03') |
+-------------------------------+
|                             4 |
+-------------------------------+

SELECT MINUTE ('23:12:50');
+---------------------+
| MINUTE ('23:12:50') |
+---------------------+
|                  12 |
+---------------------+

URL: https://mariadb.com/kb/en/minute/https://mariadb.com/kb/en/minute/2 MONTHSyntax
------

MONTH(date)

Description
-----------

Returns the month for date in the range 1 to 12 for January to December, or 0
for dates such as '0000-00-00' or '2008-00-00' that have a zero month part.

Examples
--------

SELECT MONTH('2019-01-03');
+---------------------+
| MONTH('2019-01-03') |
+---------------------+
|                   1 |
+---------------------+

SELECT MONTH('2019-00-03');
+---------------------+
| MONTH('2019-00-03') |
+---------------------+
|                   0 |
+---------------------+

URL: https://mariadb.com/kb/en/month/https://mariadb.com/kb/en/month/e�>����1��v\j�k@�Syntax
------

FROM_UNIXTIME(unix_timestamp), FROM_UNIXTIME(unix_timestamp,format)

Description
-----------

Returns a representation of the unix_timestamp argument as a value in
'YYYY-MM-DD HH:MM:SS' or YYYYMMDDHHMMSS.uuuuuu format, depending on whether
the function is used in a string or numeric context. The value is expressed in
the current time zone. unix_timestamp is an internal timestamp value such as
is produced by the UNIX_TIMESTAMP() function.

If format is given, the result is formatted according to the format string,
which is used the same way as listed in the entry for the DATE_FORMAT()
function.

Timestamps in MariaDB have a maximum value of 2147483647, equivalent to
2038-01-19 05:14:07. This is due to the underlying 32-bit limitation. Using
the function on a timestamp beyond this will result in NULL being returned.
Use DATETIME as a storage type if you require dates beyond this.

The options that can be used by FROM_UNIXTIME(), as well as DATE_FORMAT() and
STR_TO_DATE(), are:

+---------------------------+------------------------------------------------+
| Option                    | Description                                    |
+---------------------------+------------------------------------------------+
| %a                        | Short weekday name in current locale           |
|                           | (Variable lc_time_names).                      |
+---------------------------+------------------------------------------------+
| %b                        | Short form month name in current locale. For   |
|                           | locale en_US this is one of:                   |
|                           | Jan,Feb,Mar,Apr,May,Jun,Jul,Aug,Sep,Oct,Nov    |
|                           | or Dec.                                        |
+---------------------------+------------------------------------------------+
| %c                        | Month with 1 or 2 digits.                      |
+---------------------------+------------------------------------------------+
| %D                        | Day with English suffix 'th', 'nd', 'st' or    |
|                           | 'rd''. (1st, 2nd, 3rd...).                     |
+---------------------------+------------------------------------------------+
| %d                        | Day with 2 digits.                             |
+---------------------------+------------------------------------------------+
| %e                        | Day with 1 or 2 digits.                        |
+---------------------------+------------------------------------------------+
| %f                        | Microseconds 6 digits.                         |
+---------------------------+------------------------------------------------+
| %H                        | Hour with 2 digits between 00-23.              |
+---------------------------+------------------------------------------------+
| %h                        | Hour with 2 digits between 01-12.              |
+---------------------------+------------------------------------------------+
| %I                        | Hour with 2 digits between 01-12.              |
+---------------------------+------------------------------------------------+
| %i                        | Minute with 2 digits.                          |
+---------------------------+------------------------------------------------+
| %j                        | Day of the year (001-366)                      |
+---------------------------+------------------------------------------------+
| %k                        | Hour with 1 digits between 0-23.               |
+---------------------------+------------------------------------------------+
| %l                        | Hour with 1 digits between 1-12.               |
+---------------------------+------------------------------------------------+
| %M                        | Full month name in current locale (Variable    |
|                           | lc_time_names).                                |
+---------------------------+------------------------------------------------+
| %m                        | Month with 2 digits.                           |
+---------------------------+------------------------------------------------+
| %p                        | AM/PM according to current locale (Variable    |
|                           | lc_time_names).                                |
+---------------------------+------------------------------------------------+
| %r                        | Time in 12 hour format, followed by AM/PM.     |
|                           | Short for '%I:%i:%S %p'.                       |
+---------------------------+------------------------------------------------+
| %S                        | Seconds with 2 digits.                         |
+---------------------------+------------------------------------------------+
| %s                        | Seconds with 2 digits.                         |
+---------------------------+------------------------------------------------+
| %T                        | Time in 24 hour format. Short for '%H:%i:%S'.  |
+---------------------------+------------------------------------------------+
| %U                        | Week number (00-53), when first day of the     |
|                           | week is Sunday.                                |
+---------------------------+------------------------------------------------+
| %u                        | Week number (00-53), when first day of the     |
|                           | week is Monday.                                |
+---------------------------+------------------------------------------------+
| %V                        | Week number (01-53), when first day of the     |
|                           | week is Sunday. Used with %X.                  |
+---------------------------+------------------------------------------------+
| %v                        | Week number (01-53), when first day of the     |
|                           | week is Monday. Used with %x.                  |
+---------------------------+------------------------------------------------+
| %W                        | Full weekday name in current locale (Variable  |
|                           | lc_time_names).                                |
+---------------------------+------------------------------------------------+
| %w                        | Day of the week. 0 = Sunday, 6 = Saturday.     |
+---------------------------+------------------------------------------------+
| %X                        | Year with 4 digits when first day of the week  |
|                           | is Sunday. Used with %V.                       |
+---------------------------+------------------------------------------------+
| %x                        | Year with 4 digits when first day of the week  |
|                           | is Sunday. Used with %v.                       |
+---------------------------+------------------------------------------------+
| %Y                        | Year with 4 digits.                            |
+---------------------------+------------------------------------------------+
| %y                        | Year with 2 digits.                            |
+---------------------------+------------------------------------------------+
| %#                        | For str_to_date(), skip all numbers.           |
+---------------------------+------------------------------------------------+
| %.                        | For str_to_date(), skip all punctation         |
|                           | characters.                                    |
+---------------------------+------------------------------------------------+
| %@                        | For str_to_date(), skip all alpha characters.  |
+---------------------------+------------------------------------------------+
| %%                        | A literal % character.                         |
+---------------------------+------------------------------------------------+

Performance Considerations
--------------------------

If your session time zone is set to SYSTEM (the default), FROM_UNIXTIME() will
call the���	�_��INSyntax
------

expr IN (value,...)

Description
-----------

Returns 1 if expr is equal to any of the values in the IN list, else returns
0. If all values are constants, they are evaluated according to the type of
expr and sorted. The search for the item then is done using a binary search.
This means IN is very quick if the IN value list consists entirely of
constants. Otherwise, type conversion takes place according to the rules
described at Type Conversion, but applied to all the arguments.

If expr is NULL, IN always returns NULL. If at least one of the values in the
list is NULL, and one of the comparisons is true, the result is 1. If at least
one of the values in the list is NULL and none of the comparisons is true, the
result is NULL.

Examples
--------

SELECT 2 IN (0,3,5,7);
+----------------+
| 2 IN (0,3,5,7) |
+----------------+
|              0 |
+----------------+

SELECT 'wefwf' IN ('wee','wefwf','weg');
+----------------------------------+
| 'wefwf' IN ('wee','wefwf','weg') |
+----------------------------------+
|                                1 |
+----------------------------------+

Type conversion:

SELECT 1 IN ('1', '2', '3');
+----------------------+
| 1 IN ('1', '2', '3') |
+----------------------+
|                    1 |
+----------------------+

SELECT NULL IN (1, 2, 3);
+-------------------+
| NULL IN (1, 2, 3) |
+-------------------+
|              NULL |
+-------------------+

SELECT 1 IN (1, 2, NULL);
+-------------------+
| 1 IN (1, 2, NULL) |
+-------------------+
|                 1 |
+-------------------+

SELECT 5 IN (1, 2, NULL);
+-------------------+
| 5 IN (1, 2, NULL) |
+-------------------+
|              NULL |
+-------------------+

URL: https://mariadb.com/kb/en/in/https://mariadb.com/kb/en/in/�
#INTERVALSyntax
------

INTERVAL(N,N1,N2,N3,...)

Description
-----------

Returns the index of the last argument that is less than the first argument or
is NULL.

Returns 0 if N < N1, 1 if N < N2, 2 if N < N3 and so on or -1 if N is NULL.
All arguments are treated as integers. It is required that N1 < N2 < N3 < ...
< Nn for this function to work correctly. This is because a fast binary search
is used.

Examples
--------

SELECT INTERVAL(23, 1, 15, 17, 30, 44, 200);
+--------------------------------------+
| INTERVAL(23, 1, 15, 17, 30, 44, 200) |
+--------------------------------------+
|                                    3 |
+--------------------------------------+

SELECT INTERVAL(10, 1, 10, 100, 1000);
+--------------------------------+
| INTERVAL(10, 1, 10, 100, 1000) |
+--------------------------------+
|                              2 |
+--------------------------------+

SELECT INTERVAL(22, 23, 30, 44, 200);
+-------------------------------+
| INTERVAL(22, 23, 30, 44, 200) |
+-------------------------------+
|                             0 |
+-------------------------------+

SELECT INTERVAL(10, 2, NULL);
+-----------------------+
| INTERVAL(10, 2, NULL) |
+-----------------------+
|                     2 |
+-----------------------+

URL: https://mariadb.com/kb/en/interval/https://mariadb.com/kb/en/interval/�{ISSyntax
------

IS boolean_value

Description
-----------

Tests a value against a boolean value, where boolean_value can be TRUE, FALSE,
or UNKNOWN.

There is an important difference between using IS TRUE or comparing a value
with TRUE using =. When using =, only 1 equals to TRUE. But when using IS
TRUE, all values which are logically true (like a number > 1) return TRUE.

Examples
--------

SELECT 1 IS TRUE, 0 IS FALSE, NULL IS UNKNOWN;
+-----------+------------+-----------------+
| 1 IS TRUE | 0 IS FALSE | NULL IS UNKNOWN |
+-----------+------------+-----------------+
|         1 |          1 |               1 |
+-----------+------------+-----------------+

Difference between = and IS TRUE:

SELECT 2 = TRUE, 2 IS TRUE;
+----------+-----------+
| 2 = TRUE | 2 IS TRUE |
+----------+-----------+
|        0 |         1 |
+----------+-----------+

URL: https://mariadb.com/kb/en/is/https://mariadb.com/kb/en/is/�D!IS NOTSyntax
------

IS NOT boolean_value

Description
-----------

Tests a value against a boolean value, where boolean_value can be TRUE, FALSE,
or UNKNOWN.

Examples
--------

SELECT 1 IS NOT UNKNOWN, 0 IS NOT UNKNOWN, NULL IS NOT UNKNOWN;
+------------------+------------------+---------------------+
| 1 IS NOT UNKNOWN | 0 IS NOT UNKNOWN | NULL IS NOT UNKNOWN |
+------------------+------------------+---------------------+
|                1 |                1 |                   0 |
+------------------+------------------+---------------------+

SELECT NULL IS NOT TRUE, NULL IS NOT FALSE;
+------------------+-------------------+
| NULL IS NOT TRUE | NULL IS NOT FALSE |
+------------------+-------------------+
|                1 |                 1 |
+------------------+-------------------+

URL: https://mariadb.com/kb/en/is-not/https://mariadb.com/kb/en/is-not/ 	�$MONTHNAMESyntax
------

MONTHNAME(date)

Description
-----------

Returns the full name of the month for date. The language used for the name is
controlled by the value of the lc_time_names system variable. See server
locale for more on the supported locales.

Examples
--------

SELECT MONTHNAME('2019-02-03');
+-------------------------+
| MONTHNAME('2019-02-03') |
+-------------------------+
| February                |
+-------------------------+

Changing the locale:

SET lc_time_names = 'fr_CA';

SELECT MONTHNAME('2019-05-21');
+-------------------------+
| MONTHNAME('2019-05-21') |
+-------------------------+
| mai                     |
+-------------------------+

URL: https://mariadb.com/kb/en/monthname/https://mariadb.com/kb/en/monthname/$r"QUARTERSyntax
------

QUARTER(date)

Description
-----------

Returns the quarter of the year for date, in the range 1 to 4. Returns 0 if
month contains a zero value, or NULL if the given value is not otherwise a
valid date (zero values are accepted).

Examples
--------

SELECT QUARTER('2008-04-01');
+-----------------------+
| QUARTER('2008-04-01') |
+-----------------------+
|                     2 |
+-----------------------+

SELECT QUARTER('2019-00-01');
+-----------------------+
| QUARTER('2019-00-01') |
+-----------------------+
|                     0 |
+-----------------------+

URL: https://mariadb.com/kb/en/quarter/https://mariadb.com/kb/en/quarter/%=!SECONDSyntax
------

SECOND(time)

Description
-----------

Returns the second for a given time (which can include microseconds), in the
range 0 to 59, or NULL if not given a valid time value.

Examples
--------

SELECT SECOND('10:05:03');
+--------------------+
| SECOND('10:05:03') |
+--------------------+
|                  3 |
+--------------------+

SELECT SECOND('10:05:01.999999');
+---------------------------+
| SECOND('10:05:01.999999') |
+---------------------------+
|                         1 |
+---------------------------+

URL: https://mariadb.com/kb/en/second/https://mariadb.com/kb/en/second/�W@
��'�%&STR_TO_DATE+
�(TIME FunctionSyntax
------

TIME(expr)

Description
-----------

Extracts the time part of the time or datetime expression expr and returns it
as a string.

Examples
--------

SELECT TIME('2003-12-31 01:02:03');
+-----------------------------+
| TIME('2003-12-31 01:02:03') |
+-----------------------------+
| 01:02:03                    |
+-----------------------------+

SELECT TIME('2003-12-31 01:02:03.000123');
+------------------------------------+
| TIME('2003-12-31 01:02:03.000123') |
+------------------------------------+
| 01:02:03.000123                    |
+------------------------------------+

URL: https://mariadb.com/kb/en/time-function/https://mariadb.com/kb/en/time-function/���/rh�g�yF�F�
�q�Syntax
------

STR_TO_DATE(str,format)

Description
-----------

This is the inverse of the DATE_FORMAT() function. It takes a string str and a
format string format. STR_TO_DATE() returns a DATETIME value if the format
string contains both date and time parts, or a DATE or TIME value if the
string contains only date or time parts.

The date, time, or datetime values contained in str should be given in the
format indicated by format. If str contains an illegal date, time, or datetime
value, STR_TO_DATE() returns NULL. An illegal value also produces a warning.

Under specific SQL_MODE settings an error may also be generated if the str
isn't a valid date:

* ALLOW_INVALID_DATES
* NO_ZERO_DATE
* NO_ZERO_IN_DATE

The options that can be used by STR_TO_DATE(), as well as its inverse
DATE_FORMAT() and the FROM_UNIXTIME() function, are:

+---------------------------+------------------------------------------------+
| Option                    | Description                                    |
+---------------------------+------------------------------------------------+
| %a                        | Short weekday name in current locale           |
|                           | (Variable lc_time_names).                      |
+---------------------------+------------------------------------------------+
| %b                        | Short form month name in current locale. For   |
|                           | locale en_US this is one of:                   |
|                           | Jan,Feb,Mar,Apr,May,Jun,Jul,Aug,Sep,Oct,Nov    |
|                           | or Dec.                                        |
+---------------------------+------------------------------------------------+
| %c                        | Month with 1 or 2 digits.                      |
+---------------------------+------------------------------------------------+
| %D                        | Day with English suffix 'th', 'nd', 'st' or    |
|                           | 'rd''. (1st, 2nd, 3rd...).                     |
+---------------------------+------------------------------------------------+
| %d                        | Day with 2 digits.                             |
+---------------------------+------------------------------------------------+
| %e                        | Day with 1 or 2 digits.                        |
+---------------------------+------------------------------------------------+
| %f                        | Microseconds 6 digits.                         |
+---------------------------+------------------------------------------------+
| %H                        | Hour with 2 digits between 00-23.              |
+---------------------------+------------------------------------------------+
| %h                        | Hour with 2 digits between 01-12.              |
+---------------------------+------------------------------------------------+
| %I                        | Hour with 2 digits between 01-12.              |
+---------------------------+------------------------------------------------+
| %i                        | Minute with 2 digits.                          |
+---------------------------+------------------------------------------------+
| %j                        | Day of the year (001-366)                      |
+---------------------------+------------------------------------------------+
| %k                        | Hour with 1 digits between 0-23.               |
+---------------------------+------------------------------------------------+
| %l                        | Hour with 1 digits between 1-12.               |
+---------------------------+------------------------------------------------+
| %M                        | Full month name in current locale (Variable    |
|                           | lc_time_names).                                |
+---------------------------+------------------------------------------------+
| %m                        | Month with 2 digits.                           |
+---------------------------+------------------------------------------------+
| %p                        | AM/PM according to current locale (Variable    |
|                           | lc_time_names).                                |
+---------------------------+------------------------------------------------+
| %r                        | Time in 12 hour format, followed by AM/PM.     |
|                           | Short for '%I:%i:%S %p'.                       |
+---------------------------+------------------------------------------------+
| %S                        | Seconds with 2 digits.                         |
+---------------------------+------------------------------------------------+
| %s                        | Seconds with 2 digits.                         |
+---------------------------+------------------------------------------------+
| %T                        | Time in 24 hour format. Short for '%H:%i:%S'.  |
+---------------------------+------------------------------------------------+
| %U                        | Week number (00-53), when first day of the     |
|                           | week is Sunday.                                |
+---------------------------+------------------------------------------------+
| %u                        | Week number (00-53), when first day of the     |
|                           | week is Monday.                                |
+---------------------------+------------------------------------------------+
| %V                        | Week number (01-53), when first day of the     |
|                           | week is Sunday. Used with %X.                  |
+---------------------------+------------------------------------------------+
| %v                        | Week number (01-53), when first day of the     |
|                           | week is Monday. Used with %x.                  |
+---------------------------+------------------------------------------------+
| %W                        | Full weekday name in current locale (Variable  |
|                           | lc_time_names).                                |
+---------------------------+------------------------------------------------+
| %w                        | Day of the week. 0 = Sunday, 6 = Saturday.     |
+---------------------------+------------------------------------------------+
| %X                        | Year with 4 digits when first day of the week  |
|                           | is Sunday. Used with %V.                       |
+---------------------------+------------------------------------------------+
| %x                        | Year with 4 digits when first day of the week  |
|                           | is Monday. Used with %v.                       |
+---------------------------+------------------------------------------------+
| %Y                        | Year with 4 digits.                            |
+---------------------------+------------------------------------------------+
| %y                        | Year with 2 digits.                            |
+---------------------------+------------------------------------------------+
| %#                        | For str_to_date(), skip all numbers.           |
+---------------------------+------------------------------------------------+
| %.                        | For str_to_date(), skip all punctation         |
|                           | characters.                                    |
+---------------------------+------------------------------------------------+
| %@                        | For str_to_date(), skip all alpha characters.  |
+---------------------------+------------------------------------------------+
| %%                        | A literal % character.                         |
+---------------------------+------------------------------------------------+

Examples
--------

SELECT STR_TO_DATE('Wednesday, June 2, 2014', '%W, %M %e, %Y');
+---------------------------------------------------------+
| STR_TO_DATE('Wednesday, June 2, 2014', '%W, %M %e, %Y') |
+---------------------------------------------------------+
| 2014-06-02                               o�mW����"IS NULLSyntax
------

IS NULL

Description
-----------

Tests whether a value is NULL. See also NULL Values in MariaDB.

Examples
--------

SELECT 1 IS NULL, 0 IS NULL, NULL IS NULL;
+-----------+-----------+--------------+
| 1 IS NULL | 0 IS NULL | NULL IS NULL |
+-----------+-----------+--------------+
|         0 |         0 |            1 |
+-----------+-----------+--------------+

Compatibility
-------------

Some ODBC applications use the syntax auto_increment_field IS NOT NULL to find
the latest row that was inserted with an autogenerated key value. If your
applications need this, you can set the sql_auto_is_null variable to 1.

SET @@sql_auto_is_null=1;
CREATE TABLE t1 (auto_increment_column INT NOT NULL AUTO_INCREMENT PRIMARY
KEY);
INSERT INTO t1 VALUES (NULL);
SELECT * FROM t1 WHERE auto_increment_column IS NULL;

+-----------------------+
| auto_increment_column |
+-----------------------+
|                     1 |
+-----------------------+

URL: https://mariadb.com/kb/en/is-null/https://mariadb.com/kb/en/is-null/�l LEASTSyntax
------

LEAST(value1,value2,...)

Description
-----------

With two or more arguments, returns the smallest (minimum-valued) argument.
The arguments are compared using the following rules:

* If the return value is used in an INTEGER context or all arguments are
integer-valued, they are compared as integers.
* If the return value is used in a REAL context or all arguments are
real-valued, they are compared as reals.
* If any argument is a case-sensitive string, the arguments are compared as
case-sensitive strings.
* In all other cases, the arguments are compared as case-insensitive strings.

LEAST() returns NULL if any argument is NULL.

Examples
--------

SELECT LEAST(2,0);
+------------+
| LEAST(2,0) |
+------------+
|          0 |
+------------+

SELECT LEAST(34.0,3.0,5.0,767.0);
+---------------------------+
| LEAST(34.0,3.0,5.0,767.0) |
+---------------------------+
|                       3.0 |
+---------------------------+

SELECT LEAST('B','A','C');
+--------------------+
| LEAST('B','A','C') |
+--------------------+
| A                  |
+--------------------+

URL: https://mariadb.com/kb/en/least/https://mariadb.com/kb/en/least/�[&NOT BETWEENSyntax
------

expr NOT BETWEEN min AND max

Description
-----------

This is the same as NOT (expr BETWEEN min AND max).

Note that the meaning of the alternative form NOT expr BETWEEN min AND max is
affected by the HIGH_NOT_PRECEDENCE SQL_MODE flag.

Examples
--------

SELECT 1 NOT BETWEEN 2 AND 3;
+-----------------------+
| 1 NOT BETWEEN 2 AND 3 |
+-----------------------+
|                     1 |
+-----------------------+

SELECT 'b' NOT BETWEEN 'a' AND 'c';
+-----------------------------+
| 'b' NOT BETWEEN 'a' AND 'c' |
+-----------------------------+
|                           0 |
+-----------------------------+

NULL:

SELECT 1 NOT BETWEEN 1 AND NULL;
+--------------------------+
| 1 NOT BETWEEN 1 AND NULL |
+--------------------------+
|                     NULL |
+--------------------------+

URL: https://mariadb.com/kb/en/not-between/https://mariadb.com/kb/en/not-between/��!NOT INSyntax
------

expr NOT IN (value,...)

Description
-----------

This is the same as NOT (expr IN (value,...)).

Examples
--------

SELECT 2 NOT IN (0,3,5,7);
+--------------------+
| 2 NOT IN (0,3,5,7) |
+--------------------+
|                  1 |
+--------------------+

SELECT 'wefwf' NOT IN ('wee','wefwf','weg');
+--------------------------------------+
| 'wefwf' NOT IN ('wee','wefwf','weg') |
+--------------------------------------+
|                                    0 |
+--------------------------------------+

SELECT 1 NOT IN ('1', '2', '3');
+--------------------------+
| 1 NOT IN ('1', '2', '3') |
+--------------------------+
|                        0 |
+--------------------------+

NULL:

SELECT NULL NOT IN (1, 2, 3);
+-----------------------+
| NULL NOT IN (1, 2, 3) |
+-----------------------+
|                  NULL |
+-----------------------+

SELECT 1 NOT IN (1, 2, NULL);
+-----------------------+
| 1 NOT IN (1, 2, NULL) |
+-----------------------+
|                     0 |
+-----------------------+

SELECT 5 NOT IN (1, 2, NULL);
+-----------------------+
| 5 NOT IN (1, 2, NULL) |
+-----------------------+
|                  NULL |
+-----------------------+

URL: https://mariadb.com/kb/en/not-in/https://mariadb.com/kb/en/not-in/�%	&ParenthesesParentheses are sometimes called precedence operators - this means that they
can be used to change the other operator's precedence in an expression. The
expressions that are written between parentheses are computed before the
expressions that are written outside. Parentheses must always contain an
expression (that is, they cannot be empty), and can be nested.

For example, the following expressions could return different results:

* NOT a OR b
* NOT (a OR b)

In the first case, NOT applies to a, so if a is FALSE or b is TRUE, the
expression returns TRUE. In the second case, NOT applies to the result of a OR
b, so if at least one of a or b is TRUE, the expression is TRUE.

When the precedence of operators is not intuitive, you can use parentheses to
make it immediately clear for whoever reads the statement.

The precedence of the NOT operator can also be affected by the
HIGH_NOT_PRECEDENCE SQL_MODE flag.

Other uses
----------

Parentheses must always be used to enclose subqueries.

Parentheses can also be used in a JOIN statement between multiple tables to
determine which tables must be joined first.

Also, parentheses are used to enclose the list of parameters to be passed to
built-in functions, user-defined functions and stored routines. However, when
no parameter is passed to a stored procedure, parentheses are optional. For
builtin functions and user-defined functions, spaces are not allowed between
the function name and the open parenthesis, unless the IGNORE_SPACE SQL_MODE
is set. For stored routines (and for functions if IGNORE_SPACE is set) spaces
are allowed before the open parenthesis, including tab characters and new line
characters.

Syntax errors
-------------

If there are more open parentheses than closed parentheses, the error usually
looks like this:

ERROR 1064 (42000): You have an error in your SQL syntax; check the manual that
corresponds to your MariaDB server version for the right syntax to use near ''
a
t line 1

Note the empty string.

If there are more closed parentheses than open parentheses, the error usually
looks like this:

ERROR 1064 (42000): You have an error in your SQL syntax; check the manual that
corresponds to your MariaDB server version for the right syntax to use near ')'
at line 1

Note the quoted closed parenthesis.

URL: https://mariadb.com/kb/en/parentheses/https://mariadb.com/kb/en/parentheses/0T&TIME_FORMATSyntax
------

TIME_FORMAT(time,format)

Description
-----------

This is used like the DATE_FORMAT() function, but the format string may
contain format specifiers only for hours, minutes, and seconds. Other
specifiers produce a NULL value or 0.

Examples
--------

SELECT TIME_FORMAT('100:00:00', '%H %k %h %I %l');
+--------------------------------------------+
| TIME_FORMAT('100:00:00', '%H %k %h %I %l') |
+--------------------------------------------+
| 100 100 04 04 4                            |
+--------------------------------------------+

URL: https://mariadb.com/kb/en/time_format/https://mariadb.com/kb/en/time_format/��id	c��*��\���
�
(ANALYZE TABLESyntax
------

ANALYZE [NO_WRITE_TO_BINLOG | LOCAL] TABLE tbl_name [,tbl_name ...]
 [PERSISTENT FOR
  { ALL
   | COLUMNS ([col_name [,col_name ...]]) INDEXES ([index_name [,index_name
...]])
  }
 ]

Description
-----------

ANALYZE TABLE analyzes and stores the key distribution for a table (index
statistics). This statement works with MyISAM, Aria and InnoDB tables. During
the analysis, InnoDB will allow reads/writes, and MyISAM/Aria reads/inserts.
For MyISAM tables, this statement is equivalent to using myisamchk --analyze.

For more information on how the analysis works within InnoDB, see InnoDB
Limitations.

MariaDB uses the stored key distribution to decide the order in which tables
should be joined when you perform a join on something other than a constant.
In addition, key distributions can be used when deciding which indexes to use
for a specific table within a query.

This statement requires SELECT and INSERT privileges for the table.

By default, ANALYZE TABLE statements are written to the binary log and will be
replicated. The NO_WRITE_TO_BINLOG keyword (LOCAL is an alias) will ensure the
statement is not written to the binary log.

From MariaDB 10.3.19, ANALYZE TABLE statements are not logged to the binary
log if read_only is set. See also Read-Only Replicas.

ANALYZE TABLE is also supported for partitioned tables. You can use ALTER
TABLE ... ANALYZE PARTITION to analyze one or more partitions.

The Aria storage engine supports progress reporting for the ANALYZE TABLE
statement.

Engine-Independent Statistics
-----------------------------

ANALYZE TABLE supports engine-independent statistics. See Engine-Independent
Table Statistics: Collecting Statistics with the ANALYZE TABLE Statement for
more information.

Useful Variables
----------------

For calculating the number of duplicates, ANALYZE TABLE uses a buffer of
sort_buffer_size bytes per column. You can slightly increase the speed of
ANALYZE TABLE by increasing this variable.

Examples
--------

-- update all engine-independent statistics for all columns and indexes
ANALYZE TABLE tbl PERSISTENT FOR ALL;

-- update specific columns and indexes:
ANALYZE TABLE tbl PERSISTENT FOR COLUMNS (col1,col2,...) INDEXES
(idx1,idx2,...);

-- empty lists are allowed:
ANALYZE TABLE tbl PERSISTENT FOR COLUMNS (col1,col2,...) INDEXES ();
ANALYZE TABLE tbl PERSISTENT FOR COLUMNS () INDEXES (idx1,idx2,...);

-- the following will only update mysql.table_stats fields:
ANALYZE TABLE tbl PERSISTENT FOR COLUMNS () INDEXES ();

-- when use_stat_tables is set to 'COMPLEMENTARY' or 'PREFERABLY', 
-- a simple ANALYZE TABLE  collects engine-independent statistics for all
columns and indexes.
SET SESSION use_stat_tables='COMPLEMENTARY';
ANALYZE TABLE tbl;

URL: https://mariadb.com/kb/en/analyze-table/https://mariadb.com/kb/en/analyze-table/��	)CHECKSUM TABLESyntax
------

CHECKSUM TABLE tbl_name [, tbl_name] ... [ QUICK | EXTENDED ]

Description
-----------

CHECKSUM TABLE reports a table checksum. This is very useful if you want to
know if two tables are the same (for example on a master and slave).

With QUICK, the live table checksum is reported if it is available, or NULL
otherwise. This is very fast. A live checksum is enabled by specifying the
CHECKSUM=1 table option when you create the table; currently, this is
supported only for Aria and MyISAM tables.

With EXTENDED, the entire table is read row by row and the checksum is
calculated. This can be very slow for large tables.

If neither QUICK nor EXTENDED is specified, MariaDB returns a live checksum if
the table storage engine supports it and scans the table otherwise.

CHECKSUM TABLE requires the SELECT privilege for the table.

For a nonexistent table, CHECKSUM TABLE returns NULL and generates a warning.

The table row format affects the checksum value. If the row format changes,
the checksum will change. This means that when a table created with a
MariaDB/MySQL version is upgraded to another version, the checksum value will
probably change.

Two identical tables should always match to the same checksum value; however,
also for non-identical tables there is a very slight chance that they will
return the same value as the hashing algorithm is not completely
collision-free.

Identical Tables
----------------

Identical tables mean that the CREATE statement is identical and that the
following variable, which affects the storage formats, was the same when the
tables were created:

* mysql56-temporal-format

Differences Between MariaDB and MySQL
-------------------------------------

CHECKSUM TABLE may give a different result as MariaDB doesn't ignore NULLs in
the columns as MySQL 5.1 does (Later MySQL versions should calculate checksums
the same way as MariaDB). You can get the 'old style' checksum in MariaDB by
starting mysqld with the --old option. Note however that that the MyISAM and
Aria storage engines in MariaDB are using the new checksum internally, so if
you are using --old, the CHECKSUM command will be slower as it needs to
calculate the checksum row by row. Starting from MariaDB Server 10.9, --old is
deprecated and will be removed in a future release. Set --old-mode or OLD_MODE
to COMPAT_5_1_CHECKSUM to get 'old style' checksum.

URL: https://mariadb.com/kb/en/checksum-table/https://mariadb.com/kb/en/checksum-table/5�#UTC_DATESyntax
------

UTC_DATE, UTC_DATE()

Description
-----------

Returns the current UTC date as a value in 'YYYY-MM-DD' or YYYYMMDD format,
depending on whether the function is used in a string or numeric context.

Examples
--------

SELECT UTC_DATE(), UTC_DATE() + 0;
+------------+----------------+
| UTC_DATE() | UTC_DATE() + 0 |
+------------+----------------+
| 2010-03-27 |       20100327 |
+------------+----------------+

URL: https://mariadb.com/kb/en/utc_date/https://mariadb.com/kb/en/utc_date/6�#UTC_TIMESyntax
------

UTC_TIME
UTC_TIME([precision])

Description
-----------

Returns the current UTC time as a value in 'HH:MM:SS' or HHMMSS.uuuuuu format,
depending on whether the function is used in a string or numeric context.

The optional precision determines the microsecond precision. See Microseconds
in MariaDB.

Examples
--------

SELECT UTC_TIME(), UTC_TIME() + 0;
+------------+----------------+
| UTC_TIME() | UTC_TIME() + 0 |
+------------+----------------+
| 17:32:34   |  173234.000000 |
+------------+----------------+

With precision:

SELECT UTC_TIME(5);
+----------------+
| UTC_TIME(5)    |
+----------------+
| 07:52:50.78369 |
+----------------+

URL: https://mariadb.com/kb/en/utc_time/https://mariadb.com/kb/en/utc_time/>J' AsBinaryA synonym for ST_AsBinary().

URL: https://mariadb.com/kb/en/wkb-asbinary/https://mariadb.com/kb/en/wkb-asbinary/?C  AsWKBA synonym for ST_AsBinary().

URL: https://mariadb.com/kb/en/aswkb/https://mariadb.com/kb/en/aswkb/@�' MLineFromWKBSyntax
------

MLineFromWKB(wkb[,srid])
MultiLineStringFromWKB(wkb[,srid])

Description
-----------

Constructs a MULTILINESTRING value using its WKB representation and SRID.

MLineFromWKB() and MultiLineStringFromWKB() are synonyms.

Examples
--------

SET @g = ST_AsBinary(MLineFromText('MULTILINESTRING((10 48,10 21,10 0),(16
0,16 23,16 48))'));

SELECT ST_AsText(MLineFromWKB(@g));
+--------------------------------------------------------+
| ST_AsText(MLineFromWKB(@g))                            |
+--------------------------------------------------------+
| MULTILINESTRING((10 48,10 21,10 0),(16 0,16 23,16 48)) |
+--------------------------------------------------------+

URL: https://mariadb.com/kb/en/mlinefromwkb/https://mariadb.com/kb/en/mlinefromwkb/��v����
1�	%������&CHECK TABLESyntax
------

CHECK TABLE tbl_name [, tbl_name] ... [option] ...

option = {FOR UPGRADE | QUICK | FAST | MEDIUM | EXTENDED | CHANGED}

Description
-----------

CHECK TABLE checks a table or tables for errors. CHECK TABLE works for
Archive, Aria, CSV, InnoDB and MyISAM tables. For Aria and MyISAM tables, the
key statistics are updated as well. For CSV, see also Checking and Repairing
CSV Tables.

As an alternative, myisamchk is a commandline tool for checking MyISAM tables
when the tables are not being accessed. For Aria tables, there is a similar
tool: aria_chk.

For checking dynamic columns integrity, COLUMN_CHECK() can be used.

CHECK TABLE can also check views for problems, such as tables that are
referenced in the view definition that no longer exist.

CHECK TABLE is also supported for partitioned tables. You can use ALTER TABLE
... CHECK PARTITION to check one or more partitions.

The meaning of the different options are as follows - note that this can vary
a bit between storage engines:

+-----+----------------------------------------------------------------------+
| FOR | Do a very quick check if the storage format for the table has        |
| UPG | changed so that one needs to do a REPAIR. This is only needed when   |
| ADE | one upgrades between major versions of MariaDB or MySQL. This is     |
|     | usually done by running mariadb-upgrade.                             |
+-----+----------------------------------------------------------------------+
| FAS | Only check tables that has not been closed properly or are marked    |
|     | as corrupt. Only supported by the MyISAM and Aria engines. For       |
|     | other engines the table is checked normally                          |
+-----+----------------------------------------------------------------------+
| CHA | Check only tables that has changed since last REPAIR / CHECK. Only   |
| GED | supported by the MyISAM and Aria engines. For other engines the      |
|     | table is checked normally.                                           |
+-----+----------------------------------------------------------------------+
| QUI | Do a fast check. For MyISAM and Aria, this means skipping the check  |
| K   | of the delete link chain, which may take some time.                  |
+-----+----------------------------------------------------------------------+
| MED | Scan also the data files. Checks integrity between data and index    |
| UM  | files with checksums. In most cases this should find all possible    |
|     | errors.                                                              |
+-----+----------------------------------------------------------------------+
| EXT | Does a full check to verify every possible error. For InnoDB, Aria,  |
| NDE | and MyISAM, verify for each row that all its keys exists, and for    |
|     | those index keys, they point back to the primary clustered key.      |
|     | This may take a long time on large tables. This option was           |
|     | previously ignored by InnoDB before MariaDB 10.6.11, MariaDB         |
|     | 10.7.7, MariaDB 10.8.6 and MariaDB 10.9.4.                           |
+-----+----------------------------------------------------------------------+

For most cases running CHECK TABLE without options or MEDIUM should be good
enough.

The Aria storage engine supports progress reporting for this statement.

If you want to know if two tables are identical, take a look at CHECKSUM TABLE.

InnoDB
------

If CHECK TABLE finds an error in an InnoDB table, MariaDB might shutdown to
prevent the error propagation. In this case, the problem will be reported in
the error log. Otherwise the table or an index might be marked as corrupted,
to prevent use. This does not happen with some minor problems, like a wrong
number of entries in a secondary index. Those problems are reported in the
output of CHECK TABLE.

Each tablespace contains a header with metadata. This header is not checked by
this statement.

During the execution of CHECK TABLE, other threads may be blocked.

URL: https://mariadb.com/kb/en/check-table/https://mariadb.com/kb/en/check-table/�b'REPAIR TABLESyntax
------

REPAIR [NO_WRITE_TO_BINLOG | LOCAL] TABLE
  tbl_name [, tbl_name] ...
  [QUICK] [EXTENDED] [USE_FRM]

Description
-----------

REPAIR TABLE repairs a possibly corrupted table. By default, it has the same
effect as

myisamchk --recover tbl_name

or

aria_chk --recover tbl_name

See aria_chk and myisamchk for more.

REPAIR TABLE works for Archive, Aria, CSV and MyISAM tables. For InnoDB, see
recovery modes. For CSV, see also Checking and Repairing CSV Tables. For
Archive, this statement also improves compression. If the storage engine does
not support this statement, a warning is issued.

This statement requires SELECT and INSERT privileges for the table.

By default, REPAIR TABLE statements are written to the binary log and will be
replicated. The NO_WRITE_TO_BINLOG keyword (LOCAL is an alias) will ensure the
statement is not written to the binary log.

From MariaDB 10.3.19, REPAIR TABLE statements are not logged to the binary log
if read_only is set. See also Read-Only Replicas.

When an index is recreated, the storage engine may use a configurable buffer
in the process. Incrementing the buffer speeds up the index creation. Aria and
MyISAM allocate a buffer whose size is defined by aria_sort_buffer_size or
myisam_sort_buffer_size, also used for ALTER TABLE.

REPAIR TABLE is also supported for partitioned tables. However, the USE_FRM
option cannot be used with this statement on a partitioned table.

ALTER TABLE ... REPAIR PARTITION can be used to repair one or more partitions.

The Aria storage engine supports progress reporting for this statement.

URL: https://mariadb.com/kb/en/repair-table/https://mariadb.com/kb/en/repair-table/A
�( MPointFromWKBSyntax
------

MPointFromWKB(wkb[,srid])
MultiPointFromWKB(wkb[,srid])

Description
-----------

Constructs a MULTIPOINT value using its WKB representation and SRID.

MPointFromWKB() and MultiPointFromWKB() are synonyms.

Examples
--------

SET @g = ST_AsBinary(MPointFromText('MultiPoint( 1 1, 2 2, 5 3, 7 2, 9 3, 8 4,
6 6, 6 9, 4 9, 1 5 )'));

SELECT ST_AsText(MPointFromWKB(@g));
+-----------------------------------------------------+
| ST_AsText(MPointFromWKB(@g))                        |
+-----------------------------------------------------+
| MULTIPOINT(1 1,2 2,5 3,7 2,9 3,8 4,6 6,6 9,4 9,1 5) |
+-----------------------------------------------------+

URL: https://mariadb.com/kb/en/mpointfromwkb/https://mariadb.com/kb/en/mpointfromwkb/B�' MPolyFromWKBSyntax
------

MPolyFromWKB(wkb[,srid])
MultiPolygonFromWKB(wkb[,srid])

Description
-----------

Constructs a MULTIPOLYGON value using its WKB representation and SRID.

MPolyFromWKB() and MultiPolygonFromWKB() are synonyms.

Examples
--------

SET @g = ST_AsBinary(MPointFromText('MULTIPOLYGON(((28 26,28 0,84 0,84 42,28
26),(52 18,66 23,73 9,48 6,52 18)),((59 18,67 18,67 13,59 13,59 18)))'));

SELECT ST_AsText(MPolyFromWKB(@g))\G
*************************** 1. row ***************************
ST_AsText(MPolyFromWKB(@g)): MULTIPOLYGON(((28 26,28 0,84 0,84 42,28 26),(52
18,66 23,73 9,48 6,52 18)),((59 18,67 18,67 13,59 13,59 18)))

URL: https://mariadb.com/kb/en/mpolyfromwkb/https://mariadb.com/kb/en/mpolyfromwkb/���D�8M�(��W�)OPTIMIZE TABLESyntax
------

OPTIMIZE [NO_WRITE_TO_BINLOG | LOCAL] TABLE
  tbl_name [, tbl_name] ...
  [WAIT n | NOWAIT]

Description
-----------

OPTIMIZE TABLE has two main functions. It can either be used to defragment
tables, or to update the InnoDB fulltext index.

WAIT/NOWAIT
-----------

Set the lock wait timeout. See WAIT and NOWAIT.

Defragmenting
-------------

OPTIMIZE TABLE works for InnoDB (before MariaDB 10.1.1, only if the
innodb_file_per_table server system variable is set), Aria, MyISAM and ARCHIVE
tables, and should be used if you have deleted a large part of a table or if
you have made many changes to a table with variable-length rows (tables that
have VARCHAR, VARBINARY, BLOB, or TEXT columns). Deleted rows are maintained
in a linked list and subsequent INSERT operations reuse old row positions.

This statement requires SELECT and INSERT privileges for the table.

By default, OPTIMIZE TABLE statements are written to the binary log and will
be replicated. The NO_WRITE_TO_BINLOG keyword (LOCAL is an alias) will ensure
the statement is not written to the binary log.

OPTIMIZE TABLE statements are not logged to the binary log if read_only is
set. See also Read-Only Replicas.

OPTIMIZE TABLE is also supported for partitioned tables. You can use ALTER
TABLE ... OPTIMIZE PARTITION to optimize one or more partitions.

You can use OPTIMIZE TABLE to reclaim the unused space and to defragment the
data file. With other storage engines, OPTIMIZE TABLE does nothing by default,
and returns this message: " The storage engine for the table doesn't support
optimize". However, if the server has been started with the --skip-new option,
OPTIMIZE TABLE is linked to ALTER TABLE, and recreates the table. This
operation frees the unused space and updates index statistics.

The Aria storage engine supports progress reporting for this statement.

If a MyISAM table is fragmented, concurrent inserts will not be performed
until an OPTIMIZE TABLE statement is executed on that table, unless the
concurrent_insert server system variable is set to ALWAYS.

Updating an InnoDB fulltext index
---------------------------------

When rows are added or deleted to an InnoDB fulltext index, the index is not
immediately re-organized, as this can be an expensive operation. Change
statistics are stored in a separate location . The fulltext index is only
fully re-organized when an OPTIMIZE TABLE statement is run.

By default, an OPTIMIZE TABLE will defragment a table. In order to use it to
update fulltext index statistics, the innodb_optimize_fulltext_only system
variable must be set to 1. This is intended to be a temporary setting, and
should be reset to 0 once the fulltext index has been re-organized.

Since fulltext re-organization can take a long time, the
innodb_ft_num_word_optimize variable limits the re-organization to a number of
words (2000 by default). You can run multiple OPTIMIZE statements to fully
re-organize the index.

Defragmenting InnoDB tablespaces
--------------------------------

MariaDB 10.1.1 merged the Facebook/Kakao defragmentation patch, allowing one
to use OPTIMIZE TABLE to defragment InnoDB tablespaces. For this functionality
to be enabled, the innodb_defragment system variable must be enabled. No new
tables are created and there is no need to copy data from old tables to new
tables. Instead, this feature loads n pages (determined by
innodb-defragment-n-pages) and tries to move records so that pages would be
full of records and then frees pages that are fully empty after the operation.
Note that tablespace files (including ibdata1) will not shrink as the result
of defragmentation, but one will get better memory utilization in the InnoDB
buffer pool as there are fewer data pages in use.

See Defragmenting InnoDB Tablespaces for more details.

URL: https://mariadb.com/kb/en/optimize-table/https://mariadb.com/kb/en/optimize-table/��&REPAIR VIEWSyntax
------

REPAIR [NO_WRITE_TO_BINLOG | LOCAL] VIEW  view_name[, view_name] ... [FROM
MYSQL]

Description
-----------

The REPAIR VIEW statement was introduced to assist with fixing MDEV-6916, an
issue introduced in MariaDB 5.2 where the view algorithms were swapped
compared to their MySQL on disk representation. It checks whether the view
algorithm is correct. It is run as part of mariadb-upgrade, and should not
normally be required in regular use.

By default it corrects the checksum and if necessary adds the mariadb-version
field. If the optional FROM MYSQL clause is used, and no mariadb-version field
is present, the MERGE and TEMPTABLE algorithms are toggled.

By default, REPAIR VIEW statements are written to the binary log and will be
replicated. The NO_WRITE_TO_BINLOG keyword (LOCAL is an alias) will ensure the
statement is not written to the binary log.

URL: https://mariadb.com/kb/en/repair-view/https://mariadb.com/kb/en/repair-view/CV. GeomCollFromWKBA synonym for ST_GeomCollFromWKB.

URL: https://mariadb.com/kb/en/wkb-geomcollfromwkb/https://mariadb.com/kb/en/wkb-geomcollfromwkb/D\4 GeometryCollectionFromWKBA synonym for ST_GeomCollFromWKB.

URL: https://mariadb.com/kb/en/geometrycollectionfromwkb/https://mariadb.com/kb/en/geometrycollectionfromwkb/EN* GeometryFromWKBA synonym for ST_GeomFromWKB.

URL: https://mariadb.com/kb/en/geometryfromwkb/https://mariadb.com/kb/en/geometryfromwkb/FN* GeomFromWKBA synonym for ST_GeomFromWKB.

URL: https://mariadb.com/kb/en/wkb-geomfromwkb/https://mariadb.com/kb/en/wkb-geomfromwkb/GN* LineFromWKBA synonym for ST_LineFromWKB.

URL: https://mariadb.com/kb/en/wkb-linefromwkb/https://mariadb.com/kb/en/wkb-linefromwkb/HP, LineStringFromWKBA synonym for ST_LineFromWKB.

URL: https://mariadb.com/kb/en/linestringfromwkb/https://mariadb.com/kb/en/linestringfromwkb/IU1 MultiLineStringFromWKBA synonym for MLineFromWKB().

URL: https://mariadb.com/kb/en/multilinestringfromwkb/https://mariadb.com/kb/en/multilinestringfromwkb/JO, MultiPointFromWKBA synonym for MPointFromWKB.

URL: https://mariadb.com/kb/en/multipointfromwkb/https://mariadb.com/kb/en/multipointfromwkb/KN. MultiPolygonFromWKBSynonym for MPolyFromWKB.

URL: https://mariadb.com/kb/en/multipolygonfromwkb/https://mariadb.com/kb/en/multipolygonfromwkb/LP+ PointFromWKBA synonym for ST_PointFromWKB.

URL: https://mariadb.com/kb/en/wkb-pointfromwkb/https://mariadb.com/kb/en/wkb-pointfromwkb/MN* PolyFromWKBA synonym for ST_PolyFromWKB.

URL: https://mariadb.com/kb/en/wkb-polyfromwkb/https://mariadb.com/kb/en/wkb-polyfromwkb/NM) PolygonFromWKBA synonym for ST_PolyFromWKB.

URL: https://mariadb.com/kb/en/polygonfromwkb/https://mariadb.com/kb/en/polygonfromwkb/O�& ST_AsBinarySyntax
------

ST_AsBinary(g)
AsBinary(g)
ST_AsWKB(g)
AsWKB(g)

Description
-----------

Converts a value in internal geometry format to its WKB representation and
returns the binary result.

ST_AsBinary(), AsBinary(), ST_AsWKB() and AsWKB() are synonyms,

Examples
--------

SET @poly = ST_GeomFromText('POLYGON((0 0,0 1,1 1,1 0,0 0))');
SELECT ST_AsBinary(@poly);

SELECT ST_AsText(ST_GeomFromWKB(ST_AsWKB(@poly)));
+--------------------------------------------+
| ST_AsText(ST_GeomFromWKB(ST_AsWKB(@poly))) |
+--------------------------------------------+
| POLYGON((0 0,0 1,1 1,1 0,0 0))             |
+--------------------------------------------+

URL: https://mariadb.com/kb/en/st_asbinary/https://mariadb.com/kb/en/st_asbinary/q���N��������=��������.�V�J�
o	����
*mysql.func TableThe mysql.func table stores information about user-defined functions (UDFs)
created with the CREATE FUNCTION UDF statement.

MariaDB starting with 10.4
--------------------------
In MariaDB 10.4 and later, this table uses the Aria storage engine.

MariaDB until 10.3
------------------
In MariaDB 10.3 and before, this table uses the MyISAM storage engine.

The mysql.func table contains the following fields:

+----------+---------+---------+-------+--------------+---------------------+
| Field    | Type    | Null    | Key   | Default      | Description         |
+----------+---------+---------+-------+--------------+---------------------+
| name     | char(64 | NO      | PRI   |              | UDF name            |
|          |         |         |       |              |                     |
+----------+---------+---------+-------+--------------+---------------------+
| ret      | tinyint | NO      |       | 0            |                     |
|          | 1)      |         |       |              |                     |
+----------+---------+---------+-------+--------------+---------------------+
| dl       | char(12 | NO      |       |              | Shared library name |
|          | )       |         |       |              |                     |
+----------+---------+---------+-------+--------------+---------------------+
| type     | enum('f | NO      |       | NULL         | Type, either        |
|          | nction' |         |       |              | function or         |
|          | 'aggreg |         |       |              | aggregate.          |
|          | te')    |         |       |              | Aggregate           |
|          |         |         |       |              | functions are       |
|          |         |         |       |              | summary functions   |
|          |         |         |       |              | such as SUM() and   |
|          |         |         |       |              | AVG().              |
+----------+---------+---------+-------+--------------+---------------------+

Example
-------

SELECT * FROM mysql.func;
+------------------------------+-----+--------------+-----------+
| name                         | ret | dl           | type      |
+------------------------------+-----+--------------+-----------+
| spider_direct_sql            |   2 | ha_spider.so | function  |
| spider_bg_direct_sql         |   2 | ha_spider.so | aggregate |
| spider_ping_table            |   2 | ha_spider.so | function  |
| spider_copy_tables           |   2 | ha_spider.so | function  |
| spider_flush_table_mon_cache |   2 | ha_spider.so | function  |
+------------------------------+-----+--------------+-----------+

URL: https://mariadb.com/kb/en/mysqlfunc-table/https://mariadb.com/kb/en/mysqlfunc-table/�@,DROP FUNCTION UDFSyntax
------

DROP FUNCTION [IF EXISTS] function_name

Description
-----------

This statement drops the user-defined function (UDF) named function_name.

To drop a function, you must have the DELETE privilege for the mysql database.
This is because DROP FUNCTION removes the row from the mysql.func system table
that records the function's name, type and shared library name.

For dropping a stored function, see DROP FUNCTION.

Upgrading a UDF
---------------

To upgrade the UDF's shared library, first run a DROP FUNCTION statement, then
upgrade the shared library and finally run the CREATE FUNCTION statement. If
you upgrade without following this process, you may crash the server.

Examples
--------

DROP FUNCTION jsoncontains_path;

IF EXISTS:

DROP FUNCTION jsoncontains_path;
ERROR 1305 (42000): FUNCTION test.jsoncontains_path does not exist

DROP FUNCTION IF EXISTS jsoncontains_path;
Query OK, 0 rows affected, 1 warning (0.00 sec)

SHOW WARNINGS;
+-------+------+------------------------------------------------+
| Level | Code | Message                                        |
+-------+------+------------------------------------------------+
| Note  | 1305 | FUNCTION test.jsoncontains_path does not exist |
+-------+------+------------------------------------------------+

URL: https://mariadb.com/kb/en/drop-function-udf/https://mariadb.com/kb/en/drop-function-udf/:User-Defined Functions SecurityThe MariaDB server imposes a number of limitations on user-defined functions
for security purposes.

* The INSERT privilege for the mysql database is required to run CREATE
FUNCTION, as a record will be added to the mysql.func-table.
* The DELETE privilege for the mysql database is required to run DROP FUNCTION
as the corresponding record will be removed from the mysql.func-table.
* UDF object files can only be placed in the plugin directory, as specified by
the value of the plugin_dir system variable.
* At least one symbol, beyond the required x() - corresponding to an SQL
function X()) - is required. These can be x_init(), x_deinit(), xxx_reset(),
x_clear() and x_add() functions (see Creating User-defined Functions). The
allow-suspicious-udfs mysqld option (by default unset) provides a workaround,
permitting only one symbol to be used. This is not recommended, as it opens
the possibility of loading shared objects that are not legitimate user-defined
functions.

URL: https://mariadb.com/kb/en/user-defined-functions-security/https://mariadb.com/kb/en/user-defined-functions-security/PF# ST_AsWKBA synonym for ST_AsBinary().

URL: https://mariadb.com/kb/en/st_aswkb/https://mariadb.com/kb/en/st_aswkb/R_7 ST_GeometryCollectionFromWKBA synonym for ST_GeomCollFromWKB.

URL: https://mariadb.com/kb/en/st_geometrycollectionfromwkb/https://mariadb.com/kb/en/st_geometrycollectionfromwkb/SQ- ST_GeometryFromWKBA synonym for ST_GeomFromWKB.

URL: https://mariadb.com/kb/en/st_geometryfromwkb/https://mariadb.com/kb/en/st_geometryfromwkb/T�) ST_GeomFromWKBSyntax
------

ST_GeomFromWKB(wkb[,srid])
ST_GeometryFromWKB(wkb[,srid])
GeomFromWKB(wkb[,srid])
GeometryFromWKB(wkb[,srid])

Description
-----------

Constructs a geometry value of any type using its WKB representation and SRID.

ST_GeomFromWKB(), ST_GeometryFromWKB(), GeomFromWKB() and GeometryFromWKB()
are synonyms.

Examples
--------

SET @g = ST_AsBinary(ST_LineFromText('LINESTRING(0 4, 4 6)'));

SELECT ST_AsText(ST_GeomFromWKB(@g));
+-------------------------------+
| ST_AsText(ST_GeomFromWKB(@g)) |
+-------------------------------+
| LINESTRING(0 4,4 6)           |
+-------------------------------+

URL: https://mariadb.com/kb/en/st_geomfromwkb/https://mariadb.com/kb/en/st_geomfromwkb/Ue) ST_LineFromWKBSyntax
------

ST_LineFromWKB(wkb[,srid])
LineFromWKB(wkb[,srid])
ST_LineStringFromWKB(wkb[,srid])
LineStringFromWKB(wkb[,srid])

Description
-----------

Constructs a LINESTRING value using its WKB representation and SRID.

ST_LineFromWKB(), LineFromWKB(), ST_LineStringFromWKB(), and
LineStringFromWKB() are synonyms.

Examples
--------

SET @g = ST_AsBinary(ST_LineFromText('LineString(0 4,4 6)'));

SELECT ST_AsText(ST_LineFromWKB(@g)) AS l;
+---------------------+
| l                   |
+---------------------+
| LINESTRING(0 4,4 6) |
+---------------------+

URL: https://mariadb.com/kb/en/st_linefromwkb/https://mariadb.com/kb/en/st_linefromwkb/VS/ ST_LineStringFromWKBA synonym for ST_LineFromWKB.

URL: https://mariadb.com/kb/en/st_linestringfromwkb/https://mariadb.com/kb/en/st_linestringfromwkb/f�����E����x��
X�

���h.CREATE FUNCTION UDFSyntax
------

CREATE [OR REPLACE] [AGGREGATE] FUNCTION [IF NOT EXISTS] function_name
  RETURNS {STRING|INTEGER|REAL|DECIMAL}
  SONAME shared_library_name

Description
-----------

A user-defined function (UDF) is a way to extend MariaDB with a new function
that works like a native (built-in) MariaDB function such as ABS() or CONCAT().

function_name is the name that should be used in SQL statements to invoke the
function.

To create a function, you must have the INSERT privilege for the mysql
database. This is necessary becauseCREATE FUNCTION adds a row to the
mysql.func system table that records the function's name, type, and shared
library name. If you do not have this table, you should run the
mariadb-upgrade command to create it.

UDFs need to be written in C, C++ or another language that uses C calling
conventions, MariaDB needs to have been dynamically compiled, and your
operating system must support dynamic loading.

For an example, see sql/udf_example.cc in the source tree. For a collection of
existing UDFs see http://www.mysqludf.org/.

Statements making use of user-defined functions are not safe for replication.

For creating a stored function as opposed to a user-defined function, see
CREATE FUNCTION.

For valid identifiers to use as function names, see Identifier Names.

RETURNS
-------

The RETURNS clause indicates the type of the function's return value, and can
be one of STRING, INTEGER, REAL or DECIMAL. DECIMAL functions currently return
string values and should be written like STRING functions.

shared_library_name
-------------------

shared_library_name is the basename of the shared object file that contains
the code that implements the function. The file must be located in the plugin
directory. This directory is given by the value of the plugin_dir system
variable. Note that before MariaDB/MySQL 5.1, the shared object could be
located in any directory that was searched by your system's dynamic linker.

AGGREGATE
---------

Aggregate functions are summary functions such as SUM() and AVG().

MariaDB starting with 10.4
--------------------------
Aggregate UDF functions can be used as window functions.

OR REPLACE
----------

MariaDB starting with 10.1.3
----------------------------
The OR REPLACE clause was added in MariaDB 10.1.3

If the optional OR REPLACE clause is used, it acts as a shortcut for:

DROP FUNCTION IF EXISTS function_name;
CREATE FUNCTION name ...;

IF NOT EXISTS
-------------

MariaDB starting with 10.1.3
----------------------------
The IF NOT EXISTS clause was added in MariaDB 10.1.3

When the IF NOT EXISTS clause is used, MariaDB will return a warning instead
of an error if the specified function already exists. Cannot be used together
with OR REPLACE.

Upgrading a UDF
---------------

To upgrade the UDF's shared library, first run a DROP FUNCTION statement, then
upgrade the shared library and finally run the CREATE FUNCTION statement. If
you upgrade without following this process, you may crash the server.

Examples
--------

CREATE FUNCTION jsoncontains_path RETURNS integer SONAME 'ha_connect.so';
Query OK, 0 rows affected (0.00 sec)

OR REPLACE and IF NOT EXISTS:

CREATE FUNCTION jsoncontains_path RETURNS integer SONAME 'ha_connect.so';
ERROR 1125 (HY000): Function 'jsoncontains_path' already exists

CREATE OR REPLACE FUNCTION jsoncontains_path RETURNS integer SONAME
'ha_connect.so';
Query OK, 0 rows affected (0.00 sec)

CREATE FUNCTION IF NOT EXISTS jsoncontains_path RETURNS integer SONAME
'ha_connect.so';
Query OK, 0 rows affected, 1 warning (0.00 sec)

SHOW WARNINGS;
+-------+------+---------------------------------------------+
| Level | Code | Message                                     |
+-------+------+---------------------------------------------+
| Note  | 1125 | Function 'jsoncontains_path' already exists |
+-------+------+---------------------------------------------+

URL: https://mariadb.com/kb/en/create-function-udf/https://mariadb.com/kb/en/create-function-udf/�"TINYINTSyntax
------

TINYINT[(M)] [SIGNED | UNSIGNED | ZEROFILL]

Description
-----------

A very small integer. The signed range is -128 to 127. The unsigned range is 0
to 255. For details on the attributes, see Numeric Data Type Overview.

INT1 is a synonym for TINYINT. BOOL and BOOLEAN are synonyms for TINYINT(1).

Examples
--------

CREATE TABLE tinyints (a TINYINT,b TINYINT UNSIGNED,c TINYINT ZEROFILL);

With strict_mode set, the default from MariaDB 10.2.4:

INSERT INTO tinyints VALUES (-10,-10,-10);
ERROR 1264 (22003): Out of range value for column 'b' at row 1

INSERT INTO tinyints VALUES (-10,10,-10);
ERROR 1264 (22003): Out of range value for column 'c' at row 1

INSERT INTO tinyints VALUES (-10,10,10);

SELECT * FROM tinyints;
+------+------+------+
| a    | b    | c    |
+------+------+------+
|  -10 |   10 |  010 |
+------+------+------+

INSERT INTO tinyints VALUES (128,128,128);
ERROR 1264 (22003): Out of range value for column 'a' at row 1

INSERT INTO tinyints VALUES (127,128,128);

SELECT * FROM tinyints;
+------+------+------+
| a    | b    | c    |
+------+------+------+
|  -10 |   10 |  010 |
|  127 |  128 |  128 |
+------+------+------+

With strict_mode unset, the default until MariaDB 10.2.3:

INSERT INTO tinyints VALUES (-10,-10,-10);
Query OK, 1 row affected, 2 warnings (0.08 sec)
Warning (Code 1264): Out of range value for column 'b' at row 1
Warning (Code 1264): Out of range value for column 'c' at row 1

INSERT INTO tinyints VALUES (-10,10,-10);
Query OK, 1 row affected, 1 warning (0.11 sec)
Warning (Code 1264): Out of range value for column 'c' at row 1

INSERT INTO tinyints VALUES (-10,10,10);

SELECT * FROM tinyints;
+------+------+------+
| a    | b    | c    |
+------+------+------+
|  -10 |    0 |  000 |
|  -10 |   10 |  000 |
|  -10 |   10 |  010 |
+------+------+------+

INSERT INTO tinyints VALUES (128,128,128);
Query OK, 1 row affected, 1 warning (0.19 sec)
Warning (Code 1264): Out of range value for column 'a' at row 1

INSERT INTO tinyints VALUES (127,128,128);

SELECT * FROM tinyints;
+------+------+------+
| a    | b    | c    |
+------+------+------+
|  -10 |    0 |  000 |
|  -10 |   10 |  000 |
|  -10 |   10 |  010 |
|  127 |  128 |  128 |
|  127 |  128 |  128 |
+------+------+------+

URL: https://mariadb.com/kb/en/tinyint/https://mariadb.com/kb/en/tinyint/W�* ST_PointFromWKBSyntax
------

ST_PointFromWKB(wkb[,srid])
PointFromWKB(wkb[,srid])

Description
-----------

Constructs a POINT value using its WKB representation and SRID.

ST_PointFromWKB() and PointFromWKB() are synonyms.

Examples
--------

SET @g = ST_AsBinary(ST_PointFromText('POINT(0 4)'));

SELECT ST_AsText(ST_PointFromWKB(@g)) AS p;
+------------+
| p          |
+------------+
| POINT(0 4) |
+------------+

URL: https://mariadb.com/kb/en/st_pointfromwkb/https://mariadb.com/kb/en/st_pointfromwkb/X�) ST_PolyFromWKBSyntax
------

ST_PolyFromWKB(wkb[,srid])
ST_PolygonFromWKB(wkb[,srid])
PolyFromWKB(wkb[,srid])
PolygonFromWKB(wkb[,srid])

Description
-----------

Constructs a POLYGON value using its WKB representation and SRID.

ST_PolyFromWKB(), ST_PolygonFromWKB(), PolyFromWKB() and PolygonFromWKB() are
synonyms.

Examples
--------

SET @g = ST_AsBinary(ST_PolyFromText('POLYGON((1 1,1 5,4 9,6 9,9 3,7 2,1
1))'));

SELECT ST_AsText(ST_PolyFromWKB(@g)) AS p;
+----------------------------------------+
| p                                      |
+----------------------------------------+
| POLYGON((1 1,1 5,4 9,6 9,9 3,7 2,1 1)) |
+----------------------------------------+

URL: https://mariadb.com/kb/en/st_polyfromwkb/https://mariadb.com/kb/en/st_polyfromwkb/��6	�$L=Y�X�:Creating User-Defined FunctionsUser-defined functions allow MariaDB to be extended with a new function that
works like a native (built-in) MariaDB function such as ABS() or CONCAT().
There are alternative ways to add a new function: writing a native function
(which requires modifying and compiling the server source code), or writing a
stored function.

Statements making use of user-defined functions are not safe for replication.

Functions are written in C or C++, and to make use of them, the operating
system must support dynamic loading.

Each new SQL function requires corresponding functions written in C/C++. In
the list below, at least the main function - x() - and one other, are
required. x should be replaced by the name of the function you are creating.

All functions need to be thread-safe, so not global or static variables that
change can be allocated. Memory is allocated in x_init()/ and freed in
x_deinit().

Simple Functions
----------------

x()
---

Required for all UDFs; this is where the results are calculated.

+------------------------------------------+----------------------------------+
| C/C++ type                               | SQL type                         |
+------------------------------------------+----------------------------------+
| char *                                   | STRING                           |
+------------------------------------------+----------------------------------+
| long long                                | INTEGER                          |
+------------------------------------------+----------------------------------+
| double                                   | REAL                             |
+------------------------------------------+----------------------------------+

DECIMAL functions return string values, and so should be written accordingly.
It is not possible to create ROW functions.

x_init()
--------

Initialization function for x(). Can be used for the following:

* Check the number of arguments to X() (the SQL equivalent).
* Verify the argument types, or to force arguments to be of a particular type
after the function is called.
* Specify whether the result can be NULL.
* Specify the maximum result length.
* For REAL functions, specify the maximum number of decimals for the result.
* Allocate any required memory.

x_deinit()
----------

De-initialization function for x(). Used to de-allocate memory that was
allocated in x_init().

Description
-----------

Each time the SQL function X() is called:

* MariaDB will first call the C/C++ initialization function, x_init(),
assuming it exists. All setup will be performed, and if it returns an error,
the SQL statement is aborted and no further functions are called.
* If there is no x_init() function, or it has been called and did not return
an error, x() is then called once per row.
* After all rows have finished processing, x_deinit() is called, if present,
to clean up by de-allocating any memory that was allocated in x_init().
* See User-defined Functions Calling Sequences for more details on the
functions.

Aggregate Functions
-------------------

The following functions are required for aggregate functions, such as AVG()
and SUM(). When using CREATE FUNCTION, the AGGREGATE keyword is required.

x_clear()
---------

Used to reset the current aggregate, but without inserting the argument as the
initial aggregate value for the new group.

x_add()
-------

Used to add the argument to the current aggregate.

x_remove()
----------

Starting from MariaDB 10.4, improves the support of window functions (so it is
not obligatory to add it) and should remove the argument from the current
aggregate.

Description
-----------

Each time the aggregate SQL function X() is called:

* MariaDB will first call the C/C++ initialization function, x_init(),
assuming it exists. All setup will be performed, and if it returns an error,
the SQL statement is aborted and no further functions are called.
* If there is no x_init() function, or it has been called and did not return
an error, x() is then called once per row.
* After all rows have finished processing, x_deinit() is called, if present,
to clean up by de-allocating any memory that was allocated in x_init().

* MariaDB will first call the C/C++ initialization function, x_init(),
assuming it exists. All setup will be performed, and if it returns an error,
the SQL statement is aborted and no further functions are called.
* The table is sorted according to the GROUP BY expression.
* x_clear() is called for the first row of each new group.
* x_add() is called once per row for each row in the same group.
* x() is called when the group changes, or after the last row, to get the
aggregate result. 
* The latter three steps are repeated until all rows have been processed.
* After all rows have finished processing, x_deinit() is called, if present,
to clean up by de-allocating any memory that was allocated in x_init().

Examples
--------

For an example, see sql/udf_example.cc in the source tree. For a collection of
existing UDFs see https://github.com/mysqludf.

URL: https://mariadb.com/kb/en/creating-user-defined-functions/https://mariadb.com/kb/en/creating-user-defined-functions/YP, ST_PolygonFromWKBA synonym for ST_PolyFromWKB.

URL: https://mariadb.com/kb/en/st_polygonfromwkb/https://mariadb.com/kb/en/st_polygonfromwkb/]X7#BOUNDARYA synonym for ST_BOUNDARY.

URL: https://mariadb.com/kb/en/geometry-properties-boundary/https://mariadb.com/kb/en/geometry-properties-boundary/^	F$#DIMENSIONA synonym for ST_DIMENSION.

URL: https://mariadb.com/kb/en/dimension/https://mariadb.com/kb/en/dimension/_X7#ENVELOPEA synonym for ST_ENVELOPE.

URL: https://mariadb.com/kb/en/geometry-properties-envelope/https://mariadb.com/kb/en/geometry-properties-envelope/`	Z8#GeometryNA synonym for ST_GeometryN.

URL: https://mariadb.com/kb/en/geometry-properties-geometryn/https://mariadb.com/kb/en/geometry-properties-geometryn/a`;#GeometryTypeA synonym for ST_GeometryType.

URL: https://mariadb.com/kb/en/geometry-properties-geometrytype/https://mariadb.com/kb/en/geometry-properties-geometrytype/bD##IsClosedA synonym for ST_IsClosed.

URL: https://mariadb.com/kb/en/isclosed/https://mariadb.com/kb/en/isclosed/cV6#IsEmptyA synonym for ST_IsEmpty.

URL: https://mariadb.com/kb/en/geometry-properties-isempty/https://mariadb.com/kb/en/geometry-properties-isempty/d@!#IsRingA synonym for ST_IsRing.

URL: https://mariadb.com/kb/en/isring/https://mariadb.com/kb/en/isring/eX7#IsSimpleA synonym for ST_IsSImple.

URL: https://mariadb.com/kb/en/geometry-properties-issimple/https://mariadb.com/kb/en/geometry-properties-issimple/f
b<#NumGeometriesA synonym for ST_NumGeometries.

URL: https://mariadb.com/kb/en/geometry-properties-numgeometries/https://mariadb.com/kb/en/geometry-properties-numgeometries/gP3#SRIDA synonym for ST_SRID.

URL: https://mariadb.com/kb/en/geometry-properties-srid/https://mariadb.com/kb/en/geometry-properties-srid/kf'#ST_GEOMETRYNSyntax
------

ST_GeometryN(gc,N)
GeometryN(gc,N)

Description
-----------

Returns the N-th geometry in the GeometryCollection gc. Geometries are
numbered beginning with 1.

ST_GeometryN() and GeometryN() are synonyms.

Example
-------

SET @gc = 'GeometryCollection(Point(1 1),LineString(12 14, 9 11))';

SELECT AsText(GeometryN(GeomFromText(@gc),1));
+----------------------------------------+
| AsText(GeometryN(GeomFromText(@gc),1)) |
+----------------------------------------+
| POINT(1 1)                             |
+----------------------------------------+

URL: https://mariadb.com/kb/en/st_geometryn/https://mariadb.com/kb/en/st_geometryn/��0�w���]u��?}����<����{�o���X�5(�CUser-Defined Functions Calling SequencesThe functions described in Creating User-defined Functions are expanded on
this page. They are declared as follows:

Simple Functions
----------------

x()
---

If x() returns an integer, it is declared as follows:

long long x(UDF_INIT *initid, UDF_ARGS *args,
       char *is_null, char *error);

If x() returns a string (DECIMAL functions also return string values), it is
declared as follows:

char *x(UDF_INIT *initid, UDF_ARGS *args,
     char *result, unsigned long *length,
     char *is_null, char *error);

If x() returns a real, it is declared as follows:

double x(UDF_INIT *initid, UDF_ARGS *args,
       char *is_null, char *error);

x_init()
--------

my_bool x_init(UDF_INIT *initid, UDF_ARGS *args, char *message);

x_deinit()
----------

void x_deinit(UDF_INIT *initid);

Description
-----------

initid is a parameter passed to all three functions that points to a UDF_INIT
structure, used for communicating information between the functions. Its
structure members are:

* my_bool maybe_null
maybe_null should be set to 1 if x_init can return a NULL value, Defaults to 1
if any arguments are declared maybe_null.

* unsigned int decimals
Number of decimals after the decimal point. The default, if an explicit number
of decimals is passed in the arguments to the main function, is the maximum
number of decimals, so if 9.5, 9.55 and 9.555 are passed to the function, the
default would be three (based on 9.555, the maximum).  If there are no
explicit number of decimals, the default is set to 31, or one more than the
maximum for the DOUBLE, FLOAT and DECIMAL types. This default can be changed
in the function to suit the actual calculation.

* unsigned int max_length
Maximum length of the result. For integers, the default is 21. For strings,
the length of the longest argument. For reals, the default is 13 plus the
number of decimals indicated by initid->decimals. The length includes any
signs or decimal points. Can also be set to 65KB or 16MB in order to return a
BLOB. The memory remains unallocated, but this is used to decide on the data
type to use if the data needs to be temporarily stored.

* char *ptr
A pointer for use as required by the function. Commonly, initid->ptr is used
to communicate allocated memory, with x_init() allocating the memory and
assigning it to this pointer, x() using it, and x_deinit() de-allocating it.

* my_bool const_item
Should be set to 1 in x_init() if x() always returns the same value, otherwise
0.

Aggregate Functions
-------------------

x_clear()
---------

x_clear() is a required function for aggregate functions, and is declared as
follows:

void x_clear(UDF_INIT *initid, char *is_null, char *error);

It is called when the summary results need to be reset, that is at the
beginning of each new group. but also to reset the values when there were no
matching rows.

is_null is set to point to CHAR(0) before calling x_clear().

In the case of an error, you can store the value to which the error argument
points (a single-byte variable, not a string string buffer) in the variable.

x_reset()
---------

x_reset() is declared as follows:

void x_reset(UDF_INIT *initid, UDF_ARGS *args,
       char *is_null, char *error);

It is called on finding the first row in a new group. Should reset the summary
variables, and then use UDF_ARGS as the first value in the group's internal
summary value. The function is not required if the UDF interface uses
x_clear().

x_add()
-------

x_add() is declared as follows:

void x_add(UDF_INIT *initid, UDF_ARGS *args,
      char *is_null, char *error);

It is called for all rows belonging to the same group, and should be used to
add the value in UDF_ARGS to the internal summary variable.

x_remove()
----------

x_remove() was added in MariaDB 10.4 and is declared as follows (same as
x_add()):

void x_remove(UDF_INIT* initid, UDF_ARGS* args,
       char* is_null, char *error );

It adds more efficient support of aggregate UDFs as window functions.
x_remove() should "subtract" the row (reverse x_add()). In MariaDB 10.4
aggregate UDFs will work as WINDOW functions without x_remove() but it will
not be so efficient.

If x_remove() supported (defined) detected automatically.

URL: https://mariadb.com/kb/en/user-defined-functions-calling-sequences/https://mariadb.com/kb/en/user-defined-functions-calling-sequences/�"BOOLEANSyntax
------

BOOL, BOOLEAN

Description
-----------

These types are synonyms for TINYINT(1). A value of zero is considered false.
Non-zero values are considered true.

However, the values TRUE and FALSE are merely aliases for 1 and 0. See Boolean
Literals, as well as the IS operator for testing values against a boolean.

Examples
--------

CREATE TABLE boo (i BOOLEAN);

DESC boo;
+-------+------------+------+-----+---------+-------+
| Field | Type       | Null | Key | Default | Extra |
+-------+------------+------+-----+---------+-------+
| i     | tinyint(1) | YES  |     | NULL    |       |
+-------+------------+------+-----+---------+-------+

SELECT IF(0, 'true', 'false');
+------------------------+
| IF(0, 'true', 'false') |
+------------------------+
| false                  |
+------------------------+

SELECT IF(1, 'true', 'false');
+------------------------+
| IF(1, 'true', 'false') |
+------------------------+
| true                   |
+------------------------+

SELECT IF(2, 'true', 'false');
+------------------------+
| IF(2, 'true', 'false') |
+------------------------+
| true                   |
+------------------------+

TRUE and FALSE as aliases for 1 and 0:

SELECT IF(0 = FALSE, 'true', 'false');

+--------------------------------+
| IF(0 = FALSE, 'true', 'false') |
+--------------------------------+
| true                           |
+--------------------------------+

SELECT IF(1 = TRUE, 'true', 'false');
+-------------------------------+
| IF(1 = TRUE, 'true', 'false') |
+-------------------------------+
| true                          |
+-------------------------------+

SELECT IF(2 = TRUE, 'true', 'false');
+-------------------------------+
| IF(2 = TRUE, 'true', 'false') |
+-------------------------------+
| false                         |
+-------------------------------+

SELECT IF(2 = FALSE, 'true', 'false');
+--------------------------------+
| IF(2 = FALSE, 'true', 'false') |
+--------------------------------+
| false                          |
+--------------------------------+

The last two statements display the results shown because 2 is equal to
neither 1 nor 0.

URL: https://mariadb.com/kb/en/boolean/https://mariadb.com/kb/en/boolean/l{*#ST_GEOMETRYTYPESyntax
------

ST_GeometryType(g)
GeometryType(g)

Description
-----------

Returns as a string the name of the geometry type of which the geometry
instance g is a member. The name corresponds to one of the instantiable
Geometry subclasses.

ST_GeometryType() and GeometryType() are synonyms.

Examples
--------

SELECT GeometryType(GeomFromText('POINT(1 1)'));
+------------------------------------------+
| GeometryType(GeomFromText('POINT(1 1)')) |
+------------------------------------------+
| POINT                                    |
+------------------------------------------+

URL: https://mariadb.com/kb/en/st_geometrytype/https://mariadb.com/kb/en/st_geometrytype/n
�%#ST_ISEMPTYSyntax
------

ST_IsEmpty(g)
IsEmpty(g)

Description
-----------

IsEmpty is a function defined by the OpenGIS specification, but is not fully
implemented by MariaDB or MySQL.

Since MariaDB and MySQL do not support GIS EMPTY values such as POINT EMPTY,
as implemented it simply returns 1 if the geometry value g is invalid, 0 if it
is valid, and NULL if the argument is NULL.

ST_IsEmpty() and IsEmpty() are synonyms.

URL: https://mariadb.com/kb/en/st_isempty/https://mariadb.com/kb/en/st_isempty/���3�'�;����5Numeric Data Type OverviewThere are a number of numeric data types:

* TINYINT
* BOOLEAN - Synonym for TINYINT(1)
* INT1 - Synonym for TINYINT
* SMALLINT
* INT2 - Synonym for SMALLINT
* MEDIUMINT
* INT3 - Synonym for MEDIUMINT
* INT, INTEGER
* INT4 - Synonym for INT
* BIGINT
* INT8 - Synonym for BIGINT
* DECIMAL, DEC, NUMERIC, FIXED
* FLOAT
* DOUBLE, DOUBLE PRECISION, REAL
* BIT

See the specific articles for detailed information on each.

SIGNED, UNSIGNED and ZEROFILL
-----------------------------

Most numeric types can be defined as SIGNED, UNSIGNED or ZEROFILL, for example:

TINYINT[(M)] [SIGNED | UNSIGNED | ZEROFILL]

If SIGNED, or no attribute, is specified, a portion of the numeric type will
be reserved for the sign (plus or minus). For example, a TINYINT SIGNED can
range from -128 to 127.

If UNSIGNED is specified, no portion of the numeric type is reserved for the
sign, so for integer types range can be larger. For example, a TINYINT
UNSIGNED can range from 0 to 255. Floating point and fixed-point types also
can be UNSIGNED, but this only prevents negative values from being stored and
doesn't alter the range.

If ZEROFILL is specified, the column will be set to UNSIGNED and the spaces
used by default to pad the field are replaced with zeros. ZEROFILL is ignored
in expressions or as part of a UNION. ZEROFILL is a non-standard MySQL and
MariaDB enhancement.

Note that although the preferred syntax indicates that the attributes are
exclusive, more than one attribute can be specified.

Until MariaDB 10.2.7 (MDEV-8659), any combination of the attributes could be
used in any order, with duplicates. In this case:

* the presence of ZEROFILL makes the column UNSIGNED ZEROFILL.
* the presence of UNSIGNED makes the column UNSIGNED.

From MariaDB 10.2.8, only the following combinations are supported:

* SIGNED
* UNSIGNED
* ZEROFILL
* UNSIGNED ZEROFILL
* ZEROFILL UNSIGNED

The latter two should be replaced with simply ZEROFILL, but are still accepted
by the parser.

Examples
--------

CREATE TABLE zf (
 i1 TINYINT SIGNED,
 i2 TINYINT UNSIGNED,
 i3 TINYINT ZEROFILL
);

INSERT INTO zf VALUES (2,2,2);

SELECT * FROM zf;
+------+------+------+
| i1   | i2   | i3   |
+------+------+------+
|    2 |    2 |  002 |
+------+------+------+

Range
-----

When attempting to add a value that is out of the valid range for the numeric
type, MariaDB will react depending on the strict SQL_MODE setting.

If strict_mode has been set (the default from MariaDB 10.2.4), MariaDB will
return an error.

If strict_mode has not been set (the default until MariaDB 10.2.3), MariaDB
will adjust the number to fit in the field, returning a warning.

Examples
--------

With strict_mode set:

SHOW VARIABLES LIKE 'sql_mode';
+---------------+--------------------------------------------------------------
----------------------------+
| Variable_name | Value                                                       
              |
+---------------+--------------------------------------------------------------
----------------------------+
| sql_mode      |
STRICT_TRANS_TABLES,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SU
STITUTION |
+---------------+--------------------------------------------------------------
----------------------------+

CREATE TABLE ranges (i1 TINYINT, i2 SMALLINT, i3 TINYINT UNSIGNED);

INSERT INTO ranges VALUES (257,257,257);
ERROR 1264 (22003): Out of range value for column 'i1' at row 1

SELECT * FROM ranges;
Empty set (0.10 sec)

With strict_mode unset:

SHOW VARIABLES LIKE 'sql_mode%';
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| sql_mode      |       |
+---------------+-------+

CREATE TABLE ranges (i1 TINYINT, i2 SMALLINT, i3 TINYINT UNSIGNED);

INSERT INTO ranges VALUES (257,257,257);
Query OK, 1 row affected, 2 warnings (0.00 sec)

SHOW WARNINGS;
+---------+------+---------------------------------------------+
| Level   | Code | Message                                     |
+---------+------+---------------------------------------------+
| Warning | 1264 | Out of range value for column 'i1' at row 1 |
| Warning | 1264 | Out of range value for column 'i3' at row 1 |
+---------+------+---------------------------------------------+
2 rows in set (0.00 sec)

SELECT * FROM ranges;
+------+------+------+
| i1   | i2   | i3   |
+------+------+------+
|  127 |  257 |  255 |
+------+------+------+

Auto_increment
--------------

The AUTO_INCREMENT attribute can be used to generate a unique identity for new
rows. For more details, see auto_increment.

URL: https://mariadb.com/kb/en/numeric-data-type-overview/https://mariadb.com/kb/en/numeric-data-type-overview/�#SMALLINTSyntax
------

SMALLINT[(M)] [SIGNED | UNSIGNED | ZEROFILL]

Description
-----------

A small integer. The signed range is -32768 to 32767. The unsigned range is 0
to 65535.

If a column has been set to ZEROFILL, all values will be prepended by zeros so
that the SMALLINT value contains a number of M digits.

Note: If the ZEROFILL attribute has been specified, the column will
automatically become UNSIGNED.

INT2 is a synonym for SMALLINT.

For more details on the attributes, see Numeric Data Type Overview.

Examples
--------

CREATE TABLE smallints (a SMALLINT,b SMALLINT UNSIGNED,c SMALLINT ZEROFILL);

With strict_mode set, the default from MariaDB 10.2.4:

INSERT INTO smallints VALUES (-10,-10,-10);
ERROR 1264 (22003): Out of range value for column 'b' at row 1

INSERT INTO smallints VALUES (-10,10,-10);
ERROR 1264 (22003): Out of range value for column 'c' at row 1

INSERT INTO smallints VALUES (-10,10,10);

INSERT INTO smallints VALUES (32768,32768,32768);
ERROR 1264 (22003): Out of range value for column 'a' at row 1

INSERT INTO smallints VALUES (32767,32768,32768);

SELECT * FROM smallints;
+-------+-------+-------+
| a     | b     | c     |
+-------+-------+-------+
|   -10 |    10 | 00010 |
| 32767 | 32768 | 32768 |
+-------+-------+-------+

With strict_mode unset, the default until MariaDB 10.2.3:

INSERT INTO smallints VALUES (-10,-10,-10);
Query OK, 1 row affected, 2 warnings (0.09 sec)
Warning (Code 1264): Out of range value for column 'b' at row 1
Warning (Code 1264): Out of range value for column 'c' at row 1

INSERT INTO smallints VALUES (-10,10,-10);
Query OK, 1 row affected, 1 warning (0.08 sec)
Warning (Code 1264): Out of range value for column 'c' at row 1

INSERT INTO smallints VALUES (-10,10,10);

INSERT INTO smallints VALUES (32768,32768,32768);
Query OK, 1 row affected, 1 warning (0.04 sec)
Warning (Code 1264): Out of range value for column 'a' at row 1

INSERT INTO smallints VALUES (32767,32768,32768);

SELECT * FROM smallints;
+-------+-------+-------+
| a     | b     | c     |
+-------+-------+-------+
|   -10 |     0 | 00000 |
|   -10 |    10 | 00000 |
|   -10 |    10 | 00010 |
| 32767 | 32768 | 32768 |
| 32767 | 32768 | 32768 |
+-------+-------+-------+

URL: https://mariadb.com/kb/en/smallint/https://mariadb.com/kb/en/smallint/o	�$#ST_IsRingMariaDB starting with 10.1.2
----------------------------
The ST_IsRing function was introduced in MariaDB 10.1.2

Syntax
------

ST_IsRing(g)
IsRing(g)

Description
-----------

Returns true if a given LINESTRING is a ring, that is, both ST_IsClosed and
ST_IsSimple. A simple curve does not pass through the same point more than
once. However, see MDEV-7510.

St_IsRing() and IsRing() are synonyms.

URL: https://mariadb.com/kb/en/st_isring/https://mariadb.com/kb/en/st_isring/k�]	Qq�9��y	%$MEDIUMINTSyntax
------

MEDIUMINT[(M)] [SIGNED | UNSIGNED | ZEROFILL]

Description
-----------

A medium-sized integer. The signed range is -8388608 to 8388607. The unsigned
range is 0 to 16777215.

ZEROFILL pads the integer with zeroes and assumes UNSIGNED (even if UNSIGNED
is not specified).

INT3 is a synonym for MEDIUMINT.

For details on the attributes, see Numeric Data Type Overview.

Examples
--------

CREATE TABLE mediumints (a MEDIUMINT,b MEDIUMINT UNSIGNED,c MEDIUMINT
ZEROFILL);

DESCRIBE mediumints;
+-------+--------------------------------+------+-----+---------+-------+
| Field | Type                           | Null | Key | Default | Extra |
+-------+--------------------------------+------+-----+---------+-------+
| a     | mediumint(9)                   | YES  |     | NULL    |       |
| b     | mediumint(8) unsigned          | YES  |     | NULL    |       |
| c     | mediumint(8) unsigned zerofill | YES  |     | NULL    |       |
+-------+--------------------------------+------+-----+---------+-------+

With strict_mode set, the default from MariaDB 10.2.4:

INSERT INTO mediumints VALUES (-10,-10,-10);
ERROR 1264 (22003): Out of range value for column 'b' at row 1

INSERT INTO mediumints VALUES (-10,10,-10);
ERROR 1264 (22003): Out of range value for column 'c' at row 1

INSERT INTO mediumints VALUES (-10,10,10);

INSERT INTO mediumints VALUES (8388608,8388608,8388608);
ERROR 1264 (22003): Out of range value for column 'a' at row 1

INSERT INTO mediumints VALUES (8388607,8388608,8388608);

SELECT * FROM mediumints;
+---------+---------+----------+
| a       | b       | c        |
+---------+---------+----------+
|     -10 |      10 | 00000010 |
| 8388607 | 8388608 | 08388608 |
+---------+---------+----------+

With strict_mode unset, the default until MariaDB 10.2.3:

INSERT INTO mediumints VALUES (-10,-10,-10);
Query OK, 1 row affected, 2 warnings (0.05 sec)
Warning (Code 1264): Out of range value for column 'b' at row 1
Warning (Code 1264): Out of range value for column 'c' at row 1

INSERT INTO mediumints VALUES (-10,10,-10);
Query OK, 1 row affected, 1 warning (0.08 sec)
Warning (Code 1264): Out of range value for column 'c' at row 1

INSERT INTO mediumints VALUES (-10,10,10);

INSERT INTO mediumints VALUES (8388608,8388608,8388608);
Query OK, 1 row affected, 1 warning (0.05 sec)
Warning (Code 1264): Out of range value for column 'a' at row 1

INSERT INTO mediumints VALUES (8388607,8388608,8388608);

SELECT * FROM mediumints;
+---------+---------+----------+
| a       | b       | c        |
+---------+---------+----------+
|     -10 |       0 | 00000000 |
|     -10 |       0 | 00000000 |
|     -10 |      10 | 00000000 |
|     -10 |      10 | 00000010 |
| 8388607 | 8388608 | 08388608 |
| 8388607 | 8388608 | 08388608 |
+---------+---------+----------+

URL: https://mariadb.com/kb/en/mediumint/https://mariadb.com/kb/en/mediumint/
INTSyntax
------

INT[(M)] [SIGNED | UNSIGNED | ZEROFILL]
INTEGER[(M)] [SIGNED | UNSIGNED | ZEROFILL]

Description
-----------

A normal-size integer. When marked UNSIGNED, it ranges from 0 to 4294967295,
otherwise its range is -2147483648 to 2147483647 (SIGNED is the default). If a
column has been set to ZEROFILL, all values will be prepended by zeros so that
the INT value contains a number of M digits. INTEGER is a synonym for INT.

Note: If the ZEROFILL attribute has been specified, the column will
automatically become UNSIGNED.

INT4 is a synonym for INT.

For details on the attributes, see Numeric Data Type Overview.

Examples
--------

CREATE TABLE ints (a INT,b INT UNSIGNED,c INT ZEROFILL);

With strict_mode set, the default from MariaDB 10.2.4:

INSERT INTO ints VALUES (-10,-10,-10);
ERROR 1264 (22003): Out of range value for column 'b' at row 1

INSERT INTO ints VALUES (-10,10,-10);
ERROR 1264 (22003): Out of range value for column 'c' at row 1

INSERT INTO ints VALUES (-10,10,10);

INSERT INTO ints VALUES (2147483648,2147483648,2147483648);
ERROR 1264 (22003): Out of range value for column 'a' at row 1

INSERT INTO ints VALUES (2147483647,2147483648,2147483648);

SELECT * FROM ints;
+------------+------------+------------+
| a          | b          | c          |
+------------+------------+------------+
|        -10 |         10 | 0000000010 |
| 2147483647 | 2147483648 | 2147483648 |
+------------+------------+------------+

With strict_mode unset, the default until MariaDB 10.2.3:

INSERT INTO ints VALUES (-10,-10,-10);
Query OK, 1 row affected, 2 warnings (0.10 sec)
Warning (Code 1264): Out of range value for column 'b' at row 1
Warning (Code 1264): Out of range value for column 'c' at row 1

INSERT INTO ints VALUES (-10,10,-10);
Query OK, 1 row affected, 1 warning (0.08 sec)
Warning (Code 1264): Out of range value for column 'c' at row 1

INSERT INTO ints VALUES (-10,10,10);

INSERT INTO ints VALUES (2147483648,2147483648,2147483648);
Query OK, 1 row affected, 1 warning (0.07 sec)
Warning (Code 1264): Out of range value for column 'a' at row 1

INSERT INTO ints VALUES (2147483647,2147483648,2147483648);

SELECT * FROM ints;
+------------+------------+------------+
| a          | b          | c          |
+------------+------------+------------+
|        -10 |          0 | 0000000000 |
|        -10 |         10 | 0000000000 |
|        -10 |         10 | 0000000010 |
| 2147483647 | 2147483648 | 2147483648 |
| 2147483647 | 2147483648 | 2147483648 |
+------------+------------+------------+

URL: https://mariadb.com/kb/en/int/https://mariadb.com/kb/en/int/p*&#ST_IsSimpleSyntax
------

ST_IsSimple(g)
IsSimple(g)

Description
-----------

Returns true if the given Geometry has no anomalous geometric points, false if
it does, or NULL if given a NULL value.

ST_IsSimple() and IsSimple() are synonyms.

Examples
--------

A POINT is always simple.

SET @g = 'Point(1 2)';

SELECT ST_ISSIMPLE(GEOMFROMTEXT(@g));
+-------------------------------+
| ST_ISSIMPLE(GEOMFROMTEXT(@g)) |
+-------------------------------+
|                             1 |
+-------------------------------+

URL: https://mariadb.com/kb/en/st_issimple/https://mariadb.com/kb/en/st_issimple/q,+#ST_NUMGEOMETRIESSyntax
------

ST_NumGeometries(gc)
NumGeometries(gc)

Description
-----------

Returns the number of geometries in the GeometryCollection gc.

ST_NumGeometries() and NumGeometries() are synonyms.

Example
-------

SET @gc = 'GeometryCollection(Point(1 1),LineString(2 2, 3 3))';

SELECT NUMGEOMETRIES(GeomFromText(@gc));
+----------------------------------+
| NUMGEOMETRIES(GeomFromText(@gc)) |
+----------------------------------+
|                                2 |
+----------------------------------+

URL: https://mariadb.com/kb/en/st_numgeometries/https://mariadb.com/kb/en/st_numgeometries/r	�$#ST_RELATEMariaDB starting with 10.1.2
----------------------------
The ST_RELATE() function was introduced in MariaDB 10.1.2

Syntax
------

ST_Relate(g1, g2, i)

Description
-----------

Returns true if Geometry g1 is spatially related to Geometryg2 by testing for
intersections between the interior, boundary and exterior of the two
geometries as specified by the values in intersection matrix pattern i.

URL: https://mariadb.com/kb/en/st_relate/https://mariadb.com/kb/en/st_relate/s�"#ST_SRIDSyntax
------

ST_SRID(g)
SRID(g)

Description
-----------

Returns an integer indicating the Spatial Reference System ID for the geometry
value g.

In MariaDB, the SRID value is just an integer associated with the geometry
value. All calculations are done assuming Euclidean (planar) geometry.

ST_SRID() and SRID() are synonyms.

Examples
--------

SELECT SRID(GeomFromText('LineString(1 1,2 2)',101));
+-----------------------------------------------+
| SRID(GeomFromText('LineString(1 1,2 2)',101)) |
+-----------------------------------------------+
|                                           101 |
+-----------------------------------------------+

URL: https://mariadb.com/kb/en/st_srid/https://mariadb.com/kb/en/st_srid/}���u�il@
`L5����N!BIGINTSyntax
------

BIGINT[(M)] [SIGNED | UNSIGNED | ZEROFILL]

Description
-----------

A large integer. The signed range is -9223372036854775808 to
9223372036854775807. The unsigned range is 0 to 18446744073709551615.

If a column has been set to ZEROFILL, all values will be prepended by zeros so
that the BIGINT value contains a number of M digits.

Note: If the ZEROFILL attribute has been specified, the column will
automatically become UNSIGNED.

For more details on the attributes, see Numeric Data Type Overview.

SERIAL is an alias for:

BIGINT UNSIGNED NOT NULL AUTO_INCREMENT UNIQUE

INT8 is a synonym for BIGINT.

Examples
--------

CREATE TABLE bigints (a BIGINT,b BIGINT UNSIGNED,c BIGINT ZEROFILL);

With strict_mode set, the default from MariaDB 10.2.4:

INSERT INTO bigints VALUES (-10,-10,-10);
ERROR 1264 (22003): Out of range value for column 'b' at row 1

INSERT INTO bigints VALUES (-10,10,-10);
ERROR 1264 (22003): Out of range value for column 'c' at row 1

INSERT INTO bigints VALUES (-10,10,10);

INSERT INTO bigints VALUES
(9223372036854775808,9223372036854775808,9223372036854775808);
ERROR 1264 (22003): Out of range value for column 'a' at row 1

INSERT INTO bigints VALUES
(9223372036854775807,9223372036854775808,9223372036854775808);

SELECT * FROM bigints;
+---------------------+---------------------+----------------------+
| a                   | b                   | c                    |
+---------------------+---------------------+----------------------+
|                 -10 |                  10 | 00000000000000000010 |
| 9223372036854775807 | 9223372036854775808 | 09223372036854775808 |
+---------------------+---------------------+----------------------+

With strict_mode unset, the default until MariaDB 10.2.3:

INSERT INTO bigints VALUES (-10,-10,-10);
Query OK, 1 row affected, 2 warnings (0.08 sec)
Warning (Code 1264): Out of range value for column 'b' at row 1
Warning (Code 1264): Out of range value for column 'c' at row 1

INSERT INTO bigints VALUES (-10,10,-10);
Query OK, 1 row affected, 1 warning (0.08 sec)
Warning (Code 1264): Out of range value for column 'c' at row 1

INSERT INTO bigints VALUES (-10,10,10);

INSERT INTO bigints VALUES
(9223372036854775808,9223372036854775808,9223372036854775808);
Query OK, 1 row affected, 1 warning (0.07 sec)
Warning (Code 1264): Out of range value for column 'a' at row 1

INSERT INTO bigints VALUES
(9223372036854775807,9223372036854775808,9223372036854775808);

SELECT * FROM bigints;
+---------------------+---------------------+----------------------+
| a                   | b                   | c                    |
+---------------------+---------------------+----------------------+
|                 -10 |                   0 | 00000000000000000000 |
|                 -10 |                  10 | 00000000000000000000 |
|                 -10 |                  10 | 00000000000000000010 |
| 9223372036854775807 | 9223372036854775808 | 09223372036854775808 |
| 9223372036854775807 | 9223372036854775808 | 09223372036854775808 |
+---------------------+---------------------+----------------------+

URL: https://mariadb.com/kb/en/bigint/https://mariadb.com/kb/en/bigint/	e"DECIMALSyntax
------

DECIMAL[(M[,D])] [SIGNED | UNSIGNED | ZEROFILL]

Description
-----------

A packed "exact" fixed-point number. M is the total number of digits (the
precision) and D is the number of digits after the decimal point (the scale).

* The decimal point and (for negative numbers) the "-" sign are not
counted in M. 
* If D is 0, values have no decimal point or fractional
part and on INSERT the value will be rounded to the nearest DECIMAL. 
* The maximum number of digits (M) for DECIMAL is 65. 
* The maximum number of supported decimals (D) is 30 before MariadB 10.2.1 and
38 afterwards. 
* If D is omitted, the default is 0. If M is omitted, the default is 10.

UNSIGNED, if specified, disallows negative values.

ZEROFILL, if specified, pads the number with zeros, up to the total number of
digits specified by M.

All basic calculations (+, -, *, /) with DECIMAL columns are done with a
precision of 65 digits.

For more details on the attributes, see Numeric Data Type Overview.

DEC, NUMERIC and FIXED are synonyms, as well as NUMBER in Oracle mode from
MariaDB 10.3.

Examples
--------

CREATE TABLE t1 (d DECIMAL UNSIGNED ZEROFILL);

INSERT INTO t1 VALUES (1),(2),(3),(4.0),(5.2),(5.7);
Query OK, 6 rows affected, 2 warnings (0.16 sec)
Records: 6  Duplicates: 0  Warnings: 2

Note (Code 1265): Data truncated for column 'd' at row 5
Note (Code 1265): Data truncated for column 'd' at row 6

SELECT * FROM t1;
+------------+
| d          |
+------------+
| 0000000001 |
| 0000000002 |
| 0000000003 |
| 0000000004 |
| 0000000005 |
| 0000000006 |
+------------+

With strict_mode set, the default from MariaDB 10.2.4:

INSERT INTO t1 VALUES (-7);
ERROR 1264 (22003): Out of range value for column 'd' at row 1

With strict_mode unset, the default until MariaDB 10.2.3:

INSERT INTO t1 VALUES (-7);
Query OK, 1 row affected, 1 warning (0.02 sec)
Warning (Code 1264): Out of range value for column 'd' at row 1

SELECT * FROM t1;
+------------+
| d          |
+------------+
| 0000000001 |
| 0000000002 |
| 0000000003 |
| 0000000004 |
| 0000000005 |
| 0000000006 |
| 0000000000 |
+------------+

URL: https://mariadb.com/kb/en/decimal/https://mariadb.com/kb/en/decimal/u
�%$NOT REGEXPSyntax
------

expr NOT REGEXP pat, expr NOT RLIKE pat

Description
-----------

This is the same as NOT (expr REGEXP pat).

URL: https://mariadb.com/kb/en/not-regexp/https://mariadb.com/kb/en/not-regexp/z@ $ASCIISyntax
------

ASCII(str)

Description
-----------

Returns the numeric ASCII value of the leftmost character of the string
argument. Returns 0 if the given string is empty and NULL if it is NULL.

ASCII() works for 8-bit characters.

Examples
--------

SELECT ASCII(9);
+----------+
| ASCII(9) |
+----------+
|       57 |
+----------+

SELECT ASCII('9');
+------------+
| ASCII('9') |
+------------+
|         57 |
+------------+

SELECT ASCII('abc');
+--------------+
| ASCII('abc') |
+--------------+
|           97 |
+--------------+

URL: https://mariadb.com/kb/en/ascii/https://mariadb.com/kb/en/ascii/{�$BINSyntax
------

BIN(N)

Description
-----------

Returns a string representation of the binary value of the given longlong
(that is, BIGINT) number. This is equivalent to CONV(N,10,2). The argument
should be positive. If it is a FLOAT, it will be truncated. Returns NULL if
the argument is NULL.

Examples
--------

SELECT BIN(12);
+---------+
| BIN(12) |
+---------+
| 1100    |
+---------+

URL: https://mariadb.com/kb/en/bin/https://mariadb.com/kb/en/bin/}
k%$BIT_LENGTHSyntax
------

BIT_LENGTH(str)

Description
-----------

Returns the length of the given string argument in bits. If the argument is
not a string, it will be converted to string. If the argument is NULL, it
returns NULL.

Examples
--------

SELECT BIT_LENGTH('text');
+--------------------+
| BIT_LENGTH('text') |
+--------------------+
|                 32 |
+--------------------+

SELECT BIT_LENGTH('');
+----------------+
| BIT_LENGTH('') |
+----------------+
|              0 |
+----------------+

Compatibility
-------------

PostgreSQL and Sybase support BIT_LENGTH().

URL: https://mariadb.com/kb/en/bit_length/https://mariadb.com/kb/en/bit_length/\���s+�����)��
� FLOATSyntax
------

FLOAT[(M,D)] [SIGNED | UNSIGNED | ZEROFILL]

Description
-----------

A small (single-precision) floating-point number (see DOUBLE for a
regular-size floating point number). Allowable values are:

* -3.402823466E+38 to -1.175494351E-38
* 0
* 1.175494351E-38 to 3.402823466E+38.

These are the theoretical limits, based on the IEEE standard. The actual range
might be slightly smaller depending on your hardware or operating system.

M is the total number of digits and D is the number of digits following the
decimal point. If M and D are omitted, values are stored to the limits allowed
by the hardware. A single-precision floating-point number is accurate to
approximately 7 decimal places.

UNSIGNED, if specified, disallows negative values.

Using FLOAT might give you some unexpected problems because all calculations
in MariaDB are done with double precision. See Floating Point Accuracy.

For more details on the attributes, see Numeric Data Type Overview.

URL: https://mariadb.com/kb/en/float/https://mariadb.com/kb/en/float/!DOUBLESyntax
------

DOUBLE[(M,D)] [SIGNED | UNSIGNED | ZEROFILL]
DOUBLE PRECISION[(M,D)] [SIGNED | UNSIGNED | ZEROFILL]
REAL[(M,D)] [SIGNED | UNSIGNED | ZEROFILL]

Description
-----------

A normal-size (double-precision) floating-point number (see FLOAT for a
single-precision floating-point number).

Allowable values are:

* -1.7976931348623157E+308 to -2.2250738585072014E-308
* 0
* 2.2250738585072014E-308 to 1.7976931348623157E+308

These are the theoretical limits, based on the IEEE standard. The actual range
might be slightly smaller depending on your hardware or operating system.

M is the total number of digits and D is the number of digits following the
decimal point. If M and D are omitted, values are stored to the limits allowed
by the hardware. A double-precision floating-point number is accurate to
approximately 15 decimal places.

UNSIGNED, if specified, disallows negative values.

ZEROFILL, if specified, pads the number with zeros, up to the total number of
digits specified by M.

REAL and DOUBLE PRECISION are synonyms, unless the REAL_AS_FLOAT SQL mode is
enabled, in which case REAL is a synonym for FLOAT rather than DOUBLE.

See Floating Point Accuracy for issues when using floating-point numbers.

For more details on the attributes, see Numeric Data Type Overview.

Examples
--------

CREATE TABLE t1 (d DOUBLE(5,0) zerofill);

INSERT INTO t1 VALUES (1),(2),(3),(4);

SELECT * FROM t1;
+-------+
| d     |
+-------+
| 00001 |
| 00002 |
| 00003 |
| 00004 |
+-------+

URL: https://mariadb.com/kb/en/double/https://mariadb.com/kb/en/double/�BITSyntax
------

BIT[(M)]

Description
-----------

A bit-field type. M indicates the number of bits per value, from 1 to 64. The
default is 1 if M is omitted.

Bit values can be inserted with b'value' notation, where value is the bit
value in 0's and 1's.

Bit fields are automatically zero-padded from the left to the full length of
the bit, so for example in a BIT(4) field, '10' is equivalent to '0010'.

Bits are returned as binary, so to display them, either add 0, or use a
function such as HEX, OCT or BIN to convert them.

Examples
--------

CREATE TABLE b ( b1 BIT(8) );

With strict_mode set, the default from MariaDB 10.2.4:

INSERT INTO b VALUES (b'11111111');

INSERT INTO b VALUES (b'01010101');

INSERT INTO b VALUES (b'1111111111111');
ERROR 1406 (22001): Data too long for column 'b1' at row 1

SELECT b1+0, HEX(b1), OCT(b1), BIN(b1) FROM b;
+------+---------+---------+----------+
| b1+0 | HEX(b1) | OCT(b1) | BIN(b1)  |
+------+---------+---------+----------+
|  255 | FF      | 377     | 11111111 |
|   85 | 55      | 125     | 1010101  |
+------+---------+---------+----------+

With strict_mode unset, the default until MariaDB 10.2.3:

INSERT INTO b VALUES (b'11111111'),(b'01010101'),(b'1111111111111');
Query OK, 3 rows affected, 1 warning (0.10 sec)
Records: 3  Duplicates: 0  Warnings: 1

SHOW WARNINGS;
+---------+------+---------------------------------------------+
| Level   | Code | Message                                     |
+---------+------+---------------------------------------------+
| Warning | 1264 | Out of range value for column 'b1' at row 3 |
+---------+------+---------------------------------------------+

SELECT b1+0, HEX(b1), OCT(b1), BIN(b1) FROM b;
+------+---------+---------+----------+
| b1+0 | HEX(b1) | OCT(b1) | BIN(b1)  |
+------+---------+---------+----------+
|  255 | FF      | 377     | 11111111 |
|   85 | 55      | 125     | 1010101  |
|  255 | FF      | 377     | 11111111 |
+------+---------+---------+----------+

URL: https://mariadb.com/kb/en/bit/https://mariadb.com/kb/en/bit/
�2Floating-point AccuracyDue to their nature, not all floating-point numbers can be stored with exact
precision. Hardware architecture, the CPU or even the compiler version and
optimization level may affect the precision.

If you are comparing DOUBLEs or FLOATs with numeric decimals, it is not safe
to use the equality operator.

Sometimes, changing a floating-point number from single-precision (FLOAT) to
double-precision (DOUBLE) will fix the problem.

Example
-------

f1, f2 and f3 have seemingly identical values across each row, but due to
floating point accuracy, the results may be unexpected.

CREATE TABLE fpn (id INT, f1 FLOAT, f2 DOUBLE, f3 DECIMAL (10,3));
INSERT INTO fpn VALUES (1,2,2,2),(2,0.1,0.1,0.1);

SELECT * FROM fpn WHERE f1*f1 = f2*f2;
+------+------+------+-------+
| id   | f1   | f2   | f3    |
+------+------+------+-------+
|    1 |    2 |    2 | 2.000 |
+------+------+------+-------+

The reason why only one instead of two rows was returned becomes clear when we
see how the floating point squares were evaluated.

SELECT f1*f1, f2*f2, f3*f3 FROM fpn;
+----------------------+----------------------+----------+
| f1*f1                | f2*f2                | f3*f3    |
+----------------------+----------------------+----------+
|                    4 |                    4 | 4.000000 |
| 0.010000000298023226 | 0.010000000000000002 | 0.010000 |
+----------------------+----------------------+----------+

URL: https://mariadb.com/kb/en/floating-point-accuracy/https://mariadb.com/kb/en/floating-point-accuracy/�� $INSTRSyntax
------

INSTR(str,substr)

Description
-----------

Returns the position of the first occurrence of substring substr in string
str. This is the same as the two-argument form of LOCATE(), except that the
order of the arguments is reversed.

INSTR() performs a case-insensitive search.

If any argument is NULL, returns NULL.

Examples
--------

SELECT INSTR('foobarbar', 'bar');
+---------------------------+
| INSTR('foobarbar', 'bar') |
+---------------------------+
|                         4 |
+---------------------------+

SELECT INSTR('My', 'Maria');
+----------------------+
| INSTR('My', 'Maria') |
+----------------------+
|                    0 |
+----------------------+

URL: https://mariadb.com/kb/en/instr/https://mariadb.com/kb/en/instr/�| $LCASESyntax
------

LCASE(str)

Description
-----------

LCASE() is a synonym for LOWER().

URL: https://mariadb.com/kb/en/lcase/https://mariadb.com/kb/en/lcase/�X$LEFTSyntax
------

LEFT(str,len)

Description
-----------

Returns the leftmost len characters from the string str, or NULL if any
argument is NULL.

Examples
--------

SELECT LEFT('MariaDB', 5);
+--------------------+
| LEFT('MariaDB', 5) |
+--------------------+
| Maria              |
+--------------------+

URL: https://mariadb.com/kb/en/left/https://mariadb.com/kb/en/left/O����m
85,�p����!BINARYThis page describes the BINARY data type. For details about the operator, see
Binary Operator.

Syntax
------

BINARY(M)

Description
-----------

The BINARY type is similar to the CHAR type, but stores binary byte strings
rather than non-binary character strings. M represents the column length in
bytes.

It contains no character set, and comparison and sorting are based on the
numeric value of the bytes.

If the maximum length is exceeded, and SQL strict mode is not enabled , the
extra characters will be dropped with a warning. If strict mode is enabled, an
error will occur.

BINARY values are right-padded with 0x00 (the zero byte) to the specified
length when inserted. The padding is not removed on select, so this needs to
be taken into account when sorting and comparing, where all bytes are
significant. The zero byte, 0x00 is less than a space for comparison purposes.

Examples
--------

Inserting too many characters, first with strict mode off, then with it on:

CREATE TABLE bins (a BINARY(10));

INSERT INTO bins VALUES('12345678901');
Query OK, 1 row affected, 1 warning (0.04 sec)

SELECT * FROM bins;
+------------+
| a          |
+------------+
| 1234567890 |
+------------+

SET sql_mode='STRICT_ALL_TABLES';

INSERT INTO bins VALUES('12345678901');
ERROR 1406 (22001): Data too long for column 'a' at row 1

Sorting is performed with the byte value:

TRUNCATE bins;

INSERT INTO bins VALUES('A'),('B'),('a'),('b');

SELECT * FROM bins ORDER BY a;
+------+
| a    |
+------+
| A    |
| B    |
| a    |
| b    |
+------+

Using CAST to sort as a CHAR instead:

SELECT * FROM bins ORDER BY CAST(a AS CHAR);
+------+
| a    |
+------+
| a    |
| A    |
| b    |
| B    |
+------+

The field is a BINARY(10), so padding of two '\0's are inserted, causing
comparisons that don't take this into account to fail:

TRUNCATE bins;

INSERT INTO bins VALUES('12345678');

SELECT a = '12345678', a = '12345678\0\0' from bins;
+----------------+--------------------+
| a = '12345678' | a = '12345678\0\0' |
+----------------+--------------------+
|              0 |                  1 |
+----------------+--------------------+

URL: https://mariadb.com/kb/en/binary/https://mariadb.com/kb/en/binary/�BLOBSyntax
------

BLOB[(M)]

Description
-----------

A BLOB column with a maximum length of 65,535 (216 - 1) bytes. Each BLOB value
is stored using a two-byte length prefix that indicates the number of bytes in
the value.

An optional length M can be given for this type. If this is done, MariaDB
creates the column as the smallest BLOB type large enough to hold values M
bytes long.

BLOBS can also be used to store dynamic columns.

BLOB and TEXT columns can both be assigned a DEFAULT value.

Indexing
--------

MariaDB starting with 10.4
--------------------------
From MariaDB 10.4, it is possible to set a unique index on a column that uses
the BLOB data type. In previous releases this was not possible, as the index
would only guarantee the uniqueness of a fixed number of characters.

Oracle Mode
-----------

In Oracle mode from MariaDB 10.3, BLOB is a synonym for LONGBLOB.

URL: https://mariadb.com/kb/en/blob/https://mariadb.com/kb/en/blob/�CHARThis article covers the CHAR data type. See CHAR Function for the function.

Syntax
------

[NATIONAL] CHAR[(M)] [CHARACTER SET charset_name] [COLLATE collation_name]

Description
-----------

A fixed-length string that is always right-padded with spaces to the specified
length when stored. M represents the column length in characters. The range of
M is 0 to 255. If M is omitted, the length is 1.

CHAR(0) columns can contain 2 values: an empty string or NULL. Such columns
cannot be part of an index. The CONNECT storage engine does not support
CHAR(0).

Note: Trailing spaces are removed when CHAR values are retrieved unless the
PAD_CHAR_TO_FULL_LENGTH SQL mode is enabled.

Before MariaDB 10.2, all collations were of type PADSPACE, meaning that CHAR
(as well as VARCHAR and TEXT) values are compared without regard for trailing
spaces. This does not apply to the LIKE pattern-matching operator, which takes
into account trailing spaces.

If a unique index consists of a column where trailing pad characters are
stripped or ignored, inserts into that column where values differ only by the
number of trailing pad characters will result in a duplicate-key error.

Examples
--------

Trailing spaces:

CREATE TABLE strtest (c CHAR(10));
INSERT INTO strtest VALUES('Maria   ');

SELECT c='Maria',c='Maria   ' FROM strtest;
+-----------+--------------+
| c='Maria' | c='Maria   ' |
+-----------+--------------+
|         1 |            1 |
+-----------+--------------+

SELECT c LIKE 'Maria',c LIKE 'Maria   ' FROM strtest;
+----------------+-------------------+
| c LIKE 'Maria' | c LIKE 'Maria   ' |
+----------------+-------------------+
|              1 |                 0 |
+----------------+-------------------+

NO PAD Collations
-----------------

NO PAD collations regard trailing spaces as normal characters. You can get a
list of all NO PAD collations by querying the Information Schema Collations
table, for example:

SELECT collation_name FROM information_schema.collations 
 WHERE collation_name LIKE "%nopad%";
+------------------------------+
| collation_name               |
+------------------------------+
| big5_chinese_nopad_ci        |
| big5_nopad_bin               |
...

URL: https://mariadb.com/kb/en/char/https://mariadb.com/kb/en/char/�G$MIDSyntax
------

MID(str,pos,len)

Description
-----------

MID(str,pos,len) is a synonym for SUBSTRING(str,pos,len).

Examples
--------

SELECT MID('abcd',4,1);
+-----------------+
| MID('abcd',4,1) |
+-----------------+
| d               |
+-----------------+

SELECT MID('abcd',2,2);
+-----------------+
| MID('abcd',2,2) |
+-----------------+
| bc              |
+-----------------+

A negative starting position:

SELECT MID('abcd',-2,4);
+------------------+
| MID('abcd',-2,4) |
+------------------+
| cd               |
+------------------+

URL: https://mariadb.com/kb/en/mid/https://mariadb.com/kb/en/mid/��#$NOT LIKESyntax
------

expr NOT LIKE pat [ESCAPE 'escape_char']

Description
-----------

This is the same as NOT (expr LIKE pat [ESCAPE 'escape_char']).

URL: https://mariadb.com/kb/en/not-like/https://mariadb.com/kb/en/not-like/�3$ORDSyntax
------

ORD(str)

Description
-----------

If the leftmost character of the string str is a multi-byte character, returns
the code for that character, calculated from the numeric values of its
constituent bytes using this formula:

(1st byte code)
+ (2nd byte code x 256)
+ (3rd byte code x 256 x 256) ...

If the leftmost character is not a multi-byte character, ORD() returns the
same value as the ASCII() function.

Examples
--------

SELECT ORD('2');
+----------+
| ORD('2') |
+----------+
|       50 |
+----------+

URL: https://mariadb.com/kb/en/ord/https://mariadb.com/kb/en/ord/��#$POSITIONSyntax
------

POSITION(substr IN str)

Description
-----------

POSITION(substr IN str) is a synonym for LOCATE(substr,str).

It's part of ODBC 3.0.

URL: https://mariadb.com/kb/en/position/https://mariadb.com/kb/en/position/�� $QUOTESyntax
------

QUOTE(str)

Description
-----------

Quotes a string to produce a result that can be used as a properly escaped
data value in an SQL statement. The string is returned enclosed by single
quotes and with each instance of single quote ("'"), backslash ("\"), ASCII
NUL, and Control-Z preceded by a backslash. If the argument is NULL, the
return value is the word "NULL" without enclosing single quotes.

Examples
--------

SELECT QUOTE("Don't!");
+-----------------+
| QUOTE("Don't!") |
+-----------------+
| 'Don\'t!'       |
+-----------------+

SELECT QUOTE(NULL); 
+-------------+
| QUOTE(NULL) |
+-------------+
| NULL        |
+-------------+

URL: https://mariadb.com/kb/en/quote/https://mariadb.com/kb/en/quote/=�E��b��yv�����38����[ENUMSyntax
------

ENUM('value1','value2',...) [CHARACTER SET charset_name] [COLLATE
collation_name]

Description
-----------

An enumeration. A string object that can have only one value, chosen from the
list of values 'value1', 'value2', ..., NULL or the special '' error value. In
theory, an ENUM column can have a maximum of 65,535 distinct values; in
practice, the real maximum depends on many factors. ENUM values are
represented internally as integers.

Trailing spaces are automatically stripped from ENUM values on table creation.

ENUMs require relatively little storage space compared to strings, either one
or two bytes depending on the number of enumeration values.

NULL and empty values
---------------------

An ENUM can also contain NULL and empty values. If the ENUM column is declared
to permit NULL values, NULL becomes a valid value, as well as the default
value (see below). If strict SQL Mode is not enabled, and an invalid value is
inserted into an ENUM, a special empty string, with an index value of zero
(see Numeric index, below), is inserted, with a warning. This may be
confusing, because the empty string is also a possible value, and the only
difference if that is this case its index is not 0. Inserting will fail with
an error if strict mode is active.

If a DEFAULT clause is missing, the default value will be:

* NULL if the column is nullable;
* otherwise, the first value in the enumeration.

Numeric index
-------------

ENUM values are indexed numerically in the order they are defined, and sorting
will be performed in this numeric order. We suggest not using ENUM to store
numerals, as there is little to no storage space benefit, and it is easy to
confuse the enum integer with the enum numeral value by leaving out the quotes.

An ENUM defined as ENUM('apple','orange','pear') would have the following
index values:

+--------------------------------------+--------------------------------------+
| Index                                | Value                                |
+--------------------------------------+--------------------------------------+
| NULL                                 | NULL                                 |
+--------------------------------------+--------------------------------------+
| 0                                    | ''                                   |
+--------------------------------------+--------------------------------------+
| 1                                    | 'apple'                              |
+--------------------------------------+--------------------------------------+
| 2                                    | 'orange'                             |
+--------------------------------------+--------------------------------------+
| 3                                    | 'pear'                               |
+--------------------------------------+--------------------------------------+

Examples
--------

CREATE TABLE fruits (
 id INT NOT NULL auto_increment PRIMARY KEY,
 fruit ENUM('apple','orange','pear'),
 bushels INT);

DESCRIBE fruits;
+---------+-------------------------------+------+-----+---------+-------------
--+
| Field   | Type                          | Null | Key | Default | Extra      
 |
+---------+-------------------------------+------+-----+---------+-------------
--+
| id      | int(11)                       | NO   | PRI | NULL    |
auto_increment |
| fruit   | enum('apple','orange','pear') | YES  |     | NULL    |            
 |
| bushels | int(11)                       | YES  |     | NULL    |            
 |
+---------+-------------------------------+------+-----+---------+-------------
--+

INSERT INTO fruits
  (fruit,bushels) VALUES
  ('pear',20),
  ('apple',100),
  ('orange',25);

INSERT INTO fruits
  (fruit,bushels) VALUES
  ('avocado',10);
ERROR 1265 (01000): Data truncated for column 'fruit' at row 1

SELECT * FROM fruits;
+----+--------+---------+
| id | fruit  | bushels |
+----+--------+---------+
|  1 | pear   |      20 |
|  2 | apple  |     100 |
|  3 | orange |      25 |
+----+--------+---------+

Selecting by numeric index:

SELECT * FROM fruits WHERE fruit=2;
+----+--------+---------+
| id | fruit  | bushels |
+----+--------+---------+
|  3 | orange |      25 |
+----+--------+---------+

Sorting is according to the index value:

CREATE TABLE enums (a ENUM('2','1'));

INSERT INTO enums VALUES ('1'),('2');

SELECT * FROM enums ORDER BY a ASC;
+------+
| a    |
+------+
| 2    |
| 1    |
+------+

It's easy to get confused between returning the enum integer with the stored
value, so we don't suggest using ENUM to store numerals. The first example
returns the 1st indexed field ('2' has an index value of 1, as it's defined
first), while the second example returns the string value '1'.

SELECT * FROM enums WHERE a=1;
+------+
| a    |
+------+
| 2    |
+------+

SELECT * FROM enums WHERE a='1';
+------+
| a    |
+------+
| 1    |
+------+

URL: https://mariadb.com/kb/en/enum/https://mariadb.com/kb/en/enum/�*$REPEAT FunctionSyntax
------

REPEAT(str,count)

Description
-----------

Returns a string consisting of the string str repeated count times. If count
is less than 1, returns an empty string. Returns NULL if str or count are NULL.

Examples
--------

SELECT QUOTE(REPEAT('MariaDB ',4));
+------------------------------------+
| QUOTE(REPEAT('MariaDB ',4))        |
+------------------------------------+
| 'MariaDB MariaDB MariaDB MariaDB ' |
+------------------------------------+

URL: https://mariadb.com/kb/en/repeat-function/https://mariadb.com/kb/en/repeat-function/�4+$REPLACE FunctionSyntax
------

REPLACE(str,from_str,to_str)

Description
-----------

Returns the string str with all occurrences of the string from_str replaced by
the string to_str. REPLACE() performs a case-sensitive match when searching
for from_str.

Examples
--------

SELECT REPLACE('www.mariadb.org', 'w', 'Ww');
+---------------------------------------+
| REPLACE('www.mariadb.org', 'w', 'Ww') |
+---------------------------------------+
| WwWwWw.mariadb.org                    |
+---------------------------------------+

URL: https://mariadb.com/kb/en/replace-function/https://mariadb.com/kb/en/replace-function/�H"$REVERSESyntax
------

REVERSE(str)

Description
-----------

Returns the string str with the order of the characters reversed.

Examples
--------

SELECT REVERSE('desserts');
+---------------------+
| REVERSE('desserts') |
+---------------------+
| stressed            |
+---------------------+

URL: https://mariadb.com/kb/en/reverse/https://mariadb.com/kb/en/reverse/�a $RIGHTSyntax
------

RIGHT(str,len)

Description
-----------

Returns the rightmost len characters from the string str, or NULL if any
argument is NULL.

Examples
--------

SELECT RIGHT('MariaDB', 2);
+---------------------+
| RIGHT('MariaDB', 2) |
+---------------------+
| DB                  |
+---------------------+

URL: https://mariadb.com/kb/en/right/https://mariadb.com/kb/en/right/�w&$SOUNDS LIKESyntax
------

expr1 SOUNDS LIKE expr2

Description
-----------

This is the same as SOUNDEX(expr1) = SOUNDEX(expr2).

Example
-------

SELECT givenname, surname FROM users WHERE givenname SOUNDS LIKE "robert";
+-----------+---------+
| givenname | surname |
+-----------+---------+
| Roberto   | Castro  |
+-----------+---------+

URL: https://mariadb.com/kb/en/sounds-like/https://mariadb.com/kb/en/sounds-like/r���_�}�J��I��GV INET4MariaDB starting with 10.10.0
-----------------------------
The INET4 data type was added in MariaDB 10.10.0

Syntax
------

INET4

Description
-----------

INET4 is a data type to store IPv4 addresses, as 4-byte binary strings.

Examples
--------

CREATE OR REPLACE TABLE t1 (a INET4);

INSERT INTO t1 VALUES('0.0.0.0'), ('255.10.0.0'), ('255.255.255.255');

INSERT INTO t1 VALUES (0xa0000001);
INSERT INTO t1 VALUES (0xf0000000);
INSERT INTO t1 VALUES (0xff000001);

SELECT HEX(a), a FROM t1 ORDER BY a;
+----------+-----------------+
| HEX(a)   | a               |
+----------+-----------------+
| 00000000 | 0.0.0.0         |
| A0000001 | 160.0.0.1       |
| F0000000 | 240.0.0.0       |
| FF000001 | 255.0.0.1       |
| FF0A0000 | 255.10.0.0      |
| FFFFFFFF | 255.255.255.255 |
+----------+-----------------+

URL: https://mariadb.com/kb/en/inet4/https://mariadb.com/kb/en/inet4/)JSON Data TypeThe JSON alias was added to make it possible to use JSON columns in statement
based replication from MySQL to MariaDB and to make it possible for MariaDB to
read mysqldumps from MySQL.

JSON is an alias for LONGTEXT introduced for compatibility reasons with
MySQL's JSON data type. MariaDB implements this as a LONGTEXT rather, as the
JSON data type contradicts the SQL standard, and MariaDB's benchmarks indicate
that performance is at least equivalent.

In order to ensure that a a valid json document is inserted, the JSON_VALID
function can be used as a CHECK constraint. This constraint is automatically
included for types using the JSON alias from MariaDB 10.4.3.

Examples
--------

CREATE TABLE t (j JSON);

DESC t;
+-------+----------+------+-----+---------+-------+
| Field | Type     | Null | Key | Default | Extra |
+-------+----------+------+-----+---------+-------+
| j     | longtext | YES  |     | NULL    |       |
+-------+----------+------+-----+---------+-------+

With validation:

CREATE TABLE t2 (
 j JSON
 CHECK (JSON_VALID(j))
);

INSERT INTO t2 VALUES ('invalid');
ERROR 4025 (23000): CONSTRAINT `j` failed for `test`.`t2`

INSERT INTO t2 VALUES ('{"id": 1, "name": "Monty"}');
Query OK, 1 row affected (0.13 sec)

Replicating JSON Data Between MySQL and MariaDB
-----------------------------------------------

The JSON type in MySQL stores the JSON object in a compact form, not as
LONGTEXT as in MariaDB. This means that row based replication will not work
for JSON types from MySQL to MariaDB.

There are a a few different ways to solve this:

* Use statement based replication.
* Change the JSON column to type TEXT in MySQL
* If you must use row-based replication and cannot change the MySQL master
from JSON to TEXT, you can try to introduce an intermediate MySQL slave and
change the column type from JSON to TEXT on it. Then you replicate from this
intermediate slave to MariaDB.

Converting a MySQL TABLE with JSON Fields to MariaDB
----------------------------------------------------

MariaDB can't directly access MySQL's JSON format.

There are a a few different ways to move the table to MariaDB:

* From MariaDB 10.5.7, see the you can use the mysql_json plugin. See Making
MariaDB understand MySQL JSON.
* Change the JSON column to type TEXT in MySQL.  After this, MariaDB can
directly use the table without any need for a dump and restore.
* Use mysqldump to copy the table.

Differences Between MySQL JSON Strings and MariaDB JSON Strings
---------------------------------------------------------------

* In MySQL, JSON is an object and is compared according to json values. In
MariaDB JSON strings are normal strings and compared as strings. One exception
is when using JSON_EXTRACT() in which case strings are unescaped before
comparison.

URL: https://mariadb.com/kb/en/json-data-type/https://mariadb.com/kb/en/json-data-type/##LONGTEXTSyntax
------

LONGTEXT [CHARACTER SET charset_name] [COLLATE collation_name]

Description
-----------

A TEXT column with a maximum length of 4,294,967,295 or 4GB (232 - 1)
characters. The effective maximum length is less if the value contains
multi-byte characters. The effective maximum length of LONGTEXT columns also
depends on the configured maximum packet size in the client/server protocol
and available memory. Each LONGTEXT value is stored using a four-byte length
prefix that indicates the number of bytes in the value.

From MariaDB 10.2.7, JSON is an alias for LONGTEXT. See JSON Data Type for
details.

Oracle Mode
-----------

MariaDB starting with 10.3
--------------------------
In Oracle mode from MariaDB 10.3, CLOB is a synonym for LONGTEXT.

URL: https://mariadb.com/kb/en/longtext/https://mariadb.com/kb/en/longtext/	H$VARBINARYSyntax
------

VARBINARY(M)

Description
-----------

The VARBINARY type is similar to the VARCHAR type, but stores binary byte
strings rather than non-binary character strings. M represents the maximum
column length in bytes.

It contains no character set, and comparison and sorting are based on the
numeric value of the bytes.

If the maximum length is exceeded, and SQL strict mode is not enabled , the
extra characters will be dropped with a warning. If strict mode is enabled, an
error will occur.

Unlike BINARY values, VARBINARYs are not right-padded when inserting.

Oracle Mode
-----------

MariaDB starting with 10.3
--------------------------
In Oracle mode from MariaDB 10.3, RAW is a synonym for VARBINARY.

Examples
--------

Inserting too many characters, first with strict mode off, then with it on:

CREATE TABLE varbins (a VARBINARY(10));

INSERT INTO varbins VALUES('12345678901');
Query OK, 1 row affected, 1 warning (0.04 sec)

SELECT * FROM varbins;
+------------+
| a          |
+------------+
| 1234567890 |
+------------+

SET sql_mode='STRICT_ALL_TABLES';

INSERT INTO varbins VALUES('12345678901');
ERROR 1406 (22001): Data too long for column 'a' at row 1

Sorting is performed with the byte value:

TRUNCATE varbins;

INSERT INTO varbins VALUES('A'),('B'),('a'),('b');

SELECT * FROM varbins ORDER BY a;
+------+
| a    |
+------+
| A    |
| B    |
| a    |
| b    |
+------+

Using CAST to sort as a CHAR instead:

SELECT * FROM varbins ORDER BY CAST(a AS CHAR);
+------+
| a    |
+------+
| a    |
| A    |
| b    |
| B    |
+------+

URL: https://mariadb.com/kb/en/varbinary/https://mariadb.com/kb/en/varbinary/�7 $SPACESyntax
------

SPACE(N)

Description
-----------

Returns a string consisting of N space characters. If N is NULL, returns NULL.

Examples
--------

SELECT QUOTE(SPACE(6));
+-----------------+
| QUOTE(SPACE(6)) |
+-----------------+
| '      '        |
+-----------------+

URL: https://mariadb.com/kb/en/space/https://mariadb.com/kb/en/space/�g!$SUBSTRDescription
-----------

SUBSTR() is a synonym for SUBSTRING().

URL: https://mariadb.com/kb/en/substr/https://mariadb.com/kb/en/substr/�| $UCASESyntax
------

UCASE(str)

Description
-----------

UCASE() is a synonym for UPPER().

URL: https://mariadb.com/kb/en/ucase/https://mariadb.com/kb/en/ucase/�� $UPPERSyntax
------

UPPER(str)

Description
-----------

Returns the string str with all characters changed to uppercase according to
the current character set mapping. The default is latin1 (cp1252 West
European).

SELECT UPPER(surname), givenname FROM users ORDER BY surname;
+----------------+------------+
| UPPER(surname) | givenname  |
+----------------+------------+
| ABEL           | Jacinto    |
| CASTRO         | Robert     |
| COSTA          | Phestos    |
| MOSCHELLA      | Hippolytos |
+----------------+------------+

UPPER() is ineffective when applied to binary strings (BINARY, VARBINARY,
BLOB). The description of LOWER() shows how to perform lettercase conversion
of binary strings.

URL: https://mariadb.com/kb/en/upper/https://mariadb.com/kb/en/upper/���5��jH��\�W�f߂����ROWMariaDB starting with 10.3.0
----------------------------
The ROW data type was introduced in MariaDB 10.3.0.

Syntax
------

ROW (<field name> <data type> [{, <field name> <data type>}... ])

Description
-----------

ROW is a data type for stored procedure variables.

Features
--------

ROW fields as normal variables
------------------------------

ROW fields (members) act as normal variables, and are able to appear in all
query parts where a stored procedure variable is allowed:

* Assignment is using the := operator and the SET command:

a.x:= 10;
a.x:= b.x;
SET a.x= 10, a.y=20, a.z= b.z;

* Passing to functions and operators:

SELECT f1(rec.a), rec.a<10;

* Clauses (select list, WHERE, HAVING, LIMIT, etc...,):

SELECT var.a, t1.b FROM t1 WHERE t1.b=var.b LIMIT var.c;

* INSERT values:

INSERT INTO t1 VALUES (rec.a, rec.b, rec.c);

* SELECT .. INTO targets

SELECT a,b INTO rec.a, rec.b FROM t1 WHERE t1.id=10;

* Dynamic SQL out parameters (EXECUTE and EXECUTE IMMEDIATE)

EXECUTE IMMEDIATE 'CALL proc_with_out_param(?)' USING rec.a;

ROW type variables as FETCH targets
-----------------------------------

ROW type variables are allowed as FETCH targets:

FETCH cur INTO rec;

where cur is a CURSOR and rec is a ROW type stored procedure variable.

Note, currently an attempt to use FETCH for a ROW type variable returns this
error:

ERROR 1328 (HY000): Incorrect number of FETCH variables

FETCH from a cursor cur into a ROW variable rec works as follows:

* The number of fields in cur must match the number of fields in rec.
 Otherwise, an error is reported.

* Assignment is done from left to right. The first cursor field is assigned to
 the first variable field, the second cursor field is assigned to the second
 variable field, etc.

* Field names in rec are not important and can differ from field names
 in cur.

See FETCH Examples (below) for examples of using this with sql_mode=ORACLE and
sql_mode=DEFAULT.

ROW type variables as SELECT...INTO targets
-------------------------------------------

ROW type variables are allowed as SELECT..INTO targets with some differences
depending on which sql_mode is in use.

* When using sql_mode=ORACLE, table%ROWTYPE and cursor%ROWTYPE
 variables can be used as SELECT...INTO targets.

* Using multiple ROW variables in the SELECT..INTO list will report an
 error.

* Using ROW variables with a different column count than in
 the SELECT..INTO list will report an error.

See SELECT...INTO Examples (below) for examples of using this with
sql_mode=ORACLE and sql_mode=DEFAULT.

Features not implemented
------------------------

The following features are planned, but not implemented yet:

* Returning a ROW type expression from a stored function (see MDEV-12252).
This will need some grammar change to support field names after parentheses:

SELECT f1().x FROM DUAL;

* Returning a ROW type expression from a built-in hybrid type function, such
as CASE, IF, etc. 
* ROW of ROWs

Examples
--------

Declaring a ROW in a stored procedure
-------------------------------------

DELIMITER $$
CREATE PROCEDURE p1()
BEGIN
 DECLARE r ROW (c1 INT, c2 VARCHAR(10));
 SET r.c1= 10;
 SET r.c2= 'test';
 INSERT INTO t1 VALUES (r.c1, r.c2);
END;
$$
DELIMITER ;
CALL p1();

FETCH Examples
--------------

A complete FETCH example for sql_mode=ORACLE:

DROP TABLE IF EXISTS t1;
CREATE TABLE t1 (a INT, b VARCHAR(32));
INSERT INTO t1 VALUES (10,'b10');
INSERT INTO t1 VALUES (20,'b20');
INSERT INTO t1 VALUES (30,'b30');

SET sql_mode=oracle;
DROP PROCEDURE IF EXISTS p1;
DELIMITER $$
CREATE PROCEDURE p1 AS
 rec ROW(a INT, b VARCHAR(32));
 CURSOR c IS SELECT a,b FROM t1;
BEGIN
 OPEN c;
 LOOP
  FETCH c INTO rec;
  EXIT WHEN c%NOTFOUND;
  SELECT ('rec=(' || rec.a ||','|| rec.b||')');
 END LOOP;
 CLOSE c;
END;
$$
DELIMITER ;
CALL p1();

A complete FETCH example for sql_mode=DEFAULT:

DROP TABLE IF EXISTS t1;
CREATE TABLE t1 (a INT, b VARCHAR(32));
INSERT INTO t1 VALUES (10,'b10');
INSERT INTO t1 VALUES (20,'b20');
INSERT INTO t1 VALUES (30,'b30');

SET sql_mode=DEFAULT;
DROP PROCEDURE IF EXISTS p1;
DELIMITER $$
CREATE PROCEDURE p1()
BEGIN
 DECLARE done INT DEFAULT FALSE;
 DECLARE rec ROW(a INT, b VARCHAR(32));
 DECLARE c CURSOR FOR SELECT a,b FROM t1;
 DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = TRUE;
 OPEN c;
read_loop:
 LOOP
  FETCH c INTO rec;
  IF done THEN
   LEAVE read_loop;
  END IF;
  SELECT CONCAT('rec=(',rec.a,',',rec.b,')');
 END LOOP;
 CLOSE c;
END;
$$
DELIMITER ;
CALL p1();

SELECT...INTO Examples
----------------------

A SELECT...INTO example for sql_mode=DEFAULT:

SET sql_mode=DEFAULT;
DROP TABLE IF EXISTS t1;
DROP PROCEDURE IF EXISTS p1;
CREATE TABLE t1 (a INT, b VARCHAR(32));
INSERT INTO t1 VALUES (10,'b10');
DELIMITER $$
CREATE PROCEDURE p1()
BEGIN
 DECLARE rec1 ROW(a INT, b VARCHAR(32));
 SELECT * FROM t1 INTO rec1;
 SELECT rec1.a, rec1.b;
END;
$$
DELIMITER ;
CALL p1();

The above example returns:

+--------+--------+
| rec1.a | rec1.b |
+--------+--------+
|     10 | b10    |
+--------+--------+

A SELECT...INTO example for sql_mode=ORACLE:

SET sql_mode=ORACLE;
DROP TABLE IF EXISTS t1;
DROP PROCEDURE IF EXISTS p1;
CREATE TABLE t1 (a INT, b VARCHAR(32));
INSERT INTO t1 VALUES (10,'b10');
DELIMITER $$
CREATE PROCEDURE p1 AS
 rec1 ROW(a INT, b VARCHAR(32));
BEGIN
 SELECT * FROM t1 INTO rec1;
 SELECT rec1.a, rec1.b;
END;
$$
DELIMITER ;
CALL p1();

The above example returns:

+--------+--------+
| rec1.a | rec1.b |
+--------+--------+
|     10 | b10    |
+--------+--------+

An example for sql_mode=ORACLE using table%ROWTYPE variables as SELECT..INTO
targets:

SET sql_mode=ORACLE;
DROP TABLE IF EXISTS t1;
DROP PROCEDURE IF EXISTS p1;
CREATE TABLE t1 (a INT, b VARCHAR(32));
INSERT INTO t1 VALUES (10,'b10');
DELIMITER $$
CREATE PROCEDURE p1 AS
 rec1 t1%ROWTYPE;
BEGIN
 SELECT * FROM t1 INTO rec1;
 SELECT rec1.a, rec1.b;
END;
$$
DELIMITER ;
CALL p1();

The above example returns:

+--------+--------+
| rec1.a | rec1.b |
+--------+--------+
|     10 | b10    |
+--------+--------+

An example for sql_mode=ORACLE using cursor%ROWTYPE variables as SELECT..INTO
targets:

SET sql_mode=ORACLE;
DROP TABLE IF EXISTS t1;
DROP PROCEDURE IF EXISTS p1;
CREATE TABLE t1 (a INT, b VARCHAR(32));
INSERT INTO t1 VALUES (10,'b10');
DELIMITER $$
CREATE PROCEDURE p1 AS
 CURSOR cur1 IS SELECT * FROM t1;
 rec1 cur1%ROWTYPE;
BEGIN
 SELECT * FROM t1 INTO rec1;
 SELECT rec1.a, rec1.b;
END;
$$
DELIMITER ;
CALL p1();

The above example returns:

+--------+--------+
| rec1.a | rec1.b |
+--------+--------+
|     10 | b10    |
+--------+--------+

URL: https://mariadb.com/kb/en/row/https://mariadb.com/kb/en/row/��!%_rowidSyntax
------

_rowid

Description
-----------

The _rowid pseudo column is mapped to the primary key in the related table.
This can be used as a replacement of the rowid pseudo column in other
databases. Another usage is to simplify sql queries as one doesn't have to
know the name of the primary key.

Examples
--------

create table t1 (a int primary key, b varchar(80));
insert into t1 values (1,"one"),(2,"two");
select * from t1 where _rowid=1;

+---+------+
| a | b    |
+---+------+
| 1 | one  |
+---+------+

update t1 set b="three" where _rowid=2;
select * from t1 where _rowid>=1 and _rowid<=10;

+---+-------+
| a | b     |
+---+-------+
| 1 | one   |
| 2 | three |
+---+-------+

URL: https://mariadb.com/kb/en/_rowid/https://mariadb.com/kb/en/_rowid/��C.�
�1
TEXTSyntax
------

TEXT[(M)] [CHARACTER SET charset_name] [COLLATE collation_name]

Description
-----------

A TEXT column with a maximum length of 65,535 (216 - 1) characters. The
effective maximum length is less if the value contains multi-byte characters.
Each TEXT value is stored using a two-byte length prefix that indicates the
number of bytes in the value. If you need a bigger storage, consider using
MEDIUMTEXT instead.

An optional length M can be given for this type. If this is done, MariaDB
creates the column as the smallest TEXT type large enough to hold values M
characters long.

Before MariaDB 10.2, all MariaDB collations were of type PADSPACE, meaning
that TEXT (as well as VARCHAR and CHAR values) are compared without regard for
trailing spaces. This does not apply to the LIKE pattern-matching operator,
which takes into account trailing spaces.

Before MariaDB 10.2.1, BLOB and TEXT columns could not be assigned a DEFAULT
value. This restriction was lifted in MariaDB 10.2.1.

Examples
--------

Trailing spaces:

CREATE TABLE strtest (d TEXT(10));
INSERT INTO strtest VALUES('Maria   ');

SELECT d='Maria',d='Maria   ' FROM strtest;
+-----------+--------------+
| d='Maria' | d='Maria   ' |
+-----------+--------------+
|         1 |            1 |
+-----------+--------------+

SELECT d LIKE 'Maria',d LIKE 'Maria   ' FROM strtest;
+----------------+-------------------+
| d LIKE 'Maria' | d LIKE 'Maria   ' |
+----------------+-------------------+
|              0 |                 1 |
+----------------+-------------------+

Indexing
--------

TEXT columns can only be indexed over a specified length. This means that they
cannot be used as the primary key of a table norm until MariaDB 10.4, can a
unique index be created on them.

MariaDB starting with 10.4
--------------------------
Starting with MariaDB 10.4, a unique index can be created on a TEXT column.

Internally, this uses hash indexing to quickly check the values and if a hash
collision is found, the actual stored values are compared in order to retain
the uniqueness.

Difference between VARCHAR and TEXT
-----------------------------------

* VARCHAR columns can be fully indexed. TEXT columns can only be indexed over
a specified length.
* Using TEXT or BLOB in a SELECT query that uses temporary tables for storing
intermediate results will force the temporary table to be disk based (using
the Aria storage engine instead of the memory storage engine, which is a bit
slower. This is not that bad as the Aria storage engine caches the rows in
memory. To get the benefit of this, one should ensure that the
aria_pagecache_buffer_size variable is big enough to hold most of the row and
index data for temporary tables.

For Storage Engine Developers
-----------------------------

* Internally the full length of the VARCHAR column is allocated inside each
TABLE objects record[] structure. As there are three such buffers, each open
table will allocate 3 times max-length-to-store-varchar bytes of memory.
* TEXT and BLOB columns are stored with a pointer (4 or 8 bytes) + a 1-4 bytes
length.  The TEXT data is only stored once. This means that internally TEXT
uses less memory for each open table but instead has the additional overhead
that each TEXT object needs to be allocated and freed for each row access
(with some caching in between).

URL: https://mariadb.com/kb/en/text/https://mariadb.com/kb/en/text/#�DATESyntax
------

DATE

Description
-----------

A date. The supported range is '1000-01-01' to '9999-12-31'. MariaDB displays
DATE values in 'YYYY-MM-DD' format, but can be assigned dates in looser
formats, including strings or numbers, as long as they make sense. These
include a short year, YY-MM-DD, no delimiters, YYMMDD, or any other acceptable
delimiter, for example YYYY/MM/DD. For details, see date and time literals.

'0000-00-00' is a permitted special value (zero-date), unless the NO_ZERO_DATE
SQL_MODE is used. Also, individual components of a date can be set to 0 (for
example: '2015-00-12'), unless the NO_ZERO_IN_DATE SQL_MODE is used. In many
cases, the result of en expression involving a zero-date, or a date with
zero-parts, is NULL. If the ALLOW_INVALID_DATES SQL_MODE is enabled, if the
day part is in the range between 1 and 31, the date does not produce any
error, even for months that have less than 31 days.

Oracle Mode
-----------

MariaDB starting with 10.3
--------------------------
In Oracle mode from MariaDB 10.3, DATE with a time portion is a synonym for
DATETIME. See also mariadb_schema.

Examples
--------

CREATE TABLE t1 (d DATE);

INSERT INTO t1 VALUES ("2010-01-12"), ("2011-2-28"), ('120314'),('13*04*21');

SELECT * FROM t1;
+------------+
| d          |
+------------+
| 2010-01-12 |
| 2011-02-28 |
| 2012-03-14 |
| 2013-04-21 |
+------------+

URL: https://mariadb.com/kb/en/date/https://mariadb.com/kb/en/date/�i@���|&&ALTER TABLE�U.&ALTER LOGFILE GROUPSyntax
------

ALTER LOGFILE GROUP logfile_group
  ADD UNDOFILE 'file_name'
  [INITIAL_SIZE [=] size]
  [WAIT]
  ENGINE [=] engine_name

The ALTER LOGFILE GROUP statement is not supported by MariaDB. It was
originally inherited from MySQL NDB Cluster. See MDEV-19295 for more
information.

URL: https://mariadb.com/kb/en/alter-logfile-group/https://mariadb.com/kb/en/alter-logfile-group/��'&ALTER SERVERSyntax
------

ALTER SERVER server_name
  OPTIONS (option [, option] ...)

Description
-----------

Alters the server information for server_name, adjusting the specified options
as per the CREATE SERVER command. The corresponding fields in the
mysql.servers table are updated accordingly. This statement requires the SUPER
privilege or, from MariaDB 10.5.2, the FEDERATED ADMIN privilege.

ALTER SERVER is not written to the binary log, irrespective of the binary log
format being used. From MariaDB 10.1.13, Galera replicates the CREATE SERVER,
ALTER SERVER and DROP SERVER statements.

Examples
--------

ALTER SERVER s OPTIONS (USER 'sally');

URL: https://mariadb.com/kb/en/alter-server/https://mariadb.com/kb/en/alter-server/�L+&ALTER TABLESPACEThe ALTER TABLESPACE statement is not supported by MariaDB. It was originally
inherited from MySQL NDB Cluster. In MySQL 5.7 and later, the statement is
also supported for InnoDB. However, MariaDB has chosen not to include that
specific feature. See MDEV-19294 for more information.

URL: https://mariadb.com/kb/en/alter-tablespace/https://mariadb.com/kb/en/alter-tablespace/�m@	�I��ޡ'&CREATE TABLE�r@S�I���-*&CREATE FUNCTION�s@I�S��8"+&CREATE PROCEDURE�N,&CREATE TABLESPACEThe CREATE TABLESPACE statement is not supported by MariaDB. It was originally
inherited from MySQL NDB Cluster. In MySQL 5.7 and later, the statement is
also supported for InnoDB. However, MariaDB has chosen not to include that
specific feature. See MDEV-19294 for more information.

URL: https://mariadb.com/kb/en/create-tablespace/https://mariadb.com/kb/en/create-tablespace/�t@I���8&&CREATE VIEW�v@x�I��1�F,&Generated (Virtual and Persistent/Stored) Columns�P'&DROP PACKAGEMariaDB starting with 10.3.5
----------------------------
Oracle-style packages were introduced in MariaDB 10.3.5.

Syntax
------

DROP PACKAGE [IF EXISTS]  [ db_name . ] package_name

Description
-----------

The DROP PACKAGE statement can be used when Oracle SQL_MODE is set.

The DROP PACKAGE statement drops a stored package entirely:

* Drops the package specification (earlier created using the CREATE PACKAGE
statement).
* Drops the package implementation, if the implementation was already created
using the CREATE PACKAGE BODY statement.

URL: https://mariadb.com/kb/en/drop-package/https://mariadb.com/kb/en/drop-package/2��U�(��4�3�0����W�/(n
�b
BP,�Syntax
------

ALTER [ONLINE] [IGNORE] TABLE [IF EXISTS] tbl_name
  [WAIT n | NOWAIT]
  alter_specification [, alter_specification] ...
alter_specification:
  table_option ...
 | ADD [COLUMN] [IF NOT EXISTS] col_name column_definition
    [FIRST | AFTER col_name ]
 | ADD [COLUMN] [IF NOT EXISTS] (col_name column_definition,...)
 | ADD {INDEX|KEY} [IF NOT EXISTS] [index_name]
    [index_type] (index_col_name,...) [index_option] ...
 | ADD [CONSTRAINT [symbol]] PRIMARY KEY
    [index_type] (index_col_name,...) [index_option] ...
 | ADD [CONSTRAINT [symbol]]
    UNIQUE [INDEX|KEY] [index_name]
    [index_type] (index_col_name,...) [index_option] ...
 | ADD FULLTEXT [INDEX|KEY] [index_name]
    (index_col_name,...) [index_option] ...
 | ADD SPATIAL [INDEX|KEY] [index_name]
    (index_col_name,...) [index_option] ...
 | ADD [CONSTRAINT [symbol]]
    FOREIGN KEY [IF NOT EXISTS] [index_name] (index_col_name,...)
    reference_definition
 | ADD PERIOD FOR SYSTEM_TIME (start_column_name, end_column_name)
 | ALTER [COLUMN] col_name SET DEFAULT literal | (expression)
 | ALTER [COLUMN] col_name DROP DEFAULT
 | ALTER {INDEX|KEY} index_name [NOT] INVISIBLE
 | CHANGE [COLUMN] [IF EXISTS] old_col_name new_col_name column_definition
    [FIRST|AFTER col_name]
 | MODIFY [COLUMN] [IF EXISTS] col_name column_definition
    [FIRST | AFTER col_name]
 | DROP [COLUMN] [IF EXISTS] col_name [RESTRICT|CASCADE]
 | DROP PRIMARY KEY
 | DROP {INDEX|KEY} [IF EXISTS] index_name
 | DROP FOREIGN KEY [IF EXISTS] fk_symbol
 | DROP CONSTRAINT [IF EXISTS] constraint_name
 | DISABLE KEYS
 | ENABLE KEYS
 | RENAME [TO] new_tbl_name
 | ORDER BY col_name [, col_name] ...
 | RENAME COLUMN old_col_name TO new_col_name
 | RENAME {INDEX|KEY} old_index_name TO new_index_name
 | CONVERT TO CHARACTER SET charset_name [COLLATE collation_name]
 | [DEFAULT] CHARACTER SET [=] charset_name
 | [DEFAULT] COLLATE [=] collation_name
 | DISCARD TABLESPACE
 | IMPORT TABLESPACE
 | ALGORITHM [=] {DEFAULT|INPLACE|COPY|NOCOPY|INSTANT}
 | LOCK [=] {DEFAULT|NONE|SHARED|EXCLUSIVE}
 | FORCE
 | partition_options
 | CONVERT TABLE normal_table TO partition_definition
 | CONVERT PARTITION partition_name TO TABLE tbl_name
 | ADD PARTITION [IF NOT EXISTS] (partition_definition)
 | DROP PARTITION [IF EXISTS] partition_names
 | COALESCE PARTITION number
 | REORGANIZE PARTITION [partition_names INTO (partition_definitions)]
 | ANALYZE PARTITION partition_names
 | CHECK PARTITION partition_names
 | OPTIMIZE PARTITION partition_names
 | REBUILD PARTITION partition_names
 | REPAIR PARTITION partition_names
 | EXCHANGE PARTITION partition_name WITH TABLE tbl_name
 | REMOVE PARTITIONING
 | ADD SYSTEM VERSIONING
 | DROP SYSTEM VERSIONING
index_col_name:
  col_name [(length)] [ASC | DESC]
index_type:
  USING {BTREE | HASH | RTREE}
index_option:
  [ KEY_BLOCK_SIZE [=] value
 | index_type
 | WITH PARSER parser_name
 | COMMENT 'string'
 | CLUSTERING={YES| NO} ]
 [ IGNORED | NOT IGNORED ]
table_options:
  table_option [[,] table_option] ...

Description
-----------

ALTER TABLE enables you to change the structure of an existing table. For
example, you can add or delete columns, create or destroy indexes, change the
type of existing columns, or rename columns or the table itself. You can also
change the comment for the table and the storage engine of the table.

If another connection is using the table, a metadata lock is active, and this
statement will wait until the lock is released. This is also true for
non-transactional tables.

When adding a UNIQUE index on a column (or a set of columns) which have
duplicated values, an error will be produced and the statement will be
stopped. To suppress the error and force the creation of UNIQUE indexes,
discarding duplicates, the IGNORE option can be specified. This can be useful
if a column (or a set of columns) should be UNIQUE but it contains duplicate
values; however, this technique provides no control on which rows are
preserved and which are deleted. Also, note that IGNORE is accepted but
ignored in ALTER TABLE ... EXCHANGE PARTITION statements.

This statement can also be used to rename a table. For details see RENAME
TABLE.

When an index is created, the storage engine may use a configurable buffer in
the process. Incrementing the buffer speeds up the index creation. Aria and
MyISAM allocate a buffer whose size is defined by aria_sort_buffer_size or
myisam_sort_buffer_size, also used for REPAIR TABLE. InnoDB allocates three
buffers whose size is defined by innodb_sort_buffer_size.

Privileges
----------

Executing the ALTER TABLE statement generally requires at least the ALTER
privilege for the table or the database..

If you are renaming a table, then it also requires the DROP, CREATE and INSERT
privileges for the table or the database as well.

Online DDL
----------

Online DDL is supported with the ALGORITHM and LOCK clauses.

See InnoDB Online DDL Overview for more information on online DDL with InnoDB.

ALTER ONLINE TABLE
------------------

ALTER ONLINE TABLE also works for partitioned tables.

Online ALTER TABLE is available by executing the following:

ALTER ONLINE TABLE ...;

This statement has the following semantics:

This statement is equivalent to the following:

ALTER TABLE ... LOCK=NONE;

See the LOCK alter specification for more information.

This statement is equivalent to the following:

ALTER TABLE ... ALGORITHM=INPLACE;

See the ALGORITHM alter specification for more information.

WAIT/NOWAIT
-----------

Set the lock wait timeout. See WAIT and NOWAIT.

IF EXISTS
---------

The IF EXISTS and IF NOT EXISTS clauses are available for the following:

ADD COLUMN       [IF NOT EXISTS]
ADD INDEX        [IF NOT EXISTS]
ADD FOREIGN KEY  [IF NOT EXISTS]
ADD PARTITION    [IF NOT EXISTS]
CREATE INDEX     [IF NOT EXISTS]
DROP COLUMN      [IF EXISTS]
DROP INDEX       [IF EXISTS]
DROP FOREIGN KEY [IF EXISTS]
DROP PARTITION   [IF EXISTS]
CHANGE COLUMN    [IF EXISTS]
MODIFY COLUMN    [IF EXISTS]
DROP INDEX       [IF EXISTS]
When IF EXISTS and IF NOT EXISTS are used in clauses, queries will not report
errors when the condition is triggered for that clause. A warning with the
same message text will be issued and the ALTER will move on to the next clause
in the statement (or end if finished).

MariaDB starting with 10.5.2
----------------------------
If this is directive is used after ALTER ... TABLE, one will not get an error
if the table doesn't exist.

Column Definitions
------------------

See CREATE TABLE: Column Definitions for information about column definitions.

Index Definitions
-----------------

See CREATE TABLE: Index Definitions for information about index definitions.

The CREATE INDEX and DROP INDEX statements can also be used to add or remove
an index.

Character Sets and Collations
-----------------------------

CONVERT TO CHARACTER SET charset_name [COLLATE collation_name]
[DEFAULT] CHARACTER SET [=] charset_name
[DEFAULT] COLLATE [=] collation_name
See Setting Character Sets and Collations for details on setting the character
sets and collations.

Alter Specifications
--------------------

Table Options
-------------

See CREATE TABLE: Table Options for information about table options.

ADD COLUMN
----------

... ADD COLUMN [IF NOT EXISTS]  (col_name column_definition,...)
Adds a column to the table. The syntax is the same as in CREATE TABLE. If you
are using IF NOT_EXISTS the column will not be added if it was not there
already. This is very useful when doing scripts to modify tables.

The FIRST and AFTER clauses affect the physical order of columns in the
datafile. Use FIRST to add a column in the first (leftmost) position, or AFTER
followed by a column name to add the new column in any other position. Note
that, nowadays, the physical position of a column is usually irrelevant.

See also Instant ADD COLUMN for InnoDB.

DROP COLUMN
-----------

... DROP COLUMN [IF EXISTS] col_name [CASCADE|RESTRICT]
Drops the column from the table. If you are using IF EXISTS you will not get
an error if the column didn't exist. If the column is part of any index, the
column will be dropped from them, except if you add a new column with
identical name at the�+6w same time. The index will be dropped if all columns from
the index were dropped. If the column was used in a view or trigger, you will
get an error next time the view or trigger is accessed. Dropping a column that
is part of a multi-column UNIQUE constraint is not permitted. For example:

CREATE TABLE a (
 a int,
 b int,
 primary key (a,b)
);

ALTER TABLE x DROP COLUMN a;
[42000][1072] Key column 'A' doesn't exist in table

The reason is that dropping column a would result in the new constraint that
all values in column b be unique. In order to drop the column, an explicit
DROP PRIMARY KEY and ADD PRIMARY KEY would be required. Up until MariaDB
10.2.7, the column was dropped and the additional constraint applied,
resulting in the following structure:

ALTER TABLE x DROP COLUMN a;
Query OK, 0 rows affected (0.46 sec)

DESC x;
+-------+---------+------+-----+---------+-------+
| Field | Type    | Null | Key | Default | Extra |
+-------+---------+------+-----+---------+-------+
| b     | int(11) | NO   | PRI | NULL    |       |
+-------+---------+------+-----+---------+-------+

MariaDB starting with 10.4.0
----------------------------
MariaDB 10.4.0 supports instant DROP COLUMN. DROP COLUMN of an indexed column
would imply DROP INDEX (and in the case of a non-UNIQUE multi-column index,
possibly ADD INDEX). These will not be allowed with ALGORITHM=INSTANT, but
unlike before, they can be allowed with ALGORITHM=NOCOPY

RESTRICT and CASCADE are allowed to make porting from other database systems
easier. In MariaDB, they do nothing.

MODIFY COLUMN
-------------

Allows you to modify the type of a column. The column will be at the same
place as the original column and all indexes on the column will be kept. Note
that when modifying column, you should specify all attributes for the new
column.

CREATE TABLE t1 (a INT UNSIGNED AUTO_INCREMENT, PRIMARY KEY((a));
ALTER TABLE t1 MODIFY a BIGINT UNSIGNED AUTO_INCREMENT;

CHANGE COLUMN
-------------

Works like MODIFY COLUMN except that you can also change the name of the
column. The column will be at the same place as the original column and all
index on the column will be kept.

CREATE TABLE t1 (a INT UNSIGNED AUTO_INCREMENT, PRIMARY KEY(a));
ALTER TABLE t1 CHANGE a b BIGINT UNSIGNED AUTO_INCREMENT;

ALTER COLUMN
------------

This lets you change column options.

CREATE TABLE t1 (a INT UNSIGNED AUTO_INCREMENT, b varchar(50), PRIMARY KEY(a));
ALTER TABLE t1 ALTER b SET DEFAULT 'hello';

RENAME INDEX/KEY
----------------

MariaDB starting with 10.5.2
----------------------------
From MariaDB 10.5.2, it is possible to rename an index using the RENAME INDEX
(or RENAME KEY) syntax, for example:

ALTER TABLE t1 RENAME INDEX i_old TO i_new;

RENAME COLUMN
-------------

MariaDB starting with 10.5.2
----------------------------
From MariaDB 10.5.2, it is possible to rename a column using the RENAME COLUMN
syntax, for example:

ALTER TABLE t1 RENAME COLUMN c_old TO c_new;

ADD PRIMARY KEY
---------------

Add a primary key.

For PRIMARY KEY indexes, you can specify a name for the index, but it is
silently ignored, and the name of the index is always PRIMARY.

See Getting Started with Indexes: Primary Key for more information.

DROP PRIMARY KEY
----------------

Drop a primary key.

For PRIMARY KEY indexes, you can specify a name for the index, but it is
silently ignored, and the name of the index is always PRIMARY.

See Getting Started with Indexes: Primary Key for more information.

ADD FOREIGN KEY
---------------

Add a foreign key.

For FOREIGN KEY indexes, a reference definition must be provided.

For FOREIGN KEY indexes, you can specify a name for the constraint, using the
CONSTRAINT keyword. That name will be used in error messages.

First, you have to specify the name of the target (parent) table and a column
or a column list which must be indexed and whose values must match to the
foreign key's values. The MATCH clause is accepted to improve the
compatibility with other DBMS's, but has no meaning in MariaDB. The ON DELETE
and ON UPDATE clauses specify what must be done when a DELETE (or a REPLACE)
statements attempts to delete a referenced row from the parent table, and when
an UPDATE statement attempts to modify the referenced foreign key columns in a
parent table row, respectively. The following options are allowed:

* RESTRICT: The delete/update operation is not performed.  The statement
terminates with a 1451 error (SQLSTATE '2300').
* NO ACTION: Synonym for RESTRICT.
* CASCADE: The delete/update operation is performed in both tables.
* SET NULL: The update or delete goes ahead in the parent table, and the
corresponding foreign key fields in the child table are set to NULL.  (They
must not be defined as NOT NULL for this to succeed).
* SET DEFAULT: This option is implemented only for the legacy PBXT storage
engine, which is disabled by default and no longer maintained. It sets the
child table's foreign key fields to their DEFAULT values when the referenced
parent table key entries are updated or deleted.

If either clause is omitted, the default behavior for the omitted clause is
RESTRICT.

See Foreign Keys for more information.

DROP FOREIGN KEY
----------------

Drop a foreign key.

See Foreign Keys for more information.

ADD INDEX
---------

Add a plain index.

Plain indexes are regular indexes that are not unique, and are not acting as a
primary key or a foreign key. They are also not the "specialized" FULLTEXT or
SPATIAL indexes.

See Getting Started with Indexes: Plain Indexes for more information.

DROP INDEX
----------

Drop a plain index.

Plain indexes are regular indexes that are not unique, and are not acting as a
primary key or a foreign key. They are also not the "specialized" FULLTEXT or
SPATIAL indexes.

See Getting Started with Indexes: Plain Indexes for more information.

ADD UNIQUE INDEX
----------------

Add a unique index.

The UNIQUE keyword means that the index will not accept duplicated values,
except for NULLs. An error will raise if you try to insert duplicate values in
a UNIQUE index.

For UNIQUE indexes, you can specify a name for the constraint, using the
CONSTRAINT keyword. That name will be used in error messages.

See Getting Started with Indexes: Unique Index for more information.

DROP UNIQUE INDEX
-----------------

Drop a unique index.

The UNIQUE keyword means that the index will not accept duplicated values,
except for NULLs. An error will raise if you try to insert duplicate values in
a UNIQUE index.

For UNIQUE indexes, you can specify a name for the constraint, using the
CONSTRAINT keyword. That name will be used in error messages.

See Getting Started with Indexes: Unique Index for more information.

ADD FULLTEXT INDEX
------------------

Add a FULLTEXT index.

See Full-Text Indexes for more information.

DROP FULLTEXT INDEX
-------------------

Drop a FULLTEXT index.

See Full-Text Indexes for more information.

ADD SPATIAL INDEX
-----------------

Add a SPATIAL index.

See SPATIAL INDEX for more information.

DROP SPATIAL INDEX
------------------

Drop a SPATIAL index.

See SPATIAL INDEX for more information.

ENABLE/ DISABLE KEYS
--------------------

DISABLE KEYS will disable all non unique keys for the table for storage
engines that support this (at least MyISAM and Aria). This can be used to
speed up inserts into empty tables.

ENABLE KEYS will enable all disabled keys.

RENAME TO
---------

Renames the table. See also RENAME TABLE.

ADD CONSTRAINT
--------------

Modifies the table adding a constraint on a particular column or columns.

ALTER TABLE table_name 
ADD CONSTRAINT [constraint_name] CHECK(expression);
Before a row is inserted or updated, all constraints are evaluated in the
order they are defined. If any constraint fails, then the row will not be
updated. One can use most deterministic functions in a constraint, including
UDF's.

CREATE TABLE account_ledger (
	id INT PRIMARY KEY AUTO_INCREMENT,
	transaction_name VARCHAR(100),
	credit_account VARCHAR(100),
	credit_amount INT,
	debit_account VARCHAR(100),
	debit_amount INT);

ALTER TABLE account_ledger 
ADD CONSTRAINT is_balanced 
  CHECK((debit_amount + credit_amount) = 0);

T�n�he constraint_name is optional. If you don't provide one in the ALTER TABLE
statement, MariaDB auto-generates a name for you. This is done so that you can
remove it later using DROP CONSTRAINT clause.

You can disable all constraint expression checks by setting the variable
check_constraint_checks to OFF. You may find this useful when loading a table
that violates some constraints that you want to later find and fix in SQL.

To view constraints on a table, query information_schema.TABLE_CONSTRAINTS:

SELECT CONSTRAINT_NAME, TABLE_NAME, CONSTRAINT_TYPE 
FROM information_schema.TABLE_CONSTRAINTS
WHERE TABLE_NAME = 'account_ledger';

+-----------------+----------------+-----------------+
| CONSTRAINT_NAME | TABLE_NAME     | CONSTRAINT_TYPE |
+-----------------+----------------+-----------------+
| is_balanced     | account_ledger | CHECK           |
+-----------------+----------------+-----------------+

DROP CONSTRAINT
---------------

DROP CONSTRAINT for UNIQUE and FOREIGN KEY constraints was introduced in
MariaDB 10.2.22 and MariaDB 10.3.13.

DROP CONSTRAINT for CHECK constraints was introduced in MariaDB 10.2.1

Modifies the table, removing the given constraint.

ALTER TABLE table_name
DROP CONSTRAINT constraint_name;

When you add a constraint to a table, whether through a CREATE TABLE or ALTER
TABLE...ADD CONSTRAINT statement, you can either set a constraint_name
yourself, or allow MariaDB to auto-generate one for you. To view constraints
on a table, query information_schema.TABLE_CONSTRAINTS. For instance,

CREATE TABLE t (
 a INT,
 b INT,
 c INT,
 CONSTRAINT CHECK(a > b),
 CONSTRAINT check_equals CHECK(a = c));

SELECT CONSTRAINT_NAME, TABLE_NAME, CONSTRAINT_TYPE 
FROM information_schema.TABLE_CONSTRAINTS
WHERE TABLE_NAME = 't';

+-----------------+----------------+-----------------+
| CONSTRAINT_NAME | TABLE_NAME     | CONSTRAINT_TYPE |
+-----------------+----------------+-----------------+
| check_equals    | t              | CHECK           |
| CONSTRAINT_1    | t              | CHECK           |
+-----------------+----------------+-----------------+

To remove a constraint from the table, issue an ALTER TABLE...DROP CONSTRAINT
statement. For example,

ALTER TABLE t DROP CONSTRAINT is_unique;

ADD SYSTEM VERSIONING
---------------------

Add system versioning. See System-versioned tables.

DROP SYSTEM VERSIONING
----------------------

Drop system versioning. See System-versioned tables.

ADD PERIOD FOR SYSTEM_TIME
--------------------------

See System-versioned tables.

FORCE
-----

ALTER TABLE ... FORCE can force MariaDB to re-build the table.

In MariaDB 5.5 and before, this could only be done by setting the ENGINE table
option to its old value. For example, for an InnoDB table, one could execute
the following:

ALTER TABLE tab_name ENGINE = InnoDB;

The FORCE option can be used instead. For example, :

ALTER TABLE tab_name FORCE;

With InnoDB, the table rebuild will only reclaim unused space (i.e. the space
previously used for deleted rows) if the innodb_file_per_table system variable
is set to ON (the default). If the system variable is OFF, then the space will
not be reclaimed, but it will be-re-used for new data that's later added.

CONVERT TABLE / CONVERT PARTITION
---------------------------------

CONVERT TABLE and CONVERT PARTITION was introduced in MariaDB 10.7.1.

CONVERT PARTITION can be used to remove a partition from a table and make this
an ordinary table. For example:

ALTER TABLE partitioned_table CONVERT PARTITION part1 TO TABLE normal_table;

CONVERT PARTITION will take an existing table and move this to another table
as its own partition with a specified partition definition. For example the
following moves normal_table to a partition of partitioned_table with a
definition that its values, based on the PARTITION BY of the
partitioned_table, are less than 12345.

ALTER TABLE partitioned_table CONVERT TABLE normal_table TO PARTITION part1
VALUES LESS THAN (12345);

EXCHANGE PARTITION
------------------

This is used to exchange the contents of a partition with another table.

This is performed by swapping the tablespaces of the partition with the other
table.

See copying InnoDB's transportable tablespaces for more information.

DISCARD TABLESPACE
------------------

This is used to discard an InnoDB table's tablespace.

See copying InnoDB's transportable tablespaces for more information.

IMPORT TABLESPACE
-----------------

This is used to import an InnoDB table's tablespace. The tablespace should
have been copied from its original server after executing FLUSH TABLES FOR
EXPORT.

See copying InnoDB's transportable tablespaces for more information.

ALTER TABLE ... IMPORT only applies to InnoDB tables. Most other popular
storage engines, such as Aria and MyISAM, will recognize their data files as
soon as they've been placed in the proper directory under the datadir, and no
special DDL is required to import them.

ALGORITHM
---------

The ALTER TABLE statement supports the ALGORITHM clause. This clause is one of
the clauses that is used to implement online DDL. ALTER TABLE supports several
different algorithms. An algorithm can be explicitly chosen for an ALTER TABLE
operation by setting the ALGORITHM clause. The supported values are:

* ALGORITHM=DEFAULT - This implies the default behavior for the specific
statement, such as if no ALGORITHM clause is specified.
* ALGORITHM=COPY
* ALGORITHM=INPLACE
* ALGORITHM=NOCOPY - This was added in MariaDB 10.3.7.
* ALGORITHM=INSTANT - This was added in MariaDB 10.3.7.

See InnoDB Online DDL Overview: ALGORITHM for information on how the ALGORITHM
clause affects InnoDB.

ALGORITHM=DEFAULT
-----------------

The default behavior, which occurs if ALGORITHM=DEFAULT is specified, or if
ALGORITHM is not specified at all, usually only makes a copy if the operation
doesn't support being done in-place at all. In this case, the most efficient
available algorithm will usually be used.

However, in MariaDB 10.3.6 and before, if the value of the old_alter_table
system variable is set to ON, then the default behavior is to perform ALTER
TABLE operations by making a copy of the table using the old algorithm.

In MariaDB 10.3.7 and later, the old_alter_table system variable is
deprecated. Instead, the alter_algorithm system variable defines the default
algorithm for ALTER TABLE operations.

ALGORITHM=COPY
--------------

ALGORITHM=COPY is the name for the original ALTER TABLE algorithm from early
MariaDB versions.

When ALGORITHM=COPY is set, MariaDB essentially does the following operations:

-- Create a temporary table with the new definition
CREATE TEMPORARY TABLE tmp_tab (
...
);

-- Copy the data from the original table
INSERT INTO tmp_tab
 SELECT * FROM original_tab;

-- Drop the original table
DROP TABLE original_tab;

-- Rename the temporary table, so that it replaces the original one
RENAME TABLE tmp_tab TO original_tab;

This algorithm is very inefficient, but it is generic, so it works for all
storage engines.

If ALGORITHM=COPY is specified, then the copy algorithm will be used even if
it is not necessary. This can result in a lengthy table copy. If multiple
ALTER TABLE operations are required that each require the table to be rebuilt,
then it is best to specify all operations in a single ALTER TABLE statement,
so that the table is only rebuilt once.

ALGORITHM=INPLACE
-----------------

ALGORITHM=COPY can be incredibly slow, because the whole table has to be
copied and rebuilt. ALGORITHM=INPLACE was introduced as a way to avoid this by
performing operations in-place and avoiding the table copy and rebuild, when
possible.

When ALGORITHM=INPLACE is set, the underlying storage engine uses
optimizations to perform the operation while avoiding the table copy and
rebuild. However, INPLACE is a bit of a misnomer, since some operations may
still require the table to be rebuilt for some storage engines. Regardless,
several operations can be performed without a full copy of the table for some
storage engines.

A more accurate name would have been ALGORITHM=ENGINE, where ENGINE refers to
an "engine-specific" algorithm.

If an ALTER TABLE operation supports ALGORITHM=INPf�o�LACE, then it can be
performed using optimizations by the underlying storage engine, but it may
rebuilt.

See InnoDB Online DDL Operations with ALGORITHM=INPLACE for more.

ALGORITHM=NOCOPY
----------------

ALGORITHM=NOCOPY was introduced in MariaDB 10.3.7.

ALGORITHM=INPLACE can sometimes be surprisingly slow in instances where it has
to rebuild the clustered index, because when the clustered index has to be
rebuilt, the whole table has to be rebuilt. ALGORITHM=NOCOPY was introduced as
a way to avoid this.

If an ALTER TABLE operation supports ALGORITHM=NOCOPY, then it can be
performed without rebuilding the clustered index.

If ALGORITHM=NOCOPY is specified for an ALTER TABLE operation that does not
support ALGORITHM=NOCOPY, then an error will be raised. In this case, raising
an error is preferable, if the alternative is for the operation to rebuild the
clustered index, and perform unexpectedly slowly.

See InnoDB Online DDL Operations with ALGORITHM=NOCOPY for more.

ALGORITHM=INSTANT
-----------------

ALGORITHM=INSTANT was introduced in MariaDB 10.3.7.

ALGORITHM=INPLACE can sometimes be surprisingly slow in instances where it has
to modify data files. ALGORITHM=INSTANT was introduced as a way to avoid this.

If an ALTER TABLE operation supports ALGORITHM=INSTANT, then it can be
performed without modifying any data files.

If ALGORITHM=INSTANT is specified for an ALTER TABLE operation that does not
support ALGORITHM=INSTANT, then an error will be raised. In this case, raising
an error is preferable, if the alternative is for the operation to modify data
files, and perform unexpectedly slowly.

See InnoDB Online DDL Operations with ALGORITHM=INSTANT for more.

LOCK
----

The ALTER TABLE statement supports the LOCK clause. This clause is one of the
clauses that is used to implement online DDL. ALTER TABLE supports several
different locking strategies. A locking strategy can be explicitly chosen for
an ALTER TABLE operation by setting the LOCK clause. The supported values are:

* DEFAULT: Acquire the least restrictive lock on the table that is supported
for the specific operation. Permit the maximum amount of concurrency that is
supported for the specific operation.
* NONE: Acquire no lock on the table. Permit all concurrent DML. If this
locking strategy is not permitted for an operation, then an error is raised.
* SHARED: Acquire a read lock on the table. Permit read-only concurrent DML.
If this locking strategy is not permitted for an operation, then an error is
raised.
* EXCLUSIVE: Acquire a write lock on the table. Do not permit concurrent DML.

Different storage engines support different locking strategies for different
operations. If a specific locking strategy is chosen for an ALTER TABLE
operation, and that table's storage engine does not support that locking
strategy for that specific operation, then an error will be raised.

If the LOCK clause is not explicitly set, then the operation uses LOCK=DEFAULT.

ALTER ONLINE TABLE is equivalent to LOCK=NONE. Therefore, the ALTER ONLINE
TABLE statement can be used to ensure that your ALTER TABLE operation allows
all concurrent DML.

See InnoDB Online DDL Overview: LOCK for information on how the LOCK clause
affects InnoDB.

Progress Reporting
------------------

MariaDB provides progress reporting for ALTER TABLE statement for clients that
support the new progress reporting protocol. For example, if you were using
the mariadb client, then the progress report might look like this::

ALTER TABLE test ENGINE=Aria;
Stage: 1 of 2 'copy to tmp table'    46% of stage

The progress report is also shown in the output of the SHOW PROCESSLIST
statement and in the contents of the information_schema.PROCESSLIST table.

See Progress Reporting for more information.

Aborting ALTER TABLE Operations
-------------------------------

If an ALTER TABLE operation is being performed and the connection is killed,
the changes will be rolled back in a controlled manner. The rollback can be a
slow operation as the time it takes is relative to how far the operation has
progressed.

Aborting ALTER TABLE ... ALGORITHM=COPY was made faster in MariaDB 10.2.13 by
removing excessive undo logging (MDEV-11415). This significantly shortened the
time it takes to abort a running ALTER TABLE operation, compared with earlier
releases.

Atomic ALTER TABLE
------------------

MariaDB starting with 10.6.1
----------------------------
From MariaDB 10.6, ALTER TABLE is atomic for most engines, including InnoDB,
MyRocks, MyISAM and Aria (MDEV-25180). This means that if there is a crash
(server down or power outage) during an ALTER TABLE operation, after recovery,
either the old table and associated triggers and status will be intact, or the
new table will be active.

In older MariaDB versions one could get leftover #sql-alter..',
'#sql-backup..' or 'table_name.frm˝' files if the system crashed during the
ALTER TABLE operation.

See Atomic DDL for more information.

Replication
-----------

MariaDB starting with 10.8.1
----------------------------
Before MariaDB 10.8.1, ALTER TABLE got fully executed on the primary first,
and only then was it replicated and started executing on replicas. From
MariaDB 10.8.1, ALTER TABLE gains an option to replicate sooner and begin
executing on replicas when it merely starts executing on the primary, not when
it finishes. This way the replication lag caused by a heavy ALTER TABLE can be
completely eliminated (MDEV-11675).

Examples
--------

Adding a new column:

ALTER TABLE t1 ADD x INT;

Dropping a column:

ALTER TABLE t1 DROP x;

Modifying the type of a column:

ALTER TABLE t1 MODIFY x bigint unsigned;

Changing the name and type of a column:

ALTER TABLE t1 CHANGE a b bigint unsigned auto_increment;

Combining multiple clauses in a single ALTER TABLE statement, separated by
commas:

ALTER TABLE t1 DROP x, ADD x2 INT,  CHANGE y y2 INT;

Changing the storage engine and adding a comment:

ALTER TABLE t1 
 ENGINE = InnoDB
 COMMENT = 'First of three tables containing usage info';

Rebuilding the table (the previous example will also rebuild the table if it
was already InnoDB):

ALTER TABLE t1 FORCE;

Dropping an index:

ALTER TABLE rooms DROP INDEX u;

Adding a unique index:

ALTER TABLE rooms ADD UNIQUE INDEX u(room_number);

From MariaDB 10.5.3, adding a primary key for an application-time period table
with a WITHOUT OVERLAPS constraint:

ALTER TABLE rooms ADD PRIMARY KEY(room_number, p WITHOUT OVERLAPS);

From MariaDB 10.8.1, ALTER query can be replicated faster with the setting of

SET @@SESSION.binlog_alter_two_phase = true;

prior the ALTER query. Binlog would contain two event groups

| master-bin.000001 | 495 | Gtid              |         1 |         537 | GTID
0-1-2 START ALTER                                        |
| master-bin.000001 | 537 | Query             |         1 |         655 | use
`test`; alter table t add column b int, algorithm=inplace |
| master-bin.000001 | 655 | Gtid              |         1 |         700 | GTID
0-1-3 COMMIT ALTER id=2                                  |
| master-bin.000001 | 700 | Query             |         1 |         835 | use
`test`; alter table t add column b int, algorithm=inplace |

of which the first one gets delivered to replicas before ALTER is taken to
actual execution on the primary.

URL: https://mariadb.com/kb/en/alter-table/
pSyntax
------

CREATE [OR REPLACE] [TEMPORARY] TABLE [IF NOT EXISTS] tbl_name
  (create_definition,...) [table_options    ]... [partition_options]
CREATE [OR REPLACE] [TEMPORARY] TABLE [IF NOT EXISTS] tbl_name
  [(create_definition,...)] [table_options   ]... [partition_options]
  select_statement
CREATE [OR REPLACE] [TEMPORARY] TABLE [IF NOT EXISTS] tbl_name
 { LIKE old_table_name | (LIKE old_table_name) }
select_statement:
  [IGNORE | REPLACE] [AS] SELECT ...   (Some legal select statement)

Description
-----------

Use the CREATE TABLE statement to create a table with the given name.

In its most basic form, the CREATE TABLE statement provides a table name
followed by a list of columns, indexes, and constraints. By default, the table
is created in the default database. Specify a database with db_name.tbl_name.
If you quote the table name, you must quote the database name and table name
separately as `db_name`.`tbl_name`. This is particularly useful for CREATE
TABLE ... SELECT, because it allows to create a table into a database, which
contains data from other databases. See Identifier Qualifiers.

If a table with the same name exists, error 1050 results. Use IF NOT EXISTS to
suppress this error and issue a note instead. Use SHOW WARNINGS to see notes.

The CREATE TABLE statement automatically commits the current transaction,
except when using the TEMPORARY keyword.

For valid identifiers to use as table names, see Identifier Names.

Note: if the default_storage_engine is set to ColumnStore then it needs
setting on all UMs. Otherwise when the tables using the default engine are
replicated across UMs they will use the wrong engine. You should therefore not
use this option as a session variable with ColumnStore.

Microsecond precision can be between 0-6. If no precision is specified it is
assumed to be 0, for backward compatibility reasons.

Privileges
----------

Executing the CREATE TABLE statement requires the CREATE privilege for the
table or the database.

CREATE OR REPLACE
-----------------

If the OR REPLACE clause is used and the table already exists, then instead of
returning an error, the server will drop the existing table and replace it
with the newly defined table.

This syntax was originally added to make replication more robust if it has to
rollback and repeat statements such as CREATE ... SELECT on replicas.

CREATE OR REPLACE TABLE table_name (a int);

is basically the same as:

DROP TABLE IF EXISTS table_name;
CREATE TABLE table_name (a int);

with the following exceptions:

* If table_name was locked with LOCK TABLES it will continue to be locked
after the statement.
* Temporary tables are only dropped if the TEMPORARY keyword was used.  (With
DROP TABLE,  temporary tables are preferred to be dropped before normal
tables).

Things to be Aware of With CREATE OR REPLACE
--------------------------------------------

* The table is dropped first (if it existed), after that the CREATE is done.
Because of this, if the CREATE fails, then the table will not exist anymore
after the statement.  If the table was used with LOCK TABLES it will be
unlocked.
* One can't use OR REPLACE together with IF EXISTS.
* Slaves in replication will by default use CREATE OR REPLACE when replicating
CREATE statements that don''t use IF EXISTS. This can be changed by setting
the variable slave-ddl-exec-mode to STRICT.

CREATE TABLE IF NOT EXISTS
--------------------------

If the IF NOT EXISTS clause is used, then the table will only be created if a
table with the same name does not already exist. If the table already exists,
then a warning will be triggered by default.

CREATE TEMPORARY TABLE
----------------------

Use the TEMPORARY keyword to create a temporary table that is only available
to the current session. Temporary tables are dropped when the session ends.
Temporary table names are specific to the session. They will not conflict with
other temporary tables from other sessions even if they share the same name.
They will shadow names of non-temporary tables or views, if they are
identical. A temporary table can have the same name as a non-temporary table
which is located in the same database. In that case, their name will reference
the temporary table when used in SQL statements. You must have the CREATE
TEMPORARY TABLES privilege on the database to create temporary tables. If no
storage engine is specified, the default_tmp_storage_engine setting will
determine the engine.

ROCKSDB temporary tables cannot be created by setting the
default_tmp_storage_engine system variable, or using CREATE TEMPORARY TABLE
LIKE. Before MariaDB 10.7, they could be specified, but would silently fail,
and a MyISAM table would be created instead. From MariaDB 10.7 an error is
returned. Explicitly creating a temporary table with ENGINE=ROCKSDB has never
been permitted.

CREATE TABLE ... LIKE
---------------------

Use the LIKE clause instead of a full table definition to create a table with
the same definition as another table, including columns, indexes, and table
options. Foreign key definitions, as well as any DATA DIRECTORY or INDEX
DIRECTORY table options specified on the original table, will not be created.

CREATE TABLE ... SELECT
-----------------------

You can create a table containing data from other tables using the CREATE ...
SELECT statement. Columns will be created in the table for each field returned
by the SELECT query.

You can also define some columns normally and add other columns from a SELECT.
You can also create columns in the normal way and assign them some values
using the query, this is done to force a certain type or other field
characteristics. The columns that are not named in the query will be placed
before the others. For example:

CREATE TABLE test (a INT NOT NULL, b CHAR(10)) ENGINE=MyISAM
  SELECT 5 AS b, c, d FROM another_table;

Remember that the query just returns data. If you want to use the same
indexes, or the same columns attributes ([NOT] NULL, DEFAULT, AUTO_INCREMENT)
in the new table, you need to specify them manually. Types and sizes are not
automatically preserved if no data returned by the SELECT requires the full
size, and VARCHAR could be converted into CHAR. The CAST() function can be
used to forcee the new table to use certain types.

Aliases (AS) are taken into account, and they should always be used when you
SELECT an expression (function, arithmetical operation, etc).

If an error occurs during the query, the table will not be created at all.

If the new table has a primary key or UNIQUE indexes, you can use the IGNORE
or REPLACE keywords to handle duplicate key errors during the query. IGNORE
means that the newer values must not be inserted an identical value exists in
the index. REPLACE means that older values must be overwritten.

If the columns in the new table are more than the rows returned by the query,
the columns populated by the query will be placed after other columns. Note
that if the strict SQL_MODE is on, and the columns that are not names in the
query do not have a DEFAULT value, an error will raise and no rows will be
copied.

Concurrent inserts are not used during the execution of a CREATE ... SELECT.

If the table already exists, an error similar to the following will be
returned:

ERROR 1050 (42S01): Table 't' already exists

If the IF NOT EXISTS clause is used and the table exists, a note will be
produced instead of an error.

To insert rows from a query into an existing table, INSERT ... SELECT can be
used.

Column Definitions
------------------

create_definition:
 { col_name column_definition | index_definition | period_definition | CHECK
(expr) }
column_definition:
 data_type
  [NOT NULL | NULL] [DEFAULT default_value | (expression)]
  [ON UPDATE [NOW | CURRENT_TIMESTAMP] [(precision)]]
  [AUTO_INCREMENT] [ZEROFILL] [UNIQUE [KEY] | [PRIMARY] KEY]
  [INVISIBLE] [{WITH|WITHOUT} SYSTEM VERSIONING]
  [COMMENT 'string'] [REF_SYSTEM_ID = value]
  [reference_definition]
 | data_type [GENERATED ALWAYS]
 AS { { ROW {START|END} } | { (expression) [VIRTUAL | PERSISTENT | STORED] } }
   [UNIQUE [KEY]] [COMMENT 'string']
constraint_definition:
 CONSTRAINT [constraint_name] CHECK (expr�}?ession)
Note: Until MariaDB 10.4, MariaDB accepts the shortcut format with a
REFERENCES clause only in ALTER TABLE and CREATE TABLE statements, but that
syntax does nothing. For example:

CREATE TABLE b(for_key INT REFERENCES a(not_key));

MariaDB simply parses it without returning any error or warning, for
compatibility with other DBMS's. Before MariaDB 10.2.1 this was also true for
CHECK constraints. However, only the syntax described below creates foreign
keys.

From MariaDB 10.5, MariaDB will attempt to apply the constraint. See Foreign
Keys examples.

Each definition either creates a column in the table or specifies and index or
constraint on one or more columns. See Indexes below for details on creating
indexes.

Create a column by specifying a column name and a data type, optionally
followed by column options. See Data Types for a full list of data types
allowed in MariaDB.

NULL and NOT NULL
-----------------

Use the NULL or NOT NULL options to specify that values in the column may or
may not be NULL, respectively. By default, values may be NULL. See also NULL
Values in MariaDB.

DEFAULT Column Option
---------------------

Specify a default value using the DEFAULT clause. If you don't specify DEFAULT
then the following rules apply:

* If the column is not defined with NOT NULL, AUTO_INCREMENT or TIMESTAMP, an
explicit DEFAULT NULL will be added.
Note that in MySQL and in MariaDB before 10.1.6, you may get an explicit
DEFAULT for primary key parts, if not specified with NOT NULL.

The default value will be used if you INSERT a row without specifying a value
for that column, or if you specify DEFAULT for that column. Before MariaDB
10.2.1 you couldn't usually provide an expression or function to evaluate at
insertion time. You had to provide a constant default value instead. The one
exception is that you may use CURRENT_TIMESTAMP as the default value for a
TIMESTAMP column to use the current timestamp at insertion time.

CURRENT_TIMESTAMP may also be used as the default value for a DATETIME

You can use most functions in DEFAULT. Expressions should have parentheses
around them. If you use a non deterministic function in DEFAULT then all
inserts to the table will be replicated in row mode. You can even refer to
earlier columns in the DEFAULT expression (excluding AUTO_INCREMENT columns):

CREATE TABLE t1 (a int DEFAULT (1+1), b int DEFAULT (a+1));
CREATE TABLE t2 (a bigint primary key DEFAULT UUID_SHORT());

The DEFAULT clause cannot contain any stored functions or subqueries, and a
column used in the clause must already have been defined earlier in the
statement.

It is possible to assign BLOB or TEXT columns a DEFAULT value. In versions
prior to MariaDB 10.2.1, assigning a default to these columns was not possible.

You can also use DEFAULT (NEXT VALUE FOR sequence)

AUTO_INCREMENT Column Option
----------------------------

Use AUTO_INCREMENT to create a column whose value can can be set automatically
from a simple counter. You can only use AUTO_INCREMENT on a column with an
integer type. The column must be a key, and there can only be one
AUTO_INCREMENT column in a table. If you insert a row without specifying a
value for that column (or if you specify 0, NULL, or DEFAULT as the value),
the actual value will be taken from the counter, with each insertion
incrementing the counter by one. You can still insert a value explicitly. If
you insert a value that is greater than the current counter value, the counter
is set based on the new value. An AUTO_INCREMENT column is implicitly NOT
NULL. Use LAST_INSERT_ID to get the AUTO_INCREMENT value most recently used by
an INSERT statement.

ZEROFILL Column Option
----------------------

If the ZEROFILL column option is specified for a column using a numeric data
type, then the column will be set to UNSIGNED and the spaces used by default
to pad the field are replaced with zeros. ZEROFILL is ignored in expressions
or as part of a UNION. ZEROFILL is a non-standard MySQL and MariaDB
enhancement.

PRIMARY KEY Column Option
-------------------------

Use PRIMARY KEY to make a column a primary key. A primary key is a special
type of a unique key. There can be at most one primary key per table, and it
is implicitly NOT NULL.

Specifying a column as a unique key creates a unique index on that column. See
the Index Definitions section below for more information.

UNIQUE KEY Column Option
------------------------

Use UNIQUE KEY (or just UNIQUE) to specify that all values in the column must
be distinct from each other. Unless the column is NOT NULL, there may be
multiple rows with NULL in the column.

Specifying a column as a unique key creates a unique index on that column.

See the Index Definitions section below for more information.

COMMENT Column Option
---------------------

You can provide a comment for each column using the COMMENT clause. The
maximum length is 1024 characters. Use the SHOW FULL COLUMNS statement to see
column comments.

REF_SYSTEM_ID
-------------

REF_SYSTEM_ID can be used to specify Spatial Reference System IDs for spatial
data type columns. For example:

CREATE TABLE t1(g GEOMETRY(9,4) REF_SYSTEM_ID=101);

Generated Columns
-----------------

A generated column is a column in a table that cannot explicitly be set to a
specific value in a DML query. Instead, its value is automatically generated
based on an expression. This expression might generate the value based on the
values of other columns in the table, or it might generate the value by
calling built-in functions or user-defined functions (UDFs).

There are two types of generated columns:

* PERSISTENT or STORED: This type's value is actually stored in the table.
* VIRTUAL: This type's value is not stored at all. Instead, the value is
generated dynamically when the table is queried. This type is the default.

Generated columns are also sometimes called computed columns or virtual
columns.

For a complete description about generated columns and their limitations, see
Generated (Virtual and Persistent/Stored) Columns.

COMPRESSED
----------

Certain columns may be compressed. See Storage-Engine Independent Column
Compression.

INVISIBLE
---------

Columns may be made invisible, and hidden in certain contexts. See Invisible
Columns.

WITH SYSTEM VERSIONING Column Option
------------------------------------

Columns may be explicitly marked as included from system versioning. See
System-versioned tables for details.

WITHOUT SYSTEM VERSIONING Column Option
---------------------------------------

Columns may be explicitly marked as excluded from system versioning. See
System-versioned tables for details.

Index Definitions
-----------------

index_definition:
  {INDEX|KEY} [index_name] [index_type] (index_col_name,...) [index_option]
...
 {{{|}}} {FULLTEXT|SPATIAL} [INDEX|KEY] [index_name] (index_col_name,...)
[index_option] ...
 {{{|}}} [CONSTRAINT [symbol]] PRIMARY KEY [index_type] (index_col_name,...)
[index_option] ...
 {{{|}}} [CONSTRAINT [symbol]] UNIQUE [INDEX|KEY] [index_name] [index_type]
(index_col_name,...) [index_option] ...
 {{{|}}} [CONSTRAINT [symbol]] FOREIGN KEY [index_name] (index_col_name,...)
reference_definition

index_col_name:
  col_name [(length)] [ASC | DESC]

index_type:
  USING {BTREE | HASH | RTREE}

index_option:
  [ KEY_BLOCK_SIZE [=] value
 {{{|}}} index_type
 {{{|}}} WITH PARSER parser_name
 {{{|}}} COMMENT 'string'
 {{{|}}} CLUSTERING={YES| NO} ]
 [ IGNORED | NOT IGNORED ]

reference_definition:
  REFERENCES tbl_name (index_col_name,...)
   [MATCH FULL | MATCH PARTIAL | MATCH SIMPLE]
   [ON DELETE reference_option]
   [ON UPDATE reference_option]

reference_option:
  RESTRICT | CASCADE | SET NULL | NO ACTION

INDEX and KEY are synonyms.

Index names are optional, if not specified an automatic name will be assigned.
Index name are needed to drop indexes and appear in error messages when a
constraint is violated.

Index Categories
----------------

Plain Indexes
-------------

Plain indexes are regular indexes that are not unique, and are not acting as a
primary key or a foreign key. They are also not the "specialized" FULLTEXT or
SPATIAL indexes.

See Getting Started with Insl,Gdexes: Plain Indexes for more information.

PRIMARY KEY
-----------

For PRIMARY KEY indexes, you can specify a name for the index, but it is
ignored, and the name of the index is always PRIMARY. From MariaDB 10.3.18 and
MariaDB 10.4.8, a warning is explicitly issued if a name is specified. Before
then, the name was silently ignored.

See Getting Started with Indexes: Primary Key for more information.

UNIQUE
------

The UNIQUE keyword means that the index will not accept duplicated values,
except for NULLs. An error will raise if you try to insert duplicate values in
a UNIQUE index.

For UNIQUE indexes, you can specify a name for the constraint, using the
CONSTRAINT keyword. That name will be used in error messages.

MariaDB starting with 10.5
--------------------------
Unique, if index type is not specified, is normally a BTREE index that can
also be used by the optimizer to find rows. If the key is longer than the max
key length for the used storage engine, a HASH key will be created. This
enables MariaDB to enforce uniqueness for any type or number of columns.

See Getting Started with Indexes: Unique Index for more information.

FOREIGN KEY
-----------

For FOREIGN KEY indexes, a reference definition must be provided.

For FOREIGN KEY indexes, you can specify a name for the constraint, using the
CONSTRAINT keyword. That name will be used in error messages.

First, you have to specify the name of the target (parent) table and a column
or a column list which must be indexed and whose values must match to the
foreign key's values. The MATCH clause is accepted to improve the
compatibility with other DBMS's, but has no meaning in MariaDB. The ON DELETE
and ON UPDATE clauses specify what must be done when a DELETE (or a REPLACE)
statements attempts to delete a referenced row from the parent table, and when
an UPDATE statement attempts to modify the referenced foreign key columns in a
parent table row, respectively. The following options are allowed:

* RESTRICT: The delete/update operation is not performed.  The statement
terminates with a 1451 error (SQLSTATE '2300').
* NO ACTION: Synonym for RESTRICT.
* CASCADE: The delete/update operation is performed in both tables.
* SET NULL: The update or delete goes ahead in the parent table, and the
corresponding foreign key fields in the child table are set to NULL.  (They
must not be defined as NOT NULL for this to succeed).
* SET DEFAULT: This option is currently implemented only for the PBXT storage
engine, which is disabled by default and no longer maintained. It sets the
child table's foreign key fields to their DEFAULT values when the referenced
parent table key entries are updated or deleted.

If either clause is omitted, the default behavior for the omitted clause is
RESTRICT.

See Foreign Keys for more information.

FULLTEXT
--------

Use the FULLTEXT keyword to create full-text indexes.

See Full-Text Indexes for more information.

SPATIAL
-------

Use the SPATIAL keyword to create geometric indexes.

See SPATIAL INDEX for more information.

Index Options
-------------

KEY_BLOCK_SIZE Index Option
---------------------------

The KEY_BLOCK_SIZE index option is similar to the KEY_BLOCK_SIZE table option.

With the InnoDB storage engine, if you specify a non-zero value for the
KEY_BLOCK_SIZE table option for the whole table, then the table will
implicitly be created with the ROW_FORMAT table option set to COMPRESSED.
However, this does not happen if you just set the KEY_BLOCK_SIZE index option
for one or more indexes in the table. The InnoDB storage engine ignores the
KEY_BLOCK_SIZE index option. However, the SHOW CREATE TABLE statement may
still report it for the index.

For information about the KEY_BLOCK_SIZE index option, see the KEY_BLOCK_SIZE
table option below.

Index Types
-----------

Each storage engine supports some or all index types. See Storage Engine Index
Types for details on permitted index types for each storage engine.

Different index types are optimized for different kind of operations:

* BTREE is the default type, and normally is the best choice. It is supported
by all storage engines. It can be used to compare a column's value with a
value using the =, >, >=, <, <=, BETWEEN, and LIKE operators. BTREE can also
be used to find NULL values. Searches against an index prefix are possible.
* HASH is only supported by the MEMORY storage engine. HASH indexes can only
be used for =, <=, and >= comparisons. It can not be used for the ORDER BY
clause. Searches against an index prefix are not possible.
* RTREE is the default for SPATIAL indexes, but if the storage engine does not
support it BTREE can be used.

Index columns names are listed between parenthesis. After each column, a
prefix length can be specified. If no length is specified, the whole column
will be indexed. ASC and DESC can be specified for compatibility with are
DBMS's, but have no meaning in MariaDB.

WITH PARSER Index Option
------------------------

The WITH PARSER index option only applies to FULLTEXT indexes and contains the
fulltext parser name. The fulltext parser must be an installed plugin.

COMMENT Index Option
--------------------

A comment of up to 1024 characters is permitted with the COMMENT index option.

The COMMENT index option allows you to specify a comment with user-readable
text describing what the index is for. This information is not used by the
server itself.

CLUSTERING Index Option
-----------------------

The CLUSTERING index option is only valid for tables using the TokuDB storage
engine.

IGNORED / NOT IGNORED
---------------------

MariaDB starting with 10.6.0
----------------------------
From MariaDB 10.6.0, indexes can be specified to be ignored by the optimizer.
See Ignored Indexes.

Periods
-------

period_definition:
  PERIOD FOR SYSTEM_TIME (start_column_name, end_column_name)
MariaDB supports a subset of the standard syntax for periods. At the moment
it's only used for creating System-versioned tables. Both columns must be
created, must be either of a TIMESTAMP(6) or BIGINT UNSIGNED type, and be
generated as ROW START and ROW END accordingly. See System-versioned tables
for details.

The table must also have the WITH SYSTEM VERSIONING clause.

Constraint Expressions
----------------------

Note: Before MariaDB 10.2.1, constraint expressions were accepted in the
syntax but ignored.

MariaDB 10.2.1 introduced two ways to define a constraint:

* CHECK(expression) given as part of a column definition.
* CONSTRAINT [constraint_name] CHECK (expression)

Before a row is inserted or updated, all constraints are evaluated in the
order they are defined. If any constraints fails, then the row will not be
updated. One can use most deterministic functions in a constraint, including
UDFs.

create table t1 (a int check(a>0) ,b int check (b> 0), constraint abc check
(a>b));

If you use the second format and you don't give a name to the constraint, then
the constraint will get a auto generated name. This is done so that you can
later delete the constraint with ALTER TABLE DROP constraint_name.

One can disable all constraint expression checks by setting the variable
check_constraint_checks to OFF. This is useful for example when loading a
table that violates some constraints that you want to later find and fix in
SQL.

See CONSTRAINT for more information.

Table Options
-------------

For each individual table you create (or alter), you can set some table
options. The general syntax for setting options is:

<OPTION_NAME> = <option_value>, [<OPTION_NAME> = <option_value> ...]

The equal sign is optional.

Some options are supported by the server and can be used for all tables, no
matter what storage engine they use; other options can be specified for all
storage engines, but have a meaning only for some engines. Also, engines can
extend CREATE TABLE with new options.

If the IGNORE_BAD_TABLE_OPTIONS SQL_MODE is enabled, wrong table options
generate a warning; otherwise, they generate an error.

table_option:    
  [STORAGE] ENGINE [=] engine_name
 | AUTO_INCREMENT [=] value
 | AVG_ROW_LENGTH [=] value
 | [DEFAULT] CHARACTER SET [=] charset_name
 | CHECKSUM [=] {0 | 1}
 | [DEFA�thULT] COLLATE [=] collation_name
 | COMMENT [=] 'string'
 | CONNECTION [=] 'connect_string'
 | DATA DIRECTORY [=] 'absolute path to directory'
 | DELAY_KEY_WRITE [=] {0 | 1}
 | ENCRYPTED [=] {YES | NO}
 | ENCRYPTION_KEY_ID [=] value
 | IETF_QUOTES [=] {YES | NO}
 | INDEX DIRECTORY [=] 'absolute path to directory'
 | INSERT_METHOD [=] { NO | FIRST | LAST }
 | KEY_BLOCK_SIZE [=] value
 | MAX_ROWS [=] value
 | MIN_ROWS [=] value
 | PACK_KEYS [=] {0 | 1 | DEFAULT}
 | PAGE_CHECKSUM [=] {0 | 1}
 | PAGE_COMPRESSED [=] {0 | 1}
 | PAGE_COMPRESSION_LEVEL [=] {0 .. 9}
 | PASSWORD [=] 'string'
 | ROW_FORMAT [=] {DEFAULT|DYNAMIC|FIXED|COMPRESSED|REDUNDANT|COMPACT|PAGE}
 | SEQUENCE [=] {0|1}
 | STATS_AUTO_RECALC [=] {DEFAULT|0|1}
 | STATS_PERSISTENT [=] {DEFAULT|0|1}
 | STATS_SAMPLE_PAGES [=] {DEFAULT|value}
 | TABLESPACE tablespace_name
 | TRANSACTIONAL [=]  {0 | 1}
 | UNION [=] (tbl_name[,tbl_name]...)
 | WITH SYSTEM VERSIONING

[STORAGE] ENGINE
----------------

[STORAGE] ENGINE specifies a storage engine for the table. If this option is
not used, the default storage engine is used instead. That is, the
default_storage_engine session option value if it is set, or the value
specified for the --default-storage-engine mysqld startup option, or the
default storage engine, InnoDB. If the specified storage engine is not
installed and active, the default value will be used, unless the
NO_ENGINE_SUBSTITUTION SQL MODE is set (default). This is only true for CREATE
TABLE, not for ALTER TABLE. For a list of storage engines that are present in
your server, issue a SHOW ENGINES.

AUTO_INCREMENT
--------------

AUTO_INCREMENT specifies the initial value for the AUTO_INCREMENT primary key.
This works for MyISAM, Aria, InnoDB, MEMORY, and ARCHIVE tables. You can
change this option with ALTER TABLE, but in that case the new value must be
higher than the highest value which is present in the AUTO_INCREMENT column.
If the storage engine does not support this option, you can insert (and then
delete) a row having the wanted value - 1 in the AUTO_INCREMENT column.

AVG_ROW_LENGTH
--------------

AVG_ROW_LENGTH is the average rows size. It only applies to tables using
MyISAM and Aria storage engines that have the ROW_FORMAT table option set to
FIXED format.

MyISAM uses MAX_ROWS and AVG_ROW_LENGTH to decide the maximum size of a table
(default: 256TB, or the maximum file size allowed by the system).

[DEFAULT] CHARACTER SET/CHARSET
-------------------------------

[DEFAULT] CHARACTER SET (or [DEFAULT] CHARSET) is used to set a default
character set for the table. This is the character set used for all columns
where an explicit character set is not specified. If this option is omitted or
DEFAULT is specified, database's default character set will be used. See
Setting Character Sets and Collations for details on setting the character
sets.

CHECKSUM/TABLE_CHECKSUM
-----------------------

CHECKSUM (or TABLE_CHECKSUM) can be set to 1 to maintain a live checksum for
all table's rows. This makes write operations slower, but CHECKSUM TABLE will
be very fast. This option is only supported for MyISAM and Aria tables.

[DEFAULT] COLLATE
-----------------

[DEFAULT] COLLATE is used to set a default collation for the table. This is
the collation used for all columns where an explicit character set is not
specified. If this option is omitted or DEFAULT is specified, database's
default option will be used. See Setting Character Sets and Collations for
details on setting the collations

COMMENT
-------

COMMENT is a comment for the table. The maximum length is 2048 characters.
Also used to define table parameters when creating a Spider table.

CONNECTION
----------

CONNECTION is used to specify a server name or a connection string for a
Spider, CONNECT, Federated or FederatedX table.

DATA DIRECTORY/INDEX DIRECTORY
------------------------------

DATA DIRECTORY and INDEX DIRECTORY are supported for MyISAM and Aria, and DATA
DIRECTORY is also supported by InnoDB if the innodb_file_per_table server
system variable is enabled, but only in CREATE TABLE, not in ALTER TABLE. So,
carefully choose a path for InnoDB tables at creation time, because it cannot
be changed without dropping and re-creating the table. These options specify
the paths for data files and index files, respectively. If these options are
omitted, the database's directory will be used to store data files and index
files. Note that these table options do not work for partitioned tables (use
the partition options instead), or if the server has been invoked with the
--skip-symbolic-links startup option. To avoid the overwriting of old files
with the same name that could be present in the directories, you can use the
--keep_files_on_create option (an error will be issued if files already
exist). These options are ignored if the NO_DIR_IN_CREATE SQL_MODE is enabled
(useful for replication slaves). Also note that symbolic links cannot be used
for InnoDB tables.

DATA DIRECTORY works by creating symlinks from where the table would normally
have been (inside the datadir) to where the option specifies. For security
reasons, to avoid bypassing the privilege system, the server does not permit
symlinks inside the datadir. Therefore, DATA DIRECTORY cannot be used to
specify a location inside the datadir. An attempt to do so will result in an
error 1210 (HY000) Incorrect arguments to DATA DIRECTORY.

DELAY_KEY_WRITE
---------------

DELAY_KEY_WRITE is supported by MyISAM and Aria, and can be set to 1 to speed
up write operations. In that case, when data are modified, the indexes are not
updated until the table is closed. Writing the changes to the index file
altogether can be much faster. However, note that this option is applied only
if the delay_key_write server variable is set to 'ON'. If it is 'OFF' the
delayed index writes are always disabled, and if it is 'ALL' the delayed index
writes are always used, disregarding the value of DELAY_KEY_WRITE.

ENCRYPTED
---------

The ENCRYPTED table option can be used to manually set the encryption status
of an InnoDB table. See InnoDB Encryption for more information.

Aria does not support the ENCRYPTED table option. See MDEV-18049.

See Data-at-Rest Encryption for more information.

ENCRYPTION_KEY_ID
-----------------

The ENCRYPTION_KEY_ID table option can be used to manually set the encryption
key of an InnoDB table. See InnoDB Encryption for more information.

Aria does not support the ENCRYPTION_KEY_ID table option. See MDEV-18049.

See Data-at-Rest Encryption for more information.

IETF_QUOTES
-----------

For the CSV storage engine, the IETF_QUOTES option, when set to YES, enables
IETF-compatible parsing of embedded quote and comma characters. Enabling this
option for a table improves compatibility with other tools that use CSV, but
is not compatible with MySQL CSV tables, or MariaDB CSV tables created without
this option. Disabled by default.

INSERT_METHOD
-------------

INSERT_METHOD is only used with MERGE tables. This option determines in which
underlying table the new rows should be inserted. If you set it to 'NO' (which
is the default) no new rows can be added to the table (but you will still be
able to perform INSERTs directly against the underlying tables). FIRST means
that the rows are inserted into the first table, and LAST means that thet are
inserted into the last table.

KEY_BLOCK_SIZE
--------------

KEY_BLOCK_SIZE is used to determine the size of key blocks, in bytes or
kilobytes. However, this value is just a hint, and the storage engine could
modify or ignore it. If KEY_BLOCK_SIZE is set to 0, the storage engine's
default value will be used.

With the InnoDB storage engine, if you specify a non-zero value for the
KEY_BLOCK_SIZE table option for the whole table, then the table will
implicitly be created with the ROW_FORMAT table option set to COMPRESSED.

MIN_ROWS/MAX_ROWS
-----------------

MIN_ROWS and MAX_ROWS let the storage engine know how many rows you are
planning to store as a minimum and as a maximum. These values will not be used
as real limits, but they help the storage engine to optimize the table.
MIN_ROWS is only used by MEMORY storage engine E��yto decide the minimum memory
that is always allocated. MAX_ROWS is used to decide the minimum size for
indexes.

PACK_KEYS
---------

PACK_KEYS can be used to determine whether the indexes will be compressed. Set
it to 1 to compress all keys. With a value of 0, compression will not be used.
With the DEFAULT value, only long strings will be compressed. Uncompressed
keys are faster.

PAGE_CHECKSUM
-------------

PAGE_CHECKSUM is only applicable to Aria tables, and determines whether
indexes and data should use page checksums for extra safety.

PAGE_COMPRESSED
---------------

PAGE_COMPRESSED is used to enable InnoDB page compression for InnoDB tables.

PAGE_COMPRESSION_LEVEL
----------------------

PAGE_COMPRESSION_LEVEL is used to set the compression level for InnoDB page
compression for InnoDB tables. The table must also have the PAGE_COMPRESSED
table option set to 1.

Valid values for PAGE_COMPRESSION_LEVEL are 1 (the best speed) through 9 (the
best compression), .

PASSWORD
--------

PASSWORD is unused.

RAID_TYPE
---------

RAID_TYPE is an obsolete option, as the raid support has been disabled since
MySQL 5.0.

ROW_FORMAT
----------

The ROW_FORMAT table option specifies the row format for the data file.
Possible values are engine-dependent.

Supported MyISAM Row Formats
----------------------------

For MyISAM, the supported row formats are:

* FIXED
* DYNAMIC
* COMPRESSED

The COMPRESSED row format can only be set by the myisampack command line tool.

See MyISAM Storage Formats for more information.

Supported Aria Row Formats
--------------------------

For Aria, the supported row formats are:

* PAGE
* FIXED
* DYNAMIC.

See Aria Storage Formats for more information.

Supported InnoDB Row Formats
----------------------------

For InnoDB, the supported row formats are:

* COMPACT
* REDUNDANT
* COMPRESSED
* DYNAMIC.

If the ROW_FORMAT table option is set to FIXED for an InnoDB table, then the
server will either return an error or a warning depending on the value of the
innodb_strict_mode system variable. If the innodb_strict_mode system variable
is set to OFF, then a warning is issued, and MariaDB will create the table
using the default row format for the specific MariaDB server version. If the
innodb_strict_mode system variable is set to ON, then an error will be raised.

See InnoDB Storage Formats for more information.

Other Storage Engines and ROW_FORMAT
------------------------------------

Other storage engines do not support the ROW_FORMAT table option.

SEQUENCE
--------

If the table is a sequence, then it will have the SEQUENCE set to 1.

STATS_AUTO_RECALC
-----------------

STATS_AUTO_RECALC indicates whether to automatically recalculate persistent
statistics (see STATS_PERSISTENT, below) for an InnoDB table. If set to 1,
statistics will be recalculated when more than 10% of the data has changed.
When set to 0, stats will be recalculated only when an ANALYZE TABLE is run.
If set to DEFAULT, or left out, the value set by the innodb_stats_auto_recalc
system variable applies. See InnoDB Persistent Statistics.

STATS_PERSISTENT
----------------

STATS_PERSISTENT indicates whether the InnoDB statistics created by ANALYZE
TABLE will remain on disk or not. It can be set to 1 (on disk), 0 (not on
disk, the pre-MariaDB 10 behavior), or DEFAULT (the same as leaving out the
option), in which case the value set by the innodb_stats_persistent system
variable will apply. Persistent statistics stored on disk allow the statistics
to survive server restarts, and provide better query plan stability. See
InnoDB Persistent Statistics.

STATS_SAMPLE_PAGES
------------------

STATS_SAMPLE_PAGES indicates how many pages are used to sample index
statistics. If 0 or DEFAULT, the default value, the innodb_stats_sample_pages
value is used. See InnoDB Persistent Statistics.

TRANSACTIONAL
-------------

TRANSACTIONAL is only applicable for Aria tables. In future Aria tables
created with this option will be fully transactional, but currently this
provides a form of crash protection. See Aria Storage Engine for more details.

UNION
-----

UNION must be specified when you create a MERGE table. This option contains a
comma-separated list of MyISAM tables which are accessed by the new table. The
list is enclosed between parenthesis. Example: UNION = (t1,t2)

WITH SYSTEM VERSIONING
----------------------

WITH SYSTEM VERSIONING is used for creating System-versioned tables.

Partitions
----------

partition_options:
  PARTITION BY
    { [LINEAR] HASH(expr)
    | [LINEAR] KEY(column_list)
    | RANGE(expr)
    | LIST(expr)
    | SYSTEM_TIME [INTERVAL time_quantity time_unit] [LIMIT num] }
  [PARTITIONS num]
  [SUBPARTITION BY
    { [LINEAR] HASH(expr)
    | [LINEAR] KEY(column_list) }
   [SUBPARTITIONS num]
  ]
  [(partition_definition [, partition_definition] ...)]
partition_definition:
  PARTITION partition_name
    [VALUES {LESS THAN {(expr) | MAXVALUE} | IN (value_list)}]
    [[STORAGE] ENGINE [=] engine_name]
    [COMMENT [=] 'comment_text' ]
    [DATA DIRECTORY [=] 'data_dir']
    [INDEX DIRECTORY [=] 'index_dir']
    [MAX_ROWS [=] max_number_of_rows]
    [MIN_ROWS [=] min_number_of_rows]
    [TABLESPACE [=] tablespace_name]
    [NODEGROUP [=] node_group_id]
    [(subpartition_definition [, subpartition_definition] ...)]
subpartition_definition:
  SUBPARTITION logical_name
    [[STORAGE] ENGINE [=] engine_name]
    [COMMENT [=] 'comment_text' ]
    [DATA DIRECTORY [=] 'data_dir']
    [INDEX DIRECTORY [=] 'index_dir']
    [MAX_ROWS [=] max_number_of_rows]
    [MIN_ROWS [=] min_number_of_rows]
    [TABLESPACE [=] tablespace_name]
    [NODEGROUP [=] node_group_id]
If the PARTITION BY clause is used, the table will be partitioned. A partition
method must be explicitly indicated for partitions and subpartitions.
Partition methods are:

* [LINEAR] HASH creates a hash key which will be used to read and write rows.
The partition function can be any valid SQL expression which returns an
INTEGER number. Thus, it is possible to use the HASH method on an integer
column, or on functions which accept integer columns as an argument. However,
VALUES LESS THAN and VALUES IN clauses can not be used with HASH. An example:

CREATE TABLE t1 (a INT, b CHAR(5), c DATETIME)
  PARTITION BY HASH ( YEAR(c) );

[LINEAR] HASH can be used for subpartitions, too.

* [LINEAR] KEY is similar to HASH, but the index has an even distribution of
data. Also, the expression can only be a column or a list of columns. VALUES
LESS THAN and VALUES IN clauses can not be used with KEY.
* RANGE partitions the rows using on a range of values, using the VALUES LESS
THAN operator. VALUES IN is not allowed with RANGE. The partition function can
be any valid SQL expression which returns a single value.
* LIST assigns partitions based on a table's column with a restricted set of
possible values. It is similar to RANGE, but VALUES IN must be used for at
least 1 columns, and VALUES LESS THAN is disallowed.
* SYSTEM_TIME partitioning is used for System-versioned tables to store
historical data separately from current data.

Only HASH and KEY can be used for subpartitions, and they can be [LINEAR].

It is possible to define up to 1024 partitions and subpartitions.

The number of defined partitions can be optionally specified as PARTITION
count. This can be done to avoid specifying all partitions individually. But
you can also declare each individual partition and, additionally, specify a
PARTITIONS count clause; in the case, the number of PARTITIONs must equal
count.

Also see Partitioning Types Overview.

Sequences
---------

CREATE TABLE can also be used to create a SEQUENCE. See CREATE SEQUENCE and
Sequence Overview.

Atomic DDL
----------

MariaDB starting with 10.6.1
----------------------------
MariaDB 10.6.1 supports Atomic DDL. CREATE TABLE is atomic, except for CREATE
OR REPLACE, which is only crash safe.

Examples
--------

create table if not exists test (
a bigint auto_increment primary key,
name varchar(128) charset utf8,
key name (name(32))
) engine=InnoDB default charset latin1;

This example shows a couple of things:

* Usage of IF NOT EXISTS; If the table already existed, it wic]�sSyntax
------

CREATE [OR REPLACE]
  [DEFINER = {user | CURRENT_USER | role | CURRENT_ROLE }]
  [AGGREGATE] FUNCTION [IF NOT EXISTS] func_name ([func_parameter[,...]])
  RETURNS type
  [characteristic ...]
  RETURN func_body
func_parameter:
  [ IN | OUT | INOUT | IN OUT ]  param_name type
type:
  Any valid MariaDB data type
characteristic:
  LANGUAGE SQL
 | [NOT] DETERMINISTIC
 | { CONTAINS SQL | NO SQL | READS SQL DATA | MODIFIES SQL DATA }
 | SQL SECURITY { DEFINER | INVOKER }
 | COMMENT 'string'
func_body:
  Valid SQL procedure statement

Description
-----------

Use the CREATE FUNCTION statement to create a new stored function. You must
have the CREATE ROUTINE database privilege to use CREATE FUNCTION. A function
takes any number of arguments and returns a value from the function body. The
function body can be any valid SQL expression as you would use, for example,
in any select expression. If you have the appropriate privileges, you can call
the function exactly as you would any built-in function. See Security below
for details on privileges.

You can also use a variant of the CREATE FUNCTION statement to install a
user-defined function (UDF) defined by a plugin. See CREATE FUNCTION (UDF) for
details.

You can use a SELECT statement for the function body by enclosing it in
parentheses, exactly as you would to use a subselect for any other expression.
The SELECT statement must return a single value. If more than one column is
returned when the function is called, error 1241 results. If more than one row
is returned when the function is called, error 1242 results. Use a LIMIT
clause to ensure only one row is returned.

You can also replace the RETURN clause with a BEGIN...END compound statement.
The compound statement must contain a RETURN statement. When the function is
called, the RETURN statement immediately returns its result, and any
statements after RETURN are effectively ignored.

By default, a function is associated with the current database. To associate
the function explicitly with a given database, specify the fully-qualified
name as db_name.func_name when you create it. If the function name is the same
as the name of a built-in function, you must use the fully qualified name when
you call it.

The parameter list enclosed within parentheses must always be present. If
there are no parameters, an empty parameter list of () should be used.
Parameter names are not case sensitive.

Each parameter can be declared to use any valid data type, except that the
COLLATE attribute cannot be used.

For valid identifiers to use as function names, see Identifier Names.

IN | OUT | INOUT | IN OUT
-------------------------

MariaDB starting with 10.8.0
----------------------------
The function parameter qualifiers for IN, OUT, INOUT, and IN OUT were added in
a 10.8.0 preview release. Prior to 10.8.0 quantifiers were supported only in
procedures.

OUT, INOUT and its equivalent IN OUT, are only valid if called from SET and
not SELECT. These quantifiers are especially useful for creating functions
with more than one return value. This allows functions to be more complex and
nested.

DELIMITER $$
CREATE FUNCTION add_func3(IN a INT, IN b INT, OUT c INT) RETURNS INT
BEGIN
 SET c = 100;
 RETURN a + b;
END;
$$
DELIMITER ;

SET @a = 2;
SET @b = 3;
SET @c = 0;
SET @res= add_func3(@a, @b, @c);

SELECT add_func3(@a, @b, @c);
ERROR 4186 (HY000): OUT or INOUT argument 3 for function add_func3 is not
allowed here

DELIMITER $$
CREATE FUNCTION add_func4(IN a INT, IN b INT, d INT) RETURNS INT
BEGIN
 DECLARE c, res INT;
 SET res = add_func3(a, b, c) + d;
 if (c > 99) then
  return  3;
 else
  return res;
 end if;
END;
$$

DELIMITER ;

SELECT add_func4(1,2,3);
+------------------+
| add_func4(1,2,3) |
+------------------+
|                3 |
+------------------+

AGGREGATE
---------

It is possible to create stored aggregate functions as well. See Stored
Aggregate Functions for details.

RETURNS
-------

The RETURNS clause specifies the return type of the function. NULL values are
permitted with all return types.

What happens if the RETURN clause returns a value of a different type? It
depends on the SQL_MODE in effect at the moment of the function creation.

If the SQL_MODE is strict (STRICT_ALL_TABLES or STRICT_TRANS_TABLES flags are
specified), a 1366 error will be produced.

Otherwise, the value is coerced to the proper type. For example, if a function
specifies an ENUM or SET value in the RETURNS clause, but the RETURN clause
returns an integer, the value returned from the function is the string for the
corresponding ENUM member of set of SET members.

MariaDB stores the SQL_MODE system variable setting that is in effect at the
time a routine is created, and always executes the routine with this setting
in force, regardless of the server SQL mode in effect when the routine is
invoked.

LANGUAGE SQL
------------

LANGUAGE SQL is a standard SQL clause, and it can be used in MariaDB for
portability. However that clause has no meaning, because SQL is the only
supported language for stored functions.

A function is deterministic if it can produce only one result for a given list
of parameters. If the result may be affected by stored data, server variables,
random numbers or any value that is not explicitly passed, then the function
is not deterministic. Also, a function is non-deterministic if it uses
non-deterministic functions like NOW() or CURRENT_TIMESTAMP(). The optimizer
may choose a faster execution plan if it known that the function is
deterministic. In such cases, you should declare the routine using the
DETERMINISTIC keyword. If you want to explicitly state that the function is
not deterministic (which is the default) you can use the NOT DETERMINISTIC
keywords.

If you declare a non-deterministic function as DETERMINISTIC, you may get
incorrect results. If you declare a deterministic function as NOT
DETERMINISTIC, in some cases the queries will be slower.

OR REPLACE
----------

If the optional OR REPLACE clause is used, it acts as a shortcut for:

DROP FUNCTION IF EXISTS function_name;
CREATE FUNCTION function_name ...;

with the exception that any existing privileges for the function are not
dropped.

IF NOT EXISTS
-------------

If the IF NOT EXISTS clause is used, MariaDB will return a warning instead of
an error if the function already exists. Cannot be used together with OR
REPLACE.

[NOT] DETERMINISTIC
-------------------

The [NOT] DETERMINISTIC clause also affects binary logging, because the
STATEMENT format can not be used to store or replicate non-deterministic
statements.

CONTAINS SQL, NO SQL, READS SQL DATA, and MODIFIES SQL DATA are informative
clauses that tell the server what the function does. MariaDB does not check in
any way whether the specified clause is correct. If none of these clauses are
specified, CONTAINS SQL is used by default.

MODIFIES SQL DATA
-----------------

MODIFIES SQL DATA means that the function contains statements that may modify
data stored in databases. This happens if the function contains statements
like DELETE, UPDATE, INSERT, REPLACE or DDL.

READS SQL DATA
--------------

READS SQL DATA means that the function reads data stored in databases, but
does not modify any data. This happens if SELECT statements are used, but
there no write operations are executed.

CONTAINS SQL
------------

CONTAINS SQL means that the function contains at least one SQL statement, but
it does not read or write any data stored in a database. Examples include SET
or DO.

NO SQL
------

NO SQL means nothing, because MariaDB does not currently support any language
other than SQL.

Oracle Mode
-----------

A subset of Oracle's PL/SQL language is supported in addition to the
traditional SQL/PSM-based MariaDB syntax. See Oracle mode for details on
changes when running Oracle mode.

Security
--------

You must have the EXECUTE privilege on a function to call it. MariaDB
automatically grants the EXECUTE and ALTER ROUTINE privileges to the account
that called CREATE FUNCTION, even if the DEFINER clause was used.

Each function has an account associated as the definer. By default, the
definer is the account that created th1��Syntax
------

CREATE
  [OR REPLACE]
  [DEFINER = { user | CURRENT_USER | role | CURRENT_ROLE }]
  PROCEDURE [IF NOT EXISTS] sp_name ([proc_parameter[,...]])
  [characteristic ...] routine_body

proc_parameter:
  [ IN | OUT | INOUT ] param_name type

type:
  Any valid MariaDB data type

characteristic:
  LANGUAGE SQL
 | [NOT] DETERMINISTIC
 | { CONTAINS SQL | NO SQL | READS SQL DATA | MODIFIES SQL DATA }
 | SQL SECURITY { DEFINER | INVOKER }
 | COMMENT 'string'

routine_body:
  Valid SQL procedure statement

Description
-----------

Creates a stored procedure. By default, a routine is associated with the
default database. To associate the routine explicitly with a given database,
specify the name as db_name.sp_name when you create it.

When the routine is invoked, an implicit USE db_name is performed (and undone
when the routine terminates). The causes the routine to have the given default
database while it executes. USE statements within stored routines are
disallowed.

When a stored procedure has been created, you invoke it by using the CALL
statement (see CALL).

To execute the CREATE PROCEDURE statement, it is necessary to have the CREATE
ROUTINE privilege. By default, MariaDB automatically grants the ALTER ROUTINE
and EXECUTE privileges to the routine creator. See also Stored Routine
Privileges.

The DEFINER and SQL SECURITY clauses specify the security context to be used
when checking access privileges at routine execution time, as described here.
Requires the SUPER privilege, or, from MariaDB 10.5.2, the SET USER privilege.

If the routine name is the same as the name of a built-in SQL function, you
must use a space between the name and the following parenthesis when defining
the routine, or a syntax error occurs. This is also true when you invoke the
routine later. For this reason, we suggest that it is better to avoid re-using
the names of existing SQL functions for your own stored routines.

The IGNORE_SPACE SQL mode applies to built-in functions, not to stored
routines. It is always allowable to have spaces after a routine name,
regardless of whether IGNORE_SPACE is enabled.

The parameter list enclosed within parentheses must always be present. If
there are no parameters, an empty parameter list of () should be used.
Parameter names are not case sensitive.

Each parameter can be declared to use any valid data type, except that the
COLLATE attribute cannot be used.

For valid identifiers to use as procedure names, see Identifier Names.

Things to be Aware of With CREATE OR REPLACE
--------------------------------------------

* One can't use OR REPLACE together with IF EXISTS.

CREATE PROCEDURE IF NOT EXISTS
------------------------------

If the IF NOT EXISTS clause is used, then the procedure will only be created
if a procedure with the same name does not already exist. If the procedure
already exists, then a warning will be triggered by default.

IN/OUT/INOUT
------------

Each parameter is an IN parameter by default. To specify otherwise for a
parameter, use the keyword OUT or INOUT before the parameter name.

An IN parameter passes a value into a procedure. The procedure might modify
the value, but the modification is not visible to the caller when the
procedure returns. An OUT parameter passes a value from the procedure back to
the caller. Its initial value is NULL within the procedure, and its value is
visible to the caller when the procedure returns. An INOUT parameter is
initialized by the caller, can be modified by the procedure, and any change
made by the procedure is visible to the caller when the procedure returns.

For each OUT or INOUT parameter, pass a user-defined variable in the CALL
statement that invokes the procedure so that you can obtain its value when the
procedure returns. If you are calling the procedure from within another stored
procedure or function, you can also pass a routine parameter or local routine
variable as an IN or INOUT parameter.

DETERMINISTIC/NOT DETERMINISTIC
-------------------------------

DETERMINISTIC and NOT DETERMINISTIC apply only to functions. Specifying
DETERMINISTC or NON-DETERMINISTIC in procedures has no effect. The default
value is NOT DETERMINISTIC. Functions are DETERMINISTIC when they always
return the same value for the same input. For example, a truncate or substring
function. Any function involving data, therefore, is always NOT DETERMINISTIC.

CONTAINS SQL/NO SQL/READS SQL DATA/MODIFIES SQL DATA
----------------------------------------------------

CONTAINS SQL, NO SQL, READS SQL DATA, and MODIFIES SQL DATA are informative
clauses that tell the server what the function does. MariaDB does not check in
any way whether the specified clause is correct. If none of these clauses are
specified, CONTAINS SQL is used by default.

MODIFIES SQL DATA means that the function contains statements that may modify
data stored in databases. This happens if the function contains statements
like DELETE, UPDATE, INSERT, REPLACE or DDL.

READS SQL DATA means that the function reads data stored in databases, but
does not modify any data. This happens if SELECT statements are used, but
there no write operations are executed.

CONTAINS SQL means that the function contains at least one SQL statement, but
it does not read or write any data stored in a database. Examples include SET
or DO.

NO SQL means nothing, because MariaDB does not currently support any language
other than SQL.

The routine_body consists of a valid SQL procedure statement. This can be a
simple statement such as SELECT or INSERT, or it can be a compound statement
written using BEGIN and END. Compound statements can contain declarations,
loops, and other control structure statements. See Programmatic and Compound
Statements for syntax details.

MariaDB allows routines to contain DDL statements, such as CREATE and DROP.
MariaDB also allows stored procedures (but not stored functions) to contain
SQL transaction statements such as COMMIT.

For additional information about statements that are not allowed in stored
routines, see Stored Routine Limitations.

Invoking stored procedure from within programs
----------------------------------------------

For information about invoking stored procedures from within programs written
in a language that has a MariaDB/MySQL interface, see CALL.

OR REPLACE
----------

If the optional OR REPLACE clause is used, it acts as a shortcut for:

DROP PROCEDURE IF EXISTS name;
CREATE PROCEDURE name ...;

with the exception that any existing privileges for the procedure are not
dropped.

sql_mode
--------

MariaDB stores the sql_mode system variable setting that is in effect at the
time a routine is created, and always executes the routine with this setting
in force, regardless of the server SQL mode in effect when the routine is
invoked.

Character Sets and Collations
-----------------------------

Procedure parameters can be declared with any character set/collation. If the
character set and collation are not specifically set, the database defaults at
the time of creation will be used. If the database defaults change at a later
stage, the stored procedure character set/collation will not be changed at the
same time; the stored procedure needs to be dropped and recreated to ensure
the same character set/collation as the database is used.

Oracle Mode
-----------

A subset of Oracle's PL/SQL language is supported in addition to the
traditional SQL/PSM-based MariaDB syntax. See Oracle mode for details on
changes when running Oracle mode.

Examples
--------

The following example shows a simple stored procedure that uses an OUT
parameter. It uses the DELIMITER command to set a new delimiter for the
duration of the process — see Delimiters in the mariadb client.

DELIMITER //

CREATE PROCEDURE simpleproc (OUT param1 INT)
 BEGIN
 SELECT COUNT(*) INTO param1 FROM t;
 END;
//

DELIMITER ;

CALL simpleproc(@a);

SELECT @a;
+------+
| @a   |
+------+
|    1 |
+------+

Character set and collation:

DELIMITER //

CREATE PROCEDURE simpleproc2 (
 OUT param1 CHAR(10) CHARACTER SET 'utf8' COLLATE 'utf8_bin'
)
 BEGIN
 SELECT CONCAT('a'),f1 INTO param1 FROM t;
 END;
//

DELIMITER ;

CREATE OR RE��ISyntax
------

CREATE
  [OR REPLACE]
  [ALGORITHM = {UNDEFINED | MERGE | TEMPTABLE}]
  [DEFINER = { user | CURRENT_USER | role | CURRENT_ROLE }]
  [SQL SECURITY { DEFINER | INVOKER }]
  VIEW [IF NOT EXISTS] view_name [(column_list)]
  AS select_statement
  [WITH [CASCADED | LOCAL] CHECK OPTION]

Description
-----------

The CREATE VIEW statement creates a new view, or replaces an existing one if
the OR REPLACE clause is given. If the view does not exist, CREATE OR REPLACE
VIEW is the same as CREATE VIEW. If the view does exist, CREATE OR REPLACE
VIEW is the same as ALTER VIEW.

The select_statement is a SELECT statement that provides the definition of the
view. (When you select from the view, you select in effect using the SELECT
statement.) select_statement can select from base tables or other views.

The view definition is "frozen" at creation time, so changes to the underlying
tables afterwards do not affect the view definition. For example, if a view is
defined as SELECT * on a table, new columns added to the table later do not
become part of the view. A SHOW CREATE VIEW shows that such queries are
rewritten and column names are included in the view definition.

The view definition must be a query that does not return errors at view
creation times. However, the base tables used by the views might be altered
later and the query may not be valid anymore. In this case, querying the view
will result in an error. CHECK TABLE helps in finding this kind of problems.

The ALGORITHM clause affects how MariaDB processes the view. The DEFINER and
SQL SECURITY clauses specify the security context to be used when checking
access privileges at view invocation time. The WITH CHECK OPTION clause can be
given to constrain inserts or updates to rows in tables referenced by the
view. These clauses are described later in this section.

The CREATE VIEW statement requires the CREATE VIEW privilege for the view, and
some privilege for each column selected by the SELECT statement. For columns
used elsewhere in the SELECT statement you must have the SELECT privilege. If
the OR REPLACE clause is present, you must also have the DROP privilege for
the view.

A view belongs to a database. By default, a new view is created in the default
database. To create the view explicitly in a given database, specify the name
as db_name.view_name when you create it.

CREATE VIEW test.v AS SELECT * FROM t;

Base tables and views share the same namespace within a database, so a
database cannot contain a base table and a view that have the same name.

Views must have unique column names with no duplicates, just like base tables.
By default, the names of the columns retrieved by the SELECT statement are
used for the view column names. To define explicit names for the view columns,
the optional column_list clause can be given as a list of comma-separated
identifiers. The number of names in column_list must be the same as the number
of columns retrieved by the SELECT statement.

MySQL until 5.1.28
------------------
Prior to MySQL 5.1.29, When you modify an existing view, the current view
definition is backed up and saved. It is stored in that table's database
directory, in a subdirectory named arc. The backup file for a view v is named
v.frm-00001. If you alter the view again, the next backup is named
v.frm-00002. The three latest view backup definitions are stored. Backed up
view definitions are not preserved by mysqldump, or any other such programs,
but you can retain them using a file copy operation. However, they are not
needed for anything but to provide you with a backup of your previous view
definition. It is safe to remove these backup definitions, but only while
mysqld is not running. If you delete the arc subdirectory or its files while
mysqld is running, you will receive an error the next time you try to alter
the view:

MariaDB [test]> ALTER VIEW v AS SELECT * FROM t; 
ERROR 6 (HY000): Error on delete of '.\test\arc/v.frm-0004' (Errcode: 2)

Columns retrieved by the SELECT statement can be simple references to table
columns. They can also be expressions that use functions, constant values,
operators, and so forth.

Unqualified table or view names in the SELECT statement are interpreted with
respect to the default database. A view can refer to tables or views in other
databases by qualifying the table or view name with the proper database name.

A view can be created from many kinds of SELECT statements. It can refer to
base tables or other views. It can use joins, UNION, and subqueries. The
SELECT need not even refer to any tables. The following example defines a view
that selects two columns from another table, as well as an expression
calculated from those columns:

CREATE TABLE t (qty INT, price INT);

INSERT INTO t VALUES(3, 50);

CREATE VIEW v AS SELECT qty, price, qty*price AS value FROM t;

SELECT * FROM v;
+------+-------+-------+
| qty  | price | value |
+------+-------+-------+
|    3 |    50 |   150 |
+------+-------+-------+

A view definition is subject to the following restrictions:

* The SELECT statement cannot contain a subquery in the FROM clause.
* The SELECT statement cannot refer to system or user variables.
* Within a stored program, the definition cannot refer to program parameters
or local variables.
* The SELECT statement cannot refer to prepared statement parameters.
* Any table or view referred to in the definition must exist. However, after a
view has been created, it is possible to drop a table or view that the
definition refers to. In this case, use of the view results in an error. To
check a view definition for problems of this kind, use the CHECK TABLE
statement.
* The definition cannot refer to a TEMPORARY table, and you cannot create a
TEMPORARY view.
* Any tables named in the view definition must exist at definition time.
* You cannot associate a trigger with a view.
* For valid identifiers to use as view names, see Identifier Names.

ORDER BY is allowed in a view definition, but it is ignored if you select from
a view using a statement that has its own ORDER BY.

For other options or clauses in the definition, they are added to the options
or clauses of the statement that references the view, but the effect is
undefined. For example, if a view definition includes a LIMIT clause, and you
select from the view using a statement that has its own LIMIT clause, it is
undefined which limit applies. This same principle applies to options such as
ALL, DISTINCT, or SQL_SMALL_RESULT that follow the SELECT keyword, and to
clauses such as INTO, FOR UPDATE, and LOCK IN SHARE MODE.

The PROCEDURE clause cannot be used in a view definition, and it cannot be
used if a view is referenced in the FROM clause.

If you create a view and then change the query processing environment by
changing system variables, that may affect the results that you get from the
view:

CREATE VIEW v (mycol) AS SELECT 'abc';

SET sql_mode = '';

SELECT "mycol" FROM v;
+-------+
| mycol |
+-------+
| mycol | 
+-------+

SET sql_mode = 'ANSI_QUOTES';

SELECT "mycol" FROM v;
+-------+
| mycol |
+-------+
| abc   | 
+-------+

The DEFINER and SQL SECURITY clauses determine which MariaDB account to use
when checking access privileges for the view when a statement is executed that
references the view. They were added in MySQL 5.1.2. The legal SQL SECURITY
characteristic values are DEFINER and INVOKER. These indicate that the
required privileges must be held by the user who defined or invoked the view,
respectively. The default SQL SECURITY value is DEFINER.

If a user value is given for the DEFINER clause, it should be a MariaDB
account in 'user_name'@'host_name' format (the same format used in the GRANT
statement). The user_name and host_name values both are required. The definer
can also be given as CURRENT_USER or CURRENT_USER(). The default DEFINER value
is the user who executes the CREATE VIEW statement. This is the same as
specifying DEFINER = CURRENT_USER explicitly.

If you specify the DEFINER clause, these rules determine the legal DEFINER
user values:

* If you do not have the SUPER privilege, or, from MariaDB 10.5.2, the SET
USER privilege, the only legal uN��;ser value is your own account, either
specified literally or by using CURRENT_USER. You cannot set the definer to
some other account.
* If you have the SUPER privilege, or, from MariaDB 10.5.2, the SET USER
privilege, you can specify any syntactically legal account name. If the
account does not actually exist, a warning is generated.
* If the SQL SECURITY value is DEFINER but the definer account does not exist
when the view is referenced, an error occurs.

Within a view definition, CURRENT_USER returns the view's DEFINER value by
default. For views defined with the SQL SECURITY INVOKER characteristic,
CURRENT_USER returns the account for the view's invoker. For information about
user auditing within views, see
http://dev.mysql.com/doc/refman/5.1/en/account-activity-auditing.html.

Within a stored routine that is defined with the SQL SECURITY DEFINER
characteristic, CURRENT_USER returns the routine's DEFINER value. This also
affects a view defined within such a program, if the view definition contains
a DEFINER value of CURRENT_USER.

View privileges are checked like this:

* At view definition time, the view creator must have the privileges needed to
use the top-level objects accessed by the view. For example, if the view
definition refers to table columns, the creator must have privileges for the
columns, as described previously. If the definition refers to a stored
function, only the privileges needed to invoke the function can be checked.
The privileges required when the function runs can be checked only as it
executes: For different invocations of the function, different execution paths
within the function might be taken.
* When a view is referenced, privileges for objects accessed by the view are
checked against the privileges held by the view creator or invoker, depending
on whether the SQL SECURITY characteristic is DEFINER or INVOKER, respectively.
* If reference to a view causes execution of a stored function, privilege
checking for statements executed within the function depend on whether the
function is defined with a SQL SECURITY characteristic of DEFINER or INVOKER.
If the security characteristic is DEFINER, the function runs with the
privileges of its creator. If the characteristic is INVOKER, the function runs
with the privileges determined by the view's SQL SECURITY characteristic.

Example: A view might depend on a stored function, and that function might
invoke other stored routines. For example, the following view invokes a stored
function f():

CREATE VIEW v AS SELECT * FROM t WHERE t.id = f(t.name);

Suppose that f() contains a statement such as this:

IF name IS NULL then
 CALL p1();
ELSE
 CALL p2();
END IF;

The privileges required for executing statements within f() need to be checked
when f() executes. This might mean that privileges are needed for p1() or
p2(), depending on the execution path within f(). Those privileges must be
checked at runtime, and the user who must possess the privileges is determined
by the SQL SECURITY values of the view v and the function f().

The DEFINER and SQL SECURITY clauses for views are extensions to standard SQL.
In standard SQL, views are handled using the rules for SQL SECURITY INVOKER.

If you invoke a view that was created before MySQL 5.1.2, it is treated as
though it was created with a SQL SECURITY DEFINER clause and with a DEFINER
value that is the same as your account. However, because the actual definer is
unknown, MySQL issues a warning. To make the warning go away, it is sufficient
to re-create the view so that the view definition includes a DEFINER clause.

The optional ALGORITHM clause is an extension to standard SQL. It affects how
MariaDB processes the view. ALGORITHM takes three values: MERGE, TEMPTABLE, or
UNDEFINED. The default algorithm is UNDEFINED if no ALGORITHM clause is
present. See View Algorithms for more information.

Some views are updatable. That is, you can use them in statements such as
UPDATE, DELETE, or INSERT to update the contents of the underlying table. For
a view to be updatable, there must be a one-to-one relationship between the
rows in the view and the rows in the underlying table. There are also certain
other constructs that make a view non-updatable. See Inserting and Updating
with Views.

WITH CHECK OPTION
-----------------

The WITH CHECK OPTION clause can be given for an updatable view to prevent
inserts or updates to rows except those for which the WHERE clause in the
select_statement is true.

In a WITH CHECK OPTION clause for an updatable view, the LOCAL and CASCADED
keywords determine the scope of check testing when the view is defined in
terms of another view. The LOCAL keyword restricts the CHECK OPTION only to
the view being defined. CASCADED causes the checks for underlying views to be
evaluated as well. When neither keyword is given, the default is CASCADED.

For more information about updatable views and the WITH CHECK OPTION clause,
see Inserting and Updating with Views.

IF NOT EXISTS
-------------

MariaDB starting with 10.1.3
----------------------------
The IF NOT EXISTS clause was added in MariaDB 10.1.3

When the IF NOT EXISTS clause is used, MariaDB will return a warning instead
of an error if the specified view already exists. Cannot be used together with
the OR REPLACE clause.

Atomic DDL
----------

MariaDB starting with 10.6.1
----------------------------
MariaDB 10.6.1 supports Atomic DDL and CREATE VIEW is atomic.

Examples
--------

CREATE TABLE t (a INT, b INT) ENGINE = InnoDB;

INSERT INTO t VALUES (1,1), (2,2), (3,3);

CREATE VIEW v AS SELECT a, a*2 AS a2 FROM t;

SELECT * FROM v;
+------+------+
| a    | a2   |
+------+------+
|    1 |    2 |
|    2 |    4 |
|    3 |    6 |
+------+------+

OR REPLACE and IF NOT EXISTS:

CREATE VIEW v AS SELECT a, a*2 AS a2 FROM t;
ERROR 1050 (42S01): Table 'v' already exists

CREATE OR REPLACE VIEW v AS SELECT a, a*2 AS a2 FROM t;
Query OK, 0 rows affected (0.04 sec)

CREATE VIEW IF NOT EXISTS v AS SELECT a, a*2 AS a2 FROM t;
Query OK, 0 rows affected, 1 warning (0.01 sec)

SHOW WARNINGS;
+-------+------+--------------------------+
| Level | Code | Message                  |
+-------+------+--------------------------+
| Note  | 1050 | Table 'v' already exists |
+-------+------+--------------------------+

URL: https://mariadb.com/kb/en/create-view/�N[oSyntax
------

<type>  [GENERATED ALWAYS]  AS   ( <expression> )
[VIRTUAL | PERSISTENT | STORED]  [UNIQUE] [UNIQUE KEY] [COMMENT <text>]

MariaDB's generated columns syntax is designed to be similar to the syntax for
Microsoft SQL Server's computed columns and Oracle Database's virtual columns.
In MariaDB 10.2 and later, the syntax is also compatible with the syntax for
MySQL's generated columns.

Description
-----------

A generated column is a column in a table that cannot explicitly be set to a
specific value in a DML query. Instead, its value is automatically generated
based on an expression. This expression might generate the value based on the
values of other columns in the table, or it might generate the value by
calling built-in functions or user-defined functions (UDFs).

There are two types of generated columns:

* PERSISTENT (a.k.a. STORED): This type's value is actually stored in the
table.
* VIRTUAL: This type's value is not stored at all. Instead, the value is
generated dynamically when the table is queried. This type is the default.

Generated columns are also sometimes called computed columns or virtual
columns.

Supported Features
------------------

Storage Engine Support
----------------------

* Generated columns can only be used with storage engines which support them.
If you try to use a storage engine that does not support them, then you will
see an error similar to the following:

ERROR 1910 (HY000): TokuDB storage engine does not support computed columns

* InnoDB, Aria, MyISAM and CONNECT support generated columns.

* A column in a MERGE table can be built on a PERSISTENT generated column.
However, a column in a MERGE table can not be defined as a VIRTUAL and
PERSISTENT generated column.

Data Type Support
-----------------

* All data types are supported when defining generated columns.

* Using the ZEROFILL column option is supported when defining generated
columns.

* Using the AUTO_INCREMENT column option is not supported when defining
generated columns. Until MariaDB 10.2.25, it was supported, but this support
was removed, because it would not work correctly. See MDEV-11117.

Index Support
-------------

* Using a generated column as a table's primary key is not supported. See
MDEV-5590 for more information. If you try to use one as a primary key, then
you will see an error similar to the following:

ERROR 1903 (HY000): Primary key cannot be defined upon a computed column

* Using PERSISTENT generated columns as part of a foreign key is supported.

* Referencing PERSISTENT generated columns as part of a foreign key is also
supported.
However, using the ON UPDATE CASCADE, ON UPDATE SET NULL, or ON DELETE SET
NULL clauses is not supported. If you try to use an unsupported clause, then
you will see an error similar to the following:

ERROR 1905 (HY000): Cannot define foreign key with ON UPDATE SET NULL clause
on a computed column

* Defining indexes on both VIRTUAL and PERSISTENT generated columns is
supported.
If an index is defined on a generated column, then the optimizer considers
using it in the same way as indexes based on "real" columns.

Statement Support
-----------------

* Generated columns are used in DML queries just as if they were "real"
columns.
However, VIRTUAL and PERSISTENT generated columns differ in how their data is
stored.
Values for PERSISTENT generated columns are generated whenever a DML queries
inserts or updates the row with the special DEFAULT value. This generates the
columns value, and it is stored in the table like the other "real" columns.
This value can be read by other DML queries just like the other "real" columns.
Values for VIRTUAL generated columns are not stored in the table. Instead, the
value is generated dynamically whenever the column is queried. If other
columns in a row are queried, but the VIRTUAL generated column is not one of
the queried columns, then the column's value is not generated.

* The SELECT statement supports generated columns.

* Generated columns can be referenced in the INSERT, UPDATE, and DELETE
statements.
However, VIRTUAL or PERSISTENT generated columns cannot be explicitly set to
any other values than NULL or DEFAULT. If a generated column is explicitly set
to any other value, then the outcome depends on whether strict mode is enabled
in sql_mode. If it is not enabled, then a warning will be raised and the
default generated value will be used instead. If it is enabled, then an error
will be raised instead.

* The CREATE TABLE statement has limited support for generated columns.
It supports defining generated columns in a new table.
It supports using generated columns to partition tables.
It does not support using the versioning clauses with generated columns.

* The ALTER TABLE statement has limited support for generated columns.
It supports the MODIFY and CHANGE clauses for PERSISTENT generated columns.
It does not support the MODIFY clause for VIRTUAL generated columns if
ALGORITHM is not set to COPY. See MDEV-15476 for more information.
It does not support the  CHANGE clause for VIRTUAL generated columns if
ALGORITHM is not set to COPY. See MDEV-17035 for more information.
It does not support altering a table if ALGORITHM is not set to COPY if the
table has a VIRTUAL generated column that is indexed. See MDEV-14046 for more
information.
It does not support adding a VIRTUAL generated column with the ADD clause if
the same statement is also adding other columns if ALGORITHM is not set to
COPY. See MDEV-17468 for more information.
It also does not support altering an existing column into a VIRTUAL generated
column.
It supports using generated columns to partition tables.
It does not support using the versioning clauses with generated columns.

* The SHOW CREATE TABLE statement supports generated columns.

* The DESCRIBE statement can be used to check whether a table has generated
columns.
You can tell which columns are generated by looking for the ones where the
Extra column is set to either VIRTUAL or PERSISTENT. For example:

DESCRIBE table1;
+-------+-------------+------+-----+---------+------------+
| Field | Type        | Null | Key | Default | Extra      |
+-------+-------------+------+-----+---------+------------+
| a     | int(11)     | NO   |     | NULL    |            |
| b     | varchar(32) | YES  |     | NULL    |            |
| c     | int(11)     | YES  |     | NULL    | VIRTUAL    |
| d     | varchar(5)  | YES  |     | NULL    | PERSISTENT |
+-------+-------------+------+-----+---------+------------+

* Generated columns can be properly referenced in the NEW and OLD rows in
triggers.

* Stored procedures support generated columns.

* The HANDLER statement supports generated columns.

Expression Support
------------------

* Most legal, deterministic expressions which can be calculated are supported
in expressions for generated columns.

* Most built-in functions are supported in expressions for generated columns.
However, some built-in functions can't be supported for technical reasons. For
example,  If you try to use an unsupported function in an expression, an error
is generated similar to the following:

ERROR 1901 (HY000): Function or expression 'dayname()' cannot be used in the
GENERATED ALWAYS AS clause of `v`

* Subqueries are not supported in expressions for generated columns because
the underlying data can change.

* Using anything that depends on data outside the row is not supported in
expressions for generated columns.

* Stored functions are not supported in expressions for generated columns. See
MDEV-17587 for more information.

* Non-deterministic built-in functions are supported in expressions for not
indexed VIRTUAL generated columns.

* Non-deterministic built-in functions are not supported in expressions for
PERSISTENT or indexed VIRTUAL generated columns.

* User-defined functions (UDFs) are supported in expressions for generated
columns.
However, MariaDB can't check whether a UDF is deterministic, so it is up to
the user to be sure that they do not use non-deterministic UDFs with VIRTUAL
generated columns.

* Defining a generated column based on other generated columns defined before
it in the taMlq�ble definition is supported. For example:

CREATE TABLE t1 (a int as (1), b int as (a));

* However, defining a generated column based on other generated columns
defined after in the table definition is not supported in expressions for
generation columns because generated columns are calculated in the order they
are defined.

* Using an expression that exceeds 255 characters in length is supported in
expressions for generated columns. The new limit for the entire table
definition, including all expressions for generated columns, is 65,535 bytes.

* Using constant expressions is supported in expressions for generated
columns. For example:

CREATE TABLE t1 (a int as (1));

Making Stored Values Consistent
-------------------------------

When a generated column is PERSISTENT or indexed, the value of the expression
needs to be consistent regardless of the SQL Mode flags in the current
session. If it is not, then the table will be seen as corrupted when the value
that should actually be returned by the computed expression and the value that
was previously stored and/or indexed using a different sql_mode setting
disagree.

There are currently two affected classes of inconsistencies: character padding
and unsigned subtraction:

* For a VARCHAR or TEXT generated column the length of the value returned can
vary depending on the PAD_CHAR_TO_FULL_LENGTH sql_mode flag.  To make the
value consistent, create the generated column using an RTRIM() or RPAD()
function.  Alternately, create the generated column as a CHAR column so that
its data is always fully padded.

* If a SIGNED generated column is based on the subtraction of an UNSIGNED
value, the resulting value can vary depending on how large the value is and
the NO_UNSIGNED_SUBTRACTION sql_mode flag.  To make the value consistent, use
CAST() to ensure that each UNSIGNED operand is SIGNED before the subtraction.

MariaDB starting with 10.5
--------------------------
Beginning in MariaDB 10.5, there is a fatal error generated when trying to
create a generated column whose value can change depending on the SQL Mode
when its data is PERSISTENT or indexed.

For an existing generated column that has a potentially inconsistent value, a
warning about a bad expression is generated the first time it is used (if
warnings are enabled).

Beginning in MariaDB 10.4.8, MariaDB 10.3.18, and MariaDB 10.2.27 a
potentially inconsistent generated column outputs a warning when created or
first used (without restricting their creation).

Here is an example of two tables that would be rejected in MariaDB 10.5 and
warned about in the other listed versions:

CREATE TABLE bad_pad (
 txt CHAR(5),
 -- CHAR -> VARCHAR or CHAR -> TEXT can't be persistent or indexed:
 vtxt VARCHAR(5) AS (txt) PERSISTENT
);

CREATE TABLE bad_sub (
 num1 BIGINT UNSIGNED,
 num2 BIGINT UNSIGNED,
 -- The resulting value can vary for some large values
 vnum BIGINT AS (num1 - num2) VIRTUAL,
 KEY(vnum)
);

The warnings for the above tables look like this:

Warning (Code 1901): Function or expression '`txt`' cannot be used in the
GENERATED ALWAYS AS clause of `vtxt`
Warning (Code 1105): Expression depends on the @@sql_mode value
PAD_CHAR_TO_FULL_LENGTH

Warning (Code 1901): Function or expression '`num1` - `num2`' cannot be used
in the GENERATED ALWAYS AS clause of `vnum`
Warning (Code 1105): Expression depends on the @@sql_mode value
NO_UNSIGNED_SUBTRACTION

To work around the issue, force the padding or type to make the generated
column's expression return a consistent value. For example:

CREATE TABLE good_pad (
 txt CHAR(5),
 -- Using RTRIM() or RPAD() makes the value consistent:
 vtxt VARCHAR(5) AS (RTRIM(txt)) PERSISTENT,
 -- When not persistent or indexed, it is OK for the value to vary by mode:
 vtxt2 VARCHAR(5) AS (txt) VIRTUAL,
 -- CHAR -> CHAR is always OK:
 txt2 CHAR(5) AS (txt) PERSISTENT
);

CREATE TABLE good_sub (
 num1 BIGINT UNSIGNED,
 num2 BIGINT UNSIGNED,
 -- The indexed value will always be consistent in this expression:
 vnum BIGINT AS (CAST(num1 AS SIGNED) - CAST(num2 AS SIGNED)) VIRTUAL,
 KEY(vnum)
);

MySQL Compatibility Support
---------------------------

* The STORED keyword is supported as an alias for the PERSISTENT keyword.

* Tables created with MySQL 5.7 or later that contain MySQL's generated
columns can be imported into MariaDB without a dump and restore.

Implementation Differences
--------------------------

Generated columns are subject to various constraints in other DBMSs that are
not present in MariaDB's implementation. Generated columns may also be called
computed columns or virtual columns in different implementations. The various
details for a specific implementation can be found in the documentation for
each specific DBMS.

Implementation Differences Compared to Microsoft SQL Server
-----------------------------------------------------------

MariaDB's generated columns implementation does not enforce the following
restrictions that are present in Microsoft SQL Server's computed columns
implementation:

* MariaDB allows server variables in generated column expressions, including
those that change dynamically, such as warning_count.
* MariaDB allows the CONVERT_TZ() function to be called with a named time zone
as an argument, even though time zone names and time offsets are configurable.
* MariaDB allows the CAST() function to be used with non-unicode character
sets, even though character sets are configurable and differ between
binaries/versions.
* MariaDB allows FLOAT expressions to be used in generated columns. Microsoft
SQL Server considers these expressions to be "imprecise" due to potential
cross-platform differences in floating-point implementations and precision.
* Microsoft SQL Server requires the ARITHABORT mode to be set, so that
division by zero returns an error, and not a NULL.
* Microsoft SQL Server requires QUOTED_IDENTIFIER to be set in sql_mode. In
MariaDB, if data is inserted without ANSI_QUOTES set in sql_mode, then it will
be processed and stored differently in a generated column that contains quoted
identifiers.

Microsoft SQL Server enforces the above restrictions by doing one of the
following things:

* Refusing to create computed columns.
* Refusing to allow updates to a table containing them.
* Refusing to use an index over such a column if it can not be guaranteed that
the expression is fully deterministic.

In MariaDB, as long as the sql_mode, language, and other settings that were in
effect during the CREATE TABLE remain unchanged, the generated column
expression will always be evaluated the same. If any of these things change,
then please be aware that the generated column expression might not be
evaluated the same way as it previously was.

If you try to update a virtual column, you will get an error if the default
strict mode is enabled in sql_mode, or a warning otherwise.

Development History
-------------------

Generated columns was originally developed by Andrey Zhakov. It was then
modified by Sanja Byelkin and Igor Babaev at Monty Program for inclusion in
MariaDB. Monty did the work on MariaDB 10.2 to lift a some of the old
limitations.

Examples
--------

Here is an example table that uses both VIRTUAL and PERSISTENT virtual columns:

USE TEST;

CREATE TABLE table1 (
  a INT NOT NULL,
  b VARCHAR(32),
  c INT AS (a mod 10) VIRTUAL,
  d VARCHAR(5) AS (left(b,5)) PERSISTENT);

If you describe the table, you can easily see which columns are virtual by
looking in the "Extra" column:

DESCRIBE table1;
+-------+-------------+------+-----+---------+------------+
| Field | Type        | Null | Key | Default | Extra      |
+-------+-------------+------+-----+---------+------------+
| a     | int(11)     | NO   |     | NULL    |            |
| b     | varchar(32) | YES  |     | NULL    |            |
| c     | int(11)     | YES  |     | NULL    | VIRTUAL    |
| d     | varchar(5)  | YES  |     | NULL    | PERSISTENT |
+-------+-------------+------+-----+---------+------------+

To find out what function(s) generate the value of the virtual column you can
use SHOW CREATE TABLE:

SHOW CREATE TABLE table1;

| table1 | CREATE TABLE `table1` (
 `a` int(11) NOT NULL,
 `b` varchar�tW��(32) DEFAULT NULL,
 `c` int(11) AS (a mod 10) VIRTUAL,
 `d` varchar(5) AS (left(b,5)) PERSISTENT
) ENGINE=MyISAM DEFAULT CHARSET=latin1 |

If you try to insert non-default values into a virtual column, you will
receive a warning and what you tried to insert will be ignored and the derived
value inserted instead:

WARNINGS;
Show warnings enabled.

INSERT INTO table1 VALUES (1, 'some text',default,default);
Query OK, 1 row affected (0.00 sec)

INSERT INTO table1 VALUES (2, 'more text',5,default);
Query OK, 1 row affected, 1 warning (0.00 sec)

Warning (Code 1645): The value specified for computed column 'c' in table
'table1' has been ignored.

INSERT INTO table1 VALUES (123, 'even more text',default,'something');
Query OK, 1 row affected, 2 warnings (0.00 sec)

Warning (Code 1645): The value specified for computed column 'd' in table
'table1' has been ignored.
Warning (Code 1265): Data truncated for column 'd' at row 1

SELECT * FROM table1;
+-----+----------------+------+-------+
| a   | b              | c    | d     |
+-----+----------------+------+-------+
|   1 | some text      |    1 | some  |
|   2 | more text      |    2 | more  |
| 123 | even more text |    3 | even  |
+-----+----------------+------+-------+
3 rows in set (0.00 sec)

If the ZEROFILL clause is specified, it should be placed directly after the
type definition, before the AS (<expression>):

CREATE TABLE table2 (a INT, b INT ZEROFILL AS (a*2) VIRTUAL);
INSERT INTO table2 (a) VALUES (1);

SELECT * FROM table2;
+------+------------+
| a    | b          |
+------+------------+
|    1 | 0000000002 |
+------+------------+
1 row in set (0.00 sec)

You can also use virtual columns to implement a "poor man's partial index".
See example at the end of Unique Index.

URL: https://mariadb.com/kb/en/generated-columns/ 'Svantepolk', 250),
('Sales', 'Angelo', 200);

We could do this without using window functions, as follows:

select dept, name, salary
from employee_salaries as t1
where (select count(t2.salary)
   from employee_salaries as t2
   where t1.name != t2.name and
      t1.dept = t2.dept and
      t2.salary > t1.salary) < 5
order by dept, salary desc;

+-------------+--------------+--------+
| dept        | name         | salary |
+-------------+--------------+--------+
| Engineering | Dharma       |   3500 |
| Engineering | Binh         |   3000 |
| Engineering | Adalynn      |   2800 |
| Engineering | Samuel       |   2500 |
| Engineering | Cveta        |   2200 |
| Sales       | Carbry       |    500 |
| Sales       | Clytemnestra |    400 |
| Sales       | Juraj        |    300 |
| Sales       | Kalpana      |    300 |
| Sales       | Svantepolk   |    250 |
+-------------+--------------+--------+

This has a number of disadvantages:

* if there is no index, the query could take a long time if the
employee_salary_table is large
* Adding and maintaining indexes adds overhead, and even with indexes on dept
and salary, each subquery execution adds overhead by performing a lookup
through the index.

Let's try achieve the same with window functions. First, generate a rank for
all employees, using the RANK function.

select rank() over (partition by dept order by salary desc) as ranking,
  dept, name, salary
  from employee_salaries
  order by dept, ranking;
+---------+-------------+--------------+--------+
| ranking | dept        | name         | salary |
+---------+-------------+--------------+--------+
|       1 | Engineering | Dharma       |   3500 |
|       2 | Engineering | Binh         |   3000 |
|       3 | Engineering | Adalynn      |   2800 |
|       4 | Engineering | Samuel       |   2500 |
|       5 | Engineering | Cveta        |   2200 |
|       6 | Engineering | Ebele        |   1800 |
|       1 | Sales       | Carbry       |    500 |
|       2 | Sales       | Clytemnestra |    400 |
|       3 | Sales       | Juraj        |    300 |
|       3 | Sales       | Kalpana      |    300 |
|       5 | Sales       | Svantepolk   |    250 |
|       6 | Sales       | Angelo       |    200 |
+---------+-------------+--------------+--------+

Each department has a separate sequence of ranks due to the PARTITION BY
clause. This particular sequence of values for rank() is given by the ORDER BY
clause inside the window function’s OVER clause. Finally, to get our results
in a readable format we order the data by dept and the newly generated ranking
column.

Now, we need to reduce the results to find only the top 5 per department. Here
is a common mistake:

select
rank() over (partition by dept order by salary desc) as ranking,
dept, name, salary
from employee_salaries
where ranking <= 5
order by dept, ranking;

ERROR 1054 (42S22): Unknown column 'ranking' in 'where clause'

Trying to filter only the first 5 values per department by putting a where
clause in the statement does not work, due to the way window functions are
computed. The computation of window functions happens after all WHERE, GROUP
BY and HAVING clauses have been completed, right before ORDER BY, so the WHERE
clause has no idea that the ranking column exists. It is only present after we
have filtered and grouped all the rows.

To counteract this problem, we need to wrap our query into a derived table. We
can then attach a where clause to it:

select *from (select rank() over (partition by dept order by salary desc) as
ranking,
 dept, name, salary
from employee_salaries) as salary_ranks
where (salary_ranks.ranking <= 5)
 order by dept, ranking;
+---------+-------------+--------------+--------+
| ranking | dept        | name         | salary |
+---------+-------------+--------------+--------+
|       1 | Engineering | Dharma       |   3500 |
|       2 | Engineering | Binh         |   3000 |
|       3 | Engineering | Adalynn      |   2800 |
|       4 | Engineering | Samuel       |   2500 |
|       5 | Engineering | Cveta        |   2200 |
|       1 | Sales       | Carbry       |    500 |
|       2 | Sales       | Clytemnestra |    400 |
|       3 | Sales       | Juraj        |    300 |
|       3 | Sales       | Kalpana      |    300 |
|       5 | Sales       | Svantepolk   |    250 |
+---------+-------------+--------------+--------+

URL: https://mariadb.com/kb/en/window-functions-overview/J
Lf�B� �"VARCHARSyntax
------

[NATIONAL] VARCHAR(M) [CHARACTER SET charset_name] [COLLATE collation_name]

Description
-----------

A variable-length string. M represents the maximum column length in
characters. The range of M is 0 to 65,532. The effective maximum length of a
VARCHAR is subject to the maximum row size and the character set used. For
example, utf8 characters can require up to three bytes per character, so a
VARCHAR column that uses the utf8 character set can be declared to be a
maximum of 21,844 characters.

Note: For the ColumnStore engine, M represents the maximum column length in
bytes.

MariaDB stores VARCHAR values as a one-byte or two-byte length prefix plus
data. The length prefix indicates the number of bytes in the value. A VARCHAR
column uses one length byte if values require no more than 255 bytes, two
length bytes if values may require more than 255 bytes.

MariaDB follows the standard SQL specification, and does not remove trailing
spaces from VARCHAR values.

VARCHAR(0) columns can contain 2 values: an empty string or NULL. Such columns
cannot be part of an index. The CONNECT storage engine does not support
VARCHAR(0).

VARCHAR is shorthand for CHARACTER VARYING. NATIONAL VARCHAR is the standard
SQL way to define that a VARCHAR column should use some predefined character
set. MariaDB uses utf8 as this predefined character set, as does MySQL 4.1 and
up. NVARCHAR is shorthand for NATIONAL VARCHAR.

Before MariaDB 10.2, all MariaDB collations were of type PADSPACE, meaning
that VARCHAR (as well as CHAR and TEXT values) are compared without regard for
trailing spaces. This does not apply to the LIKE pattern-matching operator,
which takes into account trailing spaces. From MariaDB 10.2, a number of NO
PAD collations are available.

If a unique index consists of a column where trailing pad characters are
stripped or ignored, inserts into that column where values differ only by the
number of trailing pad characters will result in a duplicate-key error.

Examples
--------

The following are equivalent:

VARCHAR(30) CHARACTER SET utf8
NATIONAL VARCHAR(30)
NVARCHAR(30)
NCHAR VARCHAR(30)
NATIONAL CHARACTER VARYING(30)
NATIONAL CHAR VARYING(30)

Trailing spaces:

CREATE TABLE strtest (v VARCHAR(10));
INSERT INTO strtest VALUES('Maria   ');

SELECT v='Maria',v='Maria   ' FROM strtest;
+-----------+--------------+
| v='Maria' | v='Maria   ' |
+-----------+--------------+
|         1 |            1 |
+-----------+--------------+

SELECT v LIKE 'Maria',v LIKE 'Maria   ' FROM strtest;
+----------------+-------------------+
| v LIKE 'Maria' | v LIKE 'Maria   ' |
+----------------+-------------------+
|              0 |                 1 |
+----------------+-------------------+

Truncation
----------

* Depending on whether or not strict sql mode is set, you will either get a
warning or an error if you try to insert a string that is too long into a
VARCHAR column. If the extra characters are spaces, the spaces that can't fit
will be removed and you will always get a warning, regardless of the sql mode
setting.

Difference Between VARCHAR and TEXT
-----------------------------------

* VARCHAR columns can be fully indexed. TEXT columns can only be indexed over
a specified length.
* Using TEXT or BLOB in a SELECT query that uses temporary tables for storing
intermediate results will force the temporary table to be disk based (using
the Aria storage engine instead of the memory storage engine, which is a bit
slower. This is not that bad as the Aria storage engine caches the rows in
memory. To get the benefit of this, one should ensure that the
aria_pagecache_buffer_size variable is big enough to hold most of the row and
index data for temporary tables.

Oracle Mode
-----------

MariaDB starting with 10.3
--------------------------
In Oracle mode from MariaDB 10.3, VARCHAR2 is a synonym.

For Storage Engine Developers
-----------------------------

* Internally the full length of the VARCHAR column is allocated inside each
TABLE objects record[] structure. As there are three such buffers, each open
table will allocate 3 times max-length-to-store-varchar bytes of memory.
* TEXT and BLOB columns are stored with a pointer (4 or 8 bytes) + a 1-4 bytes
length.  The TEXT data is only stored once. This means that internally TEXT
uses less memory for each open table but instead has the additional overhead
that each TEXT object needs to be allocated and freed for each row access
(with some caching in between).

URL: https://mariadb.com/kb/en/varchar/https://mariadb.com/kb/en/varchar/'�)YEAR Data TypeSyntax
------

YEAR[(4)]

Description
-----------

A year in two-digit or four-digit format. The default is four-digit format.
Note that the two-digit format has been deprecated since MariaDB 5.5.27.

In four-digit format, the allowable values are 1901 to 2155, and 0000. In
two-digit format, the allowable values are 70 to 69, representing years from
1970 to 2069. MariaDB displays YEAR values in YYYY format, but allows you to
assign values to YEAR columns using either strings or numbers.

Inserting numeric zero has a different result for YEAR(4) and YEAR(2). For
YEAR(2), the value 00 reflects the year 2000. For YEAR(4), the value 0000
reflects the year zero. This only applies to numeric zero. String zero always
reflects the year 2000.

Examples
--------

Accepting a string or a number:

CREATE TABLE y(y YEAR);

INSERT INTO y VALUES (1990),('2012');

SELECT * FROM y;
+------+
| y    |
+------+
| 1990 |
| 2012 |
+------+

With strict_mode set, the default from MariaDB 10.2.4:

Out of range:

INSERT INTO y VALUES (1005),('3080');
ERROR 1264 (22003): Out of range value for column 'y' at row 1

INSERT INTO y VALUES ('2013-12-12');
ERROR 1265 (01000): Data truncated for column 'y' at row 1

SELECT * FROM y;
+------+
| y    |
+------+
| 1990 |
| 2012 |
+------+

With strict_mode unset, the default until MariaDB 10.2.3:

Out of range:

INSERT INTO y VALUES (1005),('3080');
Query OK, 2 rows affected, 2 warnings (0.05 sec)
Records: 2  Duplicates: 0  Warnings: 2

SHOW WARNINGS;
+---------+------+--------------------------------------------+
| Level   | Code | Message                                    |
+---------+------+--------------------------------------------+
| Warning | 1264 | Out of range value for column 'y' at row 1 |
| Warning | 1264 | Out of range value for column 'y' at row 2 |
+---------+------+--------------------------------------------+

SELECT * FROM y;
+------+
| y    |
+------+
| 1990 |
| 2012 |
| 0000 |
| 0000 |
+------+

Truncating:

INSERT INTO y VALUES ('2013-12-12');
Query OK, 1 row affected, 1 warning (0.05 sec)

SHOW WARNINGS;
+---------+------+----------------------------------------+
| Level   | Code | Message                                |
+---------+------+----------------------------------------+
| Warning | 1265 | Data truncated for column 'y' at row 1 |
+---------+------+----------------------------------------+

SELECT * FROM y;
+------+
| y    |
+------+
| 1990 |
| 2012 |
| 0000 |
| 0000 |
| 2013 |
+------+

Difference between YEAR(2) and YEAR(4), and string and numeric zero:

CREATE TABLE y2(y YEAR(4), y2 YEAR(2));
Query OK, 0 rows affected, 1 warning (0.40 sec)

Note (Code 1287): 'YEAR(2)' is deprecated and will be removed in a future
release. 
 Please use YEAR(4) instead

INSERT INTO y2 VALUES(0,0),('0','0');

SELECT YEAR(y),YEAR(y2) FROM y2;
+---------+----------+
| YEAR(y) | YEAR(y2) |
+---------+----------+
|       0 |     2000 |
|    2000 |     2000 |
+---------+----------+

URL: https://mariadb.com/kb/en/year-data-type/https://mariadb.com/kb/en/year-data-type/��������"S)UUID Data TypeMariaDB starting with 10.7.0
----------------------------
The UUID data type was added in a MariaDB 10.7.0 preview.

Syntax
------

UUID

Description
-----------

The UUID data type is intended for the storage of 128-bit UUID (Universally
Unique Identifier) data. See the UUID function page for more details on UUIDs
themselves.

Retrieval
---------

Data retrieved by this data type is in the string representation defined in
RFC4122.

Casting
-------

String literals of hexadecimal characters and CHAR/VARCHAR/TEXT can be cast to
the UUID data type. Likewise hexadecimal literals, binary-literals, and
BINARY/VARBINARY/BLOB types can also be cast to UUID.

The data type will not accept a short UUID generated with the UUID_SHORT
function, but will accept a value without the - character generated by the
SYS_GUID function (or inserted directly). Hyphens can be partially omitted as
well, or included after any group of two digits.

The type does not accept UUIDs in braces, permitted by some implementations.

Storage
-------

UUID are stored in an index friendly manner, the order of a UUID of
llllllll-mmmm-Vhhh-vsss-nnnnnnnnnnnn is stored as:

nnnnnnnnnnnn-vsss-Vhhh-mmmm-llllllll

This provides a sorting order, if a UUIDv1 (node and timestamp) is used, of
the node, followed by the timestamp.

Examples
--------

CREATE TABLE t1 (id UUID);

Directly Inserting via string literals:

INSERT INTO t1 VALUES('123e4567-e89b-12d3-a456-426655440000');

Directly Inserting via hexadecimal literals:

INSERT INTO t1 VALUES (x'fffffffffffffffffffffffffffffffe');

Generating and inserting via the UUID function.

INSERT INTO t1 VALUES (UUID());

Retrieval:

SELECT * FROM t1;
+--------------------------------------+
| id                                   |
+--------------------------------------+
| 123e4567-e89b-12d3-a456-426655440000 |
| ffffffff-ffff-ffff-ffff-fffffffffffe |
| 93aac041-1a14-11ec-ab4e-f859713e4be4 |
+--------------------------------------+

The UUID_SHORT function does not generate valid full-length UUID:

INSERT INTO t1 VALUES (UUID_SHORT());
ERROR 1292 (22007): Incorrect uuid value: '99440417627439104' 
 for column `test`.`t1`.`id` at row 1

Accepting a value without the - character, either directly or generated by the
SYS_GUID function:

INSERT INTO t1 VALUES (SYS_GUID());

SELECT * FROM t1;
+--------------------------------------+
| id                                   |
+--------------------------------------+
| 123e4567-e89b-12d3-a456-426655440000 |
| ffffffff-ffff-ffff-ffff-fffffffffffe |
| 93aac041-1a14-11ec-ab4e-f859713e4be4 |
| ea0368d3-1a14-11ec-ab4e-f859713e4be4 |
+--------------------------------------+

SELECT SYS_GUID();
+----------------------------------+
| SYS_GUID()                       |
+----------------------------------+
| ff5b6bcc1a1411ecab4ef859713e4be4 |
+----------------------------------+

INSERT INTO t1 VALUES ('ff5b6bcc1a1411ecab4ef859713e4be4');

SELECT * FROM t1;
+--------------------------------------+
| id                                   |
+--------------------------------------+
| 123e4567-e89b-12d3-a456-426655440000 |
| ffffffff-ffff-ffff-ffff-fffffffffffe |
| 93aac041-1a14-11ec-ab4e-f859713e4be4 |
| ea0368d3-1a14-11ec-ab4e-f859713e4be4 |
| ff5b6bcc-1a14-11ec-ab4e-f859713e4be4 |
+--------------------------------------+

Valid and invalid hyphen and brace usage:

TRUNCATE t1;

INSERT INTO t1 VALUES ('f8aa-ed66-1a1b-11ec-ab4e-f859-713e-4be4');

INSERT INTO t1 VALUES ('1b80667f1a1c-11ecab4ef859713e4be4');

INSERT INTO t1 VALUES ('2fd6c945-1a-1c-11ec-ab4e-f859713e4be4');

INSERT INTO t1 VALUES ('49-c9-f9-59-1a-1c-11ec-ab4e-f859713e4be4');

INSERT INTO t1 VALUES ('57-96-da-c1-1a-1c-11-ec-ab-4e-f8-59-71-3e-4b-e4');

INSERT INTO t1 VALUES ('6-eb74f8f-1a1c-11ec-ab4e-f859713e4be4');

INSERT INTO t1 VALUES ('{29bad136-1a1d-11ec-ab4e-f859713e4be4}');
ERROR 1292 (22007): Incorrect uuid value:
'{29bad136-1a1d-11ec-ab4e-f859713e4be4}' 
 for column `test`.`t1`.`id` at row 1

SELECT * FROM t1;
+--------------------------------------+
| id                                   |
+--------------------------------------+
| f8aaed66-1a1b-11ec-ab4e-f859713e4be4 |
| 1b80667f-1a1c-11ec-ab4e-f859713e4be4 |
| 2fd6c945-1a1c-11ec-ab4e-f859713e4be4 |
| 49c9f959-1a1c-11ec-ab4e-f859713e4be4 |
| 5796dac1-1a1c-11ec-ab4e-f859713e4be4 |
| 6eb74f8f-1a1c-11ec-ab4e-f859713e4be4 |
+--------------------------------------+

URL: https://mariadb.com/kb/en/uuid-data-type/https://mariadb.com/kb/en/uuid-data-type/)4OUsing Compound Statements Outside of Stored ProgramsCompound statements can also be used outside of stored programs.

delimiter |
IF @have_innodb THEN
 CREATE TABLE IF NOT EXISTS innodb_index_stats (
  database_name    VARCHAR(64) NOT NULL,
  table_name       VARCHAR(64) NOT NULL,
  index_name       VARCHAR(64) NOT NULL,
  last_update      TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE
CURRENT_TIMESTAMP,
  stat_name        VARCHAR(64) NOT NULL,
  stat_value       BIGINT UNSIGNED NOT NULL,
  sample_size      BIGINT UNSIGNED,
  stat_description VARCHAR(1024) NOT NULL,
  PRIMARY KEY (database_name, table_name, index_name, stat_name)
 ) ENGINE=INNODB DEFAULT CHARSET=utf8 COLLATE=utf8_bin STATS_PERSISTENT=0;
END IF|
Query OK, 0 rows affected, 2 warnings (0.00 sec)

Note, that using compound statements this way is subject to following
limitations:

* Only BEGIN, IF, CASE, LOOP, WHILE, REPEAT statements may start a compound
statement outside of stored programs.
* BEGIN must use the BEGIN NOT ATOMIC syntax (otherwise it'll be confused with
BEGIN that starts a transaction).
* A compound statement might not start with a label.
* A compound statement is parsed completely—note "2 warnings" in the above
example, even if the condition was false (InnoDB was, indeed, disabled), and
the CREATE TABLE statement was not executed, it was still parsed and the
parser produced "Unknown storage engine" warning.

Inside a compound block first three limitations do not apply, one can use
anything that can be used inside a stored program — including labels,
condition handlers, variables, and so on:

BEGIN NOT ATOMIC
  DECLARE foo CONDITION FOR 1146;
  DECLARE x INT DEFAULT 0;
  DECLARE CONTINUE HANDLER FOR SET x=1;
  INSERT INTO test.t1 VALUES ("hndlr1", val, 2);
  END|

Example how to use IF:

IF (1>0) THEN BEGIN NOT ATOMIC SELECT 1; END ; END IF;;

Example of how to use WHILE loop:

DELIMITER |
BEGIN NOT ATOMIC
  DECLARE x INT DEFAULT 0;
  WHILE x <= 10 DO
    SET x = x + 1;
    SELECT x;
  END WHILE;
END|
DELIMITER ;

URL:
https://mariadb.com/kb/en/using-compound-statements-outside-of-stored-programs/https://mariadb.com/kb/en/using-compound-statements-outside-of-stored-programs/��,&DROP PACKAGE BODYMariaDB starting with 10.3.5
----------------------------
Oracle-style packages were introduced in MariaDB 10.3.5.

Syntax
------

DROP PACKAGE BODY [IF EXISTS]  [ db_name . ] package_name

Description
-----------

The DROP PACKAGE BODY statement can be used when Oracle SQL_MODE is set.

The DROP PACKAGE BODY statement drops the package body (i.e the
implementation), previously created using the CREATE PACKAGE BODY statement.

Note, DROP PACKAGE BODY drops only the package implementation, but does not
drop the package specification. Use DROP PACKAGE to drop the package entirely
(i.e. both implementation and specification).

URL: https://mariadb.com/kb/en/drop-package-body/https://mariadb.com/kb/en/drop-package-body/M����c�:�}$K
TIMESyntax
------

TIME [(<microsecond precision>)]

Description
-----------

A time. The range is '-838:59:59.999999' to '838:59:59.999999'. Microsecond
precision can be from 0-6; if not specified 0 is used. Microseconds have been
available since MariaDB 5.3.

MariaDB displays TIME values in 'HH:MM:SS.ssssss' format, but allows
assignment of times in looser formats, including 'D HH:MM:SS', 'HH:MM:SS',
'HH:MM', 'D HH:MM', 'D HH', 'SS', or 'HHMMSS', as well as permitting dropping
of any leading zeros when a delimiter is provided, for example '3:9:10'. For
details, see date and time literals.

MariaDB 10.1.2 introduced the --mysql56-temporal-format option, on by default,
which allows MariaDB to store TIMEs using the same low-level format MySQL 5.6
uses.

Internal Format
---------------

In MariaDB 10.1.2 a new temporal format was introduced from MySQL 5.6 that
alters how the TIME, DATETIME and TIMESTAMP columns operate at lower levels.
These changes allow these temporal data types to have fractional parts and
negative values. You can disable this feature using the
mysql56_temporal_format system variable.

Tables that include TIMESTAMP values that were created on an older version of
MariaDB or that were created while the mysql56_temporal_format system variable
was disabled continue to store data using the older data type format.

In order to update table columns from the older format to the newer format,
execute an ALTER TABLE... MODIFY COLUMN statement that changes the column to
the *same* data type. This change may be needed if you want to export the
table's tablespace and import it onto a server that has
mysql56_temporal_format=ON set (see MDEV-15225).

For instance, if you have a TIME column in your table:

SHOW VARIABLES LIKE 'mysql56_temporal_format';

+-------------------------+-------+
| Variable_name           | Value |
+-------------------------+-------+
| mysql56_temporal_format | ON    |
+-------------------------+-------+

ALTER TABLE example_table MODIFY ts_col TIME;

When MariaDB executes the ALTER TABLE statement, it converts the data from the
older temporal format to the newer one.

In the event that you have several tables and columns using temporal data
types that you want to switch over to the new format, make sure the system
variable is enabled, then perform a dump and restore using mariadb-dump. The
columns using relevant temporal data types are restored using the new temporal
format.

Starting from MariaDB 10.5.1 columns with old temporal formats are marked with
a /* mariadb-5.3 */ comment in the output of SHOW CREATE TABLE, SHOW COLUMNS,
DESCRIBE statements, as well as in the COLUMN_TYPE column of the
INFORMATION_SCHEMA.COLUMNS Table.

SHOW CREATE TABLE mariadb5312_time\G
*************************** 1. row ***************************
   Table: mariadb5312_time
Create Table: CREATE TABLE `mariadb5312_time` (
 `t0` time /* mariadb-5.3 */ DEFAULT NULL,
 `t6` time(6) /* mariadb-5.3 */ DEFAULT NULL
) ENGINE=MyISAM DEFAULT CHARSET=latin1

Note, columns with the current format are not marked with a comment.

Examples
--------

INSERT INTO time VALUES ('90:00:00'), ('800:00:00'), (800), (22), (151413),
('9:6:3'), ('12 09');

SELECT * FROM time;
+-----------+
| t         |
+-----------+
| 90:00:00  |
| 800:00:00 |
| 00:08:00  |
| 00:00:22  |
| 15:14:13  |
| 09:06:03  |
| 297:00:00 |
+-----------+

URL: https://mariadb.com/kb/en/time/https://mariadb.com/kb/en/time/*	+
$BEGIN ENDSyntax
------

[begin_label:] BEGIN [NOT ATOMIC]
  [statement_list]
END [end_label]

NOT ATOMIC is required when used outside of a stored procedure. Inside stored
procedures or within an anonymous block, BEGIN alone starts a new anonymous
block.

Description
-----------

BEGIN ... END syntax is used for writing compound statements. A compound
statement can contain multiple statements, enclosed by the BEGIN and END
keywords. statement_list represents a list of one or more statements, each
terminated by a semicolon (i.e., ;) statement delimiter. statement_list is
optional, which means that the empty compound statement (BEGIN END) is legal.

Note that END will perform a commit. If you are running in autocommit mode,
every statement will be committed separately. If you are not running in
autocommit mode, you must execute a COMMIT or ROLLBACK after END to get the
database up to date.

Use of multiple statements requires that a client is able to send statement
strings containing the ; statement delimiter. This is handled in the mysql
command-line client with the DELIMITER command. Changing the ;
end-of-statement delimiter (for example, to //) allows ; to be used in a
program body.

A compound statement within a stored program can be labeled. end_label cannot
be given unless begin_label also is present. If both are present, they must be
the same.

BEGIN ... END constructs can be nested. Each block can define its own
variables, a CONDITION, a HANDLER and a CURSOR, which don't exist in the outer
blocks. The most local declarations override the outer objects which use the
same name (see example below).

The declarations order is the following:

* DECLARE local variables;
* DECLARE CONDITIONs;
* DECLARE CURSORs;
* DECLARE HANDLERs;

Note that DECLARE HANDLER contains another BEGIN ... END construct.

Here is an example of a very simple, anonymous block:

BEGIN NOT ATOMIC
SET @a=1;
CREATE TABLE test.t1(a INT);
END|

Below is an example of nested blocks in a stored procedure:

CREATE PROCEDURE t( )
BEGIN
 DECLARE x TINYINT UNSIGNED DEFAULT 1;
 BEGIN
   DECLARE x CHAR(2) DEFAULT '02';
   DECLARE y TINYINT UNSIGNED DEFAULT 10;
   SELECT x, y;
 END;
 SELECT x;
END;

In this example, a TINYINT variable, x is declared in the outter block. But in
the inner block x is re-declared as a CHAR and an y variable is declared. The
inner SELECT shows the "new" value of x, and the value of y. But when x is
selected in the outer block, the "old" value is returned. The final SELECT
doesn't try to read y, because it doesn't exist in that context.

URL: https://mariadb.com/kb/en/begin-end/https://mariadb.com/kb/en/begin-end/�J*&DROP TABLESPACEThe DROP TABLESPACE statement is not supported by MariaDB. It was originally
inherited from MySQL NDB Cluster. In MySQL 5.7 and later, the statement is
also supported for InnoDB. However, MariaDB has chosen not to include that
specific feature. See MDEV-19294 for more information.

URL: https://mariadb.com/kb/en/drop-tablespace/https://mariadb.com/kb/en/drop-tablespace/�|@I��~?*&Dynamic Columns�~@I���,'Sequence Overview�
%(JSON_ARRAYSyntax
------

JSON_ARRAY([value[, value2] ...])

Description
-----------

Returns a JSON array containing the listed values. The list can be empty.

Example
-------

SELECT Json_Array(56, 3.1416, 'My name is "Foo"', NULL);
+--------------------------------------------------+
| Json_Array(56, 3.1416, 'My name is "Foo"', NULL) |
+--------------------------------------------------+
| [56, 3.1416, "My name is \"Foo\"", null]         |
+--------------------------------------------------+

URL: https://mariadb.com/kb/en/json_array/https://mariadb.com/kb/en/json_array/��'(JSON_COMPACTSyntax
------

JSON_COMPACT(json_doc)

Description
-----------

Removes all unnecessary spaces so the json document is as short as possible.

Example
-------

SET @j = '{ "A": 1, "B": [2, 3]}';

SELECT JSON_COMPACT(@j), @j;
+-------------------+------------------------+
| JSON_COMPACT(@j)  | @j                     |
+-------------------+------------------------+
| {"A":1,"B":[2,3]} | { "A": 1, "B": [2, 3]} |
+-------------------+------------------------+

URL: https://mariadb.com/kb/en/json_compact/https://mariadb.com/kb/en/json_compact/*9�Q�.,���
f
|
���Dynamic columns allow one to store different sets of columns for each row in a
table. It works by storing a set of columns in a blob and having a small set
of functions to manipulate it. Dynamic columns should be used when it is not
possible to use regular columns. A typical use case is when one needs to store
items that may have many different attributes (like size, color, weight, etc),
and the set of possible attributes is very large and/or unknown in advance. In
that case, attributes can be put into dynamic columns.

Dynamic Columns Basics
----------------------

The table should have a blob column which will be used as storage for dynamic
columns:

create table assets (
 item_name varchar(32) primary key, -- A common attribute for all items
 dynamic_cols  blob  -- Dynamic columns will be stored here
);

Once created, one can access dynamic columns via dynamic column functions:

Insert a row with two dynamic columns: color=blue, size=XL

INSERT INTO assets VALUES 
 ('MariaDB T-shirt', COLUMN_CREATE('color', 'blue', 'size', 'XL'));

Insert another row with dynamic columns: color=black, price=500

INSERT INTO assets VALUES
 ('Thinkpad Laptop', COLUMN_CREATE('color', 'black', 'price', 500));

Select dynamic column 'color' for all items:

SELECT item_name, COLUMN_GET(dynamic_cols, 'color' as char) 
 AS color FROM assets;
+-----------------+-------+
| item_name       | color |
+-----------------+-------+
| MariaDB T-shirt | blue  |
| Thinkpad Laptop | black |
+-----------------+-------+

It is possible to add and remove dynamic columns from a row:

-- Remove a column:
UPDATE assets SET dynamic_cols=COLUMN_DELETE(dynamic_cols, "price") 
WHERE COLUMN_GET(dynamic_cols, 'color' as char)='black';

-- Add a column:
UPDATE assets SET dynamic_cols=COLUMN_ADD(dynamic_cols, 'warranty', '3 years')
WHERE item_name='Thinkpad Laptop';

You can also list all columns, or get them together with their values in JSON
format:

SELECT item_name, column_list(dynamic_cols) FROM assets;
+-----------------+---------------------------+
| item_name       | column_list(dynamic_cols) |
+-----------------+---------------------------+
| MariaDB T-shirt | `size`,`color`            |
| Thinkpad Laptop | `color`,`warranty`        |
+-----------------+---------------------------+

SELECT item_name, COLUMN_JSON(dynamic_cols) FROM assets;
+-----------------+----------------------------------------+
| item_name       | COLUMN_JSON(dynamic_cols)              |
+-----------------+----------------------------------------+
| MariaDB T-shirt | {"size":"XL","color":"blue"}           |
| Thinkpad Laptop | {"color":"black","warranty":"3 years"} |
+-----------------+----------------------------------------+

Dynamic Columns Reference
-------------------------

The rest of this page is a complete reference of dynamic columns in MariaDB

Dynamic Columns Functions
-------------------------

COLUMN_CREATE
-------------

COLUMN_CREATE(column_nr, value [as type], [column_nr, value 
 [as type]]...);
COLUMN_CREATE(column_name, value [as type], [column_name, value 
 [as type]]...);

Return a dynamic columns blob that stores the specified columns with values.

The return value is suitable for

* 
storing in a table
further modification with other dynamic columns functions

The as type part allows one to specify the value type. In most cases, this is
redundant because MariaDB will be able to deduce the type of the value.
Explicit type specification may be needed when the type of the value is not
apparent. For example, a literal '2012-12-01' has a CHAR type by default, one
will need to specify '2012-12-01' AS DATE to have it stored as a date. See the
Datatypes section for further details. Note also MDEV-597.

Typical usage:

-- MariaDB 5.3+:
INSERT INTO tbl SET dyncol_blob=COLUMN_CREATE(1 /*column id*/, "value");
-- MariaDB 10.0.1+:
INSERT INTO tbl SET dyncol_blob=COLUMN_CREATE("column_name", "value");

COLUMN_ADD
----------

COLUMN_ADD(dyncol_blob, column_nr, value [as type], 
 [column_nr, value [as type]]...);
COLUMN_ADD(dyncol_blob, column_name, value [as type], 
 [column_name, value [as type]]...);

Adds or updates dynamic columns.

* 
dyncol_blob must be either a valid dynamic columns blob (for example,
COLUMN_CREATE returns such blob), or an empty string.
column_name specifies the name of the column to be added. If dyncol_blob
already has a column with this name, it will be overwritten.
value specifies the new value for the column.  Passing a NULL value will cause
the column to be deleted.
as type is optional. See #datatypes section for a discussion about types.

The return value is a dynamic column blob after the modifications.

Typical usage:

-- MariaDB 5.3+:
UPDATE tbl SET dyncol_blob=COLUMN_ADD(dyncol_blob, 1 /*column id*/, "value") 
 WHERE id=1;
-- MariaDB 10.0.1+:
UPDATE t1 SET dyncol_blob=COLUMN_ADD(dyncol_blob, "column_name", "value") 
 WHERE id=1;

Note: COLUMN_ADD() is a regular function (just like CONCAT()), hence, in order
to update the value in the table you have to use the UPDATE ... SET
dynamic_col=COLUMN_ADD(dynamic_col, ....) pattern.

COLUMN_GET
----------

COLUMN_GET(dyncol_blob, column_nr as type);
COLUMN_GET(dyncol_blob, column_name as type);

Get the value of a dynamic column by its name. If no column with the given
name exists, NULL will be returned.

column_name as type requires that one specify the datatype of the dynamic
column they are reading.

This may seem counter-intuitive: why would one need to specify which datatype
they're retrieving? Can't the dynamic columns system figure the datatype from
the data being stored?

The answer is: SQL is a statically-typed language. The SQL interpreter needs
to know the datatypes of all expressions before the query is run (for example,
when one is using prepared statements and runs "select COLUMN_GET(...)", the
prepared statement API requires the server to inform the client about the
datatype of the column being read before the query is executed and the server
can see what datatype the column actually has).

See the Datatypes section for more information about datatypes.

COLUMN_DELETE
-------------

COLUMN_DELETE(dyncol_blob, column_nr, column_nr...);
COLUMN_DELETE(dyncol_blob, column_name, column_name...);

Delete a dynamic column with the specified name. Multiple names can be given.

The return value is a dynamic column blob after the modification.

COLUMN_EXISTS
-------------

COLUMN_EXISTS(dyncol_blob, column_nr);
COLUMN_EXISTS(dyncol_blob, column_name);

Check if a column with name column_name exists in dyncol_blob. If yes, return
1, otherwise return 0.

COLUMN_LIST
-----------

COLUMN_LIST(dyncol_blob);

Return a comma-separated list of column names. The names are quoted with
backticks.

SELECT column_list(column_create('col1','val1','col2','val2'));
+---------------------------------------------------------+
| column_list(column_create('col1','val1','col2','val2')) |
+---------------------------------------------------------+
| `col1`,`col2`                                           |
+---------------------------------------------------------+

COLUMN_CHECK
------------

COLUMN_CHECK(dyncol_blob);

Check if dyncol_blob is a valid packed dynamic columns blob. Return value of 1
means the blob is valid, return value of 0 means it is not.

Rationale: Normally, one works with valid dynamic column blobs. Functions like
COLUMN_CREATE, COLUMN_ADD, COLUMN_DELETE always return valid dynamic column
blobs. However, if a dynamic column blob is accidentally truncated, or
transcoded from one character set to another, it will be corrupted. This
function can be used to check if a value in a blob field is a valid dynamic
column blob.

Note: It is possible that a truncation cut a Dynamic Column "clearly" so that
COLUMN_CHECK will not notice the corruption, but in any case of truncation a
warning is issued during value storing.

COLUMN_JSON
-----------

COLUMN_JSON(dyncol_blob);

Return a JSON representation of data in dyncol_blob.

Example:

SELECT item_name, COLUMN_JSON(dynamic_cols) FROM assets;
+-----------------+----------------------------------------+
| item_name       | COLUMN_JSON(dynamic_cols)              |
+----=�',-------------+----------------------------------------+
| MariaDB T-shirt | {"size":"XL","color":"blue"}           |
| Thinkpad Laptop | {"color":"black","warranty":"3 years"} |
+-----------------+----------------------------------------+

Limitation: COLUMN_JSON will decode nested dynamic columns at a nesting level
of not more than 10 levels deep. Dynamic columns that are nested deeper than
10 levels will be shown as BINARY string, without encoding.

Nesting Dynamic Columns
-----------------------

It is possible to use nested dynamic columns by putting one dynamic column
blob inside another. The COLUMN_JSON function will display nested columns.

SET @tmp= column_create('parent_column', 
 column_create('child_column', 12345));
Query OK, 0 rows affected (0.00 sec)

SELECT column_json(@tmp);
+------------------------------------------+
| column_json(@tmp)                        |
+------------------------------------------+
| {"parent_column":{"child_column":12345}} |
+------------------------------------------+

SELECT column_get(column_get(@tmp, 'parent_column' AS char), 
 'child_column' AS int);
+------------------------------------------------------------------------------

| column_get(column_get(@tmp, 'parent_column' as char), 'child_column' as int)
|
+------------------------------------------------------------------------------

|                                                                        12345
|
+------------------------------------------------------------------------------

If you are trying to get a nested dynamic column as a string use 'as BINARY'
as the last argument of COLUMN_GET (otherwise problems with character set
conversion and illegal symbols are possible):

select column_json( column_get(
 column_create('test1',
  column_create('key1','value1','key2','value2','key3','value3')),
 'test1' as BINARY));

Datatypes
---------

In SQL, one needs to define the type of each column in a table. Dynamic
columns do not provide any way to declare a type in advance ("whenever there
is a column 'weight', it should be integer" is not possible). However, each
particular dynamic column value is stored together with its datatype.

The set of possible datatypes is mostly the same as that used by the SQL CAST
and CONVERT functions. However, note that there are currently some differences
- see MDEV-597.

+--------+----------------------------------------------+-------------------+
| type   | dynamic column internal type                 | description       |
+--------+----------------------------------------------+-------------------+
| BINARY | DYN_COL_STRING                               | (variable length  |
| (N)]   |                                              | string with       |
|        |                                              | binary charset)   |
+--------+----------------------------------------------+-------------------+
| CHAR[( | DYN_COL_STRING                               | (variable length  |
| )]     |                                              | string with       |
|        |                                              | charset)          |
+--------+----------------------------------------------+-------------------+
| DATE   | DYN_COL_DATE                                 | (date - 3 bytes)  |
+--------+----------------------------------------------+-------------------+
| DATETI | DYN_COL_DATETIME                             | (date and time    |
| E[(D)] |                                              | (with             |
|        |                                              | microseconds) -   |
|        |                                              | 9 bytes)          |
+--------+----------------------------------------------+-------------------+
| DECIMA | DYN_COL_DECIMAL                              | (variable length  |
| [(M[,D |                                              | binary decimal    |
| )]     |                                              | representation    |
|        |                                              | with MariaDB      |
|        |                                              | limitation)       |
+--------+----------------------------------------------+-------------------+
| DOUBLE | DYN_COL_DOUBLE                               | (64 bit           |
| (M,D)] |                                              | double-precision  |
|        |                                              | floating point)   |
+--------+----------------------------------------------+-------------------+
| INTEGE | DYN_COL_INT                                  | (variable         |
|        |                                              | length, up to 64  |
|        |                                              | bit signed        |
|        |                                              | integer)          |
+--------+----------------------------------------------+-------------------+
| SIGNED | DYN_COL_INT                                  | (variable         |
| [INTEG |                                              | length, up to 64  |
| R]     |                                              | bit signed        |
|        |                                              | integer)          |
+--------+----------------------------------------------+-------------------+
| TIME[( | DYN_COL_TIME                                 | (time (with       |
| )]     |                                              | microseconds,     |
|        |                                              | may be negative)  |
|        |                                              | - 6 bytes)        |
+--------+----------------------------------------------+-------------------+
| UNSIGN | DYN_COL_UINT                                 | (variable         |
| D      |                                              | length, up to     |
| [INTEG |                                              | 64bit unsigned    |
| R]     |                                              | integer)          |
+--------+----------------------------------------------+-------------------+

A Note About Lengths
--------------------

If you're running queries like

SELECT COLUMN_GET(blob, 'colname' as CHAR) ...

without specifying a maximum length (i.e. using #as CHAR#, not as CHAR(n)),
MariaDB will report the maximum length of the resultset column to be
53,6870,911 (bytes or characters?) for MariaDB 5.3-10.0.0 and 16,777,216 for
MariaDB 10.0.1+. This may cause excessive memory usage in some client
libraries, because they try to pre-allocate a buffer of maximum resultset
width. If you suspect you're hitting this problem, use CHAR(n) whenever you're
using COLUMN_GET in the select list.

MariaDB 5.3 vs MariaDB 10.0
---------------------------

The dynamic columns feature was introduced into MariaDB in two steps:

* MariaDB 5.3 was the first version to support dynamic columns. Only numbers
 could be used as column names in this version.
* In MariaDB 10.0.1, column names can be either numbers or strings.
 Also, the COLUMN_JSON and COLUMN_CHECK functions were added.

See also Dynamic Columns in MariaDB 10.

Client-side API
---------------

It is also possible to create or parse dynamic columns blobs on the client
side. libmysql client library now includes an API for writing/reading dynamic
column blobs. See dynamic-columns-api for details.

Limitations
-----------

+---------------------------------------------------+------------------------+
| Description                                       | Limit                  |
+---------------------------------------------------+------------------------+
| Max number of columns                             | 65535                  |
+---------------------------------------------------+------------------------+
| Max total length of packed dynamic column         | max_allowed_packet     |
|                                                   | (1G)                   |
+---------------------------------------------------+------------------------+

URL: https://mariadb.com/kb/en/dynamic-columns/a@aThis page is about sequence objects. For details about the storage engine, see
Sequence Storage Engine.

Introduction
------------

A sequence is an object that generates a sequence of numeric values, as
specified by the CREATE SEQUENCE statement.

CREATE SEQUENCE will create a sequence that generates new values when called
with NEXT VALUE FOR sequence_name. It's an alternative to AUTO INCREMENT when
one wants to have more control of how the numbers are generated. As the
SEQUENCE caches values (up to the CACHE value in the CREATE SEQUENCE
statement, by default 1000) it can in some cases be much faster than AUTO
INCREMENT. Another benefit is that one can access the last value generated by
all used sequences, which solves one of the limitations with LAST_INSERT_ID().

Creating a Sequence
-------------------

The CREATE SEQUENCE statement is used to create a sequence. Here is an example
of a sequence starting at 100, incrementing by 10 each time:

CREATE SEQUENCE s START WITH 100 INCREMENT BY 10;

The CREATE SEQUENCE statement, along with defaults, can be viewd with the SHOW
CREATE SEQUENCE STATEMENT, for example:

SHOW CREATE SEQUENCE s\G
*************************** 1. row ***************************
   Table: s
Create Table: CREATE SEQUENCE `s` start with 100 minvalue 1 maxvalue
9223372036854775806 
 increment by 10 cache 1000 nocycle ENGINE=InnoDB

Using Sequence Objects
----------------------

To get the next value from a sequence, use

NEXT VALUE FOR sequence_name

or

NEXTVAL(sequence_name)

or in Oracle mode (SQL_MODE=ORACLE)

sequence_name.nextval

For retrieving the last value used by the current connection from a sequence
use:

PREVIOUS VALUE FOR sequence_name

or

LASTVAL(sequence_name)

or in Oracle mode (SQL_MODE=ORACLE)

sequence_name.currval

For example:

SELECT NEXTVAL(s);
+------------+
| NEXTVAL(s) |
+------------+
|        100 |
+------------+

SELECT NEXTVAL(s);
+------------+
| NEXTVAL(s) |
+------------+
|        110 |
+------------+

SELECT LASTVAL(s);
+------------+
| LASTVAL(s) |
+------------+
|        110 |
+------------+

Using Sequences in DEFAULT
--------------------------

Sequences can be used in DEFAULT:

create sequence s1;
create table t1 (a int primary key default (next value for s1), b int);
insert into t1 (b) values (1),(2);
select * from t1;
+---+------+
| a | b    |
+---+------+
| 1 |    1 |
| 2 |    2 |
+---+------+

Changing a Sequence
-------------------

The ALTER SEQUENCE statement is used for changing sequences. For example, to
restart the sequence at another value:

ALTER SEQUENCE s RESTART 50;

SELECT NEXTVAL(s);
+------------+
| NEXTVAL(s) |
+------------+
|         50 |
+------------+

The SETVAL function can also be used to set the next value to be returned for
a SEQUENCE, for example:

SELECT SETVAL(s, 100);
+----------------+
| SETVAL(s, 100) |
+----------------+
|            100 |
+----------------+

SETVAL can only be used to increase the sequence value. Attempting to set a
lower value will fail, returning NULL:

SELECT SETVAL(s, 50);
+---------------+
| SETVAL(s, 50) |
+---------------+
|          NULL |
+---------------+

Dropping a Sequence
-------------------

The DROP SEQUENCE statement is used to drop a sequence, for example:

DROP SEQUENCE s;

Replication
-----------

If one wants to use Sequences in a master-master setup or with Galera one
should use INCREMENT=0. This will tell the Sequence to use
auto_increment_increment and auto_increment_offset to generate unique values
for each server.

Standards Compliance
--------------------

MariaDB supports both ANSI SQL and Oracle syntax for sequences.

However as SEQUENCE is implemented as a special kind of table, it uses the
same namespace as tables. The benefits are that sequences show up in SHOW
TABLES, and one can also create a sequence with CREATE TABLE and drop it with
DROP TABLE. One can SELECT from it as from any other table. This ensures that
all old tools that work with tables should work with sequences.

Since sequence objects act as regular tables in many contexts, they will be
affected by LOCK TABLES. This is not the case in other DBMS, such as Oracle,
where LOCK TABLE does not affect sequences.

Notes
-----

One of the goals with the Sequence implementation is that all old tools, such
as mariadb-dump (previously mysqldump), should work unchanged, while still
keeping the normal usage of sequence standard compatibly.

To make this possible, sequence is currently implemented as a table with a few
exclusive properties.

The special properties for sequence tables are:

* A sequence table has always one row.
* When one creates a sequence, either with CREATE TABLE or CREATE SEQUENCE,
one row will be inserted.
* If one tries to insert into a sequence table, the single row will be
updated.  This allows mariadb-dump to work but also gives the additional
benefit that one can change all properties of a sequence with a single insert.
New applications should of course also use ALTER SEQUENCE.
* UPDATE or DELETE can't be performed on Sequence objects.
* Doing a select on the sequence shows the current state of the sequence,
except the values that are reserved in the cache.  The next_value column shows
the next value not reserved by the cache.
* FLUSH TABLES will close the sequence and the next sequence number generated
will be according to what's stored in the Sequence object. In effect, this
will discard the cached values.
* A number of normal table operations work on Sequence tables. See next
section.

Table Operations that Work with Sequences
-----------------------------------------

* SHOW CREATE TABLE sequence_name. This shows the table structure that is
behind the SEQUENCE including the field names that can be used with SELECT or
even CREATE TABLE.
* CREATE TABLE sequence-structure ... SEQUENCE=1
* ALTER TABLE sequence RENAME TO sequence2
* RENAME TABLE sequence_name TO new_sequence_name
* DROP TABLE sequence_name. This is allowed mainly to get old tools like
mariadb-dump to work with sequence tables.
* SHOW TABLES

Implementation
--------------

Internally, sequence tables are created as a normal table without rollback
(the InnoDB, Aria and MySAM engines support this), wrapped by a sequence
engine object. This allowed us to create sequences with almost no performance
impact for normal tables. (The cost is one 'if' per insert if the binary log
is enabled).

Underlying Table Structure
--------------------------

The following example shows the table structure of sequences and how it can be
used as a table. (Output of results are slightly edited to make them easier to
read)

create sequence t1;
show create sequence t1\G
*************************** 1. row ***************************
 CREATE SEQUENCE `t1` start with 1 minvalue 1 maxvalue 9223372036854775806
 increment by 1 cache 1000 nocycle ENGINE=InnoDB

show create table t1\G
*************************** 1. row ***************************
Create Table: CREATE TABLE `t1` (
 `next_not_cached_value` bigint(21) NOT NULL,
 `minimum_value` bigint(21) NOT NULL,
 `maximum_value` bigint(21) NOT NULL,
 `start_value` bigint(21) NOT NULL COMMENT 'start value when sequences is
created or value if RESTART is used',
 `increment` bigint(21) NOT NULL COMMENT 'increment value',
 `cache_size` bigint(21) unsigned NOT NULL,
 `cycle_option` tinyint(1) unsigned NOT NULL COMMENT '0 if no cycles are
allowed, 1 if the sequence should begin a new cycle when maximum_value is
passed',
 `cycle_count` bigint(21) NOT NULL COMMENT 'How many cycles have been done'
) ENGINE=InnoDB SEQUENCE=1

select * from t1\G
next_not_cached_value: 1
 minimum_value: 1
 maximum_value: 9223372036854775806
 start_value: 1
 increment: 1
 cache_size: 1000
 cycle_option: 0
 cycle_count: 0

The cycle_count column is incremented every time the sequence wraps around.

Credits
-------

* Thanks to Jianwe Zhao from Aliyun for his work on SEQUENCE in AliSQL, which
gave ideas and inspiration for this work.
* Thanks to Peter Gulutzan,who helped test and gave useful comments about the
implementation.

URL: https://mariadb.com/kb/en/sequence-overview/�����%I#DATETIMESyntax
------

DATETIME [(microsecond precision)]

Description
-----------

A date and time combination.

MariaDB displays DATETIME values in 'YYYY-MM-DD HH:MM:SS.ffffff' format, but
allows assignment of values to DATETIME columns using either strings or
numbers. For details, see date and time literals.

DATETIME columns also accept CURRENT_TIMESTAMP as the default value.

MariaDB 10.1.2 introduced the --mysql56-temporal-format option, on by default,
which allows MariaDB to store DATETMEs using the same low-level format MySQL
5.6 uses. For more information, see Internal Format, below.

For storage requirements, see Data Type Storage Requirements.

Supported Values
----------------

MariaDB stores values that use the DATETIME data type in a format that
supports values between 1000-01-01 00:00:00.000000 and 9999-12-31
23:59:59.999999.

MariaDB can also store microseconds with a precision between 0 and 6. If no
microsecond precision is specified, then 0 is used by default.

MariaDB also supports '0000-00-00' as a special zero-date value, unless
NO_ZERO_DATE is specified in the SQL_MODE. Similarly, individual components of
a date can be set to 0 (for example: '2015-00-12'), unless NO_ZERO_IN_DATE is
specified in the SQL_MODE. In many cases, the result of en expression
involving a zero-date, or a date with zero-parts, is NULL. If the
ALLOW_INVALID_DATES SQL_MODE is enabled, if the day part is in the range
between 1 and 31, the date does not produce any error, even for months that
have less than 31 days.

Oracle Mode
-----------

MariaDB starting with 10.3
--------------------------
In Oracle mode from MariaDB 10.3, DATE with a time portion is a synonym for
DATETIME. See also mariadb_schema.

Internal Format
---------------

In MariaDB 10.1.2 a new temporal format was introduced from MySQL 5.6 that
alters how the TIME, DATETIME and TIMESTAMP columns operate at lower levels.
These changes allow these temporal data types to have fractional parts and
negative values. You can disable this feature using the
mysql56_temporal_format system variable.

Tables that include TIMESTAMP values that were created on an older version of
MariaDB or that were created while the mysql56_temporal_format system variable
was disabled continue to store data using the older data type format.

In order to update table columns from the older format to the newer format,
execute an ALTER TABLE... MODIFY COLUMN statement that changes the column to
the *same* data type. This change may be needed if you want to export the
table's tablespace and import it onto a server that has
mysql56_temporal_format=ON set (see MDEV-15225).

For instance, if you have a DATETIME column in your table:

SHOW VARIABLES LIKE 'mysql56_temporal_format';

+-------------------------+-------+
| Variable_name           | Value |
+-------------------------+-------+
| mysql56_temporal_format | ON    |
+-------------------------+-------+

ALTER TABLE example_table MODIFY ts_col DATETIME;

When MariaDB executes the ALTER TABLE statement, it converts the data from the
older temporal format to the newer one.

In the event that you have several tables and columns using temporal data
types that you want to switch over to the new format, make sure the system
variable is enabled, then perform a dump and restore using mysqldump. The
columns using relevant temporal data types are restored using the new temporal
format.

Starting from MariaDB 10.5.1 columns with old temporal formats are marked with
a /* mariadb-5.3 */ comment in the output of SHOW CREATE TABLE, SHOW COLUMNS,
DESCRIBE statements, as well as in the COLUMN_TYPE column of the
INFORMATION_SCHEMA.COLUMNS Table.

SHOW CREATE TABLE mariadb5312_datetime\G
*************************** 1. row ***************************
   Table: mariadb5312_datetime
Create Table: CREATE TABLE `mariadb5312_datetime` (
 `dt0` datetime /* mariadb-5.3 */ DEFAULT NULL,
 `dt6` datetime(6) /* mariadb-5.3 */ DEFAULT NULL
) ENGINE=MyISAM DEFAULT CHARSET=latin1

Examples
--------

CREATE TABLE t1 (d DATETIME);

INSERT INTO t1 VALUES ("2011-03-11"), ("2012-04-19 13:08:22"),
 ("2013-07-18 13:44:22.123456");

SELECT * FROM t1;
+---------------------+
| d                   |
+---------------------+
| 2011-03-11 00:00:00 |
| 2012-04-19 13:08:22 |
| 2013-07-18 13:44:22 |
+---------------------+

CREATE TABLE t2 (d DATETIME(6));

INSERT INTO t2 VALUES ("2011-03-11"), ("2012-04-19 13:08:22"),
 ("2013-07-18 13:44:22.123456");

SELECT * FROM t2;
+----------------------------+
| d                          |
+----------------------------+
| 2011-03-11 00:00:00.000000 |
| 2012-04-19 13:08:22.000000 |
| 2013-07-18 13:44:22.123456 |
+----------------------------++

Strings used in datetime context are automatically converted to datetime(6).
If you want to have a datetime without seconds, you should use
CONVERT(..,datetime).

SELECT CONVERT('2007-11-30 10:30:19',datetime);
+-----------------------------------------+
| CONVERT('2007-11-30 10:30:19',datetime) |
+-----------------------------------------+
| 2007-11-30 10:30:19                     |
+-----------------------------------------+

SELECT CONVERT('2007-11-30 10:30:19',datetime(6));
+--------------------------------------------+
| CONVERT('2007-11-30 10:30:19',datetime(6)) |
+--------------------------------------------+
| 2007-11-30 10:30:19.000000                 |
+--------------------------------------------+

URL: https://mariadb.com/kb/en/datetime/https://mariadb.com/kb/en/datetime/�
�%(JSON_LOOSESyntax
------

JSON_LOOSE(json_doc)

Description
-----------

Adds spaces to a JSON document to make it look more readable.

Example
-------

SET @j = '{ "A":1,"B":[2,3]}';

SELECT JSON_LOOSE(@j), @j;
+-----------------------+--------------------+
| JSON_LOOSE(@j)        | @j                 |
+-----------------------+--------------------+
| {"A": 1, "B": [2, 3]} | { "A":1,"B":[2,3]} |
+-----------------------+--------------------+

URL: https://mariadb.com/kb/en/json_loose/https://mariadb.com/kb/en/json_loose/�
�%(JSON_MERGESyntax
------

JSON_MERGE(json_doc, json_doc[, json_doc] ...)

Description
-----------

Merges the given JSON documents.

Returns the merged result,or NULL if any argument is NULL.

An error occurs if any of the arguments are not valid JSON documents.

JSON_MERGE has been deprecated since MariaDB 10.2.25, MariaDB 10.3.16 and
MariaDB 10.4.5. JSON_MERGE_PATCH is an RFC 7396-compliant replacement, and
JSON_MERGE_PRESERVE is a synonym.

Example
-------

SET @json1 = '[1, 2]';
SET @json2 = '[3, 4]';

SELECT JSON_MERGE(@json1,@json2);
+---------------------------+
| JSON_MERGE(@json1,@json2) |
+---------------------------+
| [1, 2, 3, 4]              |
+---------------------------+

URL: https://mariadb.com/kb/en/json_merge/https://mariadb.com/kb/en/json_merge/G&(JSON_OBJECTSyntax
------

JSON_OBJECT([key, value[, key, value] ...])

Description
-----------

Returns a JSON object containing the given key/value pairs. The key/value list
can be empty.

An error will occur if there are an odd number of arguments, or any key name
is NULL.

Example
-------

SELECT JSON_OBJECT("id", 1, "name", "Monty");
+---------------------------------------+
| JSON_OBJECT("id", 1, "name", "Monty") |
+---------------------------------------+
| {"id": 1, "name": "Monty"}            |
+---------------------------------------+

URL: https://mariadb.com/kb/en/json_object/https://mariadb.com/kb/en/json_object/������l��(q)AUTO_INCREMENTDescription
-----------

The AUTO_INCREMENT attribute can be used to generate a unique identity for new
rows. When you insert a new record to the table (or upon adding an
AUTO_INCREMENT attribute with the ALTER TABLE statement), and the
auto_increment field is NULL or DEFAULT (in the case of an INSERT), the value
will automatically be incremented. This also applies to 0, unless the
NO_AUTO_VALUE_ON_ZERO SQL_MODE is enabled.

AUTO_INCREMENT columns start from 1 by default. The automatically generated
value can never be lower than 0.

Each table can have only one AUTO_INCREMENT column. It must defined as a key
(not necessarily the PRIMARY KEY or UNIQUE key). In some storage engines
(including the default InnoDB), if the key consists of multiple columns, the
AUTO_INCREMENT column must be the first column. Storage engines that permit
the column to be placed elsewhere are Aria, MyISAM, MERGE, Spider, TokuDB,
BLACKHOLE, FederatedX and Federated.

CREATE TABLE animals (
  id MEDIUMINT NOT NULL AUTO_INCREMENT,
  name CHAR(30) NOT NULL,
  PRIMARY KEY (id)
 );

INSERT INTO animals (name) VALUES
  ('dog'),('cat'),('penguin'),
  ('fox'),('whale'),('ostrich');

SELECT * FROM animals;
+----+---------+
| id | name    |
+----+---------+
|  1 | dog     |
|  2 | cat     |
|  3 | penguin |
|  4 | fox     |
|  5 | whale   |
|  6 | ostrich |
+----+---------+

SERIAL is an alias for BIGINT UNSIGNED NOT NULL AUTO_INCREMENT UNIQUE.

CREATE TABLE t (id SERIAL, c CHAR(1)) ENGINE=InnoDB;

SHOW CREATE TABLE t \G
*************************** 1. row ***************************
   Table: t
Create Table: CREATE TABLE `t` (
 `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
 `c` char(1) DEFAULT NULL,
 UNIQUE KEY `id` (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1

Setting or Changing the Auto_Increment Value
--------------------------------------------

You can use an ALTER TABLE statement to assign a new value to the
auto_increment table option, or set the insert_id server system variable to
change the next AUTO_INCREMENT value inserted by the current session.

LAST_INSERT_ID() can be used to see the last AUTO_INCREMENT value inserted by
the current session.

ALTER TABLE animals AUTO_INCREMENT=8;

INSERT INTO animals (name) VALUES ('aardvark');

SELECT * FROM animals;
+----+-----------+
| id | name      |
+----+-----------+
|  1 | dog       |
|  2 | cat       |
|  3 | penguin   |
|  4 | fox       |
|  5 | whale     |
|  6 | ostrich   |
|  8 | aardvark  |
+----+-----------+

SET insert_id=12;

INSERT INTO animals (name) VALUES ('gorilla');

SELECT * FROM animals;
+----+-----------+
| id | name      |
+----+-----------+
|  1 | dog       |
|  2 | cat       |
|  3 | penguin   |
|  4 | fox       |
|  5 | whale     |
|  6 | ostrich   |
|  8 | aardvark  |
| 12 | gorilla   |
+----+-----------+

InnoDB
------

Until MariaDB 10.2.3, InnoDB used an auto-increment counter that is stored in
memory. When the server restarts, the counter is re-initialized to the highest
value used in the table, which cancels the effects of any AUTO_INCREMENT = N
option in the table statements.

From MariaDB 10.2.4, this restriction has been lifted and AUTO_INCREMENT is
persistent.

See also AUTO_INCREMENT Handling in InnoDB.

Setting Explicit Values
-----------------------

It is possible to specify a value for an AUTO_INCREMENT column. If the key is
primary or unique, the value must not already exist in the key.

If the new value is higher than the current maximum value, the AUTO_INCREMENT
value is updated, so the next value will be higher. If the new value is lower
than the current maximum value, the AUTO_INCREMENT value remains unchanged.

The following example demonstrates these behaviors:

CREATE TABLE t (id INTEGER UNSIGNED AUTO_INCREMENT PRIMARY KEY) ENGINE =
InnoDB;

INSERT INTO t VALUES (NULL);
SELECT id FROM t;
+----+
| id |
+----+
|  1 |
+----+

INSERT INTO t VALUES (10); -- higher value
SELECT id FROM t;
+----+
| id |
+----+
|  1 |
| 10 |
+----+

INSERT INTO t VALUES (2); -- lower value
INSERT INTO t VALUES (NULL); -- auto value
SELECT id FROM t;
+----+
| id |
+----+
|  1 |
|  2 |
| 10 |
| 11 |
+----+

The ARCHIVE storage engine does not allow to insert a value that is lower than
the current maximum.

Missing Values
--------------

An AUTO_INCREMENT column normally has missing values. This happens because if
a row is deleted, or an AUTO_INCREMENT value is explicitly updated, old values
are never re-used. The REPLACE statement also deletes a row, and its value is
wasted. With InnoDB, values can be reserved by a transaction; but if the
transaction fails (for example, because of a ROLLBACK) the reserved value will
be lost.

Thus AUTO_INCREMENT values can be used to sort results in a chronological
order, but not to create a numeric sequence.

Replication
-----------

To make master-master or Galera safe to use AUTO_INCREMENT one should use the
system variables auto_increment_increment and auto_increment_offset to
generate unique values for each server.

CHECK Constraints, DEFAULT Values and Virtual Columns
-----------------------------------------------------

MariaDB starting with 10.2.6
----------------------------
From MariaDB 10.2.6 auto_increment columns are no longer permitted in CHECK
constraints, DEFAULT value expressions and virtual columns. They were
permitted in earlier versions, but did not work correctly. See MDEV-11117.

Generating Auto_Increment Values When Adding the Attribute
----------------------------------------------------------

CREATE OR REPLACE TABLE t1 (a INT);
INSERT t1 VALUES (0),(0),(0);
ALTER TABLE t1 MODIFY a INT NOT NULL AUTO_INCREMENT PRIMARY KEY;
SELECT * FROM t1;
+---+
| a |
+---+
| 1 |
| 2 |
| 3 |
+---+

CREATE OR REPLACE TABLE t1 (a INT);
INSERT t1 VALUES (5),(0),(8),(0);
ALTER TABLE t1 MODIFY a INT NOT NULL AUTO_INCREMENT PRIMARY KEY;
SELECT * FROM t1;
+---+
| a |
+---+
| 5 |
| 6 |
| 8 |
| 9 |
+---+

If the NO_AUTO_VALUE_ON_ZERO SQL_MODE is set, zero values will not be
automatically incremented:

SET SQL_MODE='no_auto_value_on_zero';
CREATE OR REPLACE TABLE t1 (a INT);
INSERT t1 VALUES (3), (0);
ALTER TABLE t1 MODIFY a INT NOT NULL AUTO_INCREMENT PRIMARY KEY;
SELECT * FROM t1;
+---+
| a |
+---+
| 0 |
| 3 |
+---+

URL: https://mariadb.com/kb/en/auto_increment/https://mariadb.com/kb/en/auto_increment/�&(JSON_PRETTYJSON_PRETTY was added as an alias for JSON_DETAILED in MariaDB 10.10.3,
MariaDB 10.9.5, MariaDB 10.8.7, MariaDB 10.7.8, MariaDB 10.6.12, MariaDB
10.5.19 and MariaDB 10.4.28.

URL: https://mariadb.com/kb/en/json_pretty/https://mariadb.com/kb/en/json_pretty/	J#(JSON_SETSyntax
------

JSON_SET(json_doc, path, val[, path, val] ...)

Description
-----------

Updates or inserts data into a JSON document, returning the result, or NULL if
any of the arguments are NULL or the optional path fails to find an object.

An error will occur if the JSON document is invalid, the path is invalid or if
the path contains a * or wildcard.

JSON_SET can update or insert data, while JSON_REPLACE can only update, and
JSON_INSERT only insert.

Examples
--------

SELECT JSON_SET(Priv, '$.locked', 'true') FROM mysql.global_priv

URL: https://mariadb.com/kb/en/json_set/https://mariadb.com/kb/en/json_set/��@x�I�>14)Window Functions Overview	K$)NTH_VALUESyntax
------

NTH_VALUE (expr[, num_row]) OVER ( 
 [ PARTITION BY partition_expression ]
 [ ORDER BY order_list ]
)

Description
-----------

The NTH_VALUE function returns the value evaluated at row number num_row of
the window frame, starting from 1, or NULL if the row does not exist.

URL: https://mariadb.com/kb/en/nth_value/https://mariadb.com/kb/en/nth_value/��^=����b��Introduction
------------

Window functions allow calculations to be performed across a set of rows
related to the current row.

Syntax
------

function (expression) OVER (
 [ PARTITION BY expression_list ]
 [ ORDER BY order_list [ frame_clause ] ] )

function:
 A valid window function

expression_list:
 expression | column_name [, expr_list ]

order_list:
 expression | column_name [ ASC | DESC ]
 [, ... ]

frame_clause:
 {ROWS | RANGE} {frame_border | BETWEEN frame_border AND frame_border}

frame_border:
 | UNBOUNDED PRECEDING
 | UNBOUNDED FOLLOWING
 | CURRENT ROW
 | expr PRECEDING
 | expr FOLLOWING

Description
-----------

In some ways, window functions are similar to aggregate functions in that they
perform calculations across a set of rows. However, unlike aggregate
functions, the output is not grouped into a single row.

Non-aggregate window functions include

* CUME_DIST
* DENSE_RANK
* FIRST_VALUE
* LAG
* LAST_VALUE
* LEAD
* MEDIAN
* NTH_VALUE
* NTILE
* PERCENT_RANK
* PERCENTILE_CONT
* PERCENTILE_DISC
* RANK, ROW_NUMBER

Aggregate functions that can also be used as window functions include

* AVG
* BIT_AND
* BIT_OR
* BIT_XOR
* COUNT
* MAX
* MIN
* STD
* STDDEV
* STDDEV_POP
* STDDEV_SAMP
* SUM
* VAR_POP
* VAR_SAMP
* VARIANCE

Window function queries are characterised by the OVER keyword, following which
the set of rows used for the calculation is specified. By default, the set of
rows used for the calculation (the "window) is the entire dataset, which can
be ordered with the ORDER BY clause. The PARTITION BY clause is used to reduce
the window to a particular group within the dataset.

For example, given the following data:

CREATE TABLE student (name CHAR(10), test CHAR(10), score TINYINT);

INSERT INTO student VALUES 
 ('Chun', 'SQL', 75), ('Chun', 'Tuning', 73),
 ('Esben', 'SQL', 43), ('Esben', 'Tuning', 31),
 ('Kaolin', 'SQL', 56), ('Kaolin', 'Tuning', 88),
 ('Tatiana', 'SQL', 87), ('Tatiana', 'Tuning', 83);

the following two queries return the average partitioned by test and by name
respectively:

SELECT name, test, score, AVG(score) OVER (PARTITION BY test) 
 AS average_by_test FROM student;
+---------+--------+-------+-----------------+
| name    | test   | score | average_by_test |
+---------+--------+-------+-----------------+
| Chun    | SQL    |    75 |         65.2500 |
| Chun    | Tuning |    73 |         68.7500 |
| Esben   | SQL    |    43 |         65.2500 |
| Esben   | Tuning |    31 |         68.7500 |
| Kaolin  | SQL    |    56 |         65.2500 |
| Kaolin  | Tuning |    88 |         68.7500 |
| Tatiana | SQL    |    87 |         65.2500 |
| Tatiana | Tuning |    83 |         68.7500 |
+---------+--------+-------+-----------------+

SELECT name, test, score, AVG(score) OVER (PARTITION BY name) 
 AS average_by_name FROM student;
+---------+--------+-------+-----------------+
| name    | test   | score | average_by_name |
+---------+--------+-------+-----------------+
| Chun    | SQL    |    75 |         74.0000 |
| Chun    | Tuning |    73 |         74.0000 |
| Esben   | SQL    |    43 |         37.0000 |
| Esben   | Tuning |    31 |         37.0000 |
| Kaolin  | SQL    |    56 |         72.0000 |
| Kaolin  | Tuning |    88 |         72.0000 |
| Tatiana | SQL    |    87 |         85.0000 |
| Tatiana | Tuning |    83 |         85.0000 |
+---------+--------+-------+-----------------+

It is also possible to specify which rows to include for the window function
(for example, the current row and all preceding rows). See Window Frames for
more details.

Scope
-----

Window functions were introduced in SQL:2003, and their definition was
expanded in subsequent versions of the standard. The last expansion was in the
latest version of the standard, SQL:2011.

Most database products support a subset of the standard, they implement some
functions defined as late as in SQL:2011, and at the same time leave some
parts of SQL:2008 unimplemented.

MariaDB:

* Supports ROWS and RANGE-type frames
All kinds of frame bounds are supported, including RANGE PRECEDING|FOLLOWING n
frame bounds (unlike PostgreSQL or MS SQL Server)
Does not yet support DATE[TIME] datatype and arithmetic for RANGE-type frames
(MDEV-9727)

* Does not support GROUPS-type frames (it seems that no popular database
supports it, either)

* Does not support frame exclusion (no other database seems to support it,
either) (MDEV-9724)
* Does not support explicit NULLS FIRST or NULLS LAST.
* Does not support nested navigation in window functions (this is
VALUE_OF(expr AT row_marker [, default_value) syntax)

* The following window functions are supported:
"Streamable" window functions: ROW_NUMBER, RANK, DENSE_RANK, 
Window functions that can be streamed once the number of rows in partition is
known: PERCENT_RANK, CUME_DIST, NTILE

* Aggregate functions that are currently supported as window functions are:
COUNT, SUM, AVG, BIT_OR, BIT_AND, BIT_XOR.
* Aggregate functions with the DISTINCT specifier (e.g. COUNT( DISTINCT x))
are not supported as window functions.

Links
-----

* MDEV-6115 is the main jira task for window functions development. Other
tasks are are attached as sub-tasks
* bb-10.2-mdev9543 is the feature tree for window functions. Development is
ongoing, and this tree has the newest changes.
* Testcases are in mysql-test/t/win*.test

Examples
--------

Given the following sample data:

CREATE TABLE users (
 email VARCHAR(30),
 first_name VARCHAR(30),
 last_name VARCHAR(30),
 account_type VARCHAR(30)
);

INSERT INTO users VALUES 
 ('admin@boss.org', 'Admin', 'Boss', 'admin'),
 ('bob.carlsen@foo.bar', 'Bob', 'Carlsen', 'regular'),
 ('eddie.stevens@data.org', 'Eddie', 'Stevens', 'regular'),
 ('john.smith@xyz.org', 'John', 'Smith', 'regular'),
 ('root@boss.org', 'Root', 'Chief', 'admin')

First, let's order the records by email alphabetically, giving each an
ascending rnum value starting with 1. This will make use of the ROW_NUMBER
window function:

SELECT row_number() OVER (ORDER BY email) AS rnum,
  email, first_name, last_name, account_type
FROM users ORDER BY email;
+------+------------------------+------------+-----------+--------------+
| rnum | email                  | first_name | last_name | account_type |
+------+------------------------+------------+-----------+--------------+
|    1 | admin@boss.org         | Admin      | Boss      | admin        |
|    2 | bob.carlsen@foo.bar    | Bob        | Carlsen   | regular      |
|    3 | eddie.stevens@data.org | Eddie      | Stevens   | regular      |
|    4 | john.smith@xyz.org     | John       | Smith     | regular      |
|    5 | root@boss.org          | Root       | Chief     | admin        |
+------+------------------------+------------+-----------+--------------

We can generate separate sequences based on account type, using the PARTITION
BY clause:

SELECT row_number() OVER (PARTITION BY account_type ORDER BY email) AS rnum, 
 email, first_name, last_name, account_type
FROM users ORDER BY account_type,email;
+------+------------------------+------------+-----------+--------------+
| rnum | email                  | first_name | last_name | account_type |
+------+------------------------+------------+-----------+--------------+
|    1 | admin@boss.org         | Admin      | Boss      | admin        |
|    2 | root@boss.org          | Root       | Chief     | admin        |
|    1 | bob.carlsen@foo.bar    | Bob        | Carlsen   | regular      |
|    2 | eddie.stevens@data.org | Eddie      | Stevens   | regular      |
|    3 | john.smith@xyz.org     | John       | Smith     | regular      |
+------+------------------------+------------+-----------+--------------+

Given the following structure and data, we want to find the top 5 salaries
from each department.

CREATE TABLE employee_salaries (dept VARCHAR(20), name VARCHAR(20), salary
INT(11));

INSERT INTO employee_salaries VALUES
('Engineering', 'Dharma', 3500),
('Engineering', 'Binh', 3000),
('Engineering', 'Adalynn', 2800),
('Engineering', 'Samuel', 2500),
('Engineering', 'Cveta', 2200),
('Engineering', 'Ebele', 1800),
('Sales', 'Carbry', 500),
('Sales', 'Clytemnestra', 400),
('Sales', 'Juraj', 300),
('Sales', 'Kalpana', 300),
('Sales',�?��D+�)CASE StatementSyntax
------

CASE case_value
  WHEN when_value THEN statement_list
  [WHEN when_value THEN statement_list] ...
  [ELSE statement_list]
END CASE

Or:

CASE
  WHEN search_condition THEN statement_list
  [WHEN search_condition THEN statement_list] ...
  [ELSE statement_list]
END CASE

Description
-----------

The text on this page describes the CASE statement for stored programs. See
the CASE OPERATOR for details on the CASE operator outside of stored programs.

The CASE statement for stored programs implements a complex conditional
construct. If a search_condition evaluates to true, the corresponding SQL
statement list is executed. If no search condition matches, the statement list
in the ELSE clause is executed. Each statement_list consists of one or more
statements.

The CASE statement cannot have an ELSE NULL clause, and it is terminated with
END CASE instead of END. implements a complex conditional construct. If a
search_condition evaluates to true, the corresponding SQL statement list is
executed. If no search condition matches, the statement list in the ELSE
clause is executed. Each statement_list consists of one or more statements.

If no when_value or search_condition matches the value tested and the CASE
statement contains no ELSE clause, a Case not found for CASE statement error
results.

Each statement_list consists of one or more statements; an empty
statement_list is not allowed. To handle situations where no value is matched
by any WHEN clause, use an ELSE containing an empty BEGIN ... END block, as
shown in this example:

DELIMITER |
CREATE PROCEDURE p()
BEGIN
 DECLARE v INT DEFAULT 1;
 CASE v
  WHEN 2 THEN SELECT v;
  WHEN 3 THEN SELECT 0;
  ELSE BEGIN END;
 END CASE;
END;
|

The indentation used here in the ELSE clause is for purposes of clarity only,
and is not otherwise significant. See Delimiters in the mariadb client for
more on the use of the delimiter command.

Note: The syntax of the CASE statement used inside stored programs differs
slightly from that of the SQL CASE expression described in CASE OPERATOR. The
CASE statement cannot have an ELSE NULL clause, and it is terminated with END
CASE instead of END.

URL: https://mariadb.com/kb/en/case-statement/https://mariadb.com/kb/en/case-statement/,H,DECLARE CONDITIONSyntax
------

DECLARE condition_name CONDITION FOR condition_value

condition_value:
  SQLSTATE [VALUE] sqlstate_value
 | mysql_error_code

Description
-----------

The DECLARE ... CONDITION statement defines a named error condition. It
specifies a condition that needs specific handling and associates a name with
that condition. Later, the name can be used in a DECLARE ... HANDLER, SIGNAL
or RESIGNAL statement (as long as the statement is located in the same BEGIN
... END block).

Conditions must be declared after local variables, but before CURSORs and
HANDLERs.

A condition_value for DECLARE ... CONDITION can be an SQLSTATE value (a
5-character string literal) or a MySQL error code (a number). You should not
use SQLSTATE value '00000' or MySQL error code 0, because those indicate
sucess rather than an error condition. If you try, or if you specify an
invalid SQLSTATE value, an error like this is produced:

ERROR 1407 (42000): Bad SQLSTATE: '00000'

For a list of SQLSTATE values and MariaDB error codes, see MariaDB Error Codes.

URL: https://mariadb.com/kb/en/declare-condition/https://mariadb.com/kb/en/declare-condition/.�+DECLARE VariableSyntax
------

DECLARE var_name [, var_name] ... [[ROW] TYPE OF]] type [DEFAULT value]

Description
-----------

This statement is used to declare local variables within stored programs. To
provide a default value for the variable, include a DEFAULT clause. The value
can be specified as an expression (even subqueries are permitted); it need not
be a constant. If the DEFAULT clause is missing, the initial value is NULL.

Local variables are treated like stored routine parameters with respect to
data type and overflow checking. See CREATE PROCEDURE.

Local variables must be declared before CONDITIONs, CURSORs and HANDLERs.

Local variable names are not case sensitive.

The scope of a local variable is within the BEGIN ... END block where it is
declared. The variable can be referred to in blocks nested within the
declaring block, except those blocks that declare a variable with the same
name.

TYPE OF / ROW TYPE OF
---------------------

MariaDB starting with 10.3
--------------------------
TYPE OF and ROW TYPE OF anchored data types for stored routines were
introduced in MariaDB 10.3.

Anchored data types allow a data type to be defined based on another object,
such as a table row, rather than specifically set in the declaration. If the
anchor object changes, so will the anchored data type. This can lead to
routines being easier to maintain, so that if the data type in the table is
changed, it will automatically be changed in the routine as well.

Variables declared with ROW TYPE OF will have the same features as implicit
ROW variables. It is not possible to use ROW TYPE OF variables in a LIMIT
clause.

The real data type of TYPE OF and ROW TYPE OF table_name will become known at
the very beginning of the stored routine call. ALTER TABLE or DROP TABLE
statements performed inside the current routine on the tables that appear in
anchors won't affect the data type of the anchored variables, even if the
variable is declared after an ALTER TABLE or DROP TABLE statement.

The real data type of a ROW TYPE OF cursor_name variable will become known
when execution enters into the block where the variable is declared. Data type
instantiation will happen only once. In a cursor ROW TYPE OF variable that is
declared inside a loop, its data type will become known on the very first
iteration and won't change on further loop iterations.

The tables referenced in TYPE OF and ROW TYPE OF declarations will be checked
for existence at the beginning of the stored routine call. CREATE PROCEDURE or
CREATE FUNCTION will not check the referenced tables for existence.

Examples
--------

TYPE OF and ROW TYPE OF from MariaDB 10.3:

DECLARE tmp TYPE OF t1.a; -- Get the data type from the column {{a}} in the
table {{t1}}

DECLARE rec1 ROW TYPE OF t1; -- Get the row data type from the table {{t1}}

DECLARE rec2 ROW TYPE OF cur1; -- Get the row data type from the cursor
{{cur1}}

URL: https://mariadb.com/kb/en/declare-variable/https://mariadb.com/kb/en/declare-variable/';B)Aggregate Functions as Window FunctionsIt is possible to use aggregate functions as window functions. An aggregate
function used as a window function must have the OVER clause. For example,
here's COUNT() used as a window function:

select COUNT(*) over  (order by column) from table;

MariaDB currently allows these aggregate functions to be used as window
functions:

* AVG
* BIT_AND
* BIT_OR
* BIT_XOR
* COUNT
* JSON_ARRAYAGG
* JSON_OBJECTAGG
* MAX
* MIN
* STD
* STDDEV
* STDDEV_POP
* STDDEV_SAMP
* SUM
* VAR_POP
* VAR_SAMP
* VARIANCE

URL: https://mariadb.com/kb/en/aggregate-functions-as-window-functions/https://mariadb.com/kb/en/aggregate-functions-as-window-functions/��@I	��H)ColumnStore Window Functions#�7*SPIDER_FLUSH_TABLE_MON_CACHESyntax
------

SPIDER_FLUSH_TABLE_MON_CACHE()

Description
-----------

A UDF installed with the Spider Storage Engine, this function is used for
refreshing monitoring server information. It returns a value of 1.

Examples
--------

SELECT SPIDER_FLUSH_TABLE_MON_CACHE();
+--------------------------------+
| SPIDER_FLUSH_TABLE_MON_CACHE() |
+--------------------------------+
|                              1 |
+--------------------------------+

URL: https://mariadb.com/kb/en/spider_flush_table_mon_cache/https://mariadb.com/kb/en/spider_flush_table_mon_cache/C]
9X��
����6%��Introduction
------------

MariaDB ColumnStore provides support for window functions broadly following
the SQL 2003 specification. A window function allows for calculations relating
to a window of data surrounding the current row in a result set. This
capability provides for simplified queries in support of common business
questions such as cumulative totals, rolling averages, and top 10 lists.

Aggregate functions are utilized for window functions however differ in
behavior from a group by query because the rows remain ungrouped. This
provides support for cumulative sums and rolling averages, for example.

Two key concepts for window functions are Partition and Frame:

* A Partition is a group of rows, or window, that have the same value for a
specific column, for example a Partition can be created over a time period
such as a quarter or lookup values.
* The Frame for each row  is a subset of the row's Partition. The frame
typically is dynamic allowing for a sliding frame of rows within the
Partition. The Frame determines the range of rows for the windowing function.
A Frame could be defined as the last X rows and next Y rows all the way up to
the entire Partition.

Window functions are applied after joins, group by, and having clauses are
calculated.

Syntax
------

A window function is applied in the select clause using the following syntax:

function_name ([expression [, expression ... ]]) OVER ( window_definition )

where window_definition is defined as:

[ PARTITION BY expression [, ...] ]
[ ORDER BY expression [ ASC | DESC ] [ NULLS { FIRST | LAST } ] [, ...] ]
[ frame_clause ]

PARTITION BY:

* Divides the window result set into groups based on one or more expressions.
* An expression may be a constant, column, and non window function expressions.
* A query is not limited to a single partition by clause. Different partition
clauses can be used across different window function applications.
* The partition by columns do not need to be in the select list but do need to
be available from the query result set.
* If there is no PARTITION BY clause, all rows of the result set define the
group.

ORDER BY

* Defines the ordering of values within the partition.
* Can be ordered by multiple keys which may be a constant, column or non
window function expression.
* The order by columns do not need to be in the select list but need to be
available from the query result set.
* Use of a select column alias from the query is not supported.
* ASC (default) and DESC options allow for ordering ascending or descending.
* NULLS FIRST and NULL_LAST options specify whether null values come first or
last in the ordering sequence. NULLS_FIRST is the default for ASC order, and
NULLS_LAST is the default for DESC order.

and the optional frame_clause is defined as:

{ RANGE | ROWS } frame_start
{ RANGE | ROWS } BETWEEN frame_start AND frame_end

and the optional frame_start and frame_end are defined as (value being a
numeric expression):

UNBOUNDED PRECEDING
value PRECEDING
CURRENT ROW
value FOLLOWING
UNBOUNDED FOLLOWING

RANGE/ROWS:

* Defines the windowing clause for calculating the set of rows that the
function applies to for calculating a given rows window function result.
* Requires an ORDER BY clause to define the row order for the window.
* ROWS specify the window in physical units, i.e. result set rows and must be
a constant or expression evaluating to a positive numeric value.
* RANGE specifies the window as a logical offset. If the the expression
evaluates to a numeric value then the ORDER BY expression must be a numeric or
DATE type. If the expression evaluates to an interval value then the ORDER BY
expression must be a DATE data type.
* UNBOUNDED PRECEDING indicates the window starts at the first row of the
partition.
* UNBOUNDED FOLLOWING indicates the window ends at the last row of the
partition.
* CURRENT ROW specifies the window start or ends at the current row or value.
* If omitted, the default is ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW.

Supported Functions
-------------------

+--------------------------------+-------------------------------------------+
| Function                       | Description                               |
+--------------------------------+-------------------------------------------+
| AVG()                          | The average of all input values.          |
+--------------------------------+-------------------------------------------+
| COUNT()                        | Number of input rows.                     |
+--------------------------------+-------------------------------------------+
| CUME_DIST()                    | Calculates the cumulative distribution,   |
|                                | or relative rank, of the current row to   |
|                                | other rows in the same partition. Number  |
|                                | of peer or preceding rows / number of     |
|                                | rows in partition.                        |
+--------------------------------+-------------------------------------------+
| DENSE_RANK()                   | Ranks items in a group leaving no gaps    |
|                                | in ranking sequence when there are ties.  |
+--------------------------------+-------------------------------------------+
| FIRST_VALUE()                  | The value evaluated at the row that is    |
|                                | the first row of the window frame         |
|                                | (counting from 1); null if no such row.   |
+--------------------------------+-------------------------------------------+
| LAG()                          | The value evaluated at the row that is    |
|                                | offset rows before the current row        |
|                                | within the partition; if there is no      |
|                                | such row, instead return default. Both    |
|                                | offset and default are evaluated with     |
|                                | respect to the current row. If omitted,   |
|                                | offset defaults to 1 and default to       |
|                                | null. LAG provides access to more than    |
|                                | one row of a table at the same time       |
|                                | without a self-join. Given a series of    |
|                                | rows returned from a query and a          |
|                                | position of the cursor, LAG provides      |
|                                | access to a row at a given physical       |
|                                | offset prior to that position.            |
+--------------------------------+-------------------------------------------+
| LAST_VALUE()                   | The value evaluated at the row that is    |
|                                | the last row of the window frame          |
|                                | (counting from 1); null if no such row.   |
+--------------------------------+-------------------------------------------+
| LEAD()                         | Provides access to a row at a given       |
|                                | physical offset beyond that position.     |
|                                | Returns value evaluated at the row that   |
|                                | is offset rows after the current row      |
|                                | within the partition; if there is no      |
|                                | such row, instead return default. Both    |
|                                | offset and default are evaluated with     |
|                                | respect to the current row. If omitted,   |
|                                | offset defaults to 1 and default to null. |
+--------------------------------+-------------------------------------------+
| MAX()                          | Maximum value of expression across all    |
|                                | input values.                             |
+--------------------------------+-------------------------------------------+
| MEDIAN() 6�ɚ                      | An inverse distribution function that     |
|                                | assumes a continuous distribution model.  |
|                                | It takes a numeric or datetime value and  |
|                                | returns the middle value or an            |
|                                | interpolated value that would be the      |
|                                | middle value once the values are sorted.  |
|                                | Nulls are ignored in the calculation.     |
+--------------------------------+-------------------------------------------+
| MIN()                          | Minimum value of expression across all    |
|                                | input values.                             |
+--------------------------------+-------------------------------------------+
| NTH_VALUE()                    | The value evaluated at the row that is    |
|                                | the nth row of the window frame           |
|                                | (counting from 1); null if no such row.   |
+--------------------------------+-------------------------------------------+
| NTILE()                        | Divides an ordered data set into a        |
|                                | number of buckets indicated by expr and   |
|                                | assigns the appropriate bucket number to  |
|                                | each row. The buckets are numbered 1      |
|                                | through expr. The expr value must         |
|                                | resolve to a positive constant for each   |
|                                | partition. Integer ranging from 1 to the  |
|                                | argument value, dividing the partition    |
|                                | as equally as possible.                   |
+--------------------------------+-------------------------------------------+
| PERCENT_RANK()                 | relative rank of the current row: (rank   |
|                                | - 1) / (total rows - 1).                  |
+--------------------------------+-------------------------------------------+
| PERCENTILE_CONT()              | An inverse distribution function that     |
|                                | assumes a continuous distribution model.  |
|                                | It takes a percentile value and a sort    |
|                                | specification, and returns an             |
|                                | interpolated value that would fall into   |
|                                | that percentile value with respect to     |
|                                | the sort specification. Nulls are         |
|                                | ignored in the calculation.               |
+--------------------------------+-------------------------------------------+
| PERCENTILE_DISC()              | An inverse distribution function that     |
|                                | assumes a discrete distribution model.    |
|                                | It takes a percentile value and a sort    |
|                                | specification and returns an element      |
|                                | from the set. Nulls are ignored in the    |
|                                | calculation.                              |
+--------------------------------+-------------------------------------------+
| RANK()                         | rank of the current row with gaps; same   |
|                                | as row_number of its first peer.          |
+--------------------------------+-------------------------------------------+
| ROW_NUMBER()                   | number of the current row within its      |
|                                | partition, counting from 1                |
+--------------------------------+-------------------------------------------+
| STDDEV() STDDEV_POP()          | Computes the population standard          |
|                                | deviation and returns the square root of  |
|                                | the population variance.                  |
+--------------------------------+-------------------------------------------+
| STDDEV_SAMP()                  | Computes the cumulative sample standard   |
|                                | deviation and returns the square root of  |
|                                | the sample variance.                      |
+--------------------------------+-------------------------------------------+
| SUM()                          | Sum of expression across all input        |
|                                | values.                                   |
+--------------------------------+-------------------------------------------+
| VARIANCE() VAR_POP()           | Population variance of the input values   |
|                                | (square of the population standard        |
|                                | deviation).                               |
+--------------------------------+-------------------------------------------+
| VAR_SAMP()                     | Sample variance of the input values       |
|                                | (square of the sample standard            |
|                                | deviation).                               |
+--------------------------------+-------------------------------------------+

Examples
--------

Example Schema
--------------

The examples are all based on the following simplified sales opportunity table:

create table opportunities (
id int,
accountName varchar(20),
name varchar(128),
owner varchar(7),
amount decimal(10,2),
closeDate date,
stageName varchar(11)
) engine=columnstore;

Some example values are (thanks to https://www.mockaroo.com for sample data
generation):

+----+---------------+------+--------+---------+-------------+-------------+
| id | accountName   | name | owner  | amount  | closeDate   | stageName   |
+----+---------------+------+--------+---------+-------------+-------------+
| 1  | Browseblab    | Mult | Bob    | 26444.8 | 2016-10-20  | Negotiating |
|    |               | -lat |        |         |             |             |
|    |               | ral  |        |         |             |             |
|    |               | exec |        |         |             |             |
|    |               | tive |        |         |             |             |
|    |               | func |        |         |             |             |
|    |               | ion  |        |         |             |             |
+----+---------------+------+--------+---------+-------------+-------------+
| 2  | Mita          | Orga | Maria  | 477878. | 2016-11-28  | ClosedWon   |
|    |               | ic   |        | 1       |             |             |
|    |               | dema |        |         |             |             |
|    |               | d-dr |        |         |             |             |
|    |               | ven  |        |         |             |             |
|    |               | benc |        |         |             |             |
|    |               | mark |        |         |             |             |
+----+---------------+------+--------+---------+-------------+-------------+
| 3  | Miboo         | De-e | Olivie | 80181.7 | 2017-01-05  | ClosedWon   |
|    |               | gine |        |         |             |             |
|    |               | red  |        |         |             |             |
|    |               | hybr |        |         |             |             |
|    |               | d    |        |         |             |             |
|    |               | grou |        |         |             |             |
|    |               | ware |        |         |             |             |
+----+---------------+------+--------+---------+-------------+-------------+
| 4  | Youbridge     | Ente | Chris  | 946245. | 2016-07-02  | ClosedWon   |
|    |               | pris |        | 9       |             |             |
|    |               | -wid |        |         |             |             |
|    |               |    �e[�  |        |         |             |             |
|    |               | bott |        |         |             |             |
|    |               | m-li |        |         |             |             |
|    |               | e    |        |         |             |             |
|    |               | Grap |        |         |             |             |
|    |               | ic   |        |         |             |             |
|    |               | Inte |        |         |             |             |
|    |               | face |        |         |             |             |
+----+---------------+------+--------+---------+-------------+-------------+
| 5  | Skyba         | Reve | Maria  | 696241. | 2017-02-17  | Negotiating |
|    |               | se-e |        | 2       |             |             |
|    |               | gine |        |         |             |             |
|    |               | red  |        |         |             |             |
|    |               | fres |        |         |             |             |
|    |               | -thi |        |         |             |             |
|    |               | king |        |         |             |             |
|    |               | stan |        |         |             |             |
|    |               | ardi |        |         |             |             |
|    |               | atio |        |         |             |             |
|    |               |      |        |         |             |             |
+----+---------------+------+--------+---------+-------------+-------------+
| 6  | Eayo          | Fund | Bob    | 765605. | 2016-08-27  | Prospecting |
|    |               | ment |        | 2       |             |             |
|    |               | l    |        |         |             |             |
|    |               | well |        |         |             |             |
|    |               | modu |        |         |             |             |
|    |               | ated |        |         |             |             |
|    |               | arti |        |         |             |             |
|    |               | icia |        |         |             |             |
|    |               |      |        |         |             |             |
|    |               | inte |        |         |             |             |
|    |               | lige |        |         |             |             |
|    |               | ce   |        |         |             |             |
+----+---------------+------+--------+---------+-------------+-------------+
| 7  | Yotz          | Exte | Chris  | 319624. | 2017-01-06  | ClosedLost  |
|    |               | ded  |        | 0       |             |             |
|    |               | seco |        |         |             |             |
|    |               | dary |        |         |             |             |
|    |               | infr |        |         |             |             |
|    |               | stru |        |         |             |             |
|    |               | ture |        |         |             |             |
+----+---------------+------+--------+---------+-------------+-------------+
| 8  | Oloo          | Conf | Chris  | 321016. | 2017-03-08  | ClosedLost  |
|    |               | gura |        | 6       |             |             |
|    |               | le   |        |         |             |             |
|    |               | web- |        |         |             |             |
|    |               | nabl |        |         |             |             |
|    |               | d    |        |         |             |             |
|    |               | data |        |         |             |             |
|    |               | ware |        |         |             |             |
|    |               | ouse |        |         |             |             |
+----+---------------+------+--------+---------+-------------+-------------+
| 9  | Kaymbo        | Mult | Bob    | 690881. | 2017-01-02  | Developing  |
|    |               | -lat |        | 1       |             |             |
|    |               | ral  |        |         |             |             |
|    |               | web- |        |         |             |             |
|    |               | nabl |        |         |             |             |
|    |               | d    |        |         |             |             |
|    |               | defi |        |         |             |             |
|    |               | itio |        |         |             |             |
|    |               |      |        |         |             |             |
+----+---------------+------+--------+---------+-------------+-------------+
| 10 | Rhyloo        | Publ | Chris  | 965477. | 2016-11-07  | Prospecting |
|    |               | c-ke |        | 4       |             |             |
|    |               |      |        |         |             |             |
|    |               | cohe |        |         |             |             |
|    |               | ent  |        |         |             |             |
|    |               | infr |        |         |             |             |
|    |               | stru |        |         |             |             |
|    |               | ture |        |         |             |             |
+----+---------------+------+--------+---------+-------------+-------------+

The schema, sample data, and queries are available as an attachment to this
article.

Cumulative Sum and Running Max Example
--------------------------------------

Window functions can be used to achieve cumulative / running calculations on a
detail report. In this case a won opportunity report for a 7 day period adds
columns to show the accumulated won amount as well as the current highest
opportunity amount in preceding rows.

select owner, 
accountName, 
CloseDate, 
amount, 
sum(amount) over (order by CloseDate rows between unbounded preceding and
current row) cumeWon, 
max(amount) over (order by CloseDate rows between unbounded preceding and
current row) runningMax
from opportunities 
where stageName='ClosedWon' 
and closeDate >= '2016-10-02' and closeDate <= '2016-10-09' 
order by CloseDate;

with example results:

+--------+---------------+-------------+---------+----------+--------------+
| owner  | accountName   | CloseDate   | amount  | cumeWon  | runningMax   |
+--------+---------------+-------------+---------+----------+--------------+
| Bill   | Babbleopia    | 2016-10-02  | 437636. | 437636.4 | 437636.47    |
|        |               |             | 7       |          |              |
+--------+---------------+-------------+---------+----------+--------------+
| Bill   | Thoughtworks  | 2016-10-04  | 146086. | 583722.9 | 437636.47    |
|        |               |             | 1       |          |              |
+--------+---------------+-------------+---------+----------+--------------+
| Olivie | Devpulse      | 2016-10-05  | 834235. | 1417958. | 834235.93    |
|        |               |             | 3       | 1        |              |
+--------+---------------+-------------+---------+----------+--------------+
| Chris  | Linkbridge    | 2016-10-07  | 539977. | 2458738. | 834235.93    |
|        |               |             | 5       | 5        |              |
+--------+---------------+-------------+---------+----------+--------------+
| Olivie | Trupe         | 2016-10-07  | 500802. | 1918761. | 834235.93    |
|        |               |             | 9       | 0        |              |
+--------+---------------+-------------+---------+----------+--------------+
| Bill   | Latz          | 2016-10-08  | 857254. | 3315993. | 857254.87    |
|        |               |             | 7       | 2        |              |
+--------+---------------+-------------+---------+----------+--------------+
| Chris  | Avamm         | 2016-10-09  | 699566. | 4015560. | 857254.87    |
|        |               |             | 6       | 8        |              |
+--------+---------------+-------------+---------+----------+--------------+

Partitioned Cumulative Sum and Running Max Example
-----�8�---------------------------------------------

The above example can be partitioned, so that the window functions are over a
particular field grouping such as owner and accumulate within that grouping.
This is achieved by adding the syntax "partition by <columns>" in the window
function clause.

select owner,  
accountName,  
CloseDate,  
amount,  
sum(amount) over (partition by owner order by CloseDate rows between unbounded
preceding and current row) cumeWon,  
max(amount) over (partition by owner order by CloseDate rows between unbounded
preceding and current row) runningMax 
from opportunities  
where stageName='ClosedWon' 
and closeDate >= '2016-10-02' and closeDate <= '2016-10-09'  
order by owner, CloseDate;

with example results:

+--------+---------------+-------------+---------+----------+--------------+
| owner  | accountName   | CloseDate   | amount  | cumeWon  | runningMax   |
+--------+---------------+-------------+---------+----------+--------------+
| Bill   | Babbleopia    | 2016-10-02  | 437636. | 437636.4 | 437636.47    |
|        |               |             | 7       |          |              |
+--------+---------------+-------------+---------+----------+--------------+
| Bill   | Thoughtworks  | 2016-10-04  | 146086. | 583722.9 | 437636.47    |
|        |               |             | 1       |          |              |
+--------+---------------+-------------+---------+----------+--------------+
| Bill   | Latz          | 2016-10-08  | 857254. | 1440977. | 857254.87    |
|        |               |             | 7       | 5        |              |
+--------+---------------+-------------+---------+----------+--------------+
| Chris  | Linkbridge    | 2016-10-07  | 539977. | 539977.4 | 539977.45    |
|        |               |             | 5       |          |              |
+--------+---------------+-------------+---------+----------+--------------+
| Chris  | Avamm         | 2016-10-09  | 699566. | 1239544. | 699566.86    |
|        |               |             | 6       | 1        |              |
+--------+---------------+-------------+---------+----------+--------------+
| Olivie | Devpulse      | 2016-10-05  | 834235. | 834235.9 | 834235.93    |
|        |               |             | 3       |          |              |
+--------+---------------+-------------+---------+----------+--------------+
| Olivie | Trupe         | 2016-10-07  | 500802. | 1335038. | 834235.93    |
|        |               |             | 9       | 2        |              |
+--------+---------------+-------------+---------+----------+--------------+

Ranking / Top Results
---------------------

The rank window function allows for ranking or assigning a numeric order value
based on the window function definition. Using the Rank() function will result
in the same value for ties / equal values and the next rank value skipped. The
Dense_Rank() function behaves similarly except the next consecutive number is
used after a tie rather than skipped. The Row_Number() function will provide a
unique ordering value. The example query shows the Rank() function being
applied to rank sales reps by the number of opportunities for Q4 2016.

select owner, 
wonCount, 
rank() over (order by wonCount desc) rank 
from (
 select owner,
 count(*) wonCount
 from opportunities
 where stageName='ClosedWon'
 and closeDate >= '2016-10-01' and closeDate < '2016-12-31'
 group by owner
) t
order by rank;

with example results (note the query is technically incorrect by using
closeDate < '2016-12-31' however this creates a tie scenario for illustrative
purposes):

+----------------------+----------------------------------+------------------+
| owner                | wonCount                         | rank             |
+----------------------+----------------------------------+------------------+
| Bill                 | 19                               | 1                |
+----------------------+----------------------------------+------------------+
| Chris                | 15                               | 2                |
+----------------------+----------------------------------+------------------+
| Maria                | 14                               | 3                |
+----------------------+----------------------------------+------------------+
| Bob                  | 14                               | 3                |
+----------------------+----------------------------------+------------------+
| Olivier              | 10                               | 5                |
+----------------------+----------------------------------+------------------+

If the dense_rank function is used the rank values would be 1,2,3,3,4 and for
the row_number function the values would be 1,2,3,4,5.

First and Last Values
---------------------

The first_value and last_value functions allow determining the first and last
values of a given range. Combined with a group by this allows summarizing
opening and closing values. The example shows a more complex case where
detailed information is presented for first and last opportunity by quarter.

select a.year, 
a.quarter, 
f.accountName firstAccountName, 
f.owner firstOwner, 
f.amount firstAmount, 
l.accountName lastAccountName, 
l.owner lastOwner, 
l.amount lastAmount 
from (
 select year,
 quarter,
 min(firstId) firstId,
 min(lastId) lastId
 from (
  select year(closeDate) year,
  quarter(closeDate) quarter,
  first_value(id) over (partition by year(closeDate), quarter(closeDate)
order by closeDate rows between unbounded preceding and current row) firstId, 
  last_value(id) over (partition by year(closeDate), quarter(closeDate)
order by closeDate rows between current row and unbounded following) lastId 
  from opportunities  where stageName='ClosedWon'
 ) t
 group by year, quarter order by year,quarter
) a 
join opportunities f on a.firstId = f.id 
join opportunities l on a.lastId = l.id 
order by year, quarter;

with example results:

+----+------+------------+--------+---------+-----------+-------+--------+
| ye | quar | firstAccou | firstO | firstAm | lastAccou | lastO | lastAm |
| r  | er   | tName      | ner    | unt     | tName     | ner   | unt    |
+----+------+------------+--------+---------+-----------+-------+--------+
| 20 | 3    | Skidoo     | Bill   | 523295. | Skipstorm | Bill  | 151420 |
| 6  |      |            |        | 7       |           |       | 86     |
+----+------+------------+--------+---------+-----------+-------+--------+
| 20 | 4    | Skimia     | Chris  | 961513. | Avamm     | Maria | 112493 |
| 6  |      |            |        | 9       |           |       | 65     |
+----+------+------------+--------+---------+-----------+-------+--------+
| 20 | 1    | Yombu      | Bob    | 536875. | Skaboo    | Chris | 270273 |
| 7  |      |            |        | 1       |           |       | 08     |
+----+------+------------+--------+---------+-----------+-------+--------+

Prior and Next Example
----------------------

Sometimes it useful to understand the previous and next values in the context
of a given row. The lag and lead window functions provide this capability. By
default the offset is one providing the prior or next value but can also be
provided to get a larger offset. The example query is a report of
opportunities by account name showing the opportunity amount, and the prior
and next opportunity amount for that account by close date.

select accountName, 
closeDate,  
amount currentOppAmount, 
lag(amount) over (partition by accountName order by closeDate) priorAmount,
lead(amount) over (partition by accountName order by closeDate) nextAmount 
from opportunities 
order by accountName, closeDate 
limit 9;

with example results:

+--------------+-----------+-------------------+--------------+-------------+
| accountName  | closeDate | currentOppAmount  | priorAmount  | nextAmount  |
+--------------+-----------+-------------------+--------------+-------------+
| Abata        | 2016-09-1 | 645098.45         | NULL         | 161086.82   |
|              |           |                   |              |             |
+--------------+-----------+-------------------+--------------+-----���n--------+
| Abata        | 2016-10-1 | 161086.82         | 645098.45    | 350235.75   |
|              |           |                   |              |             |
+--------------+-----------+-------------------+--------------+-------------+
| Abata        | 2016-12-1 | 350235.75         | 161086.82    | 878595.89   |
|              |           |                   |              |             |
+--------------+-----------+-------------------+--------------+-------------+
| Abata        | 2016-12-3 | 878595.89         | 350235.75    | 922322.39   |
|              |           |                   |              |             |
+--------------+-----------+-------------------+--------------+-------------+
| Abata        | 2017-01-2 | 922322.39         | 878595.89    | NULL        |
|              |           |                   |              |             |
+--------------+-----------+-------------------+--------------+-------------+
| Abatz        | 2016-10-1 | 795424.15         | NULL         | NULL        |
|              |           |                   |              |             |
+--------------+-----------+-------------------+--------------+-------------+
| Agimba       | 2016-07-0 | 288974.84         | NULL         | 914461.49   |
|              |           |                   |              |             |
+--------------+-----------+-------------------+--------------+-------------+
| Agimba       | 2016-09-0 | 914461.49         | 288974.84    | 176645.52   |
|              |           |                   |              |             |
+--------------+-----------+-------------------+--------------+-------------+
| Agimba       | 2016-09-2 | 176645.52         | 914461.49    | NULL        |
|              |           |                   |              |             |
+--------------+-----------+-------------------+--------------+-------------+

Quartiles Example
-----------------

The NTile window function allows for breaking up a data set into portions
assigned a numeric value to each portion of the range. NTile(4) breaks the
data up into quartiles (4 sets). The example query produces a report of all
opportunities summarizing the quartile boundaries of amount values.

select t.quartile, 
min(t.amount) min, 
max(t.amount) max 
from (
 select amount,
 ntile(4) over (order by amount asc) quartile
 from opportunities
 where closeDate >= '2016-10-01' and closeDate <= '2016-12-31'
 ) t
group by quartile 
order by quartile;

With example results:

+-----------------------------------------+----------------+----------------+
| quartile                                | min            | max            |
+-----------------------------------------+----------------+----------------+
| 1                                       | 6337.15        | 287634.01      |
+-----------------------------------------+----------------+----------------+
| 2                                       | 288796.14      | 539977.45      |
+-----------------------------------------+----------------+----------------+
| 3                                       | 540070.04      | 748727.51      |
+-----------------------------------------+----------------+----------------+
| 4                                       | 753670.77      | 998864.47      |
+-----------------------------------------+----------------+----------------+

Percentile Example
------------------

The percentile functions have a slightly different syntax from other window
functions as can be seen in the example below. These functions can be only
applied against numeric values. The argument to the function is the percentile
to evaluate. Following 'within group' is the sort expression which indicates
the sort column and optionally order. Finally after 'over' is an optional
partition by clause, for no partition clause use 'over ()'. The example below
utilizes the value 0.5 to calculate the median opportunity amount in the rows.
The values differ sometimes because percentile_cont will return the average of
the 2 middle rows for an even data set while percentile_desc returns the first
encountered in the sort.

select owner,  
accountName,  
CloseDate,  
amount,
percentile_cont(0.5) within group (order by amount) over (partition by owner)
pct_cont,
percentile_disc(0.5) within group (order by amount) over (partition by owner)
pct_disc
from opportunities  
where stageName='ClosedWon' 
and closeDate >= '2016-10-02' and closeDate <= '2016-10-09'  
order by owner, CloseDate;

With example results:

+--------+----------------+-------------+---------+------------+------------+
| owner  | accountName    | CloseDate   | amount  | pct_cont   | pct_disc   |
+--------+----------------+-------------+---------+------------+------------+
| Bill   | Babbleopia     | 2016-10-02  | 437636. | 437636.470 | 437636.47  |
|        |                |             | 7       | 000000     |            |
+--------+----------------+-------------+---------+------------+------------+
| Bill   | Thoughtworks   | 2016-10-04  | 146086. | 437636.470 | 437636.47  |
|        |                |             | 1       | 000000     |            |
+--------+----------------+-------------+---------+------------+------------+
| Bill   | Latz           | 2016-10-08  | 857254. | 437636.470 | 437636.47  |
|        |                |             | 7       | 000000     |            |
+--------+----------------+-------------+---------+------------+------------+
| Chris  | Linkbridge     | 2016-10-07  | 539977. | 619772.155 | 539977.45  |
|        |                |             | 5       | 000000     |            |
+--------+----------------+-------------+---------+------------+------------+
| Chris  | Avamm          | 2016-10-09  | 699566. | 619772.155 | 539977.45  |
|        |                |             | 6       | 000000     |            |
+--------+----------------+-------------+---------+------------+------------+
| Olivie | Devpulse       | 2016-10-05  | 834235. | 667519.110 | 500802.29  |
|        |                |             | 3       | 000000     |            |
+--------+----------------+-------------+---------+------------+------------+
| Olivie | Trupe          | 2016-10-07  | 500802. | 667519.110 | 500802.29  |
|        |                |             | 9       | 000000     |            |
+--------+----------------+-------------+---------+------------+------------+

URL: https://mariadb.com/kb/en/window-functions-columnstore-window-functions/���,��-�*DECLARE HANDLERSyntax
------

DECLARE handler_type HANDLER
  FOR condition_value [, condition_value] ...
  statement

handler_type:
  CONTINUE
 | EXIT
 | UNDO

condition_value:
  SQLSTATE [VALUE] sqlstate_value
 | condition_name
 | SQLWARNING
 | NOT FOUND
 | SQLEXCEPTION
 | mariadb_error_code

Description
-----------

The DECLARE ... HANDLER statement specifies handlers that each may deal with
one or more conditions. If one of these conditions occurs, the specified
statement is executed. statement can be a simple statement (for example, SET
var_name = value), or it can be a compound statement written using BEGIN and
END.

Handlers must be declared after local variables, a CONDITION and a CURSOR.

For a CONTINUE handler, execution of the current program continues after
execution of the handler statement. For an EXIT handler, execution terminates
for the BEGIN ... END compound statement in which the handler is declared.
(This is true even if the condition occurs in an inner block.) The UNDO
handler type statement is not supported.

If a condition occurs for which no handler has been declared, the default
action is EXIT.

A condition_value for DECLARE ... HANDLER can be any of the following values:

* An SQLSTATE value (a 5-character string literal) or a MariaDB error
code (a number). You should not use SQLSTATE value '00000' or MariaDB
error code 0, because those indicate sucess rather than an error
condition. For a list of SQLSTATE values and MariaDB error codes, see
MariaDB Error Codes.
* A condition name previously specified with DECLARE ... CONDITION. It must be
in the same stored program. See DECLARE CONDITION.
* SQLWARNING is shorthand for the class of SQLSTATE values that begin
with '01'.
* NOT FOUND is shorthand for the class of SQLSTATE values that begin
with '02'. This is relevant only the context of cursors and is used to
control what happens when a cursor reaches the end of a data set. If
no more rows are available, a No Data condition occurs with SQLSTATE
value 02000. To detect this condition, you can set up a handler for it
(or for a NOT FOUND condition). An example is shown in Cursor Overview. This
condition also occurs for SELECT ... INTO var_list statements that retrieve no
rows.
* SQLEXCEPTION is shorthand for the class of SQLSTATE values that do
not begin with '00', '01', or '02'.

When an error raises, in some cases it could be handled by multiple HANDLERs.
For example, there may be an handler for 1050 error, a separate handler for
the 42S01 SQLSTATE, and another separate handler for the SQLEXCEPTION class:
in theory all occurrences of HANDLER may catch the 1050 error, but MariaDB
chooses the HANDLER with the highest precedence. Here are the precedence rules:

* Handlers which refer to an error code have the highest precedence.
* Handlers which refer to a SQLSTATE come next.
* Handlers which refer to an error class have the lowest precedence.

In some cases, a statement could produce multiple errors. If this happens, in
some cases multiple handlers could have the highest precedence. In such cases,
the choice of the handler is indeterminate.

Note that if an error occurs within a CONTINUE HANDLER block, it can be
handled by another HANDLER. However, a HANDLER which is already in the stack
(that is, it has been called to handle an error and its execution didn't
finish yet) cannot handle new errors—this prevents endless loops. For example,
suppose that a stored procedure contains a CONTINUE HANDLER for SQLWARNING and
another CONTINUE HANDLER for NOT FOUND. At some point, a NOT FOUND error
occurs, and the execution enters the NOT FOUND HANDLER. But within that
handler, a warning occurs, and the execution enters the SQLWARNING HANDLER. If
another NOT FOUND error occurs, it cannot be handled again by the NOT FOUND
HANDLER, because its execution is not finished.

When a DECLARE HANDLER block can handle more than one error condition, it may
be useful to know which errors occurred. To do so, you can use the GET
DIAGNOSTICS statement.

An error that is handled by a DECLARE HANDLER construct can be issued again
using the RESIGNAL statement.

Below is an example using DECLARE HANDLER:

CREATE TABLE test.t (s1 INT, PRIMARY KEY (s1));

DELIMITER //

CREATE PROCEDURE handlerdemo ( )
  BEGIN
   DECLARE CONTINUE HANDLER FOR SQLSTATE '23000' SET @x2 = 1;
   SET @x = 1;
   INSERT INTO test.t VALUES (1);
   SET @x = 2;
   INSERT INTO test.t VALUES (1);
   SET @x = 3;
  END;
  //

DELIMITER ;

CALL handlerdemo( );

SELECT @x;
+------+
| @x   |
+------+
|    3 |
+------+

URL: https://mariadb.com/kb/en/declare-handler/https://mariadb.com/kb/en/declare-handler//�
FORMariaDB starting with 10.3
--------------------------
FOR loops were introduced in MariaDB 10.3.

Syntax
------

Integer range FOR loop:

[begin_label:]
FOR var_name IN [ REVERSE ] lower_bound .. upper_bound
DO statement_list
END FOR [ end_label ]

Explicit cursor FOR loop

[begin_label:]
FOR record_name IN cursor_name [ ( cursor_actual_parameter_list)]
DO statement_list
END FOR [ end_label ]

Explicit cursor FOR loop (Oracle mode)

[begin_label:]
FOR record_name IN cursor_name [ ( cursor_actual_parameter_list)]
LOOP
 statement_list
END LOOP [ end_label ]

Implicit cursor FOR loop

[begin_label:]
FOR record_name IN ( select_statement )
DO statement_list
END FOR [ end_label ]

Description
-----------

FOR loops allow code to be executed a fixed number of times.

In an integer range FOR loop, MariaDB will compare the lower bound and upper
bound values, and assign the lower bound value to a counter. If REVERSE is not
specified, and the upper bound value is greater than or equal to the counter,
the counter will be incremented and the statement will continue, after which
the loop is entered again. If the upper bound value is greater than the
counter, the loop will be exited.

If REVERSE is specified, the counter is decremented, and the upper bound value
needs to be less than or equal for the loop to continue.

Examples
--------

Intger range FOR loop:

CREATE TABLE t1 (a INT);

DELIMITER //

FOR i IN 1..3
DO
 INSERT INTO t1 VALUES (i);
END FOR;
//

DELIMITER ;

SELECT * FROM t1;
+------+
| a    |
+------+
|    1 |
|    2 |
|    3 |
+------+

REVERSE integer range FOR loop:

CREATE OR REPLACE TABLE t1 (a INT);

DELIMITER //
FOR i IN REVERSE 4..12
  DO
  INSERT INTO t1 VALUES (i);
END FOR;
//
Query OK, 9 rows affected (0.422 sec)

DELIMITER ;

SELECT * FROM t1;
+------+
| a    |
+------+
|   12 |
|   11 |
|   10 |
|    9 |
|    8 |
|    7 |
|    6 |
|    5 |
|    4 |
+------+

Explicit cursor in Oracle mode:

SET sql_mode=ORACLE;

CREATE OR REPLACE TABLE t1 (a INT, b VARCHAR(32));

INSERT INTO t1 VALUES (10,'b0');
INSERT INTO t1 VALUES (11,'b1');
INSERT INTO t1 VALUES (12,'b2');

DELIMITER //

CREATE OR REPLACE PROCEDURE p1(pa INT) AS 
 CURSOR cur(va INT) IS
  SELECT a, b FROM t1 WHERE a=va;
BEGIN
 FOR rec IN cur(pa)
 LOOP
  SELECT rec.a, rec.b;
 END LOOP;
END;
//

DELIMITER ;

CALL p1(10);
+-------+-------+
| rec.a | rec.b |
+-------+-------+
|    10 | b0    |
+-------+-------+

CALL p1(11);
+-------+-------+
| rec.a | rec.b |
+-------+-------+
|    11 | b1    |
+-------+-------+

CALL p1(12);
+-------+-------+
| rec.a | rec.b |
+-------+-------+
|    12 | b2    |
+-------+-------+

CALL p1(13);
Query OK, 0 rows affected (0.000 sec)

URL: https://mariadb.com/kb/en/for/https://mariadb.com/kb/en/for/>�
2�����2�"ITERATESyntax
------

ITERATE label

ITERATE can appear only within LOOP, REPEAT, and WHILE statements. ITERATE
means "do the loop again", and uses the statement's label to determine which
statements to repeat. The label must be in the same stored program, not in a
caller procedure.

If you try to use ITERATE with a non-existing label, or if the label is
associated to a construct which is not a loop, the following error will be
produced:

ERROR 1308 (42000): ITERATE with no matching label: <label_name>

Below is an example of how ITERATE might be used:

CREATE PROCEDURE doiterate(p1 INT)
BEGIN
 label1: LOOP
  SET p1 = p1 + 1;
  IF p1 < 10 THEN ITERATE label1; END IF;
  LEAVE label1;
 END LOOP label1;
 SET @x = p1;
END

URL: https://mariadb.com/kb/en/iterate/https://mariadb.com/kb/en/iterate/3!LabelsSyntax
------

label: <construct>
[label]

Labels are MariaDB identifiers which can be used to identify a BEGIN ... END
construct or a loop. They have a maximum length of 16 characters and can be
quoted with backticks (i.e.., `).

Labels have a start part and an end part. The start part must precede the
portion of code it refers to, must be followed by a colon (:) and can be on
the same or different line. The end part is optional and adds nothing, but can
make the code more readable. If used, the end part must precede the
construct's delimiter (;). Constructs identified by a label can be nested.
Each construct can be identified by only one label.

Labels need not be unique in the stored program they belong to. However, a
label for an inner loop cannot be identical to a label for an outer loop. In
this case, the following error would be produced:

ERROR 1309 (42000): Redefining label <label_name>

LEAVE and ITERATE statements can be used to exit or repeat a portion of code
identified by a label. They must be in the same Stored Routine, Trigger or
Event which contains the target label.

Below is an example using a simple label that is used to exit a LOOP:

CREATE PROCEDURE `test_sp`()
BEGIN
 `my_label`:
 LOOP
   SELECT 'looping';
   LEAVE `my_label`;
 END LOOP;
 SELECT 'out of loop';
END;

The following label is used to exit a procedure, and has an end part:

CREATE PROCEDURE `test_sp`()
`my_label`:
BEGIN
 IF @var = 1 THEN
   LEAVE `my_label`;
 END IF;
 DO something();
END `my_label`;

URL: https://mariadb.com/kb/en/labels/https://mariadb.com/kb/en/labels/4� LEAVESyntax
------

LEAVE label

This statement is used to exit the flow control construct that has the given
label. The label must be in the same stored program, not in a caller
procedure. LEAVE can be used within BEGIN ... END or loop constructs (LOOP,
REPEAT, WHILE). In Stored Procedures, Triggers and Events, LEAVE can refer to
the outmost BEGIN ... END construct; in that case, the program exits the
procedure. In Stored Functions, RETURN can be used instead.

Note that LEAVE cannot be used to exit a DECLARE HANDLER block.

If you try to LEAVE a non-existing label, or if you try to LEAVE a HANDLER
block, the following error will be produced:

ERROR 1308 (42000): LEAVE with no matching label: <label_name>

The following example uses LEAVE to exit the procedure if a condition is true:

CREATE PROCEDURE proc(IN p TINYINT)
CONTAINS SQL
`whole_proc`:
BEGIN
 SELECT 1;
 IF p < 1 THEN
   LEAVE `whole_proc`;
 END IF;
 SELECT 2;
END;

CALL proc(0);
+---+
| 1 |
+---+
| 1 |
+---+

URL: https://mariadb.com/kb/en/leave/https://mariadb.com/kb/en/leave/6?&REPEAT LOOPSyntax
------

[begin_label:] REPEAT
  statement_list
UNTIL search_condition
END REPEAT [end_label]

The statement list within a REPEAT statement is repeated until the
search_condition is true. Thus, a REPEAT always enters the loop at least once.
statement_list consists of one or more statements, each terminated by a
semicolon (i.e., ;) statement delimiter.

A REPEAT statement can be labeled. end_label cannot be given unless
begin_label also is present. If both are present, they must be the same.

See Delimiters in the mariadb client for more on client delimiter usage.

DELIMITER //

CREATE PROCEDURE dorepeat(p1 INT)
 BEGIN
  SET @x = 0;
  REPEAT SET @x = @x + 1; UNTIL @x > p1 END REPEAT;
 END
//

CALL dorepeat(1000)//

SELECT @x//
+------+
| @x   |
+------+
| 1001 |
+------+

URL: https://mariadb.com/kb/en/repeat-loop/https://mariadb.com/kb/en/repeat-loop/9�%SELECT INTOSyntax
------

SELECT col_name [, col_name] ...
  INTO var_name [, var_name] ...
  table_expr

Description
-----------

SELECT ... INTO enables selected columns to be stored directly into variables.
No resultset is produced. The query should return a single row. If the query
returns no rows, a warning with error code 1329 occurs (No data), and the
variable values remain unchanged. If the query returns multiple rows, error
1172 occurs (Result consisted of more than one row). If it is possible that
the statement may retrieve multiple rows, you can use LIMIT 1 to limit the
result set to a single row.

The INTO clause can also be specified at the end of the statement.

In the context of such statements that occur as part of events executed by the
Event Scheduler, diagnostics messages (not only errors, but also warnings) are
written to the error log, and, on Windows, to the application event log.

This statement can be used with both local variables and user-defined
variables.

For the complete syntax, see SELECT.

Another way to set a variable's value is the SET statement.

SELECT ... INTO results are not stored in the query cache even if SQL_CACHE is
specified.

Examples
--------

SELECT id, data INTO @x,@y 
FROM test.t1 LIMIT 1;
SELECT * from t1 where t1.a=@x and t1.b=@y

If you want to use this construct with UNION you have to use the syntax:

SELECT  * INTO @x FROM (SELECT t1.a FROM t1 UNION SELECT t2.a FROM t2);

URL: https://mariadb.com/kb/en/selectinto/https://mariadb.com/kb/en/selectinto/%�'+COLUMN_CHECKSyntax
------

COLUMN_CHECK(dyncol_blob);

Description
-----------

Check if dyncol_blob is a valid packed dynamic columns blob. Return value of 1
means the blob is valid, return value of 0 means it is not.

Rationale: Normally, one works with valid dynamic column blobs. Functions like
COLUMN_CREATE, COLUMN_ADD, COLUMN_DELETE always return valid dynamic column
blobs. However, if a dynamic column blob is accidentally truncated, or
transcoded from one character set to another, it will be corrupted. This
function can be used to check if a value in a blob field is a valid dynamic
column blob.

URL: https://mariadb.com/kb/en/column_check/https://mariadb.com/kb/en/column_check/'
V(+COLUMN_DELETESyntax
------

COLUMN_DELETE(dyncol_blob, column_nr, column_nr...);
COLUMN_DELETE(dyncol_blob, column_name, column_name...);

Description
-----------

Deletes a dynamic column with the specified name. Multiple names can be given.
The return value is a dynamic column blob after the modification.

URL: https://mariadb.com/kb/en/column_delete/https://mariadb.com/kb/en/column_delete/(
7(+COLUMN_EXISTSSyntax
------

COLUMN_EXISTS(dyncol_blob, column_nr);
COLUMN_EXISTS(dyncol_blob, column_name);

Description
-----------

Checks if a column with name column_name exists in dyncol_blob. If yes, return
1, otherwise return 0. See dynamic columns for more information.

URL: https://mariadb.com/kb/en/column_exists/https://mariadb.com/kb/en/column_exists/�z��-�'�
~|	-<@0�*^	��7�#RESIGNALSyntax
------

RESIGNAL [error_condition]
  [SET error_property
  [, error_property] ...]

error_condition:
  SQLSTATE [VALUE] 'sqlstate_value'
 | condition_name

error_property:
  error_property_name = <error_property_value>

error_property_name:
  CLASS_ORIGIN
 | SUBCLASS_ORIGIN
 | MESSAGE_TEXT
 | MYSQL_ERRNO
 | CONSTRAINT_CATALOG
 | CONSTRAINT_SCHEMA
 | CONSTRAINT_NAME
 | CATALOG_NAME
 | SCHEMA_NAME
 | TABLE_NAME
 | COLUMN_NAME
 | CURSOR_NAME

Description
-----------

The syntax of RESIGNAL and its semantics are very similar to SIGNAL. This
statement can only be used within an error HANDLER. It produces an error, like
SIGNAL. RESIGNAL clauses are the same as SIGNAL, except that they all are
optional, even SQLSTATE. All the properties which are not specified in
RESIGNAL, will be identical to the properties of the error that was received
by the error HANDLER. For a description of the clauses, see diagnostics area.

Note that RESIGNAL does not empty the diagnostics area: it just appends
another error condition.

RESIGNAL, without any clauses, produces an error which is identical to the
error that was received by HANDLER.

If used out of a HANDLER construct, RESIGNAL produces the following error:

ERROR 1645 (0K000): RESIGNAL when handler not active

In MariaDB 5.5, if a HANDLER contained a CALL to another procedure, that
procedure could use RESIGNAL. Since MariaDB 10.0, trying to do this raises the
above error.

For a list of SQLSTATE values and MariaDB error codes, see MariaDB Error Codes.

The following procedure tries to query two tables which don't exist, producing
a 1146 error in both cases. Those errors will trigger the HANDLER. The first
time the error will be ignored and the client will not receive it, but the
second time, the error is re-signaled, so the client will receive it.

CREATE PROCEDURE test_error( )
BEGIN
 DECLARE CONTINUE HANDLER
   FOR 1146
 BEGIN
 IF @hide_errors IS FALSE THEN
   RESIGNAL;
 END IF;
 END;
 SET @hide_errors = TRUE;
 SELECT 'Next error will be ignored' AS msg;
 SELECT `c` FROM `temptab_one`;
 SELECT 'Next error won''t be ignored' AS msg;
 SET @hide_errors = FALSE;
 SELECT `c` FROM `temptab_two`;
END;

CALL test_error( );

+----------------------------+
| msg                        |
+----------------------------+
| Next error will be ignored |
+----------------------------+

+-----------------------------+
| msg                         |
+-----------------------------+
| Next error won't be ignored |
+-----------------------------+

ERROR 1146 (42S02): Table 'test.temptab_two' doesn't exist

The following procedure re-signals an error, modifying only the error message
to clarify the cause of the problem.

CREATE PROCEDURE test_error()
BEGIN
 DECLARE CONTINUE HANDLER
 FOR 1146
 BEGIN
   RESIGNAL SET
   MESSAGE_TEXT = '`temptab` does not exist';
 END;
 SELECT `c` FROM `temptab`;
END;

CALL test_error( );
ERROR 1146 (42S02): `temptab` does not exist

As explained above, this works on MariaDB 5.5, but produces a 1645 error since
10.0.

CREATE PROCEDURE handle_error()
BEGIN
 RESIGNAL;
END;
CREATE PROCEDURE p()
BEGIN
 DECLARE EXIT HANDLER FOR SQLEXCEPTION CALL p();
 SIGNAL SQLSTATE '45000';
END;

URL: https://mariadb.com/kb/en/resignal/https://mariadb.com/kb/en/resignal/=U)DECLARE CURSORSyntax
------

<= MariaDB 10.2

DECLARE cursor_name CURSOR FOR select_statement

From MariaDB 10.3

DECLARE cursor_name CURSOR [(cursor_formal_parameter[,...])] FOR
select_statement

cursor_formal_parameter:
  name type [collate clause]

From MariaDB 10.8

DECLARE cursor_name CURSOR [(cursor_formal_parameter[,...])] FOR
select_statement

cursor_formal_parameter:
  [IN] name type [collate clause]

Description
-----------

This statement declares a cursor. Multiple cursors may be declared in a stored
program, but each cursor in a given block must have a unique name.

select_statement is not executed until the OPEN statement is executed. It is
important to remember this if the query produces an error, or calls functions
which have side effects.

A SELECT associated to a cursor can use variables, but the query itself cannot
be a variable, and cannot be dynamically composed. The SELECT statement cannot
have an INTO clause.

Cursors must be declared before HANDLERs, but after local variables and
CONDITIONs.

Parameters
----------

MariaDB starting with 10.3.0
----------------------------
From MariaDB 10.3.0, cursors can have parameters. This is a non-standard SQL
extension. Cursor parameters can appear in any part of the DECLARE CURSOR
select_statement where a stored procedure variable is allowed (select list,
WHERE, HAVING, LIMIT etc).

IN
--

MariaDB starting with 10.8.0
----------------------------
From MariaDB 10.8.0 preview release, the IN qualifier is supported in the
cursor_format_parameter part of the syntax.

See Cursor Overview for an example.

URL: https://mariadb.com/kb/en/declare-cursor/https://mariadb.com/kb/en/declare-cursor/+�&+COLUMN_LISTSyntax
------

COLUMN_LIST(dyncol_blob);

Description
-----------

Returns a comma-separated list of column names. The names are quoted with
backticks.

See dynamic columns for more information.

URL: https://mariadb.com/kb/en/column_list/https://mariadb.com/kb/en/column_list/,�/,WSREP_LAST_SEEN_GTIDMariaDB starting with 10.4.2
----------------------------
WSREP_LAST_SEEN_GTID was added as part of Galera 4 in MariaDB 10.4.2.

Syntax
------

WSREP_LAST_SEEN_GTID()

Description
-----------

Returns the Global Transaction ID of the most recent write transaction
observed by the client.

The result can be useful to determine the transaction to provide to
WSREP_SYNC_WAIT_UPTO_GTID for waiting and unblocking purposes.

URL: https://mariadb.com/kb/en/wsrep_last_seen_gtid/https://mariadb.com/kb/en/wsrep_last_seen_gtid/-_2,WSREP_LAST_WRITTEN_GTIDMariaDB starting with 10.4.2
----------------------------
WSREP_LAST_WRITTEN_GTID was added as part of Galera 4 in MariaDB 10.4.2.

Syntax
------

WSREP_LAST_WRITTEN_GTID()

Description
-----------

Returns the Global Transaction ID of the most recent write transaction
performed by the client.

URL: https://mariadb.com/kb/en/wsrep_last_written_gtid/https://mariadb.com/kb/en/wsrep_last_written_gtid/��@��I
�/Q2-System-Versioned Tables��@I�S�0m$3-Application-Time Periods2�/.ST_AsGeoJSONSyntax
------

ST_AsGeoJSON(g[, max_decimals[, options]])

Description
-----------

Returns the given geometry g as a GeoJSON element. The optional max_decimals
limits the maximum number of decimals displayed.

The optional options flag can be set to 1 to add a bounding box to the output.

Examples
--------

SELECT ST_AsGeoJSON(ST_GeomFromText('POINT(5.3 7.2)'));
+-------------------------------------------------+
| ST_AsGeoJSON(ST_GeomFromText('POINT(5.3 7.2)')) |
+-------------------------------------------------+
| {"type": "Point", "coordinates": [5.3, 7.2]}    |
+-------------------------------------------------+

URL: https://mariadb.com/kb/en/geojson-st_asgeojson/https://mariadb.com/kb/en/geojson-st_asgeojson/5�,0Addition Operator (+)Syntax
------

+

Description
-----------

Addition.

If both operands are integers, the result is calculated with BIGINT precision.
If either integer is unsigned, the result is also an unsigned integer.

For real or string operands, the operand with the highest precision determines
the result precision.

Examples
--------

SELECT 3+5;
+-----+
| 3+5 |
+-----+
|   8 |
+-----+

URL: https://mariadb.com/kb/en/addition-operator/https://mariadb.com/kb/en/addition-operator/�����<�;���*w.������pMariaDB supports temporal data tables in the form of system-versioning tables
(allowing you to query and operate on historic data, discussed below),
application-time periods (allow you to query and operate on a temporal range
of data), and bitemporal tables (which combine both system-versioning and
application-time periods).

System-Versioned Tables
-----------------------

System-versioned tables store the history of all changes, not only data which
is currently valid. This allows data analysis for any point in time, auditing
of changes and comparison of data from different points in time. Typical uses
cases are:

* Forensic analysis & legal requirements to store data for N years.
* Data analytics (retrospective, trends etc.), e.g. to get your staff
information as of one year ago.
* Point-in-time recovery - recover a table state as of particular point in
time.

System-versioned tables were first introduced in the SQL:2011 standard.

Creating a System-Versioned Table
---------------------------------

The CREATE TABLE syntax has been extended to permit creating a
system-versioned table. To be system-versioned, according to SQL:2011, a table
must have two generated columns, a period, and a special table option clause:

CREATE TABLE t(
 x INT,
 start_timestamp TIMESTAMP(6) GENERATED ALWAYS AS ROW START,
 end_timestamp TIMESTAMP(6) GENERATED ALWAYS AS ROW END,
 PERIOD FOR SYSTEM_TIME(start_timestamp, end_timestamp)
) WITH SYSTEM VERSIONING;

In MariaDB one can also use a simplified syntax:

CREATE TABLE t (
 x INT
) WITH SYSTEM VERSIONING;

In the latter case no extra columns will be created and they won't clutter the
output of, say, SELECT * FROM t. The versioning information will still be
stored, and it can be accessed via the pseudo-columns ROW_START and ROW_END:

SELECT x, ROW_START, ROW_END FROM t;

Adding or Removing System Versioning To/From a Table
----------------------------------------------------

An existing table can be altered to enable system versioning for it.

CREATE TABLE t(
 x INT
);

ALTER TABLE t ADD SYSTEM VERSIONING;

SHOW CREATE TABLE t\G
*************************** 1. row ***************************
   Table: t
Create Table: CREATE TABLE `t` (
 `x` int(11) DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=latin1 WITH SYSTEM VERSIONING

Similarly, system versioning can be removed from a table:

ALTER TABLE t DROP SYSTEM VERSIONING;

SHOW CREATE TABLE t\G
*************************** 1. row ***************************
   Table: t
Create Table: CREATE TABLE `t` (
 `x` int(11) DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=latin1

One can also add system versioning with all columns created explicitly:

ALTER TABLE t ADD COLUMN ts TIMESTAMP(6) GENERATED ALWAYS AS ROW START,
       ADD COLUMN te TIMESTAMP(6) GENERATED ALWAYS AS ROW END,
       ADD PERIOD FOR SYSTEM_TIME(ts, te),
       ADD SYSTEM VERSIONING;

SHOW CREATE TABLE t\G
*************************** 1. row ***************************
   Table: t
Create Table: CREATE TABLE `t` (
 `x` int(11) DEFAULT NULL,
 `ts` timestamp(6) GENERATED ALWAYS AS ROW START,
 `te` timestamp(6) GENERATED ALWAYS AS ROW END,
 PERIOD FOR SYSTEM_TIME (`ts`, `te`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1 WITH SYSTEM VERSIONING

Inserting Data
--------------

When data is inserted into a system-versioned table, it is given a row_start
value of the current timestamp, and a row_end value of
FROM_UNIXTIME(2147483647.999999). The current timestamp can be adjusted by
setting the timestamp system variable, for example:

SELECT NOW();
+---------------------+
| NOW()               |
+---------------------+
| 2022-10-24 23:09:38 |
+---------------------+

INSERT INTO t VALUES(1);

SET @@timestamp = UNIX_TIMESTAMP('2033-10-24');

INSERT INTO t VALUES(2);

SET @@timestamp = default;

INSERT INTO t VALUES(3);

SELECT a,row_start,row_end FROM t;
+------+----------------------------+----------------------------+
| a    | row_start                  | row_end                    |
+------+----------------------------+----------------------------+
|    1 | 2022-10-24 23:09:38.951347 | 2038-01-19 05:14:07.999999 |
|    2 | 2033-10-24 00:00:00.000000 | 2038-01-19 05:14:07.999999 |
|    3 | 2022-10-24 23:09:38.961857 | 2038-01-19 05:14:07.999999 |
+------+----------------------------+----------------------------+

Querying Historical Data
------------------------

SELECT
------

To query the historical data one uses the clause FOR SYSTEM_TIME directly
after the table name (before the table alias, if any). SQL:2011 provides three
syntactic extensions:

* AS OF is used to see the table as it was at a specific point in time in the
past:

SELECT * FROM t FOR SYSTEM_TIME AS OF TIMESTAMP'2016-10-09 08:07:06';

* BETWEEN start AND end will show all rows that were visible at any point
between two specified points in time. It works inclusively, a row visible
exactly at start or exactly at end will be shown too.

SELECT * FROM t FOR SYSTEM_TIME BETWEEN (NOW() - INTERVAL 1 YEAR) AND NOW();

* FROM start TO end will also show all rows that were visible at any point
between two specified points in time, including start, but excluding end.

SELECT * FROM t FOR SYSTEM_TIME FROM '2016-01-01 00:00:00' TO '2017-01-01
00:00:00';

Additionally MariaDB implements a non-standard extension:

* ALL will show all rows, historical and current.

SELECT * FROM t FOR SYSTEM_TIME ALL;

If the FOR SYSTEM_TIME clause is not used, the table will show the current
data. This is usually the same as if one had specified FOR SYSTEM_TIME AS OF
CURRENT_TIMESTAMP, unless one has adjusted the row_start value (until MariaDB
10.11, only possible by setting the secure_timestamp variable). For example:

CREATE OR REPLACE TABLE t (a int) WITH SYSTEM VERSIONING;

SELECT NOW();
+---------------------+
| NOW()               |
+---------------------+
| 2022-10-24 23:43:37 |
+---------------------+

INSERT INTO t VALUES (1);

SET @@timestamp = UNIX_TIMESTAMP('2033-03-03');

INSERT INTO t VALUES (2);

DELETE FROM t;

SET @@timestamp = default;

SELECT a, row_start, row_end FROM t FOR SYSTEM_TIME ALL;
+------+----------------------------+----------------------------+
| a    | row_start                  | row_end                    |
+------+----------------------------+----------------------------+
|    1 | 2022-10-24 23:43:37.192725 | 2033-03-03 00:00:00.000000 |
|    2 | 2033-03-03 00:00:00.000000 | 2033-03-03 00:00:00.000000 |
+------+----------------------------+----------------------------+
2 rows in set (0.000 sec)

SELECT a, row_start, row_end FROM t FOR SYSTEM_TIME AS OF CURRENT_TIMESTAMP;
+------+----------------------------+----------------------------+
| a    | row_start                  | row_end                    |
+------+----------------------------+----------------------------+
|    1 | 2022-10-24 23:43:37.192725 | 2033-03-03 00:00:00.000000 |
+------+----------------------------+----------------------------+
1 row in set (0.000 sec)

SELECT a, row_start, row_end FROM t;
Empty set (0.001 sec)

Views and Subqueries
--------------------

When a system-versioned tables is used in a view or in a subquery in the from
clause, FOR SYSTEM_TIME can be used directly in the view or subquery body, or
(non-standard) applied to the whole view when it's being used in a SELECT:

CREATE VIEW v1 AS SELECT * FROM t FOR SYSTEM_TIME AS OF TIMESTAMP'2016-10-09
08:07:06';

Or

CREATE VIEW v1 AS SELECT * FROM t;
SELECT * FROM v1 FOR SYSTEM_TIME AS OF TIMESTAMP'2016-10-09 08:07:06';

Use in Replication and Binary Logs
----------------------------------

Tables that use system-versioning implicitly add the row_end column to the
Primary Key. While this is generally not an issue for most use cases, it can
lead to problems when re-applying write statements from the binary log or in
replication environments, where a primary retries an SQL statement on the
replica.

Specifically, these writes include a value on the row_end column containing
the timestamp from when the write was initially made. The re-occurrence of the
Primary Key with the old system-versioning columns raises an error due to the
duplication.

To mitigate this with MariaDB Replication, set the secure_timestamp17[ system
variable to YES on the replica. When set, the replica uses its own system
clock when applying to the row log, meaning that the primary can retry as many
times as needed without causing a conflict. The retries generate new
historical rows with new values for the row_start and row_end columns.

Transaction-Precise History in InnoDB
-------------------------------------

A point in time when a row was inserted or deleted does not necessarily mean
that a change became visible at the same moment. With transactional tables, a
row might have been inserted in a long transaction, and became visible hours
after it was inserted.

For some applications — for example, when doing data analytics on one-year-old
data — this distinction does not matter much. For others — forensic analysis —
it might be crucial.

MariaDB supports transaction-precise history (only for the InnoDB storage
engine) that allows seeing the data exactly as it would've been seen by a new
connection doing a SELECT at the specified point in time — rows inserted
before that point, but committed after will not be shown.

To use transaction-precise history, InnoDB needs to remember not timestamps,
but transaction identifier per row. This is done by creating generated columns
as BIGINT UNSIGNED, not TIMESTAMP(6):

CREATE TABLE t(
 x INT,
 start_trxid BIGINT UNSIGNED GENERATED ALWAYS AS ROW START,
 end_trxid BIGINT UNSIGNED GENERATED ALWAYS AS ROW END,
 PERIOD FOR SYSTEM_TIME(start_trxid, end_trxid)
) WITH SYSTEM VERSIONING;

These columns must be specified explicitly, but they can be made INVISIBLE to
avoid cluttering SELECT * output.

When one uses transaction-precise history, one can optionally use transaction
identifiers in the FOR SYSTEM_TIME clause:

SELECT * FROM t FOR SYSTEM_TIME AS OF TRANSACTION 12345;

This will show the data, exactly as it was seen by the transaction with the
identifier 12345.

Storing the History Separately
------------------------------

When the history is stored together with the current data, it increases the
size of the table, so current data queries — table scans and index searches —
will take more time, because they will need to skip over historical data. If
most queries on that table use only current data, it might make sense to store
the history separately, to reduce the overhead from versioning.

This is done by partitioning the table by SYSTEM_TIME. Because of the
partition pruning optimization, all current data queries will only access one
partition, the one that stores current data.

This example shows how to create such a partitioned table:

CREATE TABLE t (x INT) WITH SYSTEM VERSIONING
 PARTITION BY SYSTEM_TIME (
  PARTITION p_hist HISTORY,
  PARTITION p_cur CURRENT
 );

In this example all history will be stored in the partition p_hist while all
current data will be in the partition p_cur. The table must have exactly one
current partition and at least one historical partition.

Partitioning by SYSTEM_TIME also supports automatic partition rotation. One
can rotate historical partitions by time or by size. This example shows how to
rotate partitions by size:

CREATE TABLE t (x INT) WITH SYSTEM VERSIONING
 PARTITION BY SYSTEM_TIME LIMIT 100000 (
  PARTITION p0 HISTORY,
  PARTITION p1 HISTORY,
  PARTITION pcur CURRENT
 );

MariaDB will start writing history rows into partition p0, and when it reaches
a size of 100000 rows, MariaDB will switch to partition p1. There are only two
historical partitions, so when p1 overflows, MariaDB will issue a warning, but
will continue writing into it.

Similarly, one can rotate partitions by time:

CREATE TABLE t (x INT) WITH SYSTEM VERSIONING
 PARTITION BY SYSTEM_TIME INTERVAL 1 WEEK (
  PARTITION p0 HISTORY,
  PARTITION p1 HISTORY,
  PARTITION p2 HISTORY,
  PARTITION pcur CURRENT
 );

This means that the history for the first week after the table was created
will be stored in p0. The history for the second week — in p1, and all later
history will go into p2. One can see the exact rotation time for each
partition in the INFORMATION_SCHEMA.PARTITIONS table.

It is possible to combine partitioning by SYSTEM_TIME and subpartitions:

CREATE TABLE t (x INT) WITH SYSTEM VERSIONING
 PARTITION BY SYSTEM_TIME
  SUBPARTITION BY KEY (x)
  SUBPARTITIONS 4 (
  PARTITION ph HISTORY,
  PARTITION pc CURRENT
 );

Default Partitions
------------------

MariaDB starting with 10.5.0
----------------------------
Since partitioning by current and historical data is such a typical usecase,
from MariaDB 10.5, it is possible to use a simplified statement to do so. For
example, instead of

CREATE TABLE t (x INT) WITH SYSTEM VERSIONING 
 PARTITION BY SYSTEM_TIME (
  PARTITION p0 HISTORY,
  PARTITION pn CURRENT
);

you can use

CREATE TABLE t (x INT) WITH SYSTEM VERSIONING 
 PARTITION BY SYSTEM_TIME;

You can also specify the number of partitions, which is useful if you want to
rotate history by time, for example:

CREATE TABLE t (x INT) WITH SYSTEM VERSIONING 
 PARTITION BY SYSTEM_TIME
  INTERVAL 1 MONTH
  PARTITIONS 12;

Specifying the number of partitions without specifying a rotation condition
will result in a warning:

CREATE OR REPLACE TABLE t (x INT) WITH SYSTEM VERSIONING
 PARTITION BY SYSTEM_TIME PARTITIONS 12;
Query OK, 0 rows affected, 1 warning (0.518 sec)

Warning (Code 4115): Maybe missing parameters: no rotation condition for
multiple HISTORY partitions.

while specifying only 1 partition will result in an error:

CREATE OR REPLACE TABLE t (x INT) WITH SYSTEM VERSIONING
 PARTITION BY SYSTEM_TIME PARTITIONS 1;
ERROR 4128 (HY000): Wrong partitions for `t`: must have at least one HISTORY
and exactly one last CURRENT

Automatically Creating Partitions
---------------------------------

MariaDB starting with 10.9.1
----------------------------
From MariaDB 10.9.1, the AUTO keyword can be used to automatically create
history partitions.

For example

CREATE TABLE t1 (x int) WITH SYSTEM VERSIONING
  PARTITION BY SYSTEM_TIME INTERVAL 1 HOUR AUTO;

CREATE TABLE t1 (x int) WITH SYSTEM VERSIONING
 PARTITION BY SYSTEM_TIME INTERVAL 1 MONTH
 STARTS '2021-01-01 00:00:00' AUTO PARTITIONS 12;

CREATE TABLE t1 (x int) WITH SYSTEM VERSIONING
 PARTITION BY SYSTEM_TIME LIMIT 1000 AUTO;

Or with explicit partitions:

CREATE TABLE t1 (x int) WITH SYSTEM VERSIONING
 PARTITION BY SYSTEM_TIME INTERVAL 1 HOUR AUTO
 (PARTITION p0 HISTORY, PARTITION pn CURRENT);

To disable or enable auto-creation one can use ALTER TABLE by adding or
removing AUTO from the partitioning specification:

CREATE TABLE t1 (x int) WITH SYSTEM VERSIONING
 PARTITION BY SYSTEM_TIME INTERVAL 1 HOUR AUTO;

# Disables auto-creation:
ALTER TABLE t1 PARTITION BY SYSTEM_TIME INTERVAL 1 HOUR;

# Enables auto-creation:
ALTER TABLE t1 PARTITION BY SYSTEM_TIME INTERVAL 1 HOUR AUTO;

If the rest of the partitioning specification is identical to CREATE TABLE, no
repartitioning will be done (for details see MDEV-27328).

Removing Old History
--------------------

Because it stores all the history, a system-versioned table might grow very
large over time. There are many options to trim down the space and remove the
old history.

One can completely drop the versioning from the table and add it back again,
this will delete all the history:

ALTER TABLE t DROP SYSTEM VERSIONING;
ALTER TABLE t ADD SYSTEM VERSIONING;

It might be a rather time-consuming operation, though, as the table will need
to be rebuilt, possibly twice (depending on the storage engine).

Another option would be to use partitioning and drop some of historical
partitions:

ALTER TABLE t DROP PARTITION p0;

Note, that one cannot drop a current partition or the only historical
partition.

And the third option; one can use a variant of the DELETE statement to prune
the history:

DELETE HISTORY FROM t;

or only old history up to a specific point in time:

DELETE HISTORY FROM t BEFORE SYSTEM_TIME '2016-10-09 08:07:06';

or to a specific transaction (with BEFORE SYSTEM_TIME TRANSACTION xxx).

To protect the integrity of the history, this statement requires a special
DELETE HISTORY privilege.

Currently, using the DELETE HISTORY statement with a BEFORE SYSTEM_TIME
greater than the ROW_END of the �:M��active records (as a TIMESTAMP, this has a
maximum value of '2038-01-19 03:14:07' UTC) will result in the historical
records being dropped, and the active records being deleted and moved to
history. See MDEV-25468.

Prior to MariaDB 10.4.5, the TRUNCATE TABLE statement drops all historical
records from a system-versioned-table.

From MariaDB 10.4.5, historic data is protected from TRUNCATE statements, as
per the SQL standard, and an Error 4137 is instead raised:

TRUNCATE t;
ERROR 4137 (HY000): System-versioned tables do not support TRUNCATE TABLE

Excluding Columns From Versioning
---------------------------------

Another MariaDB extension allows to version only a subset of columns in a
table. This is useful, for example, if you have a table with user information
that should be versioned, but one column is, let's say, a login counter that
is incremented often and is not interesting to version. Such a column can be
excluded from versioning by declaring it WITHOUT VERSIONING

CREATE TABLE t (
 x INT,
 y INT WITHOUT SYSTEM VERSIONING
) WITH SYSTEM VERSIONING;

A column can also be declared WITH VERSIONING, that will automatically make
the table versioned. The statement below is equivalent to the one above:

CREATE TABLE t (
 x INT WITH SYSTEM VERSIONING,
 y INT
);

Changes in other sections: https://mariadb.com/kb/en/create-table/
https://mariadb.com/kb/en/alter-table/ https://mariadb.com/kb/en/join-syntax/
https://mariadb.com/kb/en/partitioning-types-overview/
https://mariadb.com/kb/en/date-and-time-units/
https://mariadb.com/kb/en/delete/ https://mariadb.com/kb/en/grant/

they all reference back to this page

Also, TODO:

* limitations (size, speed, adding history to unique not nullable columns)

System Variables
----------------

There are a number of system variables related to system-versioned tables:

system_versioning_alter_history
-------------------------------

* Description: SQL:2011 does not allow ALTER TABLE on system-versioned tables.
When this variable is set to ERROR, an attempt to alter a system-versioned
table will result in an error. When this variable is set to KEEP, ALTER TABLE
will be allowed, but the history will become incorrect — querying historical
data will show the new table structure. This mode is still useful, for
example, when adding new columns to a table. Note that if historical data
contains or would contain nulls, attempting to ALTER these columns to be NOT
NULL will return an error (or warning if strict_mode is not set).
* Commandline: --system-versioning-alter-history=value
* Scope: Global, Session
* Dynamic: Yes
* Type: Enum
* Default Value: ERROR
* Valid Values: ERROR, KEEP

system_versioning_asof
----------------------

* Description: If set to a specific timestamp value, an implicit FOR
SYSTEM_TIME AS OF clause will be applied to all queries. This is useful if one
wants to do many queries for history at the specific point in time. Set it to
DEFAULT to restore the default behavior. Has no effect on DML, so queries such
as INSERT .. SELECT and REPLACE .. SELECT need to state AS OF explicitly.
* Commandline: None
* Scope: Global, Session
* Dynamic: Yes
* Type: Varchar
* Default Value: DEFAULT

system_versioning_innodb_algorithm_simple
-----------------------------------------

* Description: Never fully implemented and removed in the following release.
* Commandline: --system-versioning-innodb-algorithm-simple[={0|1}]
* Scope: Global, Session
* Dynamic: Yes
* Type: Boolean
* Default Value: ON
* Introduced: MariaDB 10.3.4
* Removed: MariaDB 10.3.5

system_versioning_insert_history
--------------------------------

* Description: Allows direct inserts into ROW_START and ROW_END columns if
secure_timestamp allows changing timestamp.
* Commandline: --system-versioning-insert-history[={0|1}]
* Scope: Global, Session
* Dynamic: Yes
* Type: Boolean
* Default Value: OFF
* Introduced: MariaDB 10.11.0

Limitations
-----------

* Versioning clauses can not be applied to generated (virtual and persistent)
columns.
* Before MariaDB 10.11, mariadb-dump did not read historical rows from
versioned tables, and so historical data would not be backed up. Also, a
restore of the timestamps would not be possible as they cannot be defined by
an insert/a user. From MariaDB 10.11, use the -H or --dump-history options to
include the history.

URL: https://mariadb.com/kb/en/system-versioned-tables/''z:bMariaDB starting with 10.4.3
----------------------------
Support for application-time period-versioning was added in MariaDB 10.4.3.

Extending system-versioned tables, MariaDB 10.4 supports application-time
period tables. Time periods are defined by a range between two temporal
columns. The columns must be of the same temporal data type, i.e. DATE,
TIMESTAMP or DATETIME (TIME and YEAR are not supported), and of the same width.

Using time periods implicitly defines the two columns as NOT NULL. It also
adds a constraint to check whether the first value is less than the second
value. The constraint is invisible to SHOW CREATE TABLE statements. The name
of this constraint is prefixed by the time period name, to avoid conflict with
other constraints.

Creating Tables with Time Periods
---------------------------------

To create a table with a time period, use a CREATE TABLE statement with the
PERIOD table option.

CREATE TABLE t1(
 name VARCHAR(50),
 date_1 DATE,
 date_2 DATE,
 PERIOD FOR date_period(date_1, date_2));

This creates a table with a time_period period and populates the table with
some basic temporal values.

Examples are available in the MariaDB Server source code, at
mysql-test/suite/period/r/create.result.

Adding and Removing Time Periods
--------------------------------

The ALTER TABLE statement now supports syntax for adding and removing time
periods from a table. To add a period, use the ADD PERIOD clause.

For example:

CREATE OR REPLACE TABLE rooms (
 room_number INT,
 guest_name VARCHAR(255),
 checkin DATE,
 checkout DATE
 );

ALTER TABLE rooms ADD PERIOD FOR p(checkin,checkout);

To remove a period, use the DROP PERIOD clause:

ALTER TABLE rooms DROP PERIOD FOR p;

Both ADD PERIOD and DROP PERIOD clauses include an option to handle whether
the period already exists:

ALTER TABLE rooms ADD PERIOD IF NOT EXISTS FOR p(checkin,checkout);

ALTER TABLE rooms DROP PERIOD IF EXISTS FOR p;

Deletion by Portion
-------------------

You can also remove rows that fall within certain time periods.

When MariaDB executes a DELETE FOR PORTION statement, it removes the row:

* When the row period falls completely within the delete period, it removes
the row.
* When the row period overlaps the delete period, it shrinks the row, removing
the overlap from the first or second row period value.
* When the delete period falls completely within the row period, it splits the
row into two rows.  The first row runs from the starting row period to the
starting delete period.  The second runs from the ending delete period to the
ending row period.

To test this, first populate the table with some data to operate on:

CREATE TABLE t1(
 name VARCHAR(50),
 date_1 DATE,
 date_2 DATE,
 PERIOD FOR date_period(date_1, date_2));

INSERT INTO t1 (name, date_1, date_2) VALUES
  ('a', '1999-01-01', '2000-01-01'),
  ('b', '1999-01-01', '2018-12-12'),
  ('c', '1999-01-01', '2017-01-01'),
  ('d', '2017-01-01', '2019-01-01');

SELECT * FROM t1;
+------+------------+------------+
| name | date_1     | date_2     |
+------+------------+------------+
| a    | 1999-01-01 | 2000-01-01 |
| b    | 1999-01-01 | 2018-12-12 |
| c    | 1999-01-01 | 2017-01-01 |
| d    | 2017-01-01 | 2019-01-01 |
+------+------------+------------+

Then, run the DELETE FOR PORTION statement:

DELETE FROM t1
FOR PORTION OF date_period
  FROM '2001-01-01' TO '2018-01-01';
Query OK, 3 rows affected (0.028 sec)

SELECT * FROM t1 ORDER BY name;
+------+------------+------------+
| name | date_1     | date_2     |
+------+------------+------------+
| a    | 1999-01-01 | 2000-01-01 |
| b    | 1999-01-01 | 2001-01-01 |
| b    | 2018-01-01 | 2018-12-12 |
| c    | 1999-01-01 | 2001-01-01 |
| d    | 2018-01-01 | 2019-01-01 |
+------+------------+------------+

Here:

* a is unchanged, as the range falls entirely out of the specified portion to
be deleted.
* b, with values ranging from 1999 to 2018, is split into two rows, 1999 to
2000 and 2018-01 to 2018-12.
* c, with values ranging from 1999 to 2017, where only the upper value falls
within the portion to be deleted, has been shrunk to 1999 to 2001.
* d, with values ranging from 2017 to 2019, where only the lower value falls
within the portion to be deleted, has been shrunk to 2018 to 2019.

The DELETE FOR PORTION statement has the following restrictions

* The FROM...TO clause must be constant
* Multi-delete is not supported

If there are DELETE or INSERT triggers, it works as follows: any matched row
is deleted, and then one or two rows are inserted. If the record is deleted
completely, nothing is inserted.

Updating by Portion
-------------------

The UPDATE syntax now supports UPDATE FOR PORTION, which modifies rows based
on their occurrence in a range:

To test it, first populate the table with some data:

TRUNCATE t1;

INSERT INTO t1 (name, date_1, date_2) VALUES
  ('a', '1999-01-01', '2000-01-01'),
  ('b', '1999-01-01', '2018-12-12'),
  ('c', '1999-01-01', '2017-01-01'),
  ('d', '2017-01-01', '2019-01-01');

SELECT * FROM t1;
+------+------------+------------+
| name | date_1     | date_2     |
+------+------------+------------+
| a    | 1999-01-01 | 2000-01-01 |
| b    | 1999-01-01 | 2018-12-12 |
| c    | 1999-01-01 | 2017-01-01 |
| d    | 2017-01-01 | 2019-01-01 |
+------+------------+------------+

Then run the update:

UPDATE t1 FOR PORTION OF date_period
 FROM '2000-01-01' TO '2018-01-01'
SET name = CONCAT(name,'_original');

SELECT * FROM t1 ORDER BY name;
+------------+------------+------------+
| name       | date_1     | date_2     |
+------------+------------+------------+
| a          | 1999-01-01 | 2000-01-01 |
| b          | 1999-01-01 | 2000-01-01 |
| b          | 2018-01-01 | 2018-12-12 |
| b_original | 2000-01-01 | 2018-01-01 |
| c          | 1999-01-01 | 2000-01-01 |
| c_original | 2000-01-01 | 2017-01-01 |
| d          | 2018-01-01 | 2019-01-01 |
| d_original | 2017-01-01 | 2018-01-01 |
+------------+------------+------------+

* a is unchanged, as the range falls entirely out of the specified portion to
be deleted.
* b, with values ranging from 1999 to 2018, is split into two rows, 1999 to
2000 and 2018-01 to 2018-12.
* c, with values ranging from 1999 to 2017, where only the upper value falls
within the portion to be deleted, has been shrunk to 1999 to 2001.
* d, with values ranging from 2017 to 2019, where only the lower value falls
within the portion to be deleted, has been shrunk to 2018 to 2019. 
* Original rows affected by the update have "_original" appended to the name.

The UPDATE FOR PORTION statement has the following limitations:

* The operation cannot modify the two temporal columns used by the time period
* The operation cannot reference period values in the SET expression
* FROM...TO expressions must be constant

WITHOUT OVERLAPS
----------------

MariaDB starting with 10.5.3
----------------------------
MariaDB 10.5 introduced a new clause, WITHOUT OVERLAPS, which allows one to
create an index specifying that application time periods should not overlap.

An index constrained by WITHOUT OVERLAPS is required to be either a primary
key or a unique index.

Take the following example, an application time period table for a booking
system:

CREATE OR REPLACE TABLE rooms (
 room_number INT,
 guest_name VARCHAR(255),
 checkin DATE,
 checkout DATE,
 PERIOD FOR p(checkin,checkout)
 );

INSERT INTO rooms VALUES 
 (1, 'Regina', '2020-10-01', '2020-10-03'),
 (2, 'Cochise', '2020-10-02', '2020-10-05'),
 (1, 'Nowell', '2020-10-03', '2020-10-07'),
 (2, 'Eusebius', '2020-10-04', '2020-10-06');

Our system is not intended to permit overlapping bookings, so the fourth
record above should not have been inserted. Using WITHOUT OVERLAPS in a unique
index (in this case based on a combination of room number and the application
time period) allows us to specify this constraint in the table definition.

CREATE OR REPLACE TABLE rooms (
 room_number INT,
 guest_name VARCHAR(255),
 checkin DATE,
 checkout DATE,
 PERIOD FOR p(checkin,checkout),
 UNIQUE (room_number, p WITHOUT OVERLAPS)
 );

INSERT INTO rooms VALUES 
 (1, 'Regina', '2020-10-01', '2020-10-03'),
 (2, 'Cochise', '2020-10-02', '2020-10-05'),
 (1, 'Nowell', '�+Hs�w:�!SIGNALSyntax
------

SIGNAL error_condition
  [SET error_property
  [, error_property] ...]

error_condition:
  SQLSTATE [VALUE] 'sqlstate_value'
 | condition_name

error_property:
  error_property_name = <error_property_value>

error_property_name:
  CLASS_ORIGIN
 | SUBCLASS_ORIGIN
 | MESSAGE_TEXT
 | MYSQL_ERRNO
 | CONSTRAINT_CATALOG
 | CONSTRAINT_SCHEMA
 | CONSTRAINT_NAME
 | CATALOG_NAME
 | SCHEMA_NAME
 | TABLE_NAME
 | COLUMN_NAME
 | CURSOR_NAME

SIGNAL empties the diagnostics area and produces a custom error. This
statement can be used anywhere, but is generally useful when used inside a
stored program. When the error is produced, it can be caught by a HANDLER. If
not, the current stored program, or the current statement, will terminate with
the specified error.

Sometimes an error HANDLER just needs to SIGNAL the same error it received,
optionally with some changes. Usually the RESIGNAL statement is the most
convenient way to do this.

error_condition can be an SQLSTATE value or a named error condition defined
via DECLARE CONDITION. SQLSTATE must be a constant string consisting of five
characters. These codes are standard to ODBC and ANSI SQL. For customized
errors, the recommended SQLSTATE is '45000'. For a list of SQLSTATE values
used by MariaDB, see the MariaDB Error Codes page. The SQLSTATE can be read
via the API method mysql_sqlstate( ).

To specify error properties user-defined variables and local variables can be
used, as well as character set conversions (but you can't set a collation).

The error properties, their type and their default values are explained in the
diagnostics area page.

Errors
------

If the SQLSTATE is not valid, the following error like this will be produced:

ERROR 1407 (42000): Bad SQLSTATE: '123456'

If a property is specified more than once, an error like this will be produced:

ERROR 1641 (42000): Duplicate condition information item 'MESSAGE_TEXT'

If you specify a condition name which is not declared, an error like this will
be produced:

ERROR 1319 (42000): Undefined CONDITION: cond_name

If MYSQL_ERRNO is out of range, you will get an error like this:

ERROR 1231 (42000): Variable 'MYSQL_ERRNO' can't be set to the value of '0'

Examples
--------

Here's what happens if SIGNAL is used in the client to generate errors:

SIGNAL SQLSTATE '01000';
Query OK, 0 rows affected, 1 warning (0.00 sec)

SHOW WARNINGS;

+---------+------+------------------------------------------+
| Level   | Code | Message                                  |
+---------+------+------------------------------------------+
| Warning | 1642 | Unhandled user-defined warning condition |
+---------+------+------------------------------------------+
1 row in set (0.06 sec)

SIGNAL SQLSTATE '02000';
ERROR 1643 (02000): Unhandled user-defined not found condition

How to specify MYSQL_ERRNO and MESSAGE_TEXT properties:

SIGNAL SQLSTATE '45000' SET MYSQL_ERRNO=30001, MESSAGE_TEXT='H
ello, world!';

ERROR 30001 (45000): Hello, world!

The following code shows how to use user variables, local variables and
character set conversion with SIGNAL:

CREATE PROCEDURE test_error(x INT)
BEGIN
 DECLARE errno SMALLINT UNSIGNED DEFAULT 31001;
 SET @errmsg = 'Hello, world!';
 IF x = 1 THEN
   SIGNAL SQLSTATE '45000' SET
   MYSQL_ERRNO = errno,
   MESSAGE_TEXT = @errmsg;
 ELSE
   SIGNAL SQLSTATE '45000' SET
   MYSQL_ERRNO = errno,
   MESSAGE_TEXT = _utf8'Hello, world!';
 END IF;
END;

How to use named error conditions:

CREATE PROCEDURE test_error(n INT)
BEGIN
 DECLARE `too_big` CONDITION FOR SQLSTATE '45000';
 IF n > 10 THEN
   SIGNAL `too_big`;
 END IF;
END;

In this example, we'll define a HANDLER for an error code. When the error
occurs, we SIGNAL a more informative error which makes sense for our procedure:

CREATE PROCEDURE test_error()
BEGIN
 DECLARE EXIT HANDLER
 FOR 1146
 BEGIN
   SIGNAL SQLSTATE '45000' SET
   MESSAGE_TEXT = 'Temporary tables not found; did you call init()
procedure?';
 END;
 -- this will produce a 1146 error
 SELECT `c` FROM `temptab`;
END;

URL: https://mariadb.com/kb/en/signal/https://mariadb.com/kb/en/signal/D
m%LINESTRINGSyntax
------

LineString(pt1,pt2,...)

Description
-----------

Constructs a WKB LineString value from a number of WKB Point arguments. If any
argument is not a WKB Point, the return value is NULL. If the number of Point
arguments is less than two, the return value is NULL.

Examples
--------

SET @ls = 'LineString(1 1,2 2,3 3)';

SELECT AsText(EndPoint(GeomFromText(@ls)));
+-------------------------------------+
| AsText(EndPoint(GeomFromText(@ls))) |
+-------------------------------------+
| POINT(3 3)                          |
+-------------------------------------+

CREATE TABLE gis_line  (g LINESTRING);
INSERT INTO gis_line VALUES
  (LineFromText('LINESTRING(0 0,0 10,10 0)')),
  (LineStringFromText('LINESTRING(10 10,20 10,20 20,10 20,10 10)')),
  (LineStringFromWKB(AsWKB(LineString(Point(10, 10), Point(40, 10)))));

URL: https://mariadb.com/kb/en/linestring/https://mariadb.com/kb/en/linestring/7*0Modulo Operator (%)Syntax
------

N % M

Description
-----------

Modulo operator. Returns the remainder of N divided by M. See also MOD.

Examples
--------

SELECT 1042 % 50;
+-----------+
| 1042 % 50 |
+-----------+
|        42 |
+-----------+

URL: https://mariadb.com/kb/en/modulo-operator/https://mariadb.com/kb/en/modulo-operator/��@��S�:�p+1CHANGE MASTER TO>�'1RESET MASTERRESET MASTER [TO #]

Deletes all binary log files listed in the index file, resets the binary log
index file to be empty, and creates a new binary log file with a suffix of
.000001.

If TO # is given, then the first new binary log file will start from number #.

This statement is for use only when the master is started for the first time,
and should never be used if any slaves are actively replicating from the
binary log.

URL: https://mariadb.com/kb/en/reset-master/https://mariadb.com/kb/en/reset-master/Y%4�^��@��The terms master and slave have historically been used in replication, but the
terms terms primary and replica are now preferred. The old terms are used
still used in parts of the documentation, and in MariaDB commands, although
MariaDB 10.5 has begun the process of renaming. The documentation process is
ongoing. See MDEV-18777 to follow progress on this effort.

Syntax
------

CHANGE MASTER ['connection_name'] TO master_def  [, master_def] ... 
 [FOR CHANNEL 'channel_name']

master_def:
  MASTER_BIND = 'interface_name'
 | MASTER_HOST = 'host_name'
 | MASTER_USER = 'user_name'
 | MASTER_PASSWORD = 'password'
 | MASTER_PORT = port_num
 | MASTER_CONNECT_RETRY = interval
 | MASTER_HEARTBEAT_PERIOD = interval
 | MASTER_LOG_FILE = 'master_log_name'
 | MASTER_LOG_POS = master_log_pos
 | RELAY_LOG_FILE = 'relay_log_name'
 | RELAY_LOG_POS = relay_log_pos
 | MASTER_DELAY = interval
 | MASTER_SSL = {0|1}
 | MASTER_SSL_CA = 'ca_file_name'
 | MASTER_SSL_CAPATH = 'ca_directory_name'
 | MASTER_SSL_CERT = 'cert_file_name'
 | MASTER_SSL_CRL = 'crl_file_name'
 | MASTER_SSL_CRLPATH = 'crl_directory_name'
 | MASTER_SSL_KEY = 'key_file_name'
 | MASTER_SSL_CIPHER = 'cipher_list'
 | MASTER_SSL_VERIFY_SERVER_CERT = {0|1}
 | MASTER_USE_GTID = {current_pos|slave_pos|no}
 | MASTER_DEMOTE_TO_SLAVE = bool
 | IGNORE_SERVER_IDS = (server_id_list)
 | DO_DOMAIN_IDS = ([N,..])
 | IGNORE_DOMAIN_IDS = ([N,..])

Description
-----------

The CHANGE MASTER statement sets the options that a replica uses to connect to
and replicate from a primary.

MariaDB starting with 10.7.0
----------------------------
The FOR CHANNEL keyword was added for MySQL compatibility. This is identical
to using the channel_name directly after CHANGE MASTER.

Multi-Source Replication
------------------------

If you are using multi-source replication, then you need to specify a
connection name when you execute CHANGE MASTER. There are two ways to do this:

* Setting the default_master_connection system variable prior to executing
CHANGE MASTER.
* Setting the connection_name parameter when executing CHANGE MASTER.

default_master_connection
-------------------------

SET default_master_connection = 'gandalf';
STOP SLAVE;
CHANGE MASTER TO 
 MASTER_PASSWORD='new3cret';
START SLAVE;

connection_name
---------------

STOP SLAVE 'gandalf';
CHANGE MASTER 'gandalf' TO 
 MASTER_PASSWORD='new3cret';
START SLAVE 'gandalf';

Options
-------

Connection Options
------------------

MASTER_USER
-----------

The MASTER_USER option for CHANGE MASTER defines the user account that the
replica will use to connect to the primary.

This user account will need the REPLICATION SLAVE privilege (or, from MariaDB
10.5.1, the REPLICATION REPLICA on the primary.

For example:

STOP SLAVE;
CHANGE MASTER TO
 MASTER_USER='repl',
 MASTER_PASSWORD='new3cret';
START SLAVE;

The maximum length of the MASTER_USER string is 96 characters until MariaDB
10.5, and 128 characters from MariaDB 10.6.

MASTER_PASSWORD
---------------

The MASTER_PASSWORD option for CHANGE MASTER defines the password that the
replica will use to connect to the primary as the user account defined by the
MASTER_USER option.

For example:

STOP SLAVE;
CHANGE MASTER TO 
 MASTER_PASSWORD='new3cret';
START SLAVE;

The maximum length of the MASTER_PASSWORD string is 32 characters. The
effective maximum length of the string depends on how many bytes are used per
character and can be up to 96 characters.

Due to MDEV-29994, the password can be silently truncated to 41 characters
when MariaDB is restarted. For this reason it is recommended to use a password
that is shorter than this.

MASTER_HOST
-----------

The MASTER_HOST option for CHANGE MASTER defines the hostname or IP address of
the primary.

If you set the value of the MASTER_HOST option to the empty string, then that
is not the same as not setting the option's value at all. If you set the value
of the MASTER_HOST option to the empty string, then the CHANGE MASTER command
will fail with an error. In MariaDB 5.3 and before, if you set the value of
the MASTER_HOST option to the empty string, then the CHANGE MASTER command
would succeed, but the subsequent START SLAVE command would fail.

For example:

STOP SLAVE;
CHANGE MASTER TO
 MASTER_HOST='dbserver1.example.com',
 MASTER_USER='repl',
 MASTER_PASSWORD='new3cret',
 MASTER_USE_GTID=slave_pos;
START SLAVE;

If you set the value of the MASTER_HOST option in a CHANGE MASTER command,
then the replica assumes that the primary is different from before, even if
you set the value of this option to the same value it had previously. In this
scenario, the replica will consider the old values for the primary's binary
log file name and position to be invalid for the new primary. As a side
effect, if you do not explicitly set the values of the MASTER_LOG_FILE and
MASTER_LOG_POS options in the statement, then the statement will be implicitly
appended with MASTER_LOG_FILE='' and MASTER_LOG_POS=4. However, if you enable
GTID mode for replication by setting the MASTER_USE_GTID option to some value
other than no in the statement, then these values will effectively be ignored
anyway.

Replicas cannot connect to primaries using Unix socket files or Windows named
pipes. The replica must connect to the primary using TCP/IP.

The maximum length of the MASTER_HOST string is 60 characters until MariaDB
10.5, and 255 characters from MariaDB 10.6.

MASTER_PORT
-----------

The MASTER_PORT option for CHANGE MASTER defines the TCP/IP port of the
primary.

For example:

STOP SLAVE;
CHANGE MASTER TO
 MASTER_HOST='dbserver1.example.com',
 MASTER_PORT=3307,
 MASTER_USER='repl',
 MASTER_PASSWORD='new3cret',
 MASTER_USE_GTID=slave_pos;
START SLAVE;

If you set the value of the MASTER_PORT option in a CHANGE MASTER command,
then the replica assumes that the primary is different from before, even if
you set the value of this option to the same value it had previously. In this
scenario, the replica will consider the old values for the primary's binary
log file name and position to be invalid for the new primary. As a side
effect, if you do not explicitly set the values of the MASTER_LOG_FILE and
MASTER_LOG_POS options in the statement, then the statement will be implicitly
appended with MASTER_LOG_FILE='' and MASTER_LOG_POS=4. However, if you enable
GTID mode for replication by setting the MASTER_USE_GTID option to some value
other than no in the statement, then these values will effectively be ignored
anyway.

Replicas cannot connect to primaries using Unix socket files or Windows named
pipes. The replica must connect to the primary using TCP/IP.

MASTER_CONNECT_RETRY
--------------------

The MASTER_CONNECT_RETRY option for CHANGE MASTER defines how many seconds
that the replica will wait between connection retries. The default is 60.

STOP SLAVE;
CHANGE MASTER TO 
 MASTER_CONNECT_RETRY=20;
START SLAVE;

The number of connection attempts is limited by the master_retry_count option.
It can be set either on the command-line or in a server option group in an
option file prior to starting up the server. For example:

[mariadb]
...
master_retry_count=4294967295

MASTER_BIND
-----------

The MASTER_BIND option for CHANGE MASTER is only supported by MySQL 5.6.2 and
later and by MySQL NDB Cluster 7.3.1 and later. This option is not supported
by MariaDB. See MDEV-19248 for more information.

The MASTER_BIND option for CHANGE MASTER can be used on replicas that have
multiple network interfaces to choose which network interface the replica will
use to connect to the primary.

MASTER_HEARTBEAT_PERIOD
-----------------------

The MASTER_HEARTBEAT_PERIOD option for CHANGE MASTER can be used to set the
interval in seconds between replication heartbeats. Whenever the primary's
binary log is updated with an event, the waiting period for the next heartbeat
is reset.

This option's interval argument has the following characteristics:

* It is a decimal value with a range of 0 to 4294967 seconds.
* It has a resolution of hundredths of a second.
* Its smallest valid non-zero value is 0.001.
* Its default value is the value of the slave_net_timeout system variable
divided by 2.
* If it's set to 0, then heart��beats are disabled.

Heartbeats are sent by the primary only if there are no unsent events in the
binary log file for a period longer than the interval.

If the RESET SLAVE statement is executed, then the heartbeat interval is reset
to the default.

If the slave_net_timeout system variable is set to a value that is lower than
the current heartbeat interval, then a warning will be issued.

TLS Options
-----------

The TLS options are used for providing information about TLS. The options can
be set even on replicas that are compiled without TLS support. The TLS options
are saved to either the default master.info file or the file that is
configured by the master_info_file option, but these TLS options are ignored
unless the replica supports TLS.

See Replication with Secure Connections for more information.

MASTER_SSL
----------

The MASTER_SSL option for CHANGE MASTER tells the replica whether to force TLS
for the connection. The valid values are 0 or 1. Required to be set to 1 for
the other MASTER_SSL* options to have any effect.

For example:

STOP SLAVE;
CHANGE MASTER TO
 MASTER_SSL=1;
START SLAVE;

MASTER_SSL_CA
-------------

The MASTER_SSL_CA option for CHANGE MASTER defines a path to a PEM file that
should contain one or more X509 certificates for trusted Certificate
Authorities (CAs) to use for TLS. This option requires that you use the
absolute path, not a relative path.

For example:

STOP SLAVE;
CHANGE MASTER TO
 MASTER_SSL_CERT='/etc/my.cnf.d/certificates/server-cert.pem',
 MASTER_SSL_KEY='/etc/my.cnf.d/certificates/server-key.pem',
 MASTER_SSL_CA='/etc/my.cnf.d/certificates/ca.pem',
 MASTER_SSL_VERIFY_SERVER_CERT=1;
START SLAVE;

See Secure Connections Overview: Certificate Authorities (CAs) for more
information.

The maximum length of MASTER_SSL_CA string is 511 characters.

MASTER_SSL_CAPATH
-----------------

The MASTER_SSL_CAPATH option for CHANGE MASTER defines a path to a directory
that contains one or more PEM files that should each contain one X509
certificate for a trusted Certificate Authority (CA) to use for TLS. This
option requires that you use the absolute path, not a relative path. The
directory specified by this option needs to be run through the openssl rehash
command.

For example:

STOP SLAVE;
CHANGE MASTER TO
 MASTER_SSL_CERT='/etc/my.cnf.d/certificates/server-cert.pem',
 MASTER_SSL_KEY='/etc/my.cnf.d/certificates/server-key.pem',
 MASTER_SSL_CAPATH='/etc/my.cnf.d/certificates/ca/',
 MASTER_SSL_VERIFY_SERVER_CERT=1;
START SLAVE;

See Secure Connections Overview: Certificate Authorities (CAs) for more
information.

The maximum length of MASTER_SSL_CA_PATH string is 511 characters.

MASTER_SSL_CERT
---------------

The MASTER_SSL_CERT option for CHANGE MASTER defines a path to the X509
certificate file to use for TLS. This option requires that you use the
absolute path, not a relative path.

For example:

STOP SLAVE;
CHANGE MASTER TO
 MASTER_SSL_CERT='/etc/my.cnf.d/certificates/server-cert.pem',
 MASTER_SSL_KEY='/etc/my.cnf.d/certificates/server-key.pem',
 MASTER_SSL_CA='/etc/my.cnf.d/certificates/ca.pem',
 MASTER_SSL_VERIFY_SERVER_CERT=1;
START SLAVE;

The maximum length of MASTER_SSL_CERT string is 511 characters.

MASTER_SSL_CRL
--------------

The MASTER_SSL_CRL option for CHANGE MASTER defines a path to a PEM file that
should contain one or more revoked X509 certificates to use for TLS. This
option requires that you use the absolute path, not a relative path.

This option is only supported if the server was built with OpenSSL. If the
server was built with yaSSL, then this option is not supported. See TLS and
Cryptography Libraries Used by MariaDB for more information about which
libraries are used on which platforms.

For example:

STOP SLAVE;
CHANGE MASTER TO
 MASTER_SSL_CERT='/etc/my.cnf.d/certificates/server-cert.pem',
 MASTER_SSL_KEY='/etc/my.cnf.d/certificates/server-key.pem',
 MASTER_SSL_CA='/etc/my.cnf.d/certificates/ca.pem',
 MASTER_SSL_VERIFY_SERVER_CERT=1,
 MASTER_SSL_CRL='/etc/my.cnf.d/certificates/crl.pem';
START SLAVE;

See Secure Connections Overview: Certificate Revocation Lists (CRLs) for more
information.

The maximum length of MASTER_SSL_CRL string is 511 characters.

MASTER_SSL_CRLPATH
------------------

The MASTER_SSL_CRLPATH option for CHANGE MASTER defines a path to a directory
that contains one or more PEM files that should each contain one revoked X509
certificate to use for TLS. This option requires that you use the absolute
path, not a relative path. The directory specified by this variable needs to
be run through the openssl rehash command.

This option is only supported if the server was built with OpenSSL. If the
server was built with yaSSL, then this option is not supported. See TLS and
Cryptography Libraries Used by MariaDB for more information about which
libraries are used on which platforms.

For example:

STOP SLAVE;
CHANGE MASTER TO
 MASTER_SSL_CERT='/etc/my.cnf.d/certificates/server-cert.pem',
 MASTER_SSL_KEY='/etc/my.cnf.d/certificates/server-key.pem',
 MASTER_SSL_CA='/etc/my.cnf.d/certificates/ca.pem',
 MASTER_SSL_VERIFY_SERVER_CERT=1,
 MASTER_SSL_CRLPATH='/etc/my.cnf.d/certificates/crl/';
START SLAVE;

See Secure Connections Overview: Certificate Revocation Lists (CRLs) for more
information.

The maximum length of MASTER_SSL_CRL_PATH string is 511 characters.

MASTER_SSL_KEY
--------------

The MASTER_SSL_KEY option for CHANGE MASTER defines a path to a private key
file to use for TLS. This option requires that you use the absolute path, not
a relative path.

For example:

STOP SLAVE;
CHANGE MASTER TO
 MASTER_SSL_CERT='/etc/my.cnf.d/certificates/server-cert.pem',
 MASTER_SSL_KEY='/etc/my.cnf.d/certificates/server-key.pem',
 MASTER_SSL_CA='/etc/my.cnf.d/certificates/ca.pem',
 MASTER_SSL_VERIFY_SERVER_CERT=1;
START SLAVE;

The maximum length of MASTER_SSL_KEY string is 511 characters.

MASTER_SSL_CIPHER
-----------------

The MASTER_SSL_CIPHER option for CHANGE MASTER defines the list of permitted
ciphers or cipher suites to use for TLS. Besides cipher names, if MariaDB was
compiled with OpenSSL, this option could be set to "SSLv3" or "TLSv1.2" to
allow all SSLv3 or all TLSv1.2 ciphers. Note that the TLSv1.3 ciphers cannot
be excluded when using OpenSSL, even by using this option. See Using TLSv1.3
for details.

For example:

STOP SLAVE;
CHANGE MASTER TO
 MASTER_SSL_CERT='/etc/my.cnf.d/certificates/server-cert.pem',
 MASTER_SSL_KEY='/etc/my.cnf.d/certificates/server-key.pem',
 MASTER_SSL_CA='/etc/my.cnf.d/certificates/ca.pem',
 MASTER_SSL_VERIFY_SERVER_CERT=1,
 MASTER_SSL_CIPHER='TLSv1.2';
START SLAVE;

The maximum length of MASTER_SSL_CIPHER string is 511 characters.

MASTER_SSL_VERIFY_SERVER_CERT
-----------------------------

The MASTER_SSL_VERIFY_SERVER_CERT option for CHANGE MASTER enables server
certificate verification. This option is disabled by default.

For example:

STOP SLAVE;
CHANGE MASTER TO
 MASTER_SSL_CERT='/etc/my.cnf.d/certificates/server-cert.pem',
 MASTER_SSL_KEY='/etc/my.cnf.d/certificates/server-key.pem',
 MASTER_SSL_CA='/etc/my.cnf.d/certificates/ca.pem',
 MASTER_SSL_VERIFY_SERVER_CERT=1;
START SLAVE;

See Secure Connections Overview: Server Certificate Verification for more
information.

Binary Log Options
------------------

These options are related to the binary log position on the primary.

MASTER_LOG_FILE
---------------

The MASTER_LOG_FILE option for CHANGE MASTER can be used along with
MASTER_LOG_POS to specify the coordinates at which the replica's I/O thread
should begin reading from the primary's binary logs the next time the thread
starts.

For example:

STOP SLAVE;
CHANGE MASTER TO
 MASTER_LOG_FILE='master2-bin.001',
 MASTER_LOG_POS=4;
START SLAVE;

The MASTER_LOG_FILE and MASTER_LOG_POS options cannot be specified if the
RELAY_LOG_FILE and RELAY_LOG_POS options were also specified.

The MASTER_LOG_FILE and MASTER_LOG_POS options are effectively ignored if you
enable GTID mode for replication by setting the MASTER_USE_GTID option to some
value other than no in the statement.

MASTER_LOG_POS
--------------

The MASTER_LOG_POS option for CHANGE MASTER can be used along with
MASTER_LOG_FILE to specify the coordinates a�!~t which the replica's I/O thread
should begin reading from the primary's binary logs the next time the thread
starts.

For example:

STOP SLAVE;
CHANGE MASTER TO
 MASTER_LOG_FILE='master2-bin.001',
 MASTER_LOG_POS=4;
START SLAVE;

The MASTER_LOG_FILE and MASTER_LOG_POS options cannot be specified if the
RELAY_LOG_FILE and RELAY_LOG_POS options were also specified.

The MASTER_LOG_FILE and MASTER_LOG_POS options are effectively ignored if you
enable GTID mode for replication by setting the MASTER_USE_GTID option to some
value other than no in the statement.

Relay Log Options
-----------------

These options are related to the relay log position on the replica.

RELAY_LOG_FILE
--------------

The RELAY_LOG_FILE option for CHANGE MASTER can be used along with the
RELAY_LOG_POS option to specify the coordinates at which the replica's SQL
thread should begin reading from the relay log the next time the thread starts.

The CHANGE MASTER statement usually deletes all relay log files. However, if
the RELAY_LOG_FILE and/or RELAY_LOG_POS options are specified, then existing
relay log files are kept.

When you want to change the relay log position, you only need to stop the
replica's SQL thread. The replica's I/O thread can continue running. The STOP
SLAVE and START SLAVE statements support the SQL_THREAD option for this
scenario. For example:

STOP SLAVE SQL_THREAD;
CHANGE MASTER TO
 RELAY_LOG_FILE='slave-relay-bin.006',
 RELAY_LOG_POS=4025;
START SLAVE SQL_THREAD;

When the value of this option is changed, the metadata about the replica's SQL
thread's position in the relay logs will also be changed in the relay-log.info
file or the file that is configured by the relay_log_info_file system variable.

The RELAY_LOG_FILE and RELAY_LOG_POS options cannot be specified if the
MASTER_LOG_FILE and MASTER_LOG_POS options were also specified.

RELAY_LOG_POS
-------------

The RELAY_LOG_POS option for CHANGE MASTER can be used along with the
RELAY_LOG_FILE option to specify the coordinates at which the replica's SQL
thread should begin reading from the relay log the next time the thread starts.

The CHANGE MASTER statement usually deletes all relay log files. However, if
the RELAY_LOG_FILE and/or RELAY_LOG_POS options are specified, then existing
relay log files are kept.

When you want to change the relay log position, you only need to stop the
replica's SQL thread. The replica's I/O thread can continue running. The STOP
SLAVE and START SLAVE statements support the SQL_THREAD option for this
scenario. For example:

STOP SLAVE SQL_THREAD;
CHANGE MASTER TO
 RELAY_LOG_FILE='slave-relay-bin.006',
 RELAY_LOG_POS=4025;
START SLAVE SQL_THREAD;

When the value of this option is changed, the metadata about the replica's SQL
thread's position in the relay logs will also be changed in the relay-log.info
file or the file that is configured by the relay_log_info_file system variable.

The RELAY_LOG_FILE and RELAY_LOG_POS options cannot be specified if the
MASTER_LOG_FILE and MASTER_LOG_POS options were also specified.

GTID Options
------------

MASTER_USE_GTID
---------------

The MASTER_USE_GTID option for CHANGE MASTER can be used to configure the
replica to use the global transaction ID (GTID) when connecting to a primary.
The possible values are:

* current_pos - Replicate in GTID mode and use gtid_current_pos as the
position to start downloading transactions from the primary. Deprecated from
MariaDB 10.10. Using to transition to primary can break the replication state
if the replica executes local transactions due to actively updating
gtid_current_pos with gtid_binlog_pos and gtid_slave_pos. Use the new, safe,
MASTER_DEMOTE_TO_SLAVE=<bool> option instead.
* slave_pos - Replicate in GTID mode and use gtid_slave_pos as the position to
start downloading transactions from the primary. From MariaDB 10.5.1,
replica_pos is an alias for slave_pos.
* no - Don't replicate in GTID mode.

For example:

STOP SLAVE;
CHANGE MASTER TO
 MASTER_USE_GTID = current_pos;
START SLAVE;

Or:

STOP SLAVE;
SET GLOBAL gtid_slave_pos='0-1-153';
CHANGE MASTER TO
 MASTER_USE_GTID = slave_pos;
START SLAVE;

MASTER_DEMOTE_TO_SLAVE
----------------------

MariaDB starting with 10.10
---------------------------
Used to transition a primary to become a replica. Replaces the old
MASTER_USE_GTID=current_pos with a safe alternative by forcing users to set
Using_Gtid=Slave_Pos and merging gtid_binlog_pos into gtid_slave_pos once at
CHANGE MASTER TO time. If gtid_slave_pos is more recent than gtid_binlog_pos
(as in the case of chain replication), the replication state should be
preserved.

For example:

STOP SLAVE;
CHANGE MASTER TO
 MASTER_DEMOTE_TO_SLAVE = 1;
START SLAVE;

Replication Filter Options
--------------------------

Also see Replication filters.

IGNORE_SERVER_IDS
-----------------

The IGNORE_SERVER_IDS option for CHANGE MASTER can be used to configure a
replica to ignore binary log events that originated from certain servers.
Filtered binary log events will not get logged to the replica’s relay log, and
they will not be applied by the replica.

The option's value can be specified by providing a comma-separated list of
server_id values. For example:

STOP SLAVE;
CHANGE MASTER TO 
 IGNORE_SERVER_IDS = (3,5);
START SLAVE;

If you would like to clear a previously set list, then you can set the value
to an empty list. For example:

STOP SLAVE;
CHANGE MASTER TO 
 IGNORE_SERVER_IDS = ();
START SLAVE;

DO_DOMAIN_IDS
-------------

The DO_DOMAIN_IDS option for CHANGE MASTER can be used to configure a replica
to only apply binary log events if the transaction's GTID is in a specific
gtid_domain_id value. Filtered binary log events will not get logged to the
replica’s relay log, and they will not be applied by the replica.

The option's value can be specified by providing a comma-separated list of
gtid_domain_id values. Duplicate values are automatically ignored. For example:

STOP SLAVE;
CHANGE MASTER TO 
 DO_DOMAIN_IDS = (1,2);
START SLAVE;

If you would like to clear a previously set list, then you can set the value
to an empty list. For example:

STOP SLAVE;
CHANGE MASTER TO 
 DO_DOMAIN_IDS = ();
START SLAVE;

The DO_DOMAIN_IDS option and the IGNORE_DOMAIN_IDS option cannot both be set
to non-empty values at the same time. If you want to set the DO_DOMAIN_IDS
option, and the IGNORE_DOMAIN_IDS option was previously set, then you need to
clear the value of the IGNORE_DOMAIN_IDS option. For example:

STOP SLAVE;
CHANGE MASTER TO 
 IGNORE_DOMAIN_IDS = (),
 DO_DOMAIN_IDS = (1,2);
START SLAVE;

The DO_DOMAIN_IDS option can only be specified if the replica is replicating
in GTID mode. Therefore, the MASTER_USE_GTID option must also be set to some
value other than no in order to use this option.

IGNORE_DOMAIN_IDS
-----------------

The IGNORE_DOMAIN_IDS option for CHANGE MASTER can be used to configure a
replica to ignore binary log events if the transaction's GTID is in a specific
gtid_domain_id value. Filtered binary log events will not get logged to the
replica’s relay log, and they will not be applied by the replica.

The option's value can be specified by providing a comma-separated list of
gtid_domain_id values. Duplicate values are automatically ignored. For example:

STOP SLAVE;
CHANGE MASTER TO 
 IGNORE_DOMAIN_IDS = (1,2);
START SLAVE;

If you would like to clear a previously set list, then you can set the value
to an empty list. For example:

STOP SLAVE;
CHANGE MASTER TO 
 IGNORE_DOMAIN_IDS = ();
START SLAVE;

The DO_DOMAIN_IDS option and the IGNORE_DOMAIN_IDS option cannot both be set
to non-empty values at the same time. If you want to set the IGNORE_DOMAIN_IDS
option, and the DO_DOMAIN_IDS option was previously set, then you need to
clear the value of the DO_DOMAIN_IDS option. For example:

STOP SLAVE;
CHANGE MASTER TO 
 DO_DOMAIN_IDS = (),
 IGNORE_DOMAIN_IDS = (1,2);
START SLAVE;

The IGNORE_DOMAIN_IDS option can only be specified if the replica is
replicating in GTID mode. Therefore, the MASTER_USE_GTID option must also be
set to some value other than no in order to use this option.

Delayed Replication Options
---------------------------

MASTER_DELAY
------------

T����he MASTER_DELAY option for CHANGE MASTER can be used to enable delayed
replication. This option specifies the time in seconds (at least) that a
replica should lag behind the primary up to a maximum value of 2147483647, or
about 68 years. Before executing an event, the replica will first wait, if
necessary, until the given time has passed since the event was created on the
primary. The result is that the replica will reflect the state of the primary
some time back in the past. The default is zero, no delay.

STOP SLAVE;
CHANGE MASTER TO 
 MASTER_DELAY=3600;
START SLAVE;

Changing Option Values
----------------------

If you don't specify a given option when executing the CHANGE MASTER
statement, then the option keeps its old value in most cases. Most of the
time, there is no need to specify the options that do not need to change. For
example, if the password for the user account that the replica uses to connect
to its primary has changed, but no other options need to change, then you can
just change the MASTER_PASSWORD option by executing the following commands:

STOP SLAVE;
CHANGE MASTER TO 
 MASTER_PASSWORD='new3cret';
START SLAVE;

There are some cases where options are implicitly reset, such as when the
MASTER_HOST and MASTER_PORT options are changed.

Option Persistence
------------------

The values of the MASTER_LOG_FILE and MASTER_LOG_POS options (i.e. the binary
log position on the primary) and most other options are written to either the
default master.info file or the file that is configured by the
master_info_file option. The replica's I/O thread keeps this binary log
position updated as it downloads events only when MASTER_USE_GTID option is
set to NO. Otherwise the file is not updated on a per event basis.

The master_info_file option can be set either on the command-line or in a
server option group in an option file prior to starting up the server. For
example:

[mariadb]
...
master_info_file=/mariadb/myserver1-master.info

The values of the RELAY_LOG_FILE and RELAY_LOG_POS options (i.e. the relay log
position) are written to either the default relay-log.info file or the file
that is configured by the relay_log_info_file system variable. The replica's
SQL thread keeps this relay log position updated as it applies events.

The relay_log_info_file system variable can be set either on the command-line
or in a server option group in an option file prior to starting up the server.
For example:

[mariadb]
...
relay_log_info_file=/mariadb/myserver1-relay-log.info

GTID Persistence
----------------

If the replica is replicating binary log events that contain GTIDs, then the
replica's SQL thread will write every GTID that it applies to the
mysql.gtid_slave_pos table. This GTID can be inspected and modified through
the gtid_slave_pos system variable.

If the replica has the log_slave_updates system variable enabled and if the
replica has the binary log enabled, then every write by the replica's SQL
thread will also go into the replica's binary log. This means that GTIDs of
replicated transactions would be reflected in the value of the gtid_binlog_pos
system variable.

Creating a Replica from a Backup
--------------------------------

The CHANGE MASTER statement is useful for setting up a replica when you have a
backup of the primary and you also have the binary log position or GTID
position corresponding to the backup.

After restoring the backup on the replica, you could execute something like
this to use the binary log position:

CHANGE MASTER TO
 MASTER_LOG_FILE='master2-bin.001',
 MASTER_LOG_POS=4;
START SLAVE;

Or you could execute something like this to use the GTID position:

SET GLOBAL gtid_slave_pos='0-1-153';
CHANGE MASTER TO
 MASTER_USE_GTID=slave_pos;
START SLAVE;

See Setting up a Replication Slave with Mariabackup for more information on
how to do this with Mariabackup.

Example
-------

The following example changes the primary and primary's binary log
coordinates. This is used when you want to set up the replica to replicate the
primary:

CHANGE MASTER TO
 MASTER_HOST='master2.mycompany.com',
 MASTER_USER='replication',
 MASTER_PASSWORD='bigs3cret',
 MASTER_PORT=3306,
 MASTER_LOG_FILE='master2-bin.001',
 MASTER_LOG_POS=4,
 MASTER_CONNECT_RETRY=10;
START SLAVE;

URL: https://mariadb.com/kb/en/change-master-to/�)�$G��<8*Cursor OverviewDescription
-----------

A cursor is a structure that allows you to go over records sequentially, and
perform processing based on the result.

MariaDB permits cursors inside stored programs, and MariaDB cursors are
non-scrollable, read-only and asensitive.

* Non-scrollable means that the rows can only be fetched in the order
specified by the SELECT statement. Rows cannot be skipped, you cannot jump to
a specific row, and you cannot fetch rows in reverse order.
* Read-only means that data cannot be updated through the cursor.
* Asensitive means that the cursor points to the actual underlying data. This
kind of cursor is quicker than the alternative, an insensitive cursor, as no
data is copied to a temporary table. However, changes to the data being used
by the cursor will affect the cursor data.

Cursors are created with a DECLARE CURSOR statement and opened with an OPEN
statement. Rows are read with a FETCH statement before the cursor is finally
closed with a CLOSE statement.

When FETCH is issued and there are no more rows to extract, the following
error is produced:

ERROR 1329 (02000): No data - zero rows fetched, selected, or processed

To avoid problems, a DECLARE HANDLER statement is generally used. The HANDLER
should handler the 1329 error, or the '02000' SQLSTATE, or the NOT FOUND error
class.

Only SELECT statements are allowed for cursors, and they cannot be contained
in a variable - so, they cannot be composed dynamically. However, it is
possible to SELECT from a view. Since the CREATE VIEW statement can be
executed as a prepared statement, it is possible to dynamically create the
view that is queried by the cursor.

From MariaDB 10.3.0, cursors can have parameters. Cursor parameters can appear
in any part of the DECLARE CURSOR select_statement where a stored procedure
variable is allowed (select list, WHERE, HAVING, LIMIT etc). See DECLARE
CURSOR and OPEN for syntax, and below for an example:

Examples
--------

CREATE TABLE c1(i INT);

CREATE TABLE c2(i INT);

CREATE TABLE c3(i INT);

DELIMITER //

CREATE PROCEDURE p1()
BEGIN
 DECLARE done INT DEFAULT FALSE;
 DECLARE x, y INT;
 DECLARE cur1 CURSOR FOR SELECT i FROM test.c1;
 DECLARE cur2 CURSOR FOR SELECT i FROM test.c2;
 DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = TRUE;

OPEN cur1;
 OPEN cur2;

read_loop: LOOP
  FETCH cur1 INTO x;
  FETCH cur2 INTO y;
  IF done THEN
   LEAVE read_loop;
  END IF;
  IF x < y THEN
   INSERT INTO test.c3 VALUES (x);
  ELSE
   INSERT INTO test.c3 VALUES (y);
  END IF;
 END LOOP;

CLOSE cur1;
 CLOSE cur2;
END; //

DELIMITER ;

INSERT INTO c1 VALUES(5),(50),(500);

INSERT INTO c2 VALUES(10),(20),(30);

CALL p1;

SELECT * FROM c3;
+------+
| i    |
+------+
|    5 |
|   20 |
|   30 |
+------+

From MariaDB 10.3.0

DROP PROCEDURE IF EXISTS p1;
DROP TABLE IF EXISTS t1;
CREATE TABLE t1 (a INT, b VARCHAR(10));

INSERT INTO t1 VALUES (1,'old'),(2,'old'),(3,'old'),(4,'old'),(5,'old');

DELIMITER //

CREATE PROCEDURE p1(min INT,max INT)
BEGIN
 DECLARE done INT DEFAULT FALSE;
 DECLARE va INT;
 DECLARE cur CURSOR(pmin INT, pmax INT) FOR SELECT a FROM t1 WHERE a BETWEEN
pmin AND pmax;
 DECLARE CONTINUE HANDLER FOR NOT FOUND SET done=TRUE;
 OPEN cur(min,max);
 read_loop: LOOP
  FETCH cur INTO va;
  IF done THEN
   LEAVE read_loop;
  END IF;
  INSERT INTO t1 VALUES (va,'new');
 END LOOP;
 CLOSE cur;
END;
//

DELIMITER ;

CALL p1(2,4);

SELECT * FROM t1;
+------+------+
| a    | b    |
+------+------+
|    1 | old  |
|    2 | old  |
|    3 | old  |
|    4 | old  |
|    5 | old  |
|    2 | new  |
|    3 | new  |
|    4 | new  |
+------+------+

URL: https://mariadb.com/kb/en/cursor-overview/https://mariadb.com/kb/en/cursor-overview/G�'MULTIPOLYGONSyntax
------

MultiPolygon(poly1,poly2,...)

Description
-----------

Constructs a WKB MultiPolygon value from a set of WKB Polygon arguments. If
any argument is not a WKB Polygon, the return value is NULL.

Example
-------

CREATE TABLE gis_multi_polygon  (g MULTIPOLYGON);
INSERT INTO gis_multi_polygon VALUES
  (MultiPolygonFromText('MULTIPOLYGON(((28 26,28 0,84 0,84 42,28 26),(52
18,66 23,73 9,48 6,52 18)),
  ((59 18,67 18,67 13,59 13,59 18)))')),
  (MPolyFromText('MULTIPOLYGON(((28 26,28 0,84 0,84 42,28 26),(52 18,66
23,73 9,48 6,52 18)),
    ((59 18,67 18,67 13,59 13,59 18)))')),
  (MPolyFromWKB(AsWKB(MultiPolygon(Polygon(LineString(
   Point(0, 3), Point(3, 3), Point(3, 0), Point(0, 3)))))));

URL: https://mariadb.com/kb/en/multipolygon/https://mariadb.com/kb/en/multipolygon/Jg"POLYGONSyntax
------

Polygon(ls1,ls2,...)

Description
-----------

Constructs a WKB Polygon value from a number of WKB LineString arguments. If
any argument does not represent the WKB of a LinearRing (that is, not a closed
and simple LineString) the return value is NULL.

Note that according to the OpenGIS standard, a POLYGON should have exactly one
ExteriorRing and all other rings should lie within that ExteriorRing and thus
be the InteriorRings. Practically, however, some systems, including MariaDB's,
permit polygons to have several 'ExteriorRings'. In the case of there being
multiple, non-overlapping exterior rings ST_NUMINTERIORRINGS() will return 1.

Examples
--------

SET @g = ST_GEOMFROMTEXT('POLYGON((1 1,1 5,4 9,6 9,9 3,7 2,1 1))');

CREATE TABLE gis_polygon   (g POLYGON);
INSERT INTO gis_polygon VALUES
  (PolygonFromText('POLYGON((10 10,20 10,20 20,10 20,10 10))')),
  (PolyFromText('POLYGON((0 0,50 0,50 50,0 50,0 0), (10 10,20 10,20 20,10
20,10 10))')),
  (PolyFromWKB(AsWKB(Polygon(LineString(Point(0, 0), Point(30, 0), Point(30,
30), Point(0, 0))))));

Non-overlapping 'polygon':

SELECT ST_NumInteriorRings(ST_PolyFromText('POLYGON((0 0,10 0,10 10,0 10,0 0),
 (-1 -1,-5 -1,-5 -5,-1 -5,-1 -1))')) AS NumInteriorRings;
+------------------+
| NumInteriorRings |
+------------------+
|                1 |
+------------------+

URL: https://mariadb.com/kb/en/polygon/https://mariadb.com/kb/en/polygon/���2'o���ZK	�$ST_BUFFERSyntax
------

ST_BUFFER(g1,r)
BUFFER(g1,r)

Description
-----------

Returns a geometry that represents all points whose distance from geometry g1
is less than or equal to distance, or radius, r.

Uses for this function could include creating for example a new geometry
representing a buffer zone around an island.

BUFFER() is a synonym.

Examples
--------

Determining whether a point is within a buffer zone:

SET @g1 = ST_GEOMFROMTEXT('POLYGON((10 10, 10 20, 20 20, 20 10, 10 10))');

SET @g2 = ST_GEOMFROMTEXT('POINT(8 8)');

SELECT ST_WITHIN(@g2,ST_BUFFER(@g1,5));
+---------------------------------+
| ST_WITHIN(@g2,ST_BUFFER(@g1,5)) |
+---------------------------------+
|                               1 |
+---------------------------------+

SELECT ST_WITHIN(@g2,ST_BUFFER(@g1,1));
+---------------------------------+
| ST_WITHIN(@g2,ST_BUFFER(@g1,1)) |
+---------------------------------+
|                               0 |
+---------------------------------+

URL: https://mariadb.com/kb/en/st_buffer/https://mariadb.com/kb/en/st_buffer/L
d(ST_CONVEXHULLMariaDB starting with 10.1.2
----------------------------
ST_ConvexHull() was introduced in MariaDB 10.1.2

Syntax
------

ST_ConvexHull(g)
ConvexHull(g)

Description
-----------

Given a geometry, returns a geometry that is the minimum convex geometry
enclosing all geometries within the set. Returns NULL if the geometry value is
NULL or an empty value.

ST_ConvexHull() and ConvexHull() are synonyms.

Examples
--------

The ConvexHull of a single point is simply the single point:

SET @g = ST_GEOMFROMTEXT('Point(0 0)');

SELECT ST_ASTEXT(ST_CONVEXHULL(@g));
+------------------------------+
| ST_ASTEXT(ST_CONVEXHULL(@g)) |
+------------------------------+
| POINT(0 0)                   |
+------------------------------+

SET @g = ST_GEOMFROMTEXT('MultiPoint(0 0, 1 2, 2 3)');

SELECT ST_ASTEXT(ST_CONVEXHULL(@g));
+------------------------------+
| ST_ASTEXT(ST_CONVEXHULL(@g)) |
+------------------------------+
| POLYGON((0 0,1 2,2 3,0 0))   |
+------------------------------+

SET @g = ST_GEOMFROMTEXT('MultiPoint( 1 1, 2 2, 5 3, 7 2, 9 3, 8 4, 6 6, 6 9,
4 9, 1 5 )');

SELECT ST_ASTEXT(ST_CONVEXHULL(@g));
+----------------------------------------+
| ST_ASTEXT(ST_CONVEXHULL(@g))           |
+----------------------------------------+
| POLYGON((1 1,1 5,4 9,6 9,9 3,7 2,1 1)) |
+----------------------------------------+

URL: https://mariadb.com/kb/en/st_convexhull/https://mariadb.com/kb/en/st_convexhull/O�+ST_SYMDIFFERENCESyntax
------

ST_SYMDIFFERENCE(g1,g2)

Description
-----------

Returns a geometry that represents the portions of geometry g1 and geometry g2
that don't intersect.

Examples
--------

SET @g1 = ST_GEOMFROMTEXT('LINESTRING(10 20, 10 40)');

SET @g2 = ST_GEOMFROMTEXT('LINESTRING(10 15, 10 25)');

SELECT ASTEXT(ST_SYMDIFFERENCE(@g1,@g2));
+----------------------------------------------+
| ASTEXT(ST_SYMDIFFERENCE(@g1,@g2))            |
+----------------------------------------------+
| MULTILINESTRING((10 15,10 20),(10 25,10 40)) |
+----------------------------------------------+

SET @g2 = ST_GeomFromText('LINESTRING(10 20, 10 41)');

SELECT ASTEXT(ST_SYMDIFFERENCE(@g1,@g2));
+-----------------------------------+
| ASTEXT(ST_SYMDIFFERENCE(@g1,@g2)) |
+-----------------------------------+
| LINESTRING(10 40,10 41)           |
+-----------------------------------+

URL: https://mariadb.com/kb/en/st_symdifference/https://mariadb.com/kb/en/st_symdifference/P_#ST_UNIONSyntax
------

ST_UNION(g1,g2)

Description
-----------

Returns a geometry that is the union of the geometry g1 and geometry g2.

Examples
--------

SET @g1 = GEOMFROMTEXT('POINT (0 2)');

SET @g2 = GEOMFROMTEXT('POINT (2 0)');

SELECT ASTEXT(ST_UNION(@g1,@g2));
+---------------------------+
| ASTEXT(ST_UNION(@g1,@g2)) |
+---------------------------+
| MULTIPOINT(2 0,0 2)       |
+---------------------------+

SET @g1 = GEOMFROMTEXT('POLYGON((0 0,0 3,3 3,3 0,0 0))');

SET @g2 = GEOMFROMTEXT('POLYGON((2 2,4 2,4 4,2 4,2 2))');

SELECT ASTEXT(ST_UNION(@g1,@g2));
+------------------------------------------------+
| ASTEXT(ST_UNION(@g1,@g2))                      |
+------------------------------------------------+
| POLYGON((0 0,0 3,2 3,2 4,4 4,4 2,3 2,3 0,0 0)) |
+------------------------------------------------+

URL: https://mariadb.com/kb/en/st_union/https://mariadb.com/kb/en/st_union/Q�	&SHOW GRANTSSyntax
------

SHOW GRANTS [FOR user|role]

Description
-----------

The SHOW GRANTS statement lists privileges granted to a particular user or
role.

Users
-----

The statement lists the GRANT statement or statements that must be issued to
duplicate the privileges that are granted to a MariaDB user account. The
account is named using the same format as for the GRANT statement; for
example, 'jeffrey'@'localhost'. If you specify only the user name part of the
account name, a host name part of '%' is used. For additional information
about specifying account names, see GRANT.

SHOW GRANTS FOR 'root'@'localhost';
+---------------------------------------------------------------------+
| Grants for root@localhost                                           |
+---------------------------------------------------------------------+
| GRANT ALL PRIVILEGES ON *.* TO 'root'@'localhost' WITH GRANT OPTION |
+---------------------------------------------------------------------+

To list the privileges granted to the account that you are using to connect to
the server, you can use any of the following statements:

SHOW GRANTS;
SHOW GRANTS FOR CURRENT_USER;
SHOW GRANTS FOR CURRENT_USER();

If SHOW GRANTS FOR CURRENT_USER (or any of the equivalent syntaxes) is used in
DEFINER context (such as within a stored procedure that is defined with SQL
SECURITY DEFINER), the grants displayed are those of the definer and not the
invoker.

Note that the DELETE HISTORY privilege, introduced in MariaDB 10.3.4, was
displayed as DELETE VERSIONING ROWS when running SHOW GRANTS until MariaDB
10.3.15 (MDEV-17655).

Roles
-----

SHOW GRANTS can also be used to view the privileges granted to a role.

Example
-------

SHOW GRANTS FOR journalist;
+------------------------------------------+
| Grants for journalist                    |
+------------------------------------------+
| GRANT USAGE ON *.* TO 'journalist'       |
| GRANT DELETE ON `test`.* TO 'journalist' |
+------------------------------------------+

FOR PUBLIC
----------

MariaDB starting with 10.11
---------------------------
GRANT ... TO PUBLIC was introduced in MariaDB 10.11 to grant privileges to all
users. SHOW GRANTS FOR PUBLIC shows all these grants.

SHOW GRANTS FOR public;
+------------------------------------------------+
| Grants for PUBLIC                              |
+------------------------------------------------+
| GRANT ALL PRIVILEGES ON `dev_db`.* TO `PUBLIC` |
+------------------------------------------------+

URL: https://mariadb.com/kb/en/show-grants/https://mariadb.com/kb/en/show-grants/a-
�
��	�>�2q�Gm��R+SHOW CREATE USERSyntax
------

SHOW CREATE USER user_name

Description
-----------

Shows the CREATE USER statement that created the given user. The statement
requires the SELECT privilege for the mysql database, except for the current
user.

Examples
--------

CREATE USER foo4@test require cipher 'text' 
 issuer 'foo_issuer' subject 'foo_subject';

SHOW CREATE USER foo4@test\G
*************************** 1. row ***************************
CREATE USER 'foo4'@'test' 
 REQUIRE ISSUER 'foo_issuer'
 SUBJECT 'foo_subject'
 CIPHER 'text'

User Password Expiry:

CREATE USER 'monty'@'localhost' PASSWORD EXPIRE INTERVAL 120 DAY;

SHOW CREATE USER 'monty'@'localhost';
+------------------------------------------------------------------+
| CREATE USER for monty@localhost                                  |
+------------------------------------------------------------------+
| CREATE USER 'monty'@'localhost' PASSWORD EXPIRE INTERVAL 120 DAY |
+------------------------------------------------------------------+

URL: https://mariadb.com/kb/en/show-create-user/https://mariadb.com/kb/en/show-create-user/T`,SHOW CREATE TABLESyntax
------

SHOW CREATE TABLE tbl_name

Description
-----------

Shows the CREATE TABLE statement that created the given table. The statement
requires the SELECT privilege for the table. This statement also works with
views and SEQUENCE.

SHOW CREATE TABLE quotes table and column names according to the value of the
sql_quote_show_create server system variable.

Certain SQL_MODE values can result in parts of the original CREATE statement
not being included in the output. MariaDB-specific table options, column
options, and index options are not included in the output of this statement if
the NO_TABLE_OPTIONS, NO_FIELD_OPTIONS and NO_KEY_OPTIONS SQL_MODE flags are
used. All MariaDB-specific table attributes are also not shown when a
non-MariaDB/MySQL emulation mode is used, which includes ANSI, DB2,
POSTGRESQL, MSSQL, MAXDB or ORACLE.

Invalid table options, column options and index options are normally commented
out (note, that it is possible to create a table with invalid options, by
altering a table of a different engine, where these options were valid). To
have them uncommented, enable the IGNORE_BAD_TABLE_OPTIONS SQL_MODE. Remember
that replaying a CREATE TABLE statement with uncommented invalid options will
fail with an error, unless the IGNORE_BAD_TABLE_OPTIONS SQL_MODE is in effect.

Note that SHOW CREATE TABLE is not meant to provide metadata about a table. It
provides information about how the table was declared, but the real table
structure could differ a bit. For example, if an index has been declared as
HASH, the CREATE TABLE statement returned by SHOW CREATE TABLE will declare
that index as HASH; however, it is possible that the index is in fact a BTREE,
because the storage engine does not support HASH.

MariaDB starting with 10.2.1
----------------------------
MariaDB 10.2.1 permits TEXT and BLOB data types to be assigned a DEFAULT
value. As a result, from MariaDB 10.2.1, SHOW CREATE TABLE will append a
DEFAULT NULL to nullable TEXT or BLOB fields if no specific default is
provided.

MariaDB starting with 10.2.2
----------------------------
From MariaDB 10.2.2, numbers are no longer quoted in the DEFAULT clause in
SHOW CREATE statement. Previously, MariaDB quoted numbers.

Index Order
-----------

Indexes are sorted and displayed in the following order, which may differ from
the order of the CREATE TABLE statement.

* PRIMARY KEY
* UNIQUE keys where all column are NOT NULL
* UNIQUE keys that don't contain partial segments
* Other UNIQUE keys
* LONG UNIQUE keys
* Normal keys
* Fulltext keys

See sql/sql_table.cc for details.

Examples
--------

SHOW CREATE TABLE t\G
*************************** 1. row ***************************
   Table: t
Create Table: CREATE TABLE `t` (
 `id` int(11) NOT NULL AUTO_INCREMENT,
 `s` char(60) DEFAULT NULL,
 PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1

With sql_quote_show_create off:

SHOW CREATE TABLE t\G
*************************** 1. row ***************************
   Table: t
Create Table: CREATE TABLE t (
 id int(11) NOT NULL AUTO_INCREMENT,
 s char(60) DEFAULT NULL,
 PRIMARY KEY (id)
) ENGINE=InnoDB DEFAULT CHARSET=latin1

Unquoted numeric DEFAULTs, from MariaDB 10.2.2:

CREATE TABLE td (link TINYINT DEFAULT 1);

SHOW CREATE TABLE td\G
*************************** 1. row ***************************
   Table: td
Create Table: CREATE TABLE `td` (
 `link` tinyint(4) DEFAULT 1
) ENGINE=InnoDB DEFAULT CHARSET=latin1

Quoted numeric DEFAULTs, until MariaDB 10.2.1:

CREATE TABLE td (link TINYINT DEFAULT 1);

SHOW CREATE TABLE td\G
*************************** 1. row ***************************
   Table: td
Create Table: CREATE TABLE `td` (
 `link` tinyint(4) DEFAULT '1'
) ENGINE=InnoDB DEFAULT CHARSET=latin1

SQL_MODE impacting the output:

SELECT @@sql_mode;
+------------------------------------------------------------------------------
------------+
| @@sql_mode                                                                  
      |
+------------------------------------------------------------------------------
------------+
|
STRICT_TRANS_TABLES,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SU
STITUTION |
+------------------------------------------------------------------------------
------------+

CREATE TABLE `t1` (
   `id` int(11) NOT NULL AUTO_INCREMENT,
   `msg` varchar(100) DEFAULT NULL,
   PRIMARY KEY (`id`)
  ) ENGINE=InnoDB DEFAULT CHARSET=latin1
;

SHOW CREATE TABLE t1\G
*************************** 1. row ***************************
   Table: t1
Create Table: CREATE TABLE `t1` (
 `id` int(11) NOT NULL AUTO_INCREMENT,
 `msg` varchar(100) DEFAULT NULL,
 PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1

SET SQL_MODE=ORACLE;

SHOW CREATE TABLE t1\G
*************************** 1. row ***************************
   Table: t1
Create Table: CREATE TABLE "t1" (
 "id" int(11) NOT NULL,
 "msg" varchar(100) DEFAULT NULL,
 PRIMARY KEY ("id")

URL: https://mariadb.com/kb/en/show-create-table/https://mariadb.com/kb/en/show-create-table/j�^��s���S'SHOW COLUMNSSyntax
------

SHOW [FULL] {COLUMNS | FIELDS} FROM tbl_name [FROM db_name]
  [LIKE 'pattern' | WHERE expr]

Description
-----------

SHOW COLUMNS displays information about the columns in a given table. It also
works for views. The LIKE clause, if present on its own, indicates which
column names to match. The WHERE and LIKE clauses can be given to select rows
using more general conditions, as discussed in Extended SHOW.

If the data types differ from what you expect them to be based on a CREATE
TABLE statement, note that MariaDB sometimes changes data types when you
create or alter a table. The conditions under which this occurs are described
in the Silent Column Changes article.

The FULL keyword causes the output to include the column collation and
comments, as well as the privileges you have for each column.

You can use db_name.tbl_name as an alternative to the tbl_name FROM db_name
syntax. In other words, these two statements are equivalent:

SHOW COLUMNS FROM mytable FROM mydb;
SHOW COLUMNS FROM mydb.mytable;

SHOW COLUMNS displays the following values for each table column:

Field indicates the column name.

Type indicates the column data type.

Collation indicates the collation for non-binary string columns, or NULL for
other columns. This value is displayed only if you use the FULL keyword.

The Null field contains YES if NULL values can be stored in the column, NO if
not.

The Key field indicates whether the column is indexed:

* If Key is empty, the column either is not indexed or is indexed only as a
 secondary column in a multiple-column, non-unique index.
* If Key is PRI, the column is a PRIMARY KEY or
 is one of the columns in a multiple-column PRIMARY KEY.
* If Key is UNI, the column is the first column of a unique-valued
 index that cannot contain NULL values.
* If Key is MUL, multiple occurrences of a given value are allowed
 within the column. The column is the first column of a non-unique index or a
 unique-valued index that can contain NULL values.

If more than one of the Key values applies to a given column of a table, Key
displays the one with the highest priority, in the order PRI, UNI, MUL.

A UNIQUE index may be displayed as PRI if it cannot contain NULL values and
there is no PRIMARY KEY in the table. A UNIQUE index may display as MUL if
several columns form a composite UNIQUE index; although the combination of the
columns is unique, each column can still hold multiple occurrences of a given
value.

The Default field indicates the default value that is assigned to the column.

The Extra field contains any additional information that is available about a
given column.

+------------------------+---------------------------------------------------+
| Value                  | Description                                       |
+------------------------+---------------------------------------------------+
| AUTO_INCREMENT         | The column was created with the AUTO_INCREMENT    |
|                        | keyword.                                          |
+------------------------+---------------------------------------------------+
| PERSISTENT             | The column was created with the PERSISTENT        |
|                        | keyword. (New in 5.3)                             |
+------------------------+---------------------------------------------------+
| VIRTUAL                | The column was created with the VIRTUAL keyword.  |
|                        | (New in 5.3)                                      |
+------------------------+---------------------------------------------------+
| on update              | The column is a TIMESTAMP column that is          |
| CURRENT_TIMESTAMP      | automatically updated on INSERT and UPDATE.       |
+------------------------+---------------------------------------------------+

Privileges indicates the privileges you have for the column. This value is
displayed only if you use the FULL keyword.

Comment indicates any comment the column has. This value is displayed only if
you use the FULL keyword.

SHOW FIELDS is a synonym for SHOW COLUMNS. Also DESCRIBE and EXPLAIN can be
used as shortcuts.

You can also list a table's columns with:

mariadb-show db_name tbl_name

See the mariadb-show command for more details.

The DESCRIBE statement provides information similar to SHOW COLUMNS. The
information_schema.COLUMNS table provides similar, but more complete,
information.

The SHOW CREATE TABLE, SHOW TABLE STATUS, and SHOW INDEX statements also
provide information about tables.

Examples
--------

SHOW COLUMNS FROM city;
+------------+----------+------+-----+---------+----------------+
| Field      | Type     | Null | Key | Default | Extra          |
+------------+----------+------+-----+---------+----------------+
| Id         | int(11)  | NO   | PRI | NULL    | auto_increment |
| Name       | char(35) | NO   |     |         |                |
| Country    | char(3)  | NO   | UNI |         |                |
| District   | char(20) | YES  | MUL |         |                |
| Population | int(11)  | NO   |     | 0       |                |
+------------+----------+------+-----+---------+----------------+

SHOW COLUMNS FROM employees WHERE Type LIKE 'Varchar%';
+---------------+-------------+------+-----+---------+-------+
| Field         | Type        | Null | Key | Default | Extra |
+---------------+-------------+------+-----+---------+-------+
| first_name    | varchar(30) | NO   | MUL | NULL    |       |
| last_name     | varchar(40) | NO   |     | NULL    |       |
| position      | varchar(25) | NO   |     | NULL    |       |
| home_address  | varchar(50) | NO   |     | NULL    |       |
| home_phone    | varchar(12) | NO   |     | NULL    |       |
| employee_code | varchar(25) | NO   | UNI | NULL    |       |
+---------------+-------------+------+-----+---------+-------+

URL: https://mariadb.com/kb/en/show-columns/https://mariadb.com/kb/en/show-columns/St�Z4��U
	%SHOW INDEXSyntax
------

SHOW {INDEX | INDEXES | KEYS} 
 FROM tbl_name [FROM db_name]
 [WHERE expr]

Description
-----------

SHOW INDEX returns table index information. The format resembles that of the
SQLStatistics call in ODBC.

You can use db_name.tbl_name as an alternative to the tbl_name FROM db_name
syntax. These two statements are equivalent:

SHOW INDEX FROM mytable FROM mydb;
SHOW INDEX FROM mydb.mytable;

SHOW KEYS and SHOW INDEXES are synonyms for SHOW INDEX.

You can also list a table's indexes with the mariadb-show command:

mariadb-show -k db_name tbl_name

The information_schema.STATISTICS table stores similar information.

The following fields are returned by SHOW INDEX.

+------------------------+---------------------------------------------------+
| Field                  | Description                                       |
+------------------------+---------------------------------------------------+
| Table                  | Table name                                        |
+------------------------+---------------------------------------------------+
| Non_unique             | 1 if the index permits duplicate values, 0 if     |
|                        | values must be unique.                            |
+------------------------+---------------------------------------------------+
| Key_name               | Index name. The primary key is always named       |
|                        | PRIMARY.                                          |
+------------------------+---------------------------------------------------+
| Seq_in_index           | The column's sequence in the index, beginning     |
|                        | with 1.                                           |
+------------------------+---------------------------------------------------+
| Column_name            | Column name.                                      |
+------------------------+---------------------------------------------------+
| Collation              | Either A, if the column is sorted in ascending    |
|                        | order in the index, or NULL if it's not sorted.   |
+------------------------+---------------------------------------------------+
| Cardinality            | Estimated number of unique values in the index.   |
|                        | The cardinality statistics are calculated at      |
|                        | various times, and can help the optimizer make    |
|                        | improved decisions.                               |
+------------------------+---------------------------------------------------+
| Sub_part               | NULL if the entire column is included in the      |
|                        | index, or the number of included characters if    |
|                        | not.                                              |
+------------------------+---------------------------------------------------+
| Packed                 | NULL if the index is not packed, otherwise how    |
|                        | the index is packed.                              |
+------------------------+---------------------------------------------------+
| Null                   | NULL if NULL values are permitted in the column,  |
|                        | an empty string if NULLs are not permitted.       |
+------------------------+---------------------------------------------------+
| Index_type             | The index type, which can be BTREE, FULLTEXT,     |
|                        | HASH or RTREE. See Storage Engine Index Types.    |
+------------------------+---------------------------------------------------+
| Comment                | Other information, such as whether the index is   |
|                        | disabled.                                         |
+------------------------+---------------------------------------------------+
| Index_comment          | Contents of the COMMENT attribute when the index  |
|                        | was created.                                      |
+------------------------+---------------------------------------------------+
| Ignored                | Whether or not an index will be ignored by the    |
|                        | optimizer. See Ignored Indexes. From MariaDB      |
|                        | 10.6.0.                                           |
+------------------------+---------------------------------------------------+

The WHERE and LIKE clauses can be given to select rows using more general
conditions, as discussed in Extended SHOW.

Examples
--------

CREATE TABLE IF NOT EXISTS `employees_example` (
 `id` int(11) NOT NULL AUTO_INCREMENT,
 `first_name` varchar(30) NOT NULL,
 `last_name` varchar(40) NOT NULL,
 `position` varchar(25) NOT NULL,
 `home_address` varchar(50) NOT NULL,
 `home_phone` varchar(12) NOT NULL,
 `employee_code` varchar(25) NOT NULL,
 PRIMARY KEY (`id`),
 UNIQUE KEY `employee_code` (`employee_code`),
 KEY `first_name` (`first_name`,`last_name`)
) ENGINE=Aria;

INSERT INTO `employees_example` (`first_name`, `last_name`, `position`,
`home_address`, `home_phone`, `employee_code`)
 VALUES
 ('Mustapha', 'Mond', 'Chief Executive Officer', '692 Promiscuous Plaza',
'326-555-3492', 'MM1'),
 ('Henry', 'Foster', 'Store Manager', '314 Savage Circle', '326-555-3847',
'HF1'),
 ('Bernard', 'Marx', 'Cashier', '1240 Ambient Avenue', '326-555-8456', 'BM1'),
 ('Lenina', 'Crowne', 'Cashier', '281 Bumblepuppy Boulevard', '328-555-2349',
'LC1'),
 ('Fanny', 'Crowne', 'Restocker', '1023 Bokanovsky Lane', '326-555-6329',
'FC1'),
 ('Helmholtz', 'Watson', 'Janitor', '944 Soma Court', '329-555-2478', 'HW1');

SHOW INDEXES FROM employees_example\G
*************************** 1. row ***************************
    Table: employees_example
 Non_unique: 0
  Key_name: PRIMARY
 Seq_in_index: 1
 Column_name: id
  Collation: A
 Cardinality: 6
  Sub_part: NULL
   Packed: NULL
    Null:
 Index_type: BTREE
   Comment:
Index_comment: 
   Ignored: NO
*************************** 2. row ***************************
    Table: employees_example
 Non_unique: 0
  Key_name: employee_code
 Seq_in_index: 1
 Column_name: employee_code
  Collation: A
 Cardinality: 6
  Sub_part: NULL
   Packed: NULL
    Null:
 Index_type: BTREE
   Comment:
Index_comment: 
   Ignored: NO
*************************** 3. row ***************************
    Table: employees_example
 Non_unique: 1
  Key_name: first_name
 Seq_in_index: 1
 Column_name: first_name
  Collation: A
 Cardinality: NULL
  Sub_part: NULL
   Packed: NULL
    Null:
 Index_type: BTREE
   Comment:
Index_comment: 
   Ignored: NO
*************************** 4. row ***************************
    Table: employees_example
 Non_unique: 1
  Key_name: first_name
 Seq_in_index: 2
 Column_name: last_name
  Collation: A
 Cardinality: NULL
  Sub_part: NULL
   Packed: NULL
    Null:
 Index_type: BTREE
   Comment:
Index_comment: 
   Ignored: NO

URL: https://mariadb.com/kb/en/show-index/https://mariadb.com/kb/en/show-index/FoFAq��
Va'SHOW EXPLAINSyntax
------

SHOW EXPLAIN [FORMAT=JSON] FOR <connection_id>;
EXPLAIN [FORMAT=JSON] FOR CONNECTION <connection_id>;

Description
-----------

The SHOW EXPLAIN command allows one to get an EXPLAIN (that is, a description
of a query plan) of a query running in a certain connection.

SHOW EXPLAIN FOR <connection_id>;

will produce an EXPLAIN output for the query that connection number
connection_id is running. The connection id can be obtained with SHOW
PROCESSLIST.

SHOW EXPLAIN FOR 1;
+------+-------------+-------+-------+---------------+------+---------+------+-
-------+-------------+
| id   | select_type | table | type  | possible_keys | key  | key_len | ref  |
rows    | Extra       |
+------+-------------+-------+-------+---------------+------+---------+------+-
-------+-------------+
|    1 | SIMPLE      | tbl   | index | NULL          | a    | 5       | NULL |
1000107 | Using index |
+------+-------------+-------+-------+---------------+------+---------+------+-
-------+-------------+
1 row in set, 1 warning (0.00 sec)

The output is always accompanied with a warning which shows the query the
target connection is running (this shows what the EXPLAIN is for):

SHOW WARNINGS;
+-------+------+------------------------+
| Level | Code | Message                |
+-------+------+------------------------+
| Note  | 1003 | select sum(a) from tbl |
+-------+------+------------------------+
1 row in set (0.00 sec)

EXPLAIN FOR CONNECTION
----------------------

MariaDB starting with 10.9
--------------------------
The EXPLAIN FOR CONNECTION syntax was added for MySQL compatibility.

FORMAT=JSON
-----------

MariaDB starting with 10.9
--------------------------
SHOW EXPLAIN [FORMAT=JSON] FOR <connection_id> extends SHOW EXPLAIN to return
more detailed JSON output.

Possible Errors
---------------

The output can be only produced if the target connection is currently running
a query, which has a ready query plan. If this is not the case, the output
will be:

SHOW EXPLAIN FOR 2;
ERROR 1932 (HY000): Target is not running an EXPLAINable command

You will get this error when:

* the target connection is not running a command for which one can run EXPLAIN
* the target connection is running a command for which one can run EXPLAIN, but
there is no query plan yet (for example, tables are open and locks are
 acquired before the query plan is produced)

Differences Between SHOW EXPLAIN and EXPLAIN Outputs
----------------------------------------------------

Background
----------

In MySQL, EXPLAIN execution takes a slightly different route from the way the
real query (typically the SELECT) is optimized. This is unfortunate, and has
caused a number of bugs in EXPLAIN. (For example, see MDEV-326, MDEV-410, and
lp:1013343. lp:992942 is not directly about EXPLAIN, but it also would not
have existed if MySQL didn't try to delete parts of a query plan in the middle
of the query)

SHOW EXPLAIN examines a running SELECT, and hence its output may be slightly
different from what EXPLAIN SELECT would produce. We did our best to make sure
that either the difference is negligible, or SHOW EXPLAIN's output is closer
to reality than EXPLAIN's output.

List of Recorded Differences
----------------------------

* SHOW EXPLAIN may have Extra='no matching row in const table', where  EXPLAIN
would produce Extra='Impossible WHERE ...'
* For queries with subqueries, SHOW EXPLAIN may print select_type==PRIMARY
where regular EXPLAIN used to print select_type==SIMPLE, or vice versa.

Required Permissions
--------------------

Running SHOW EXPLAIN requires the same permissions as running SHOW PROCESSLIST
would.

URL: https://mariadb.com/kb/en/show-explain/https://mariadb.com/kb/en/show-explain/Xd&BACKUP LOCKMariaDB starting with 10.4.2
----------------------------
The BACKUP LOCK command was introduced in MariaDB 10.4.2.

BACKUP LOCK blocks a table from DDL statements. This is mainly intended to be
used by tools like mariabackup that need to ensure there are no DDLs on a
table while the table files are opened. For example, for an Aria table that
stores data in 3 files with extensions .frm, .MAI and .MAD. Normal read/write
operations can continue as normal.

Syntax
------

To lock a table:

BACKUP LOCK table_name

To unlock a table:

BACKUP UNLOCK

Usage in a Backup Tool
----------------------

BACKUP LOCK [database.]table_name;
 - Open all files related to a table (for example, t.frm, t.MAI and t.MYD)
BACKUP UNLOCK;
- Copy data
- Close files

This ensures that all files are from the same generation, that is created at
the same time by the MariaDB server. This works, because the open files will
point to the original table files which will not be affected if there is any
ALTER TABLE while copying the files.

Privileges
----------

BACKUP LOCK requires the RELOAD privilege.

Notes
-----

* The idea is that the BACKUP LOCK should be held for as short a time as
possible by the backup tool. The time to take an uncontested lock is very
short! One can easily do 50,000 locks/unlocks per second on low end hardware.
* One should use different connections for BACKUP STAGE commands and BACKUP
LOCK.

Implementation
--------------

* Internally, BACKUP LOCK is implemented by taking an MDLSHARED_HIGH_PRIO MDL
lock on the table object, which protects the table from any DDL operations.

URL: https://mariadb.com/kb/en/backup-lock/https://mariadb.com/kb/en/backup-lock/���Sܯ���W�'BACKUP STAGEMariaDB starting with 10.4.1
----------------------------
The BACKUP STAGE commands were introduced in MariaDB 10.4.1.

The BACKUP STAGE commands are a set of commands to make it possible to make an
efficient external backup tool.

Syntax
------

BACKUP STAGE [START | FLUSH | BLOCK_DDL | BLOCK_COMMIT | END ]

In the following text, a transactional table means InnoDB or "InnoDB-like
engine with redo log that can lock redo purges and can be copied without locks
by an outside process".

Goals with BACKUP STAGE Commands
--------------------------------

* To be able to do a majority of the backup with the minimum possible server
locks. Especially for transactional tables (InnoDB, MyRocks etc) there is only
need for a very short block of new commits while copying statistics and log
tables.
* DDL are only needed to be blocked for a very short duration of the backup
while mariabackup is copying the tables affected by DDL during the initial
part of the backup.
* Most non transactional tables (those that are not in use) will be copied
during BACKUP STAGE START.  The exceptions are system statistic and log tables
that are not blocked during the backup until BLOCK_COMMIT.
* Should work efficiently with backup tools that use disk snapshots.
* Should work as efficiently as possible for all table types that store data
on the local disks.
* As little copying as possible under higher level stages/locks. For example,
.frm (dictionary) and .trn (trigger) files should be copying while copying the
table data.

BACKUP STAGE Commands
---------------------

BACKUP STAGE START
------------------

The START stage is designed for the following tasks:

* Blocks purge of redo files for storage engines that needs this (Aria)
* Start logging of DDL commands into 'datadir'/ddl.log. This may take a short
time as the command has to wait until there are no active DDL commands.

BACKUP STAGE FLUSH
------------------

The FLUSH stage is designed for the following tasks:

* FLUSH all changes for inactive non-transactional tables, except for
statistics and log tables.
* Close all tables that are not in use, to ensure they are marked as closed
for the backup.
* BLOCK all new write locks for all non transactional tables (except
statistics and log tables).  The command will not wait for tables that are in
use by read-only transactions.

DDLs don't have to be blocked at this stage as they can't cause the table to
be in an inconsistent state. This is true also for non-transactional tables.

BACKUP STAGE BLOCK_DDL
----------------------

The BLOCK_DDL stage is designed for the following tasks:

* Wait for all statements using write locked non-transactional tables to end.
* Blocks CREATE TABLE, DROP TABLE, TRUNCATE TABLE, and RENAME TABLE.
* Blocks also start off a new ALTER TABLE and the final rename phase of ALTER
TABLE. Running ALTER TABLES are not blocked.

BACKUP STAGE BLOCK_COMMIT
-------------------------

The BLOCK_COMMIT stage is designed for the following tasks:

* Lock the binary log and commit/rollback to ensure that no changes are
committed to any tables. If there are active commits or data to be copied to
the binary log this will be allowed to finish.  Active transactions will not
affect BLOCK_COMMIT.
* This doesn't lock temporary tables that are not used by replication. However
these will be blocked when it's time to write to the binary log.
* Lock system log tables and statistics tables, flush them and mark them
closed.

When the BLOCK_COMMIT's stages return, this is the 'backup time'. Everything
committed will be in the backup and everything not committed will roll back.

Transactional engines will continue to do changes to the redo log during the
BLOCK COMMIT stage, but this is not important as all of these will roll back
later as the changes will not be committed.

BACKUP STAGE END
----------------

The END stage is designed for the following tasks:

* End DDL logging
* Free resources

Using BACKUP STAGE Commands with Backup Tools
---------------------------------------------

Using BACKUP STAGE Commands with Mariabackup
--------------------------------------------

The BACKUP STAGE commands are a set of commands to make it possible to make an
efficient external backup tool. How Mariabackup uses these commands depends on
whether you are using the version that is bundled with MariaDB Community
Server or the version that is bundled with MariaDB Enterprise Server. See
Mariabackup and BACKUP STAGE Commands for some examples on how Mariabackup
uses these commands.

If you would like to use a version of Mariabackup that uses the BACKUP STAGE
commands in an efficient way, then one option is to use MariaDB Enterprise
Backup that is bundled with MariaDB Enterprise Server.

Using BACKUP STAGE Commands with Storage Snapshots
--------------------------------------------------

The BACKUP STAGE commands are a set of commands to make it possible to make an
efficient external backup tool. These commands could even be used by tools
that perform backups by taking a snapshot of a file system, SAN, or some other
kind of storage device. See Storage Snapshots and BACKUP STAGE Commands for
some examples on how to use each BACKUP STAGE command in an efficient way.

Privileges
----------

BACKUP STAGE requires the RELOAD privilege.

Notes
-----

* Only one connection can run BACKUP STAGE START. If a second connection
tries, it will wait until the first one has executed BACKUP STAGE END.
* If the user skips a BACKUP STAGE, then all intermediate backup stages will
automatically be run. This will allow us to add new stages within the BACKUP
STAGE hierarchy in the future with even more precise locks without causing
problems for tools using an earlier version of the BACKUP STAGE implementation.
* One can use the max_statement_time or lock_wait_timeout system variables to
ensure that a BACKUP STAGE command doesn't block the server too long.
* DDL logging will only be available in MariaDB Enterprise Server 10.2 and
later.
* A disconnect will automatically release backup stages.
* There is no easy way to see which is the current stage.

URL: https://mariadb.com/kb/en/backup-stage/https://mariadb.com/kb/en/backup-stage/<����8[{2FLUSH TABLES FOR EXPORTSyntax
------

FLUSH TABLES table_name [, table_name] FOR EXPORT

Description
-----------

FLUSH TABLES ... FOR EXPORT flushes changes to the specified tables to disk so
that binary copies can be made while the server is still running. This works
for Archive, Aria, CSV, InnoDB, MyISAM, MERGE, and XtraDB tables.

The table is read locked until one has issued UNLOCK TABLES.

If a storage engine does not support FLUSH TABLES FOR EXPORT, a 1031 error
(SQLSTATE 'HY000') is produced.

If FLUSH TABLES ... FOR EXPORT is in effect in the session, the following
statements will produce an error if attempted:

* FLUSH TABLES WITH READ LOCK
* FLUSH TABLES ... WITH READ LOCK
* FLUSH TABLES ... FOR EXPORT
* Any statement trying to update any table

If any of the following statements is in effect in the session, attempting
FLUSH TABLES ... FOR EXPORT will produce an error.

* FLUSH TABLES ... WITH READ LOCK
* FLUSH TABLES ... FOR EXPORT
* LOCK TABLES ... READ
* LOCK TABLES ... WRITE

FLUSH FOR EXPORT is not written to the binary log.

This statement requires the RELOAD and the LOCK TABLES privileges.

If one of the specified tables cannot be locked, none of the tables will be
locked.

If a table does not exist, an error like the following will be produced:

ERROR 1146 (42S02): Table 'test.xxx' doesn't exist

If a table is a view, an error like the following will be produced:

ERROR 1347 (HY000): 'test.v' is not BASE TABLE

Example
-------

FLUSH TABLES test.t1 FOR EXPORT;
#  Copy files related to the table (see below)
UNLOCK TABLES;

For a full description, please see copying MariaDB tables.

URL: https://mariadb.com/kb/en/flush-tables-for-export/https://mariadb.com/kb/en/flush-tables-for-export/\/SHOW RELAYLOG EVENTSThe terms master and slave have historically been used in replication, but the
terms terms primary and replica are now preferred. The old terms are used
still used in parts of the documentation, and in MariaDB commands, although
MariaDB 10.5 has begun the process of renaming. The documentation process is
ongoing. See MDEV-18777 to follow progress on this effort.

Syntax
------

SHOW RELAYLOG ['connection_name'] EVENTS
  [IN 'log_name'] [FROM pos] [LIMIT [offset,] row_count]
  [ FOR CHANNEL 'channel_name']

Description
-----------

On replicas, this command shows the events in the relay log. If 'log_name' is
not specified, the first relay log is shown.

Syntax for the LIMIT clause is the same as for SELECT ... LIMIT.

Using the LIMIT clause is highly recommended because the SHOW RELAYLOG EVENTS
command returns the complete contents of the relay log, which can be quite
large.

This command does not return events related to setting user and system
variables. If you need those, use mariadb-binlog.

On the primary, this command does nothing.

Requires the REPLICA MONITOR privilege (>= MariaDB 10.5.9), the REPLICATION
SLAVE ADMIN privilege (>= MariaDB 10.5.2) or the REPLICATION SLAVE privilege
(<= MariaDB 10.5.1).

connection_name
---------------

If there is only one nameless primary, or the default primary (as specified by
the default_master_connection system variable) is intended, connection_name
can be omitted. If provided, the SHOW RELAYLOG statement will apply to the
specified primary. connection_name is case-insensitive.

MariaDB starting with 10.7.0
----------------------------
The FOR CHANNEL keyword was added for MySQL compatibility. This is identical
as using the channel_name directly after SHOW RELAYLOG.

URL: https://mariadb.com/kb/en/show-relaylog-events/https://mariadb.com/kb/en/show-relaylog-events/^{-SHOW MASTER STATUSSyntax
------

SHOW MASTER STATUS
SHOW BINLOG STATUS -- From MariaDB 10.5.2

Description
-----------

Provides status information about the binary log files of the primary.

This statement requires the SUPER privilege, the REPLICATION_CLIENT privilege,
or, from MariaDB 10.5.2, the BINLOG MONITOR privilege.

To see information about the current GTIDs in the binary log, use the
gtid_binlog_pos variable.

SHOW MASTER STATUS was renamed to SHOW BINLOG STATUS in MariaDB 10.5.2, but
the old name remains an alias for compatibility purposes.

Example
-------

SHOW MASTER STATUS;
+--------------------+----------+--------------+------------------+
| File               | Position | Binlog_Do_DB | Binlog_Ignore_DB |
+--------------------+----------+--------------+------------------+
| mariadb-bin.000016 |      475 |              |                  |
+--------------------+----------+--------------+------------------+
SELECT @@global.gtid_binlog_pos;
+--------------------------+
| @@global.gtid_binlog_pos |
+--------------------------+
| 0-1-2                    |
+--------------------------+

URL: https://mariadb.com/kb/en/show-binlog-status/https://mariadb.com/kb/en/show-binlog-status/_q-SHOW SLAVE HOSTSSyntax
------

SHOW SLAVE HOSTS
SHOW REPLICA HOSTS -- from MariaDB 10.5.1

Description
-----------

This command is run on the primary and displays a list of replicas that are
currently registered with it. Only replicas started with the
--report-host=host_name option are visible in this list.

The output looks like this:

SHOW SLAVE HOSTS;
+------------+-----------+------+-----------+
| Server_id  | Host      | Port | Master_id |
+------------+-----------+------+-----------+
|  192168010 | iconnect2 | 3306 | 192168011 |
| 1921680101 | athena    | 3306 | 192168011 |
+------------+-----------+------+-----------+

* Server_id: The unique server ID of the replica server, as configured in the
server's option file, or on the command line with --server-id=value.
* Host: The host name of the replica server, as configured in the server's
option file, or on the command line with --report-host=host_name. Note that
this can differ from the machine name as configured in the operating system.
* Port: The port the replica server is listening on.
* Master_id: The unique server ID of the primary server that the replica
server is replicating from.

Some MariaDB and MySQL versions report another variable, rpl_recovery_rank.
This variable was never used, and was eventually removed in MariaDB 10.1.2 .

Requires the REPLICATION MASTER ADMIN privilege (>= MariaDB 10.5.2) or the
REPLICATION SLAVE privilege (<= MariaDB 10.5.1).

SHOW REPLICA HOSTS
------------------

MariaDB starting with 10.5.1
----------------------------
SHOW REPLICA HOSTS is an alias for SHOW SLAVE HOSTS from MariaDB 10.5.1.

URL: https://mariadb.com/kb/en/show-replica-hosts/https://mariadb.com/kb/en/show-replica-hosts/��0��R���_��`R
'SHOW PLUGINSSyntax
------

SHOW PLUGINS;

Description
-----------

SHOW PLUGINS displays information about installed plugins. The Library column
indicates the plugin library - if it is NULL, the plugin is built-in and
cannot be uninstalled.

The PLUGINS table in the information_schema database contains more detailed
information.

For specific information about storage engines (a particular type of plugin),
see the information_schema.ENGINES table and the SHOW ENGINES statement.

Examples
--------

SHOW PLUGINS;
+----------------------------+----------+--------------------+-------------+---
-----+
| Name                       | Status   | Type               | Library     |
License |
+----------------------------+----------+--------------------+-------------+---
-----+
| binlog                     | ACTIVE   | STORAGE ENGINE     | NULL        |
GPL     |
| mysql_native_password      | ACTIVE   | AUTHENTICATION     | NULL        |
GPL     |
| mysql_old_password         | ACTIVE   | AUTHENTICATION     | NULL        |
GPL     |
| MRG_MyISAM                 | ACTIVE   | STORAGE ENGINE     | NULL        |
GPL     |
| MyISAM                     | ACTIVE   | STORAGE ENGINE     | NULL        |
GPL     |
| CSV                        | ACTIVE   | STORAGE ENGINE     | NULL        |
GPL     |
| MEMORY                     | ACTIVE   | STORAGE ENGINE     | NULL        |
GPL     |
| FEDERATED                  | ACTIVE   | STORAGE ENGINE     | NULL        |
GPL     |
| PERFORMANCE_SCHEMA         | ACTIVE   | STORAGE ENGINE     | NULL        |
GPL     |
| Aria                       | ACTIVE   | STORAGE ENGINE     | NULL        |
GPL     |
| InnoDB                     | ACTIVE   | STORAGE ENGINE     | NULL        |
GPL     |
| INNODB_TRX                 | ACTIVE   | INFORMATION SCHEMA | NULL        |
GPL     |
...
| INNODB_SYS_FOREIGN         | ACTIVE   | INFORMATION SCHEMA | NULL        |
GPL     |
| INNODB_SYS_FOREIGN_COLS    | ACTIVE   | INFORMATION SCHEMA | NULL        |
GPL     |
| SPHINX                     | ACTIVE   | STORAGE ENGINE     | NULL        |
GPL     |
| ARCHIVE                    | ACTIVE   | STORAGE ENGINE     | NULL        |
GPL     |
| BLACKHOLE                  | ACTIVE   | STORAGE ENGINE     | NULL        |
GPL     |
| FEEDBACK                   | DISABLED | INFORMATION SCHEMA | NULL        |
GPL     |
| partition                  | ACTIVE   | STORAGE ENGINE     | NULL        |
GPL     |
| pam                        | ACTIVE   | AUTHENTICATION     | auth_pam.so |
GPL     |
+----------------------------+----------+--------------------+-------------+---
-----+

URL: https://mariadb.com/kb/en/show-plugins/https://mariadb.com/kb/en/show-plugins/a�.SHOW PLUGINS SONAMESyntax
------

SHOW PLUGINS SONAME { library | LIKE 'pattern' | WHERE expr };

Description
-----------

SHOW PLUGINS SONAME displays information about compiled-in and all server
plugins in the plugin_dir directory, including plugins that haven't been
installed.

Examples
--------

SHOW PLUGINS SONAME 'ha_example.so';
+----------+---------------+----------------+---------------+---------+
| Name     | Status        | Type           | Library       | License |
+----------+---------------+----------------+---------------+---------+
| EXAMPLE  | NOT INSTALLED | STORAGE ENGINE | ha_example.so | GPL     |
| UNUSABLE | NOT INSTALLED | DAEMON         | ha_example.so | GPL     |
+----------+---------------+----------------+---------------+---------+

There is also a corresponding information_schema table, called ALL_PLUGINS,
which contains more complete information.

URL: https://mariadb.com/kb/en/show-plugins-soname/https://mariadb.com/kb/en/show-plugins-soname/c�,SET CHARACTER SETSyntax
------

SET {CHARACTER SET | CHARSET}
  {charset_name | DEFAULT}

Description
-----------

Sets the character_set_client and character_set_results session system
variables to the specified character set and collation_connection to the value
of collation_database, which implicitly sets character_set_connection to the
value of character_set_database.

This maps all strings sent between the current client and the server with the
given mapping.

Example
-------

SHOW VARIABLES LIKE 'character_set\_%';
+--------------------------+--------+
| Variable_name            | Value  |
+--------------------------+--------+
| character_set_client     | utf8   |
| character_set_connection | utf8   |
| character_set_database   | latin1 |
| character_set_filesystem | binary |
| character_set_results    | utf8   |
| character_set_server     | latin1 |
| character_set_system     | utf8   |
+--------------------------+--------+

SHOW VARIABLES LIKE 'collation%';
+----------------------+-------------------+
| Variable_name        | Value             |
+----------------------+-------------------+
| collation_connection | utf8_general_ci   |
| collation_database   | latin1_swedish_ci |
| collation_server     | latin1_swedish_ci |
+----------------------+-------------------+

SET CHARACTER SET utf8mb4;

SHOW VARIABLES LIKE 'character_set\_%';
+--------------------------+---------+
| Variable_name            | Value   |
+--------------------------+---------+
| character_set_client     | utf8mb4 |
| character_set_connection | latin1  |
| character_set_database   | latin1  |
| character_set_filesystem | binary  |
| character_set_results    | utf8mb4 |
| character_set_server     | latin1  |
| character_set_system     | utf8    |
+--------------------------+---------+

SHOW VARIABLES LIKE 'collation%';
+----------------------+-------------------+
| Variable_name        | Value             |
+----------------------+-------------------+
| collation_connection | latin1_swedish_ci |
| collation_database   | latin1_swedish_ci |
| collation_server     | latin1_swedish_ci |
+----------------------+-------------------+

URL: https://mariadb.com/kb/en/set-character-set/https://mariadb.com/kb/en/set-character-set/���
��
�+���WbfSETSyntax
------

SET variable_assignment [, variable_assignment] ...

variable_assignment:
   user_var_name = expr
  | [GLOBAL | SESSION] system_var_name = expr
  | [@@global. | @@session. | @@]system_var_name = expr

One can also set a user variable in any expression with this syntax:

user_var_name:= expr

Description
-----------

The SET statement assigns values to different types of variables that affect
the operation of the server or your client. Older versions of MySQL employed
SET OPTION, but this syntax was deprecated in favor of SET without OPTION, and
was removed in MariaDB 10.0.

Changing a system variable by using the SET statement does not make the change
permanently. To do so, the change must be made in a configuration file.

For setting variables on a per-query basis, see SET STATEMENT.

See SHOW VARIABLES for documentation on viewing server system variables.

See Server System Variables for a list of all the system variables.

GLOBAL / SESSION
----------------

When setting a system variable, the scope can be specified as either GLOBAL or
SESSION.

A global variable change affects all new sessions. It does not affect any
currently open sessions, including the one that made the change.

A session variable change affects the current session only.

If the variable has a session value, not specifying either GLOBAL or SESSION
will be the same as specifying SESSION. If the variable only has a global
value, not specifying GLOBAL or SESSION will apply to the change to the global
value.

DEFAULT
-------

Setting a global variable to DEFAULT will restore it to the server default,
and setting a session variable to DEFAULT will restore it to the current
global value.

Examples
--------

* innodb_sync_spin_loops is a global variable.
* skip_parallel_replication is a session variable.
* max_error_count is both global and session.

SELECT VARIABLE_NAME, SESSION_VALUE, GLOBAL_VALUE FROM
 INFORMATION_SCHEMA.SYSTEM_VARIABLES WHERE 
 VARIABLE_NAME IN ('max_error_count', 'skip_parallel_replication',
'innodb_sync_spin_loops');
+---------------------------+---------------+--------------+
| VARIABLE_NAME             | SESSION_VALUE | GLOBAL_VALUE |
+---------------------------+---------------+--------------+
| MAX_ERROR_COUNT           | 64            | 64           |
| SKIP_PARALLEL_REPLICATION | OFF           | NULL         |
| INNODB_SYNC_SPIN_LOOPS    | NULL          | 30           |
+---------------------------+---------------+--------------+

Setting the session values:

SET max_error_count=128;Query OK, 0 rows affected (0.000 sec)

SET skip_parallel_replication=ON;Query OK, 0 rows affected (0.000 sec)

SET innodb_sync_spin_loops=60;
ERROR 1229 (HY000): Variable 'innodb_sync_spin_loops' is a GLOBAL variable 
 and should be set with SET GLOBAL

SELECT VARIABLE_NAME, SESSION_VALUE, GLOBAL_VALUE FROM
 INFORMATION_SCHEMA.SYSTEM_VARIABLES WHERE 
 VARIABLE_NAME IN ('max_error_count', 'skip_parallel_replication',
'innodb_sync_spin_loops');
+---------------------------+---------------+--------------+
| VARIABLE_NAME             | SESSION_VALUE | GLOBAL_VALUE |
+---------------------------+---------------+--------------+
| MAX_ERROR_COUNT           | 128           | 64           |
| SKIP_PARALLEL_REPLICATION | ON            | NULL         |
| INNODB_SYNC_SPIN_LOOPS    | NULL          | 30           |
+---------------------------+---------------+--------------+

Setting the global values:

SET GLOBAL max_error_count=256;

SET GLOBAL skip_parallel_replication=ON;
ERROR 1228 (HY000): Variable 'skip_parallel_replication' is a SESSION variable 
 and can't be used with SET GLOBAL

SET GLOBAL innodb_sync_spin_loops=120;

SELECT VARIABLE_NAME, SESSION_VALUE, GLOBAL_VALUE FROM
 INFORMATION_SCHEMA.SYSTEM_VARIABLES WHERE 
 VARIABLE_NAME IN ('max_error_count', 'skip_parallel_replication',
'innodb_sync_spin_loops');
+---------------------------+---------------+--------------+
| VARIABLE_NAME             | SESSION_VALUE | GLOBAL_VALUE |
+---------------------------+---------------+--------------+
| MAX_ERROR_COUNT           | 128           | 256          |
| SKIP_PARALLEL_REPLICATION | ON            | NULL         |
| INNODB_SYNC_SPIN_LOOPS    | NULL          | 120          |
+---------------------------+---------------+--------------+

SHOW VARIABLES will by default return the session value unless the variable is
global only.

SHOW VARIABLES LIKE 'max_error_count';
+-----------------+-------+
| Variable_name   | Value |
+-----------------+-------+
| max_error_count | 128   |
+-----------------+-------+

SHOW VARIABLES LIKE 'skip_parallel_replication';
+---------------------------+-------+
| Variable_name             | Value |
+---------------------------+-------+
| skip_parallel_replication | ON    |
+---------------------------+-------+

SHOW VARIABLES LIKE 'innodb_sync_spin_loops';
+------------------------+-------+
| Variable_name          | Value |
+------------------------+-------+
| innodb_sync_spin_loops | 120   |
+------------------------+-------+

Using the inplace syntax:

SELECT (@a:=1);
+---------+
| (@a:=1) |
+---------+
|       1 |
+---------+

SELECT @a;
+------+
| @a   |
+------+
|    1 |
+------+

URL: https://mariadb.com/kb/en/set/https://mariadb.com/kb/en/set/�T�\���d	�$SET NAMESSyntax
------

SET NAMES {'charset_name'
  [COLLATE 'collation_name'] | DEFAULT}

Description
-----------

Sets the character_set_client, character_set_connection, character_set_results
and, implicitly, the collation_connection session system variables to the
specified character set and collation.

This determines which character set the client will use to send statements to
the server, and the server will use for sending results back to the client.

ucs2, utf16, utf16le and utf32 are not valid character sets for SET NAMES, as
they cannot be used as client character sets.

The collation clause is optional. If not defined (or if DEFAULT is specified),
the default collation for the character set will be used.

Quotes are optional for the character set or collation clauses.

Examples
--------

SELECT VARIABLE_NAME, SESSION_VALUE 
 FROM INFORMATION_SCHEMA.SYSTEM_VARIABLES WHERE
 VARIABLE_NAME LIKE 'character_set_c%' OR
 VARIABLE_NAME LIKE 'character_set_re%' OR
 VARIABLE_NAME LIKE 'collation_c%';
+--------------------------+-----------------+
| VARIABLE_NAME            | SESSION_VALUE   |
+--------------------------+-----------------+
| CHARACTER_SET_RESULTS    | utf8            |
| CHARACTER_SET_CONNECTION | utf8            |
| CHARACTER_SET_CLIENT     | utf8            |
| COLLATION_CONNECTION     | utf8_general_ci |
+--------------------------+-----------------+

SET NAMES big5;

SELECT VARIABLE_NAME, SESSION_VALUE 
 FROM INFORMATION_SCHEMA.SYSTEM_VARIABLES WHERE
 VARIABLE_NAME LIKE 'character_set_c%' OR
 VARIABLE_NAME LIKE 'character_set_re%' OR
 VARIABLE_NAME LIKE 'collation_c%';
+--------------------------+-----------------+
| VARIABLE_NAME            | SESSION_VALUE   |
+--------------------------+-----------------+
| CHARACTER_SET_RESULTS    | big5            |
| CHARACTER_SET_CONNECTION | big5            |
| CHARACTER_SET_CLIENT     | big5            |
| COLLATION_CONNECTION     | big5_chinese_ci |
+--------------------------+-----------------+

SET NAMES 'latin1' COLLATE 'latin1_bin';

SELECT VARIABLE_NAME, SESSION_VALUE 
 FROM INFORMATION_SCHEMA.SYSTEM_VARIABLES WHERE
 VARIABLE_NAME LIKE 'character_set_c%' OR
 VARIABLE_NAME LIKE 'character_set_re%' OR
 VARIABLE_NAME LIKE 'collation_c%';
+--------------------------+---------------+
| VARIABLE_NAME            | SESSION_VALUE |
+--------------------------+---------------+
| CHARACTER_SET_RESULTS    | latin1        |
| CHARACTER_SET_CONNECTION | latin1        |
| CHARACTER_SET_CLIENT     | latin1        |
| COLLATION_CONNECTION     | latin1_bin    |
+--------------------------+---------------+

SET NAMES DEFAULT;

SELECT VARIABLE_NAME, SESSION_VALUE 
 FROM INFORMATION_SCHEMA.SYSTEM_VARIABLES WHERE
 VARIABLE_NAME LIKE 'character_set_c%' OR
 VARIABLE_NAME LIKE 'character_set_re%' OR
 VARIABLE_NAME LIKE 'collation_c%';
+--------------------------+-------------------+
| VARIABLE_NAME            | SESSION_VALUE     |
+--------------------------+-------------------+
| CHARACTER_SET_RESULTS    | latin1            |
| CHARACTER_SET_CONNECTION | latin1            |
| CHARACTER_SET_CLIENT     | latin1            |
| COLLATION_CONNECTION     | latin1_swedish_ci |
+--------------------------+-------------------+

URL: https://mariadb.com/kb/en/set-names/https://mariadb.com/kb/en/set-names/f
�	(SET STATEMENTMariaDB starting with 10.1.2
----------------------------
Per-query variables were introduced in MariaDB 10.1.2

SET STATEMENT can be used to set the value of a system variable for the
duration of the statement. It is also possible to set multiple variables.

Syntax
------

SET STATEMENT var1=value1 [, var2=value2, ...] 
 FOR <statement>

where varN is a system variable (list of allowed variables is provided below),
and valueN is a constant literal.

Description
-----------

SET STATEMENT var1=value1 FOR stmt

is roughly equivalent to

SET @save_value=@@var1;
SET SESSION var1=value1;
stmt;
SET SESSION var1=@save_value;

The server parses the whole statement before executing it, so any variables
set in this fashion that affect the parser may not have the expected effect.
Examples include the charset variables, sql_mode=ansi_quotes, etc.

Examples
--------

One can limit statement execution time max_statement_time:

SET STATEMENT max_statement_time=1000 FOR SELECT ... ;

One can switch on/off individual optimizations:

SET STATEMENT optimizer_switch='materialization=off' FOR SELECT ....;

It is possible to enable MRR/BKA for a query:

SET STATEMENT  join_cache_level=6, optimizer_switch='mrr=on'  FOR SELECT ...

Note that it makes no sense to try to set a session variable inside a SET
STATEMENT:

#USELESS STATEMENT
SET STATEMENT sort_buffer_size = 100000 for SET SESSION sort_buffer_size =
200000;

For the above, after setting sort_buffer_size to 200000 it will be reset to
its original state (the state before the SET STATEMENT started) after the
statement execution.

Limitations
-----------

There are a number of variables that cannot be set on per-query basis. These
include:

* autocommit
* character_set_client
* character_set_connection
* character_set_filesystem
* collation_connection
* default_master_connection
* debug_sync
* interactive_timeout
* gtid_domain_id
* last_insert_id
* log_slow_filter
* log_slow_rate_limit
* log_slow_verbosity
* long_query_time
* min_examined_row_limit
* profiling
* profiling_history_size
* query_cache_type
* rand_seed1
* rand_seed2
* skip_replication
* slow_query_log
* sql_log_off
* tx_isolation
* wait_timeout

Source
------

* The feature was originally implemented as a Google Summer of Code 2009
project by Joseph Lukas. 
* Percona Server 5.6 included it as Per-query variable statement
* MariaDB ported the patch and fixed many bugs. The task in MariaDB Jira is
MDEV-5231.

URL: https://mariadb.com/kb/en/set-statement/https://mariadb.com/kb/en/set-statement/��	��
q���g\'SET VariableSyntax
------

SET var_name = expr [, var_name = expr] ...

Description
-----------

The SET statement in stored programs is an extended version of the general SET
statement. Referenced variables may be ones declared inside a stored program,
global system variables, or user-defined variables.

The SET statement in stored programs is implemented as part of the
pre-existing SET syntax. This allows an extended syntax of SET a=x, b=y, ...
where different variable types (locally declared variables, global and session
server variables, user-defined variables) can be mixed. This also allows
combinations of local variables and some options that make sense only for
system variables; in that case, the options are recognized but ignored.

SET can be used with both local variables and user-defined variables.

When setting several variables using the columns returned by a query, SELECT
INTO should be preferred.

To set many variables to the same value, the LAST_VALUE( ) function can be
used.

Below is an example of how a user-defined variable may be set:

SET @x = 1;

URL: https://mariadb.com/kb/en/set-variable/https://mariadb.com/kb/en/set-variable/h
d%About SHOWSHOW has many forms that provide information about databases, tables, columns,
or status information about the server. These include:

* SHOW AUTHORS
* SHOW CHARACTER SET [like_or_where]
* SHOW COLLATION [like_or_where]
* SHOW [FULL] COLUMNS FROM tbl_name [FROM db_name] [like_or_where]
* SHOW CONTRIBUTORS
* SHOW CREATE DATABASE db_name
* SHOW CREATE EVENT event_name
* SHOW CREATE PACKAGE package_name
* SHOW CREATE PACKAGE BODY package_name
* SHOW CREATE PROCEDURE proc_name
* SHOW CREATE TABLE tbl_name
* SHOW CREATE TRIGGER trigger_name
* SHOW CREATE VIEW view_name
* SHOW DATABASES [like_or_where]
* SHOW ENGINE engine_name {STATUS | MUTEX}
* SHOW [STORAGE] ENGINES
* SHOW ERRORS [LIMIT [offset,] row_count]
* SHOW [FULL] EVENTS
* SHOW FUNCTION CODE func_name
* SHOW FUNCTION STATUS [like_or_where]
* SHOW GRANTS FOR user
* SHOW INDEX FROM tbl_name [FROM db_name]
* SHOW INNODB STATUS
* SHOW OPEN TABLES [FROM db_name] [like_or_where]
* SHOW PLUGINS
* SHOW PROCEDURE CODE proc_name
* SHOW PROCEDURE STATUS [like_or_where]
* SHOW PRIVILEGES
* SHOW [FULL] PROCESSLIST
* SHOW PROFILE [types] [FOR QUERY n] [OFFSET n] [LIMIT n]
* SHOW PROFILES
* SHOW [GLOBAL | SESSION] STATUS [like_or_where]
* SHOW TABLE STATUS [FROM db_name] [like_or_where]
* SHOW TABLES [FROM db_name] [like_or_where]
* SHOW TRIGGERS [FROM db_name] [like_or_where]
* SHOW [GLOBAL | SESSION] VARIABLES [like_or_where]
* SHOW WARNINGS [LIMIT [offset,] row_count]

like_or_where:
  LIKE 'pattern'
 | WHERE expr

If the syntax for a given SHOW statement includes a LIKE 'pattern' part,
'pattern' is a string that can contain the SQL "%" and "_" wildcard
characters. The pattern is useful for restricting statement output to matching
values.

Several SHOW statements also accept a WHERE clause that provides more
flexibility in specifying which rows to display. See Extended Show.

URL: https://mariadb.com/kb/en/about-show/https://mariadb.com/kb/en/about-show/k�+SHOW BINARY LOGSSyntax
------

SHOW BINARY LOGS
SHOW MASTER LOGS

Description
-----------

Lists the binary log files on the server. This statement is used as part of
the procedure described in PURGE BINARY LOGS, that shows how to determine
which logs can be purged.

This statement requires the SUPER privilege, the REPLICATION_CLIENT privilege,
or, from MariaDB 10.5.2, the BINLOG MONITOR privilege.

Examples
--------

SHOW BINARY LOGS;
+--------------------+-----------+
| Log_name           | File_size |
+--------------------+-----------+
| mariadb-bin.000001 |     19039 |
| mariadb-bin.000002 |    717389 |
| mariadb-bin.000003 |       300 |
| mariadb-bin.000004 |       333 |
| mariadb-bin.000005 |       899 |
| mariadb-bin.000006 |       125 |
| mariadb-bin.000007 |     18907 |
| mariadb-bin.000008 |     19530 |
| mariadb-bin.000009 |       151 |
| mariadb-bin.000010 |       151 |
| mariadb-bin.000011 |       125 |
| mariadb-bin.000012 |       151 |
| mariadb-bin.000013 |       151 |
| mariadb-bin.000014 |       125 |
| mariadb-bin.000015 |       151 |
| mariadb-bin.000016 |       314 |
+--------------------+-----------+

URL: https://mariadb.com/kb/en/show-binary-logs/https://mariadb.com/kb/en/show-binary-logs/l�-SHOW BINLOG EVENTSSyntax
------

SHOW BINLOG EVENTS
 [IN 'log_name'] [FROM pos] [LIMIT [offset,] row_count]

Description
-----------

Shows the events in the binary log. If you do not specify 'log_name', the
first binary log is displayed.

Requires the BINLOG MONITOR privilege (>= MariaDB 10.5.2) or the REPLICATION
SLAVE privilege (<= MariaDB 10.5.1).

Example
-------

SHOW BINLOG EVENTS IN 'mysql_sandbox10019-bin.000002';
+-------------------------------+-----+-------------------+-----------+--------
----+------------------------------------------------+
| Log_name                      | Pos | Event_type        | Server_id |
End_log_pos | Info                                           |
+-------------------------------+-----+-------------------+-----------+--------
----+------------------------------------------------+
| mysql_sandbox10019-bin.000002 |   4 | Format_desc       |         1 |       
 248 | Server ver: 10.0.19-MariaDB-log, Binlog ver: 4 |
| mysql_sandbox10019-bin.000002 | 248 | Gtid_list         |         1 |       
 273 | []                                             |
| mysql_sandbox10019-bin.000002 | 273 | Binlog_checkpoint |         1 |       
 325 | mysql_sandbox10019-bin.000002                  |
| mysql_sandbox10019-bin.000002 | 325 | Gtid              |         1 |       
 363 | GTID 0-1-1                                     |
| mysql_sandbox10019-bin.000002 | 363 | Query             |         1 |       
 446 | CREATE DATABASE blog                           |
| mysql_sandbox10019-bin.000002 | 446 | Gtid              |         1 |       
 484 | GTID 0-1-2                                     |
| mysql_sandbox10019-bin.000002 | 484 | Query             |         1 |       
 571 | use `blog`; CREATE TABLE bb (id INT)           |
+-------------------------------+-----+-------------------+-----------+--------
----+------------------------------------------------+

URL: https://mariadb.com/kb/en/show-binlog-events/https://mariadb.com/kb/en/show-binlog-events/(�J�����#���	i
l
(Extended ShowThe following SHOW statements can be extended by using a WHERE clause and a
LIKE clause to refine the results:

* SHOW CHARACTER SET
* SHOW COLLATION
* SHOW COLUMNS
* SHOW DATABASES
* SHOW FUNCTION STATUS
* SHOW INDEX
* SHOW OPEN TABLES
* SHOW PACKAGE STATUS
* SHOW PACKAGE BODY STATUS
* SHOW INDEX
* SHOW PROCEDURE STATUS
* SHOW STATUS
* SHOW TABLE STATUS
* SHOW TABLES
* SHOW TRIGGERS
* SHOW VARIABLES

As with a regular SELECT, the WHERE clause can be used for the specific
columns returned, and the LIKE clause with the regular wildcards.

Examples
--------

SHOW TABLES;
+----------------------+
| Tables_in_test       |
+----------------------+
| animal_count         |
| animals              |
| are_the_mooses_loose |
| aria_test2           |
| t1                   |
| view1                |
+----------------------+

Showing the tables beginning with a only.

SHOW TABLES WHERE Tables_in_test LIKE 'a%';
+----------------------+
| Tables_in_test       |
+----------------------+
| animal_count         |
| animals              |
| are_the_mooses_loose |
| aria_test2           |
+----------------------+

Variables whose name starts with aria and with a valued of greater than 8192:

SHOW VARIABLES WHERE Variable_name LIKE 'aria%' AND Value >8192;
+------------------------------+---------------------+
| Variable_name                | Value               |
+------------------------------+---------------------+
| aria_checkpoint_log_activity | 1048576             |
| aria_log_file_size           | 1073741824          |
| aria_max_sort_file_size      | 9223372036853727232 |
| aria_pagecache_buffer_size   | 134217728           |
| aria_sort_buffer_size        | 134217728           |
+------------------------------+---------------------+

Shortcut, just returning variables whose name begins with aria.

SHOW VARIABLES LIKE 'aria%';
+------------------------------------------+---------------------+
| Variable_name                            | Value               |
+------------------------------------------+---------------------+
| aria_block_size                          | 8192                |
| aria_checkpoint_interval                 | 30                  |
| aria_checkpoint_log_activity             | 1048576             |
| aria_force_start_after_recovery_failures | 0                   |
| aria_group_commit                        | none                |
| aria_group_commit_interval               | 0                   |
| aria_log_file_size                       | 1073741824          |
| aria_log_purge_type                      | immediate           |
| aria_max_sort_file_size                  | 9223372036853727232 |
| aria_page_checksum                       | ON                  |
| aria_pagecache_age_threshold             | 300                 |
| aria_pagecache_buffer_size               | 134217728           |
| aria_pagecache_division_limit            | 100                 |
| aria_recover                             | NORMAL              |
| aria_repair_threads                      | 1                   |
| aria_sort_buffer_size                    | 134217728           |
| aria_stats_method                        | nulls_unequal       |
| aria_sync_log_dir                        | NEWFILE             |
| aria_used_for_temp_tables                | ON                  |
+------------------------------------------+---------------------+

URL: https://mariadb.com/kb/en/extended-show/https://mariadb.com/kb/en/extended-show/m-SHOW CHARACTER SETSyntax
------

SHOW CHARACTER SET
  [LIKE 'pattern' | WHERE expr]

Description
-----------

The SHOW CHARACTER SET statement shows all available character sets. The LIKE
clause, if present on its own, indicates which character set names to match.
The WHERE and LIKE clauses can be given to select rows using more general
conditions, as discussed in Extended SHOW.

The same information can be queried from the Information Schema CHARACTER_SETS
table.

See Setting Character Sets and Collations for details on specifying the
character set at the server, database, table and column levels.

Examples
--------

SHOW CHARACTER SET LIKE 'latin%';
+---------+-----------------------------+-------------------+--------+
| Charset | Description                 | Default collation | Maxlen |
+---------+-----------------------------+-------------------+--------+
| latin1  | cp1252 West European        | latin1_swedish_ci |      1 |
| latin2  | ISO 8859-2 Central European | latin2_general_ci |      1 |
| latin5  | ISO 8859-9 Turkish          | latin5_turkish_ci |      1 |
| latin7  | ISO 8859-13 Baltic          | latin7_general_ci |      1 |
+---------+-----------------------------+-------------------+--------+

SHOW CHARACTER SET WHERE Maxlen LIKE '2';
+---------+---------------------------+-------------------+--------+
| Charset | Description               | Default collation | Maxlen |
+---------+---------------------------+-------------------+--------+
| big5    | Big5 Traditional Chinese  | big5_chinese_ci   |      2 |
| sjis    | Shift-JIS Japanese        | sjis_japanese_ci  |      2 |
| euckr   | EUC-KR Korean             | euckr_korean_ci   |      2 |
| gb2312  | GB2312 Simplified Chinese | gb2312_chinese_ci |      2 |
| gbk     | GBK Simplified Chinese    | gbk_chinese_ci    |      2 |
| ucs2    | UCS-2 Unicode             | ucs2_general_ci   |      2 |
| cp932   | SJIS for Windows Japanese | cp932_japanese_ci |      2 |
+---------+---------------------------+-------------------+--------+

URL: https://mariadb.com/kb/en/show-character-set/https://mariadb.com/kb/en/show-character-set/�
\�
kF�b�6ju'SHOW AUTHORSSyntax
------

SHOW AUTHORS

Description
-----------

The SHOW AUTHORS statement displays information about the people who work on
MariaDB. For each author, it displays Name, Location, and Comment values. All
columns are encoded as latin1.

These include:

* First the active people in MariaDB are listed.
* Then the active people in MySQL.
* Last the people that have contributed to MariaDB/MySQL in the past.

The order is somewhat related to importance of the contribution given to the
MariaDB project, but this is not 100% accurate. There is still room for
improvement and debate...

Example
-------

SHOW AUTHORS\G
*************************** 1. row ***************************
  Name: Michael (Monty) Widenius
Location: Tusby, Finland
 Comment: Lead developer and main author
*************************** 2. row ***************************
  Name: Sergei Golubchik
Location: Kerpen, Germany
 Comment: Architect, Full-text search, precision math, plugin framework,
merges etc
*************************** 3. row ***************************
  Name: Igor Babaev
Location: Bellevue, USA
 Comment: Optimizer, keycache, core work
*************************** 4. row ***************************
  Name: Sergey Petrunia
Location: St. Petersburg, Russia
 Comment: Optimizer
*************************** 5. row ***************************
  Name: Oleksandr Byelkin
Location: Lugansk, Ukraine
 Comment: Query Cache (4.0), Subqueries (4.1), Views (5.0)
*************************** 6. row ***************************
  Name: Timour Katchaounov
Location: Sofia , Bulgaria
 Comment: Optimizer
*************************** 7. row ***************************
  Name: Kristian Nielsen
Location: Copenhagen, Denmark
 Comment: Replication, Async client prototocol, General buildbot stuff
*************************** 8. row ***************************
  Name: Alexander (Bar) Barkov
Location: Izhevsk, Russia
 Comment: Unicode and character sets
*************************** 9. row ***************************
  Name: Alexey Botchkov (Holyfoot)
Location: Izhevsk, Russia
 Comment: GIS extensions, embedded server, precision math
*************************** 10. row ***************************
  Name: Daniel Bartholomew
Location: Raleigh, USA
 Comment: MariaDB documentation, Buildbot, releases
*************************** 11. row ***************************
  Name: Colin Charles
Location: Selangor, Malesia
 Comment: MariaDB documentation, talks at a LOT of conferences
*************************** 12. row ***************************
  Name: Sergey Vojtovich
Location: Izhevsk, Russia
 Comment: initial implementation of plugin architecture, maintained native
storage engines (MyISAM, MEMORY, ARCHIVE, etc), rewrite of table cache
*************************** 13. row ***************************
  Name: Vladislav Vaintroub
Location: Mannheim, Germany
 Comment: MariaDB Java connector, new thread pool, Windows optimizations
*************************** 14. row ***************************
  Name: Elena Stepanova
Location: Sankt Petersburg, Russia
 Comment: QA, test cases
*************************** 15. row ***************************
  Name: Georg Richter
Location: Heidelberg, Germany
 Comment: New LGPL C connector, PHP connector
*************************** 16. row ***************************
  Name: Jan Lindström
Location: Ylämylly, Finland
 Comment: Working on InnoDB
*************************** 17. row ***************************
  Name: Lixun Peng
Location: Hangzhou, China
 Comment: Multi Source replication
*************************** 18. row ***************************
  Name: Olivier Bertrand
Location: Paris, France
 Comment: CONNECT storage engine
*************************** 19. row ***************************
  Name: Kentoku Shiba
Location: Tokyo, Japan
 Comment: Spider storage engine, metadata_lock_info Information schema
*************************** 20. row ***************************
  Name: Percona
Location: CA, USA
 Comment: XtraDB, microslow patches, extensions to slow log
*************************** 21. row ***************************
  Name: Vicentiu Ciorbaru
Location: Bucharest, Romania
 Comment: Roles
*************************** 22. row ***************************
  Name: Sudheera Palihakkara
Location: 
 Comment: PCRE Regular Expressions
*************************** 23. row ***************************
  Name: Pavel Ivanov
Location: USA
 Comment: Some patches and bug fixes
*************************** 24. row ***************************
  Name: Konstantin Osipov
Location: Moscow, Russia
 Comment: Prepared statements (4.1), Cursors (5.0), GET_LOCK (10.0)
*************************** 25. row ***************************
  Name: Ian Gilfillan
Location: South Africa
 Comment: MariaDB documentation
*************************** 26. row ***************************
  Name: Federico Razolli
Location: Italy
 Comment: MariaDB documentation Italian translation
*************************** 27. row ***************************
  Name: Guilhem Bichot
Location: Bordeaux, France
 Comment: Replication (since 4.0)
*************************** 28. row ***************************
  Name: Andrei Elkin
Location: Espoo, Finland
 Comment: Replication
*************************** 29. row ***************************
  Name: Dmitri Lenev
Location: Moscow, Russia
 Comment: Time zones support (4.1), Triggers (5.0)
*************************** 30. row ***************************
  Name: Marc Alff
Location: Denver, CO, USA
 Comment: Signal, Resignal, Performance schema
*************************** 31. row ***************************
  Name: Mikael Ronström
Location: Stockholm, Sweden
 Comment: NDB Cluster, Partitioning, online alter table
*************************** 32. row ***************************
  Name: Ingo Strüwing
Location: Berlin, Germany
 Comment: Bug fixing in MyISAM, Merge tables etc
*************************** 33. row ***************************
  Name: Marko Mäkelä
Location: Helsinki, Finland
 Comment: InnoDB core developer
...

URL: https://mariadb.com/kb/en/show-authors/https://mariadb.com/kb/en/show-authors/��)���Yn�1SHOW CLIENT_STATISTICSSyntax
------

SHOW CLIENT_STATISTICS

Description
-----------

The SHOW CLIENT_STATISTICS statement is part of the User Statistics feature.
It was removed as a separate statement in MariaDB 10.1.1, but effectively
replaced by the generic SHOW information_schema_table statement. The
information_schema.CLIENT_STATISTICS table holds statistics about client
connections.

The userstat system variable must be set to 1 to activate this feature. See
the User Statistics and information_schema.CLIENT_STATISTICS articles for more
information.

Example
-------

SHOW CLIENT_STATISTICS\G
*************************** 1. row ***************************
        Client: localhost
  Total_connections: 35
Concurrent_connections: 0
    Connected_time: 708
      Busy_time: 2.5557979999999985
       Cpu_time: 0.04123740000000002
    Bytes_received: 3883
      Bytes_sent: 21595
 Binlog_bytes_written: 0
      Rows_read: 18
      Rows_sent: 115
     Rows_deleted: 0
    Rows_inserted: 0
     Rows_updated: 0
   Select_commands: 70
   Update_commands: 0
    Other_commands: 0
 Commit_transactions: 1
 Rollback_transactions: 0
  Denied_connections: 0
   Lost_connections: 0
    Access_denied: 0
    Empty_queries: 35

URL: https://mariadb.com/kb/en/show-client-statistics/https://mariadb.com/kb/en/show-client-statistics/o�,SHOW CONTRIBUTORSSyntax
------

SHOW CONTRIBUTORS

Description
-----------

The SHOW CONTRIBUTORS statement displays information about the companies and
people who financially contribute to MariaDB. For each contributor, it
displays Name, Location, and Comment values. All columns are encoded as latin1.

It displays all members and sponsors of the MariaDB Foundation as well as
other financial contributors.

Example
-------

SHOW CONTRIBUTORS;
+---------------------+-------------------------------+------------------------
------------------------------------+
| Name                | Location                      | Comment               
                  |
+---------------------+-------------------------------+------------------------
------------------------------------+
| Alibaba Cloud       | https://www.alibabacloud.com/ | Platinum Sponsor of
the MariaDB Foundation                  |
| Tencent Cloud       | https://cloud.tencent.com     | Platinum Sponsor of
the MariaDB Foundation                  |
| Microsoft           | https://microsoft.com/        | Platinum Sponsor of
the MariaDB Foundation                  |
| MariaDB Corporation | https://mariadb.com           | Founding member,
Platinum Sponsor of the MariaDB Foundation |
| ServiceNow          | https://servicenow.com        | Platinum Sponsor of
the MariaDB Foundation                  |
| Intel               | https://www.intel.com         | Platinum Sponsor of
the MariaDB Foundation                  |
| SIT                 | https://sit.org               | Platinum Sponsor of
the MariaDB Foundation                  |
| Visma               | https://visma.com             | Gold Sponsor of the
MariaDB Foundation                      |
| DBS                 | https://dbs.com               | Gold Sponsor of the
MariaDB Foundation                      |
| IBM                 | https://www.ibm.com           | Gold Sponsor of the
MariaDB Foundation                      |
| Automattic          | https://automattic.com        | Silver Sponsor of the
MariaDB Foundation                    |
| Percona             | https://www.percona.com/      | Sponsor of the MariaDB
Foundation                           |
| Galera Cluster      | https://galeracluster.com     | Sponsor of the MariaDB
Foundation                           |
| Google              | USA                           | Sponsoring encryption,
parallel replication and GTID        |
| Facebook            | USA                           | Sponsoring
non-blocking API, LIMIT ROWS EXAMINED etc        |
| Ronald Bradford     | Brisbane, Australia           | EFF contribution for
UC2006 Auction                         |
| Sheeri Kritzer      | Boston, Mass. USA             | EFF contribution for
UC2006 Auction                         |
| Mark Shuttleworth   | London, UK.                   | EFF contribution for
UC2006 Auction                         |
+---------------------+-------------------------------+------------------------
------------------------------------+

URL: https://mariadb.com/kb/en/show-contributors/https://mariadb.com/kb/en/show-contributors/p�/SHOW CREATE DATABASESyntax
------

SHOW CREATE {DATABASE | SCHEMA} db_name

Description
-----------

Shows the CREATE DATABASE statement that creates the given database. SHOW
CREATE SCHEMA is a synonym for SHOW CREATE DATABASE. SHOW CREATE DATABASE
quotes database names according to the value of the sql_quote_show_create
server system variable.

Examples
--------

SHOW CREATE DATABASE test;
+----------+-----------------------------------------------------------------+
| Database | Create Database                                                 |
+----------+-----------------------------------------------------------------+
| test     | CREATE DATABASE `test` /*!40100 DEFAULT CHARACTER SET latin1 */ |
+----------+-----------------------------------------------------------------+

SHOW CREATE SCHEMA test;
+----------+-----------------------------------------------------------------+
| Database | Create Database                                                 |
+----------+-----------------------------------------------------------------+
| test     | CREATE DATABASE `test` /*!40100 DEFAULT CHARACTER SET latin1 */ |
+----------+-----------------------------------------------------------------+

With sql_quote_show_create off:

SHOW CREATE DATABASE test;
+----------+---------------------------------------------------------------+
| Database | Create Database                                               |
+----------+---------------------------------------------------------------+
| test     | CREATE DATABASE test /*!40100 DEFAULT CHARACTER SET latin1 */ |
+----------+---------------------------------------------------------------+

With a comment, from MariaDB 10.5:

SHOW CREATE DATABASE p;
+----------+-------------------------------------------------------------------
------------------+
| Database | Create Database                                                  
         |
+----------+-------------------------------------------------------------------
------------------+
| p        | CREATE DATABASE `p` /*!40100 DEFAULT CHARACTER SET latin1 */
COMMENT 'presentations' |
+----------+-------------------------------------------------------------------
------------------+

URL: https://mariadb.com/kb/en/show-create-database/https://mariadb.com/kb/en/show-create-database/�	K;?:i���O
q�,SHOW CREATE EVENTSyntax
------

SHOW CREATE EVENT event_name

Description
-----------

This statement displays the CREATE EVENT statement needed to re-create a given
event, as well as the SQL_MODE that was used when the trigger has been created
and the character set used by the connection. To find out which events are
present, use SHOW EVENTS.

The output of this statement is unreliably affected by the
sql_quote_show_create server system variable - see
http://bugs.mysql.com/bug.php?id=12719

The information_schema.EVENTS table provides similar, but more complete,
information.

Examples
--------

SHOW CREATE EVENT test.e_daily\G
*************************** 1. row ***************************
       Event: e_daily
      sql_mode:
     time_zone: SYSTEM
    Create Event: CREATE EVENT `e_daily`
            ON SCHEDULE EVERY 1 DAY
            STARTS CURRENT_TIMESTAMP + INTERVAL 6 HOUR
            ON COMPLETION NOT PRESERVE
            ENABLE
            COMMENT 'Saves total number of sessions then
                clears the table each day'
            DO BEGIN
             INSERT INTO site_activity.totals (time, total)
              SELECT CURRENT_TIMESTAMP, COUNT(*)
              FROM site_activity.sessions;
             DELETE FROM site_activity.sessions;
            END
character_set_client: latin1
collation_connection: latin1_swedish_ci
 Database Collation: latin1_swedish_ci

URL: https://mariadb.com/kb/en/show-create-event/https://mariadb.com/kb/en/show-create-event/r/SHOW CREATE FUNCTIONSyntax
------

SHOW CREATE FUNCTION func_name

Description
-----------

This statement is similar to SHOW CREATE PROCEDURE but for stored functions.

The output of this statement is unreliably affected by the
sql_quote_show_create server system variable - see
http://bugs.mysql.com/bug.php?id=12719

Example
-------

SHOW CREATE FUNCTION VatCents\G
*************************** 1. row ***************************
      Function: VatCents
      sql_mode:
  Create Function: CREATE DEFINER=`root`@`localhost` FUNCTION
`VatCents`(price DECIMAL(10,2)) RETURNS int(11)
  DETERMINISTIC
BEGIN
 DECLARE x INT;
 SET x = price * 114;
 RETURN x;
END
character_set_client: utf8
collation_connection: utf8_general_ci
 Database Collation: latin1_swedish_ci

URL: https://mariadb.com/kb/en/show-create-function/https://mariadb.com/kb/en/show-create-function/s0.SHOW CREATE PACKAGEMariaDB starting with 10.3.5
----------------------------
Oracle-style packages were introduced in MariaDB 10.3.5.

Syntax
------

SHOW CREATE PACKAGE  [ db_name . ] package_name

Description
-----------

The SHOW CREATE PACKAGE statement can be used when Oracle SQL_MODE is set.

Shows the CREATE statement that creates the given package specification.

Examples
--------

SHOW CREATE PACKAGE employee_tools\G
*************************** 1. row ***************************
      Package: employee_tools
      sql_mode:
PIPES_AS_CONCAT,ANSI_QUOTES,IGNORE_SPACE,ORACLE,NO_KEY_OPTIONS,NO_TABLE_OPTIONS
NO_FIELD_OPTIONS,NO_AUTO_CREATE_USER
   Create Package: CREATE DEFINER="root"@"localhost" PACKAGE
"employee_tools" AS
 FUNCTION getSalary(eid INT) RETURN DECIMAL(10,2);
 PROCEDURE raiseSalary(eid INT, amount DECIMAL(10,2));
 PROCEDURE raiseSalaryStd(eid INT);
 PROCEDURE hire(ename TEXT, esalary DECIMAL(10,2));
END
character_set_client: utf8
collation_connection: utf8_general_ci
 Database Collation: latin1_swedish_ci

URL: https://mariadb.com/kb/en/show-create-package/https://mariadb.com/kb/en/show-create-package/tm3SHOW CREATE PACKAGE BODYMariaDB starting with 10.3.5
----------------------------
Oracle-style packages were introduced in MariaDB 10.3.5.

Syntax
------

SHOW CREATE PACKAGE BODY  [ db_name . ] package_name

Description
-----------

The SHOW CREATE PACKAGE BODY statement can be used when Oracle SQL_MODE is set.

Shows the CREATE statement that creates the given package body (i.e. the
implementation).

Examples
--------

SHOW CREATE PACKAGE BODY employee_tools\G
*************************** 1. row ***************************
    Package body: employee_tools
      sql_mode:
PIPES_AS_CONCAT,ANSI_QUOTES,IGNORE_SPACE,ORACLE,NO_KEY_OPTIONS,NO_TABLE_OPTIONS
NO_FIELD_OPTIONS,NO_AUTO_CREATE_USER
 Create Package Body: CREATE DEFINER="root"@"localhost" PACKAGE BODY
"employee_tools" AS

stdRaiseAmount DECIMAL(10,2):=500;

PROCEDURE log (eid INT, ecmnt TEXT) AS
 BEGIN
  INSERT INTO employee_log (id, cmnt) VALUES (eid, ecmnt);
 END;

PROCEDURE hire(ename TEXT, esalary DECIMAL(10,2)) AS
  eid INT;
 BEGIN
  INSERT INTO employee (name, salary) VALUES (ename, esalary);
  eid:= last_insert_id();
  log(eid, 'hire ' || ename);
 END;

FUNCTION getSalary(eid INT) RETURN DECIMAL(10,2) AS
  nSalary DECIMAL(10,2);
 BEGIN
  SELECT salary INTO nSalary FROM employee WHERE id=eid;
  log(eid, 'getSalary id=' || eid || ' salary=' || nSalary);
  RETURN nSalary;
 END;

PROCEDURE raiseSalary(eid INT, amount DECIMAL(10,2)) AS
 BEGIN
  UPDATE employee SET salary=salary+amount WHERE id=eid;
  log(eid, 'raiseSalary id=' || eid || ' amount=' || amount);
 END;

PROCEDURE raiseSalaryStd(eid INT) AS
 BEGIN
  raiseSalary(eid, stdRaiseAmount);
  log(eid, 'raiseSalaryStd id=' || eid);
 END;

BEGIN  
 log(0, 'Session ' || connection_id() || ' ' || current_user || ' started');
END
character_set_client: utf8
collation_connection: utf8_general_ci
 Database Collation: latin1_swedish_ci

URL: https://mariadb.com/kb/en/show-create-package-body/https://mariadb.com/kb/en/show-create-package-body/�
�X	�l���<��k	uW	0SHOW CREATE PROCEDURESyntax
------

SHOW CREATE PROCEDURE proc_name

Description
-----------

This statement is a MariaDB extension. It returns the exact string that can be
used to re-create the named stored procedure, as well as the SQL_MODE that was
used when the trigger has been created and the character set used by the
connection.. A similar statement, SHOW CREATE FUNCTION, displays information
about stored functions.

Both statements require that you are the owner of the routine or have the
SELECT privilege on the mysql.proc table. When neither is true, the statements
display NULL for the Create Procedure or Create Function field.

Warning Users with SELECT privileges on mysql.proc or USAGE privileges on *.*
can view the text of routines, even when they do not have privileges for the
function or procedure itself.

The output of these statements is unreliably affected by the
sql_quote_show_create server system variable - see
http://bugs.mysql.com/bug.php?id=12719

Examples
--------

Here's a comparison of the SHOW CREATE PROCEDURE and SHOW CREATE FUNCTION
statements.

SHOW CREATE PROCEDURE test.simpleproc\G
*************************** 1. row ***************************
     Procedure: simpleproc
      sql_mode:
  Create Procedure: CREATE PROCEDURE `simpleproc`(OUT param1 INT)
           BEGIN
           SELECT COUNT(*) INTO param1 FROM t;
           END
character_set_client: latin1
collation_connection: latin1_swedish_ci
 Database Collation: latin1_swedish_ci

SHOW CREATE FUNCTION test.hello\G
*************************** 1. row ***************************
      Function: hello
      sql_mode:
  Create Function: CREATE FUNCTION `hello`(s CHAR(20))
           RETURNS CHAR(50)
           RETURN CONCAT('Hello, ',s,'!')
character_set_client: latin1
collation_connection: latin1_swedish_ci
 Database Collation: latin1_swedish_ci

When the user issuing the statement does not have privileges on the routine,
attempting to CALL the procedure raises Error 1370.

CALL test.prc1();
Error 1370 (42000): execute command denieed to user 'test_user'@'localhost'
for routine 'test'.'prc1'

If the user neither has privilege to the routine nor the SELECT privilege on
mysql.proc table, it raises Error 1305, informing them that the procedure does
not exist.

SHOW CREATE TABLES test.prc1\G
Error 1305 (42000): PROCEDURE prc1 does not exist

URL: https://mariadb.com/kb/en/show-create-procedure/https://mariadb.com/kb/en/show-create-procedure/v�/SHOW CREATE SEQUENCESyntax
------

SHOW CREATE SEQUENCE sequence_name;

Description
-----------

Shows the CREATE SEQUENCE statement that created the given sequence. The
statement requires the SELECT privilege for the table.

Example
-------

CREATE SEQUENCE s1 START WITH 50;
SHOW CREATE SEQUENCE s1\G;
*************************** 1. row ***************************
   Table: s1
Create Table: CREATE SEQUENCE `s1` start with 50 minvalue 1 maxvalue
9223372036854775806 
 increment by 1 cache 1000 nocycle ENGINE=InnoDB

Notes
-----

If you want to see the underlying table structure used for the SEQUENCE you
can use SHOW CREATE TABLE on the SEQUENCE. You can also use SELECT to read the
current recorded state of the SEQUENCE:

SHOW CREATE TABLE s1\G
*************************** 1. row ***************************
   Table: s1
Create Table: CREATE TABLE `s1` (
 `next_not_cached_value` bigint(21) NOT NULL,
 `minimum_value` bigint(21) NOT NULL,
 `maximum_value` bigint(21) NOT NULL,
 `start_value` bigint(21) NOT NULL COMMENT 'start value when sequences is
created 
  or value if RESTART is used',
 `increment` bigint(21) NOT NULL COMMENT 'increment value',
 `cache_size` bigint(21) unsigned NOT NULL,
 `cycle_option` tinyint(1) unsigned NOT NULL COMMENT '0 if no cycles are
allowed, 
  1 if the sequence should begin a new cycle when maximum_value is passed',
 `cycle_count` bigint(21) NOT NULL COMMENT 'How many cycles have been done'
) ENGINE=InnoDB SEQUENCE=1

SELECT * FROM s1\G
*************************** 1. row ***************************
next_not_cached_value: 50
    minimum_value: 1
    maximum_value: 9223372036854775806
     start_value: 50
      increment: 1
     cache_size: 1000
    cycle_option: 0
     cycle_count: 0

URL: https://mariadb.com/kb/en/show-create-sequence/https://mariadb.com/kb/en/show-create-sequence/wF.SHOW CREATE TRIGGERSyntax
------

SHOW CREATE TRIGGER trigger_name

Description
-----------

This statement shows a CREATE TRIGGER statement that creates the given
trigger, as well as the SQL_MODE that was used when the trigger has been
created and the character set used by the connection.

The TRIGGER privilege is required on the table the trigger is defined for to
execute this statement.

The output of this statement is unreliably affected by the
sql_quote_show_create server system variable - see
http://bugs.mysql.com/bug.php?id=12719

Examples
--------

SHOW CREATE TRIGGER example\G
*************************** 1. row ***************************
       Trigger: example
       sql_mode:
ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,STRICT_ALL_TABLES
,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO

ENGINE_SUBSTITUTION
SQL Original Statement: CREATE DEFINER=`root`@`localhost` TRIGGER example
BEFORE
 INSERT ON t FOR EACH ROW
BEGIN
    SET NEW.c = NEW.c * 2;
END
 character_set_client: cp850
 collation_connection: cp850_general_ci
 Database Collation: utf8_general_ci
 Created: 2016-09-29 13:53:34.35

MariaDB starting with 10.2.3
----------------------------
The Created column was added in MySQL 5.7 and MariaDB 10.2.3 as part of
introducing multiple trigger events per action.

URL: https://mariadb.com/kb/en/show-create-trigger/https://mariadb.com/kb/en/show-create-trigger/���	:�	�ny���xC+SHOW CREATE VIEWSyntax
------

SHOW CREATE VIEW view_name

Description
-----------

This statement shows a CREATE VIEW statement that creates the given view, as
well as the character set used by the connection when the view was created.
This statement also works with views.

SHOW CREATE VIEW quotes table, column and stored function names according to
the value of the sql_quote_show_create server system variable.

Examples
--------

SHOW CREATE VIEW example\G
*************************** 1. row ***************************
        View: example
    Create View: CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL
SECURITY DEFINER VIEW `example` AS (select `t`.`id` AS `id`,`t`.`s` AS `s` from
`t`)
character_set_client: cp850
collation_connection: cp850_general_ci

With sql_quote_show_create off:

SHOW CREATE VIEW example\G
*************************** 1. row ***************************
        View: example
    Create View: CREATE ALGORITHM=UNDEFINED DEFINER=root@localhost SQL
SECU
RITY DEFINER VIEW example AS (select t.id AS id,t.s AS s from t)
character_set_client: cp850
collation_connection: cp850_general_ci

Grants
------

To be able to see a view, you need to have the SHOW VIEW and the SELECT
privilege on the view:

GRANT SHOW VIEW,SELECT ON test_database.test_view TO 'test'@'localhost';

URL: https://mariadb.com/kb/en/show-create-view/https://mariadb.com/kb/en/show-create-view/y�)SHOW DATABASESSyntax
------

SHOW {DATABASES | SCHEMAS}
  [LIKE 'pattern' | WHERE expr]

Description
-----------

SHOW DATABASES lists the databases on the MariaDB server host. SHOW SCHEMAS is
a synonym for SHOW DATABASES. The LIKE clause, if present on its own,
indicates which database names to match. The WHERE and LIKE clauses can be
given to select rows using more general conditions, as discussed in Extended
SHOW.

You see only those databases for which you have some kind of privilege, unless
you have the global SHOW DATABASES privilege. You can also get this list using
the mariadb-show command.

If the server was started with the --skip-show-database option, you cannot use
this statement at all unless you have the SHOW DATABASES privilege.

The list of results returned by SHOW DATABASES is based on directories in the
data directory, which is how MariaDB implements databases. It's possible that
output includes directories that do not correspond to actual databases.

The Information Schema SCHEMATA table also contains database information.

Examples
--------

SHOW DATABASES;
+--------------------+
| Database           |
+--------------------+
| information_schema |
| mysql              |
| performance_schema |
| test               |
+--------------------+

SHOW DATABASES LIKE 'm%';
+---------------+
| Database (m%) |
+---------------+
| mysql         |
+---------------+

URL: https://mariadb.com/kb/en/show-databases/https://mariadb.com/kb/en/show-databases/|I'SHOW ENGINESSyntax
------

SHOW [STORAGE] ENGINES

Description
-----------

SHOW ENGINES displays status information about the server's storage engines.
This is particularly useful for checking whether a storage engine is
supported, or to see what the default engine is. SHOW TABLE TYPES is a
deprecated synonym.

The information_schema.ENGINES table provides the same information.

Since storage engines are plugins, different information about them is also
shown in the information_schema.PLUGINS table and by the SHOW PLUGINS
statement.

Note that both MySQL's InnoDB and Percona's XtraDB replacement are labeled as
InnoDB. However, if XtraDB is in use, it will be specified in the COMMENT
field. See XtraDB and InnoDB. The same applies to FederatedX.

The output consists of the following columns:

* Engine indicates the engine's name.
* Support indicates whether the engine is installed, and whether it is the
default engine for the current session.
* Comment is a brief description.
* Transactions, XA and Savepoints indicate whether transactions, XA
transactions and transaction savepoints are supported by the engine.

Examples
--------

SHOW ENGINES\G
*************************** 1. row ***************************
   Engine: InnoDB
  Support: DEFAULT
  Comment: Supports transactions, row-level locking, and foreign keys
Transactions: YES
     XA: YES
 Savepoints: YES
*************************** 2. row ***************************
   Engine: CSV
  Support: YES
  Comment: CSV storage engine
Transactions: NO
     XA: NO
 Savepoints: NO
*************************** 3. row ***************************
   Engine: MyISAM
  Support: YES
  Comment: MyISAM storage engine
Transactions: NO
     XA: NO
 Savepoints: NO
*************************** 4. row ***************************
   Engine: BLACKHOLE
  Support: YES
  Comment: /dev/null storage engine (anything you write to it disappears)
Transactions: NO
     XA: NO
 Savepoints: NO
*************************** 5. row ***************************
   Engine: FEDERATED
  Support: YES
  Comment: FederatedX pluggable storage engine
Transactions: YES
     XA: NO
 Savepoints: YES
*************************** 6. row ***************************
   Engine: MRG_MyISAM
  Support: YES
  Comment: Collection of identical MyISAM tables
Transactions: NO
     XA: NO
 Savepoints: NO
*************************** 7. row ***************************
   Engine: ARCHIVE
  Support: YES
  Comment: Archive storage engine
Transactions: NO
     XA: NO
 Savepoints: NO
*************************** 8. row ***************************
   Engine: MEMORY
  Support: YES
  Comment: Hash based, stored in memory, useful for temporary tables
Transactions: NO
     XA: NO
 Savepoints: NO
*************************** 9. row ***************************
   Engine: PERFORMANCE_SCHEMA
  Support: YES
  Comment: Performance Schema
Transactions: NO
     XA: NO
 Savepoints: NO
*************************** 10. row ***************************
   Engine: Aria
  Support: YES
  Comment: Crash-safe tables with MyISAM heritage
Transactions: NO
     XA: NO
 Savepoints: NO
10 rows in set (0.00 sec)

URL: https://mariadb.com/kb/en/show-engines/https://mariadb.com/kb/en/show-engines/q����]mz#��
z�&SHOW ENGINESyntax
------

SHOW ENGINE engine_name {STATUS | MUTEX}

Description
-----------

SHOW ENGINE displays operational information about a storage engine. The
following statements currently are supported:

SHOW ENGINE INNODB STATUS
SHOW ENGINE INNODB MUTEX
SHOW ENGINE PERFORMANCE_SCHEMA STATUS
SHOW ENGINE ROCKSDB STATUS

If the Sphinx Storage Engine is installed, the following is also supported:

SHOW ENGINE SPHINX STATUS

See SHOW ENGINE SPHINX STATUS.

Older (and now removed) synonyms were SHOW INNODB STATUS for SHOW ENGINE
INNODB STATUS and SHOW MUTEX STATUS for SHOW ENGINE INNODB MUTEX.

SHOW ENGINE INNODB STATUS
-------------------------

SHOW ENGINE INNODB STATUS displays extensive information from the standard
InnoDB Monitor about the state of the InnoDB storage engine. See SHOW ENGINE
INNODB STATUS for more.

SHOW ENGINE INNODB MUTEX
------------------------

SHOW ENGINE INNODB MUTEX displays InnoDB mutex statistics.

The statement displays the following output fields:

* Type: Always InnoDB.
* Name: The source file where the mutex is implemented, and the line number
 in the file where the mutex is created. The line number is dependent on the
MariaDB version.
* Status: This field displays the following values if UNIV_DEBUG was defined
at compilation time (for example, in include/univ.h in the InnoDB part of the
source tree). Only the os_waits value is displayed if UNIV_DEBUG was not
defined. Without UNIV_DEBUG, the information on which the output is based is
insufficient to distinguish regular mutexes and mutexes that protect
 rw-locks (which allow multiple readers or a single writer). Consequently, the
 output may appear to contain multiple rows for the same mutex.
count indicates how many times the mutex was requested.
spin_waits indicates how many times the spinlock had to run.
spin_rounds indicates the number of spinlock rounds. (spin_rounds divided by
 spin_waits provides the average round count.)
os_waits indicates the number of operating system waits. This occurs when
 the spinlock did not work (the mutex was not locked during the spinlock and
 it was necessary to yield to the operating system and wait).
os_yields indicates the number of times a the thread trying to lock a mutex
 gave up its timeslice and yielded to the operating system (on the
 presumption that allowing other threads to run will free the mutex so that
 it can be locked).
os_wait_times indicates the amount of time (in ms) spent in operating system
 waits, if the timed_mutexes system variable is 1 (ON). If timed_mutexes is 0
 (OFF), timing is disabled, so os_wait_times is 0. timed_mutexes is off by
 default.

Information from this statement can be used to diagnose system problems. For
example, large values of spin_waits and spin_rounds may indicate scalability
problems.

The information_schema.INNODB_MUTEXES table provides similar information.

SHOW ENGINE PERFORMANCE_SCHEMA STATUS
-------------------------------------

This statement shows how much memory is used for performance_schema tables and
internal buffers.

The output contains the following fields:

* Type: Always performance_schema.
* Name: The name of a table, the name of an internal buffer, or the
performance_schema word, followed by a dot and an attribute. Internal buffers
names are enclosed by parenthesis. performance_schema means that the attribute
refers to the whole database (it is a total). 
* Status: The value for the attribute.

The following attributes are shown, in this order, for all tables:

* row_size: The memory used for an individual record. This value will never
change.
* row_count: The number of rows in the table or buffer. For some tables, this
value depends on a server system variable.
* memory: For tables and performance_schema, this is the result of row_size *
row_count.

For internal buffers, the attributes are:

* count
* size

SHOW ENGINE ROCKSDB STATUS
--------------------------

See also MyRocks Performance Troubleshooting

URL: https://mariadb.com/kb/en/show-engine/https://mariadb.com/kb/en/show-engine/}&SHOW ERRORSSyntax
------

SHOW ERRORS [LIMIT [offset,] row_count]
SHOW ERRORS [LIMIT row_count OFFSET offset]
SHOW COUNT(*) ERRORS

Description
-----------

This statement is similar to SHOW WARNINGS, except that instead of displaying
errors, warnings, and notes, it displays only errors.

The LIMIT clause has the same syntax as for the SELECT statement.

The SHOW COUNT(*) ERRORS statement displays the number of errors. You can also
retrieve this number from the error_count variable.

SHOW COUNT(*) ERRORS;
SELECT @@error_count;

The value of error_count might be greater than the number of messages
displayed by SHOW WARNINGS if the max_error_count system variable is set so
low that not all messages are stored.

For a list of MariaDB error codes, see MariaDB Error Codes.

Examples
--------

SELECT f();
ERROR 1305 (42000): FUNCTION f does not exist

SHOW COUNT(*) ERRORS;
+-----------------------+
| @@session.error_count |
+-----------------------+
|                     1 |
+-----------------------+

SHOW ERRORS;
+-------+------+---------------------------+
| Level | Code | Message                   |
+-------+------+---------------------------+
| Error | 1305 | FUNCTION f does not exist |
+-------+------+---------------------------+

URL: https://mariadb.com/kb/en/show-errors/https://mariadb.com/kb/en/show-errors/�A���m���{�4SHOW ENGINE INNODB STATUSSHOW ENGINE INNODB STATUS is a specific form of the SHOW ENGINE statement that
displays the InnoDB Monitor output, which is extensive InnoDB information
which can be useful in diagnosing problems.

The following sections are displayed

* Status: Shows the timestamp, monitor name and the number of seconds, or the
elapsed time between the current time and the time the InnoDB Monitor output
was last displayed. The per-second averages are based upon this time.
* BACKGROUND THREAD: srv_master_thread lines show work performed by the main
background thread.
* SEMAPHORES: Threads waiting for a semaphore and stats on how the number of
times threads have needed a spin or a wait on a mutex or rw-lock semaphore. If
this number of threads is large, there may be I/O or contention issues.
Reducing the size of the innodb_thread_concurrency system variable may help if
contention is related to thread scheduling. Spin rounds per wait shows the
number of spinlock rounds per OS wait for a mutex. 
* LATEST FOREIGN KEY ERROR: Only shown if there has been a foreign key
constraint error, it displays the failed statement and information about the
constraint and the related tables.
* LATEST DETECTED DEADLOCK: Only shown if there has been a deadlock, it
displays the transactions involved in the deadlock and the statements being
executed, held and required locked and the transaction rolled back to.
* TRANSACTIONS: The output of this section can help identify lock contention,
as well as reasons for the deadlocks.
* FILE I/O: InnoDB thread information as well as pending I/O operations and
I/O performance statistics.
* INSERT BUFFER AND ADAPTIVE HASH INDEX: InnoDB insert buffer (old name for
the change buffer) and adaptive hash index status information, including the
number of each type of operation performed, and adaptive hash index
performance.
* LOG: InnoDB log information, including current log sequence number, how far
the log has been flushed to disk, the position at which InnoDB last took a
checkpoint, pending writes and write performance statistics.
* BUFFER POOL AND MEMORY: Information on buffer pool pages read and written,
which allows you to see the number of data file I/O operations performed by
your queries. See InnoDB Buffer Pool for more. Similar information is also
available from the INFORMATION_SCHEMA.INNODB_BUFFER_POOL_STATS table.
* ROW OPERATIONS:Information about the main thread, including the number and
performance rate for each type of row operation.

If the innodb_status_output_locks system variable is set to 1, extended lock
information will be displayed.

Example output:

=====================================
2019-09-06 12:44:13 0x7f93cc236700 INNODB MONITOR OUTPUT
=====================================
Per second averages calculated from the last 4 seconds
-----------------
BACKGROUND THREAD
-----------------
srv_master_thread loops: 2 srv_active, 0 srv_shutdown, 83698 srv_idle
srv_master_thread log flush and writes: 83682
----------
SEMAPHORES
----------
OS WAIT ARRAY INFO: reservation count 15
OS WAIT ARRAY INFO: signal count 8
RW-shared spins 0, rounds 20, OS waits 7
RW-excl spins 0, rounds 0, OS waits 0
RW-sx spins 0, rounds 0, OS waits 0
Spin rounds per wait: 20.00 RW-shared, 0.00 RW-excl, 0.00 RW-sx
------------
TRANSACTIONS
------------
Trx id counter 236
Purge done for trx's n:o < 236 undo n:o < 0 state: running
History list length 22
LIST OF TRANSACTIONS FOR EACH SESSION:
---TRANSACTION 421747401994584, not started
0 lock struct(s), heap size 1136, 0 row lock(s)
---TRANSACTION 421747401990328, not started
0 lock struct(s), heap size 1136, 0 row lock(s)
--------
FILE I/O
--------
I/O thread 0 state: waiting for completed aio requests (insert buffer thread)
I/O thread 1 state: waiting for completed aio requests (log thread)
I/O thread 2 state: waiting for completed aio requests (read thread)
I/O thread 3 state: waiting for completed aio requests (read thread)
I/O thread 4 state: waiting for completed aio requests (read thread)
I/O thread 5 state: waiting for completed aio requests (read thread)
I/O thread 6 state: waiting for completed aio requests (write thread)
I/O thread 7 state: waiting for completed aio requests (write thread)
I/O thread 8 state: waiting for completed aio requests (write thread)
I/O thread 9 state: waiting for completed aio requests (write thread)
Pending normal aio reads: [0, 0, 0, 0] , aio writes: [0, 0, 0, 0] ,
 ibuf aio reads:, log i/o's:, sync i/o's:
Pending flushes (fsync) log: 0; buffer pool: 0
286 OS file reads, 171 OS file writes, 22 OS fsyncs
0.00 reads/s, 0 avg bytes/read, 0.00 writes/s, 0.00 fsyncs/s
-------------------------------------
INSERT BUFFER AND ADAPTIVE HASH INDEX
-------------------------------------
Ibuf: size 1, free list len 0, seg size 2, 0 merges
merged operations:
 insert 0, delete mark 0, delete 0
discarded operations:
 insert 0, delete mark 0, delete 0
Hash table size 34679, node heap has 0 buffer(s)
Hash table size 34679, node heap has 0 buffer(s)
Hash table size 34679, node heap has 0 buffer(s)
Hash table size 34679, node heap has 0 buffer(s)
Hash table size 34679, node heap has 0 buffer(s)
Hash table size 34679, node heap has 0 buffer(s)
Hash table size 34679, node heap has 0 buffer(s)
Hash table size 34679, node heap has 0 buffer(s)
0.00 hash searches/s, 0.00 non-hash searches/s
---
LOG
---
Log sequence number 445926
Log flushed up to   445926
Pages flushed up to 445926
Last checkpoint at  445917
0 pending log flushes, 0 pending chkp writes
18 log i/o's done, 0.00 log i/o's/second
----------------------
BUFFER POOL AND MEMORY
----------------------
Total large memory allocated 167772160
Dictionary memory allocated 50768
Buffer pool size   8012
Free buffers       7611
Database pages     401
Old database pages 0
Modified db pages  0
Percent of dirty pages(LRU & free pages): 0.000
Max dirty pages percent: 75.000
Pending reads 0
Pending writes: LRU 0, flush list 0, single page 0
Pages made young 0, not young 0
0.00 youngs/s, 0.00 non-youngs/s
Pages read 264, created 137, written 156
0.00 reads/s, 0.00 creates/s, 0.00 writes/s
No buffer pool page gets since the last printout
Pages read ahead 0.00/s, evicted without access 0.00/s, Random read ahead
0.00/s
LRU len: 401, unzip_LRU len: 0
I/O sum[0]:cur[0], unzip sum[0]:cur[0]
--------------
ROW OPERATIONS
--------------
0 queries inside InnoDB, 0 queries in queue
0 read views open inside InnoDB
Process ID=4267, Main thread ID=140272021272320, state: sleeping
Number of rows inserted 1, updated 0, deleted 0, read 1
0.00 inserts/s, 0.00 updates/s, 0.00 deletes/s, 0.00 reads/s
Number of system rows inserted 0, updated 0, deleted 0, read 0
0.00 inserts/s, 0.00 updates/s, 0.00 deletes/s, 0.00 reads/s
----------------------------
END OF INNODB MONITOR OUTPUT
============================

URL: https://mariadb.com/kb/en/show-engine-innodb-status/https://mariadb.com/kb/en/show-engine-innodb-status/-�;���~�&SHOW EVENTSSyntax
------

SHOW EVENTS [{FROM | IN} schema_name]
  [LIKE 'pattern' | WHERE expr]

Description
-----------

Shows information about Event Manager events (created with CREATE EVENT).
Requires the EVENT privilege. Without any arguments, SHOW EVENTS lists all of
the events in the current schema:

SELECT CURRENT_USER(), SCHEMA();
+----------------+----------+
| CURRENT_USER() | SCHEMA() |
+----------------+----------+
| jon@ghidora    | myschema |
+----------------+----------+

SHOW EVENTS\G
*************************** 1. row ***************************
         Db: myschema
        Name: e_daily
      Definer: jon@ghidora
     Time zone: SYSTEM
        Type: RECURRING
     Execute at: NULL
   Interval value: 10
   Interval field: SECOND
       Starts: 2006-02-09 10:41:23
        Ends: NULL
       Status: ENABLED
     Originator: 0
character_set_client: latin1
collation_connection: latin1_swedish_ci
 Database Collation: latin1_swedish_ci

To see the event action, use SHOW CREATE EVENT instead, or look at the
information_schema.EVENTS table.

To see events for a specific schema, use the FROM clause. For example, to see
events for the test schema, use the following statement:

SHOW EVENTS FROM test;

The LIKE clause, if present, indicates which event names to match. The WHERE
clause can be given to select rows using more general conditions, as discussed
in Extended Show.

URL: https://mariadb.com/kb/en/show-events/https://mariadb.com/kb/en/show-events/^/SHOW FUNCTION STATUSSyntax
------

SHOW FUNCTION STATUS
  [LIKE 'pattern' | WHERE expr]

Description
-----------

This statement is similar to SHOW PROCEDURE STATUS but for stored functions.

The LIKE clause, if present on its own, indicates which function names to
match.

The WHERE and LIKE clauses can be given to select rows using more general
conditions, as discussed in Extended SHOW.

The information_schema.ROUTINES table contains more detailed information.

Examples
--------

Showing all stored functions:

SHOW FUNCTION STATUS\G
*************************** 1. row ***************************
         Db: test
        Name: VatCents
        Type: FUNCTION
      Definer: root@localhost
      Modified: 2013-06-01 12:40:31
      Created: 2013-06-01 12:40:31
   Security_type: DEFINER
      Comment:
character_set_client: utf8
collation_connection: utf8_general_ci
 Database Collation: latin1_swedish_ci

Stored functions whose name starts with 'V':

SHOW FUNCTION STATUS LIKE 'V%' \G
*************************** 1. row ***************************
         Db: test
        Name: VatCents
        Type: FUNCTION
      Definer: root@localhost
      Modified: 2013-06-01 12:40:31
      Created: 2013-06-01 12:40:31
   Security_type: DEFINER
      Comment:
character_set_client: utf8
collation_connection: utf8_general_ci
 Database Collation: latin1_swedish_ci

Stored functions with a security type of 'DEFINER':

SHOW FUNCTION STATUS WHERE Security_type LIKE 'DEFINER' \G
*************************** 1. row ***************************
         Db: test
        Name: VatCents
        Type: FUNCTION
      Definer: root@localhost
      Modified: 2013-06-01 12:40:31
      Created: 2013-06-01 12:40:31
   Security_type: DEFINER
      Comment:
character_set_client: utf8
collation_connection: utf8_general_ci
 Database Collation: latin1_swedish_ci

URL: https://mariadb.com/kb/en/show-function-status/https://mariadb.com/kb/en/show-function-status/��'SHOW LOCALESSHOW LOCALES was introduced as part of the Information Schema plugin extension.

SHOW LOCALES is used to return locales information as part of the Locales
plugin. While the information_schema.LOCALES table has 8 columns, the SHOW
LOCALES statement will only display 4 of them:

Example
-------

SHOW LOCALES;
+-----+-------+-------------------------------------+------------------------+
| Id  | Name  | Description                         | Error_Message_Language |
+-----+-------+-------------------------------------+------------------------+
|   0 | en_US | English - United States             | english                |
|   1 | en_GB | English - United Kingdom            | english                |
|   2 | ja_JP | Japanese - Japan                    | japanese               |
|   3 | sv_SE | Swedish - Sweden                    | swedish                |
...

URL: https://mariadb.com/kb/en/show-locales/https://mariadb.com/kb/en/show-locales/��	+SHOW OPEN TABLESSyntax
------

SHOW OPEN TABLES [FROM db_name]
  [LIKE 'pattern' | WHERE expr]

Description
-----------

SHOW OPEN TABLES lists the non-TEMPORARY tables that are currently open in the
table cache. See http://dev.mysql.com/doc/refman/5.1/en/table-cache.html.

The FROM and LIKE clauses may be used.

The FROM clause, if present, restricts the tables shown to those present in
the db_name database.

The LIKE clause, if present on its own, indicates which table names to match.
The WHERE and LIKE clauses can be given to select rows using more general
conditions, as discussed in Extended SHOW.

The following information is returned:

+---------------------------+------------------------------------------------+
| Column                    | Description                                    |
+---------------------------+------------------------------------------------+
| Database                  | Database name.                                 |
+---------------------------+------------------------------------------------+
| Name                      | Table name.                                    |
+---------------------------+------------------------------------------------+
| In_use                    | Number of  table instances being used.         |
+---------------------------+------------------------------------------------+
| Name_locked               | 1 if the table is name-locked, e.g. if it is   |
|                           | being dropped or renamed, otherwise 0.         |
+---------------------------+------------------------------------------------+

Before MariaDB 5.5, each use of, for example, LOCK TABLE ... WRITE would
increment In_use for that table. With the implementation of the metadata
locking improvements in MariaDB 5.5, LOCK TABLE... WRITE acquires a strong MDL
lock, and concurrent connections will wait on this MDL lock, so any subsequent
LOCK TABLE... WRITE will not increment In_use.

Example
-------

SHOW OPEN TABLES;
+----------+---------------------------+--------+-------------+
| Database | Table                     | In_use | Name_locked |
+----------+---------------------------+--------+-------------+
...
| test     | xjson                     |      0 |           0 |
| test     | jauthor                   |      0 |           0 |
| test     | locks                     |      1 |           0 |
...
+----------+---------------------------+--------+-------------+

URL: https://mariadb.com/kb/en/show-open-tables/https://mariadb.com/kb/en/show-open-tables/e�	�
����T/���	�-3SHOW PACKAGE BODY STATUSMariaDB starting with 10.3.5
----------------------------
Oracle-style packages were introduced in MariaDB 10.3.5.

Syntax
------

SHOW PACKAGE BODY STATUS
  [LIKE 'pattern' | WHERE expr]

Description
-----------

The SHOW PACKAGE BODY STATUS statement returns characteristics of stored
package bodies (implementations), such as the database, name, type, creator,
creation and modification dates, and character set information. A similar
statement, SHOW PACKAGE STATUS, displays information about stored package
specifications.

The LIKE clause, if present, indicates which package names to match. The WHERE
and LIKE clauses can be given to select rows using more general conditions, as
discussed in Extended SHOW.

The ROUTINES table in the INFORMATION_SCHEMA database contains more detailed
information.

Examples
--------

SHOW PACKAGE BODY STATUS LIKE 'pkg1'\G
*************************** 1. row ***************************
         Db: test
        Name: pkg1
        Type: PACKAGE BODY
      Definer: root@localhost
      Modified: 2018-02-27 14:44:14
      Created: 2018-02-27 14:44:14
   Security_type: DEFINER
      Comment: This is my first package body
character_set_client: utf8
collation_connection: utf8_general_ci
 Database Collation: latin1_swedish_ci

URL: https://mariadb.com/kb/en/show-package-body-status/https://mariadb.com/kb/en/show-package-body-status/�.SHOW PACKAGE STATUSMariaDB starting with 10.3.5
----------------------------
Oracle-style packages were introduced in MariaDB 10.3.5.

Syntax
------

SHOW PACKAGE STATUS
  [LIKE 'pattern' | WHERE expr]

Description
-----------

The SHOW PACKAGE STATUS statement returns characteristics of stored package
specifications, such as the database, name, type, creator, creation and
modification dates, and character set information. A similar statement, SHOW
PACKAGE BODY STATUS, displays information about stored package bodies (i.e.
implementations).

The LIKE clause, if present, indicates which package names to match. The WHERE
and LIKE clauses can be given to select rows using more general conditions, as
discussed in Extended SHOW.

The ROUTINES table in the INFORMATION_SCHEMA database contains more detailed
information.

Examples
--------

SHOW PACKAGE STATUS LIKE 'pkg1'\G
*************************** 1. row ***************************
         Db: test
        Name: pkg1
        Type: PACKAGE
      Definer: root@localhost
      Modified: 2018-02-27 14:38:15
      Created: 2018-02-27 14:38:15
   Security_type: DEFINER
      Comment: This is my first package
character_set_client: utf8
collation_connection: utf8_general_ci
 Database Collation: latin1_swedish_ci

URL: https://mariadb.com/kb/en/show-package-status/https://mariadb.com/kb/en/show-package-status/�.SHOW PROCEDURE CODESyntax
------

SHOW PROCEDURE CODE proc_name

Description
-----------

This statement is a MariaDB extension that is available only for servers that
have been built with debugging support. It displays a representation of the
internal implementation of the named stored procedure. A similar statement,
SHOW FUNCTION CODE, displays information about stored functions.

Both statements require that you be the owner of the routine or have SELECT
access to the mysql.proc table.

If the named routine is available, each statement produces a result set. Each
row in the result set corresponds to one "instruction" in the routine. The
first column is Pos, which is an ordinal number beginning with 0. The second
column is Instruction, which contains an SQL statement (usually changed from
the original source), or a directive which has meaning only to the
stored-routine handler.

Examples
--------

DELIMITER //

CREATE PROCEDURE p1 ()
 BEGIN
  DECLARE fanta INT DEFAULT 55;
  DROP TABLE t2;
  LOOP
   INSERT INTO t3 VALUES (fanta);
   END LOOP;
 END//
Query OK, 0 rows affected (0.00 sec)

SHOW PROCEDURE CODE p1//
+-----+----------------------------------------+
| Pos | Instruction                            |
+-----+----------------------------------------+
|   0 | set fanta@0 55                         |
|   1 | stmt 9 "DROP TABLE t2"                 |
|   2 | stmt 5 "INSERT INTO t3 VALUES (fanta)" |
|   3 | jump 2                                 |
+-----+----------------------------------------+

URL: https://mariadb.com/kb/en/show-procedure-code/https://mariadb.com/kb/en/show-procedure-code/�0SHOW PROCEDURE STATUSSyntax
------

SHOW PROCEDURE STATUS
  [LIKE 'pattern' | WHERE expr]

Description
-----------

This statement is a MariaDB extension. It returns characteristics of a stored
procedure, such as the database, name, type, creator, creation and
modification dates, and character set information. A similar statement, SHOW
FUNCTION STATUS, displays information about stored functions.

The LIKE clause, if present, indicates which procedure or function names to
match. The WHERE and LIKE clauses can be given to select rows using more
general conditions, as discussed in Extended SHOW.

The ROUTINES table in the INFORMATION_SCHEMA database contains more detailed
information.

Examples
--------

SHOW PROCEDURE STATUS LIKE 'p1'\G
*************************** 1. row ***************************
         Db: test
        Name: p1
        Type: PROCEDURE
      Definer: root@localhost
      Modified: 2010-08-23 13:23:03
      Created: 2010-08-23 13:23:03
   Security_type: DEFINER
      Comment:
character_set_client: latin1
collation_connection: latin1_swedish_ci
 Database Collation: latin1_swedish_ci

URL: https://mariadb.com/kb/en/show-procedure-status/https://mariadb.com/kb/en/show-procedure-status/\��
b�h�m-�����*SHOW PRIVILEGESSyntax
------

SHOW PRIVILEGES

Description
-----------

SHOW PRIVILEGES shows the list of system privileges that the MariaDB server
supports. The exact list of privileges depends on the version of your server.

Note that before MariaDB 10.3.23, MariaDB 10.4.13 and MariaDB 10.5.2 , the
Delete history privilege displays as Delete versioning rows (MDEV-20382).

Example
-------

From MariaDB 10.5.9

SHOW PRIVILEGES;
+--------------------------+---------------------------------------+-----------
--------------------------------------------------------+
| Privilege                | Context                               | Comment  
                            |
+--------------------------+---------------------------------------+-----------
--------------------------------------------------------+
| Alter                    | Tables                                | To alter
the table                                                 |
| Alter routine            | Functions,Procedures                  | To alter
or drop stored functions/procedures                       |
| Create                   | Databases,Tables,Indexes              | To create
new databases and tables                                 |
| Create routine           | Databases                             | To use
CREATE FUNCTION/PROCEDURE                                   |
| Create temporary tables  | Databases                             | To use
CREATE TEMPORARY TABLE                                      |
| Create view              | Tables                                | To create
new views                                                |
| Create user              | Server Admin                          | To create
new users                                                |
| Delete                   | Tables                                | To delete
existing rows                                            |
| Delete history           | Tables                                | To delete
versioning table historical rows                         |
| Drop                     | Databases,Tables                      | To drop
databases, tables, and views                               |
| Event                    | Server Admin                          | To
create, alter, drop and execute events                          |
| Execute                  | Functions,Procedures                  | To
execute stored routines                                         |
| File                     | File access on server                 | To read
and write files on the server                              |
| Grant option             | Databases,Tables,Functions,Procedures | To give
to other users those privileges you possess                |
| Index                    | Tables                                | To create
or drop indexes                                          |
| Insert                   | Tables                                | To insert
data into tables                                         |
| Lock tables              | Databases                             | To use
LOCK TABLES (together with SELECT privilege)                |
| Process                  | Server Admin                          | To view
the plain text of currently executing queries              |
| Proxy                    | Server Admin                          | To make
proxy user possible                                        |
| References               | Databases,Tables                      | To have
references on tables                                       |
| Reload                   | Server Admin                          | To reload
or refresh tables, logs and privileges                   |
| Binlog admin             | Server                                | To purge
binary logs                                               |
| Binlog monitor           | Server                                | To use
SHOW BINLOG STATUS and SHOW BINARY LOG                      |
| Binlog replay            | Server                                | To use
BINLOG (generated by mariadb-binlog)                        |
| Replication master admin | Server                                | To
monitor connected slaves                                        |
| Replication slave admin  | Server                                | To
start/stop slave and apply binlog events                        |
| Slave monitor            | Server                                | To use
SHOW SLAVE STATUS and SHOW RELAYLOG EVENTS                  |
| Replication slave        | Server Admin                          | To read
binary log events from the master                          |
| Select                   | Tables                                | To
retrieve rows from table                                        |
| Show databases           | Server Admin                          | To see
all databases with SHOW DATABASES                           |
| Show view                | Tables                                | To see
views with SHOW CREATE VIEW                                 |
| Shutdown                 | Server Admin                          | To shut
down the server                                            |
| Super                    | Server Admin                          | To use
KILL thread, SET GLOBAL, CHANGE MASTER, etc.                |
| Trigger                  | Tables                                | To use
triggers                                                    |
| Create tablespace        | Server Admin                          | To
create/alter/drop tablespaces                                   |
| Update                   | Tables                                | To update
existing rows                                            |
| Set user                 | Server                                | To create
views and stored routines with a different definer       |
| Federated admin          | Server                                | To
execute the CREATE SERVER, ALTER SERVER, DROP SERVER statements |
| Connection admin         | Server                                | To bypass
connection limits and kill other users' connections      |
| Read_only admin          | Server                                | To
perform write operations even if @@read_only=ON                 |
| Usage                    | Server Admin                          | No
privileges - allow connect only                                 |
+--------------------------+---------------------------------------+-----------
--------------------------------------------------------+
41 rows in set (0.000 sec)

URL: https://mariadb.com/kb/en/show-privileges/https://mariadb.com/kb/en/show-privileges/X�@����	�+SHOW PROCESSLISTSyntax
------

SHOW [FULL] PROCESSLIST

Description
-----------

SHOW PROCESSLIST shows you which threads are running. You can also get this
information from the information_schema.PROCESSLIST table or the mariadb-admin
processlist command. If you have the PROCESS privilege, you can see all
threads. Otherwise, you can see only your own threads (that is, threads
associated with the MariaDB account that you are using). If you do not use the
FULL keyword, only the first 100 characters of each statement are shown in the
Info field.

The columns shown in SHOW PROCESSLIST are:

+---------------------+------------------------------------------------------+
| Name                | Description                                          |
+---------------------+------------------------------------------------------+
| ID                  | The client's process ID.                             |
+---------------------+------------------------------------------------------+
| USER                | The username associated with the process.            |
+---------------------+------------------------------------------------------+
| HOST                | The host the client is connected to.                 |
+---------------------+------------------------------------------------------+
| DB                  | The default database of the process (NULL if no      |
|                     | default).                                            |
+---------------------+------------------------------------------------------+
| COMMAND             | The command type. See Thread Command Values.         |
+---------------------+------------------------------------------------------+
| TIME                | The amount of time, in seconds, the process has      |
|                     | been in its current state. For a replica SQL thread  |
|                     | before MariaDB 10.1, this is the time in seconds     |
|                     | between the last replicated event's timestamp and    |
|                     | the replica machine's real time.                     |
+---------------------+------------------------------------------------------+
| STATE               | See Thread States.                                   |
+---------------------+------------------------------------------------------+
| INFO                | The statement being executed.                        |
+---------------------+------------------------------------------------------+
| PROGRESS            | The total progress of the process (0-100%) (see      |
|                     | Progress Reporting).                                 |
+---------------------+------------------------------------------------------+

See TIME_MS column in information_schema.PROCESSLIST for differences in the
TIME column between MariaDB and MySQL.

The information_schema.PROCESSLIST table contains the following additional
columns:

+---------------------+------------------------------------------------------+
| Name                | Description                                          |
+---------------------+------------------------------------------------------+
| TIME_MS             | The amount of time, in milliseconds, the process     |
|                     | has been in its current state.                       |
+---------------------+------------------------------------------------------+
| STAGE               | The stage the process is currently in.               |
+---------------------+------------------------------------------------------+
| MAX_STAGE           | The maximum number of stages.                        |
+---------------------+------------------------------------------------------+
| PROGRESS            | The progress of the process within the current       |
|                     | stage (0-100%).                                      |
+---------------------+------------------------------------------------------+
| MEMORY_USED         | The amount of memory used by the process.            |
+---------------------+------------------------------------------------------+
| EXAMINED_ROWS       | The number of rows the process has examined.         |
+---------------------+------------------------------------------------------+
| QUERY_ID            | Query ID.                                            |
+---------------------+------------------------------------------------------+

Note that the PROGRESS field from the information schema, and the PROGRESS
field from SHOW PROCESSLIST display different results. SHOW PROCESSLIST shows
the total progress, while the information schema shows the progress for the
current stage only.

Threads can be killed using their thread_id or their query_id, with the KILL
statement.

Since queries on this table are locking, if the performance_schema is enabled,
you may want to query the THREADS table instead.

Examples
--------

SHOW PROCESSLIST;
+----+-----------------+-----------+------+---------+------+-------------------
----+------------------+----------+
| Id | User            | Host      | db   | Command | Time | State            
  | Info             | Progress |
+----+-----------------+-----------+------+---------+------+-------------------
----+------------------+----------+
|  2 | event_scheduler | localhost | NULL | Daemon  | 2693 | Waiting on empty
queue | NULL             |    0.000 |
|  4 | root            | localhost | NULL | Query   |    0 | Table lock       
  | SHOW PROCESSLIST |    0.000 |
+----+-----------------+-----------+------+---------+------+-------------------
----+------------------+----------+

URL: https://mariadb.com/kb/en/show-processlist/https://mariadb.com/kb/en/show-processlist/e�p]q����'SHOW PROFILESyntax
------

SHOW PROFILE [type [, type] ... ]
  [FOR QUERY n]
  [LIMIT row_count [OFFSET offset]]

type:
  ALL
 | BLOCK IO
 | CONTEXT SWITCHES
 | CPU
 | IPC
 | MEMORY
 | PAGE FAULTS
 | SOURCE
 | SWAPS

Description
-----------

The SHOW PROFILE and SHOW PROFILES statements display profiling information
that indicates resource usage for statements executed during the course of the
current session.

Profiling is controlled by the profiling session variable, which has a default
value of 0 (OFF). Profiling is enabled by setting profiling to 1 or ON:

SET profiling = 1;

SHOW PROFILES displays a list of the most recent statements sent to the
master. The size of the list is controlled by the profiling_history_size
session variable, which has a default value of 15. The maximum value is 100.
Setting the value to 0 has the practical effect of disabling profiling.

All statements are profiled except SHOW PROFILES and SHOW PROFILE, so you will
find neither of those statements in the profile list. Malformed statements are
profiled. For example, SHOW PROFILING is an illegal statement, and a syntax
error occurs if you try to execute it, but it will show up in the profiling
list.

SHOW PROFILE displays detailed information about a single statement. Without
the FOR QUERY n clause, the output pertains to the most recently executed
statement. If FOR QUERY n is included, SHOW PROFILE displays information for
statement n. The values of n correspond to the Query_ID values displayed by
SHOW PROFILES.

The LIMIT row_count clause may be given to limit the output to row_count rows.
If LIMIT is given, OFFSET offset may be added to begin the output offset rows
into the full set of rows.

By default, SHOW PROFILE displays Status and Duration columns. The Status
values are like the State values displayed by SHOW PROCESSLIST, although there
might be some minor differences in interpretation for the two statements for
some status values (see
http://dev.mysql.com/doc/refman/5.6/en/thread-information.html).

Optional type values may be specified to display specific additional types of
information:

* ALL displays all information
* BLOCK IO displays counts for block input and output operations
* CONTEXT SWITCHES displays counts for voluntary and involuntary context
switches
* CPU displays user and system CPU usage times
* IPC displays counts for messages sent and received
* MEMORY is not currently implemented
* PAGE FAULTS displays counts for major and minor page faults
* SOURCE displays the names of functions from the source code, together with
the name and line number of the file in which the function occurs
* SWAPS displays swap counts

Profiling is enabled per session. When a session ends, its profiling
information is lost.

The information_schema.PROFILING table contains similar information.

Examples
--------

SELECT @@profiling;
+-------------+
| @@profiling |
+-------------+
|           0 |
+-------------+

SET profiling = 1;

USE test;

DROP TABLE IF EXISTS t1;

CREATE TABLE T1 (id INT);

SHOW PROFILES;
+----------+------------+--------------------------+
| Query_ID | Duration   | Query                    |
+----------+------------+--------------------------+
|        1 | 0.00009200 | SELECT DATABASE()        |
|        2 | 0.00023800 | show databases           |
|        3 | 0.00018900 | show tables              |
|        4 | 0.00014700 | DROP TABLE IF EXISTS t1  |
|        5 | 0.24476900 | CREATE TABLE T1 (id INT) |
+----------+------------+--------------------------+

SHOW PROFILE;
+----------------------+----------+
| Status               | Duration |
+----------------------+----------+
| starting             | 0.000042 |
| checking permissions | 0.000044 |
| creating table       | 0.244645 |
| After create         | 0.000013 |
| query end            | 0.000003 |
| freeing items        | 0.000016 |
| logging slow query   | 0.000003 |
| cleaning up          | 0.000003 |
+----------------------+----------+

SHOW PROFILE FOR QUERY 4;
+--------------------+----------+
| Status             | Duration |
+--------------------+----------+
| starting           | 0.000126 |
| query end          | 0.000004 |
| freeing items      | 0.000012 |
| logging slow query | 0.000003 |
| cleaning up        | 0.000002 |
+--------------------+----------+

SHOW PROFILE CPU FOR QUERY 5;
+----------------------+----------+----------+------------+
| Status               | Duration | CPU_user | CPU_system |
+----------------------+----------+----------+------------+
| starting             | 0.000042 | 0.000000 |   0.000000 |
| checking permissions | 0.000044 | 0.000000 |   0.000000 |
| creating table       | 0.244645 | 0.000000 |   0.000000 |
| After create         | 0.000013 | 0.000000 |   0.000000 |
| query end            | 0.000003 | 0.000000 |   0.000000 |
| freeing items        | 0.000016 | 0.000000 |   0.000000 |
| logging slow query   | 0.000003 | 0.000000 |   0.000000 |
| cleaning up          | 0.000003 | 0.000000 |   0.000000 |
+----------------------+----------+----------+------------+

URL: https://mariadb.com/kb/en/show-profile/https://mariadb.com/kb/en/show-profile/! ���f&SHOW STATUSSyntax
------

SHOW [GLOBAL | SESSION] STATUS
  [LIKE 'pattern' | WHERE expr]

Description
-----------

SHOW STATUS provides server status information. This information also can be
obtained using the mariadb-admin extended-status command, or by querying the
Information Schema GLOBAL_STATUS and SESSION_STATUS tables. The LIKE clause,
if present, indicates which variable names to match. The WHERE clause can be
given to select rows using more general conditions.

With the GLOBAL modifier, SHOW STATUS displays the status values for all
connections to MariaDB. With SESSION, it displays the status values for the
current connection. If no modifier is present, the default is SESSION. LOCAL
is a synonym for SESSION. If you see a lot of 0 values, the reason is probably
that you have used SHOW STATUS with a new connection instead of SHOW GLOBAL
STATUS.

Some status variables have only a global value. For these, you get the same
value for both GLOBAL and SESSION.

See Server Status Variables for a full list, scope and description of the
variables that can be viewed with SHOW STATUS.

The LIKE clause, if present on its own, indicates which variable name to match.

The WHERE and LIKE clauses can be given to select rows using more general
conditions, as discussed in Extended SHOW.

Examples
--------

SHOW GLOBAL STATUS;
+--------------------------------------------------------------+---------------
------------------------+
| Variable_name                                                | Value        
            |
+--------------------------------------------------------------+---------------
------------------------+
| Aborted_clients                                              | 0            
            |
| Aborted_connects                                             | 0            
            |
| Access_denied_errors                                         | 0            
            |
| Acl_column_grants                                            | 0            
            |
| Acl_database_grants                                          | 2            
            |
| Acl_function_grants                                          | 0            
            |
| Acl_procedure_grants                                         | 0            
            |
| Acl_proxy_users                                              | 2            
            |
| Acl_role_grants                                              | 0            
            |
| Acl_roles                                                    | 0            
            |
| Acl_table_grants                                             | 0            
            |
| Acl_users                                                    | 6            
            |
| Aria_pagecache_blocks_not_flushed                            | 0            
            |
| Aria_pagecache_blocks_unused                                 | 15706        
            |
...
| wsrep_local_index                                            |
18446744073709551615                   |
| wsrep_provider_name                                          |              
            |
| wsrep_provider_vendor                                        |              
            |
| wsrep_provider_version                                       |              
            |
| wsrep_ready                                                  | OFF          
            |
| wsrep_thread_count                                           | 0            
            |
+--------------------------------------------------------------+---------------
------------------------+
516 rows in set (0.00 sec)

Example of filtered output:

SHOW STATUS LIKE 'Key%';
+------------------------+--------+
| Variable_name          | Value  |
+------------------------+--------+
| Key_blocks_not_flushed | 0      |
| Key_blocks_unused      | 107163 |
| Key_blocks_used        | 0      |
| Key_blocks_warm        | 0      |
| Key_read_requests      | 0      |
| Key_reads              | 0      |
| Key_write_requests     | 0      |
| Key_writes             | 0      |
+------------------------+--------+
8 rows in set (0.00 sec)

URL: https://mariadb.com/kb/en/show-status/https://mariadb.com/kb/en/show-status/��	&SHOW TABLESSyntax
------

SHOW [FULL] TABLES [FROM db_name]
  [LIKE 'pattern' | WHERE expr]

Description
-----------

SHOW TABLES lists the tables (until MariaDB 11.2.0, only non-TEMPORARY tables
are shown), sequences and views in a given database.

The LIKE clause, if present on its own, indicates which table names to match.
The WHERE and LIKE clauses can be given to select rows using more general
conditions, as discussed in Extended SHOW. For example, when searching for
tables in the test database, the column name for use in the WHERE and LIKE
clauses will be Tables_in_test

The FULL modifier is supported such that SHOW FULL TABLES displays a second
output column. Values for the second column, Table_type, are BASE TABLE for a
table, VIEW for a view and SEQUENCE for a sequence.

You can also get this information using:

mariadb-show db_name

See mariadb-show for more details.

If you have no privileges for a base table or view, it does not show up in the
output from SHOW TABLES or mariadb-show db_name.

The information_schema.TABLES table, as well as the SHOW TABLE STATUS
statement, provide extended information about tables.

Examples
--------

SHOW TABLES;
+----------------------+
| Tables_in_test       |
+----------------------+
| animal_count         |
| animals              |
| are_the_mooses_loose |
| aria_test2           |
| t1                   |
| view1                |
+----------------------+

Showing the tables beginning with a only.

SHOW TABLES WHERE Tables_in_test LIKE 'a%';
+----------------------+
| Tables_in_test       |
+----------------------+
| animal_count         |
| animals              |
| are_the_mooses_loose |
| aria_test2           |
+----------------------+

Showing tables and table types:

SHOW FULL TABLES;
+----------------+------------+
| Tables_in_test | Table_type |
+----------------+------------+
| s1             | SEQUENCE   |
| student        | BASE TABLE |
| v1             | VIEW       |
+----------------+------------+

Showing temporary tables: <= MariaDB 11.1

CREATE TABLE t (t int(11));
CREATE TEMPORARY TABLE t (t int(11));
CREATE TEMPORARY TABLE te (t int(11));

SHOW TABLES;
+----------------+
| Tables_in_test |
+----------------+
| t              |
+----------------+

From MariaDB 11.2.0:

CREATE TABLE t (t int(11));
CREATE TEMPORARY TABLE t (t int(11));
CREATE TEMPORARY TABLE te (t int(11));

SHOW TABLES;
+----------------+
| Tables_in_test |
+----------------+
| te             |
| t              |
| t              |
+----------------+

URL: https://mariadb.com/kb/en/show-tables/https://mariadb.com/kb/en/show-tables/�<
�̎�����,SHOW TABLE STATUSSyntax
------

SHOW TABLE STATUS [{FROM | IN} db_name]
  [LIKE 'pattern' | WHERE expr]

Description
-----------

SHOW TABLE STATUS works like SHOW TABLES, but provides more extensive
information about each table (until MariaDB 11.2.0, only non-TEMPORARY tables
are shown).

The LIKE clause, if present on its own, indicates which table names to match.
The WHERE and LIKE clauses can be given to select rows using more general
conditions, as discussed in Extended SHOW.

The following information is returned:

+---------------------------+------------------------------------------------+
| Column                    | Description                                    |
+---------------------------+------------------------------------------------+
| Name                      | Table name.                                    |
+---------------------------+------------------------------------------------+
| Engine                    | Table storage engine.                          |
+---------------------------+------------------------------------------------+
| Version                   | Version number from the table's .frm file.     |
+---------------------------+------------------------------------------------+
| Row_format                | Row format (see InnoDB, Aria and MyISAM row    |
|                           | formats).                                      |
+---------------------------+------------------------------------------------+
| Rows                      | Number of rows in the table. Some engines,     |
|                           | such as InnoDB may store an estimate.          |
+---------------------------+------------------------------------------------+
| Avg_row_length            | Average row length in the table.               |
+---------------------------+------------------------------------------------+
| Data_length               | For InnoDB, the index size, in pages,          |
|                           | multiplied by the page size. For Aria and      |
|                           | MyISAM, length of the data file, in bytes.     |
|                           | For MEMORY, the approximate allocated memory.  |
+---------------------------+------------------------------------------------+
| Max_data_length           | Maximum length of the data file, ie the total  |
|                           | number of bytes that could be stored in the    |
|                           | table. Not used in InnoDB.                     |
+---------------------------+------------------------------------------------+
| Index_length              | Length of the index file.                      |
+---------------------------+------------------------------------------------+
| Data_free                 | Bytes allocated but unused. For InnoDB tables  |
|                           | in a shared tablespace, the free space of the  |
|                           | shared tablespace with small safety margin.    |
|                           | An estimate in the case of partitioned tables  |
|                           | - see the PARTITIONS table.                    |
+---------------------------+------------------------------------------------+
| Auto_increment            | Next AUTO_INCREMENT value.                     |
+---------------------------+------------------------------------------------+
| Create_time               | Time the table was created. Some engines just  |
|                           | return the ctime information from the file     |
|                           | system layer here, in that case the value is   |
|                           | not necessarily the table creation time but    |
|                           | rather the time the file system metadata for   |
|                           | it had last changed.                           |
+---------------------------+------------------------------------------------+
| Update_time               | Time the table was last updated. On Windows,   |
|                           | the timestamp is not updated on update, so     |
|                           | MyISAM values will be inaccurate. In InnoDB,   |
|                           | if shared tablespaces are used, will be NULL,  |
|                           | while buffering can also delay the update, so  |
|                           | the value will differ from the actual time of  |
|                           | the last UPDATE, INSERT or DELETE.             |
+---------------------------+------------------------------------------------+
| Check_time                | Time the table was last checked. Not kept by   |
|                           | all storage engines, in which case will be     |
|                           | NULL.                                          |
+---------------------------+------------------------------------------------+
| Collation                 | Character set and collation.                   |
+---------------------------+------------------------------------------------+
| Checksum                  | Live checksum value, if any.                   |
+---------------------------+------------------------------------------------+
| Create_options            | Extra CREATE TABLE options.                    |
+---------------------------+------------------------------------------------+
| Comment                   | Table comment provided when MariaDB created    |
|                           | the table.                                     |
+---------------------------+------------------------------------------------+
| Max_index_length          | Maximum index length (supported by MyISAM and  |
|                           | Aria tables).                                  |
+---------------------------+------------------------------------------------+
| Temporary                 | Until MariaDB 11.2.0, placeholder to signal    |
|                           | that a table is a temporary table and always   |
|                           | "N", except "Y" for generated                  |
|                           | information_schema tables and NULL for views.  |
|                           | From MariaDB 11.2.0, will also be set to "Y"   |
|                           | for local temporary tables.                    |
+---------------------------+------------------------------------------------+

Similar information can be found in the information_schema.TABLES table as
well as by using mariadb-show:

mariadb-show --status db_name

Views
-----

For views, all columns in SHOW TABLE STATUS are NULL except 'Name' and
'Comment'

Example
-------

show table status\G
*************************** 1. row ***************************
     Name: bus_routes
    Engine: InnoDB
    Version: 10
  Row_format: Dynamic
     Rows: 5
 Avg_row_length: 3276
  Data_length: 16384
Max_data_length: 0
 Index_length: 0
   Data_free: 0
 Auto_increment: NULL
  Create_time: 2017-05-24 11:17:46
  Update_time: NULL
  Check_time: NULL
   Collation: latin1_swedish_ci
   Checksum: NULL
 Create_options: 
    Comment:

URL: https://mariadb.com/kb/en/show-table-status/https://mariadb.com/kb/en/show-table-status/��a��J0SHOW TABLE_STATISTICSSyntax
------

SHOW TABLE_STATISTICS

Description
-----------

The SHOW TABLE_STATISTICS statementis part of the User Statistics feature. It
was removed as a separate statement in MariaDB 10.1.1, but effectively
replaced by the generic SHOW information_schema_table statement. The
information_schema.TABLE_STATISTICS table shows statistics on table usage

The userstat system variable must be set to 1 to activate this feature. See
the User Statistics and information_schema.TABLE_STATISTICS articles for more
information.

Example
-------

SHOW TABLE_STATISTICS\G
*************************** 1. row ***************************
     Table_schema: mysql
      Table_name: proxies_priv
       Rows_read: 2
     Rows_changed: 0
Rows_changed_x_#indexes: 0
*************************** 2. row ***************************
     Table_schema: test
      Table_name: employees_example
       Rows_read: 7
     Rows_changed: 0
Rows_changed_x_#indexes: 0
*************************** 3. row ***************************
     Table_schema: mysql
      Table_name: user
       Rows_read: 16
     Rows_changed: 0
Rows_changed_x_#indexes: 0
*************************** 4. row ***************************
     Table_schema: mysql
      Table_name: db
       Rows_read: 2
     Rows_changed: 0
Rows_changed_x_#indexes: 0

URL: https://mariadb.com/kb/en/show-table-statistics/https://mariadb.com/kb/en/show-table-statistics/�
(SHOW TRIGGERSSyntax
------

SHOW TRIGGERS [FROM db_name]
  [LIKE 'pattern' | WHERE expr]

Description
-----------

SHOW TRIGGERS lists the triggers currently defined for tables in a database
(the default database unless a FROM clause is given). This statement requires
the TRIGGER privilege (prior to MySQL 5.1.22, it required the SUPER privilege).

The LIKE clause, if present on its own, indicates which table names to match
and causes the statement to display triggers for those tables. The WHERE and
LIKE clauses can be given to select rows using more general conditions, as
discussed in Extended SHOW.

Similar information is stored in the information_schema.TRIGGERS table.

MariaDB starting with 10.2.3
----------------------------
If there are multiple triggers for the same action, then the triggers are
shown in action order.

Examples
--------

For the trigger defined at Trigger Overview:

SHOW triggers Like 'animals' \G
*************************** 1. row ***************************
      Trigger: the_mooses_are_loose
       Event: INSERT
       Table: animals
     Statement: BEGIN
 IF NEW.name = 'Moose' THEN
 UPDATE animal_count SET animal_count.animals = animal_count.animals+100;
 ELSE 
 UPDATE animal_count SET animal_count.animals = animal_count.animals+1;
 END IF;
END
       Timing: AFTER
      Created: 2016-09-29 13:53:34.35
      sql_mode:
      Definer: root@localhost
character_set_client: utf8
collation_connection: utf8_general_ci
 Database Collation: latin1_swedish_ci

Listing all triggers associated with a certain table:

SHOW TRIGGERS FROM test WHERE `Table` = 'user' \G
*************************** 1. row ***************************
      Trigger: user_ai
       Event: INSERT
       Table: user
     Statement: BEGIN END
       Timing: AFTER
      Created:  2016-09-29 13:53:34.35
      sql_mode:
      Definer: root@%
character_set_client: utf8
collation_connection: utf8_general_ci
 Database Collation: latin1_swedish_ci

SHOW triggers WHERE Event Like 'Insert' \G
*************************** 1. row ***************************
      Trigger: the_mooses_are_loose
       Event: INSERT
       Table: animals
     Statement: BEGIN
 IF NEW.name = 'Moose' THEN
 UPDATE animal_count SET animal_count.animals = animal_count.animals+100;
 ELSE 
 UPDATE animal_count SET animal_count.animals = animal_count.animals+1;
 END IF;
END
       Timing: AFTER
      Created: 2016-09-29 13:53:34.35
      sql_mode:
      Definer: root@localhost
character_set_client: utf8
collation_connection: utf8_general_ci
 Database Collation: latin1_swedish_ci

* character_set_client is the session value of the character_set_client system
variable when the trigger was created. 
* collation_connection is the session value of the collation_connection system
variable when the trigger was
 created. 
* Database Collation is the collation of the database 
 with which the trigger is associated.

These columns were added in MariaDB/MySQL 5.1.21.

Old triggers created before MySQL 5.7 and MariaDB 10.2.3 has NULL in the
Created column.

URL: https://mariadb.com/kb/en/show-triggers/https://mariadb.com/kb/en/show-triggers/��/SHOW USER_STATISTICSSyntax
------

SHOW USER_STATISTICS

Description
-----------

The SHOW USER_STATISTICS statement is part of the User Statistics feature. It
was removed as a separate statement in MariaDB 10.1.1, but effectively
replaced by the generic SHOW information_schema_table statement. The
information_schema.USER_STATISTICS table holds statistics about user activity.
You can use this table to find out such things as which user is causing the
most load and which users are being abusive. You can also use this table to
measure how close to capacity the server may be.

The userstat system variable must be set to 1 to activate this feature. See
the User Statistics and information_schema.USER_STATISTICS table for more
information.

Example
-------

SHOW USER_STATISTICS\G
*************************** 1. row ***************************
         User: root
  Total_connections: 1
Concurrent_connections: 0
    Connected_time: 3297
      Busy_time: 0.14113400000000006
       Cpu_time: 0.017637000000000003
    Bytes_received: 969
      Bytes_sent: 22355
 Binlog_bytes_written: 0
      Rows_read: 10
      Rows_sent: 67
     Rows_deleted: 0
    Rows_inserted: 0
     Rows_updated: 0
   Select_commands: 7
   Update_commands: 0
    Other_commands: 0
 Commit_transactions: 1
 Rollback_transactions: 0
  Denied_connections: 0
   Lost_connections: 0
    Access_denied: 0
    Empty_queries: 7

URL: https://mariadb.com/kb/en/show-user-statistics/https://mariadb.com/kb/en/show-user-statistics/���K����f���)SHOW VARIABLESSyntax
------

SHOW [GLOBAL | SESSION] VARIABLES
  [LIKE 'pattern' | WHERE expr]

Description
-----------

SHOW VARIABLES shows the values of MariaDB system variables. This information
also can be obtained using the mariadb-admin variables command. The LIKE
clause, if present, indicates which variable names to match. The WHERE clause
can be given to select rows using more general conditions.

With the GLOBAL modifier, SHOW VARIABLES displays the values that are used for
new connections to MariaDB. With SESSION, it displays the values that are in
effect for the current connection. If no modifier is present, the default is
SESSION. LOCAL is a synonym for SESSION. With a LIKE clause, the statement
displays only rows for those variables with names that match the pattern. To
obtain the row for a specific variable, use a LIKE clause as shown:

SHOW VARIABLES LIKE 'maria_group_commit';
SHOW SESSION VARIABLES LIKE 'maria_group_commit';

To get a list of variables whose name match a pattern, use the "%" wildcard
character in a LIKE clause:

SHOW VARIABLES LIKE '%maria%';
SHOW GLOBAL VARIABLES LIKE '%maria%';

Wildcard characters can be used in any position within the pattern to be
matched. Strictly speaking, because "_" is a wildcard that matches any single
character, you should escape it as "\_" to match it literally. In practice,
this is rarely necessary.

The WHERE and LIKE clauses can be given to select rows using more general
conditions, as discussed in Extended SHOW.

See SET for information on setting server system variables.

See Server System Variables for a list of all the variables that can be set.

You can also see the server variables by querying the Information Schema
GLOBAL_VARIABLES and SESSION_VARIABLES tables.

Examples
--------

SHOW VARIABLES LIKE 'aria%';
+------------------------------------------+---------------------+
| Variable_name                            | Value               |
+------------------------------------------+---------------------+
| aria_block_size                          | 8192                |
| aria_checkpoint_interval                 | 30                  |
| aria_checkpoint_log_activity             | 1048576             |
| aria_force_start_after_recovery_failures | 0                   |
| aria_group_commit                        | none                |
| aria_group_commit_interval               | 0                   |
| aria_log_file_size                       | 1073741824          |
| aria_log_purge_type                      | immediate           |
| aria_max_sort_file_size                  | 9223372036853727232 |
| aria_page_checksum                       | ON                  |
| aria_pagecache_age_threshold             | 300                 |
| aria_pagecache_buffer_size               | 134217728           |
| aria_pagecache_division_limit            | 100                 |
| aria_recover                             | NORMAL              |
| aria_repair_threads                      | 1                   |
| aria_sort_buffer_size                    | 134217728           |
| aria_stats_method                        | nulls_unequal       |
| aria_sync_log_dir                        | NEWFILE             |
| aria_used_for_temp_tables                | ON                  |
+------------------------------------------+---------------------+

SELECT VARIABLE_NAME, SESSION_VALUE, GLOBAL_VALUE FROM
 INFORMATION_SCHEMA.SYSTEM_VARIABLES WHERE
 VARIABLE_NAME LIKE 'max_error_count' OR
 VARIABLE_NAME LIKE 'innodb_sync_spin_loops';
+---------------------------+---------------+--------------+
| VARIABLE_NAME             | SESSION_VALUE | GLOBAL_VALUE |
+---------------------------+---------------+--------------+
| MAX_ERROR_COUNT           | 64            | 64           |
| INNODB_SYNC_SPIN_LOOPS    | NULL          | 30           |
+---------------------------+---------------+--------------+

SET GLOBAL max_error_count=128;

SELECT VARIABLE_NAME, SESSION_VALUE, GLOBAL_VALUE FROM
 INFORMATION_SCHEMA.SYSTEM_VARIABLES WHERE
 VARIABLE_NAME LIKE 'max_error_count' OR
 VARIABLE_NAME LIKE 'innodb_sync_spin_loops';
+---------------------------+---------------+--------------+
| VARIABLE_NAME             | SESSION_VALUE | GLOBAL_VALUE |
+---------------------------+---------------+--------------+
| MAX_ERROR_COUNT           | 64            | 128          |
| INNODB_SYNC_SPIN_LOOPS    | NULL          | 30           |
+---------------------------+---------------+--------------+

SET GLOBAL max_error_count=128;

SHOW VARIABLES LIKE 'max_error_count';
+-----------------+-------+
| Variable_name   | Value |
+-----------------+-------+
| max_error_count | 64    |
+-----------------+-------+

SHOW GLOBAL VARIABLES LIKE 'max_error_count';
+-----------------+-------+
| Variable_name   | Value |
+-----------------+-------+
| max_error_count | 128   |
+-----------------+-------+

Because the following variable only has a global scope, the global value is
returned even when specifying SESSION (in this case by default):

SHOW VARIABLES LIKE 'innodb_sync_spin_loops';
+------------------------+-------+
| Variable_name          | Value |
+------------------------+-------+
| innodb_sync_spin_loops | 30    |
+------------------------+-------+

URL: https://mariadb.com/kb/en/show-variables/https://mariadb.com/kb/en/show-variables/��g0 �
�
.(SHOW WARNINGSSyntax
------

SHOW WARNINGS [LIMIT [offset,] row_count]
SHOW ERRORS [LIMIT row_count OFFSET offset]
SHOW COUNT(*) WARNINGS

Description
-----------

SHOW WARNINGS shows the error, warning, and note messages that resulted from
the last statement that generated messages in the current session. It shows
nothing if the last statement used a table and generated no messages. (That
is, a statement that uses a table but generates no messages clears the message
list.) Statements that do not use tables and do not generate messages have no
effect on the message list.

A note is different to a warning in that it only appears if the sql_notes
variable is set to 1 (the default), and is not converted to an error if strict
mode is enabled.

A related statement, SHOW ERRORS, shows only the errors.

The SHOW COUNT(*) WARNINGS statement displays the total number of errors,
warnings, and notes. You can also retrieve this number from the warning_count
variable:

SHOW COUNT(*) WARNINGS;
SELECT @@warning_count;

The value of warning_count might be greater than the number of messages
displayed by SHOW WARNINGS if the max_error_count system variable is set so
low that not all messages are stored.

The LIMIT clause has the same syntax as for the SELECT statement.

SHOW WARNINGS can be used after EXPLAIN EXTENDED to see how a query is
internally rewritten by MariaDB.

If the sql_notes server variable is set to 1, Notes are included in the output
of SHOW WARNINGS; if it is set to 0, this statement will not show (or count)
Notes.

The results of SHOW WARNINGS and SHOW COUNT(*) WARNINGS are directly sent to
the client. If you need to access those information in a stored program, you
can use the GET DIAGNOSTICS statement instead.

For a list of MariaDB error codes, see MariaDB Error Codes.

The mariadb client also has a number of options related to warnings. The \W
command will show warnings after every statement, while \w will disable this.
Starting the client with the --show-warnings option will show warnings after
every statement.

MariaDB implements a stored routine error stack trace. SHOW WARNINGS can also
be used to show more information. See the example below.

Examples
--------

SELECT 1/0;
+------+
| 1/0  |
+------+
| NULL |
+------+

SHOW COUNT(*) WARNINGS;
+-------------------------+
| @@session.warning_count |
+-------------------------+
|                       1 |
+-------------------------+

SHOW WARNINGS;
+---------+------+---------------+
| Level   | Code | Message       |
+---------+------+---------------+
| Warning | 1365 | Division by 0 |
+---------+------+---------------+

Stack Trace
-----------

Displaying a stack trace:

DELIMITER $$
CREATE OR REPLACE PROCEDURE p1()
 BEGIN
  DECLARE c CURSOR FOR SELECT * FROM not_existing;
  OPEN c;
  CLOSE c;
 END;
$$
CREATE OR REPLACE PROCEDURE p2()
 BEGIN
  CALL p1;
 END;
$$
DELIMITER ;
CALL p2;
ERROR 1146 (42S02): Table 'test.not_existing' doesn't exist

SHOW WARNINGS;
+-------+------+-----------------------------------------+
| Level | Code | Message                                 |
+-------+------+-----------------------------------------+
| Error | 1146 | Table 'test.not_existing' doesn't exist |
| Note  | 4091 | At line 6 in test.p1                    |
| Note  | 4091 | At line 4 in test.p2                    |
+-------+------+-----------------------------------------+

SHOW WARNINGS displays a stack trace, showing where the error actually
happened:

* Line 4 in test.p1 is the OPEN command which actually raised the error
* Line 3 in test.p2 is the CALL statement, calling p1 from p2.

URL: https://mariadb.com/kb/en/show-warnings/https://mariadb.com/kb/en/show-warnings/��0SHOW WSREP_MEMBERSHIPSHOW WSREP_MEMBERSHIP is part of the WSREP_INFO plugin.

Syntax
------

SHOW WSREP_MEMBERSHIP

Description
-----------

The SHOW WSREP_MEMBERSHIP statement returns Galera node cluster membership
information. It returns the same information as found in the
information_schema.WSREP_MEMBERSHIP table. Only users with the SUPER privilege
can access this information.

Examples
--------

SHOW WSREP_MEMBERSHIP;
+-------+--------------------------------------+----------+-----------------+
| Index | Uuid                                 | Name     | Address         |
+-------+--------------------------------------+----------+-----------------+
|     0 | 19058073-8940-11e4-8570-16af7bf8fced | my_node1 | 10.0.2.15:16001 |
|     1 | 19f2b0e0-8942-11e4-9cb8-b39e8ee0b5dd | my_node3 | 10.0.2.15:16003 |
|     2 | d85e62db-8941-11e4-b1ef-4bc9980e476d | my_node2 | 10.0.2.15:16002 |
+-------+--------------------------------------+----------+-----------------+

URL: https://mariadb.com/kb/en/show-wsrep_membership/https://mariadb.com/kb/en/show-wsrep_membership/��,SHOW WSREP_STATUSSHOW WSREP_STATUS is part of the WSREP_INFO plugin.

Syntax
------

SHOW WSREP_STATUS

Description
-----------

The SHOW WSREP_STATUS statement returns Galera node and cluster status
information. It returns the same information as found in the
information_schema.WSREP_STATUS table. Only users with the SUPER privilege can
access this information.

Examples
--------

SHOW WSREP_STATUS;
+------------+-------------+----------------+--------------+
| Node_Index | Node_Status | Cluster_Status | Cluster_Size |
+------------+-------------+----------------+--------------+
|          0 | Synced      | Primary        |            3 |
+------------+-------------+----------------+--------------+

URL: https://mariadb.com/kb/en/show-wsrep_status/https://mariadb.com/kb/en/show-wsrep_status/�1}Bq"�b����,PURGE BINARY LOGSSyntax
------

PURGE { BINARY | MASTER } LOGS
  { TO 'log_name' | BEFORE datetime_expr }

Description
-----------

The PURGE BINARY LOGS statement deletes all the binary log files listed in the
log index file prior to the specified log file name or date. BINARY and MASTER
are synonyms. Deleted log files also are removed from the list recorded in the
index file, so that the given log file becomes the first in the list.

The datetime expression is in the format 'YYYY-MM-DD hh:mm:ss'.

If a replica is active but has yet to read from a binary log file you attempt
to delete, the statement will fail with an error. However, if the replica is
not connected and has yet to read from a log file you delete, the file will be
deleted, but the replica will be unable to continue replicating once it
connects again.

This statement has no effect if the server was not started with the --log-bin
option to enable binary logging.

To list the binary log files on the server, use SHOW BINARY LOGS. To see which
files they are reading, use SHOW SLAVE STATUS (or SHOW REPLICA STATUS from
MariaDB 10.5.1). You can only delete the files that are older than the oldest
file that is used by the slaves.

To delete all binary log files, use RESET MASTER. To move to a new log file
(for example if you want to remove the current log file), use FLUSH LOGS
before you execute PURGE LOGS.

If the expire_logs_days server system variable is not set to 0, the server
automatically deletes binary log files after the given number of days. From
MariaDB 10.6, the binlog_expire_logs_seconds variable allows more precise
control over binlog deletion, and takes precedence if both are non-zero.

Requires the SUPER privilege or, from MariaDB 10.5.2, the BINLOG ADMIN
privilege, to run.

Examples
--------

PURGE BINARY LOGS TO 'mariadb-bin.000063';

PURGE BINARY LOGS BEFORE '2013-04-21';

PURGE BINARY LOGS BEFORE '2013-04-22 09:55:22';

URL: https://mariadb.com/kb/en/purge-binary-logs/https://mariadb.com/kb/en/purge-binary-logs/��&CACHE INDEXSyntax
------

CACHE INDEX                      
 tbl_index_list [, tbl_index_list] ...
 IN key_cache_name

tbl_index_list:
 tbl_name [[INDEX|KEY] (index_name[, index_name] ...)]

Description
-----------

The CACHE INDEX statement assigns table indexes to a specific key cache. It is
used only for MyISAM tables.

A default key cache exists and cannot be destroyed. To create more key caches,
the key_buffer_size server system variable.

The associations between tables indexes and key caches are lost on server
restart. To recreate them automatically, it is necessary to configure caches
in a configuration file and include some CACHE INDEX (and optionally LOAD
INDEX) statements in the init file.

Examples
--------

The following statement assigns indexes from the tables t1, t2, and t3 to the
key cache named hot_cache:

CACHE INDEX t1, t2, t3 IN hot_cache;
+---------+--------------------+----------+----------+
| Table   | Op                 | Msg_type | Msg_text |
+---------+--------------------+----------+----------+
| test.t1 | assign_to_keycache | status   | OK       |
| test.t2 | assign_to_keycache | status   | OK       |
| test.t3 | assign_to_keycache | status   | OK       |
+---------+--------------------+----------+----------+

Implementation (for MyISAM)
---------------------------

Normally CACHE INDEX should not take a long time to execute. Internally it's
implemented the following way:

* Find the right key cache (under LOCK_global_system_variables)
* Open the table with a TL_READ_NO_INSERT lock.
* Flush the original key cache for the given file (under key cache lock)
* Flush the new key cache for the given file (safety)
* Move the file to the new key cache (under file share lock)

The only possible long operations are getting the locks for the table and
flushing the original key cache, if there were many key blocks for the file in
it.

We plan to also add CACHE INDEX for Aria tables if there is a need for this.

URL: https://mariadb.com/kb/en/cache-index/https://mariadb.com/kb/en/cache-index/��'HELP CommandSyntax
------

HELP search_string

Description
-----------

The HELP command can be used in any MariaDB client, such as the mariadb
command-line client, to get basic syntax help and a short description for most
commands and functions.

If you provide an argument to the HELP command, the mariadb client uses it as
a search string to access server-side help. The proper operation of this
command requires that the help tables in the mysql database be initialized
with help topic information.

If there is no match for the search string, the search fails. Use HELP
contents to see a list of the help categories:

HELP contents
You asked for help about help category: "Contents"
For more information, type 'help <item>', where <item> is one of the following
categories:
 Account Management
 Administration
 Compound Statements
 Data Definition
 Data Manipulation
 Data Types
 Functions
 Functions and Modifiers for Use with GROUP BY
 Geographic Features
 Help Metadata
 Language Structure
 Plugins
 Procedures
 Sequences
 Table Maintenance
 Transactions
 User-Defined Functions
 Utility

If a search string matches multiple items, MariaDB shows a list of matching
topics:

HELP drop
Many help items for your request exist.
To make a more specific request, please type 'help <item>',
where <item> is one of the following
topics:
 ALTER TABLE
 DROP DATABASE
 DROP EVENT
 DROP FUNCTION
 DROP FUNCTION UDF
 DROP INDEX
 DROP PACKAGE
 DROP PACKAGE BODY
 DROP PROCEDURE
 DROP ROLE
 DROP SEQUENCE
 DROP SERVER
 DROP TABLE
 DROP TRIGGER
 DROP USER
 DROP VIEW

Then you can enter a topic as the search string to see the help entry for that
topic.

The help is provided with the MariaDB server and makes use of four help tables
found in the mysql database: help_relation, help_topic, help_category and
help_keyword. These tables are populated by the mariadb-install-db or
fill_help_table.sql scripts.

URL: https://mariadb.com/kb/en/help-command/https://mariadb.com/kb/en/help-command/	�	�Z}�
��KILL [CONNECTION | QUERY]Syntax
------

KILL [HARD | SOFT] { {CONNECTION|QUERY} thread_id | QUERY ID query_id | USER
user_name }

Description
-----------

Each connection to mysqld runs in a separate thread. You can see which threads
are running with the SHOW PROCESSLIST statement and kill a thread with the
KILL thread_id statement. KILL allows the optional CONNECTION or QUERY
modifier:

* KILL CONNECTION is the same as KILL with no
 modifier: It terminates the connection associated with the given thread or
query id.
* KILL QUERY terminates the statement that the connection thread_id is
 currently executing, but leaves the connection itself intact.
* KILL QUERY ID terminates the query by query_id, leaving the connection
intact.

If a connection is terminated that has an active transaction, the transaction
will be rolled back. If only a query is killed, the current transaction will
stay active. See also idle_transaction_timeout.

If you have the PROCESS privilege, you can see all threads. If you have the
SUPER privilege, or, from MariaDB 10.5.2, the CONNECTION ADMIN privilege, you
can kill all threads and statements. Otherwise, you can see and kill only your
own threads and statements.

Killing queries that repair or create indexes on MyISAM and Aria tables may
result in corrupted tables. Use the SOFT option to avoid this!

The HARD option (default) kills a command as soon as possible. If you use
SOFT, then critical operations that may leave a table in an inconsistent state
will not be interrupted. Such operations include REPAIR and INDEX creation for
MyISAM and Aria tables (REPAIR TABLE, OPTIMIZE TABLE).

KILL ... USER username will kill all connections/queries for a given user.
USER can be specified one of the following ways:

* username  (Kill without regard to hostname)
* username@hostname
* CURRENT_USER or CURRENT_USER()

If you specify a thread id and that thread does not exist, you get the
following error:

ERROR 1094 (HY000): Unknown thread id: <thread_id>

If you specify a query id that doesn't exist, you get the following error:

ERROR 1957 (HY000): Unknown query id: <query_id>

However, if you specify a user name, no error is issued for non-connected (or
even non-existing) users. To check if the connection/query has been killed,
you can use the ROW_COUNT() function.

A client whose connection is killed receives the following error:

ERROR 1317 (70100): Query execution was interrupted

To obtain a list of existing sessions, use the SHOW PROCESSLIST statement or
query the Information Schema PROCESSLIST table.

Note: You cannot use KILL with the Embedded MariaDB Server library because the
embedded server merely runs inside the threads of the host application. It
does not create any connection threads of its own.

Note: You can also use mariadb-admin kill thread_id [,thread_id...] to kill
connections. To get a list of running queries, use mariadb-admin processlist.
See mariadb-admin.

Percona Toolkit contains a program, pt-kill that can be used to automatically
kill connections that match certain criteria. For example, it can be used to
terminate idle connections, or connections that have been busy for more than
60 seconds.

URL: https://mariadb.com/kb/en/kill/https://mariadb.com/kb/en/kill/�� RESETSyntax
------

RESET reset_option [, reset_option] ...

Description
-----------

The RESET statement is used to clear the state of various server operations.
You must have the RELOAD privilege to execute RESET.

RESET acts as a stronger version of the FLUSH statement.

The different RESET options are:

+---------------------------+------------------------------------------------+
| Option                    | Description                                    |
+---------------------------+------------------------------------------------+
| SLAVE                     | Deletes all relay logs from the slave and      |
| ["connection_name"] [ALL] | reset the replication position in the master   |
|                           | binary log.                                    |
+---------------------------+------------------------------------------------+
| MASTER                    | Deletes all old binary logs, makes the binary  |
|                           | index file (--log-bin-index) empty and         |
|                           | creates a new binary log file.  This is        |
|                           | useful when you want to reset the master to    |
|                           | an initial state. If you want to just delete   |
|                           | old, not used binary logs, you should use the  |
|                           | PURGE BINARY LOGS command.                     |
+---------------------------+------------------------------------------------+
| QUERY CACHE               | Removes all queries from the query cache. See  |
|                           | also FLUSH QUERY CACHE.                        |
+---------------------------+------------------------------------------------+

URL: https://mariadb.com/kb/en/reset/https://mariadb.com/kb/en/reset/���
����o
#SHUTDOWNSyntax
------

SHUTDOWN [WAIT FOR ALL { SLAVES | REPLICAS } ]

Description
-----------

The SHUTDOWN command shuts the server down.

WAIT FOR ALL REPLICAS / SLAVES
------------------------------

MariaDB starting with 10.4.4
----------------------------
The WAIT FOR ALL SLAVES option was first added in MariaDB 10.4.4. WAIT FOR ALL
REPLICAS has been a synonym since MariaDB 10.5.1.

When a primary server is shutdown and it goes through the normal shutdown
process, the primary kills client threads in random order. By default, the
primary also considers its binary log dump threads to be regular client
threads. As a consequence, the binary log dump threads can be killed while
client threads still exist, and this means that data can be written on the
primary during a normal shutdown that won't be replicated. This is true even
if semi-synchronous replication is being used.

In MariaDB 10.4 and later, this problem can be solved by shutting down the
server with the SHUTDOWN command and by providing the WAIT FOR ALL
REPLICAS/WAIT FOR ALL SLAVES option to the command. For example:

SHUTDOWN WAIT FOR ALL REPLICAS;

When the WAIT FOR ALL REPLICAS option is provided, the server only kills its
binary log dump threads after all client threads have been killed, and it only
completes the shutdown after the last binary log has been sent to all
connected replicas.

See Replication Threads: Binary Log Dump Threads and the Shutdown Process for
more information.

Required Permissions
--------------------

One must have a SHUTDOWN privilege (see GRANT) to use this command. It is the
same privilege one needs to use the mariadb-admin shutdown command.

Shutdown for Upgrades
---------------------

If you are doing a shutdown to migrate to another major version of MariaDB,
please ensure that the innodb_fast_shutdown variable is not 2 (fast crash
shutdown). The default of this variable is 1.

Example
-------

The following example shows how to create an event which turns off the server
at a certain time:

CREATE EVENT `test`.`shutd`
  ON SCHEDULE
    EVERY 1 DAY
    STARTS '2014-01-01 20:00:00'
  COMMENT 'Shutdown Maria when the office is closed'
DO BEGIN
  SHUTDOWN;
END;

Other Ways to Stop mysqld
-------------------------

You can use the mariadb-admin shutdown command to take down mysqld cleanly.

You can also use the system kill command on Unix with signal SIGTERM (15)

kill -SIGTERM pid-of-mysqld-process

You can find the process number of the server process in the file that ends
with .pid in your data directory.

The above is identical to mariadb-admin shutdown.

On windows you should use:

NET STOP MySQL

URL: https://mariadb.com/kb/en/shutdown/https://mariadb.com/kb/en/shutdown/�x'USE [DATABASE]Syntax
------

USE db_name

In MariaDB 11.3 one can also use

USE DATABASE db_name;

Description
-----------

The 'USE db_name' statement tells MariaDB to use the db_name database as the
default (current) database for subsequent statements. The database remains the
default until the end of the session or another USE statement is issued:

USE db1;
SELECT COUNT(*) FROM mytable;   # selects from db1.mytable
USE db2;
SELECT COUNT(*) FROM mytable;   # selects from db2.mytable

The DATABASE() function (SCHEMA() is a synonym) returns the default database.

Another way to set the default database is specifying its name at mariadb
command line client startup.

One cannot use USE DATABASE to a database one has no privileges to. The reason
is that a user with no privileges to a database should not be able to know if
a database exists or not.

URL: https://mariadb.com/kb/en/use-database/https://mariadb.com/kb/en/use-database/�H&JOIN SyntaxDescription
-----------

MariaDB supports the following JOIN syntaxes for the table_references part of
SELECT statements and multiple-table DELETE and UPDATE statements:

table_references:
  table_reference [, table_reference] ...

table_reference:
  table_factor
 | join_table

table_factor:
  tbl_name [PARTITION (partition_list)]
    [query_system_time_period_specification] [[AS] alias] [index_hint_list]
 | table_subquery [query_system_time_period_specification] [AS] alias
 | ( table_references )
 | { ON table_reference LEFT OUTER JOIN table_reference
    ON conditional_expr }

join_table:
  table_reference [INNER | CROSS] JOIN table_factor [join_condition]
 | table_reference STRAIGHT_JOIN table_factor
 | table_reference STRAIGHT_JOIN table_factor ON conditional_expr
 | table_reference {LEFT|RIGHT} [OUTER] JOIN table_reference join_condition
 | table_reference NATURAL [{LEFT|RIGHT} [OUTER]] JOIN table_factor

join_condition:
  ON conditional_expr
 | USING (column_list)

query_system_time_period_specification:
  FOR SYSTEM_TIME AS OF point_in_time
 | FOR SYSTEM_TIME BETWEEN point_in_time AND point_in_time
 | FOR SYSTEM_TIME FROM point_in_time TO point_in_time
 | FOR SYSTEM_TIME ALL

point_in_time:
  [TIMESTAMP] expression
 | TRANSACTION expression

index_hint_list:
  index_hint [, index_hint] ...

index_hint:
  USE {INDEX|KEY}
   [{FOR {JOIN|ORDER BY|GROUP BY}] ([index_list])
 | IGNORE {INDEX|KEY}
   [{FOR {JOIN|ORDER BY|GROUP BY}] (index_list)
 | FORCE {INDEX|KEY}
   [{FOR {JOIN|ORDER BY|GROUP BY}] (index_list)

index_list:
  index_name [, index_name] ...

A table reference is also known as a join expression.

Each table can also be specified as db_name.tabl_name. This allows to write
queries which involve multiple databases. See Identifier Qualifiers for syntax
details.

The syntax of table_factor is extended in comparison with the SQL Standard.
The latter accepts only table_reference, not a list of them inside a pair of
parentheses.

This is a conservative extension if we consider each comma in a list of
table_reference items as equivalent to an inner join. For example:

SELECT * FROM t1 LEFT JOIN (t2, t3, t4)
        ON (t2.a=t1.a AND t3.b=t1.b AND t4.c=t1.c)

is equivalent to:

SELECT * FROM t1 LEFT JOIN (t2 CROSS JOIN t3 CROSS JOIN t4)
        ON (t2.a=t1.a AND t3.b=t1.b AND t4.c=t1.c)

In MariaDB, CROSS JOIN is a syntactic equivalent to INNER JOIN (they can
replace each other). In standard SQL, they are not equivalent. INNER JOIN is
used with an ON clause, CROSS JOIN is used otherwise.

In general, parentheses can be ignored in join expressions containing only
inner join operations. MariaDB also supports nested joins (see
http://dev.mysql.com/doc/refman/5.1/en/nested-join-optimization.html).

See System-versioned tables for more information about FOR SYSTEM_TIME syntax.

Index hints can be specified to affect how the MariaDB optimizer makes use of
indexes. For more information, see How to force query plans.

Examples
--------

SELECT left_tbl.*
 FROM left_tbl LEFT JOIN right_tbl ON left_tbl.id = right_tbl.id
 WHERE right_tbl.id IS NULL;

URL: https://mariadb.com/kb/en/join-syntax/https://mariadb.com/kb/en/join-syntax/o��
��
�#*��D�%)SHOW COLLATIONSyntax
------

SHOW COLLATION
  [LIKE 'pattern' | WHERE expr]

Description
-----------

The output from SHOW COLLATION includes all available collations. The LIKE
clause, if present on its own, indicates which collation names to match. The
WHERE and LIKE clauses can be given to select rows using more general
conditions, as discussed in Extended SHOW.

The same information can be queried from the Information Schema COLLATIONS
table.

See Setting Character Sets and Collations for details on specifying the
collation at the server, database, table and column levels.

Examples
--------

SHOW COLLATION LIKE 'latin1%';
+-------------------------+---------+------+---------+----------+---------+
| Collation               | Charset | Id   | Default | Compiled | Sortlen |
+-------------------------+---------+------+---------+----------+---------+
| latin1_german1_ci       | latin1  |    5 |         | Yes      |       1 |
| latin1_swedish_ci       | latin1  |    8 | Yes     | Yes      |       1 |
| latin1_danish_ci        | latin1  |   15 |         | Yes      |       1 |
| latin1_german2_ci       | latin1  |   31 |         | Yes      |       2 |
| latin1_bin              | latin1  |   47 |         | Yes      |       1 |
| latin1_general_ci       | latin1  |   48 |         | Yes      |       1 |
| latin1_general_cs       | latin1  |   49 |         | Yes      |       1 |
| latin1_spanish_ci       | latin1  |   94 |         | Yes      |       1 |
| latin1_swedish_nopad_ci | latin1  | 1032 |         | Yes      |       1 |
| latin1_nopad_bin        | latin1  | 1071 |         | Yes      |       1 |
+-------------------------+---------+------+---------+----------+---------+

SHOW COLLATION WHERE Sortlen LIKE '8' AND Charset LIKE 'utf8mb4';
+------------------------------+---------+------+---------+----------+---------

| Collation                    | Charset | Id   | Default | Compiled | Sortlen
|
+------------------------------+---------+------+---------+----------+---------

| utf8mb4_unicode_ci           | utf8mb4 |  224 |         | Yes      |       8
|
| utf8mb4_icelandic_ci         | utf8mb4 |  225 |         | Yes      |       8
|
| utf8mb4_latvian_ci           | utf8mb4 |  226 |         | Yes      |       8
|
| utf8mb4_romanian_ci          | utf8mb4 |  227 |         | Yes      |       8
|
| utf8mb4_slovenian_ci         | utf8mb4 |  228 |         | Yes      |       8
|
| utf8mb4_polish_ci            | utf8mb4 |  229 |         | Yes      |       8
|
| utf8mb4_estonian_ci          | utf8mb4 |  230 |         | Yes      |       8
|
| utf8mb4_spanish_ci           | utf8mb4 |  231 |         | Yes      |       8
|
| utf8mb4_swedish_ci           | utf8mb4 |  232 |         | Yes      |       8
|
| utf8mb4_turkish_ci           | utf8mb4 |  233 |         | Yes      |       8
|
| utf8mb4_czech_ci             | utf8mb4 |  234 |         | Yes      |       8
|
| utf8mb4_danish_ci            | utf8mb4 |  235 |         | Yes      |       8
|
| utf8mb4_lithuanian_ci        | utf8mb4 |  236 |         | Yes      |       8
|
| utf8mb4_slovak_ci            | utf8mb4 |  237 |         | Yes      |       8
|
| utf8mb4_spanish2_ci          | utf8mb4 |  238 |         | Yes      |       8
|
| utf8mb4_roman_ci             | utf8mb4 |  239 |         | Yes      |       8
|
| utf8mb4_persian_ci           | utf8mb4 |  240 |         | Yes      |       8
|
| utf8mb4_esperanto_ci         | utf8mb4 |  241 |         | Yes      |       8
|
| utf8mb4_hungarian_ci         | utf8mb4 |  242 |         | Yes      |       8
|
| utf8mb4_sinhala_ci           | utf8mb4 |  243 |         | Yes      |       8
|
| utf8mb4_german2_ci           | utf8mb4 |  244 |         | Yes      |       8
|
| utf8mb4_croatian_mysql561_ci | utf8mb4 |  245 |         | Yes      |       8
|
| utf8mb4_unicode_520_ci       | utf8mb4 |  246 |         | Yes      |       8
|
| utf8mb4_vietnamese_ci        | utf8mb4 |  247 |         | Yes      |       8
|
| utf8mb4_croatian_ci          | utf8mb4 |  608 |         | Yes      |       8
|
| utf8mb4_myanmar_ci           | utf8mb4 |  609 |         | Yes      |       8
|
| utf8mb4_unicode_nopad_ci     | utf8mb4 | 1248 |         | Yes      |       8
|
| utf8mb4_unicode_520_nopad_ci | utf8mb4 | 1270 |         | Yes      |       8
|
+------------------------------+---------+------+---------+----------+---------

URL: https://mariadb.com/kb/en/show-collation/https://mariadb.com/kb/en/show-collation/��7Scalar SubqueriesA scalar subquery is a subquery that returns a single value. This is the
simplest form of a subquery, and can be used in most places a literal or
single column value is valid.

The data type, length and character set and collation are all taken from the
result returned by the subquery. The result of a subquery can always be NULL,
that is, no result returned. Even if the original value is defined as NOT
NULL, this is disregarded.

A subquery cannot be used where only a literal is expected, for example LOAD
DATA INFILE expects a literal string containing the file name, and LIMIT
requires a literal integer.

Examples
--------

CREATE TABLE sq1 (num TINYINT);

CREATE TABLE sq2 (num TINYINT);

INSERT INTO sq1 VALUES (1);

INSERT INTO sq2 VALUES (10* (SELECT num FROM sq1));

SELECT * FROM sq2;
+------+
| num  |
+------+
|   10 |
+------+

Inserting a second row means the subquery is no longer a scalar, and this
particular query is not valid:

INSERT INTO sq1 VALUES (2);

INSERT INTO sq2 VALUES (10* (SELECT num FROM sq1));
ERROR 1242 (21000): Subquery returns more than 1 row

No rows in the subquery, so the scalar is NULL:

INSERT INTO sq2 VALUES (10* (SELECT num FROM sq3 WHERE num='3'));

SELECT * FROM sq2;
+------+
| num  |
+------+
|   10 |
| NULL |
+------+

A more traditional scalar subquery, as part of a WHERE clause:

SELECT * FROM sq1 WHERE num = (SELECT MAX(num)/10 FROM sq2); 
+------+
| num  |
+------+
|    1 |
+------+

URL: https://mariadb.com/kb/en/subqueries-scalar-subqueries/https://mariadb.com/kb/en/subqueries-scalar-subqueries/v:j�?ޑ����!DELETESyntax
------

Single-table syntax:

DELETE [LOW_PRIORITY] [QUICK] [IGNORE] 
 FROM tbl_name [PARTITION (partition_list)]
 [FOR PORTION OF period FROM expr1 TO expr2]
 [WHERE where_condition]
 [ORDER BY ...]
 [LIMIT row_count]
 [RETURNING select_expr
  [, select_expr ...]]

Multiple-table syntax:

DELETE [LOW_PRIORITY] [QUICK] [IGNORE]
  tbl_name[.*] [, tbl_name[.*]] ...
  FROM table_references
  [WHERE where_condition]

Or:

DELETE [LOW_PRIORITY] [QUICK] [IGNORE]
  FROM tbl_name[.*] [, tbl_name[.*]] ...
  USING table_references
  [WHERE where_condition]

Trimming history:

DELETE HISTORY
 FROM tbl_name [PARTITION (partition_list)]
 [BEFORE SYSTEM_TIME [TIMESTAMP|TRANSACTION] expression]

Description
-----------

+---------------------------+------------------------------------------------+
| Option                    | Description                                    |
+---------------------------+------------------------------------------------+
| LOW_PRIORITY              | Wait until all SELECT's are done before        |
|                           | starting the statement. Used with storage      |
|                           | engines that uses table locking (MyISAM, Aria  |
|                           | etc). See HIGH_PRIORITY and LOW_PRIORITY       |
|                           | clauses for details.                           |
+---------------------------+------------------------------------------------+
| QUICK                     | Signal the storage engine that it should       |
|                           | expect that a lot of rows are deleted. The     |
|                           | storage engine engine can do things to speed   |
|                           | up the DELETE like ignoring merging of data    |
|                           | blocks until all rows are deleted from the     |
|                           | block (instead of when a block is half full).  |
|                           | This speeds up things at the expanse of lost   |
|                           | space in data blocks. At least MyISAM and      |
|                           | Aria support this feature.                     |
+---------------------------+------------------------------------------------+
| IGNORE                    | Don't stop the query even if a not-critical    |
|                           | error occurs (like data overflow). See How     |
|                           | IGNORE works for a full description.           |
+---------------------------+------------------------------------------------+

For the single-table syntax, the DELETE statement deletes rows from tbl_name
and returns a count of the number of deleted rows. This count can be obtained
by calling the ROW_COUNT() function. The WHERE clause, if given, specifies the
conditions that identify which rows to delete. With no WHERE clause, all rows
are deleted. If the ORDER BY clause is specified, the rows are deleted in the
order that is specified. The LIMIT clause places a limit on the number of rows
that can be deleted.

For the multiple-table syntax, DELETE deletes from each tbl_name the rows that
satisfy the conditions. In this case, ORDER BY and LIMIT> cannot be used. A
DELETE can also reference tables which are located in different databases; see
Identifier Qualifiers for the syntax.

where_condition is an expression that evaluates to true for each row to be
deleted. It is specified as described in SELECT.

Currently, you cannot delete from a table and select from the same table in a
subquery.

You need the DELETE privilege on a table to delete rows from it. You need only
the SELECT privilege for any columns that are only read, such as those named
in the WHERE clause. See GRANT.

As stated, a DELETE statement with no WHERE clause deletes all rows. A faster
way to do this, when you do not need to know the number of deleted rows, is to
use TRUNCATE TABLE. However, within a transaction or if you have a lock on the
table, TRUNCATE TABLE cannot be used whereas DELETE can. See TRUNCATE TABLE,
and LOCK.

PARTITION
---------

See Partition Pruning and Selection for details.

FOR PORTION OF
--------------

MariaDB starting with 10.4.3
----------------------------
See Application Time Periods - Deletion by Portion.

RETURNING
---------

It is possible to return a resultset of the deleted rows for a single table to
the client by using the syntax DELETE ... RETURNING select_expr [,
select_expr2 ...]]

Any of SQL expression that can be calculated from a single row fields is
allowed. Subqueries are allowed. The AS keyword is allowed, so it is possible
to use aliases.

The use of aggregate functions is not allowed. RETURNING cannot be used in
multi-table DELETEs.

MariaDB starting with 10.3.1
----------------------------

Same Source and Target Table
----------------------------

Until MariaDB 10.3.1, deleting from a table with the same source and target
was not possible. From MariaDB 10.3.1, this is now possible. For example:

DELETE FROM t1 WHERE c1 IN (SELECT b.c1 FROM t1 b WHERE b.c2=0);

MariaDB starting with 10.3.4
----------------------------

DELETE HISTORY
--------------

One can use DELETE HISTORY to delete historical information from
System-versioned tables.

Examples
--------

How to use the ORDER BY and LIMIT clauses:

DELETE FROM page_hit ORDER BY timestamp LIMIT 1000000;

How to use the RETURNING clause:

DELETE FROM t RETURNING f1;
+------+
| f1   |
+------+
|    5 |
|   50 |
|  500 |
+------+

The following statement joins two tables: one is only used to satisfy a WHERE
condition, but no row is deleted from it; rows from the other table are
deleted, instead.

DELETE post FROM blog INNER JOIN post WHERE blog.id = post.blog_id;

Deleting from the Same Source and Target
----------------------------------------

CREATE TABLE t1 (c1 INT, c2 INT);
DELETE FROM t1 WHERE c1 IN (SELECT b.c1 FROM t1 b WHERE b.c2=0);

Until MariaDB 10.3.1, this returned:

ERROR 1093 (HY000): Table 't1' is specified twice, both as a target for
'DELETE' 
 and as a separate source for

From MariaDB 10.3.1:

Query OK, 0 rows affected (0.00 sec)

URL: https://mariadb.com/kb/en/delete/https://mariadb.com/kb/en/delete/$�C��Y�\"REPLACESyntax
------

REPLACE [LOW_PRIORITY | DELAYED]
 [INTO] tbl_name [PARTITION (partition_list)] [(col,...)]
 {VALUES | VALUE} ({expr | DEFAULT},...),(...),...
[RETURNING select_expr 
   [, select_expr ...]]

Or:

REPLACE [LOW_PRIORITY | DELAYED]
  [INTO] tbl_name [PARTITION (partition_list)]
  SET col={expr | DEFAULT}, ...
[RETURNING select_expr 
   [, select_expr ...]]

Or:

REPLACE [LOW_PRIORITY | DELAYED]
  [INTO] tbl_name [PARTITION (partition_list)] [(col,...)]
  SELECT ...
[RETURNING select_expr 
   [, select_expr ...]]

Description
-----------

REPLACE works exactly like INSERT, except that if an old row in the table has
the same value as a new row for a PRIMARY KEY or a UNIQUE index, the old row
is deleted before the new row is inserted. If the table has more than one
UNIQUE keys, it is possible that the new row conflicts with more than one row.
In this case, all conflicting rows will be deleted.

The table name can be specified in the form db_name.tbl_name or, if a default
database is selected, in the form tbl_name (see Identifier Qualifiers). This
allows to use REPLACE ... SELECT to copy rows between different databases.

MariaDB starting with 10.5.0
----------------------------
The RETURNING clause was introduced in MariaDB 10.5.0

Basically it works like this:

BEGIN;
SELECT 1 FROM t1 WHERE key=# FOR UPDATE;
IF found-row
 DELETE FROM t1 WHERE key=# ;
ENDIF
INSERT INTO t1 VALUES (...);
END;

The above can be replaced with:

REPLACE INTO t1 VALUES (...)

REPLACE is a MariaDB/MySQL extension to the SQL standard. It either inserts,
or deletes and inserts. For other MariaDB/MySQL extensions to standard SQL ---
that also handle duplicate values --- see IGNORE and INSERT ON DUPLICATE KEY
UPDATE.

Note that unless the table has a PRIMARY KEY or UNIQUE index, using a REPLACE
statement makes no sense. It becomes equivalent to INSERT, because there is no
index to be used to determine whether a new row duplicates another.

Values for all columns are taken from the values sSee Partition Pruning and
Selection for details.pecified in the REPLACE statement. Any missing columns
are set to their default values, just as happens for INSERT. You cannot refer
to values from the current row and use them in the new row. If you use an
assignment such as 'SET col = col + 1', the reference to the column name on
the right hand side is treated as DEFAULT(col), so the assignment is
equivalent to 'SET col = DEFAULT(col) + 1'.

To use REPLACE, you must have both the INSERT and DELETE privileges for the
table.

There are some gotchas you should be aware of, before using REPLACE:

* If there is an AUTO_INCREMENT field, a new value will be generated.
* If there are foreign keys, ON DELETE action will be activated by REPLACE.
* Triggers on DELETE and INSERT will be activated by REPLACE.

To avoid some of these behaviors, you can use INSERT ... ON DUPLICATE KEY
UPDATE.

This statement activates INSERT and DELETE triggers. See Trigger Overview for
details.

PARTITION
---------

See Partition Pruning and Selection for details.

REPLACE RETURNING
-----------------

REPLACE ... RETURNING returns a resultset of the replaced rows.

This returns the listed columns for all the rows that are replaced, or
alternatively, the specified SELECT expression. Any SQL expressions which can
be calculated can be used in the select expression for the RETURNING clause,
including virtual columns and aliases, expressions which use various operators
such as bitwise, logical and arithmetic operators, string functions, date-time
functions, numeric functions, control flow functions, secondary functions and
stored functions. Along with this, statements which have subqueries and
prepared statements can also be used.

Examples
--------

Simple REPLACE statement

REPLACE INTO t2 VALUES (1,'Leopard'),(2,'Dog') RETURNING id2, id2+id2 
as Total ,id2|id2, id2&&id2;
+-----+-------+---------+----------+
| id2 | Total | id2|id2 | id2&&id2 |
+-----+-------+---------+----------+
|   1 |     2 |       1 |        1 |
|   2 |     4 |       2 |        1 |
+-----+-------+---------+----------+

Using stored functions in RETURNING

DELIMITER |
CREATE FUNCTION f(arg INT) RETURNS INT
  BEGIN
   RETURN (SELECT arg+arg);
  END|

DELIMITER ;
PREPARE stmt FROM "REPLACE INTO t2 SET id2=3, animal2='Fox' RETURNING f2(id2),
UPPER(animal2)";

EXECUTE stmt;
+---------+----------------+
| f2(id2) | UPPER(animal2) |
+---------+----------------+
|       6 | FOX            |
+---------+----------------+

Subqueries in the statement

REPLACE INTO t1 SELECT * FROM t2 RETURNING (SELECT id2 FROM t2 WHERE 
id2 IN (SELECT id2 FROM t2 WHERE id2=1)) AS new_id;
+--------+
| new_id |
+--------+
|      1 |
|      1 |
|      1 |
|      1 |
+--------+

Subqueries in the RETURNING clause that return more than one row or column
cannot be used..

Aggregate functions cannot be used in the RETURNING clause. Since aggregate
functions work on a set of values and if the purpose is to get the row count,
ROW_COUNT() with SELECT can be used, or it can be used in REPLACE...SEL==
Description

REPLACE ... RETURNING returns a resultset of the replaced rows.

This returns the listed columns for all the rows that are replaced, or
alternatively, the specified SELECT expression. Any SQL expressions which can
be calculated can be used in the select expression for the RETURNING clause,
including virtual columns and aliases, expressions which use various operators
such as bitwise, logical and arithmetic operators, string functions, date-time
functions, numeric functions, control flow functions, secondary functions and
stored functions. Along with this, statements which have subqueries and
prepared statements can also be used.

Examples
--------

Simple REPLACE statement

REPLACE INTO t2 VALUES (1,'Leopard'),(2,'Dog') RETURNING id2, id2+id2 
as Total ,id2|id2, id2&&id2;
+-----+-------+---------+----------+
| id2 | Total | id2|id2 | id2&&id2 |
+-----+-------+---------+----------+
|   1 |     2 |       1 |        1 |
|   2 |     4 |       2 |        1 |
+-----+-------+---------+----------+

Using stored functions in RETURNING

DELIMITER |
CREATE FUNCTION f(arg INT) RETURNS INT
  BEGIN
   RETURN (SELECT arg+arg);
  END|

DELIMITER ;
PREPARE stmt FROM "REPLACE INTO t2 SET id2=3, animal2='Fox' RETURNING f2(id2),
UPPER(animal2)";

EXECUTE stmt;
+---------+----------------+
| f2(id2) | UPPER(animal2) |
+---------+----------------+
|       6 | FOX            |
+---------+----------------+

Subqueries in the statement

REPLACE INTO t1 SELECT * FROM t2 RETURNING (SELECT id2 FROM t2 WHERE 
id2 IN (SELECT id2 FROM t2 WHERE id2=1)) AS new_id;
+--------+
| new_id |
+--------+
|      1 |
|      1 |
|      1 |
|      1 |
+--------+

Subqueries in the RETURNING clause that return more than one row or column
cannot be used..

Aggregate functions cannot be used in the RETURNING clause. Since aggregate
functions work on a set of values and if the purpose is to get the row count,
ROW_COUNT() with SELECT can be used, or it can be used in
REPLACE...SELECT...RETURNING if the table in the RETURNING clause is not the
same as the REPLACE table. ECT...RETURNING if the table in the RETURNING
clause is not the same as the REPLACE table.

URL: https://mariadb.com/kb/en/replace/https://mariadb.com/kb/en/replace/�J�<,���	!UPDATESyntax
------

Single-table syntax:

UPDATE [LOW_PRIORITY] [IGNORE] table_reference 
 [PARTITION (partition_list)]
 [FOR PORTION OF period FROM expr1 TO expr2]
 SET col1={expr1|DEFAULT} [,col2={expr2|DEFAULT}] ...
 [WHERE where_condition]
 [ORDER BY ...]
 [LIMIT row_count]

Multiple-table syntax:

UPDATE [LOW_PRIORITY] [IGNORE] table_references
  SET col1={expr1|DEFAULT} [, col2={expr2|DEFAULT}] ...
  [WHERE where_condition]

Description
-----------

For the single-table syntax, the UPDATE statement updates columns of existing
rows in the named table with new values. The SET clause indicates which
columns to modify and the values they should be given. Each value can be given
as an expression, or the keyword DEFAULT to set a column explicitly to its
default value. The WHERE clause, if given, specifies the conditions that
identify which rows to update. With no WHERE clause, all rows are updated. If
the ORDER BY clause is specified, the rows are updated in the order that is
specified. The LIMIT clause places a limit on the number of rows that can be
updated.

Until MariaDB 10.3.2, for the multiple-table syntax, UPDATE updates rows in
each table named in table_references that satisfy the conditions. In this
case, ORDER BY and LIMIT cannot be used. This restriction was lifted in
MariaDB 10.3.2 and both clauses can be used with multiple-table updates. An
UPDATE can also reference tables which are located in different databases; see
Identifier Qualifiers for the syntax.

where_condition is an expression that evaluates to true for each row to be
updated.

table_references and where_condition are as specified as described in SELECT.

For single-table updates, assignments are evaluated in left-to-right order,
while for multi-table updates, there is no guarantee of a particular order. If
the SIMULTANEOUS_ASSIGNMENT sql_mode (available from MariaDB 10.3.5) is set,
UPDATE statements evaluate all assignments simultaneously.

You need the UPDATE privilege only for columns referenced in an UPDATE that
are actually updated. You need only the SELECT privilege for any columns that
are read but not modified. See GRANT.

The UPDATE statement supports the following modifiers:

* If you use the LOW_PRIORITY keyword, execution of
 the UPDATE is delayed until no other clients are reading from
 the table. This affects only storage engines that use only table-level
 locking (MyISAM, MEMORY, MERGE). See HIGH_PRIORITY and LOW_PRIORITY clauses
for details.
* If you use the IGNORE keyword, the update statement does 
 not abort even if errors occur during the update. Rows for which
 duplicate-key conflicts occur are not updated. Rows for which columns are
 updated to values that would cause data conversion errors are updated to the
 closest valid values instead.

PARTITION
---------

See Partition Pruning and Selection for details.

FOR PORTION OF
--------------

MariaDB starting with 10.4.3
----------------------------
See Application Time Periods - Updating by Portion.

UPDATE Statements With the Same Source and Target
-------------------------------------------------

MariaDB starting with 10.3.2
----------------------------
From MariaDB 10.3.2, UPDATE statements may have the same source and target.

For example, given the following table:

DROP TABLE t1;
CREATE TABLE t1 (c1 INT, c2 INT);
INSERT INTO t1 VALUES (10,10), (20,20);

Until MariaDB 10.3.1, the following UPDATE statement would not work:

UPDATE t1 SET c1=c1+1 WHERE c2=(SELECT MAX(c2) FROM t1);
ERROR 1093 (HY000): Table 't1' is specified twice, 
 both as a target for 'UPDATE' and as a separate source for data

From MariaDB 10.3.2, the statement executes successfully:

UPDATE t1 SET c1=c1+1 WHERE c2=(SELECT MAX(c2) FROM t1);

SELECT * FROM t1;
+------+------+
| c1   | c2   |
+------+------+
|   10 |   10 |
|   21 |   20 |
+------+------+

Example
-------

Single-table syntax:

UPDATE table_name SET column1 = value1, column2 = value2 WHERE id=100;

Multiple-table syntax:

UPDATE tab1, tab2 SET tab1.column1 = value1, tab1.column2 = value2 WHERE
tab1.id = tab2.id;

URL: https://mariadb.com/kb/en/update/https://mariadb.com/kb/en/update/��4Row SubqueriesA row subquery is a subquery returning a single row, as opposed to a scalar
subquery, which returns a single column from a row, or a literal.

Examples
--------

CREATE TABLE staff (name VARCHAR(10), age TINYINT);

CREATE TABLE customer (name VARCHAR(10), age TINYINT);

INSERT INTO staff VALUES ('Bilhah',37), ('Valerius',61), ('Maia',25);

INSERT INTO customer VALUES ('Thanasis',48), ('Valerius',61), ('Brion',51);

SELECT * FROM staff WHERE (name,age) = (SELECT name,age FROM customer WHERE
name='Valerius');
+----------+------+
| name     | age  |
+----------+------+
| Valerius |   61 |
+----------+------+

Finding all rows in one table also in another:

SELECT name,age FROM staff WHERE (name,age) IN (SELECT name,age FROM customer);
+----------+------+
| name     | age  |
+----------+------+
| Valerius |   61 |
+----------+------+

URL: https://mariadb.com/kb/en/subqueries-row-subqueries/https://mariadb.com/kb/en/subqueries-row-subqueries/J�>�R)����!IGNOREThe IGNORE option tells the server to ignore some common errors.

IGNORE can be used with the following statements:

* DELETE
* INSERT (see also INSERT IGNORE)
* LOAD DATA INFILE
* UPDATE
* ALTER TABLE
* CREATE TABLE ... SELECT
* INSERT ... SELECT

The logic used:

* Variables out of ranges are replaced with the maximum/minimum value.

* SQL_MODEs STRICT_TRANS_TABLES, STRICT_ALL_TABLES, NO_ZERO_IN_DATE,
NO_ZERO_DATE are ignored.

* Inserting NULL in a NOT NULL field will insert 0 ( in a numerical
 field), 0000-00-00 ( in a date field) or an empty string ( in a character
 field).

* Rows that cause a duplicate key error or break a foreign key constraint are
 not inserted, updated, or deleted.

The following errors are ignored:

+---------------------+---------------------------------+--------------------+
| Error number        | Symbolic error name             | Description        |
+---------------------+---------------------------------+--------------------+
| 1022                | ER_DUP_KEY                      | Can't write;       |
|                     |                                 | duplicate key in   |
|                     |                                 | table '%s'         |
+---------------------+---------------------------------+--------------------+
| 1048                | ER_BAD_NULL_ERROR               | Column '%s'        |
|                     |                                 | cannot be null     |
+---------------------+---------------------------------+--------------------+
| 1062                | ER_DUP_ENTRY                    | Duplicate entry    |
|                     |                                 | '%s' for key %d    |
+---------------------+---------------------------------+--------------------+
| 1242                | ER_SUBQUERY_NO_1_ROW            | Subquery returns   |
|                     |                                 | more than 1 row    |
+---------------------+---------------------------------+--------------------+
| 1264                | ER_WARN_DATA_OUT_OF_RANGE       | Out of range       |
|                     |                                 | value for column   |
|                     |                                 | '%s' at row %ld    |
+---------------------+---------------------------------+--------------------+
| 1265                | WARN_DATA_TRUNCATED             | Data truncated     |
|                     |                                 | for column '%s'    |
|                     |                                 | at row %ld         |
+---------------------+---------------------------------+--------------------+
| 1292                | ER_TRUNCATED_WRONG_VALUE        | Truncated          |
|                     |                                 | incorrect %s       |
|                     |                                 | value: '%s'        |
+---------------------+---------------------------------+--------------------+
| 1366                | ER_TRUNCATED_WRONG_VALUE_FOR_FI | Incorrect integer  |
|                     | LD                              | value              |
+---------------------+---------------------------------+--------------------+
| 1369                | ER_VIEW_CHECK_FAILED            | CHECK OPTION       |
|                     |                                 | failed '%s.%s'     |
+---------------------+---------------------------------+--------------------+
| 1451                | ER_ROW_IS_REFERENCED_2          | Cannot delete or   |
|                     |                                 | update a parent    |
|                     |                                 | row                |
+---------------------+---------------------------------+--------------------+
| 1452                | ER_NO_REFERENCED_ROW_2          | Cannot add or      |
|                     |                                 | update a child     |
|                     |                                 | row: a foreign     |
|                     |                                 | key constraint     |
|                     |                                 | fails (%s)         |
+---------------------+---------------------------------+--------------------+
| 1526                | ER_NO_PARTITION_FOR_GIVEN_VALUE | Table has no       |
|                     |                                 | partition for      |
|                     |                                 | value %s           |
+---------------------+---------------------------------+--------------------+
| 1586                | ER_DUP_ENTRY_WITH_KEY_NAME      | Duplicate entry    |
|                     |                                 | '%s' for key '%s'  |
+---------------------+---------------------------------+--------------------+
| 1591                | ER_NO_PARTITION_FOR_GIVEN_VALUE | Table has no       |
|                     | SILENT                          | partition for      |
|                     |                                 | some existing      |
|                     |                                 | values             |
+---------------------+---------------------------------+--------------------+
| 1748                | ER_ROW_DOES_NOT_MATCH_GIVEN_PAR | Found a row not    |
|                     | ITION_SET                       | matching the       |
|                     |                                 | given partition    |
|                     |                                 | set                |
+---------------------+---------------------------------+--------------------+

Ignored errors normally generate a warning.

A property of the IGNORE clause consists in causing transactional engines and
non-transactional engines (like InnoDB and Aria) to behave the same way. For
example, normally a multi-row insert which tries to violate a UNIQUE contraint
is completely rolled back on InnoDB, but might be partially executed on Aria.
With the IGNORE clause, the statement will be partially executed in both
engines.

Duplicate key errors also generate warnings. The OLD_MODE server variable can
be used to prevent this.

URL: https://mariadb.com/kb/en/ignore/https://mariadb.com/kb/en/ignore/0���r����!SELECTSyntax
------

SELECT
  [ALL | DISTINCT | DISTINCTROW]
  [HIGH_PRIORITY]
  [STRAIGHT_JOIN]
  [SQL_SMALL_RESULT] [SQL_BIG_RESULT] [SQL_BUFFER_RESULT]
  [SQL_CACHE | SQL_NO_CACHE] [SQL_CALC_FOUND_ROWS]
  select_expr [, select_expr ...]
  [ FROM table_references
   [WHERE where_condition]
   [GROUP BY {col_name | expr | position} [ASC | DESC], ... [WITH ROLLUP]]
   [HAVING where_condition]
   [ORDER BY {col_name | expr | position} [ASC | DESC], ...]
   [LIMIT {[offset,] row_count | row_count OFFSET offset  [ROWS EXAMINED
rows_limit] } |
    [OFFSET start { ROW | ROWS }]
    [FETCH { FIRST | NEXT } [ count ] { ROW | ROWS } { ONLY | WITH TIES }]
]
   procedure|[PROCEDURE procedure_name(argument_list)]
   [INTO OUTFILE 'file_name' [CHARACTER SET charset_name] [export_options] |
    INTO DUMPFILE 'file_name' | INTO var_name [, var_name] ]
   [FOR UPDATE lock_option | LOCK IN SHARE MODE lock_option]
export_options:
  [{FIELDS | COLUMNS}
    [TERMINATED BY 'string']
    [[OPTIONALLY] ENCLOSED BY 'char']
    [ESCAPED BY 'char']
  ]
  [LINES
    [STARTING BY 'string']
    [TERMINATED BY 'string']
  ]
lock_option:
  [WAIT n | NOWAIT | SKIP LOCKED]

Description
-----------

SELECT is used to retrieve rows selected from one or more tables, and can
include UNION statements and subqueries.

* Each select_expr expression indicates a column or data that you want to
retrieve. You
must have at least one select expression. See Select Expressions below.

* The FROM clause indicates the table or tables from which to retrieve rows.
Use either a single table name or a JOIN expression. See JOIN
for details. If no table is involved, FROM DUAL can be specified.

* Each table can also be specified as db_name.tabl_name. Each column can also
be specified as tbl_name.col_name or even db_name.tbl_name.col_name. This
allows one to write queries which involve multiple databases. See Identifier
Qualifiers for syntax details.

* The WHERE clause, if given, indicates the condition or
 conditions that rows must satisfy to be selected.
 where_condition is an expression that evaluates to true for
 each row to be selected. The statement selects all rows if there is no WHERE
 clause.
In the WHERE clause, you can use any of the functions and
 operators that MariaDB supports, except for aggregate (summary) functions.
See Functions and Operators and Functions and Modifiers for use with GROUP BY
(aggregate).

* Use the ORDER BY clause to order the results.

* Use the LIMIT clause allows you to restrict the results to only
a certain number of rows, optionally with an offset.

* Use the GROUP BY and HAVING clauses to group
rows together when they have columns or computed values in common.

SELECT can also be used to retrieve rows computed without reference to any
table.

Select Expressions
------------------

A SELECT statement must contain one or more select expressions, separated by
commas. Each select expression can be one of the following:

* The name of a column.
* Any expression using functions and operators.
* * to select all columns from all tables in the FROM clause.
* tbl_name.* to select all columns from just the table tbl_name.

When specifying a column, you can either use just the column name or qualify
the column name with the name of the table using tbl_name.col_name. The
qualified form is useful if you are joining multiple tables in the FROM
clause. If you do not qualify the column names when selecting from multiple
tables, MariaDB will try to find the column in each table. It is an error if
that column name exists in multiple tables.

You can quote column names using backticks. If you are qualifying column names
with table names, quote each part separately as `tbl_name`.`col_name`.

If you use any grouping functions in any of the select expressions, all rows
in your results will be implicitly grouped, as if you had used GROUP BY NULL.

DISTINCT
--------

A query may produce some identical rows. By default, all rows are retrieved,
even when their values are the same. To explicitly specify that you want to
retrieve identical rows, use the ALL option. If you want duplicates to be
removed from the resultset, use the DISTINCT option. DISTINCTROW is a synonym
for DISTINCT. See also COUNT DISTINCT and SELECT UNIQUE in Oracle mode.

INTO
----

The INTO clause is used to specify that the query results should be written to
a file or variable.

* SELECT INTO OUTFILE - formatting and writing the result to an external file.
* SELECT INTO DUMPFILE - binary-safe writing of the unformatted results to an
external file.
* SELECT INTO Variable - selecting and setting variables.

The reverse of SELECT INTO OUTFILE is LOAD DATA.

LIMIT
-----

Restricts the number of returned rows. See LIMIT and LIMIT ROWS EXAMINED for
details.

LOCK IN SHARE MODE/FOR UPDATE
-----------------------------

See LOCK IN SHARE MODE and FOR UPDATE for details on the respective locking
clauses.

OFFSET ... FETCH
----------------

MariaDB starting with 10.6
--------------------------
See SELECT ... OFFSET ... FETCH.

ORDER BY
--------

Order a resultset. See ORDER BY for details.

PARTITION
---------

Specifies to the optimizer which partitions are relevant for the query. Other
partitions will not be read. See Partition Pruning and Selection for details.

PROCEDURE
---------

Passes the whole result set to a C Procedure. See PROCEDURE and PROCEDURE
ANALYSE (the only built-in procedure not requiring the server to be
recompiled).

SKIP LOCKED
-----------

MariaDB starting with 10.6
--------------------------
The SKIP LOCKED clause was introduced in MariaDB 10.6.0.

This causes those rows that couldn't be locked (LOCK IN SHARE MODE or FOR
UPDATE) to be excluded from the result set. An explicit NOWAIT is implied
here. This is only implemented on InnoDB tables and ignored otherwise.

SQL_CALC_FOUND_ROWS
-------------------

When SQL_CALC_FOUND_ROWS is used, then MariaDB will calculate how many rows
would have been in the result, if there would be no LIMIT clause. The result
can be found by calling the function FOUND_ROWS() in your next sql statement.

max_statement_time clause
-------------------------

By using max_statement_time in conjunction with SET STATEMENT, it is possible
to limit the execution time of individual queries. For example:

SET STATEMENT max_statement_time=100 FOR 
 SELECT field1 FROM table_name ORDER BY field1;

WAIT/NOWAIT
-----------

Set the lock wait timeout. See WAIT and NOWAIT.

Examples
--------

SELECT f1,f2 FROM t1 WHERE (f3<=10) AND (f4='y');

See Getting Data from MariaDB (Beginner tutorial), or the various
sub-articles, for more examples.

URL: https://mariadb.com/kb/en/select/https://mariadb.com/kb/en/select/3�G��;
��-Subqueries and ALLSubqueries using the ALL keyword will return true if the comparison returns
true for each row returned by the subquery, or the subquery returns no rows.

Syntax
------

scalar_expression comparison_operator ALL <Table subquery>

* scalar_expression may be any expression that evaluates to a single
value
* comparison_operator may be any one of: =, >, <, >=, <=, <> or !=

ALL returns:

* NULL if the comparison operator returns NULL for at least one row returned
by the Table subquery or scalar_expression returns NULL.
* FALSE if the comparison operator returns FALSE for at least one row returned
by the Table subquery.
* TRUE if the comparison operator returns TRUE for all rows returned by the
Table subquery, or if Table subquery returns no rows.

NOT IN is an alias for <> ALL.

Examples
--------

CREATE TABLE sq1 (num TINYINT);

CREATE TABLE sq2 (num2 TINYINT);

INSERT INTO sq1 VALUES(100);

INSERT INTO sq2 VALUES(40),(50),(60);

SELECT * FROM sq1 WHERE num > ALL (SELECT * FROM sq2);
+------+
| num  |
+------+
|  100 |
+------+

Since 100 > all of 40,50 and 60, the evaluation is true and the row is returned

Adding a second row to sq1, where the evaluation for that record is false:

INSERT INTO sq1 VALUES(30);

SELECT * FROM sq1 WHERE num > ALL (SELECT * FROM sq2);
+------+
| num  |
+------+
|  100 |
+------+

Adding a new row to sq2, causing all evaluations to be false:

INSERT INTO sq2 VALUES(120);

SELECT * FROM sq1 WHERE num > ALL (SELECT * FROM sq2);
Empty set (0.00 sec)

When the subquery returns no results, the evaluation is still true:

SELECT * FROM sq1 WHERE num > ALL (SELECT * FROM sq2 WHERE num2 > 300);
+------+
| num  |
+------+
|  100 |
|   30 |
+------+

Evaluating against a NULL will cause the result to be unknown, or not true,
and therefore return no rows:

INSERT INTO sq2 VALUES (NULL);

SELECT * FROM sq1 WHERE num > ALL (SELECT * FROM sq2);

URL: https://mariadb.com/kb/en/subqueries-and-all/https://mariadb.com/kb/en/subqueries-and-all/�Y	-Subqueries and ANYSubqueries using the ANY keyword will return true if the comparison returns
true for at least one row returned by the subquery.

Syntax
------

The required syntax for an ANY or SOME quantified comparison is:

scalar_expression comparison_operator ANY <Table subquery>

Or:

scalar_expression comparison_operator SOME <Table subquery>

* scalar_expression may be any expression that evaluates to a
single value.
* comparison_operator may be any one of =, >, <, >=, <=, <> or !=.

ANY returns:

* TRUE if the comparison operator returns TRUE for at least one row returned
by the Table subquery.
* FALSE if the comparison operator returns FALSE for all rows returned by the
Table subquery, or Table subquery has zero rows.
* NULL if the comparison operator returns NULL for at least one row returned
by the Table subquery and doesn't returns TRUE for any of them, or if
scalar_expression returns NULL.

SOME is a synmonym for ANY, and IN is a synonym for = ANY

Examples
--------

CREATE TABLE sq1 (num TINYINT);

CREATE TABLE sq2 (num2 TINYINT);

INSERT INTO sq1 VALUES(100);

INSERT INTO sq2 VALUES(40),(50),(120);

SELECT * FROM sq1 WHERE num > ANY (SELECT * FROM sq2);
+------+
| num  |
+------+
|  100 |
+------+

100 is greater than two of the three values, and so the expression evaluates
as true.

SOME is a synonym for ANY:

SELECT * FROM sq1 WHERE num < SOME (SELECT * FROM sq2);
+------+
| num  |
+------+
|  100 |
+------+

IN is a synonym for = ANY, and here there are no matches, so no results are
returned:

SELECT * FROM sq1 WHERE num IN (SELECT * FROM sq2);
Empty set (0.00 sec)

INSERT INTO sq2 VALUES(100);
Query OK, 1 row affected (0.05 sec)

SELECT * FROM sq1 WHERE num <> ANY (SELECT * FROM sq2);
+------+
| num  |
+------+
|  100 |
+------+

Reading this query, the results may be counter-intuitive. It may seem to read
as "SELECT * FROM sq1 WHERE num does not match any results in sq2. Since it
does match 100, it could seem that the results are incorrect. However, the
query returns a result if the match does not match any of sq2. Since 100
already does not match 40, the expression evaluates to true immediately,
regardless of the 100's matching. It may be more easily readable to use SOME
in a case such as this:

SELECT * FROM sq1 WHERE num <> SOME (SELECT * FROM sq2);
+------+
| num  |
+------+
|  100 |
+------+

URL: https://mariadb.com/kb/en/subqueries-and-any/https://mariadb.com/kb/en/subqueries-and-any/��0Subqueries and EXISTSSyntax
------

SELECT ... WHERE EXISTS <Table subquery>

Description
-----------

Subqueries using the EXISTS keyword will return true if the subquery returns
any rows. Conversely, subqueries using NOT EXISTS will return true only if the
subquery returns no rows from the table.

EXISTS subqueries ignore the columns specified by the SELECT of the subquery,
since they're not relevant. For example,

SELECT col1 FROM t1 WHERE EXISTS (SELECT * FROM t2);

and

SELECT col1 FROM t1 WHERE EXISTS (SELECT col2 FROM t2);

produce identical results.

Examples
--------

CREATE TABLE sq1 (num TINYINT);

CREATE TABLE sq2 (num2 TINYINT);

INSERT INTO sq1 VALUES(100);

INSERT INTO sq2 VALUES(40),(50),(60);

SELECT * FROM sq1 WHERE EXISTS (SELECT * FROM sq2 WHERE num2>50);
+------+
| num  |
+------+
|  100 |
+------+

SELECT * FROM sq1 WHERE NOT EXISTS (SELECT * FROM sq2 GROUP BY num2 HAVING
MIN(num2)=40);
Empty set (0.00 sec)

URL: https://mariadb.com/kb/en/subqueries-and-exists/https://mariadb.com/kb/en/subqueries-and-exists/�#��	��߃t����6Subqueries in a FROM ClauseAlthough subqueries are more commonly placed in a WHERE clause, they can also
form part of the FROM clause. Such subqueries are commonly called derived
tables.

If a subquery is used in this way, you must also use an AS clause to name the
result of the subquery.

ORACLE mode
-----------

MariaDB starting with 10.6.0
----------------------------
From MariaDB 10.6.0, anonymous subqueries in a FROM clause (no AS clause) are
permitted in ORACLE mode.

Examples
--------

CREATE TABLE student (name CHAR(10), test CHAR(10), score TINYINT);

INSERT INTO student VALUES 
 ('Chun', 'SQL', 75), ('Chun', 'Tuning', 73),
 ('Esben', 'SQL', 43), ('Esben', 'Tuning', 31),
 ('Kaolin', 'SQL', 56), ('Kaolin', 'Tuning', 88),
 ('Tatiana', 'SQL', 87), ('Tatiana', 'Tuning', 83);

Assume that, given the data above, you want to return the average total for
all students. In other words, the average of Chun's 148 (75+73), Esben's 74
(43+31), etc.

You cannot do the following:

SELECT AVG(SUM(score)) FROM student GROUP BY name;
ERROR 1111 (HY000): Invalid use of group function

A subquery in the FROM clause is however permitted:

SELECT AVG(sq_sum) FROM (SELECT SUM(score) AS sq_sum FROM student GROUP BY
name) AS t;
+-------------+
| AVG(sq_sum) |
+-------------+
|    134.0000 |
+-------------+

From MariaDB 10.6 in ORACLE mode, the following is permitted:

SELECT * FROM (SELECT 1 FROM DUAL), (SELECT 2 FROM DUAL);

URL: https://mariadb.com/kb/en/subqueries-in-a-from-clause/https://mariadb.com/kb/en/subqueries-in-a-from-clause/��
/Subqueries and JOINsA subquery can quite often, but not in all cases, be rewritten as a JOIN.

Rewriting Subqueries as JOINS
-----------------------------

A subquery using IN can be rewritten with the DISTINCT keyword, for example:

SELECT * FROM table1 WHERE col1 IN (SELECT col1 FROM table2);

can be rewritten as:

SELECT DISTINCT table1.* FROM table1, table2 WHERE table1.col1=table2.col1;

NOT IN or NOT EXISTS queries can also be rewritten. For example, these two
queries returns the same result:

SELECT * FROM table1 WHERE col1 NOT IN (SELECT col1 FROM table2);
SELECT * FROM table1 WHERE NOT EXISTS (SELECT col1 FROM table2 WHERE
table1.col1=table2.col1);

and both can be rewritten as:

SELECT table1.* FROM table1 LEFT JOIN table2 ON table1.id=table2.id WHERE
table2.id IS NULL;

Subqueries that can be rewritten as a LEFT JOIN are sometimes more efficient.

Using Subqueries instead of JOINS
---------------------------------

There are some scenarios, though, which call for subqueries rather than joins:

* When you want duplicates, but not false duplicates. Suppose Table_1
 has three rows — {1,1,2}
 — and Table_2 has two rows
 — {1,2,2}. If you need to list the rows
 in Table_1 which are also in Table_2, only this
 subquery-based SELECT statement will give the right answer
 (1,1,2):

SELECT Table_1.column_1 
FROM   Table_1 
WHERE  Table_1.column_1 IN 
 (SELECT Table_2.column_1
  FROM   Table_2);

* This SQL statement won't work:

SELECT Table_1.column_1 
FROM   Table_1,Table_2 
WHERE  Table_1.column_1 = Table_2.column_1;

* because the result will be {1,1,2,2}
 — and the duplication of 2 is an error.  This SQL
 statement won't work either:

SELECT DISTINCT Table_1.column_1 
FROM   Table_1,Table_2 
WHERE  Table_1.column_1 = Table_2.column_1;

* because the result will be {1,2} — and
 the removal of the duplicated 1 is an error too.

* When the outermost statement is not a query. The SQL statement:

UPDATE Table_1 SET column_1 = (SELECT column_1 FROM Table_2);

* can't be expressed using a join unless some rare SQL3 features are used.

* When the join is over an expression. The SQL statement:

SELECT * FROM Table_1 
WHERE column_1 + 5 =
 (SELECT MAX(column_1) FROM Table_2);

* is hard to express with a join. In fact, the only way we can think of is
 this SQL statement:

SELECT Table_1.*
FROM   Table_1, 
   (SELECT MAX(column_1) AS max_column_1 FROM Table_2) AS Table_2
WHERE  Table_1.column_1 + 5 = Table_2.max_column_1;

* which still involves a parenthesized query, so nothing is gained from the
 transformation.

* When you want to see the exception. For example, suppose the question is:
 what books are longer than Das Kapital? These two queries are effectively
 almost the same:

SELECT DISTINCT Bookcolumn_1.*                     
FROM   Books AS Bookcolumn_1 JOIN Books AS Bookcolumn_2 USING(page_count) 
WHERE  title = 'Das Kapital';

SELECT DISTINCT Bookcolumn_1.* 
FROM   Books AS Bookcolumn_1 
WHERE  Bookcolumn_1.page_count > 
 (SELECT DISTINCT page_count
 FROM   Books AS Bookcolumn_2
 WHERE  title = 'Das Kapital');

* The difference is between these two SQL statements is, if there are two
 editions of Das Kapital (with different page counts), then the self-join
 example will return the books which are  longer than the shortest edition
 of Das Kapital. That might be the wrong answer, since the original
 question didn't ask for "... longer than ANY book named Das Kapital"
 (it seems to contain a false assumption that there's only one edition).

URL: https://mariadb.com/kb/en/subqueries-and-joins/https://mariadb.com/kb/en/subqueries-and-joins/%.�|ix�j��/Subquery LimitationsThere are a number of limitations regarding subqueries, which are discussed
below. The following tables and data will be used in the examples that follow:

CREATE TABLE staff(name VARCHAR(10),age TINYINT);

CREATE TABLE customer(name VARCHAR(10),age TINYINT);

INSERT INTO staff VALUES 
('Bilhah',37), ('Valerius',61), ('Maia',25);

INSERT INTO customer VALUES 
('Thanasis',48), ('Valerius',61), ('Brion',51);

ORDER BY and LIMIT
------------------

To use ORDER BY or limit LIMIT in subqueries both must be used.. For example:

SELECT * FROM staff WHERE name IN (SELECT name FROM customer ORDER BY name);
+----------+------+
| name     | age  |
+----------+------+
| Valerius |   61 |
+----------+------+

is valid, but

SELECT * FROM staff WHERE name IN (SELECT NAME FROM customer ORDER BY name
LIMIT 1);
ERROR 1235 (42000): This version of MariaDB doesn't 
 yet support 'LIMIT & IN/ALL/ANY/SOME subquery'

is not.

Modifying and Selecting from the Same Table
-------------------------------------------

It's not possible to both modify and select from the same table in a subquery.
For example:

DELETE FROM staff WHERE name = (SELECT name FROM staff WHERE age=61);
ERROR 1093 (HY000): Table 'staff' is specified twice, both 
 as a target for 'DELETE' and as a separate source for data

Row Comparison Operations
-------------------------

There is only partial support for row comparison operations. The expression in

expr op {ALL|ANY|SOME} subquery,

must be scalar and the subquery can only return a single column.

However, because of the way IN is implemented (it is rewritten as a sequence
of = comparisons and AND), the expression in

expression [NOT] IN subquery

is permitted to be an n-tuple and the subquery can return rows of n-tuples.

For example:

SELECT * FROM staff WHERE (name,age) NOT IN (
 SELECT name,age FROM customer WHERE age >=51]
);
+--------+------+
| name   | age  |
+--------+------+
| Bilhah |   37 |
| Maia   |   25 |
+--------+------+

is permitted, but

SELECT * FROM staff WHERE (name,age) = ALL (
 SELECT name,age FROM customer WHERE age >=51
);
ERROR 1241 (21000): Operand should contain 1 column(s)

is not.

Correlated Subqueries
---------------------

Subqueries in the FROM clause cannot be correlated subqueries. They cannot be
evaluated for each row of the outer query since they are evaluated to produce
a result set during when the query is executed.

Stored Functions
----------------

A subquery can refer to a stored function which modifies data. This is an
extension to the SQL standard, but can result in indeterminate outcomes. For
example, take:

SELECT ... WHERE x IN (SELECT f() ...);

where f() inserts rows. The function f() could be executed a different number
of times depending on how the optimizer chooses to handle the query.

This sort of construct is therefore not safe to use in replication that is not
row-based, as there could be different results on the master and the slave.

URL: https://mariadb.com/kb/en/subquery-limitations/https://mariadb.com/kb/en/subquery-limitations/�&^APrecedence Control in Table OperationsMariaDB starting with 10.4.0
----------------------------
Beginning in MariaDB 10.4, you can control the ordering of execution on table
operations using parentheses.

Syntax
------

(  expression )
[ORDER BY [column[, column...]]]
[LIMIT {[offset,] row_count | row_count OFFSET offset}]

Description
-----------

Using parentheses in your SQL allows you to control the order of execution for
SELECT statements and Table Value Constructor, including UNION, EXCEPT, and
INTERSECT operations. MariaDB executes the parenthetical expression before the
rest of the statement. You can then use ORDER BY and LIMIT clauses the further
organize the result-set.

Note: In practice, the Optimizer may rearrange the exact order in which
MariaDB executes different parts of the statement. When it calculates the
result-set, however, it returns values as though the parenthetical expression
were executed first.

Example
-------

CREATE TABLE test.t1 (num INT);

INSERT INTO test.t1 VALUES (1),(2),(3);

(SELECT * FROM test.t1 
 UNION 
 VALUES (10)) 
INTERSECT 
VALUES (1),(3),(10),(11);
+------+
| num  |
+------+
|    1 |
|    3 |
|   10 |
+------+

((SELECT * FROM test.t1 
 UNION
 VALUES (10))
 INTERSECT 
 VALUES (1),(3),(10),(11)) 
ORDER BY 1 DESC;
+------+
| num  |
+------+
|   10 |
|    3 |
|    1 |
+------+

URL: https://mariadb.com/kb/en/precedence-control-in-table-operations/https://mariadb.com/kb/en/precedence-control-in-table-operations/�/	JNon-Recursive Common Table Expressions OverviewCommon Table Expressions (CTEs) are a standard SQL feature, and are
essentially temporary named result sets. There are two kinds of CTEs:
Non-Recursive, which this article covers; and Recursive.

Non-Recursive CTEs
------------------

The WITH keyword signifies a CTE. It is given a name, followed by a body (the
main query) as follows:

CTEs are similar to derived tables. For example

WITH engineers AS 
 ( SELECT * FROM employees
  WHERE dept = 'Engineering' )

SELECT * FROM engineers
WHERE ...

SELECT * FROM
 ( SELECT * FROM employees
  WHERE dept = 'Engineering' ) AS engineers
WHERE
...

A non-recursive CTE is basically a query-local VIEW. There are several
advantages and caveats to them. The syntax is more readable than nested FROM
(SELECT ...). A CTE can refer to another and it can be referenced from
multiple places.

A CTE referencing Another CTE
-----------------------------

Using this format makes for a more readable SQL than a nested FROM(SELECT ...)
clause. Below is an example of this:

WITH engineers AS (
SELECT * FROM employees
WHERE dept IN('Development','Support') ),
eu_engineers AS ( SELECT * FROM engineers WHERE country IN('NL',...) )
SELECT
...
FROM eu_engineers;

Multiple Uses of a CTE
----------------------

This can be an 'anti-self join', for example:

WITH engineers AS (
SELECT * FROM employees
WHERE dept IN('Development','Support') )

SELECT * FROM engineers E1
WHERE NOT EXISTS
 (SELECT 1 FROM engineers E2
  WHERE E2.country=E1.country
  AND E2.name <> E1.name );

Or, for year-over-year comparisons, for example:

WITH sales_product_year AS (
SELECT product, YEAR(ship_date) AS year,
SUM(price) AS total_amt
FROM item_sales
GROUP BY product, year )

SELECT *
FROM sales_product_year CUR,
sales_product_year PREV,
WHERE CUR.product=PREV.product 
AND  CUR.year=PREV.year + 1 
AND CUR.total_amt > PREV.total_amt

Another use is to compare individuals against their group. Below is an example
of how this might be executed:

WITH sales_product_year AS (
SELECT product,
YEAR(ship_date) AS year,
SUM(price) AS total_amt
FROM item_sales
GROUP BY product, year
)

SELECT * 
FROM sales_product_year S1
WHERE
total_amt > 
  (SELECT 0.1 * SUM(total_amt)
  FROM sales_product_year S2
  WHERE S2.year = S1.year)

URL: https://mariadb.com/kb/en/non-recursive-common-table-expressions-overview/https://mariadb.com/kb/en/non-recursive-common-table-expressions-overview/��	�	QQ`��Y�` UNIONUNION is used to combine the results from multiple SELECT statements into a
single result set.

Syntax
------

SELECT ...
UNION [ALL | DISTINCT] SELECT ...
[UNION [ALL | DISTINCT] SELECT ...]
[ORDER BY [column [, column ...]]]
[LIMIT {[offset,] row_count | row_count OFFSET offset}]

Description
-----------

UNION is used to combine the results from multiple SELECT statements into a
single result set.

The column names from the first SELECT statement are used as the column names
for the results returned. Selected columns listed in corresponding positions
of each SELECT statement should have the same data type. (For example, the
first column selected by the first statement should have the same type as the
first column selected by the other statements.)

If they don't, the type and length of the columns in the result take into
account the values returned by all of the SELECTs, so there is no need for
explicit casting. Note that currently this is not the case for recursive CTEs
- see MDEV-12325.

Table names can be specified as db_name.tbl_name. This permits writing UNIONs
which involve multiple databases. See Identifier Qualifiers for syntax details.

UNION queries cannot be used with aggregate functions.

EXCEPT and UNION have the same operation precedence and INTERSECT has a higher
precedence, unless running in Oracle mode, in which case all three have the
same precedence.

ALL/DISTINCT
------------

The ALL keyword causes duplicate rows to be preserved. The DISTINCT keyword
(the default if the keyword is omitted) causes duplicate rows to be removed by
the results.

UNION ALL and UNION DISTINCT can both be present in a query. In this case,
UNION DISTINCT will override any UNION ALLs to its left.

MariaDB starting with 10.1.1
----------------------------
Until MariaDB 10.1.1, all UNION ALL statements required the server to create a
temporary table. Since MariaDB 10.1.1, the server can in most cases execute
UNION ALL without creating a temporary table, improving performance (see
MDEV-334).

ORDER BY and LIMIT
------------------

Individual SELECTs can contain their own ORDER BY and LIMIT clauses. In this
case, the individual queries need to be wrapped between parentheses. However,
this does not affect the order of the UNION, so they only are useful to limit
the record read by one SELECT.

The UNION can have global ORDER BY and LIMIT clauses, which affect the whole
resultset. If the columns retrieved by individual SELECT statements have an
alias (AS), the ORDER BY must use that alias, not the real column names.

HIGH_PRIORITY
-------------

Specifying a query as HIGH_PRIORITY will not work inside a UNION. If applied
to the first SELECT, it will be ignored. Applying to a later SELECT results in
a syntax error:

ERROR 1234 (42000): Incorrect usage/placement of 'HIGH_PRIORITY'

SELECT ... INTO ...
-------------------

Individual SELECTs cannot be written INTO DUMPFILE or INTO OUTFILE. If the
last SELECT statement specifies INTO DUMPFILE or INTO OUTFILE, the entire
result of the UNION will be written. Placing the clause after any other SELECT
will result in a syntax error.

If the result is a single row, SELECT ... INTO @var_name can also be used.

MariaDB starting with 10.4.0
----------------------------

Parentheses
-----------

From MariaDB 10.4.0, parentheses can be used to specify precedence. Before
this, a syntax error would be returned.

Examples
--------

UNION between tables having different column names:

(SELECT e_name AS name, email FROM employees)
UNION
(SELECT c_name AS name, email FROM customers);

Specifying the UNION's global order and limiting total rows:

(SELECT name, email FROM employees)
UNION
(SELECT name, email FROM customers)
ORDER BY name LIMIT 10;

Adding a constant row:

(SELECT 'John Doe' AS name, 'john.doe@example.net' AS email)
UNION
(SELECT name, email FROM customers);

Differing types:

SELECT CAST('x' AS CHAR(1)) UNION SELECT REPEAT('y',4);
+----------------------+
| CAST('x' AS CHAR(1)) |
+----------------------+
| x                    |
| yyyy                 |
+----------------------+

Returning the results in order of each individual SELECT by use of a sort
column:

(SELECT 1 AS sort_column, e_name AS name, email FROM employees)
UNION
(SELECT 2, c_name AS name, email FROM customers) ORDER BY sort_column;

Difference between UNION, EXCEPT and INTERSECT. INTERSECT ALL and EXCEPT ALL
are available from MariaDB 10.5.0.

CREATE TABLE seqs (i INT);
INSERT INTO seqs VALUES (1),(2),(2),(3),(3),(4),(5),(6);

SELECT i FROM seqs WHERE i <= 3 UNION SELECT i FROM seqs WHERE i>=3;
+------+
| i    |
+------+
|    1 |
|    2 |
|    3 |
|    4 |
|    5 |
|    6 |
+------+

SELECT i FROM seqs WHERE i <= 3 UNION ALL SELECT i FROM seqs WHERE i>=3;
+------+
| i    |
+------+
|    1 |
|    2 |
|    2 |
|    3 |
|    3 |
|    3 |
|    3 |
|    4 |
|    5 |
|    6 |
+------+

SELECT i FROM seqs WHERE i <= 3 EXCEPT SELECT i FROM seqs WHERE i>=3;
+------+
| i    |
+------+
|    1 |
|    2 |
+------+

SELECT i FROM seqs WHERE i <= 3 EXCEPT ALL SELECT i FROM seqs WHERE i>=3;
+------+
| i    |
+------+
|    1 |
|    2 |
|    2 |
+------+

SELECT i FROM seqs WHERE i <= 3 INTERSECT SELECT i FROM seqs WHERE i>=3;
+------+
| i    |
+------+
|    3 |
+------+

SELECT i FROM seqs WHERE i <= 3 INTERSECT ALL SELECT i FROM seqs WHERE i>=3;
+------+
| i    |
+------+
|    3 |
|    3 |
+------+

Parentheses for specifying precedence, from MariaDB 10.4.0

CREATE OR REPLACE TABLE t1 (a INT);
CREATE OR REPLACE TABLE t2 (b INT);
CREATE OR REPLACE TABLE t3 (c INT);

INSERT INTO t1 VALUES (1),(2),(3),(4);
INSERT INTO t2 VALUES (5),(6);
INSERT INTO t3 VALUES (1),(6);

((SELECT a FROM t1) UNION (SELECT b FROM t2)) INTERSECT (SELECT c FROM t3);
+------+
| a    |
+------+
|    1 |
|    6 |
+------+

(SELECT a FROM t1) UNION ((SELECT b FROM t2) INTERSECT (SELECT c FROM t3));
+------+
| a    |
+------+
|    1 |
|    2 |
|    3 |
|    4 |
|    6 |
+------+

URL: https://mariadb.com/kb/en/union/https://mariadb.com/kb/en/union/�1C�Y��!EXCEPTThe result of EXCEPT is all records of the left SELECT result set except
records which are in right SELECT result set, i.e. it is subtraction of two
result sets. From MariaDB 10.6.1, MINUS is a synonym when SQL_MODE=ORACLE is
set.

Syntax
------

SELECT ...
(INTERSECT [ALL | DISTINCT] | EXCEPT [ALL | DISTINCT] | UNION [ALL |
DISTINCT]) 
 SELECT ...
[(INTERSECT [ALL | DISTINCT] | EXCEPT [ALL | DISTINCT] | UNION [ALL |
DISTINCT]) 
 SELECT ...]
[ORDER BY [{col_name | expr | position} [ASC | DESC] 
 [, {col_name | expr | position} [ASC | DESC] ...]]]
[LIMIT {[offset,] row_count | row_count OFFSET offset}
| OFFSET start { ROW | ROWS }
| FETCH { FIRST | NEXT } [ count ] { ROW | ROWS } { ONLY | WITH TIES } ]

Please note:

* Brackets for explicit operation precedence are not supported; use a subquery
in the FROM clause as a workaround).

Description
-----------

MariaDB has supported EXCEPT and INTERSECT in addition to UNION since MariaDB
10.3.

The queries before and after EXCEPT must be SELECT or VALUES statements.

All behavior for naming columns, ORDER BY and LIMIT is the same as for UNION.
Note that the alternative SELECT ... OFFSET ... FETCH syntax is only
supported. This allows us to use the WITH TIES clause.

EXCEPT implicitly supposes a DISTINCT operation.

The result of EXCEPT is all records of the left SELECT result except records
which are in right SELECT result set, i.e. it is subtraction of two result
sets.

EXCEPT and UNION have the same operation precedence and INTERSECT has a higher
precedence, unless running in Oracle mode, in which case all three have the
same precedence.

MariaDB starting with 10.4.0
----------------------------

Parentheses
-----------

From MariaDB 10.4.0, parentheses can be used to specify precedence. Before
this, a syntax error would be returned.

MariaDB starting with 10.5.0
----------------------------

ALL/DISTINCT
------------

EXCEPT ALL and EXCEPT DISTINCT were introduced in MariaDB 10.5.0. The ALL
operator leaves duplicates intact, while the DISTINCT operator removes
duplicates. DISTINCT is the default behavior if neither operator is supplied,
and the only behavior prior to MariaDB 10.5.

Examples
--------

Show customers which are not employees:

(SELECT e_name AS name, email FROM customers)
EXCEPT
(SELECT c_name AS name, email FROM employees);

Difference between UNION, EXCEPT and INTERSECT. INTERSECT ALL and EXCEPT ALL
are available from MariaDB 10.5.0.

CREATE TABLE seqs (i INT);
INSERT INTO seqs VALUES (1),(2),(2),(3),(3),(4),(5),(6);

SELECT i FROM seqs WHERE i <= 3 UNION SELECT i FROM seqs WHERE i>=3;
+------+
| i    |
+------+
|    1 |
|    2 |
|    3 |
|    4 |
|    5 |
|    6 |
+------+

SELECT i FROM seqs WHERE i <= 3 UNION ALL SELECT i FROM seqs WHERE i>=3;
+------+
| i    |
+------+
|    1 |
|    2 |
|    2 |
|    3 |
|    3 |
|    3 |
|    3 |
|    4 |
|    5 |
|    6 |
+------+

SELECT i FROM seqs WHERE i <= 3 EXCEPT SELECT i FROM seqs WHERE i>=3;
+------+
| i    |
+------+
|    1 |
|    2 |
+------+

SELECT i FROM seqs WHERE i <= 3 EXCEPT ALL SELECT i FROM seqs WHERE i>=3;
+------+
| i    |
+------+
|    1 |
|    2 |
|    2 |
+------+

SELECT i FROM seqs WHERE i <= 3 INTERSECT SELECT i FROM seqs WHERE i>=3;
+------+
| i    |
+------+
|    3 |
+------+

SELECT i FROM seqs WHERE i <= 3 INTERSECT ALL SELECT i FROM seqs WHERE i>=3;
+------+
| i    |
+------+
|    3 |
|    3 |
+------+

Parentheses for specifying precedence, from MariaDB 10.4.0

CREATE OR REPLACE TABLE t1 (a INT);
CREATE OR REPLACE TABLE t2 (b INT);
CREATE OR REPLACE TABLE t3 (c INT);

INSERT INTO t1 VALUES (1),(2),(3),(4);
INSERT INTO t2 VALUES (5),(6);
INSERT INTO t3 VALUES (1),(6);

((SELECT a FROM t1) UNION (SELECT b FROM t2)) EXCEPT (SELECT c FROM t3);
+------+
| a    |
+------+
|    2 |
|    3 |
|    4 |
|    5 |
+------+

(SELECT a FROM t1) UNION ((SELECT b FROM t2) EXCEPT (SELECT c FROM t3));
+------+
| a    |
+------+
|    1 |
|    2 |
|    3 |
|    4 |
|    5 |
+------+

Here is an example that makes use of the SEQUENCE storage engine and the
VALUES statement, to generate a numeric sequence and remove some arbitrary
numbers from it:

(SELECT seq FROM seq_1_to_10) EXCEPT VALUES (2), (3), (4);
+-----+
| seq |
+-----+
|   1 |
|   5 |
|   6 |
|   7 |
|   8 |
|   9 |
|  10 |
+-----+

URL: https://mariadb.com/kb/en/except/https://mariadb.com/kb/en/except/�'	.SELECT INTO OUTFILESyntax
------

SELECT ... INTO OUTFILE 'file_name'
    [CHARACTER SET charset_name]
    [export_options]

export_options:
  [{FIELDS | COLUMNS}
    [TERMINATED BY 'string']
    [[OPTIONALLY] ENCLOSED BY 'char']
    [ESCAPED BY 'char']
  ]
  [LINES
    [STARTING BY 'string']
    [TERMINATED BY 'string']
  ]

Description
-----------

SELECT INTO OUTFILE writes the resulting rows to a file, and allows the use of
column and row terminators to specify a particular output format. The default
is to terminate fields with tabs (\t) and lines with newlines (\n).

The file must not exist. It cannot be overwritten. A user needs the FILE
privilege to run this statement. Also, MariaDB needs permission to write files
in the specified location. If the secure_file_priv system variable is set to a
non-empty directory name, the file can only be written to that directory.

The LOAD DATA INFILE statement complements SELECT INTO OUTFILE.

Character-sets
--------------

The CHARACTER SET clause specifies the character set in which the results are
to be written. Without the clause, no conversion takes place (the binary
character set). In this case, if there are multiple character sets, the output
will contain these too, and may not easily be able to be reloaded.

In cases where you have two servers using different character-sets, using
SELECT INTO OUTFILE to transfer data from one to the other can have unexpected
results. To ensure that MariaDB correctly interprets the escape sequences, use
the CHARACTER SET clause on both the SELECT INTO OUTFILE statement and the
subsequent LOAD DATA INFILE statement.

Example
-------

The following example produces a file in the CSV format:

SELECT customer_id, firstname, surname from customer
 INTO OUTFILE '/exportdata/customers.txt'
 FIELDS TERMINATED BY ',' OPTIONALLY ENCLOSED BY '"'
 LINES TERMINATED BY '\n';

The following ANSI syntax is also supported for simple SELECT without UNION

SELECT customer_id, firstname, surname INTO OUTFILE '/exportdata/customers.txt'
 FIELDS TERMINATED BY ',' OPTIONALLY ENCLOSED BY '"'
 LINES TERMINATED BY '\n'
 FROM customers;

If you want to use the ANSI syntax with UNION or similar construct you have to
use the syntax:

SELECT  * INTO OUTFILE "/tmp/skr3" FROM (SELECT * FROM t1 UNION SELECT * FROM
t1);

URL: https://mariadb.com/kb/en/select-into-outfile/https://mariadb.com/kb/en/select-into-outfile/%v	Zk5�0
�	`$INTERSECTMariaDB starting with 10.3.0
----------------------------
INTERSECT was introduced in MariaDB 10.3.0.

The result of an intersect is the intersection of right and left SELECT
results, i.e. only records that are present in both result sets will be
included in the result of the operation.

Syntax
------

SELECT ...
(INTERSECT [ALL | DISTINCT] | EXCEPT [ALL | DISTINCT] | UNION [ALL |
DISTINCT]) SELECT ...
[(INTERSECT [ALL | DISTINCT] | EXCEPT [ALL | DISTINCT] | UNION [ALL |
DISTINCT]) SELECT ...]
[ORDER BY [column [, column ...]]]
[LIMIT {[offset,] row_count | row_count OFFSET offset}]

Description
-----------

MariaDB has supported INTERSECT (as well as EXCEPT) in addition to UNION since
MariaDB 10.3.

All behavior for naming columns, ORDER BY and LIMIT is the same as for UNION.

INTERSECT implicitly supposes a DISTINCT operation.

The result of an intersect is the intersection of right and left SELECT
results, i.e. only records that are present in both result sets will be
included in the result of the operation.

INTERSECT has higher precedence than UNION and EXCEPT (unless running running
in Oracle mode, in which case all three have the same precedence). If possible
it will be executed linearly but if not it will be translated to a subquery in
the FROM clause:

(select a,b from t1)
union
(select c,d from t2)
intersect
(select e,f from t3)
union
(select 4,4);

will be translated to:

(select a,b from t1)
union
select c,d from
 ((select c,d from t2)
 intersect
 (select e,f from t3)) dummy_subselect
union
(select 4,4)

MariaDB starting with 10.4.0
----------------------------

Parentheses
-----------

From MariaDB 10.4.0, parentheses can be used to specify precedence. Before
this, a syntax error would be returned.

MariaDB starting with 10.5.0
----------------------------

ALL/DISTINCT
------------

INTERSECT ALL and INTERSECT DISTINCT were introduced in MariaDB 10.5.0. The
ALL operator leaves duplicates intact, while the DISTINCT operator removes
duplicates. DISTINCT is the default behavior if neither operator is supplied,
and the only behavior prior to MariaDB 10.5.

Examples
--------

Show customers which are employees:

(SELECT e_name AS name, email FROM employees)
INTERSECT
(SELECT c_name AS name, email FROM customers);

Difference between UNION, EXCEPT and INTERSECT. INTERSECT ALL and EXCEPT ALL
are available from MariaDB 10.5.0.

CREATE TABLE seqs (i INT);
INSERT INTO seqs VALUES (1),(2),(2),(3),(3),(4),(5),(6);

SELECT i FROM seqs WHERE i <= 3 UNION SELECT i FROM seqs WHERE i>=3;
+------+
| i    |
+------+
|    1 |
|    2 |
|    3 |
|    4 |
|    5 |
|    6 |
+------+

SELECT i FROM seqs WHERE i <= 3 UNION ALL SELECT i FROM seqs WHERE i>=3;
+------+
| i    |
+------+
|    1 |
|    2 |
|    2 |
|    3 |
|    3 |
|    3 |
|    3 |
|    4 |
|    5 |
|    6 |
+------+

SELECT i FROM seqs WHERE i <= 3 EXCEPT SELECT i FROM seqs WHERE i>=3;
+------+
| i    |
+------+
|    1 |
|    2 |
+------+

SELECT i FROM seqs WHERE i <= 3 EXCEPT ALL SELECT i FROM seqs WHERE i>=3;
+------+
| i    |
+------+
|    1 |
|    2 |
|    2 |
+------+

SELECT i FROM seqs WHERE i <= 3 INTERSECT SELECT i FROM seqs WHERE i>=3;
+------+
| i    |
+------+
|    3 |
+------+

SELECT i FROM seqs WHERE i <= 3 INTERSECT ALL SELECT i FROM seqs WHERE i>=3;
+------+
| i    |
+------+
|    3 |
|    3 |
+------+

Parentheses for specifying precedence, from MariaDB 10.4.0

CREATE OR REPLACE TABLE t1 (a INT);
CREATE OR REPLACE TABLE t2 (b INT);
CREATE OR REPLACE TABLE t3 (c INT);

INSERT INTO t1 VALUES (1),(2),(3),(4);
INSERT INTO t2 VALUES (5),(6);
INSERT INTO t3 VALUES (1),(6);

((SELECT a FROM t1) UNION (SELECT b FROM t2)) INTERSECT (SELECT c FROM t3);
+------+
| a    |
+------+
|    1 |
|    6 |
+------+

(SELECT a FROM t1) UNION ((SELECT b FROM t2) INTERSECT (SELECT c FROM t3));
+------+
| a    |
+------+
|    1 |
|    2 |
|    3 |
|    4 |
|    6 |
+------+

URL: https://mariadb.com/kb/en/intersect/https://mariadb.com/kb/en/intersect/��/SELECT INTO DUMPFILESyntax
------

SELECT ... INTO DUMPFILE 'file_path'

Description
-----------

SELECT ... INTO DUMPFILE is a SELECT clause which writes the resultset into a
single unformatted row, without any separators, in a file. The results will
not be returned to the client.

file_path can be an absolute path, or a relative path starting from the data
directory. It can only be specified as a string literal, not as a variable.
However, the statement can be dynamically composed and executed as a prepared
statement to work around this limitation.

This statement is binary-safe and so is particularly useful for writing BLOB
values to file. It can be used, for example, to copy an image or an audio
document from the database to a file. SELECT ... INTO FILE can be used to save
a text file.

The file must not exist. It cannot be overwritten. A user needs the FILE
privilege to run this statement. Also, MariaDB needs permission to write files
in the specified location. If the secure_file_priv system variable is set to a
non-empty directory name, the file can only be written to that directory.

Since MariaDB 5.1, the character_set_filesystem system variable has controlled
interpretation of file names that are given as literal strings.

Example
-------

SELECT _utf8'Hello world!' INTO DUMPFILE '/tmp/world';

SELECT LOAD_FILE('/tmp/world') AS world;
+--------------+
| world        |
+--------------+
| Hello world! |
+--------------+

URL: https://mariadb.com/kb/en/select-into-dumpfile/https://mariadb.com/kb/en/select-into-dumpfile/���b�#��
 LIMITDescription
-----------

Use the LIMIT clause to restrict the number of returned rows. When you use a
single integer n with LIMIT, the first n rows will be returned. Use the ORDER
BY clause to control which rows come first. You can also select a number of
rows after an offset using either of the following:

LIMIT offset, row_count
LIMIT row_count OFFSET offset

When you provide an offset m with a limit n, the first m rows will be ignored,
and the following n rows will be returned.

Executing an UPDATE with the LIMIT clause is not safe for replication. LIMIT 0
is an exception to this rule (see MDEV-6170).

There is a LIMIT ROWS EXAMINED optimization which provides the means to
terminate the execution of SELECT statements which examine too many rows, and
thus use too many resources. See LIMIT ROWS EXAMINED.

Multi-Table Updates
-------------------

MariaDB starting with 10.3.2
----------------------------
Until MariaDB 10.3.1, it was not possible to use LIMIT (or ORDER BY) in a
multi-table UPDATE statement. This restriction was lifted in MariaDB 10.3.2.

GROUP_CONCAT
------------

MariaDB starting with 10.3.2
----------------------------
Starting from MariaDB 10.3.3, it is possible to use LIMIT with GROUP_CONCAT().

Examples
--------

CREATE TABLE members (name VARCHAR(20));
INSERT INTO members VALUES('Jagdish'),('Kenny'),('Rokurou'),('Immaculada');

SELECT * FROM members;
+------------+
| name       |
+------------+
| Jagdish    |
| Kenny      |
| Rokurou    |
| Immaculada |
+------------+

Select the first two names (no ordering specified):

SELECT * FROM members LIMIT 2;
+---------+
| name    |
+---------+
| Jagdish |
| Kenny   |
+---------+

All the names in alphabetical order:

SELECT * FROM members ORDER BY name;
+------------+
| name       |
+------------+
| Immaculada |
| Jagdish    |
| Kenny      |
| Rokurou    |
+------------+

The first two names, ordered alphabetically:

SELECT * FROM members ORDER BY name LIMIT 2;
+------------+
| name       |
+------------+
| Immaculada |
| Jagdish    |
+------------+

The third name, ordered alphabetically (the first name would be offset zero,
so the third is offset two):

SELECT * FROM members ORDER BY name LIMIT 2,1;
+-------+
| name  |
+-------+
| Kenny |
+-------+

From MariaDB 10.3.2, LIMIT can be used in a multi-table update:

CREATE TABLE warehouse (product_id INT, qty INT);
INSERT INTO warehouse VALUES (1,100),(2,100),(3,100),(4,100);

CREATE TABLE store (product_id INT, qty INT);
INSERT INTO store VALUES (1,5),(2,5),(3,5),(4,5);

UPDATE warehouse,store SET warehouse.qty = warehouse.qty-2, store.qty =
store.qty+2 
 WHERE (warehouse.product_id = store.product_id AND store.product_id  >= 1)
  ORDER BY store.product_id DESC LIMIT 2;

SELECT * FROM warehouse;
+------------+------+
| product_id | qty  |
+------------+------+
|          1 |  100 |
|          2 |  100 |
|          3 |   98 |
|          4 |   98 |
+------------+------+

SELECT * FROM store;
+------------+------+
| product_id | qty  |
+------------+------+
|          1 |    5 |
|          2 |    5 |
|          3 |    7 |
|          4 |    7 |
+------------+------+

From MariaDB 10.3.3, LIMIT can be used with GROUP_CONCAT, so, for example,
given the following table:

CREATE TABLE d (dd DATE, cc INT);

INSERT INTO d VALUES ('2017-01-01',1);
INSERT INTO d VALUES ('2017-01-02',2);
INSERT INTO d VALUES ('2017-01-04',3);

the following query:

SELECT SUBSTRING_INDEX(GROUP_CONCAT(CONCAT_WS(":",dd,cc) ORDER BY cc
DESC),",",1) FROM d;
+----------------------------------------------------------------------------+
| SUBSTRING_INDEX(GROUP_CONCAT(CONCAT_WS(":",dd,cc) ORDER BY cc DESC),",",1) |
+----------------------------------------------------------------------------+
| 2017-01-04:3                                                               |
+----------------------------------------------------------------------------+

can be more simply rewritten as:

SELECT GROUP_CONCAT(CONCAT_WS(":",dd,cc) ORDER BY cc DESC LIMIT 1) FROM d;
+-------------------------------------------------------------+
| GROUP_CONCAT(CONCAT_WS(":",dd,cc) ORDER BY cc DESC LIMIT 1) |
+-------------------------------------------------------------+
| 2017-01-04:3                                                |
+-------------------------------------------------------------+

URL: https://mariadb.com/kb/en/limit/https://mariadb.com/kb/en/limit/�
[%FOR UPDATEInnoDB supports row-level locking. Selected rows can be locked using LOCK IN
SHARE MODE or FOR UPDATE. In both cases, a lock is acquired on the rows read
by the query, and it will be released when the current transaction is
committed.

The FOR UPDATE clause of SELECT applies only when autocommit is set to 0 or
the SELECT is enclosed in a transaction. A lock is acquired on the rows, and
other transactions are prevented from writing the rows, acquire locks, and
from reading them (unless their isolation level is READ UNCOMMITTED).

If autocommit is set to 1, the LOCK IN SHARE MODE and FOR UPDATE clauses have
no effect.

If the isolation level is set to SERIALIZABLE, all plain SELECT statements are
converted to SELECT ... LOCK IN SHARE MODE.

Example
-------

SELECT * FROM trans WHERE period=2001 FOR UPDATE;

URL: https://mariadb.com/kb/en/for-update/https://mariadb.com/kb/en/for-update/L�@�)�
��
#ORDER BYDescription
-----------

Use the ORDER BY clause to order a resultset, such as that are returned from a
SELECT statement. You can specify just a column or use any expression with
functions. If you are using the GROUP BY clause, you can use grouping
functions in ORDER BY. Ordering is done after grouping.

You can use multiple ordering expressions, separated by commas. Rows will be
sorted by the first expression, then by the second expression if they have the
same value for the first, and so on.

You can use the keywords ASC and DESC after each ordering expression to force
that ordering to be ascending or descending, respectively. Ordering is
ascending by default.

You can also use a single integer as the ordering expression. If you use an
integer n, the results will be ordered by the nth column in the select
expression.

When string values are compared, they are compared as if by the STRCMP
function. STRCMP ignores trailing whitespace and may normalize characters and
ignore case, depending on the collation in use.

Duplicated entries in the ORDER BY clause are removed.

ORDER BY can also be used to order the activities of a DELETE or UPDATE
statement (usually with the LIMIT clause).

MariaDB starting with 10.3.2
----------------------------
Until MariaDB 10.3.1, it was not possible to use ORDER BY (or LIMIT) in a
multi-table UPDATE statement. This restriction was lifted in MariaDB 10.3.2.

MariaDB starting with 10.5
--------------------------
From MariaDB 10.5, MariaDB allows packed sort keys and values of non-sorted
fields in the sort buffer. This can make filesort temporary files much smaller
when VARCHAR, CHAR or BLOBs are used, notably speeding up some ORDER BY sorts.

Examples
--------

CREATE TABLE seq (i INT, x VARCHAR(1));
INSERT INTO seq VALUES (1,'a'), (2,'b'), (3,'b'), (4,'f'), (5,'e');

SELECT * FROM seq ORDER BY i;
+------+------+
| i    | x    |
+------+------+
|    1 | a    |
|    2 | b    |
|    3 | b    |
|    4 | f    |
|    5 | e    |
+------+------+

SELECT * FROM seq ORDER BY i DESC;
+------+------+
| i    | x    |
+------+------+
|    5 | e    |
|    4 | f    |
|    3 | b    |
|    2 | b    |
|    1 | a    |
+------+------+

SELECT * FROM seq ORDER BY x,i;
+------+------+
| i    | x    |
+------+------+
|    1 | a    |
|    2 | b    |
|    3 | b    |
|    5 | e    |
|    4 | f    |
+------+------+

ORDER BY in an UPDATE statement, in conjunction with LIMIT:

UPDATE seq SET x='z' WHERE x='b' ORDER BY i DESC LIMIT 1;

SELECT * FROM seq;
+------+------+
| i    | x    |
+------+------+
|    1 | a    |
|    2 | b    |
|    3 | z    |
|    4 | f    |
|    5 | e    |
+------+------+

From MariaDB 10.3.2, ORDER BY can be used in a multi-table update:

CREATE TABLE warehouse (product_id INT, qty INT);
INSERT INTO warehouse VALUES (1,100),(2,100),(3,100),(4,100);

CREATE TABLE store (product_id INT, qty INT);
INSERT INTO store VALUES (1,5),(2,5),(3,5),(4,5);

UPDATE warehouse,store SET warehouse.qty = warehouse.qty-2, store.qty =
store.qty+2 
 WHERE (warehouse.product_id = store.product_id AND store.product_id  >= 1)
  ORDER BY store.product_id DESC LIMIT 2;

SELECT * FROM warehouse;
+------------+------+
| product_id | qty  |
+------------+------+
|          1 |  100 |
|          2 |  100 |
|          3 |   98 |
|          4 |   98 |
+------------+------+

SELECT * FROM store;
+------------+------+
| product_id | qty  |
+------------+------+
|          1 |    5 |
|          2 |    5 |
|          3 |    7 |
|          4 |    7 |
+------------+------+

URL: https://mariadb.com/kb/en/order-by/https://mariadb.com/kb/en/order-by/�o	*Optimizer HintsOptimizer hints
---------------

There are some options available in SELECT to affect the execution plan. These
are known as optimizer hints.

HIGH PRIORITY
-------------

HIGH_PRIORITY gives the statement a higher priority. If the table is locked,
high priority SELECTs will be executed as soon as the lock is released, even
if other statements are queued. HIGH_PRIORITY applies only if the storage
engine only supports table-level locking (MyISAM, MEMORY, MERGE). See
HIGH_PRIORITY and LOW_PRIORITY clauses for details.

SQL_CACHE / SQL_NO_CACHE
------------------------

If the query_cache_type system variable is set to 2 or DEMAND, and the current
statement is cacheable, SQL_CACHE causes the query to be cached and
SQL_NO_CACHE causes the query not to be cached. For UNIONs, SQL_CACHE or
SQL_NO_CACHE should be specified for the first query. See also The Query Cache
for more detail and a list of the types of statements that aren't cacheable.

SQL_BUFFER_RESULT
-----------------

SQL_BUFFER_RESULT forces the optimizer to use a temporary table to process the
result. This is useful to free locks as soon as possible.

SQL_SMALL_RESULT / SQL_BIG_RESULT
---------------------------------

SQL_SMALL_RESULT and SQL_BIG_RESULT tell the optimizer whether the result is
very big or not. Usually, GROUP BY and DISTINCT operations are performed using
a temporary table. Only if the result is very big, using a temporary table is
not convenient. The optimizer automatically knows if the result is too big,
but you can force the optimizer to use a temporary table with
SQL_SMALL_RESULT, or avoid the temporary table using SQL_BIG_RESULT.

STRAIGHT_JOIN
-------------

STRAIGHT_JOIN applies to the JOIN queries, and tells the optimizer that the
tables must be read in the order they appear in the SELECT. For const and
system table this options is sometimes ignored.

SQL_CALC_FOUND_ROWS
-------------------

SQL_CALC_FOUND_ROWS is only applied when using the LIMIT clause. If this
option is used, MariaDB will count how many rows would match the query,
without the LIMIT clause. That number can be retrieved in the next query,
using FOUND_ROWS().

USE/FORCE/IGNORE INDEX
----------------------

USE INDEX, FORCE INDEX and IGNORE INDEX constrain the query planning to a
specific index.

For further information about some of these options, see How to force query
plans.

URL: https://mariadb.com/kb/en/optimizer-hints/https://mariadb.com/kb/en/optimizer-hints/4�	(��������#GROUP BYUse the GROUP BY clause in a SELECT statement to group rows together that have
the same value in one or more column, or the same computed value using
expressions with any functions and operators except grouping functions. When
you use a GROUP BY clause, you will get a single result row for each group of
rows that have the same value for the expression given in GROUP BY.

When grouping rows, grouping values are compared as if by the = operator. For
string values, the = operator ignores trailing whitespace and may normalize
characters and ignore case, depending on the collation in use.

You can use any of the grouping functions in your select expression. Their
values will be calculated based on all the rows that have been grouped
together for each result row. If you select a non-grouped column or a value
computed from a non-grouped column, it is undefined which row the returned
value is taken from. This is not permitted if the ONLY_FULL_GROUP_BY SQL_MODE
is used.

You can use multiple expressions in the GROUP BY clause, separated by commas.
Rows are grouped together if they match on each of the expressions.

You can also use a single integer as the grouping expression. If you use an
integer n, the results will be grouped by the nth column in the select
expression.

The WHERE clause is applied before the GROUP BY clause. It filters
non-aggregated rows before the rows are grouped together. To filter grouped
rows based on aggregate values, use the HAVING clause. The HAVING clause takes
any expression and evaluates it as a boolean, just like the WHERE clause. You
can use grouping functions in the HAVING clause. As with the select
expression, if you reference non-grouped columns in the HAVING clause, the
behavior is undefined.

By default, if a GROUP BY clause is present, the rows in the output will be
sorted by the expressions used in the GROUP BY. You can also specify ASC or
DESC (ascending, descending) after those expressions, like in ORDER BY. The
default is ASC.

If you want the rows to be sorted by another field, you can add an explicit
ORDER BY. If you don't want the result to be ordered, you can add ORDER BY
NULL.

WITH ROLLUP
-----------

The WITH ROLLUP modifer adds extra rows to the resultset that represent
super-aggregate summaries. For a full description with examples, see SELECT
WITH ROLLUP.

GROUP BY Examples
-----------------

Consider the following table that records how many times each user has played
and won a game:

CREATE TABLE plays (name VARCHAR(16), plays INT, wins INT);
INSERT INTO plays VALUES 
 ("John", 20, 5),
 ("Robert", 22, 8),
 ("Wanda", 32, 8),
 ("Susan", 17, 3);

Get a list of win counts along with a count:

SELECT wins, COUNT(*) FROM plays GROUP BY wins;
+------+----------+
| wins | COUNT(*) |
+------+----------+
|    3 |        1 |
|    5 |        1 |
|    8 |        2 |
+------+----------+
3 rows in set (0.00 sec)

The GROUP BY expression can be a computed value, and can refer back to an
identifer specified with AS. Get a list of win averages along with a count:

SELECT (wins / plays) AS winavg, COUNT(*) FROM plays GROUP BY winavg;
+--------+----------+
| winavg | COUNT(*) |
+--------+----------+
| 0.1765 |        1 |
| 0.2500 |        2 |
| 0.3636 |        1 |
+--------+----------+
3 rows in set (0.00 sec)

You can use any grouping function in the select expression. For each win
average as above, get a list of the average play count taken to get that
average:

SELECT (wins / plays) AS winavg, AVG(plays) FROM plays 
 GROUP BY winavg;
+--------+------------+
| winavg | AVG(plays) |
+--------+------------+
| 0.1765 |    17.0000 |
| 0.2500 |    26.0000 |
| 0.3636 |    22.0000 |
+--------+------------+
3 rows in set (0.00 sec)

You can filter on aggregate information using the HAVING clause. The HAVING
clause is applied after GROUP BY and allows you to filter on aggregate data
that is not available to the WHERE clause. Restrict the above example to
results that involve an average number of plays over 20:

SELECT (wins / plays) AS winavg, AVG(plays) FROM plays 
 GROUP BY winavg HAVING AVG(plays) > 20;
+--------+------------+
| winavg | AVG(plays) |
+--------+------------+
| 0.2500 |    26.0000 |
| 0.3636 |    22.0000 |
+--------+------------+
2 rows in set (0.00 sec)

URL: https://mariadb.com/kb/en/group-by/https://mariadb.com/kb/en/group-by/��.SELECT ... OFFSET ... FETCHMariaDB starting with 10.6.0
----------------------------
SELECT ... OFFSET ... FETCH was introduced in MariaDB 10.6.

Syntax
------

OFFSET start { ROW | ROWS }
FETCH { FIRST | NEXT } [ count ] { ROW | ROWS } { ONLY | WITH TIES }

Description
-----------

The OFFSET clause allows one to return only those elements of a resultset that
come after a specified offset. The FETCH clause specifies the number of rows
to return, while ONLY or WITH TIES specifies whether or not to also return any
further results that tie for last place according to the ordered resultset.

Either the singular ROW or the plural ROWS can be used after the OFFSET and
FETCH clauses; the choice has no impact on the results.

In the case of WITH TIES, an ORDER BY clause is required, otherwise an ERROR
will be returned.

SELECT i FROM t1 FETCH FIRST 2 ROWS WITH TIES;
ERROR 4180 (HY000): FETCH ... WITH TIES requires ORDER BY clause to be present

Examples
--------

Given a table with 6 rows:

CREATE OR REPLACE TABLE t1 (i INT);
INSERT INTO t1 VALUES (1),(2),(3),(4), (4), (5);
SELECT i FROM t1 ORDER BY i ASC;
+------+
| i    |
+------+
|    1 |
|    2 |
|    3 |
|    4 |
|    4 |
|    5 |
+------+

OFFSET 2 allows one to skip the first two results.

SELECT i FROM t1 ORDER BY i ASC OFFSET 2 ROWS;
+------+
| i    |
+------+
|    3 |
|    4 |
|    4 |
|    5 |
+------+

FETCH FIRST 3 ROWS ONLY limits the results to three rows only

SELECT i FROM t1 ORDER BY i ASC OFFSET 1 ROWS FETCH FIRST 3 ROWS ONLY;
+------+
| i    |
+------+
|    2 |
|    3 |
|    4 |
+------+

The same outcome can also be achieved with the LIMIT clause:

SELECT i FROM t1 ORDER BY i ASC LIMIT 3 OFFSET 1;
+------+
| i    |
+------+
|    2 |
|    3 |
|    4 |
+------+

WITH TIES ensures the tied result 4 is also returned.

SELECT i FROM t1 ORDER BY i ASC OFFSET 1 ROWS FETCH FIRST 3 ROWS WITH TIES;
+------+
| i    |
+------+
|    2 |
|    3 |
|    4 |
|    4 |
+------+

URL: https://mariadb.com/kb/en/select-offset-fetch/https://mariadb.com/kb/en/select-offset-fetch/��]#�\
��WITHMariaDB starting with 10.2.1
----------------------------
Common Table Expressions were introduced in MariaDB 10.2.1.

Syntax
------

WITH [RECURSIVE] table_reference [(columns_list)] AS  (
 SELECT ...
)
[CYCLE cycle_column_list RESTRICT]
SELECT ...

Description
-----------

The WITH keyword signifies a Common Table Expression (CTE). It allows you to
refer to a subquery expression many times in a query, as if having a temporary
table that only exists for the duration of a query.

There are two kinds of CTEs:

* Non-Recursive
* Recursive (signified by the RECURSIVE keyword, supported since MariaDB
10.2.2)

You can use table_reference as any normal table in the external SELECT part.
You can also use WITH in subqueries, as well as with EXPLAIN and SELECT.

Poorly-formed recursive CTEs can in theory cause infinite loops. The
max_recursive_iterations system variable limits the number of recursions.

CYCLE ... RESTRICT
------------------

MariaDB starting with 10.5.2
----------------------------
The CYCLE clause enables CTE cycle detection, avoiding excessive or infinite
loops, MariaDB supports a relaxed, non-standard grammar.

The SQL Standard permits a CYCLE clause, as follows:

WITH RECURSIVE ... (
 ...
)
CYCLE <cycle column list>
SET <cycle mark column> TO <cycle mark value> DEFAULT <non-cycle mark value>
USING <path column>

where all clauses are mandatory.

MariaDB does not support this, but from 10.5.2 permits a non-standard relaxed
grammar, as follows:

WITH RECURSIVE ... (
 ...
)
CYCLE <cycle column list> RESTRICT

With the use of CYCLE ... RESTRICT it makes no difference whether the CTE uses
UNION ALL or UNION DISTINCT anymore. UNION ALL means "all rows, but without
cycles", which is exactly what the CYCLE clause enables. And UNION DISTINCT
means all rows should be different, which, again, is what will happen — as
uniqueness is enforced over a subset of columns, complete rows will
automatically all be different.

Examples
--------

Below is an example with the WITH at the top level:

WITH t AS (SELECT a FROM t1 WHERE b >= 'c') 
 SELECT * FROM t2, t WHERE t2.c = t.a;

The example below uses WITH in a subquery:

SELECT t1.a, t1.b FROM t1, t2
 WHERE t1.a > t2.c
  AND t2.c IN(WITH t AS (SELECT * FROM t1 WHERE t1.a < 5)
        SELECT t2.c FROM t2, t WHERE t2.c = t.a);

Below is an example of a Recursive CTE:

WITH RECURSIVE ancestors AS 
 ( SELECT * FROM folks
 WHERE name="Alex"
 UNION
 SELECT f.*
 FROM folks AS f, ancestors AS a
 WHERE f.id = a.father OR f.id = a.mother )
SELECT * FROM ancestors;

Take the following structure, and data,

CREATE TABLE t1 (from_ int, to_ int);
INSERT INTO t1 VALUES (1,2), (1,100), (2,3), (3,4), (4,1);
SELECT * FROM t1;
+-------+------+
| from_ | to_  |
+-------+------+
|     1 |    2 |
|     1 |  100 |
|     2 |    3 |
|     3 |    4 |
|     4 |    1 |
+-------+------+

Given the above, the following query would theoretically result in an infinite
loop due to the last record in t1 (note that max_recursive_iterations is set
to 10 for the purposes of this example, to avoid the excessive number of
cycles):

SET max_recursive_iterations=10;

WITH RECURSIVE cte (depth, from_, to_) AS ( 
 SELECT 0,1,1 UNION DISTINCT SELECT depth+1, t1.from_, t1.to_
  FROM t1, cte  WHERE t1.from_ = cte.to_
) 
SELECT * FROM cte;
+-------+-------+------+
| depth | from_ | to_  |
+-------+-------+------+
|     0 |     1 |    1 |
|     1 |     1 |    2 |
|     1 |     1 |  100 |
|     2 |     2 |    3 |
|     3 |     3 |    4 |
|     4 |     4 |    1 |
|     5 |     1 |    2 |
|     5 |     1 |  100 |
|     6 |     2 |    3 |
|     7 |     3 |    4 |
|     8 |     4 |    1 |
|     9 |     1 |    2 |
|     9 |     1 |  100 |
|    10 |     2 |    3 |
+-------+-------+------+

However, the CYCLE ... RESTRICT clause (from MariaDB 10.5.2) can overcome this:

WITH RECURSIVE cte (depth, from_, to_) AS ( 
 SELECT 0,1,1 UNION SELECT depth+1, t1.from_, t1.to_
  FROM t1, cte WHERE t1.from_ = cte.to_
) 
CYCLE from_, to_ RESTRICT 
SELECT * FROM cte;
+-------+-------+------+
| depth | from_ | to_  |
+-------+-------+------+
|     0 |     1 |    1 |
|     1 |     1 |    2 |
|     1 |     1 |  100 |
|     2 |     2 |    3 |
|     3 |     3 |    4 |
|     4 |     4 |    1 |
+-------+-------+------+

URL: https://mariadb.com/kb/en/with/https://mariadb.com/kb/en/with/�
G(INSERT SELECTSyntax
------

INSERT [LOW_PRIORITY | HIGH_PRIORITY] [IGNORE]
  [INTO] tbl_name [(col_name,...)]
  SELECT ...
  [ ON DUPLICATE KEY UPDATE col_name=expr, ... ]

Description
-----------

With INSERT ... SELECT, you can quickly insert many rows into a table from one
or more other tables. For example:

INSERT INTO tbl_temp2 (fld_id)
 SELECT tbl_temp1.fld_order_id
 FROM tbl_temp1 WHERE tbl_temp1.fld_order_id > 100;

tbl_name can also be specified in the form db_name.tbl_name (see Identifier
Qualifiers). This allows to copy rows between different databases.

If the new table has a primary key or UNIQUE indexes, you can use IGNORE to
handle duplicate key errors during the query. The newer values will not be
inserted if an identical value already exists.

REPLACE can be used instead of INSERT to prevent duplicates on UNIQUE indexes
by deleting old values. In that case, ON DUPLICATE KEY UPDATE cannot be used.

INSERT ... SELECT works for tables which already exist. To create a table for
a given resultset, you can use CREATE TABLE ... SELECT.

URL: https://mariadb.com/kb/en/insert-select/https://mariadb.com/kb/en/insert-select/�ي����+FRecursive Common Table Expressions OverviewCommon Table Expressions (CTEs) are a standard SQL feature, and are
essentially temporary named result sets. CTEs first appeared in the SQL
standard in 1999, and the first implementations began appearing in 2007.

There are two kinds of CTEs:

* Non-recursive
* Recursive, which this article covers.

SQL is generally poor at recursive structures.

CTEs permit a query to reference itself. A recursive CTE will repeatedly
execute subsets of the data until it obtains the complete result set. This
makes it particularly useful for handing hierarchical or tree-structured data.
max_recursive_iterations avoids infinite loops.

Syntax example
--------------

WITH RECURSIVE signifies a recursive CTE. It is given a name, followed by a
body (the main query) as follows:

Computation
-----------

Given the following structure:

First execute the anchor part of the query:

Next, execute the recursive part of the query:

Summary so far
--------------

with recursive R as (
 select anchor_data
 union [all]
 select recursive_part
 from R, ...
)
select ...

* Compute anchor_data
* Compute recursive_part to get the new data
* if (new data is non-empty) goto 2;

CAST to avoid truncating data
-----------------------------

As currently implemented by MariaDB and by the SQL Standard, data may be
truncated if not correctly cast. It is necessary to CAST the column to the
correct width if the CTE's recursive part produces wider values for a column
than the CTE's nonrecursive part. Some other DBMS give an error in this
situation, and MariaDB's behavior may change in future - see MDEV-12325. See
the examples below.

Examples
--------

Transitive closure - determining bus destinations
-------------------------------------------------

Sample data:

CREATE TABLE bus_routes (origin varchar(50), dst varchar(50));
INSERT INTO bus_routes VALUES 
 ('New York', 'Boston'),
 ('Boston', 'New York'),
 ('New York', 'Washington'),
 ('Washington', 'Boston'),
 ('Washington', 'Raleigh');

Now, we want to return the bus destinations with New York as the origin:

WITH RECURSIVE bus_dst as ( 
  SELECT origin as dst FROM bus_routes WHERE origin='New York'
 UNION
  SELECT bus_routes.dst FROM bus_routes JOIN bus_dst ON bus_dst.dst=
bus_routes.origin 
) 
SELECT * FROM bus_dst;
+------------+
| dst        |
+------------+
| New York   |
| Boston     |
| Washington |
| Raleigh    |
+------------+

The above example is computed as follows:

First, the anchor data is calculated:

* Starting from New York
* Boston and Washington are added

Next, the recursive part:

* Starting from Boston and then Washington
* Raleigh is added
* UNION excludes nodes that are already present.

Computing paths - determining bus routes
----------------------------------------

This time, we are trying to get bus routes such as "New York -> Washington ->
Raleigh".

Using the same sample data as the previous example:

WITH RECURSIVE paths (cur_path, cur_dest) AS (
  SELECT origin, origin FROM bus_routes WHERE origin='New York'
 UNION
  SELECT CONCAT(paths.cur_path, ',', bus_routes.dst), bus_routes.dst
  FROM paths
  JOIN bus_routes
   ON paths.cur_dest = bus_routes.origin AND
    NOT FIND_IN_SET(bus_routes.dst, paths.cur_path)
) 
SELECT * FROM paths;
+-----------------------------+------------+
| cur_path                    | cur_dest   |
+-----------------------------+------------+
| New York                    | New York   |
| New York,Boston             | Boston     |
| New York,Washington         | Washington |
| New York,Washington,Boston  | Boston     |
| New York,Washington,Raleigh | Raleigh    |
+-----------------------------+------------+

CAST to avoid data truncation
-----------------------------

In the following example, data is truncated because the results are not
specifically cast to a wide enough type:

WITH RECURSIVE tbl AS (
 SELECT NULL AS col
 UNION
 SELECT "THIS NEVER SHOWS UP" AS col FROM tbl
)
SELECT col FROM tbl
+------+
| col  |
+------+
| NULL |
|      |
+------+

Explicitly use CAST to overcome this:

WITH RECURSIVE tbl AS (
 SELECT CAST(NULL AS CHAR(50)) AS col
 UNION SELECT "THIS NEVER SHOWS UP" AS col FROM tbl
)  
SELECT * FROM tbl;
+---------------------+
| col                 |
+---------------------+
| NULL                |
| THIS NEVER SHOWS UP |
+---------------------+

URL: https://mariadb.com/kb/en/recursive-common-table-expressions-overview/https://mariadb.com/kb/en/recursive-common-table-expressions-overview/�)
#LOAD XMLSyntax
------

LOAD XML [LOW_PRIORITY | CONCURRENT] [LOCAL] INFILE 'file_name'
  [REPLACE | IGNORE]
  INTO TABLE [db_name.]tbl_name
  [CHARACTER SET charset_name]
  [ROWS IDENTIFIED BY '<tagname>']
  [IGNORE number {LINES | ROWS}]
  [(column_or_user_var,...)]
  [SET col_name = expr,...]

Description
-----------

The LOAD XML statement reads data from an XML file into a table. The file_name
must be given as a literal string. The tagname in the optional ROWS IDENTIFIED
BY clause must also be given as a literal string, and must be surrounded by
angle brackets (< and >).

LOAD XML acts as the complement of running the mariadb client in XML output
mode (that is, starting the client with the --xml option). To write data from
a table to an XML file, use a command such as the following one from the
system shell:

shell> mariadb --xml -e 'SELECT * FROM mytable' > file.xml

To read the file back into a table, use LOAD XML INFILE. By default, the <row>
element is considered to be the equivalent of a database table row; this can
be changed using the ROWS IDENTIFIED BY clause.

This statement supports three different XML formats:

* Column names as attributes and column values as attribute values:

<row column1="value1" column2="value2" .../>

* Column names as tags and column values as the content of these tags:

<row>
 <column1>value1</column1>
 <column2>value2</column2>
</row>

* Column names are the name attributes of <field> tags, and values are
 the contents of these tags:

<row>
 <field name='column1'>value1</field>
 <field name='column2'>value2</field>
</row>

This is the format used by other tools, such as mariadb-dump.

All 3 formats can be used in the same XML file; the import routine
automatically detects the format for each row and interprets it correctly.
Tags are matched based on the tag or attribute name and the column name.

The following clauses work essentially the same way for LOAD XML as they do
for LOAD DATA:

* LOW_PRIORITY or CONCURRENT
* LOCAL
* REPLACE or IGNORE
* CHARACTER SET
* (column_or_user_var,...)
* SET

See LOAD DATA for more information about these clauses.

The IGNORE number LINES or IGNORE number ROWS clause causes the first number
rows in the XML file to be skipped. It is analogous to the LOAD DATA
statement's IGNORE ... LINES clause.

If the LOW_PRIORITY keyword is used, insertions are delayed until no other
clients are reading from the table. The CONCURRENT keyword allows the use of
concurrent inserts. These clauses cannot be specified together.

This statement activates INSERT triggers.

URL: https://mariadb.com/kb/en/load-xml/https://mariadb.com/kb/en/load-xml/�b
�,�c�����-SELECT WITH ROLLUPSyntax
------

See SELECT for the full syntax.

Description
-----------

The WITH ROLLUP modifier adds extra rows to the resultset that represent
super-aggregate summaries. The super-aggregated column is represented by a
NULL value. Multiple aggregates over different columns will be added if there
are multiple GROUP BY columns.

The LIMIT clause can be used at the same time, and is applied after the WITH
ROLLUP rows have been added.

WITH ROLLUP cannot be used with ORDER BY. Some sorting is still possible by
using ASC or DESC clauses with the GROUP BY column, although the
super-aggregate rows will always be added last.

Examples
--------

These examples use the following sample table

CREATE TABLE booksales ( 
 country VARCHAR(35), genre ENUM('fiction','non-fiction'), year YEAR, sales
INT);

INSERT INTO booksales VALUES
 ('Senegal','fiction',2014,12234), ('Senegal','fiction',2015,15647),
 ('Senegal','non-fiction',2014,64980), ('Senegal','non-fiction',2015,78901),
 ('Paraguay','fiction',2014,87970), ('Paraguay','fiction',2015,76940),
 ('Paraguay','non-fiction',2014,8760), ('Paraguay','non-fiction',2015,9030);

The addition of the WITH ROLLUP modifier in this example adds an extra row
that aggregates both years:

SELECT year, SUM(sales) FROM booksales GROUP BY year;
+------+------------+
| year | SUM(sales) |
+------+------------+
| 2014 |     173944 |
| 2015 |     180518 |
+------+------------+
2 rows in set (0.08 sec)

SELECT year, SUM(sales) FROM booksales GROUP BY year WITH ROLLUP;
+------+------------+
| year | SUM(sales) |
+------+------------+
| 2014 |     173944 |
| 2015 |     180518 |
| NULL |     354462 |
+------+------------+

In the following example, each time the genre, the year or the country change,
another super-aggregate row is added:

SELECT country, year, genre, SUM(sales) 
 FROM booksales GROUP BY country, year, genre;
+----------+------+-------------+------------+
| country  | year | genre       | SUM(sales) |
+----------+------+-------------+------------+
| Paraguay | 2014 | fiction     |      87970 |
| Paraguay | 2014 | non-fiction |       8760 |
| Paraguay | 2015 | fiction     |      76940 |
| Paraguay | 2015 | non-fiction |       9030 |
| Senegal  | 2014 | fiction     |      12234 |
| Senegal  | 2014 | non-fiction |      64980 |
| Senegal  | 2015 | fiction     |      15647 |
| Senegal  | 2015 | non-fiction |      78901 |
+----------+------+-------------+------------+

SELECT country, year, genre, SUM(sales) 
 FROM booksales GROUP BY country, year, genre WITH ROLLUP;
+----------+------+-------------+------------+
| country  | year | genre       | SUM(sales) |
+----------+------+-------------+------------+
| Paraguay | 2014 | fiction     |      87970 |
| Paraguay | 2014 | non-fiction |       8760 |
| Paraguay | 2014 | NULL        |      96730 |
| Paraguay | 2015 | fiction     |      76940 |
| Paraguay | 2015 | non-fiction |       9030 |
| Paraguay | 2015 | NULL        |      85970 |
| Paraguay | NULL | NULL        |     182700 |
| Senegal  | 2014 | fiction     |      12234 |
| Senegal  | 2014 | non-fiction |      64980 |
| Senegal  | 2014 | NULL        |      77214 |
| Senegal  | 2015 | fiction     |      15647 |
| Senegal  | 2015 | non-fiction |      78901 |
| Senegal  | 2015 | NULL        |      94548 |
| Senegal  | NULL | NULL        |     171762 |
| NULL     | NULL | NULL        |     354462 |
+----------+------+-------------+------------+

The LIMIT clause, applied after WITH ROLLUP:

SELECT country, year, genre, SUM(sales) 
 FROM booksales GROUP BY country, year, genre WITH ROLLUP LIMIT 4;
+----------+------+-------------+------------+
| country  | year | genre       | SUM(sales) |
+----------+------+-------------+------------+
| Paraguay | 2014 | fiction     |      87970 |
| Paraguay | 2014 | non-fiction |       8760 |
| Paraguay | 2014 | NULL        |      96730 |
| Paraguay | 2015 | fiction     |      76940 |
+----------+------+-------------+------------+

Sorting by year descending:

SELECT country, year, genre, SUM(sales) 
 FROM booksales GROUP BY country, year DESC, genre WITH ROLLUP;
+----------+------+-------------+------------+
| country  | year | genre       | SUM(sales) |
+----------+------+-------------+------------+
| Paraguay | 2015 | fiction     |      76940 |
| Paraguay | 2015 | non-fiction |       9030 |
| Paraguay | 2015 | NULL        |      85970 |
| Paraguay | 2014 | fiction     |      87970 |
| Paraguay | 2014 | non-fiction |       8760 |
| Paraguay | 2014 | NULL        |      96730 |
| Paraguay | NULL | NULL        |     182700 |
| Senegal  | 2015 | fiction     |      15647 |
| Senegal  | 2015 | non-fiction |      78901 |
| Senegal  | 2015 | NULL        |      94548 |
| Senegal  | 2014 | fiction     |      12234 |
| Senegal  | 2014 | non-fiction |      64980 |
| Senegal  | 2014 | NULL        |      77214 |
| Senegal  | NULL | NULL        |     171762 |
| NULL     | NULL | NULL        |     354462 |
+----------+------+-------------+------------+

URL: https://mariadb.com/kb/en/select-with-rollup/https://mariadb.com/kb/en/select-with-rollup/���|����!INSERTSyntax
------

INSERT [LOW_PRIORITY | DELAYED | HIGH_PRIORITY] [IGNORE]
 [INTO] tbl_name [PARTITION (partition_list)] [(col,...)]
 {VALUES | VALUE} ({expr | DEFAULT},...),(...),...
 [ ON DUPLICATE KEY UPDATE
 col=expr
  [, col=expr] ... ] [RETURNING select_expr
   [, select_expr ...]]

Or:

INSERT [LOW_PRIORITY | DELAYED | HIGH_PRIORITY] [IGNORE]
  [INTO] tbl_name [PARTITION (partition_list)]
  SET col={expr | DEFAULT}, ...
  [ ON DUPLICATE KEY UPDATE
   col=expr
    [, col=expr] ... ] [RETURNING select_expr
   [, select_expr ...]]

Or:

INSERT [LOW_PRIORITY | HIGH_PRIORITY] [IGNORE]
  [INTO] tbl_name [PARTITION (partition_list)] [(col,...)]
  SELECT ...
  [ ON DUPLICATE KEY UPDATE
   col=expr
    [, col=expr] ... ] [RETURNING select_expr
   [, select_expr ...]]

The INSERT statement is used to insert new rows into an existing table. The
INSERT ... VALUES and INSERT ... SET forms of the statement insert rows based
on explicitly specified values. The INSERT ... SELECT form inserts rows
selected from another table or tables. INSERT ... SELECT is discussed further
in the INSERT ... SELECT article.

The table name can be specified in the form db_name.tbl_name or, if a default
database is selected, in the form tbl_name (see Identifier Qualifiers). This
allows to use INSERT ... SELECT to copy rows between different databases.

The PARTITION clause can be used in both the INSERT and the SELECT part. See
Partition Pruning and Selection for details.

MariaDB starting with 10.5
--------------------------
The RETURNING clause was introduced in MariaDB 10.5.

The columns list is optional. It specifies which values are explicitly
inserted, and in which order. If this clause is not specified, all values must
be explicitly specified, in the same order they are listed in the table
definition.

The list of value follow the VALUES or VALUE keyword (which are
interchangeable, regardless how much values you want to insert), and is
wrapped by parenthesis. The values must be listed in the same order as the
columns list. It is possible to specify more than one list to insert more than
one rows with a single statement. If many rows are inserted, this is a speed
optimization.

For one-row statements, the SET clause may be more simple, because you don't
need to remember the columns order. All values are specified in the form col =
expr.

Values can also be specified in the form of a SQL expression or subquery.
However, the subquery cannot access the same table that is named in the INTO
clause.

If you use the LOW_PRIORITY keyword, execution of the INSERT is delayed until
no other clients are reading from the table. If you use the HIGH_PRIORITY
keyword, the statement has the same priority as SELECTs. This affects only
storage engines that use only table-level locking (MyISAM, MEMORY, MERGE).
However, if one of these keywords is specified, concurrent inserts cannot be
used. See HIGH_PRIORITY and LOW_PRIORITY clauses for details.

INSERT DELAYED
--------------

For more details on the DELAYED option, see INSERT DELAYED.

HIGH PRIORITY and LOW PRIORITY
------------------------------

See HIGH_PRIORITY and LOW_PRIORITY.

Defaults and Duplicate Values
-----------------------------

See INSERT - Default & Duplicate Values for details..

INSERT IGNORE
-------------

See INSERT IGNORE.

INSERT ON DUPLICATE KEY UPDATE
------------------------------

See INSERT ON DUPLICATE KEY UPDATE.

Examples
--------

Specifying the column names:

INSERT INTO person (first_name, last_name) VALUES ('John', 'Doe');

Inserting more than 1 row at a time:

INSERT INTO tbl_name VALUES (1, "row 1"), (2, "row 2");

Using the SET clause:

INSERT INTO person SET first_name = 'John', last_name = 'Doe';

SELECTing from another table:

INSERT INTO contractor SELECT * FROM person WHERE status = 'c';

See INSERT ON DUPLICATE KEY UPDATE and INSERT IGNORE for further examples.

INSERT ... RETURNING
--------------------

INSERT ... RETURNING returns a resultset of the inserted rows.

This returns the listed columns for all the rows that are inserted, or
alternatively, the specified SELECT expression. Any SQL expressions which can
be calculated can be used in the select expression for the RETURNING clause,
including virtual columns and aliases, expressions which use various operators
such as bitwise, logical and arithmetic operators, string functions, date-time
functions, numeric functions, control flow functions, secondary functions and
stored functions. Along with this, statements which have subqueries and
prepared statements can also be used.

Examples
--------

Simple INSERT statement

INSERT INTO t2 VALUES (1,'Dog'),(2,'Lion'),(3,'Tiger'),(4,'Leopard') 
RETURNING id2,id2+id2,id2&id2,id2||id2;
+-----+---------+---------+----------+
| id2 | id2+id2 | id2&id2 | id2||id2 |
+-----+---------+---------+----------+
|   1 |       2 |       1 |        1 |
|   2 |       4 |       2 |        1 |
|   3 |       6 |       3 |        1 |
|   4 |       8 |       4 |        1 |
+-----+---------+---------+----------+

Using stored functions in RETURNING

DELIMITER |
CREATE FUNCTION f(arg INT) RETURNS INT
  BEGIN
   RETURN (SELECT arg+arg);
  END|

DELIMITER ;

PREPARE stmt FROM "INSERT INTO t1 SET id1=1, animal1='Bear' RETURNING f(id1),
UPPER(animal1)";

EXECUTE stmt;
+---------+----------------+
| f(id1)  | UPPER(animal1) |
+---------+----------------+
|       2 | BEAR           |
+---------+----------------+

Subqueries in the RETURNING clause that return more than one row or column
cannot be used.

Aggregate functions cannot be used in the RETURNING clause. Since aggregate
functions work on a set of values, and if the purpose is to get the row count,
ROW_COUNT() with SELECT can be used or it can be used in
INSERT...SELECT...RETURNING if the table in the RETURNING clause is not the
same as the INSERT table.

URL: https://mariadb.com/kb/en/insert/https://mariadb.com/kb/en/insert/*Ad��R	��)INSERT DELAYEDSyntax
------

INSERT DELAYED ...

Description
-----------

The DELAYED option for the INSERT statement is a MariaDB/MySQL extension to
standard SQL that is very useful if you have clients that cannot or need not
wait for the INSERT to complete. This is a common situation when you use
MariaDB for logging and you also periodically run SELECT and UPDATE statements
that take a long time to complete.

When a client uses INSERT DELAYED, it gets an okay from the server at once,
and the row is queued to be inserted when the table is not in use by any other
thread.

Another major benefit of using INSERT DELAYED is that inserts from many
clients are bundled together and written in one block. This is much faster
than performing many separate inserts.

Note that INSERT DELAYED is slower than a normal INSERT if the table is not
otherwise in use. There is also the additional overhead for the server to
handle a separate thread for each table for which there are delayed rows. This
means that you should use INSERT DELAYED only when you are really sure that
you need it.

The queued rows are held only in memory until they are inserted into the
table. This means that if you terminate mysqld forcibly (for example, with
kill -9) or if mysqld dies unexpectedly, any queued rows that have not been
written to disk are lost.

The number of concurrent INSERT DELAYED threads is limited by the
max_delayed_threads server system variables. If it is set to 0, INSERT DELAYED
is disabled. The session value can be equal to the global value, or 0 to
disable this statement for the current session. If this limit has been
reached, the DELAYED clause will be silently ignore for subsequent statements
(no error will be produced).

Limitations
-----------

There are some limitations on the use of DELAYED:

* INSERT DELAYED works only with MyISAM, MEMORY, ARCHIVE,
 and BLACKHOLE tables. If you execute INSERT DELAYED with another storage
engine, you will get an error like this: ERROR 1616 (HY000): DELAYED option
not supported for table 'tab_name'
* For MyISAM tables, if there are no free blocks in the middle of the data
 file, concurrent SELECT and INSERT statements are supported. Under these
 circumstances, you very seldom need to use INSERT DELAYED
 with MyISAM.
* INSERT DELAYED should be used only for
 INSERT statements that specify value lists. The server
 ignores DELAYED for INSERT ... SELECT
 or INSERT ... ON DUPLICATE KEY UPDATE statements.
* Because the INSERT DELAYED statement returns immediately,
 before the rows are inserted, you cannot use
 LAST_INSERT_ID() to get the
 AUTO_INCREMENT value that the statement might generate.
* DELAYED rows are not visible to SELECT
 statements until they actually have been inserted.
* After INSERT DELAYED, ROW_COUNT() returns the number of the rows you tried
to insert, not the number of the successful writes.
* DELAYED is ignored on slave replication servers, so that 
 INSERT DELAYED is treated as a normal
 INSERT on slaves. This is because
 DELAYED could cause the slave to have different data than
 the master. INSERT DELAYED statements are not safe for replication.
* Pending INSERT DELAYED statements are lost if a table is
 write locked and ALTER TABLE is used to modify the table structure.
* INSERT DELAYED is not supported for views. If you try, you will get an error
like this: ERROR 1347 (HY000): 'view_name' is not BASE TABLE
* INSERT DELAYED is not supported for partitioned tables.
* INSERT DELAYED is not supported within stored programs.
* INSERT DELAYED does not work with triggers.
* INSERT DELAYED does not work if there is a check constraint in place.
* INSERT DELAYED does not work if skip-new mode is active.

URL: https://mariadb.com/kb/en/insert-delayed/https://mariadb.com/kb/en/insert-delayed/�q-Concurrent InsertsThe MyISAM storage engine supports concurrent inserts. This feature allows
SELECT statements to be executed during INSERT operations, reducing contention.

Whether concurrent inserts can be used or not depends on the value of the
concurrent_insert server system variable:

* NEVER (0) disables concurrent inserts.
* AUTO (1) allows concurrent inserts only when the target table has no free
blocks (no data in the middle of the table has been deleted after the last
OPTIMIZE TABLE). This is the default.
* ALWAYS (2) always enables concurrent inserts, in which case new rows are
added at the end of a table if the table is being used by another thread.

If the binary log is used, CREATE TABLE ... SELECT and INSERT ... SELECT
statements cannot use concurrent inserts. These statements acquire a read lock
on the table, so concurrent inserts will need to wait. This way the log can be
safely used to restore data.

Concurrent inserts are not used by replicas with the row based replication
(see binary log formats).

If an INSERT statement contain the HIGH_PRIORITY clause, concurrent inserts
cannot be used. INSERT ... DELAYED is usually unneeded if concurrent inserts
are enabled.

LOAD DATA INFILE uses concurrent inserts if the CONCURRENT keyword is
specified and concurrent_insert is not NEVER. This makes the statement slower
(even if no other sessions access the table) but reduces contention.

LOCK TABLES allows non-conflicting concurrent inserts if a READ LOCAL lock is
used. Concurrent inserts are not allowed if the LOCAL keyword is omitted.

Notes
-----

The decision to enable concurrent insert for a table is done when the table is
opened. If you change the value of concurrent_insert it will only affect new
opened tables. If you want it to work for also for tables in use or cached,
you should do FLUSH TABLES after setting the variable.

URL: https://mariadb.com/kb/en/concurrent-inserts/https://mariadb.com/kb/en/concurrent-inserts/����X����	�+9HIGH_PRIORITY and LOW_PRIORITYThe InnoDB storage engine uses row-level locking to ensure data integrity.
However some storage engines (such as MEMORY, MyISAM, Aria and MERGE) lock the
whole table to prevent conflicts. These storage engines use two separate
queues to remember pending statements; one is for SELECTs and the other one is
for write statements (INSERT, DELETE, UPDATE). By default, the latter has a
higher priority.

To give write operations a lower priority, the low_priority_updates server
system variable can be set to ON. The option is available on both the global
and session levels, and it can be set at startup or via the SET statement.

When too many table locks have been set by write statements, some pending
SELECTs are executed. The maximum number of write locks that can be acquired
before this happens is determined by the max_write_lock_count server system
variable, which is dynamic.

If write statements have a higher priority (default), the priority of
individual write statements (INSERT, REPLACE, UPDATE, DELETE) can be changed
via the LOW_PRIORITY attribute, and the priority of a SELECT statement can be
raised via the HIGH_PRIORITY attribute. Also, LOCK TABLES supports a
LOW_PRIORITY attribute for WRITE locks.

If read statements have a higher priority, the priority of an INSERT can be
changed via the HIGH_PRIORITY attribute. However, the priority of other write
statements cannot be raised individually.

The use of LOW_PRIORITY or HIGH_PRIORITY for an INSERT prevents Concurrent
Inserts from being used.

URL: https://mariadb.com/kb/en/high_priority-and-low_priority/https://mariadb.com/kb/en/high_priority-and-low_priority/�#M:INSERT - Default & Duplicate ValuesDefault Values
--------------

If the SQL_MODE contains STRICT_TRANS_TABLES and you are inserting into a
transactional table (like InnoDB), or if the SQL_MODE contains
STRICT_ALL_TABLES, all NOT NULL columns which do not have a DEFAULT value (and
are not AUTO_INCREMENT) must be explicitly referenced in INSERT statements. If
not, an error like this is produced:

ERROR 1364 (HY000): Field 'col' doesn't have a default value

In all other cases, if a NOT NULL column without a DEFAULT value is not
referenced, an empty value will be inserted (for example, 0 for INTEGER
columns and '' for CHAR columns). See NULL Values in MariaDB:Inserting for
examples.

If a NOT NULL column having a DEFAULT value is not referenced, NULL will be
inserted.

If a NULL column having a DEFAULT value is not referenced, its default value
will be inserted. It is also possible to explicitly assign the default value
using the DEFAULT keyword or the DEFAULT() function.

If the DEFAULT keyword is used but the column does not have a DEFAULT value,
an error like this is produced:

ERROR 1364 (HY000): Field 'col' doesn't have a default value

Duplicate Values
----------------

By default, if you try to insert a duplicate row and there is a UNIQUE index,
INSERT stops and an error like this is produced:

ERROR 1062 (23000): Duplicate entry 'dup_value' for key 'col'

To handle duplicates you can use the IGNORE clause, INSERT ON DUPLICATE KEY
UPDATE or the REPLACE statement. Note that the IGNORE and DELAYED options are
ignored when you use ON DUPLICATE KEY UPDATE.

URL: https://mariadb.com/kb/en/insert-default-duplicate-values/https://mariadb.com/kb/en/insert-default-duplicate-values/�
�(INSERT IGNOREIgnoring Errors
---------------

Normally INSERT stops and rolls back when it encounters an error.

By using the IGNORE keyword all errors are converted to warnings, which will
not stop inserts of additional rows.

Invalid values are changed to the closest valid value and inserted, with a
warning produced.

The IGNORE and DELAYED options are ignored when you use ON DUPLICATE KEY
UPDATE.

Prior to MySQL and MariaDB 5.5.28, no warnings were issued for duplicate key
errors when using IGNORE. You can get the old behavior if you set OLD_MODE to
NO_DUP_KEY_WARNINGS_WITH_IGNORE.

See IGNORE for a full description of effects.

Examples
--------

CREATE TABLE t1 (x INT UNIQUE);

INSERT INTO t1 VALUES(1),(2);

INSERT INTO t1 VALUES(2),(3);
ERROR 1062 (23000): Duplicate entry '2' for key 'x'
SELECT * FROM t1;
+------+
| x    |
+------+
|    1 |
|    2 |
+------+

INSERT IGNORE INTO t1 VALUES(2),(3);
Query OK, 1 row affected, 1 warning (0.04 sec)

SHOW WARNINGS;
+---------+------+---------------------------------+
| Level   | Code | Message                         |
+---------+------+---------------------------------+
| Warning | 1062 | Duplicate entry '2' for key 'x' |
+---------+------+---------------------------------+

SELECT * FROM t1;
+------+
| x    |
+------+
|    1 |
|    2 |
|    3 |
+------+

Converting values:

CREATE OR REPLACE TABLE t2(id INT, t VARCHAR(2) NOT NULL, n INT NOT NULL);

INSERT INTO t2(id) VALUES (1),(2);
ERROR 1364 (HY000): Field 't' doesn't have a default value

INSERT IGNORE INTO t2(id) VALUES (1),(2);
Query OK, 2 rows affected, 2 warnings (0.026 sec)
Records: 2  Duplicates: 0  Warnings: 2

SHOW WARNINGS;
+---------+------+----------------------------------------+
| Level   | Code | Message                                |
+---------+------+----------------------------------------+
| Warning | 1364 | Field 't' doesn't have a default value |
| Warning | 1364 | Field 'n' doesn't have a default value |
+---------+------+----------------------------------------+

SELECT * FROM t2;
+------+---+---+
| id   | t | n |
+------+---+---+
|    1 |   | 0 |
|    2 |   | 0 |
+------+---+---+

See INSERT ON DUPLICATE KEY UPDATE for further examples using that syntax.

URL: https://mariadb.com/kb/en/insert-ignore/https://mariadb.com/kb/en/insert-ignore/T
	����B����
��9INSERT ON DUPLICATE KEY UPDATESyntax
------

INSERT [LOW_PRIORITY | DELAYED | HIGH_PRIORITY] [IGNORE]
 [INTO] tbl_name [PARTITION (partition_list)] [(col,...)]
 {VALUES | VALUE} ({expr | DEFAULT},...),(...),...
 [ ON DUPLICATE KEY UPDATE
  col=expr
   [, col=expr] ... ]

Or:

INSERT [LOW_PRIORITY | DELAYED | HIGH_PRIORITY] [IGNORE]
  [INTO] tbl_name [PARTITION (partition_list)]
  SET col={expr | DEFAULT}, ...
  [ ON DUPLICATE KEY UPDATE
   col=expr
    [, col=expr] ... ]

Or:

INSERT [LOW_PRIORITY | HIGH_PRIORITY] [IGNORE]
  [INTO] tbl_name [PARTITION (partition_list)] [(col,...)]
  SELECT ...
  [ ON DUPLICATE KEY UPDATE
   col=expr
    [, col=expr] ... ]

Description
-----------

INSERT ... ON DUPLICATE KEY UPDATE is a MariaDB/MySQL extension to the INSERT
statement that, if it finds a duplicate unique or primary key, will instead
perform an UPDATE.

The row/s affected value is reported as 1 if a row is inserted, and 2 if a row
is updated, unless the API's CLIENT_FOUND_ROWS flag is set.

If more than one unique index is matched, only the first is updated. It is not
recommended to use this statement on tables with more than one unique index.

If the table has an AUTO_INCREMENT primary key and the statement inserts or
updates a row, the LAST_INSERT_ID() function returns its AUTO_INCREMENT value.

The VALUES() function can only be used in a ON DUPLICATE KEY UPDATE clause and
has no meaning in any other context. It returns the column values from the
INSERT portion of the statement. This function is particularly useful for
multi-rows inserts.

The IGNORE and DELAYED options are ignored when you use ON DUPLICATE KEY
UPDATE.

See Partition Pruning and Selection for details on the PARTITION clause.

This statement activates INSERT and UPDATE triggers. See Trigger Overview for
details.

See also a similar statement, REPLACE.

Examples
--------

CREATE TABLE ins_duplicate (id INT PRIMARY KEY, animal VARCHAR(30));
INSERT INTO ins_duplicate VALUES (1,'Aardvark'), (2,'Cheetah'), (3,'Zebra');

If there is no existing key, the statement runs as a regular INSERT:

INSERT INTO ins_duplicate VALUES (4,'Gorilla') 
 ON DUPLICATE KEY UPDATE animal='Gorilla';
Query OK, 1 row affected (0.07 sec)

SELECT * FROM ins_duplicate;
+----+----------+
| id | animal   |
+----+----------+
|  1 | Aardvark |
|  2 | Cheetah  |
|  3 | Zebra    |
|  4 | Gorilla  |
+----+----------+

A regular INSERT with a primary key value of 1 will fail, due to the existing
key:

INSERT INTO ins_duplicate VALUES (1,'Antelope');
ERROR 1062 (23000): Duplicate entry '1' for key 'PRIMARY'

However, we can use an INSERT ON DUPLICATE KEY UPDATE instead:

INSERT INTO ins_duplicate VALUES (1,'Antelope') 
 ON DUPLICATE KEY UPDATE animal='Antelope';
Query OK, 2 rows affected (0.09 sec)

Note that there are two rows reported as affected, but this refers only to the
UPDATE.

SELECT * FROM ins_duplicate;
+----+----------+
| id | animal   |
+----+----------+
|  1 | Antelope |
|  2 | Cheetah  |
|  3 | Zebra    |
|  4 | Gorilla  |
+----+----------+

Adding a second unique column:

ALTER TABLE ins_duplicate ADD id2 INT;
UPDATE ins_duplicate SET id2=id+10;
ALTER TABLE ins_duplicate ADD UNIQUE KEY(id2);

Where two rows match the unique keys match, only the first is updated. This
can be unsafe and is not recommended unless you are certain what you are doing.

INSERT INTO ins_duplicate VALUES (2,'Lion',13) 
 ON DUPLICATE KEY UPDATE animal='Lion';
Query OK, 2 rows affected (0.004 sec)

SELECT * FROM ins_duplicate;
+----+----------+------+
| id | animal   | id2  |
+----+----------+------+
|  1 | Antelope |   11 |
|  2 | Lion     |   12 |
|  3 | Zebra    |   13 |
|  4 | Gorilla  |   14 |
+----+----------+------+

Although the third row with an id of 3 has an id2 of 13, which also matched,
it was not updated.

Changing id to an auto_increment field. If a new row is added, the
auto_increment is moved forward. If the row is updated, it remains the same.

ALTER TABLE `ins_duplicate` CHANGE `id` `id` INT( 11 ) NOT NULL AUTO_INCREMENT;
ALTER TABLE ins_duplicate DROP id2;
SELECT Auto_increment FROM INFORMATION_SCHEMA.TABLES 
 WHERE TABLE_NAME='ins_duplicate';
+----------------+
| Auto_increment |
+----------------+
|              5 |
+----------------+

INSERT INTO ins_duplicate VALUES (2,'Leopard') 
 ON DUPLICATE KEY UPDATE animal='Leopard';
Query OK, 2 rows affected (0.00 sec)

SELECT Auto_increment FROM INFORMATION_SCHEMA.TABLES 
 WHERE TABLE_NAME='ins_duplicate';
+----------------+
| Auto_increment |
+----------------+
|              5 |
+----------------+

INSERT INTO ins_duplicate VALUES (5,'Wild Dog') 
 ON DUPLICATE KEY UPDATE animal='Wild Dog';
Query OK, 1 row affected (0.09 sec)

SELECT * FROM ins_duplicate;
+----+----------+
| id | animal   |
+----+----------+
|  1 | Antelope |
|  2 | Leopard  |
|  3 | Zebra    |
|  4 | Gorilla  |
|  5 | Wild Dog |
+----+----------+

SELECT Auto_increment FROM INFORMATION_SCHEMA.TABLES 
 WHERE TABLE_NAME='ins_duplicate';
+----------------+
| Auto_increment |
+----------------+
|              6 |
+----------------+

Refering to column values from the INSERT portion of the statement:

INSERT INTO table (a,b,c) VALUES (1,2,3),(4,5,6)
  ON DUPLICATE KEY UPDATE c=VALUES(a)+VALUES(b);

See the VALUES() function for more.

URL: https://mariadb.com/kb/en/insert-on-duplicate-key-update/https://mariadb.com/kb/en/insert-on-duplicate-key-update/!�<)$���v*INSERT...RETURNINGMariaDB starting with 10.5.0
----------------------------
INSERT ... RETURNING was added in MariaDB 10.5.0, and returns a resultset of
the inserted rows.

Syntax
------

INSERT [LOW_PRIORITY | DELAYED | HIGH_PRIORITY] [IGNORE]
 [INTO] tbl_name [PARTITION (partition_list)] [(col,...)]
 {VALUES | VALUE} ({expr | DEFAULT},...),(...),...
 [ ON DUPLICATE KEY UPDATE
 col=expr
  [, col=expr] ... ] [RETURNING select_expr
   [, select_expr ...]]

Or:

INSERT [LOW_PRIORITY | DELAYED | HIGH_PRIORITY] [IGNORE]
  [INTO] tbl_name [PARTITION (partition_list)]
  SET col={expr | DEFAULT}, ...
  [ ON DUPLICATE KEY UPDATE
   col=expr
    [, col=expr] ... ] [RETURNING select_expr
   [, select_expr ...]]

Or:

INSERT [LOW_PRIORITY | HIGH_PRIORITY] [IGNORE]
  [INTO] tbl_name [PARTITION (partition_list)] [(col,...)]
  SELECT ...
  [ ON DUPLICATE KEY UPDATE
   col=expr
    [, col=expr] ... ] [RETURNING select_expr
   [, select_expr ...]]

Description
-----------

INSERT ... RETURNING returns a resultset of the inserted rows.

This returns the listed columns for all the rows that are inserted, or
alternatively, the specified SELECT expression. Any SQL expressions which can
be calculated can be used in the select expression for the RETURNING clause,
including virtual columns and aliases, expressions which use various operators
such as bitwise, logical and arithmetic operators, string functions, date-time
functions, numeric functions, control flow functions, secondary functions and
stored functions. Along with this, statements which have subqueries and
prepared statements can also be used.

Examples
--------

Simple INSERT statements:

CREATE OR REPLACE TABLE t2 (id INT, animal VARCHAR(20), t TIMESTAMP);

INSERT INTO t2 (id) VALUES (2),(3) RETURNING id,t;
+------+---------------------+
| id   | t                   |
+------+---------------------+
|    2 | 2021-04-28 00:59:32 |
|    3 | 2021-04-28 00:59:32 |
+------+---------------------+

INSERT INTO t2(id,animal) VALUES
(1,'Dog'),(2,'Lion'),(3,'Tiger'),(4,'Leopard')  
 RETURNING id,id+id,id&id,id||id;
+------+-------+-------+--------+
| id   | id+id | id&id | id||id |
+------+-------+-------+--------+
|    1 |     2 |     1 |      1 |
|    2 |     4 |     2 |      1 |
|    3 |     6 |     3 |      1 |
|    4 |     8 |     4 |      1 |
+------+-------+-------+--------+

Using stored functions in RETURNING

DELIMITER |
CREATE FUNCTION f(arg INT) RETURNS INT
  BEGIN
   RETURN (SELECT arg+arg);
  END|

DELIMITER ;

PREPARE stmt FROM "INSERT INTO t1 SET id1=1, animal1='Bear' RETURNING f(id1),
UPPER(animal1)";

EXECUTE stmt;
+---------+----------------+
| f(id1)  | UPPER(animal1) |
+---------+----------------+
|       2 | BEAR           |
+---------+----------------+

Subqueries in the RETURNING clause that return more than one row or column
cannot be used.

Aggregate functions cannot be used in the RETURNING clause. Since aggregate
functions work on a set of values, and if the purpose is to get the row count,
ROW_COUNT() with SELECT can be used or it can be used in
INSERT...SELECT...RETURNING if the table in the RETURNING clause is not the
same as the INSERT table.

URL: https://mariadb.com/kb/en/insertreturning/https://mariadb.com/kb/en/insertreturning/�+REPLACE...RETURNINGMariaDB starting with 10.5.0
----------------------------
REPLACE ... RETURNING was added in MariaDB 10.5.0, and returns a resultset of
the replaced rows.

Syntax
------

REPLACE [LOW_PRIORITY | DELAYED]
 [INTO] tbl_name [PARTITION (partition_list)] [(col,...)]
 {VALUES | VALUE} ({expr | DEFAULT},...),(...),...
[RETURNING select_expr 
   [, select_expr ...]]

Or:

REPLACE [LOW_PRIORITY | DELAYED]
  [INTO] tbl_name [PARTITION (partition_list)]
  SET col={expr | DEFAULT}, ...
[RETURNING select_expr 
   [, select_expr ...]]

Or:

REPLACE [LOW_PRIORITY | DELAYED]
  [INTO] tbl_name [PARTITION (partition_list)] [(col,...)]
  SELECT ...
[RETURNING select_expr 
   [, select_expr ...]]

Description
-----------

REPLACE ... RETURNING returns a resultset of the replaced rows.

This returns the listed columns for all the rows that are replaced, or
alternatively, the specified SELECT expression. Any SQL expressions which can
be calculated can be used in the select expression for the RETURNING clause,
including virtual columns and aliases, expressions which use various operators
such as bitwise, logical and arithmetic operators, string functions, date-time
functions, numeric functions, control flow functions, secondary functions and
stored functions. Along with this, statements which have subqueries and
prepared statements can also be used.

Examples
--------

Simple REPLACE statement

REPLACE INTO t2 VALUES (1,'Leopard'),(2,'Dog') RETURNING id2, id2+id2 
as Total ,id2|id2, id2&&id2;
+-----+-------+---------+----------+
| id2 | Total | id2|id2 | id2&&id2 |
+-----+-------+---------+----------+
|   1 |     2 |       1 |        1 |
|   2 |     4 |       2 |        1 |
+-----+-------+---------+----------+

Using stored functions in RETURNING

DELIMITER |
CREATE FUNCTION f(arg INT) RETURNS INT
  BEGIN
   RETURN (SELECT arg+arg);
  END|

DELIMITER ;
PREPARE stmt FROM "REPLACE INTO t2 SET id2=3, animal2='Fox' RETURNING f2(id2),
UPPER(animal2)";

EXECUTE stmt;
+---------+----------------+
| f2(id2) | UPPER(animal2) |
+---------+----------------+
|       6 | FOX            |
+---------+----------------+

Subqueries in the statement

REPLACE INTO t1 SELECT * FROM t2 RETURNING (SELECT id2 FROM t2 WHERE 
id2 IN (SELECT id2 FROM t2 WHERE id2=1)) AS new_id;
+--------+
| new_id |
+--------+
|      1 |
|      1 |
|      1 |
|      1 |
+--------+

Subqueries in the RETURNING clause that return more than one row or column
cannot be used..

Aggregate functions cannot be used in the RETURNING clause. Since aggregate
functions work on a set of values and if the purpose is to get the row count,
ROW_COUNT() with SELECT can be used, or it can be used in
REPLACE...SELECT...RETURNING if the table in the RETURNING clause is not the
same as the REPLACE table.

URL: https://mariadb.com/kb/en/replacereturning/https://mariadb.com/kb/en/replacereturning/�M�x����CALLSyntax
------

CALL sp_name([parameter[,...]])
CALL sp_name[()]

Description
-----------

The CALL statement invokes a stored procedure that was defined previously with
CREATE PROCEDURE.

Stored procedure names can be specified as database_name.procedure_name.
Procedure names and database names can be quoted with backticks (). This is
necessary if they are reserved words, or contain special characters. See
identifier qualifiers for details.

CALL p() and CALL p are equivalent.

If parentheses are used, any number of spaces, tab characters and newline
characters are allowed between the procedure's name and the open parenthesis.

CALL can pass back values to its caller using parameters that are declared as
OUT or INOUT parameters. If no value is assigned to an OUT parameter, NULL is
assigned (and its former value is lost). To pass such values from another
stored program you can use user-defined variables, local variables or
routine's parameters; in other contexts, you can only use user-defined
variables.

CALL can also be executed as a prepared statement. Placeholders can be used
for IN parameters in all versions of MariaDB; for OUT and INOUT parameters,
placeholders can be used since MariaDB 5.5.

When the procedure returns, a client program can also obtain the number of
rows affected for the final statement executed within the routine: At the SQL
level, call the ROW_COUNT() function; from the C API, call the
mysql_affected_rows() function.

If the CLIENT_MULTI_RESULTS API flag is set, CALL can return any number of
resultsets and the called stored procedure can execute prepared statements. If
it is not set, at most one resultset can be returned and prepared statements
cannot be used within procedures.

URL: https://mariadb.com/kb/en/call/https://mariadb.com/kb/en/call/��)Comment SyntaxThere are three supported comment styles in MariaDB:

* From a '#' to the end of a line:SELECT * FROM users; # This is a comment

* From a '-- ' to the end of a line. The space after the two dashes is
required (as in MySQL).SELECT * FROM users; -- This is a comment

* C style comments from an opening '/*' to a closing '*/'. Comments of this
form can span multiple lines:SELECT * FROM users; /* This is a
multi-line
comment */

Nested comments are possible in some situations, but they are not supported or
recommended.

Executable Comments
-------------------

As an aid to portability between different databases, MariaDB supports
executable comments. These special comments allow you to embed SQL code which
will not execute when run on other databases, but will execute when run on
MariaDB.

MariaDB supports both MySQL's executable comment format, and a slightly
modified version specific to MariaDB. This way, if you have SQL code that
works on MySQL and MariaDB, but not other databases, you can wrap it in a
MySQL executable comment, and if you have code that specifically takes
advantage of features only available in MariaDB you can use the MariaDB
specific format to hide the code from MySQL.

Executable Comment Syntax
-------------------------

MySQL and MariaDB executable comment syntax:

/*! MySQL or MariaDB-specific code */

Code that should be executed only starting from a specific MySQL or MariaDB
version:

/*!##### MySQL or MariaDB-specific code */

The numbers, represented by '######' in the syntax examples above specify the
specific the minimum versions of MySQL and MariaDB that should execute the
comment. The first number is the major version, the second 2 numbers are the
minor version and the last 2 is the patch level.

For example, if you want to embed some code that should only execute on MySQL
or MariaDB starting from 5.1.0, you would do the following:

/*!50100 MySQL and MariaDB 5.1.0 (and above) code goes here. */

MariaDB-only executable comment syntax (starting from MariaDB 5.3.1):

/*M! MariaDB-specific code */
/*M!###### MariaDB-specific code */

MariaDB ignores MySQL-style executable comments that have a version number in
the range 50700..99999. This is needed to skip features introduced in
MySQL-5.7 that are not ported to MariaDB 10.x yet.

/*!50701 MariaDB-10.x ignores MySQL-5.7 specific code */

Note: comments which have a version number in the range 50700..99999 that use
MariaDB-style executable comment syntax are still executed.

/*M!50701 MariaDB-10.x does not ignore this */

Statement delimiters cannot be used within executable comments.

Examples
--------

In MySQL all the following will return 2: In MariaDB, the last 2 queries would
return 3.

SELECT 2 /* +1 */;
SELECT 1 /*! +1 */;
SELECT 1 /*!50101 +1 */;
SELECT 2 /*M! +1 */;
SELECT 2 /*M!50301 +1 */;

The following executable statement will not work due to the delimiter inside
the executable portion:

/*M!100100 select 1 ; */
ERROR 1064 (42000): You have an error in your SQL syntax; check the manual
that corresponds to your MariaDB server version for the right syntax to use
near '' at line 1

Instead, the delimiter should be placed outside the executable portion:

/*M!100100 select 1 */;
+---+
| 1 |
+---+
| 1 |
+---+

URL: https://mariadb.com/kb/en/comment-syntax/https://mariadb.com/kb/en/comment-syntax/$'
yf
��8�\+HANDLER CommandsSyntax
------

HANDLER tbl_name OPEN [ [AS] alias]
HANDLER tbl_name READ index_name { = | >= | <= | < } (value1,value2,...)
  [ WHERE where_condition ] [LIMIT ... ]
HANDLER tbl_name READ index_name { FIRST | NEXT | PREV | LAST }
  [ WHERE where_condition ] [LIMIT ... ]
HANDLER tbl_name READ { FIRST | NEXT }
  [ WHERE where_condition ] [LIMIT ... ]
HANDLER tbl_name CLOSE

Description
-----------

The HANDLER statement provides direct access to table storage engine
interfaces for key lookups and key or table scans. It is available for at
least Aria, Memory, MyISAM and InnoDB tables (and should work with most
'normal' storage engines, but not with system tables, MERGE or views).

HANDLER ... OPEN opens a table, allowing it to be accessible to subsequent
HANDLER ... READ statements. The table can either be opened using an alias
(which must then be used by HANDLER ... READ, or a table name.

The table object is only closed when HANDLER ... CLOSE is called by the
session, and is not shared by other sessions.

Prepared statements work with HANDLER READ, which gives a much higher
performance (50% speedup) as there is no parsing and all data is transformed
in binary (without conversions to text, as with the normal protocol).

The HANDLER command does not work with partitioned tables.

Key Lookup
----------

A key lookup is started with:

HANDLER tbl_name READ index_name { = | >= | <= | < }  (value,value) [LIMIT...]

The values stands for the value of each of the key columns. For most key types
(except for HASH keys in MEMORY storage engine) you can use a prefix subset of
it's columns.

If you are using LIMIT, then in case of >= or > then there is an implicit NEXT
implied, while if you are using <= or < then there is an implicit PREV implied.

After the initial read, you can use

HANDLER tbl_name READ index_name NEXT [ LIMIT ... ]
or
HANDLER tbl_name READ index_name PREV [ LIMIT ... ]

to scan the rows in key order.

Note that the row order is not defined for keys with duplicated values and
will vary from engine to engine.

Key Scans
---------

You can scan a table in key order by doing:

HANDLER tbl_name READ index_name FIRST [ LIMIT ... ]
HANDLER tbl_name READ index_name NEXT  [ LIMIT ... ]

or, if the handler supports backwards key scans (most do):

HANDLER tbl_name READ index_name LAST [ LIMIT ... ]
HANDLER tbl_name READ index_name PREV [ LIMIT ... ]

Table Scans
-----------

You can scan a table in row order by doing:

HANDLER tbl_name READ FIRST [ LIMIT ... ]
HANDLER tbl_name READ NEXT  [ LIMIT ... ]

Limitations
-----------

As this is a direct interface to the storage engine, some limitations may
apply for what you can do and what happens if the table changes. Here follows
some of the common limitations:

Finding 'Old Rows'
------------------

HANDLER READ is not transaction safe, consistent or atomic. It's ok for the
storage engine to returns rows that existed when you started the scan but that
were later deleted. This can happen as the storage engine may cache rows as
part of the scan from a previous read.

You may also find rows committed since the scan originally started.

Invisible Columns
-----------------

HANDLER ... READ also reads the data of invisible-columns.

System-Versioned Tables
-----------------------

HANDLER ... READ reads everything from system-versioned tables, and so
includes row_start and row_end fields, as well as all rows that have since
been deleted or changed, including when history partitions are used.

Other Limitations
-----------------

* If you do an ALTER TABLE, all your HANDLERs for that table are automatically
closed.
* If you do an ALTER TABLE for a table that is used by some other connection
with HANDLER, the ALTER TABLE will wait for the HANDLER to be closed.
* For HASH keys, you must use all key parts when searching for a row.
* For HASH keys, you can't do a key scan of all values. You can only find all
rows with the same key value.
* While each HANDLER READ command is atomic, if you do a scan in many steps,
then some engines may give you error 1020 if the table changed between the
commands. Please refer to the specific engine handler page if this happens.

Error Codes
-----------

* Error 1031 (ER_ILLEGAL_HA) Table storage engine for 't1' doesn't have this
option
If you get this for HANDLER OPEN it means the storage engine doesn't support
HANDLER calls.
If you get this for HANDLER READ it means you are trying to use an incomplete
HASH key.

* Error 1020 (ER_CHECKREAD) Record has changed since last read in table '...'
This means that the table changed between two reads and the handler can't
handle this case for the given scan.

URL: https://mariadb.com/kb/en/handler-commands/https://mariadb.com/kb/en/handler-commands/��4HANDLER for MEMORY TablesThis article explains how to use HANDLER commands efficiently with MEMORY/HEAP
tables.

If you want to scan a table for over different key values, not just search for
exact key values, you should create your keys with 'USING BTREE':

CREATE TABLE t1 (a INT, b INT, KEY(a), KEY b USING BTREE (b)) engine=memory;

In the above table, a is a HASH key that only supports exact matches (=) while
b is a BTREE key that you can use to scan the table in key order, starting
from start or from a given key value.

The limitations for HANDLER READ with Memory|HEAP tables are:

Limitations for HASH keys
-------------------------

* You must use all key parts when searching for a row.
* You can't do a key scan of all values. You can only find all rows with the
same key value.
* READ NEXT gives error 1031 if the tables changed since last read.

Limitations for BTREE keys
--------------------------

* READ NEXT gives error 1031 if the tables changed since last read. This
limitation can be lifted in the future.

Limitations for table scans
---------------------------

* READ NEXT gives error 1031 if the table was truncated since last READ call.

URL: https://mariadb.com/kb/en/handler-for-memory-tables/https://mariadb.com/kb/en/handler-for-memory-tables/��	����8.ANALYZE FORMAT=JSONANALYZE FORMAT=JSON is a mix of the EXPLAIN FORMAT=JSON and ANALYZE statement
features. The ANALYZE FORMAT=JSON $statement will execute $statement, and then
print the output of EXPLAIN FORMAT=JSON, amended with data from the query
execution.

Basic Execution Data
--------------------

You can get the following also from tabular ANALYZE statement form:

* r_rows  is provided for any node that reads rows. It shows how many rows
were read, on average 
* r_filtered is provided whenever there is a condition that is checked.  It
shows the percentage of rows left after checking the condition.

Advanced Execution Data
-----------------------

The most important data not available in the regular tabula ANALYZE statement
are:

* r_loops field.  This shows how many times the node was executed. Most query
plan elements have this field.
* r_total_time_ms field. It shows how much time in total, in milliseconds, was
spent executing this node. If the node has subnodes, their execution time is
included.
* r_buffer_size field. Query plan nodes that make use of buffers report the
size of buffer that was was used.

SHOW ANALYZE FORMAT=JSON
------------------------

MariaDB starting with 10.9
--------------------------
SHOW ANALYZE FORMAT=JSON for <connection_id> extends ANALYZE [FORMAT=JSON]
<select> to allow one to analyze a query currently running in another
connection.

Data About Individual Query Plan Nodes
--------------------------------------

* filesort node reports whether sorting was done with LIMIT n parameter, and
how many rows were in the sort result. 
* block-nl-join node has r_loops field, which allows to tell whether Using
join buffer was efficient 
* range-checked-for-each-record reports counters that show the result of the
check. 
* expression-cache is used for subqueries, and it reports how many times the
cache was used, and what cache hit ratio was.
* union_result node has r_rows so one can see how many rows were produced
after UNION operation
* and so forth

Use Cases
---------

See Examples of ANALYZE FORMAT=JSON.

URL: https://mariadb.com/kb/en/analyze-format-json/https://mariadb.com/kb/en/analyze-format-json/��6ANALYZE FORMAT=JSON ExamplesExample #1
----------

Customers who have ordered more than 1M goods.

ANALYZE FORMAT=JSON
SELECT COUNT(*)
FROM customer
WHERE
 (SELECT SUM(o_totalprice) FROM orders WHERE o_custkey=c_custkey) > 1000*1000;

The query takes 40 seconds over cold cache

EXPLAIN: {
 "query_block": {
  "select_id": 1,
  "r_loops": 1,
  "r_total_time_ms": 39872,
  "table": {
   "table_name": "customer",
   "access_type": "index",
   "key": "i_c_nationkey",
   "key_length": "5",
   "used_key_parts": ["c_nationkey"],
   "r_loops": 1,
   "rows": 150303,
   "r_rows": 150000,
   "r_total_time_ms": 270.3,
   "filtered": 100,
   "r_filtered": 60.691,
   "attached_condition": "((subquery#2) > <cache>((1000 * 1000)))",
   "using_index": true
  },
  "subqueries": [
   {
    "query_block": {
     "select_id": 2,
     "r_loops": 150000,
     "r_total_time_ms": 39531,
     "table": {
      "table_name": "orders",
      "access_type": "ref",
      "possible_keys": ["i_o_custkey"],
      "key": "i_o_custkey",
      "key_length": "5",
      "used_key_parts": ["o_custkey"],
      "ref": ["dbt3sf1.customer.c_custkey"],
      "r_loops": 150000,
      "rows": 7,
      "r_rows": 10,
      "r_total_time_ms": 39208,
      "filtered": 100,
      "r_filtered": 100
     }
    }
   }
  ]
 }
}
ANALYZE shows that 39.2 seconds were spent in the subquery, which was executed
150K times (for every row of outer table).

URL: https://mariadb.com/kb/en/analyze-formatjson-examples/https://mariadb.com/kb/en/analyze-formatjson-examples/�N.EXPLAIN FORMAT=JSONSynopsis
--------

EXPLAIN FORMAT=JSON is a variant of EXPLAIN command that produces output in
JSON form. The output always has one row which has only one column titled
"JSON". The contents are a JSON representation of the query plan, formatted
for readability:

EXPLAIN FORMAT=JSON SELECT * FROM t1 WHERE col1=1\G

*************************** 1. row ***************************
EXPLAIN: {
 "query_block": {
  "select_id": 1,
  "table": {
   "table_name": "t1",
   "access_type": "ALL",
   "rows": 1000,
   "filtered": 100,
   "attached_condition": "(t1.col1 = 1)"
  }
 }
}

Output is different from MySQL
------------------------------

The output of MariaDB's EXPLAIN FORMAT=JSON is different from EXPLAIN
FORMAT=JSON in MySQL.The reasons for that are:

* MySQL's output has deficiencies. Some are listed here: EXPLAIN FORMAT=JSON
in MySQL
* The output of MySQL's EXPLAIN FORMAT=JSON is not defined. Even MySQL
Workbench has trouble parsing it (see this blog post).
* MariaDB has query optimizations that MySQL does not have. Ergo, MariaDB
generates query plans that MySQL does not generate.

A (as yet incomplete) list of how MariaDB's output is different from MySQL can
be found here: EXPLAIN FORMAT=JSON differences from MySQL.

Output Format
-------------

TODO: MariaDB's output format description.

URL: https://mariadb.com/kb/en/explain-format-json/https://mariadb.com/kb/en/explain-format-json/�����_������,ANALYZE StatementDescription
-----------

The ANALYZE statement is similar to the EXPLAIN statement. ANALYZE statement
will invoke the optimizer, execute the statement, and then produce EXPLAIN
output instead of the result set. The EXPLAIN output will be annotated with
statistics from statement execution.

This lets one check how close the optimizer's estimates about the query plan
are to the reality. ANALYZE produces an overview, while the ANALYZE
FORMAT=JSON command provides a more detailed view of the query plan and the
query execution.

The syntax is

ANALYZE explainable_statement;

where the statement is any statement for which one can run EXPLAIN.

Command Output
--------------

Consider an example:

ANALYZE SELECT * FROM tbl1 
WHERE key1 
 BETWEEN 10 AND 200 AND
 col1 LIKE 'foo%'\G

*************************** 1. row ***************************
     id: 1
 select_type: SIMPLE
    table: tbl1
    type: range
possible_keys: key1
     key: key1
   key_len: 5
     ref: NULL
    rows: 181
   r_rows: 181
  filtered: 100.00
 r_filtered: 10.50
    Extra: Using index condition; Using where

Compared to EXPLAIN, ANALYZE produces two extra columns:

* r_rows is an observation-based counterpart of the rows column. It shows how
many rows were actually read from the table. 
* r_filtered is an observation-based counterpart of the filtered column. It
shows which fraction of rows was left after applying the WHERE condition.

Interpreting the Output
-----------------------

Joins
-----

Let's consider a more complicated example.

ANALYZE SELECT *
FROM orders, customer 
WHERE
 customer.c_custkey=orders.o_custkey AND
 customer.c_acctbal < 0 AND
 orders.o_totalprice > 200*1000

+----+-------------+----------+------+---------------+-------------+---------+-
------------------+--------+--------+----------+------------+-------------+
| id | select_type | table    | type | possible_keys | key         | key_len |
ref                | rows   | r_rows | filtered | r_filtered | Extra       |
+----+-------------+----------+------+---------------+-------------+---------+-
------------------+--------+--------+----------+------------+-------------+
|  1 | SIMPLE      | customer | ALL  | PRIMARY,...   | NULL        | NULL    |
NULL               | 149095 | 150000 |    18.08 |       9.13 | Using where |
|  1 | SIMPLE      | orders   | ref  | i_o_custkey   | i_o_custkey | 5       |
customer.c_custkey |      7 |     10 |   100.00 |      30.03 | Using where |
+----+-------------+----------+------+---------------+-------------+---------+-
------------------+--------+--------+----------+------------+-------------+

Here, one can see that

* For table customer, customer.rows=149095,  customer.r_rows=150000. The
estimate for number of rows we will read was fairly precise
* customer.filtered=18.08, customer.r_filtered=9.13.  The optimizer somewhat
overestimated the number of records that will match selectivity of condition
attached to `customer` table (in general, when you have a full scan and
r_filtered is less than 15%, it's time to consider adding an appropriate
index).
* For table orders,  orders.rows=7, orders.r_rows=10.  This means that on
average, there are 7 orders for a given c_custkey, but in our case there were
10, which is close to the expectation (when this number is consistently far
from the expectation, it may be time to run ANALYZE TABLE, or even edit the
table statistics manually to get better query plans).
* orders.filtered=100, orders.r_filtered=30.03. The optimizer didn't have any
way to estimate which fraction of records will be left after it checks the
condition that is attached to table orders (it's orders.o_totalprice >
200*1000). So, it used 100%. In reality, it is 30%. 30% is typically not
selective enough to warrant adding new indexes. For joins with many tables, it
might be worth to collect and use column statistics for columns in question,
this may help the optimizer to pick a better query plan.

Meaning of NULL in r_rows and r_filtered
----------------------------------------

Let's modify the previous example slightly

ANALYZE SELECT * 
FROM orders, customer 
WHERE
 customer.c_custkey=orders.o_custkey AND
 customer.c_acctbal < -0 AND
 customer.c_comment LIKE '%foo%' AND
 orders.o_totalprice > 200*1000;

+----+-------------+----------+------+---------------+-------------+---------+-
------------------+--------+--------+----------+------------+-------------+
| id | select_type | table    | type | possible_keys | key         | key_len |
ref                | rows   | r_rows | filtered | r_filtered | Extra       |
+----+-------------+----------+------+---------------+-------------+---------+-
------------------+--------+--------+----------+------------+-------------+
|  1 | SIMPLE      | customer | ALL  | PRIMARY,...   | NULL        | NULL    |
NULL               | 149095 | 150000 |    18.08 |       0.00 | Using where |
|  1 | SIMPLE      | orders   | ref  | i_o_custkey   | i_o_custkey | 5       |
customer.c_custkey |      7 |   NULL |   100.00 |       NULL | Using where |
+----+-------------+----------+------+---------------+-------------+---------+-
------------------+--------+--------+----------+------------+-------------+

Here, one can see that orders.r_rows=NULL and orders.r_filtered=NULL. This
means that table orders was not scanned even once. Indeed, we can also see
customer.r_filtered=0.00. This shows that a part of WHERE attached to table
`customer` was never satisfied (or, satisfied in less than 0.01% of cases).

ANALYZE FORMAT=JSON
-------------------

ANALYZE FORMAT=JSON produces JSON output. It produces much more information
than tabular ANALYZE.

Notes
-----

* ANALYZE UPDATE or ANALYZE DELETE will actually make updates/deletes (ANALYZE
SELECT will perform the select operation and then discard the resultset).
* PostgreSQL has a similar command, EXPLAIN ANALYZE.
* The EXPLAIN in the slow query log feature allows MariaDB to have ANALYZE
output of slow queries printed into the slow query log (see MDEV-6388).

URL: https://mariadb.com/kb/en/analyze-statement/https://mariadb.com/kb/en/analyze-statement/�5KH@����#DESCRIBESyntax
------

{DESCRIBE | DESC} tbl_name [col_name | wild]

Description
-----------

DESCRIBE provides information about the columns in a table. It is a shortcut
for SHOW COLUMNS FROM. These statements also display information for views.

col_name can be a column name, or a string containing the SQL "%" and "_"
wildcard characters to obtain output only for the columns with names matching
the string. There is no need to enclose the string within quotes unless it
contains spaces or other special characters.

DESCRIBE city;
+------------+----------+------+-----+---------+----------------+
| Field      | Type     | Null | Key | Default | Extra          |
+------------+----------+------+-----+---------+----------------+
| Id         | int(11)  | NO   | PRI | NULL    | auto_increment |
| Name       | char(35) | YES  |     | NULL    |                |
| Country    | char(3)  | NO   | UNI |         |                |
| District   | char(20) | YES  | MUL |         |                |
| Population | int(11)  | YES  |     | NULL    |                |
+------------+----------+------+-----+---------+----------------+

The description for SHOW COLUMNS provides more information about the output
columns.

URL: https://mariadb.com/kb/en/describe/https://mariadb.com/kb/en/describe/�K6Identifier Case-sensitivityWhether objects are case-sensitive or not is partly determined by the
underlying operating system. Unix-based systems are case-sensitive, Windows is
not, while Mac OS X is usually case-insensitive by default, but devices can be
configured as case-sensitive using Disk Utility.

Database, table, table aliases and trigger names are affected by the systems
case-sensitivity, while index, column, column aliases, stored routine and
event names are never case sensitive.

Log file group name are case sensitive.

The lower_case_table_names server system variable plays a key role. It
determines whether table names, aliases and database names are compared in a
case-sensitive manner. If set to 0 (the default on Unix-based systems), table
names and aliases and database names are compared in a case-sensitive manner.
If set to 1 (the default on Windows), names are stored in lowercase and not
compared in a case-sensitive manner. If set to 2 (the default on Mac OS X),
names are stored as declared, but compared in lowercase.

It is thus possible to make Unix-based systems behave like Windows and ignore
case-sensitivity, but the reverse is not true, as the underlying Windows
filesystem can not support this.

Even on case-insensitive systems, you are required to use the same case
consistently within the same statement. The following statement fails, as it
refers to the table name in a different case.

SELECT * FROM a_table WHERE A_table.id>10;

For a full list of identifier naming rules, see Identifier Names.

Please note that lower_case_table_names is a database initialization
parameter. This means that, along with innodb_page_size, this variable must be
set before running mariadb-install-db, and will not change the behavior of
servers unless applied before the creation of core system databases.

URL: https://mariadb.com/kb/en/identifier-case-sensitivity/https://mariadb.com/kb/en/identifier-case-sensitivity/�O/Hexadecimal LiteralsHexadecimal literals can be written using any of the following syntaxes:

* x'value'
* X'value' (SQL standard)
* 0xvalue (ODBC)

value is a sequence of hexadecimal digits (from 0 to 9 and from A to F). The
case of the digits does not matter. With the first two syntaxes, value must
consist of an even number of digits. With the last syntax, digits can be even,
and they are treated as if they had an extra 0 at the beginning.

Normally, hexadecimal literals are interpreted as binary string, where each
pair of digits represents a character. When used in a numeric context, they
are interpreted as integers. (See the example below). In no case can a
hexadecimal literal be a decimal number.

The first two syntaxes; X'value' and x'value, follow the SQL standard, and
behave as a string in all contexts in MariaDB since MariaDB 10.0.3 and MariaDB
5.5.31 (fixing MDEV-4489). The latter syntax, 0xvalue, is a MySQL/MariaDB
extension for hex hybrids and behaves as a string or as a number depending on
context. MySQL treats all syntaxes the same, so there may be different results
in MariaDB and MySQL (see below).

Examples
--------

Representing the a character with the three syntaxes explained above:

SELECT x'61', X'61', 0x61;
+-------+-------+------+
| x'61' | X'61' | 0x61 |
+-------+-------+------+
| a     | a     | a    |
+-------+-------+------+

Hexadecimal literals in a numeric context:

SELECT 0 + 0xF, -0xF;
+---------+------+
| 0 + 0xF | -0xF |
+---------+------+
|      15 |  -15 |
+---------+------+

Fun with Types
--------------

CREATE TABLE t1 (a INT, b VARCHAR(10));
INSERT INTO t1 VALUES (0x31, 0x61),(COALESCE(0x31), COALESCE(0x61));

SELECT * FROM t1;
+------+------+
| a    | b    |
+------+------+
|   49 | a    |
|    1 | a    |
+------+------+

The reason for the differing results above is that when 0x31 is inserted
directly to the column, it's treated as a number, while when 0x31 is passed to
COALESCE(), it's treated as a string, because:

* HEX values have a string data type by default.
* COALESCE() has the same data type as the argument.

Differences Between MariaDB and MySQL
-------------------------------------

SELECT x'0a'+0;
+---------+
| x'0a'+0 |
+---------+
|       0 |
+---------+
1 row in set, 1 warning (0.00 sec)

Warning (Code 1292): Truncated incorrect DOUBLE value: '\x0A'

SELECT X'0a'+0;
+---------+
| X'0a'+0 |
+---------+
|       0 |
+---------+
1 row in set, 1 warning (0.00 sec)

Warning (Code 1292): Truncated incorrect DOUBLE value: '\x0A'

SELECT 0x0a+0;
+--------+
| 0x0a+0 |
+--------+
|     10 |
+--------+

In MySQL (up until at least MySQL 8.0.26):

SELECT x'0a'+0;
+---------+
| x'0a'+0 |
+---------+
|      10 |
+---------+

SELECT X'0a'+0;
+---------+
| X'0a'+0 |
+---------+
|      10 |
+---------+

SELECT 0x0a+0;
+--------+
| 0x0a+0 |
+--------+
|     10 |
+--------+

URL: https://mariadb.com/kb/en/hexadecimal-literals/https://mariadb.com/kb/en/hexadecimal-literals/��&��D���+Identifier NamesDatabases, tables, indexes, columns, aliases, views, stored routines,
triggers, events, variables, partitions, tablespaces, savepoints, labels,
users, roles, are collectively known as identifiers, and have certain rules
for naming.

Identifiers may be quoted using the backtick character - `. Quoting is
optional for identifiers that don't contain special characters, or for
identifiers that are not reserved words. If the ANSI_QUOTES SQL_MODE flag is
set, double quotes (") can also be used to quote identifiers. If the MSSQL
flag is set, square brackets ([ and ]) can be used for quoting.

Even when using reserved words as names, fully qualified names do not need to
be quoted. For example, test.select has only one possible meaning, so it is
correctly parsed even without quotes.

Unquoted
--------

The following characters are valid, and allow identifiers to be unquoted:

* ASCII: [0-9,a-z,A-Z$_] (numerals 0-9, basic Latin letters, both lowercase
and uppercase, dollar sign, underscore)
* Extended: U+0080 .. U+FFFF

Quoted
------

The following characters are valid, but identifiers using them must be quoted:

* ASCII: U+0001 .. U+007F (full Unicode Basic Multilingual Plane (BMP) except
for U+0000)
* Extended: U+0080 .. U+FFFF 
* Identifier quotes can themselves be used as part of an identifier, as long
as they are quoted.

Further Rules
-------------

There are a number of other rules for identifiers:

* Identifiers are stored as Unicode (UTF-8)
* Identifiers may or may not be case-sensitive. See Indentifier
Case-sensitivity.
* Database, table and column names can't end with space characters
* Identifier names may begin with a numeral, but can't only contain numerals
unless quoted.
* An identifier starting with a numeral, followed by an 'e', may be parsed as
a floating point number, and needs to be quoted.
* Identifiers are not permitted to contain the ASCII NUL character (U+0000)
and supplementary characters (U+10000 and higher).
* Names such as 5e6, 9e are not prohibited, but it's strongly recommended not
to use them, as they could lead to ambiguity in certain contexts, being
treated as a number or expression.
* User variables cannot be used as part of an identifier, or as an identifier
in an SQL statement.

Quote Character
---------------

The regular quote character is the backtick character - `, but if the
ANSI_QUOTES SQL_MODE option is specified, a regular double quote - " may be
used as well.

The backtick character can be used as part of an identifier. In that case the
identifier needs to be quoted. The quote character can be the backtick, but in
that case, the backtick in the name must be escaped with another backtick.

Maximum Length
--------------

* Databases, tables, columns, indexes, constraints, stored routines, triggers,
events, views, tablespaces, servers and log file groups have a maximum length
of 64 characters.
* Compound statement labels have a maximum length of 16 characters
* Aliases have a maximum length of 256 characters, except for column aliases
in CREATE VIEW statements, which are checked against the maximum column length
of 64 characters (not the maximum alias length of 256 characters).
* Users have a maximum length of 80 characters.
* Roles have a maximum length of 128 characters.
* Multi-byte characters do not count extra towards towards the character limit.

Multiple Identifiers
--------------------

MariaDB allows the column name to be used on its own if the reference will be
unambiguous, or the table name to be used with the column name, or all three
of the database, table and column names. A period is used to separate the
identifiers, and the period can be surrounded by spaces.

Examples
--------

Using the period to separate identifiers:

CREATE TABLE t1 (i int);

INSERT INTO t1(i) VALUES (10);

SELECT i FROM t1;
+------+
| i    |
+------+
|   10 |
+------+

SELECT t1.i FROM t1;
+------+
| i    |
+------+
|   10 |
+------+

SELECT test.t1.i FROM t1;
+------+
| i    |
+------+
|   10 |
+------+

The period can be separated by spaces:

SELECT test . t1 . i FROM t1;
+------+
| i    |
+------+
|   10 |
+------+

Resolving ambiguity:

CREATE TABLE t2 (i int);

SELECT i FROM t1 LEFT JOIN t2 ON t1.i=t2.i;
ERROR 1052 (23000): Column 'i' in field list is ambiguous

SELECT t1.i FROM t1 LEFT JOIN t2 ON t1.i=t2.i;
+------+
| i    |
+------+
|   10 |
+------+

Creating a table with characters that require quoting:

CREATE TABLE 123% (i int);
ERROR 1064 (42000): You have an error in your SQL syntax; 
 check the manual that corresponds to your MariaDB server version for the
right syntax 
 to use near '123% (i int)' at line 1

CREATE TABLE `123%` (i int);
Query OK, 0 rows affected (0.85 sec)

CREATE TABLE `TABLE` (i int);
Query OK, 0 rows affected (0.36 sec)

Using double quotes as a quoting character:

CREATE TABLE "SELECT" (i int);
ERROR 1064 (42000): You have an error in your SQL syntax; 
 check the manual that corresponds to your MariaDB server version for the
right syntax 
 to use near '"SELECT" (i int)' at line 1

SET sql_mode='ANSI_QUOTES';
Query OK, 0 rows affected (0.03 sec)

CREATE TABLE "SELECT" (i int);
Query OK, 0 rows affected (0.46 sec)

Using an identifier quote as part of an identifier name:

SHOW VARIABLES LIKE 'sql_mode';
+---------------+-------------+
| Variable_name | Value       |
+---------------+-------------+
| sql_mode      | ANSI_QUOTES |
+---------------+-------------+

CREATE TABLE "fg`d" (i int);
Query OK, 0 rows affected (0.34 sec)

Creating the table named * (Unicode number: U+002A) requires quoting.

CREATE TABLE `*` (a INT);

Floating point ambiguity:

CREATE TABLE 8984444cce5d (x INT);
Query OK, 0 rows affected (0.38 sec)

CREATE TABLE 8981e56cce5d (x INT);
ERROR 1064 (42000): You have an error in your SQL syntax; 
 check the manual that corresponds to your MariaDB server version for the
right syntax 
 to use near '8981e56cce5d (x INT)' at line 1

CREATE TABLE `8981e56cce5d` (x INT);
Query OK, 0 rows affected (0.39 sec)

URL: https://mariadb.com/kb/en/identifier-names/https://mariadb.com/kb/en/identifier-names/��cV��5	��1Date and Time LiteralsStandard syntaxes
-----------------

MariaDB supports the SQL standard and ODBC syntaxes for DATE, TIME and
TIMESTAMP literals.

SQL standard syntax:

* DATE 'string'
* TIME 'string'
* TIMESTAMP 'string'

ODBC syntax:

* {d 'string'}
* {t 'string'}
* {ts 'string'}

The timestamp literals are treated as DATETIME literals, because in MariaDB
the range of DATETIME is closer to the TIMESTAMP range in the SQL standard.

string is a string in a proper format, as explained below.

DATE literals
-------------

A DATE string is a string in one of the following formats: 'YYYY-MM-DD' or
'YY-MM-DD'. Note that any punctuation character can be used as delimiter. All
delimiters must consist of 1 character. Different delimiters can be used in
the same string. Delimiters are optional (but if one delimiter is used, all
delimiters must be used).

A DATE literal can also be an integer, in one of the following formats:
YYYYMMDD or YYMMDD.

All the following DATE literals are valid, and they all represent the same
value:

'19940101'
'940101'
'1994-01-01'
'94/01/01'
'1994-01/01'
'94:01!01'
19940101
940101

DATETIME literals
-----------------

A DATETIME string is a string in one of the following formats: 'YYYY-MM-DD
HH:MM:SS' or 'YY-MM-DD HH:MM:SS'. Note that any punctuation character can be
used as delimiter for the date part and for the time part. All delimiters must
consist of 1 character. Different delimiters can be used in the same string.
The hours, minutes and seconds parts can consist of one character. For this
reason, delimiters are mandatory for DATETIME literals.

The delimiter between the date part and the time part can be a T or any
sequence of space characters (including tabs, new lines and carriage returns).

A DATETIME literal can also be a number, in one of the following formats:
YYYYMMDDHHMMSS, YYMMDDHHMMSS, YYYYMMDD or YYMMDD. In this case, all the time
subparts must consist of 2 digits.

All the following DATE literals are valid, and they all represent the same
value:

'1994-01-01T12:30:03'
'1994/01/01\n\t 12+30+03'
'1994/01\\01\n\t 12+30-03'
'1994-01-01 12:30:3'

TIME literals
-------------

A TIME string is a string in one of the following formats: 'D HH:MM:SS',
'HH:MM:SS, 'D HH:MM', 'HH:MM', 'D HH', or 'SS'. D is a value from 0 to 34
which represents days. : is the only allowed delimiter for TIME literals.
Delimiters are mandatory, with an exception: the 'HHMMSS' format is allowed.
When delimiters are used, each part of the literal can consist of one
character.

A TIME literal can also be a number in one of the following formats: HHMMSS,
MMSS, or SS.

The following literals are equivalent:

'09:05:00'
'9:05:0'
'9:5:0'
'090500'

2-digit years
-------------

The year part in DATE and DATETIME literals is determined as follows:

* 70 - 99 = 1970 - 1999
* 00 - 69 = 2000 - 2069

Microseconds
------------

DATETIME and TIME literals can have an optional microseconds part. For both
string and numeric forms, it is expressed as a decimal part. Up to 6 decimal
digits are allowed. Examples:

'12:30:00.123456'
123000.123456

See Microseconds in MariaDB for details.

Date and time literals and the SQL_MODE
---------------------------------------

Unless the SQL_MODE NO_ZERO_DATE flag is set, some special values are allowed:
the '0000-00-00' DATE, the '00:00:00' TIME, and the 0000-00-00 00:00:00
DATETIME.

If the ALLOW_INVALID_DATES flag is set, the invalid dates (for example, 30th
February) are allowed. If not, if the NO_ZERO_DATE is set, an error is
produced; otherwise, a zero-date is returned.

Unless the NO_ZERO_IN_DATE flag is set, each subpart of a date or time value
(years, hours...) can be set to 0.

URL: https://mariadb.com/kb/en/date-and-time-literals/https://mariadb.com/kb/en/date-and-time-literals/��0Identifier QualifiersQualifiers are used within SQL statements to reference data structures, such
as databases, tables, or columns. For example, typically a SELECT query
contains references to some columns and at least one table.

Qualifiers can be composed by one or more identifiers, where the initial parts
affect the context within which the final identifier is interpreted:

* For a database, only the database identifier needs to be specified.
* For objects which are contained in a database (like tables, views,
functions, etc) the database identifier can be specified. If no database is
specified, the current database is assumed (see USE and DATABASE() for more
details). If there is no default database and no database is specified, an
error is issued.
* For column names, the table and the database are generally obvious from the
context of the statement. It is however possible to specify the table
identifier, or the database identifier plus the table identifier.
* An identifier is fully-qualified if it contains all possible qualifiers, for
example, the following column is fully qualified: db_name.tbl_name.col_name.

If a qualifier is composed by more than one identifier, a dot (.) must be used
as a separator. All identifiers can be quoted individually. Extra spacing
(including new lines and tabs) is allowed.

All the following examples are valid:

* db_name.tbl_name.col_name
* tbl_name
* `db_name`.`tbl_name`.`col_name`
* `db_name` . `tbl_name`
* db_name. tbl_name

If a table identifier is prefixed with a dot (.), the default database is
assumed. This syntax is supported for ODBC compliance, but has no practical
effect on MariaDB. These qualifiers are equivalent:

* tbl_name
* . tbl_name
* .`tbl_name`
* . `tbl_name`

For DML statements, it is possible to specify a list of the partitions using
the PARTITION clause. See Partition Pruning and Selection for details.

URL: https://mariadb.com/kb/en/identifier-qualifiers/https://mariadb.com/kb/en/identifier-qualifiers/���p�7����:Identifier to File Name MappingSome identifiers map to a file name on the filesystem. Databases each have
their own directory, while, depending on the storage engine, table names and
index names may map to a file name.

Not all characters that are allowed in table names can be used in file names.
Every filesystem has its own rules of what characters can be used in file
names. To let the user create tables using all characters allowed in the SQL
Standard and to not depend on whatever particular filesystem a particular
database resides, MariaDB encodes "potentially unsafe" characters in the table
name to derive the corresponding file name.

This is implemented using a special character set. MariaDB converts a table
name to the "filename" character set to get the file name for this table. And
it converts the file name from the "filename" character set to, for example,
utf8 to get the table name for this file name.

The conversion rules are as follows: if the identifier is made up only of
basic Latin numbers, letters and/or the underscore character, the encoding
matches the name (see however Identifier Case Sensitivity). Otherwise they are
encoded according to the following table:

+-----------------+------------+-----------+--------+-----------+-----------+
| Code Range      | Pattern    | Number    | Used   | Unused    | Blocks    |
+-----------------+------------+-----------+--------+-----------+-----------+
| 00C0..017F      | [@][0..4][ | 5*20= 100 | 97     | 3         | Latin-1   |
|                 | ..z]       |           |        |           | Supplemen |
|                 |            |           |        |           |  + Latin  |
|                 |            |           |        |           | Extended- |
|                 |            |           |        |           |           |
+-----------------+------------+-----------+--------+-----------+-----------+
| 0370..03FF      | [@][5..9][ | 5*20= 100 | 88     | 12        | Greek     |
|                 | ..z]       |           |        |           | and       |
|                 |            |           |        |           | Coptic    |
+-----------------+------------+-----------+--------+-----------+-----------+
| 0400..052F      | [@][g..z][ | 20*7= 140 | 137    | 3         | Cyrillic  |
|                 | ..6]       |           |        |           | +         |
|                 |            |           |        |           | Cyrillic  |
|                 |            |           |        |           | Supplemen |
|                 |            |           |        |           |           |
+-----------------+------------+-----------+--------+-----------+-----------+
| 0530..058F      | [@][g..z][ | 20*2= 40  | 38     | 2         | Armenian  |
|                 | ..8]       |           |        |           |           |
+-----------------+------------+-----------+--------+-----------+-----------+
| 2160..217F      | [@][g..z][ | 20*1= 20  | 16     | 4         | Number    |
|                 | ]          |           |        |           | Forms     |
+-----------------+------------+-----------+--------+-----------+-----------+
| 0180..02AF      | [@][g..z][ | 20*11=220 | 203    | 17        | Latin     |
|                 | ..k]       |           |        |           | Extended- |
|                 |            |           |        |           |  + IPA    |
|                 |            |           |        |           | Extension |
|                 |            |           |        |           |           |
+-----------------+------------+-----------+--------+-----------+-----------+
| 1E00..1EFF      | [@][g..z][ | 20*7= 140 | 136    | 4         | Latin     |
|                 | ..r]       |           |        |           | Extended  |
|                 |            |           |        |           | Additiona |
|                 |            |           |        |           |           |
+-----------------+------------+-----------+--------+-----------+-----------+
| 1F00..1FFF      | [@][g..z][ | 20*8= 160 | 144    | 16        | Greek     |
|                 | ..z]       |           |        |           | Extended  |
+-----------------+------------+-----------+--------+-----------+-----------+
| .... ....       | [@][a..f][ | 6*20= 120 | 0      | 120       | RESERVED  |
|                 | ..z]       |           |        |           |           |
+-----------------+------------+-----------+--------+-----------+-----------+
| 24B6..24E9      | [@][@][a.. | 26        | 26     | 0         | Enclosed  |
|                 | ]          |           |        |           | Alphanume |
|                 |            |           |        |           | ics       |
+-----------------+------------+-----------+--------+-----------+-----------+
| FF21..FF5A      | [@][a..z][ | 26        | 26     | 0         | Halfwidth |
|                 | ]          |           |        |           | and       |
|                 |            |           |        |           | Fullwidth |
|                 |            |           |        |           | forms     |
+-----------------+------------+-----------+--------+-----------+-----------+

Code Range values are UCS-2.

All of this encoding happens transparently at the filesystem level with one
exception. Until MySQL 5.1.6, an old encoding was used. Identifiers created in
a version before MySQL 5.1.6, and which haven't been updated to the new
encoding, the server prefixes mysql50 to their name.

Examples
--------

Find the file name for a table with a non-Latin1 name:

select cast(convert("this_is_таблица" USING filename) as binary);
+------------------------------------------------------------------+
| cast(convert("this_is_таблица" USING filename) as binary)        |
+------------------------------------------------------------------+
| this_is_@y0@g0@h0@r0@o0@i1@g0                                    |
+------------------------------------------------------------------+

Find the table name for a file name:

select convert(_filename "this_is_@y0@g0@h0@r0@o0@i1@g0" USING utf8);
+---------------------------------------------------------------+
| convert(_filename "this_is_@y0@g0@h0@r0@o0@i1@g0" USING utf8) |
+---------------------------------------------------------------+
| this_is_таблица                                               |
+---------------------------------------------------------------+

An old table created before MySQL 5.1.6, with the old encoding:

SHOW TABLES;
+--------------------+
| Tables_in_test     |
+--------------------+
| #mysql50#table@1   |
+--------------------+

The prefix needs to be supplied to reference this table:

SHOW COLUMNS FROM `table@1`;
ERROR 1146 (42S02): Table 'test.table@1' doesn't exist

SHOW COLUMNS FROM `#mysql50#table@1`;
+-------+---------+------+-----+---------+-------+
| Field | Type    | Null | Key | Default | Extra |
+-------+---------+------+-----+---------+-------+
| i     | int(11) | YES  |     | NULL    |       |
+-------+---------+------+-----+---------+-------+

URL: https://mariadb.com/kb/en/identifier-to-file-name-mapping/https://mariadb.com/kb/en/identifier-to-file-name-mapping/ c�����*Numeric LiteralsNumeric literals are written as a sequence of digits from 0 to 9. Initial
zeros are ignored. A sign can always precede the digits, but it is optional
for positive numbers. In decimal numbers, the integer part and the decimal
part are divided with a dot (.).

If the integer part is zero, it can be omitted, but the literal must begin
with a dot.

The notation with exponent can be used. The exponent is preceded by an E or e
character. The exponent can be preceded by a sign and must be an integer. A
number N with an exponent part X, is calculated as N * POW(10, X).

In some cases, adding zeroes at the end of a decimal number can increment the
precision of the expression where the number is used. For example, PI() by
default returns a number with 6 decimal digits. But the PI()+0.0000000000
expression (with 10 zeroes) returns a number with 10 decimal digits.

Hexadecimal literals are interpreted as numbers when used in numeric contexts.

Examples
--------

10
+10
-10

All these literals are equivalent:

0.1
.1
+0.1
+.1

With exponents:

0.2E3 -- 0.2 * POW(10, 3) = 200
.2e3
.2e+2
1.1e-10 -- 0.00000000011
-1.1e10 -- -11000000000

URL: https://mariadb.com/kb/en/numeric-iterals/https://mariadb.com/kb/en/numeric-iterals/��*String LiteralsStrings are sequences of characters and are enclosed with quotes.

The syntax is:

[_charset_name]'string' [COLLATE collation_name]

For example:

'The MariaDB Foundation'
_utf8 'Foundation' COLLATE utf8_unicode_ci;

Strings can either be enclosed in single quotes or in double quotes (the same
character must be used to both open and close the string).

The ANSI SQL-standard does not permit double quotes for enclosing strings, and
although MariaDB does by default, if the MariaDB server has enabled the
ANSI_QUOTES_SQL SQL_MODE, double quotes will be treated as being used for
identifiers instead of strings.

Strings that are next to each other are automatically concatenated. For
example:

'The ' 'MariaDB ' 'Foundation'

and

'The MariaDB Foundation'

are equivalent.

The \ (backslash character) is used to escape characters (unless the SQL_MODE
hasn't been set to NO_BACKSLASH_ESCAPES). For example:

'MariaDB's new features'

is not a valid string because of the single quote in the middle of the string,
which is treated as if it closes the string, but is actually meant as part of
the string, an apostrophe. The backslash character helps in situations like
this:

'MariaDB\'s new features'

is now a valid string, and if displayed, will appear without the backslash.

SELECT 'MariaDB\'s new features';
+------------------------+
| MariaDB's new features |
+------------------------+
| MariaDB's new features |
+------------------------+

Another way to escape the quoting character is repeating it twice:

SELECT 'I''m here', """Double""";
+----------+----------+
| I'm here | "Double" |
+----------+----------+
| I'm here | "Double" |
+----------+----------+

Escape Sequences
----------------

There are other escape sequences also. Here is a full list:

+-----------------------------------------------+-----------------------------+
| Escape sequence                               | Character                   |
+-----------------------------------------------+-----------------------------+
| \0                                            | ASCII NUL (0x00).           |
+-----------------------------------------------+-----------------------------+
| \'                                            | Single quote ("'").         |
+-----------------------------------------------+-----------------------------+
| \"                                            | Double quote (""").         |
+-----------------------------------------------+-----------------------------+
| \b                                            | Backspace.                  |
+-----------------------------------------------+-----------------------------+
| \n                                            | Newline, or linefeed,.      |
+-----------------------------------------------+-----------------------------+
| \r                                            | Carriage return.            |
+-----------------------------------------------+-----------------------------+
| \t                                            | Tab.                        |
+-----------------------------------------------+-----------------------------+
| \Z                                            | ASCII 26 (Control+Z). See   |
|                                               | note following the table.   |
+-----------------------------------------------+-----------------------------+
| \\                                            | Backslash ("\").            |
+-----------------------------------------------+-----------------------------+
| \%                                            | "%" character. See note     |
|                                               | following the table.        |
+-----------------------------------------------+-----------------------------+
| \_                                            | A "_" character. See note   |
|                                               | following the table.        |
+-----------------------------------------------+-----------------------------+

Escaping the % and _ characters can be necessary when using the LIKE operator,
which treats them as special characters.

The ASCII 26 character (\Z) needs to be escaped when included in a batch file
which needs to be executed in Windows. The reason is that ASCII 26, in
Windows, is the end of file (EOF).

Backslash (\), if not used as an escape character, must always be escaped.
When followed by a character that is not in the above table, backslashes will
simply be ignored.

URL: https://mariadb.com/kb/en/string-literals/https://mariadb.com/kb/en/string-literals/���\�J�V�Z3Table Value ConstructorsMariaDB starting with 10.3.3
----------------------------
Table Value Constructors were introduced in MariaDB 10.3.3

Syntax
------

VALUES ( row_value[, row_value...]), (...)...

Description
-----------

In Unions, Views, and sub-queries, a Table Value Constructor (TVC) allows you
to inject arbitrary values into the result-set. The given values must have the
same number of columns as the result-set, otherwise it returns Error 1222.

Examples
--------

Using TVC's with UNION operations:

CREATE TABLE test.t1 (val1 INT, val2 INT);
INSERT INTO test.t1 VALUES(5, 8), (3, 4), (1, 2);

SELECT * FROM test.t1
UNION
VALUES (70, 90), (100, 110);

+------+------+
| val1 | val2 |
+------+------+
|    5 |    8 | 
|    3 |    4 |
|    1 |    2 |
|   70 |   90 |
|  100 |  110 |
+------+------+

Using TVC's with a CREATE VIEW statement:

CREATE VIEW v1 AS VALUES (7, 9), (9, 10);

SELECT * FROM v1;
+---+----+
| 7 |  9 |
+---+----+
| 7 |  9 |
| 9 | 10 |
+---+----+

Using TVC with an ORDER BY clause:

SELECT * FROM test.t1
UNION
VALUES (10, 20), (30, 40), (50, 60), (70, 80)
ORDER BY val1 DESC;

Using TVC with LIMIT clause:

SELECT * FROM test.t1
UNION
VALUES (10, 20), (30, 40), (50, 60), (70, 80)
LIMIT 2 OFFSET 4;

+------+------+
| val1 | val2 |
+------+------+
|   30 |   40 | 
|   50 |   60 |
+------+------+

URL: https://mariadb.com/kb/en/table-value-constructors/https://mariadb.com/kb/en/table-value-constructors/��1User-Defined VariablesUser-defined variables are variables which can be created by the user and
exist in the session. This means that no one can access user-defined variables
that have been set by another user, and when the session is closed these
variables expire. However, these variables can be shared between several
queries and stored programs.

User-defined variables names must be preceded by a single at character (@).
While it is safe to use a reserved word as a user-variable name, the only
allowed characters are ASCII letters, digits, dollar sign ($), underscore (_)
and dot (.). If other characters are used, the name can be quoted in one of
the following ways:

* @`var_name`
* @'var_name'
* @"var_name"

These characters can be escaped as usual.

User-variables names are case insensitive, though they were case sensitive in
MySQL 4.1 and older versions.

User-defined variables cannot be declared. They can be read even if no value
has been set yet; in that case, they are NULL. To set a value for a
user-defined variable you can use:

* SET statement;
* := operator within a SQL statement;
* SELECT ... INTO.

Since user-defined variables type cannot be declared, the only way to force
their type is using CAST() or CONVERT():

SET @str = CAST(123 AS CHAR(5));

If a variable has not been used yet, its value is NULL:

SELECT @x IS NULL;
+------------+
| @x IS NULL |
+------------+
|          1 |
+------------+

It is unsafe to read a user-defined variable and set its value in the same
statement (unless the command is SET), because the order of these actions is
undefined.

User-defined variables can be used in most MariaDB's statements and clauses
which accept an SQL expression. However there are some exceptions, like the
LIMIT clause.

They must be used to PREPARE a prepared statement:

@sql = 'DELETE FROM my_table WHERE c>1;';
PREPARE stmt FROM @sql;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;

Another common use is to include a counter in a query:

SET @var = 0;
SELECT a, b, c, (@var:=@var+1) AS counter FROM my_table;

Information Schema
------------------

User-defined variables can be viewed in the Information Schema USER_VARIABLES
Table (as part of the User Variables plugin) from MariaDB 10.2.

Flushing User-Defined Variables
-------------------------------

User-defined variables are reset and the Information Schema table emptied with
the FLUSH USER_VARIABLES statement.

SET @str = CAST(123 AS CHAR(5));

SELECT * FROM information_schema.USER_VARIABLES ORDER BY VARIABLE_NAME;
+---------------+----------------+---------------+--------------------+
| VARIABLE_NAME | VARIABLE_VALUE | VARIABLE_TYPE | CHARACTER_SET_NAME |
+---------------+----------------+---------------+--------------------+
| str           | 123            | VARCHAR       | utf8mb3            |
+---------------+----------------+---------------+--------------------+

FLUSH USER_VARIABLES;

SELECT * FROM information_schema.USER_VARIABLES ORDER BY VARIABLE_NAME;
Empty set (0.000 sec)

URL: https://mariadb.com/kb/en/user-defined-variables/https://mariadb.com/kb/en/user-defined-variables/�
u%DelimitersThe default delimiter in the mariadb client is the semicolon.

When creating stored programs from the command-line, it is likely you will
need to differentiate between the regular delimiter and a delimiter inside a
BEGIN END block. To understand better, consider the following example:

CREATE FUNCTION FortyTwo() RETURNS TINYINT DETERMINISTIC
BEGIN
 DECLARE x TINYINT;
 SET x = 42;
 RETURN x;
END;

If you enter the above line by line, the mariadb client will treat the first
semicolon, at the end of the DECLARE x TINYINT line, as the end of the
statement. Since that's only a partial definition, it will throw a syntax
error, as follows:

CREATE FUNCTION FortyTwo() RETURNS TINYINT DETERMINISTIC
BEGIN
DECLARE x TINYINT;
ERROR 1064 (42000): You have an error in your SQL syntax; 
check the manual that corresponds to your MariaDB server version
 for the right syntax to use near '' at line 3

The solution is to specify a distinct delimiter for the duration of the
process, using the DELIMITER command. The delimiter can be any set of
characters you choose, but it needs to be a distinctive set of characters that
won't cause further confusion. // is a common choice, and used throughout the
Knowledge Base.

Here's how the function could be successfully entered from the mariadb client
with the new delimiter.

DELIMITER //

CREATE FUNCTION FortyTwo() RETURNS TINYINT DETERMINISTIC
BEGIN
 DECLARE x TINYINT;
 SET x = 42;
 RETURN x;
END

//

DELIMITER ;

At the end, the delimiter is restored to the default semicolon. The \g and \G
delimiters can always be used, even when a custom delimiter is specified.

URL: https://mariadb.com/kb/en/delimiters/https://mariadb.com/kb/en/delimiters/���)�^�qH��p&ST_CONTAINSSyntax
------

ST_CONTAINS(g1,g2)

Description
-----------

Returns 1 or 0 to indicate whether a geometry g1 completely contains geometry
g2.

ST_CONTAINS() uses object shapes, while CONTAINS(), based on the original
MySQL implementation, uses object bounding rectangles.

ST_CONTAINS tests the opposite relationship to ST_WITHIN().

Examples
--------

SET @g1 = ST_GEOMFROMTEXT('POLYGON((175 150, 20 40, 50 60, 125 100, 175
150))');

SET @g2 = ST_GEOMFROMTEXT('POINT(174 149)');

SELECT ST_CONTAINS(@g1,@g2);
+----------------------+
| ST_CONTAINS(@g1,@g2) |
+----------------------+
|                    1 |
+----------------------+

SET @g2 = ST_GEOMFROMTEXT('POINT(175 151)');

SELECT ST_CONTAINS(@g1,@g2);
+----------------------+
| ST_CONTAINS(@g1,@g2) |
+----------------------+
|                    0 |
+----------------------+

URL: https://mariadb.com/kb/en/st-contains/https://mariadb.com/kb/en/st-contains/�
�%ST_CROSSESSyntax
------

ST_CROSSES(g1,g2)

Description
-----------

Returns 1 if geometry g1 spatially crosses geometry g2. Returns NULL if g1 is
a Polygon or a MultiPolygon, or if g2 is a Point or a MultiPoint. Otherwise,
returns 0.

The term spatially crosses denotes a spatial relation between two given
geometries that has the following properties:

* The two geometries intersect
* Their intersection results in a geometry that has a dimension that is one
 less than the maximum dimension of the two given geometries
* Their intersection is not equal to either of the two given geometries

ST_CROSSES() uses object shapes, while CROSSES(), based on the original MySQL
implementation, uses object bounding rectangles.

Examples
--------

SET @g1 = ST_GEOMFROMTEXT('LINESTRING(174 149, 176 151)');

SET @g2 = ST_GEOMFROMTEXT('POLYGON((175 150, 20 40, 50 60, 125 100, 175
150))');

SELECT ST_CROSSES(@g1,@g2);
+---------------------+
| ST_CROSSES(@g1,@g2) |
+---------------------+
|                   1 |
+---------------------+

SET @g1 = ST_GEOMFROMTEXT('LINESTRING(176 149, 176 151)');

SELECT ST_CROSSES(@g1,@g2);
+---------------------+
| ST_CROSSES(@g1,@g2) |
+---------------------+
|                   0 |
+---------------------+

URL: https://mariadb.com/kb/en/st-crosses/https://mariadb.com/kb/en/st-crosses/�y&ST_DISJOINTSyntax
------

ST_DISJOINT(g1,g2)

Description
-----------

Returns 1 or 0 to indicate whether geometry g1 is spatially disjoint from
(does not intersect with) geometry g2.

ST_DISJOINT() uses object shapes, while DISJOINT(), based on the original
MySQL implementation, uses object bounding rectangles.

ST_DISJOINT() tests the opposite relationship to ST_INTERSECTS().

Examples
--------

SET @g1 = ST_GEOMFROMTEXT('POINT(0 0)');

SET @g2 = ST_GEOMFROMTEXT('LINESTRING(2 0, 0 2)');

SELECT ST_DISJOINT(@g1,@g2);
+----------------------+
| ST_DISJOINT(@g1,@g2) |
+----------------------+
|                    1 |
+----------------------+

SET @g2 = ST_GEOMFROMTEXT('LINESTRING(0 0, 0 2)');

SELECT ST_DISJOINT(@g1,@g2);
+----------------------+
| ST_DISJOINT(@g1,@g2) |
+----------------------+
|                    0 |
+----------------------+

URL: https://mariadb.com/kb/en/st_disjoint/https://mariadb.com/kb/en/st_disjoint/�	1$ST_EQUALSSyntax
------

ST_EQUALS(g1,g2)

Description
-----------

Returns 1 or 0 to indicate whether geometry g1 is spatially equal to geometry
g2.

ST_EQUALS() uses object shapes, while EQUALS(), based on the original MySQL
implementation, uses object bounding rectangles.

Examples
--------

SET @g1 = ST_GEOMFROMTEXT('LINESTRING(174 149, 176 151)');

SET @g2 = ST_GEOMFROMTEXT('LINESTRING(176 151, 174 149)');

SELECT ST_EQUALS(@g1,@g2);
+--------------------+
| ST_EQUALS(@g1,@g2) |
+--------------------+
|                  1 |
+--------------------+

SET @g1 = ST_GEOMFROMTEXT('POINT(0 2)');

SET @g1 = ST_GEOMFROMTEXT('POINT(2 0)');

SELECT ST_EQUALS(@g1,@g2);
+--------------------+
| ST_EQUALS(@g1,@g2) |
+--------------------+
|                  0 |
+--------------------+

URL: https://mariadb.com/kb/en/st-equals/https://mariadb.com/kb/en/st-equals/�
y(ST_INTERSECTSSyntax
------

ST_INTERSECTS(g1,g2)

Description
-----------

Returns 1 or 0 to indicate whether geometry g1 spatially intersects geometry
g2.

ST_INTERSECTS() uses object shapes, while INTERSECTS(), based on the original
MySQL implementation, uses object bounding rectangles.

ST_INTERSECTS() tests the opposite relationship to ST_DISJOINT().

Examples
--------

SET @g1 = ST_GEOMFROMTEXT('POINT(0 0)');

SET @g2 = ST_GEOMFROMTEXT('LINESTRING(0 0, 0 2)');

SELECT ST_INTERSECTS(@g1,@g2);
+------------------------+
| ST_INTERSECTS(@g1,@g2) |
+------------------------+
|                      1 |
+------------------------+

SET @g2 = ST_GEOMFROMTEXT('LINESTRING(2 0, 0 2)');

SELECT ST_INTERSECTS(@g1,@g2);
+------------------------+
| ST_INTERSECTS(@g1,@g2) |
+------------------------+
|                      0 |
+------------------------+

URL: https://mariadb.com/kb/en/st-intersects/https://mariadb.com/kb/en/st-intersects/��l���8��w]��
�%ST_TOUCHESSyntax
------

ST_TOUCHES(g1,g2)

Description
-----------

Returns 1 or 0 to indicate whether geometry g1 spatially touches geometry g2.
Two geometries spatially touch if the interiors of the geometries do not
intersect, but the boundary of one of the geometries intersects either the
boundary or the interior of the other.

ST_TOUCHES() uses object shapes, while TOUCHES(), based on the original MySQL
implementation, uses object bounding rectangles.

Examples
--------

SET @g1 = ST_GEOMFROMTEXT('POINT(2 0)');

SET @g2 = ST_GEOMFROMTEXT('LINESTRING(2 0, 0 2)');

SELECT ST_TOUCHES(@g1,@g2);
+---------------------+
| ST_TOUCHES(@g1,@g2) |
+---------------------+
|                   1 |
+---------------------+

SET @g1 = ST_GEOMFROMTEXT('POINT(2 1)');

SELECT ST_TOUCHES(@g1,@g2);
+---------------------+
| ST_TOUCHES(@g1,@g2) |
+---------------------+
|                   0 |
+---------------------+

URL: https://mariadb.com/kb/en/st-touches/https://mariadb.com/kb/en/st-touches/�	I$ST_WITHINSyntax
------

ST_WITHIN(g1,g2)

Description
-----------

Returns 1 or 0 to indicate whether geometry g1 is spatially within geometry g2.

This tests the opposite relationship as ST_CONTAINS().

ST_WITHIN() uses object shapes, while WITHIN(), based on the original MySQL
implementation, uses object bounding rectangles.

Examples
--------

SET @g1 = ST_GEOMFROMTEXT('POINT(174 149)');

SET @g2 = ST_GEOMFROMTEXT('POLYGON((175 150, 20 40, 50 60, 125 100, 175
150))');

SELECT ST_WITHIN(@g1,@g2);
+--------------------+
| ST_WITHIN(@g1,@g2) |
+--------------------+
|                  1 |
+--------------------+

SET @g1 = ST_GEOMFROMTEXT('POINT(176 151)');

SELECT ST_WITHIN(@g1,@g2);
+--------------------+
| ST_WITHIN(@g1,@g2) |
+--------------------+
|                  0 |
+--------------------+

URL: https://mariadb.com/kb/en/st-within/https://mariadb.com/kb/en/st-within/�!WITHINSyntax
------

Within(g1,g2)

Description
-----------

Returns 1 or 0 to indicate whether g1 is spatially within g2. This tests the
opposite relationship as Contains().

WITHIN() is based on the original MySQL implementation, and uses object
bounding rectangles, while ST_WITHIN() uses object shapes.

Examples
--------

SET @g1 = GEOMFROMTEXT('POINT(174 149)');
SET @g2 = GEOMFROMTEXT('POINT(176 151)');
SET @g3 = GEOMFROMTEXT('POLYGON((175 150, 20 40, 50 60, 125 100, 175 150))');

SELECT within(@g1,@g3);
+-----------------+
| within(@g1,@g3) |
+-----------------+
|               1 |
+-----------------+

SELECT within(@g2,@g3);
+-----------------+
| within(@g2,@g3) |
+-----------------+
|               0 |
+-----------------+

URL: https://mariadb.com/kb/en/within/https://mariadb.com/kb/en/within/�
�%ADD_MONTHSMariaDB starting with 10.6.1
----------------------------
The ADD_MONTHS function was introduced in MariaDB 10.6.1 to enhance Oracle
compatibility. Similar functionality can be achieved with the DATE_ADD
function.

Syntax
------

ADD_MONTHS(date, months)

Description
-----------

ADD_MONTHS adds an integer months to a given date (DATE, DATETIME or
TIMESTAMP), returning the resulting date.

months can be positive or negative.

The resulting day component will remain the same as that specified in date,
unless the resulting month has fewer days than the day component of the given
date, in which case the day will be the last day of the resulting month.

Returns NULL if given an invalid date, or a NULL argument.

Examples
--------

SELECT ADD_MONTHS('2012-01-31', 2);
+-----------------------------+
| ADD_MONTHS('2012-01-31', 2) |
+-----------------------------+
| 2012-03-31                  |
+-----------------------------+

SELECT ADD_MONTHS('2012-01-31', -5);
+------------------------------+
| ADD_MONTHS('2012-01-31', -5) |
+------------------------------+
| 2011-08-31                   |
+------------------------------+

SELECT ADD_MONTHS('2011-01-31', 1);
+-----------------------------+
| ADD_MONTHS('2011-01-31', 1) |
+-----------------------------+
| 2011-02-28                  |
+-----------------------------+

SELECT ADD_MONTHS('2012-01-31', 1);
+-----------------------------+
| ADD_MONTHS('2012-01-31', 1) |
+-----------------------------+
| 2012-02-29                  |
+-----------------------------+

SELECT ADD_MONTHS('2012-01-31', 2);
+-----------------------------+
| ADD_MONTHS('2012-01-31', 2) |
+-----------------------------+
| 2012-03-31                  |
+-----------------------------+

SELECT ADD_MONTHS('2012-01-31', 3);
+-----------------------------+
| ADD_MONTHS('2012-01-31', 3) |
+-----------------------------+
| 2012-04-30                  |
+-----------------------------+

URL: https://mariadb.com/kb/en/add_months/https://mariadb.com/kb/en/add_months/�	"ADDDATESyntax
------

ADDDATE(date,INTERVAL expr unit), ADDDATE(expr,days)

Description
-----------

When invoked with the INTERVAL form of the second argument, ADDDATE() is a
synonym for DATE_ADD(). The related function SUBDATE() is a synonym for
DATE_SUB(). For information on the INTERVAL unit argument, see the discussion
for DATE_ADD().

When invoked with the days form of the second argument, MariaDB treats it as
an integer number of days to be added to expr.

Examples
--------

SELECT DATE_ADD('2008-01-02', INTERVAL 31 DAY);
+-----------------------------------------+
| DATE_ADD('2008-01-02', INTERVAL 31 DAY) |
+-----------------------------------------+
| 2008-02-02                              |
+-----------------------------------------+

SELECT ADDDATE('2008-01-02', INTERVAL 31 DAY);
+----------------------------------------+
| ADDDATE('2008-01-02', INTERVAL 31 DAY) |
+----------------------------------------+
| 2008-02-02                             |
+----------------------------------------+

SELECT ADDDATE('2008-01-02', 31);
+---------------------------+
| ADDDATE('2008-01-02', 31) |
+---------------------------+
| 2008-02-02                |
+---------------------------+

CREATE TABLE t1 (d DATETIME);
INSERT INTO t1 VALUES
  ("2007-01-30 21:31:07"),
  ("1983-10-15 06:42:51"),
  ("2011-04-21 12:34:56"),
  ("2011-10-30 06:31:41"),
  ("2011-01-30 14:03:25"),
  ("2004-10-07 11:19:34");

SELECT d, ADDDATE(d, 10) from t1;
+---------------------+---------------------+
| d                   | ADDDATE(d, 10)      |
+---------------------+---------------------+
| 2007-01-30 21:31:07 | 2007-02-09 21:31:07 |
| 1983-10-15 06:42:51 | 1983-10-25 06:42:51 |
| 2011-04-21 12:34:56 | 2011-05-01 12:34:56 |
| 2011-10-30 06:31:41 | 2011-11-09 06:31:41 |
| 2011-01-30 14:03:25 | 2011-02-09 14:03:25 |
| 2004-10-07 11:19:34 | 2004-10-17 11:19:34 |
+---------------------+---------------------+

SELECT d, ADDDATE(d, INTERVAL 10 HOUR) from t1;
+---------------------+------------------------------+
| d                   | ADDDATE(d, INTERVAL 10 HOUR) |
+---------------------+------------------------------+
| 2007-01-30 21:31:07 | 2007-01-31 07:31:07          |
| 1983-10-15 06:42:51 | 1983-10-15 16:42:51          |
| 2011-04-21 12:34:56 | 2011-04-21 22:34:56          |
| 2011-10-30 06:31:41 | 2011-10-30 16:31:41          |
| 2011-01-30 14:03:25 | 2011-01-31 00:03:25          |
| 2004-10-07 11:19:34 | 2004-10-07 21:19:34          |
+---------------------+------------------------------+

URL: https://mariadb.com/kb/en/adddate/https://mariadb.com/kb/en/adddate/�(
�
��9����x_��
�D2Microseconds in MariaDBThe TIME, DATETIME, and TIMESTAMP types, along with the temporal functions,
CAST and dynamic columns, support microseconds. The datetime precision of a
column can be specified when creating the table with CREATE TABLE, for example:

CREATE TABLE example(
 col_microsec DATETIME(6),
 col_millisec TIME(3)
);

Generally, the precision can be specified for any TIME, DATETIME, or TIMESTAMP
column, in parentheses, after the type name. The datetime precision specifies
number of digits after the decimal dot and can be any integer number from 0 to
6. If no precision is specified it is assumed to be 0, for backward
compatibility reasons.

A datetime precision can be specified wherever a type name is used. For
example:

* when declaring arguments of stored routines.
* when specifying a return type of a stored function.
* when declaring variables.
* in a CAST function:create function example(x datetime(5)) returns time(4)
begin
 declare y timestamp(6);
 return cast(x as time(2));
end;

%f is used as the formatting option for microseconds in the STR_TO_DATE,
DATE_FORMAT and FROM_UNIXTIME functions, for example:

SELECT STR_TO_DATE('20200809 020917076','%Y%m%d %H%i%s%f');
+-----------------------------------------------------+
| STR_TO_DATE('20200809 020917076','%Y%m%d %H%i%s%f') |
+-----------------------------------------------------+
| 2020-08-09 02:09:17.076000                          |
+-----------------------------------------------------+

Additional Information
----------------------

* when comparing anything to a temporal value (DATETIME, TIME, DATE, or
TIMESTAMP), both values are compared as temporal values, not as strings.
* The INFORMATION_SCHEMA.COLUMNS table has a new column DATETIME_PRECISION
* NOW(), CURTIME(), UTC_TIMESTAMP(), UTC_TIME(), CURRENT_TIME(),
CURRENT_TIMESTAMP(), LOCALTIME() and LOCALTIMESTAMP() now accept datetime
precision as an optional argument. For example:SELECT CURTIME(4);
--> 10:11:12.3456

* TIME_TO_SEC() and UNIX_TIMESTAMP() preserve microseconds of the argument.
These functions will return a decimal number if the result non-zero datetime
precision and an integer otherwise (for backward compatibility).SELECT
TIME_TO_SEC('10:10:10.12345');
--> 36610.12345

* Current versions of this patch fix a bug in the following optimization: in
 certain queries with DISTINCT MariaDB can ignore this clause if it can
 prove that all result rows are unique anyway, for example, when a primary key
 is compared with a constant. Sometimes this optimization was applied
 incorrectly, though — for example, when comparing a
 string with a date constant. This is now fixed.
* DATE_ADD() and DATE_SUB() functions can now take a TIME
 expression as an argument (not just DATETIME as before).SELECT
TIME('10:10:10') + INTERVAL 100 MICROSECOND;
--> 10:10:10.000100

* The event_time field in the mysql.general_log table and the start_time,
query_time, and lock_time fields in the mysql.slow_log table now store values
with microsecond precision.
* This patch fixed a bug when comparing a temporal value using the BETWEEN
operator and one of the operands is NULL.
* The old syntax TIMESTAMP(N), where N is the display width, is no longer
supported. It was deprecated in MySQL 4.1.0 (released on
 2003-04-03).
* when a DATETIME value is compared to a TIME value, the latter is treated as
a full datetime with a zero date part, similar to comparing DATE to a
DATETIME, or to comparing DECIMAL numbers.
 Earlier versions of MariaDB used to compare only the time part of both
operands in such a case.
* In MariaDB, an extra column TIME_MS has been added to the
INFORMATION_SCHEMA.PROCESSLIST table, as well as to the output of SHOW FULL
PROCESSLIST.

Note: When you convert a temporal value to a value with a smaller precision,
it will be truncated, not rounded. This is done to guarantee that the date
part is not changed. For example:

SELECT CAST('2009-12-31 23:59:59.998877' as DATETIME(3));
-> 2009-12-31 23:59:59.998

MySQL 5.6 Microseconds
----------------------

MySQL 5.6 introduced microseconds using a slightly different implementation to
MariaDB 5.3. Since MariaDB 10.1, MariaDB has defaulted to the MySQL format, by
means of the --mysql56-temporal-format variable. The MySQL version requires
slightly more storage but has some advantages in permitting the eventual
support of negative dates, and in replication.

URL: https://mariadb.com/kb/en/microseconds-in-mariadb/https://mariadb.com/kb/en/microseconds-in-mariadb/�"ADDTIMESyntax
------

ADDTIME(expr1,expr2)

Description
-----------

ADDTIME() adds expr2 to expr1 and returns the result. expr1 is a time or
datetime expression, and expr2 is a time expression.

Examples
--------

SELECT ADDTIME('2007-12-31 23:59:59.999999', '1 1:1:1.000002');
+---------------------------------------------------------+
| ADDTIME('2007-12-31 23:59:59.999999', '1 1:1:1.000002') |
+---------------------------------------------------------+
| 2008-01-02 01:01:01.000001                              |
+---------------------------------------------------------+

SELECT ADDTIME('01:00:00.999999', '02:00:00.999998');
+-----------------------------------------------+
| ADDTIME('01:00:00.999999', '02:00:00.999998') |
+-----------------------------------------------+
| 03:00:01.999997                               |
+-----------------------------------------------+

URL: https://mariadb.com/kb/en/addtime/https://mariadb.com/kb/en/addtime/����7k��0��.Date and Time UnitsThe INTERVAL keyword can be used to add or subtract a time interval of time to
a DATETIME, DATE or TIME value.

The syntax is:

INTERVAL time_quantity time_unit

For example, the SECOND unit is used below by the DATE_ADD() function:

SELECT '2008-12-31 23:59:59' + INTERVAL 1 SECOND;
+-------------------------------------------+
| '2008-12-31 23:59:59' + INTERVAL 1 SECOND |
+-------------------------------------------+
| 2009-01-01 00:00:00                       |
+-------------------------------------------+

The following units are valid:

+---------------------+------------------------------------------------------+
| Unit                | Description                                          |
+---------------------+------------------------------------------------------+
| MICROSECOND         | Microseconds                                         |
+---------------------+------------------------------------------------------+
| SECOND              | Seconds                                              |
+---------------------+------------------------------------------------------+
| MINUTE              | Minutes                                              |
+---------------------+------------------------------------------------------+
| HOUR                | Hours                                                |
+---------------------+------------------------------------------------------+
| DAY                 | Days                                                 |
+---------------------+------------------------------------------------------+
| WEEK                | Weeks                                                |
+---------------------+------------------------------------------------------+
| MONTH               | Months                                               |
+---------------------+------------------------------------------------------+
| QUARTER             | Quarters                                             |
+---------------------+------------------------------------------------------+
| YEAR                | Years                                                |
+---------------------+------------------------------------------------------+
| SECOND_MICROSECOND  | Seconds.Microseconds                                 |
+---------------------+------------------------------------------------------+
| MINUTE_MICROSECOND  | Minutes.Seconds.Microseconds                         |
+---------------------+------------------------------------------------------+
| MINUTE_SECOND       | Minutes.Seconds                                      |
+---------------------+------------------------------------------------------+
| HOUR_MICROSECOND    | Hours.Minutes.Seconds.Microseconds                   |
+---------------------+------------------------------------------------------+
| HOUR_SECOND         | Hours.Minutes.Seconds                                |
+---------------------+------------------------------------------------------+
| HOUR_MINUTE         | Hours.Minutes                                        |
+---------------------+------------------------------------------------------+
| DAY_MICROSECOND     | Days Hours.Minutes.Seconds.Microseconds              |
+---------------------+------------------------------------------------------+
| DAY_SECOND          | Days Hours.Minutes.Seconds                           |
+---------------------+------------------------------------------------------+
| DAY_MINUTE          | Days Hours.Minutes                                   |
+---------------------+------------------------------------------------------+
| DAY_HOUR            | Days Hours                                           |
+---------------------+------------------------------------------------------+
| YEAR_MONTH          | Years-Months                                         |
+---------------------+------------------------------------------------------+

The time units containing an underscore are composite; that is, they consist
of multiple base time units. For base time units, time_quantity is an integer
number. For composite units, the quantity must be expressed as a string with
multiple integer numbers separated by any punctuation character.

Example of composite units:

INTERVAL '2:2' YEAR_MONTH
INTERVAL '1:30:30' HOUR_SECOND
INTERVAL '1!30!30' HOUR_SECOND -- same as above

Time units can be used in the following contexts:

* after a + or a - operator;
* with the following DATE or TIME functions: ADDDATE(), SUBDATE(), DATE_ADD(),
DATE_SUB(), TIMESTAMPADD(), TIMESTAMPDIFF(), EXTRACT();
* in the ON SCHEDULE clause of CREATE EVENT and ALTER EVENT.
* when defining a partitioning BY SYSTEM_TIME

URL: https://mariadb.com/kb/en/date-and-time-units/https://mariadb.com/kb/en/date-and-time-units/
�%CONVERT_TZSyntax
------

CONVERT_TZ(dt,from_tz,to_tz)

Description
-----------

CONVERT_TZ() converts a datetime value dt from the time zone given by from_tz
to the time zone given by to_tz and returns the resulting value.

In order to use named time zones, such as GMT, MET or Africa/Johannesburg, the
time_zone tables must be loaded (see mysql_tzinfo_to_sql).

No conversion will take place if the value falls outside of the supported
TIMESTAMP range ('1970-01-01 00:00:01' to '2038-01-19 05:14:07' UTC) when
converted from from_tz to UTC.

This function returns NULL if the arguments are invalid (or named time zones
have not been loaded).

See time zones for more information.

Examples
--------

SELECT CONVERT_TZ('2016-01-01 12:00:00','+00:00','+10:00');
+-----------------------------------------------------+
| CONVERT_TZ('2016-01-01 12:00:00','+00:00','+10:00') |
+-----------------------------------------------------+
| 2016-01-01 22:00:00                                 |
+-----------------------------------------------------+

Using named time zones (with the time zone tables loaded):

SELECT CONVERT_TZ('2016-01-01 12:00:00','GMT','Africa/Johannesburg');
+---------------------------------------------------------------+
| CONVERT_TZ('2016-01-01 12:00:00','GMT','Africa/Johannesburg') |
+---------------------------------------------------------------+
| 2016-01-01 14:00:00                                           |
+---------------------------------------------------------------+

The value is out of the TIMESTAMP range, so no conversion takes place:

SELECT CONVERT_TZ('1969-12-31 22:00:00','+00:00','+10:00');
+-----------------------------------------------------+
| CONVERT_TZ('1969-12-31 22:00:00','+00:00','+10:00') |
+-----------------------------------------------------+
| 1969-12-31 22:00:00                                 |
+-----------------------------------------------------+

URL: https://mariadb.com/kb/en/convert_tz/https://mariadb.com/kb/en/convert_tz/������c��5"CURDATESyntax
------

CURDATE()
CURRENT_DATE
CURRENT_DATE()

Description
-----------

CURDATE returns the current date as a value in 'YYYY-MM-DD' or YYYYMMDD
format, depending on whether the function is used in a string or numeric
context.

CURRENT_DATE and CURRENT_DATE() are synonyms.

Examples
--------

SELECT CURDATE();
+------------+
| CURDATE()  |
+------------+
| 2019-03-05 |
+------------+

In a numeric context (note this is not performing date calculations):

SELECT CURDATE() +0;
+--------------+
| CURDATE() +0 |
+--------------+
|     20190305 |
+--------------+

Data calculation:

SELECT CURDATE() - INTERVAL 5 DAY;
+----------------------------+
| CURDATE() - INTERVAL 5 DAY |
+----------------------------+
| 2019-02-28                 |
+----------------------------+

URL: https://mariadb.com/kb/en/curdate/https://mariadb.com/kb/en/curdate/	�#DATEDIFFSyntax
------

DATEDIFF(expr1,expr2)

Description
-----------

DATEDIFF() returns (expr1 – expr2) expressed as a value in days from one date
to the other. expr1 and expr2 are date or date-and-time expressions. Only the
date parts of the values are used in the calculation.

Examples
--------

SELECT DATEDIFF('2007-12-31 23:59:59','2007-12-30');
+----------------------------------------------+
| DATEDIFF('2007-12-31 23:59:59','2007-12-30') |
+----------------------------------------------+
|                                            1 |
+----------------------------------------------+

SELECT DATEDIFF('2010-11-30 23:59:59','2010-12-31');
+----------------------------------------------+
| DATEDIFF('2010-11-30 23:59:59','2010-12-31') |
+----------------------------------------------+
|                                          -31 |
+----------------------------------------------+

CREATE TABLE t1 (d DATETIME);
INSERT INTO t1 VALUES
  ("2007-01-30 21:31:07"),
  ("1983-10-15 06:42:51"),
  ("2011-04-21 12:34:56"),
  ("2011-10-30 06:31:41"),
  ("2011-01-30 14:03:25"),
  ("2004-10-07 11:19:34");

SELECT NOW();
+---------------------+
| NOW()               |
+---------------------+
| 2011-05-23 10:56:05 |
+---------------------+

SELECT d, DATEDIFF(NOW(),d) FROM t1;
+---------------------+-------------------+
| d                   | DATEDIFF(NOW(),d) |
+---------------------+-------------------+
| 2007-01-30 21:31:07 |              1574 |
| 1983-10-15 06:42:51 |             10082 |
| 2011-04-21 12:34:56 |                32 |
| 2011-10-30 06:31:41 |              -160 |
| 2011-01-30 14:03:25 |               113 |
| 2004-10-07 11:19:34 |              2419 |
+---------------------+-------------------+

URL: https://mariadb.com/kb/en/datediff/https://mariadb.com/kb/en/datediff/
#DATE_ADDSyntax
------

DATE_ADD(date,INTERVAL expr unit)

Description
-----------

Performs date arithmetic. The date argument specifies the starting date or
datetime value. expr is an expression specifying the interval value to be
added or subtracted from the starting date. expr is a string; it may start
with a "-" for negative intervals. unit is a keyword indicating the units in
which the expression should be interpreted. See Date and Time Units for a
complete list of permitted units.

Examples
--------

SELECT '2008-12-31 23:59:59' + INTERVAL 1 SECOND;
+-------------------------------------------+
| '2008-12-31 23:59:59' + INTERVAL 1 SECOND |
+-------------------------------------------+
| 2009-01-01 00:00:00                       |
+-------------------------------------------+

SELECT INTERVAL 1 DAY + '2008-12-31';
+-------------------------------+
| INTERVAL 1 DAY + '2008-12-31' |
+-------------------------------+
| 2009-01-01                    |
+-------------------------------+

SELECT '2005-01-01' - INTERVAL 1 SECOND;
+----------------------------------+
| '2005-01-01' - INTERVAL 1 SECOND |
+----------------------------------+
| 2004-12-31 23:59:59              |
+----------------------------------+

SELECT DATE_ADD('2000-12-31 23:59:59', INTERVAL 1 SECOND);
+----------------------------------------------------+
| DATE_ADD('2000-12-31 23:59:59', INTERVAL 1 SECOND) |
+----------------------------------------------------+
| 2001-01-01 00:00:00                                |
+----------------------------------------------------+

SELECT DATE_ADD('2010-12-31 23:59:59', INTERVAL 1 DAY);
+-------------------------------------------------+
| DATE_ADD('2010-12-31 23:59:59', INTERVAL 1 DAY) |
+-------------------------------------------------+
| 2011-01-01 23:59:59                             |
+-------------------------------------------------+

SELECT DATE_ADD('2100-12-31 23:59:59', INTERVAL '1:1' MINUTE_SECOND);
+---------------------------------------------------------------+
| DATE_ADD('2100-12-31 23:59:59', INTERVAL '1:1' MINUTE_SECOND) |
+---------------------------------------------------------------+
| 2101-01-01 00:01:00                                           |
+---------------------------------------------------------------+

SELECT DATE_ADD('1900-01-01 00:00:00', INTERVAL '-1 10' DAY_HOUR);
+------------------------------------------------------------+
| DATE_ADD('1900-01-01 00:00:00', INTERVAL '-1 10' DAY_HOUR) |
+------------------------------------------------------------+
| 1899-12-30 14:00:00                                        |
+------------------------------------------------------------+

SELECT DATE_ADD('1992-12-31 23:59:59.000002', INTERVAL '1.999999'
SECOND_MICROSECOND);
+------------------------------------------------------------------------------
-+
| DATE_ADD('1992-12-31 23:59:59.000002', INTERVAL '1.999999'
SECOND_MICROSECOND) |
+------------------------------------------------------------------------------
-+
| 1993-01-01 00:00:01.000001                                                  
 |
+------------------------------------------------------------------------------
-+

URL: https://mariadb.com/kb/en/date_add/https://mariadb.com/kb/en/date_add/�
�xl5�"����#DATE_SUBSyntax
------

DATE_SUB(date,INTERVAL expr unit)

Description
-----------

Performs date arithmetic. The date argument specifies the starting date or
datetime value. expr is an expression specifying the interval value to be
added or subtracted from the starting date. expr is a string; it may start
with a "-" for negative intervals. unit is a keyword indicating the units in
which the expression should be interpreted. See Date and Time Units for a
complete list of permitted units.

See also DATE_ADD().

Examples
--------

SELECT DATE_SUB('1998-01-02', INTERVAL 31 DAY);
+-----------------------------------------+
| DATE_SUB('1998-01-02', INTERVAL 31 DAY) |
+-----------------------------------------+
| 1997-12-02                              |
+-----------------------------------------+

SELECT DATE_SUB('2005-01-01 00:00:00', INTERVAL '1 1:1:1' DAY_SECOND);
+----------------------------------------------------------------+
| DATE_SUB('2005-01-01 00:00:00', INTERVAL '1 1:1:1' DAY_SECOND) |
+----------------------------------------------------------------+
| 2004-12-30 22:58:59                                            |
+----------------------------------------------------------------+

URL: https://mariadb.com/kb/en/date_sub/https://mariadb.com/kb/en/date_sub/"DAYNAMESyntax
------

DAYNAME(date)

Description
-----------

Returns the name of the weekday for date. The language used for the name is
controlled by the value of the lc_time_names system variable. See server
locale for more on the supported locales.

Examples
--------

SELECT DAYNAME('2007-02-03');
+-----------------------+
| DAYNAME('2007-02-03') |
+-----------------------+
| Saturday              |
+-----------------------+

CREATE TABLE t1 (d DATETIME);
INSERT INTO t1 VALUES
  ("2007-01-30 21:31:07"),
  ("1983-10-15 06:42:51"),
  ("2011-04-21 12:34:56"),
  ("2011-10-30 06:31:41"),
  ("2011-01-30 14:03:25"),
  ("2004-10-07 11:19:34");

SELECT d, DAYNAME(d) FROM t1;
+---------------------+------------+
| d                   | DAYNAME(d) |
+---------------------+------------+
| 2007-01-30 21:31:07 | Tuesday    |
| 1983-10-15 06:42:51 | Saturday   |
| 2011-04-21 12:34:56 | Thursday   |
| 2011-10-30 06:31:41 | Sunday     |
| 2011-01-30 14:03:25 | Sunday     |
| 2004-10-07 11:19:34 | Thursday   |
+---------------------+------------+

Changing the locale:

SET lc_time_names = 'fr_CA';

SELECT DAYNAME('2013-04-01');
+-----------------------+
| DAYNAME('2013-04-01') |
+-----------------------+
| lundi                 |
+-----------------------+

URL: https://mariadb.com/kb/en/dayname/https://mariadb.com/kb/en/dayname/
x%DAYOFMONTHSyntax
------

DAYOFMONTH(date)

Description
-----------

Returns the day of the month for date, in the range 1 to 31, or 0 for dates
such as '0000-00-00' or '2008-00-00' which have a zero day part.

DAY() is a synonym.

Examples
--------

SELECT DAYOFMONTH('2007-02-03');
+--------------------------+
| DAYOFMONTH('2007-02-03') |
+--------------------------+
|                        3 |
+--------------------------+

CREATE TABLE t1 (d DATETIME);
INSERT INTO t1 VALUES
  ("2007-01-30 21:31:07"),
  ("1983-10-15 06:42:51"),
  ("2011-04-21 12:34:56"),
  ("2011-10-30 06:31:41"),
  ("2011-01-30 14:03:25"),
  ("2004-10-07 11:19:34");

SELECT d FROM t1 where DAYOFMONTH(d) = 30;
+---------------------+
| d                   |
+---------------------+
| 2007-01-30 21:31:07 |
| 2011-10-30 06:31:41 |
| 2011-01-30 14:03:25 |
+---------------------+

URL: https://mariadb.com/kb/en/dayofmonth/https://mariadb.com/kb/en/dayofmonth/	�$DAYOFWEEKSyntax
------

DAYOFWEEK(date)

Description
-----------

Returns the day of the week index for the date (1 = Sunday, 2 = Monday, ..., 7
= Saturday). These index values correspond to the ODBC standard.

This contrasts with WEEKDAY() which follows a different index numbering (0 =
Monday, 1 = Tuesday, ... 6 = Sunday).

Examples
--------

SELECT DAYOFWEEK('2007-02-03');
+-------------------------+
| DAYOFWEEK('2007-02-03') |
+-------------------------+
|                       7 |
+-------------------------+

CREATE TABLE t1 (d DATETIME);
INSERT INTO t1 VALUES
  ("2007-01-30 21:31:07"),
  ("1983-10-15 06:42:51"),
  ("2011-04-21 12:34:56"),
  ("2011-10-30 06:31:41"),
  ("2011-01-30 14:03:25"),
  ("2004-10-07 11:19:34");

SELECT d, DAYNAME(d), DAYOFWEEK(d), WEEKDAY(d) from t1;
+---------------------+------------+--------------+------------+
| d                   | DAYNAME(d) | DAYOFWEEK(d) | WEEKDAY(d) |
+---------------------+------------+--------------+------------+
| 2007-01-30 21:31:07 | Tuesday    |            3 |          1 |
| 1983-10-15 06:42:51 | Saturday   |            7 |          5 |
| 2011-04-21 12:34:56 | Thursday   |            5 |          3 |
| 2011-10-30 06:31:41 | Sunday     |            1 |          6 |
| 2011-01-30 14:03:25 | Sunday     |            1 |          6 |
| 2004-10-07 11:19:34 | Thursday   |            5 |          3 |
+---------------------+------------+--------------+------------+

URL: https://mariadb.com/kb/en/dayofweek/https://mariadb.com/kb/en/dayofweek/�e
�F����Y7	"EXTRACTSyntax
------

EXTRACT(unit FROM date)

Description
-----------

The EXTRACT() function extracts the required unit from the date. See Date and
Time Units for a complete list of permitted units.

In MariaDB 10.0.7 and MariaDB 5.5.35, EXTRACT (HOUR FROM ...) was changed to
return a value from 0 to 23, adhering to the SQL standard. Until MariaDB
10.0.6 and MariaDB 5.5.34, and in all versions of MySQL at least as of MySQL
5.7, it could return a value > 23. HOUR() is not a standard function, so
continues to adhere to the old behaviour inherited from MySQL.

Examples
--------

SELECT EXTRACT(YEAR FROM '2009-07-02');
+---------------------------------+
| EXTRACT(YEAR FROM '2009-07-02') |
+---------------------------------+
|                            2009 |
+---------------------------------+

SELECT EXTRACT(YEAR_MONTH FROM '2009-07-02 01:02:03');
+------------------------------------------------+
| EXTRACT(YEAR_MONTH FROM '2009-07-02 01:02:03') |
+------------------------------------------------+
|                                         200907 |
+------------------------------------------------+

SELECT EXTRACT(DAY_MINUTE FROM '2009-07-02 01:02:03');
+------------------------------------------------+
| EXTRACT(DAY_MINUTE FROM '2009-07-02 01:02:03') |
+------------------------------------------------+
|                                          20102 |
+------------------------------------------------+

SELECT EXTRACT(MICROSECOND FROM '2003-01-02 10:30:00.000123');
+--------------------------------------------------------+
| EXTRACT(MICROSECOND FROM '2003-01-02 10:30:00.000123') |
+--------------------------------------------------------+
|                                                    123 |
+--------------------------------------------------------+

From MariaDB 10.0.7 and MariaDB 5.5.35, EXTRACT (HOUR FROM...) returns a value
from 0 to 23, as per the SQL standard. HOUR is not a standard function, so
continues to adhere to the old behaviour inherited from MySQL.

SELECT EXTRACT(HOUR FROM '26:30:00'), HOUR('26:30:00');
+-------------------------------+------------------+
| EXTRACT(HOUR FROM '26:30:00') | HOUR('26:30:00') |
+-------------------------------+------------------+
|                             2 |               26 |
+-------------------------------+------------------+

URL: https://mariadb.com/kb/en/extract/https://mariadb.com/kb/en/extract/y+FORMAT_PICO_TIMEMariaDB starting with 11.0.2
----------------------------
Introduced in MariaDB 11.0.2

Syntax
------

FORMAT_PICO_TIME(time_val)

Description
-----------

Given a time in picoseconds, returns a human-readable time value and unit
indicator. Resulting unit is dependent on the length of the argument, and can
be:

* ps - picoseconds
* ns - nanoseconds
* us - microseconds
* ms - milliseconds
* s - seconds
* min - minutes
* h - hours
* d - days

With the exception of results under one nanosecond, which are not rounded and
are represented as whole numbers, the result is rounded to 2 decimal places,
with a minimum of 3 significant digits.

Returns NULL if the argument is NULL.

This function is very similar to the Sys Schema FORMAT_TIME function, but with
the following differences:

* Represents minutes as min rather than m.
* Does not represent weeks.

Examples
--------

SELECT
  FORMAT_PICO_TIME(43) AS ps,
  FORMAT_PICO_TIME(4321) AS ns,
  FORMAT_PICO_TIME(43211234) AS us,
  FORMAT_PICO_TIME(432112344321) AS ms,
  FORMAT_PICO_TIME(43211234432123) AS s,
  FORMAT_PICO_TIME(432112344321234) AS m,
  FORMAT_PICO_TIME(4321123443212345) AS h,
  FORMAT_PICO_TIME(432112344321234545) AS d;
+--------+---------+----------+-----------+---------+----------+--------+------
-+
| ps     | ns      | us       | ms        | s       | m        | h      | d   
 |
+--------+---------+----------+-----------+---------+----------+--------+------
-+
|  43 ps | 4.32 ns | 43.21 us | 432.11 ms | 43.21 s | 7.20 min | 1.20 h | 5.00
d |
+--------+---------+----------+-----------+---------+----------+--------+------
-+

URL: https://mariadb.com/kb/en/format_pico_time/https://mariadb.com/kb/en/format_pico_time/*HOURSyntax
------

HOUR(time)

Description
-----------

Returns the hour for time. The range of the return value is 0 to 23 for
time-of-day values. However, the range of TIME values actually is much larger,
so HOUR can return values greater than 23.

The return value is always positive, even if a negative TIME value is provided.

Examples
--------

SELECT HOUR('10:05:03');
+------------------+
| HOUR('10:05:03') |
+------------------+
|               10 |
+------------------+

SELECT HOUR('272:59:59');
+-------------------+
| HOUR('272:59:59') |
+-------------------+
|               272 |
+-------------------+

Difference between EXTRACT (HOUR FROM ...) (>= MariaDB 10.0.7 and MariaDB
5.5.35) and HOUR:

SELECT EXTRACT(HOUR FROM '26:30:00'), HOUR('26:30:00');
+-------------------------------+------------------+
| EXTRACT(HOUR FROM '26:30:00') | HOUR('26:30:00') |
+-------------------------------+------------------+
|                             2 |               26 |
+-------------------------------+------------------+

URL: https://mariadb.com/kb/en/hour/https://mariadb.com/kb/en/hour/<[z	�n	ُ�K�
6%GET_FORMATSyntax
------

GET_FORMAT({DATE|DATETIME|TIME}, {'EUR'|'USA'|'JIS'|'ISO'|'INTERNAL'})

Description
-----------

Returns a format string. This function is useful in combination with the
DATE_FORMAT() and the STR_TO_DATE() functions.

Possible result formats are:

+--------------------------------------+--------------------------------------+
| Function Call                        | Result Format                        |
+--------------------------------------+--------------------------------------+
| GET_FORMAT(DATE,'EUR')               | '%d.%m.%Y'                           |
+--------------------------------------+--------------------------------------+
| GET_FORMAT(DATE,'USA')               | '%m.%d.%Y'                           |
+--------------------------------------+--------------------------------------+
| GET_FORMAT(DATE,'JIS')               | '%Y-%m-%d'                           |
+--------------------------------------+--------------------------------------+
| GET_FORMAT(DATE,'ISO')               | '%Y-%m-%d'                           |
+--------------------------------------+--------------------------------------+
| GET_FORMAT(DATE,'INTERNAL')          | '%Y%m%d'                             |
+--------------------------------------+--------------------------------------+
| GET_FORMAT(DATETIME,'EUR')           | '%Y-%m-%d %H.%i.%s'                  |
+--------------------------------------+--------------------------------------+
| GET_FORMAT(DATETIME,'USA')           | '%Y-%m-%d %H.%i.%s'                  |
+--------------------------------------+--------------------------------------+
| GET_FORMAT(DATETIME,'JIS')           | '%Y-%m-%d %H:%i:%s'                  |
+--------------------------------------+--------------------------------------+
| GET_FORMAT(DATETIME,'ISO')           | '%Y-%m-%d %H:%i:%s'                  |
+--------------------------------------+--------------------------------------+
| GET_FORMAT(DATETIME,'INTERNAL')      | '%Y%m%d%H%i%s'                       |
+--------------------------------------+--------------------------------------+
| GET_FORMAT(TIME,'EUR')               | '%H.%i.%s'                           |
+--------------------------------------+--------------------------------------+
| GET_FORMAT(TIME,'USA')               | '%h:%i:%s %p'                        |
+--------------------------------------+--------------------------------------+
| GET_FORMAT(TIME,'JIS')               | '%H:%i:%s'                           |
+--------------------------------------+--------------------------------------+
| GET_FORMAT(TIME,'ISO')               | '%H:%i:%s'                           |
+--------------------------------------+--------------------------------------+
| GET_FORMAT(TIME,'INTERNAL')          | '%H%i%s'                             |
+--------------------------------------+--------------------------------------+

Examples
--------

Obtaining the string matching to the standard European date format:

SELECT GET_FORMAT(DATE, 'EUR');
+-------------------------+
| GET_FORMAT(DATE, 'EUR') |
+-------------------------+
| %d.%m.%Y                |
+-------------------------+

Using the same string to format a date:

SELECT DATE_FORMAT('2003-10-03',GET_FORMAT(DATE,'EUR'));
+--------------------------------------------------+
| DATE_FORMAT('2003-10-03',GET_FORMAT(DATE,'EUR')) |
+--------------------------------------------------+
| 03.10.2003                                       |
+--------------------------------------------------+

SELECT STR_TO_DATE('10.31.2003',GET_FORMAT(DATE,'USA'));
+--------------------------------------------------+
| STR_TO_DATE('10.31.2003',GET_FORMAT(DATE,'USA')) |
+--------------------------------------------------+
| 2003-10-31                                       |
+--------------------------------------------------+

URL: https://mariadb.com/kb/en/get_format/https://mariadb.com/kb/en/get_format/1#LAST_DAYSyntax
------

LAST_DAY(date)

Description
-----------

Takes a date or datetime value and returns the corresponding value for the
last day of the month. Returns NULL if the argument is invalid.

Examples
--------

SELECT LAST_DAY('2003-02-05');
+------------------------+
| LAST_DAY('2003-02-05') |
+------------------------+
| 2003-02-28             |
+------------------------+

SELECT LAST_DAY('2004-02-05');
+------------------------+
| LAST_DAY('2004-02-05') |
+------------------------+
| 2004-02-29             |
+------------------------+

SELECT LAST_DAY('2004-01-01 01:01:01');
+---------------------------------+
| LAST_DAY('2004-01-01 01:01:01') |
+---------------------------------+
| 2004-01-31                      |
+---------------------------------+

SELECT LAST_DAY('2003-03-32');
+------------------------+
| LAST_DAY('2003-03-32') |
+------------------------+
| NULL                   |
+------------------------+
1 row in set, 1 warning (0.00 sec)

Warning (Code 1292): Incorrect datetime value: '2003-03-32'

URL: https://mariadb.com/kb/en/last_day/https://mariadb.com/kb/en/last_day/js��HX�x#MAKEDATESyntax
------

MAKEDATE(year,dayofyear)

Description
-----------

Returns a date, given year and day-of-year values. dayofyear must be greater
than 0 or the result is NULL.

Examples
--------

SELECT MAKEDATE(2011,31), MAKEDATE(2011,32);
+-------------------+-------------------+
| MAKEDATE(2011,31) | MAKEDATE(2011,32) |
+-------------------+-------------------+
| 2011-01-31        | 2011-02-01        |
+-------------------+-------------------+

SELECT MAKEDATE(2011,365), MAKEDATE(2014,365);
+--------------------+--------------------+
| MAKEDATE(2011,365) | MAKEDATE(2014,365) |
+--------------------+--------------------+
| 2011-12-31         | 2014-12-31         |
+--------------------+--------------------+

SELECT MAKEDATE(2011,0);
+------------------+
| MAKEDATE(2011,0) |
+------------------+
| NULL             |
+------------------+

URL: https://mariadb.com/kb/en/makedate/https://mariadb.com/kb/en/makedate/L#MAKETIMESyntax
------

MAKETIME(hour,minute,second)

Description
-----------

Returns a time value calculated from the hour, minute, and second arguments.

If minute or second are out of the range 0 to 60, NULL is returned. The hour
can be in the range -838 to 838, outside of which the value is truncated with
a warning.

Examples
--------

SELECT MAKETIME(13,57,33);
+--------------------+
| MAKETIME(13,57,33) |
+--------------------+
| 13:57:33           |
+--------------------+

SELECT MAKETIME(-13,57,33);
+---------------------+
| MAKETIME(-13,57,33) |
+---------------------+
| -13:57:33           |
+---------------------+

SELECT MAKETIME(13,67,33);
+--------------------+
| MAKETIME(13,67,33) |
+--------------------+
| NULL               |
+--------------------+

SELECT MAKETIME(-1000,57,33);
+-----------------------+
| MAKETIME(-1000,57,33) |
+-----------------------+
| -838:59:59            |
+-----------------------+
1 row in set, 1 warning (0.00 sec)

SHOW WARNINGS;
+---------+------+-----------------------------------------------+
| Level   | Code | Message                                       |
+---------+------+-----------------------------------------------+
| Warning | 1292 | Truncated incorrect time value: '-1000:57:33' |
+---------+------+-----------------------------------------------+

URL: https://mariadb.com/kb/en/maketime/https://mariadb.com/kb/en/maketime/&MICROSECONDSyntax
------

MICROSECOND(expr)

Description
-----------

Returns the microseconds from the time or datetime expression expr as a number
in the range from 0 to 999999.

If expr is a time with no microseconds, zero is returned, while if expr is a
date with no time, zero with a warning is returned.

Examples
--------

SELECT MICROSECOND('12:00:00.123456');
+--------------------------------+
| MICROSECOND('12:00:00.123456') |
+--------------------------------+
|                         123456 |
+--------------------------------+

SELECT MICROSECOND('2009-12-31 23:59:59.000010');
+-------------------------------------------+
| MICROSECOND('2009-12-31 23:59:59.000010') |
+-------------------------------------------+
|                                        10 |
+-------------------------------------------+

SELECT MICROSECOND('2013-08-07 12:13:14');
+------------------------------------+
| MICROSECOND('2013-08-07 12:13:14') |
+------------------------------------+
|                                  0 |
+------------------------------------+

SELECT MICROSECOND('2013-08-07');
+---------------------------+
| MICROSECOND('2013-08-07') |
+---------------------------+
|                         0 |
+---------------------------+
1 row in set, 1 warning (0.00 sec)

SHOW WARNINGS;
+---------+------+----------------------------------------------+
| Level   | Code | Message                                      |
+---------+------+----------------------------------------------+
| Warning | 1292 | Truncated incorrect time value: '2013-08-07' |
+---------+------+----------------------------------------------+

URL: https://mariadb.com/kb/en/microsecond/https://mariadb.com/kb/en/microsecond/!�	NOWSyntax
------

NOW([precision])
CURRENT_TIMESTAMP
CURRENT_TIMESTAMP([precision])
LOCALTIME, LOCALTIME([precision])
LOCALTIMESTAMP
LOCALTIMESTAMP([precision])

Description
-----------

Returns the current date and time as a value in 'YYYY-MM-DD HH:MM:SS' or
YYYYMMDDHHMMSS.uuuuuu format, depending on whether the function is used in a
string or numeric context. The value is expressed in the current time zone.

The optional precision determines the microsecond precision. See Microseconds
in MariaDB.

NOW() (or its synonyms) can be used as the default value for TIMESTAMP columns
as well as, since MariaDB 10.0.1, DATETIME columns. Before MariaDB 10.0.1, it
was only possible for a single TIMESTAMP column per table to contain the
CURRENT_TIMESTAMP as its default.

When displayed in the INFORMATION_SCHEMA.COLUMNS table, a default CURRENT
TIMESTAMP is displayed as CURRENT_TIMESTAMP up until MariaDB 10.2.2, and as
current_timestamp() from MariaDB 10.2.3, due to to MariaDB 10.2 accepting
expressions in the DEFAULT clause.

Changing the timestamp system variable with a SET timestamp statement affects
the value returned by NOW(), but not by SYSDATE().

Examples
--------

SELECT NOW();
+---------------------+
| NOW()               |
+---------------------+
| 2010-03-27 13:13:25 |
+---------------------+

SELECT NOW() + 0;
+-----------------------+
| NOW() + 0             |
+-----------------------+
| 20100327131329.000000 |
+-----------------------+

With precision:

SELECT CURRENT_TIMESTAMP(2);
+------------------------+
| CURRENT_TIMESTAMP(2)   |
+------------------------+
| 2018-07-10 09:47:26.24 |
+------------------------+

Used as a default TIMESTAMP:

CREATE TABLE t (createdTS TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP);

From MariaDB 10.2.2:

SELECT * FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_SCHEMA='test'
 AND COLUMN_NAME LIKE '%ts%'\G
*************************** 1. row ***************************
     TABLE_CATALOG: def
      TABLE_SCHEMA: test
       TABLE_NAME: t
      COLUMN_NAME: ts
    ORDINAL_POSITION: 1
     COLUMN_DEFAULT: current_timestamp()
...

<= MariaDB 10.2.1

SELECT * FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_SCHEMA='test'
 AND COLUMN_NAME LIKE '%ts%'\G
*************************** 1. row ***************************
     TABLE_CATALOG: def
      TABLE_SCHEMA: test
       TABLE_NAME: t
      COLUMN_NAME: createdTS
    ORDINAL_POSITION: 1
     COLUMN_DEFAULT: CURRENT_TIMESTAMP
...

URL: https://mariadb.com/kb/en/now/https://mariadb.com/kb/en/now/�	B	���������"
;%PERIOD_ADDSyntax
------

PERIOD_ADD(P,N)

Description
-----------

Adds N months to period P. P is in the format YYMM or YYYYMM, and is not a
date value. If P contains a two-digit year, values from 00 to 69 are converted
to from 2000 to 2069, while values from 70 are converted to 1970 upwards.

Returns a value in the format YYYYMM.

Examples
--------

SELECT PERIOD_ADD(200801,2);
+----------------------+
| PERIOD_ADD(200801,2) |
+----------------------+
|               200803 |
+----------------------+

SELECT PERIOD_ADD(6910,2);
+--------------------+
| PERIOD_ADD(6910,2) |
+--------------------+
|             206912 |
+--------------------+

SELECT PERIOD_ADD(7010,2);
+--------------------+
| PERIOD_ADD(7010,2) |
+--------------------+
|             197012 |
+--------------------+

URL: https://mariadb.com/kb/en/period_add/https://mariadb.com/kb/en/period_add/#�&PERIOD_DIFFSyntax
------

PERIOD_DIFF(P1,P2)

Description
-----------

Returns the number of months between periods P1 and P2. P1 and P2 can be in
the format YYMM or YYYYMM, and are not date values.

If P1 or P2 contains a two-digit year, values from 00 to 69 are converted to
from 2000 to 2069, while values from 70 are converted to 1970 upwards.

Examples
--------

SELECT PERIOD_DIFF(200802,200703);
+----------------------------+
| PERIOD_DIFF(200802,200703) |
+----------------------------+
|                         11 |
+----------------------------+

SELECT PERIOD_DIFF(6902,6803);
+------------------------+
| PERIOD_DIFF(6902,6803) |
+------------------------+
|                     11 |
+------------------------+

SELECT PERIOD_DIFF(7002,6803);
+------------------------+
| PERIOD_DIFF(7002,6803) |
+------------------------+
|                  -1177 |
+------------------------+

URL: https://mariadb.com/kb/en/period_diff/https://mariadb.com/kb/en/period_diff/&�&SEC_TO_TIMESyntax
------

SEC_TO_TIME(seconds)

Description
-----------

Returns the seconds argument, converted to hours, minutes, and seconds, as a
TIME value. The range of the result is constrained to that of the TIME data
type. A warning occurs if the argument corresponds to a value outside that
range.

The time will be returned in the format hh:mm:ss, or hhmmss if used in a
numeric calculation.

Examples
--------

SELECT SEC_TO_TIME(12414);
+--------------------+
| SEC_TO_TIME(12414) |
+--------------------+
| 03:26:54           |
+--------------------+

SELECT SEC_TO_TIME(12414)+0;
+----------------------+
| SEC_TO_TIME(12414)+0 |
+----------------------+
|                32654 |
+----------------------+

SELECT SEC_TO_TIME(9999999);
+----------------------+
| SEC_TO_TIME(9999999) |
+----------------------+
| 838:59:59            |
+----------------------+
1 row in set, 1 warning (0.00 sec)

SHOW WARNINGS;
+---------+------+-------------------------------------------+
| Level   | Code | Message                                   |
+---------+------+-------------------------------------------+
| Warning | 1292 | Truncated incorrect time value: '9999999' |
+---------+------+-------------------------------------------+

URL: https://mariadb.com/kb/en/sec_to_time/https://mariadb.com/kb/en/sec_to_time/(#
"SUBDATESyntax
------

SUBDATE(date,INTERVAL expr unit), SUBDATE(expr,days)

Description
-----------

When invoked with the INTERVAL form of the second argument, SUBDATE() is a
synonym for DATE_SUB(). See Date and Time Units for a complete list of
permitted units.

The second form allows the use of an integer value for days. In such cases, it
is interpreted as the number of days to be subtracted from the date or
datetime expression expr.

Examples
--------

SELECT DATE_SUB('2008-01-02', INTERVAL 31 DAY);
+-----------------------------------------+
| DATE_SUB('2008-01-02', INTERVAL 31 DAY) |
+-----------------------------------------+
| 2007-12-02                              |
+-----------------------------------------+

SELECT SUBDATE('2008-01-02', INTERVAL 31 DAY);
+----------------------------------------+
| SUBDATE('2008-01-02', INTERVAL 31 DAY) |
+----------------------------------------+
| 2007-12-02                             |
+----------------------------------------+

SELECT SUBDATE('2008-01-02 12:00:00', 31);
+------------------------------------+
| SUBDATE('2008-01-02 12:00:00', 31) |
+------------------------------------+
| 2007-12-02 12:00:00                |
+------------------------------------+

CREATE TABLE t1 (d DATETIME);
INSERT INTO t1 VALUES
  ("2007-01-30 21:31:07"),
  ("1983-10-15 06:42:51"),
  ("2011-04-21 12:34:56"),
  ("2011-10-30 06:31:41"),
  ("2011-01-30 14:03:25"),
  ("2004-10-07 11:19:34");

SELECT d, SUBDATE(d, 10) from t1;
+---------------------+---------------------+
| d                   | SUBDATE(d, 10)      |
+---------------------+---------------------+
| 2007-01-30 21:31:07 | 2007-01-20 21:31:07 |
| 1983-10-15 06:42:51 | 1983-10-05 06:42:51 |
| 2011-04-21 12:34:56 | 2011-04-11 12:34:56 |
| 2011-10-30 06:31:41 | 2011-10-20 06:31:41 |
| 2011-01-30 14:03:25 | 2011-01-20 14:03:25 |
| 2004-10-07 11:19:34 | 2004-09-27 11:19:34 |
+---------------------+---------------------+

SELECT d, SUBDATE(d, INTERVAL 10 MINUTE) from t1;
+---------------------+--------------------------------+
| d                   | SUBDATE(d, INTERVAL 10 MINUTE) |
+---------------------+--------------------------------+
| 2007-01-30 21:31:07 | 2007-01-30 21:21:07            |
| 1983-10-15 06:42:51 | 1983-10-15 06:32:51            |
| 2011-04-21 12:34:56 | 2011-04-21 12:24:56            |
| 2011-10-30 06:31:41 | 2011-10-30 06:21:41            |
| 2011-01-30 14:03:25 | 2011-01-30 13:53:25            |
| 2004-10-07 11:19:34 | 2004-10-07 11:09:34            |
+---------------------+--------------------------------+

URL: https://mariadb.com/kb/en/subdate/https://mariadb.com/kb/en/subdate/�Z
`9��xQK��,
)�"SUBTIMESyntax
------

SUBTIME(expr1,expr2)

Description
-----------

SUBTIME() returns expr1 - expr2 expressed as a value in the same format as
expr1. expr1 is a time or datetime expression, and expr2 is a time expression.

Examples
--------

SELECT SUBTIME('2007-12-31 23:59:59.999999','1 1:1:1.000002');
+--------------------------------------------------------+
| SUBTIME('2007-12-31 23:59:59.999999','1 1:1:1.000002') |
+--------------------------------------------------------+
| 2007-12-30 22:58:58.999997                             |
+--------------------------------------------------------+

SELECT SUBTIME('01:00:00.999999', '02:00:00.999998');
+-----------------------------------------------+
| SUBTIME('01:00:00.999999', '02:00:00.999998') |
+-----------------------------------------------+
| -00:59:59.999999                              |
+-----------------------------------------------+

URL: https://mariadb.com/kb/en/subtime/https://mariadb.com/kb/en/subtime/*b	"SYSDATESyntax
------

SYSDATE([precision])

Description
-----------

Returns the current date and time as a value in 'YYYY-MM-DD HH:MM:SS' or
YYYYMMDDHHMMSS.uuuuuu format, depending on whether the function is used in a
string or numeric context.

The optional precision determines the microsecond precision. See Microseconds
in MariaDB.

SYSDATE() returns the time at which it executes. This differs from the
behavior for NOW(), which returns a constant time that indicates the time at
which the statement began to execute. (Within a stored routine or trigger,
NOW() returns the time at which the routine or triggering statement began to
execute.)

In addition, changing the timestamp system variable with a SET timestamp
statement affects the value returned by NOW() but not by SYSDATE(). This means
that timestamp settings in the binary log have no effect on invocations of
SYSDATE().

Because SYSDATE() can return different values even within the same statement,
and is not affected by SET TIMESTAMP, it is non-deterministic and therefore
unsafe for replication if statement-based binary logging is used. If that is a
problem, you can use row-based logging, or start the server with the mysqld
option --sysdate-is-now to cause SYSDATE() to be an alias for NOW(). The
non-deterministic nature of SYSDATE() also means that indexes cannot be used
for evaluating expressions that refer to it, and that statements using the
SYSDATE() function are unsafe for statement-based replication.

Examples
--------

Difference between NOW() and SYSDATE():

SELECT NOW(), SLEEP(2), NOW();
+---------------------+----------+---------------------+
| NOW()               | SLEEP(2) | NOW()               |
+---------------------+----------+---------------------+
| 2010-03-27 13:23:40 |        0 | 2010-03-27 13:23:40 |
+---------------------+----------+---------------------+

SELECT SYSDATE(), SLEEP(2), SYSDATE();
+---------------------+----------+---------------------+
| SYSDATE()           | SLEEP(2) | SYSDATE()           |
+---------------------+----------+---------------------+
| 2010-03-27 13:23:52 |        0 | 2010-03-27 13:23:54 |
+---------------------+----------+---------------------+

With precision:

SELECT SYSDATE(4);
+--------------------------+
| SYSDATE(4)               |
+--------------------------+
| 2018-07-10 10:17:13.1689 |
+--------------------------+

URL: https://mariadb.com/kb/en/sysdate/https://mariadb.com/kb/en/sysdate/,]#TIMEDIFFSyntax
------

TIMEDIFF(expr1,expr2)

Description
-----------

TIMEDIFF() returns expr1 - expr2 expressed as a time value. expr1 and expr2
are time or date-and-time expressions, but both must be of the same type.

Examples
--------

SELECT TIMEDIFF('2000:01:01 00:00:00', '2000:01:01 00:00:00.000001');
+---------------------------------------------------------------+
| TIMEDIFF('2000:01:01 00:00:00', '2000:01:01 00:00:00.000001') |
+---------------------------------------------------------------+
| -00:00:00.000001                                              |
+---------------------------------------------------------------+

SELECT TIMEDIFF('2008-12-31 23:59:59.000001', '2008-12-30 01:01:01.000002');
+----------------------------------------------------------------------+
| TIMEDIFF('2008-12-31 23:59:59.000001', '2008-12-30 01:01:01.000002') |
+----------------------------------------------------------------------+
| 46:58:57.999999                                                      |
+----------------------------------------------------------------------+

URL: https://mariadb.com/kb/en/timediff/https://mariadb.com/kb/en/timediff/-V-TIMESTAMP FUNCTIONSyntax
------

TIMESTAMP(expr), TIMESTAMP(expr1,expr2)

Description
-----------

With a single argument, this function returns the date or datetime expression
expr as a datetime value. With two arguments, it adds the time expression
expr2 to the date or datetime expression expr1 and returns the result as a
datetime value.

Examples
--------

SELECT TIMESTAMP('2003-12-31');
+-------------------------+
| TIMESTAMP('2003-12-31') |
+-------------------------+
| 2003-12-31 00:00:00     |
+-------------------------+

SELECT TIMESTAMP('2003-12-31 12:00:00','6:30:00');
+--------------------------------------------+
| TIMESTAMP('2003-12-31 12:00:00','6:30:00') |
+--------------------------------------------+
| 2003-12-31 18:30:00                        |
+--------------------------------------------+

URL: https://mariadb.com/kb/en/timestamp-function/https://mariadb.com/kb/en/timestamp-function/��
���	�(�F��	.N'TIMESTAMPADDSyntax
------

TIMESTAMPADD(unit,interval,datetime_expr)

Description
-----------

Adds the integer expression interval to the date or datetime expression
datetime_expr. The unit for interval is given by the unit argument, which
should be one of the following values: MICROSECOND, SECOND, MINUTE, HOUR, DAY,
WEEK, MONTH, QUARTER, or YEAR.

The unit value may be specified using one of keywords as shown, or with a
prefix of SQL_TSI_. For example, DAY and SQL_TSI_DAY both are legal.

Before MariaDB 5.5, FRAC_SECOND was permitted as a synonym for MICROSECOND.

Examples
--------

SELECT TIMESTAMPADD(MINUTE,1,'2003-01-02');
+-------------------------------------+
| TIMESTAMPADD(MINUTE,1,'2003-01-02') |
+-------------------------------------+
| 2003-01-02 00:01:00                 |
+-------------------------------------+

SELECT TIMESTAMPADD(WEEK,1,'2003-01-02');
+-----------------------------------+
| TIMESTAMPADD(WEEK,1,'2003-01-02') |
+-----------------------------------+
| 2003-01-09                        |
+-----------------------------------+

URL: https://mariadb.com/kb/en/timestampadd/https://mariadb.com/kb/en/timestampadd//
�	(TIMESTAMPDIFFSyntax
------

TIMESTAMPDIFF(unit,datetime_expr1,datetime_expr2)

Description
-----------

Returns datetime_expr2 - datetime_expr1, where datetime_expr1 and
datetime_expr2 are date or datetime expressions. One expression may be a date
and the other a datetime; a date value is treated as a datetime having the
time part '00:00:00' where necessary. The unit for the result (an integer) is
given by the unit argument. The legal values for unit are the same as those
listed in the description of the TIMESTAMPADD() function, i.e MICROSECOND,
SECOND, MINUTE, HOUR, DAY, WEEK, MONTH, QUARTER, or YEAR.

TIMESTAMPDIFF can also be used to calculate age.

Examples
--------

SELECT TIMESTAMPDIFF(MONTH,'2003-02-01','2003-05-01');
+------------------------------------------------+
| TIMESTAMPDIFF(MONTH,'2003-02-01','2003-05-01') |
+------------------------------------------------+
|                                              3 |
+------------------------------------------------+

SELECT TIMESTAMPDIFF(YEAR,'2002-05-01','2001-01-01');
+-----------------------------------------------+
| TIMESTAMPDIFF(YEAR,'2002-05-01','2001-01-01') |
+-----------------------------------------------+
|                                            -1 |
+-----------------------------------------------+

SELECT TIMESTAMPDIFF(MINUTE,'2003-02-01','2003-05-01 12:05:55');
+----------------------------------------------------------+
| TIMESTAMPDIFF(MINUTE,'2003-02-01','2003-05-01 12:05:55') |
+----------------------------------------------------------+
|                                                   128885 |
+----------------------------------------------------------+

Calculating age:

SELECT CURDATE();
+------------+
| CURDATE()  |
+------------+
| 2019-05-27 |
+------------+

SELECT TIMESTAMPDIFF(YEAR, '1971-06-06', CURDATE()) AS age;
+------+
| age  |
+------+
|   47 |
+------+

SELECT TIMESTAMPDIFF(YEAR, '1971-05-06', CURDATE()) AS age;
+------+
| age  |
+------+
|   48 |
+------+

Age as of 2014-08-02:

SELECT name, date_of_birth, TIMESTAMPDIFF(YEAR,date_of_birth,'2014-08-02') AS
age 
 FROM student_details;
+---------+---------------+------+
| name    | date_of_birth | age  |
+---------+---------------+------+
| Chun    | 1993-12-31    |   20 |
| Esben   | 1946-01-01    |   68 |
| Kaolin  | 1996-07-16    |   18 |
| Tatiana | 1988-04-13    |   26 |
+---------+---------------+------+

URL: https://mariadb.com/kb/en/timestampdiff/https://mariadb.com/kb/en/timestampdiff/1�&TIME_TO_SECSyntax
------

TIME_TO_SEC(time)

Description
-----------

Returns the time argument, converted to seconds.

The value returned by TIME_TO_SEC is of type DOUBLE. Before MariaDB 5.3 (and
MySQL 5.6), the type was INT. The returned value preserves microseconds of the
argument. See also Microseconds in MariaDB.

Examples
--------

SELECT TIME_TO_SEC('22:23:00');
+-------------------------+
| TIME_TO_SEC('22:23:00') |
+-------------------------+
|                   80580 |
+-------------------------+

SELECT TIME_TO_SEC('00:39:38');
+-------------------------+
| TIME_TO_SEC('00:39:38') |
+-------------------------+
|                    2378 |
+-------------------------+

SELECT TIME_TO_SEC('09:12:55.2355');
+------------------------------+
| TIME_TO_SEC('09:12:55.2355') |
+------------------------------+
|                   33175.2355 |
+------------------------------+
1 row in set (0.000 sec)

URL: https://mariadb.com/kb/en/time_to_sec/https://mariadb.com/kb/en/time_to_sec/2�"TO_DAYSSyntax
------

TO_DAYS(date)

Description
-----------

Given a date date, returns the number of days since the start of the current
calendar (0000-00-00).

The function is not designed for use with dates before the advent of the
Gregorian calendar in October 1582. Results will not be reliable since it
doesn't account for the lost days when the calendar changed from the Julian
calendar.

This is the converse of the FROM_DAYS() function.

Examples
--------

SELECT TO_DAYS('2007-10-07');
+-----------------------+
| TO_DAYS('2007-10-07') |
+-----------------------+
|                733321 |
+-----------------------+

SELECT TO_DAYS('0000-01-01');
+-----------------------+
| TO_DAYS('0000-01-01') |
+-----------------------+
|                     1 |
+-----------------------+

SELECT TO_DAYS(950501);
+-----------------+
| TO_DAYS(950501) |
+-----------------+
|          728779 |
+-----------------+

URL: https://mariadb.com/kb/en/to_days/https://mariadb.com/kb/en/to_days/P�_���	�y����r3
E%TO_SECONDSSyntax
------

TO_SECONDS(expr)

Description
-----------

Returns the number of seconds from year 0 till expr, or NULL if expr is not a
valid date or datetime.

Examples
--------

SELECT TO_SECONDS('2013-06-13');
+--------------------------+
| TO_SECONDS('2013-06-13') |
+--------------------------+
|              63538300800 |
+--------------------------+

SELECT TO_SECONDS('2013-06-13 21:45:13');
+-----------------------------------+
| TO_SECONDS('2013-06-13 21:45:13') |
+-----------------------------------+
|                       63538379113 |
+-----------------------------------+

SELECT TO_SECONDS(NOW());
+-------------------+
| TO_SECONDS(NOW()) |
+-------------------+
|       63543530875 |
+-------------------+

SELECT TO_SECONDS(20130513);
+----------------------+
| TO_SECONDS(20130513) |
+----------------------+
|          63535622400 |
+----------------------+
1 row in set (0.00 sec)

SELECT TO_SECONDS(130513);
+--------------------+
| TO_SECONDS(130513) |
+--------------------+
|        63535622400 |
+--------------------+

URL: https://mariadb.com/kb/en/to_seconds/https://mariadb.com/kb/en/to_seconds/4�)UNIX_TIMESTAMPSyntax
------

UNIX_TIMESTAMP()
UNIX_TIMESTAMP(date)

Description
-----------

If called with no argument, returns a Unix timestamp (seconds since
'1970-01-01 00:00:00' UTC) as an unsigned integer. If UNIX_TIMESTAMP() is
called with a date argument, it returns the value of the argument as seconds
since '1970-01-01 00:00:00' UTC. date may be a DATE string, a DATETIME string,
a TIMESTAMP, or a number in the format YYMMDD or YYYYMMDD. The server
interprets date as a value in the current time zone and converts it to an
internal value in UTC. Clients can set their time zone as described in time
zones.

The inverse function of UNIX_TIMESTAMP() is FROM_UNIXTIME()

UNIX_TIMESTAMP() supports microseconds.

Timestamps in MariaDB have a maximum value of 2147483647, equivalent to
2038-01-19 05:14:07. This is due to the underlying 32-bit limitation. Using
the function on a date beyond this will result in NULL being returned. Use
DATETIME as a storage type if you require dates beyond this.

Error Handling
--------------

Returns NULL for wrong arguments to UNIX_TIMESTAMP(). In MySQL and MariaDB
before 5.3 wrong arguments to UNIX_TIMESTAMP() returned 0.

Compatibility
-------------

As you can see in the examples above, UNIX_TIMESTAMP(constant-date-string)
returns a timestamp with 6 decimals while MariaDB 5.2 and before returns it
without decimals. This can cause a problem if you are using UNIX_TIMESTAMP()
as a partitioning function. You can fix this by using
FLOOR(UNIX_TIMESTAMP(..)) or changing the date string to a date number, like
20080101000000.

Examples
--------

SELECT UNIX_TIMESTAMP();
+------------------+
| UNIX_TIMESTAMP() |
+------------------+
|       1269711082 |
+------------------+

SELECT UNIX_TIMESTAMP('2007-11-30 10:30:19');
+---------------------------------------+
| UNIX_TIMESTAMP('2007-11-30 10:30:19') |
+---------------------------------------+
|                     1196436619.000000 |
+---------------------------------------+

SELECT UNIX_TIMESTAMP("2007-11-30 10:30:19.123456");
+----------------------------------------------+
| unix_timestamp("2007-11-30 10:30:19.123456") |
+----------------------------------------------+
|                            1196411419.123456 |
+----------------------------------------------+

SELECT FROM_UNIXTIME(UNIX_TIMESTAMP('2007-11-30 10:30:19'));
+------------------------------------------------------+
| FROM_UNIXTIME(UNIX_TIMESTAMP('2007-11-30 10:30:19')) |
+------------------------------------------------------+
| 2007-11-30 10:30:19.000000                           |
+------------------------------------------------------+

SELECT FROM_UNIXTIME(FLOOR(UNIX_TIMESTAMP('2007-11-30 10:30:19')));
+-------------------------------------------------------------+
| FROM_UNIXTIME(FLOOR(UNIX_TIMESTAMP('2007-11-30 10:30:19'))) |
+-------------------------------------------------------------+
| 2007-11-30 10:30:19                                         |
+-------------------------------------------------------------+

URL: https://mariadb.com/kb/en/unix_timestamp/https://mariadb.com/kb/en/unix_timestamp/7
}(UTC_TIMESTAMPSyntax
------

UTC_TIMESTAMP
UTC_TIMESTAMP([precision])

Description
-----------

Returns the current UTC date and time as a value in 'YYYY-MM-DD HH:MM:SS' or
YYYYMMDDHHMMSS.uuuuuu format, depending on whether the function is used in a
string or numeric context.

The optional precision determines the microsecond precision. See Microseconds
in MariaDB.

Examples
--------

SELECT UTC_TIMESTAMP(), UTC_TIMESTAMP() + 0;
+---------------------+-----------------------+
| UTC_TIMESTAMP()     | UTC_TIMESTAMP() + 0   |
+---------------------+-----------------------+
| 2010-03-27 17:33:16 | 20100327173316.000000 |
+---------------------+-----------------------+

With precision:

SELECT UTC_TIMESTAMP(4);
+--------------------------+
| UTC_TIMESTAMP(4)         |
+--------------------------+
| 2018-07-10 07:51:09.1019 |
+--------------------------+

URL: https://mariadb.com/kb/en/utc_timestamp/https://mariadb.com/kb/en/utc_timestamp/���0�4�
���8xWEEKSyntax
------

WEEK(date[,mode])

Description
-----------

This function returns the week number for date. The two-argument form of
WEEK() allows you to specify whether the week starts on Sunday or Monday and
whether the return value should be in the range from 0 to 53 or from 1 to 53.
If the mode argument is omitted, the value of the default_week_format system
variable is used.

Modes
-----

+-------+---------------------+--------+------------------------------------+
| Mode  | 1st day of week     | Range  | Week 1 is the 1st week with        |
+-------+---------------------+--------+------------------------------------+
| 0     | Sunday              | 0-53   | a Sunday in this year              |
+-------+---------------------+--------+------------------------------------+
| 1     | Monday              | 0-53   | more than 3 days this year         |
+-------+---------------------+--------+------------------------------------+
| 2     | Sunday              | 1-53   | a Sunday in this year              |
+-------+---------------------+--------+------------------------------------+
| 3     | Monday              | 1-53   | more than 3 days this year         |
+-------+---------------------+--------+------------------------------------+
| 4     | Sunday              | 0-53   | more than 3 days this year         |
+-------+---------------------+--------+------------------------------------+
| 5     | Monday              | 0-53   | a Monday in this year              |
+-------+---------------------+--------+------------------------------------+
| 6     | Sunday              | 1-53   | more than 3 days this year         |
+-------+---------------------+--------+------------------------------------+
| 7     | Monday              | 1-53   | a Monday in this year              |
+-------+---------------------+--------+------------------------------------+

With the mode value of 3, which means 'more than 3 days this year', weeks are
numbered according to ISO 8601:1988.

Examples
--------

SELECT WEEK('2008-02-20');
+--------------------+
| WEEK('2008-02-20') |
+--------------------+
|                  7 |
+--------------------+

SELECT WEEK('2008-02-20',0);
+----------------------+
| WEEK('2008-02-20',0) |
+----------------------+
|                    7 |
+----------------------+

SELECT WEEK('2008-02-20',1);
+----------------------+
| WEEK('2008-02-20',1) |
+----------------------+
|                    8 |
+----------------------+

SELECT WEEK('2008-12-31',0);
+----------------------+
| WEEK('2008-12-31',0) |
+----------------------+
|                   52 |
+----------------------+

SELECT WEEK('2008-12-31',1);
+----------------------+
| WEEK('2008-12-31',1) |
+----------------------+
|                   53 |
+----------------------+

SELECT WEEK('2019-12-30',3);
+----------------------+
| WEEK('2019-12-30',3) |
+----------------------+
|                    1 |
+----------------------+

CREATE TABLE t1 (d DATETIME);
INSERT INTO t1 VALUES
  ("2007-01-30 21:31:07"),
  ("1983-10-15 06:42:51"),
  ("2011-04-21 12:34:56"),
  ("2011-10-30 06:31:41"),
  ("2011-01-30 14:03:25"),
  ("2004-10-07 11:19:34");

SELECT d, WEEK(d,0), WEEK(d,1) from t1;
+---------------------+-----------+-----------+
| d                   | WEEK(d,0) | WEEK(d,1) |
+---------------------+-----------+-----------+
| 2007-01-30 21:31:07 |         4 |         5 |
| 1983-10-15 06:42:51 |        41 |        41 |
| 2011-04-21 12:34:56 |        16 |        16 |
| 2011-10-30 06:31:41 |        44 |        43 |
| 2011-01-30 14:03:25 |         5 |         4 |
| 2004-10-07 11:19:34 |        40 |        41 |
+---------------------+-----------+-----------+

URL: https://mariadb.com/kb/en/week/https://mariadb.com/kb/en/week/95"WEEKDAYSyntax
------

WEEKDAY(date)

Description
-----------

Returns the weekday index for date (0 = Monday, 1 = Tuesday, ... 6 = Sunday).

This contrasts with DAYOFWEEK() which follows the ODBC standard (1 = Sunday, 2
= Monday, ..., 7 = Saturday).

Examples
--------

SELECT WEEKDAY('2008-02-03 22:23:00');
+--------------------------------+
| WEEKDAY('2008-02-03 22:23:00') |
+--------------------------------+
|                              6 |
+--------------------------------+

SELECT WEEKDAY('2007-11-06');
+-----------------------+
| WEEKDAY('2007-11-06') |
+-----------------------+
|                     1 |
+-----------------------+

CREATE TABLE t1 (d DATETIME);
INSERT INTO t1 VALUES
  ("2007-01-30 21:31:07"),
  ("1983-10-15 06:42:51"),
  ("2011-04-21 12:34:56"),
  ("2011-10-30 06:31:41"),
  ("2011-01-30 14:03:25"),
  ("2004-10-07 11:19:34");

SELECT d FROM t1 where WEEKDAY(d) = 6;
+---------------------+
| d                   |
+---------------------+
| 2011-10-30 06:31:41 |
| 2011-01-30 14:03:25 |
+---------------------+

URL: https://mariadb.com/kb/en/weekday/https://mariadb.com/kb/en/weekday/:
�%WEEKOFYEARSyntax
------

WEEKOFYEAR(date)

Description
-----------

Returns the calendar week of the date as a number in the range from 1 to 53.
WEEKOFYEAR() is a compatibility function that is equivalent to WEEK(date,3).

Examples
--------

SELECT WEEKOFYEAR('2008-02-20');
+--------------------------+
| WEEKOFYEAR('2008-02-20') |
+--------------------------+
|                        8 |
+--------------------------+

CREATE TABLE t1 (d DATETIME);
INSERT INTO t1 VALUES
  ("2007-01-30 21:31:07"),
  ("1983-10-15 06:42:51"),
  ("2011-04-21 12:34:56"),
  ("2011-10-30 06:31:41"),
  ("2011-01-30 14:03:25"),
  ("2004-10-07 11:19:34");

select * from t1;
+---------------------+
| d                   |
+---------------------+
| 2007-01-30 21:31:07 |
| 1983-10-15 06:42:51 |
| 2011-04-21 12:34:56 |
| 2011-10-30 06:31:41 |
| 2011-01-30 14:03:25 |
| 2004-10-07 11:19:34 |
+---------------------+

SELECT d, WEEKOFYEAR(d), WEEK(d,3) from t1;
+---------------------+---------------+-----------+
| d                   | WEEKOFYEAR(d) | WEEK(d,3) |
+---------------------+---------------+-----------+
| 2007-01-30 21:31:07 |             5 |         5 |
| 1983-10-15 06:42:51 |            41 |        41 |
| 2011-04-21 12:34:56 |            16 |        16 |
| 2011-10-30 06:31:41 |            43 |        43 |
| 2011-01-30 14:03:25 |             4 |         4 |
| 2004-10-07 11:19:34 |            41 |        41 |
+---------------------+---------------+-----------+

URL: https://mariadb.com/kb/en/weekofyear/https://mariadb.com/kb/en/weekofyear/!�l�vr^��p;�YEARSyntax
------

YEAR(date)

Description
-----------

Returns the year for the given date, in the range 1000 to 9999, or 0 for the
"zero" date.

Examples
--------

CREATE TABLE t1 (d DATETIME);
INSERT INTO t1 VALUES
  ("2007-01-30 21:31:07"),
  ("1983-10-15 06:42:51"),
  ("2011-04-21 12:34:56"),
  ("2011-10-30 06:31:41"),
  ("2011-01-30 14:03:25"),
  ("2004-10-07 11:19:34");

SELECT * FROM t1;
+---------------------+
| d                   |
+---------------------+
| 2007-01-30 21:31:07 |
| 1983-10-15 06:42:51 |
| 2011-04-21 12:34:56 |
| 2011-10-30 06:31:41 |
| 2011-01-30 14:03:25 |
| 2004-10-07 11:19:34 |
+---------------------+

SELECT * FROM t1 WHERE YEAR(d) = 2011;
+---------------------+
| d                   |
+---------------------+
| 2011-04-21 12:34:56 |
| 2011-10-30 06:31:41 |
| 2011-01-30 14:03:25 |
+---------------------+

SELECT YEAR('1987-01-01');
+--------------------+
| YEAR('1987-01-01') |
+--------------------+
|               1987 |
+--------------------+

URL: https://mariadb.com/kb/en/year/https://mariadb.com/kb/en/year/<�#YEARWEEKSyntax
------

YEARWEEK(date), YEARWEEK(date,mode)

Description
-----------

Returns year and week for a date. The mode argument works exactly like the
mode argument to WEEK(). The year in the result may be different from the year
in the date argument for the first and the last week of the year.

Examples
--------

SELECT YEARWEEK('1987-01-01');
+------------------------+
| YEARWEEK('1987-01-01') |
+------------------------+
|                 198652 |
+------------------------+

CREATE TABLE t1 (d DATETIME);
INSERT INTO t1 VALUES
  ("2007-01-30 21:31:07"),
  ("1983-10-15 06:42:51"),
  ("2011-04-21 12:34:56"),
  ("2011-10-30 06:31:41"),
  ("2011-01-30 14:03:25"),
  ("2004-10-07 11:19:34");

SELECT * FROM t1;
+---------------------+
| d                   |
+---------------------+
| 2007-01-30 21:31:07 |
| 1983-10-15 06:42:51 |
| 2011-04-21 12:34:56 |
| 2011-10-30 06:31:41 |
| 2011-01-30 14:03:25 |
| 2004-10-07 11:19:34 |
+---------------------+
6 rows in set (0.02 sec)

SELECT YEARWEEK(d) FROM t1 WHERE YEAR(d) = 2011;
+-------------+
| YEARWEEK(d) |
+-------------+
|      201116 |
|      201144 |
|      201105 |
+-------------+
3 rows in set (0.03 sec)

URL: https://mariadb.com/kb/en/yearweek/https://mariadb.com/kb/en/yearweek/=�7 Well-Known Binary (WKB) FormatWKB stands for Well-Known Binary, a format for representing geographical and
geometrical data.

WKB uses 1-byte unsigned integers, 4-byte unsigned integers, and 8-byte
double-precision numbers.

* The first byte indicates the byte order. 00 for big endian, or 01 for little
endian.
* The next 4 bytes indicate the geometry type. Values from 1 to 7 indicate
whether the type is Point, LineString, Polygon, MultiPoint, MultiLineString,
MultiPolygon, or GeometryCollection respectively. 
* The 8-byte floats represent the co-ordinates.

Take the following example, a sequence of 21 bytes each represented by two hex
digits:

000000000140000000000000004010000000000000

* It's big endian
000000000140000000000000004010000000000000

* It's a POINT
000000000140000000000000004010000000000000

* The X co-ordinate is 2.0
000000000140000000000000004010000000000000

* The Y-co-ordinate is 4.0
000000000140000000000000004010000000000000

URL: https://mariadb.com/kb/en/well-known-binary-wkb-format/https://mariadb.com/kb/en/well-known-binary-wkb-format/Q�- ST_GeomCollFromWKBSyntax
------

ST_GeomCollFromWKB(wkb[,srid])
ST_GeometryCollectionFromWKB(wkb[,srid])
GeomCollFromWKB(wkb[,srid])
GeometryCollectionFromWKB(wkb[,srid])

Description
-----------

Constructs a GEOMETRYCOLLECTION value using its WKB representation and SRID.

ST_GeomCollFromWKB(), ST_GeometryCollectionFromWKB(), GeomCollFromWKB() and
GeometryCollectionFromWKB() are synonyms.

Examples
--------

SET @g = ST_AsBinary(ST_GeomFromText('GEOMETRYCOLLECTION(
 POLYGON((5 5,10 5,10 10,5 5)),POINT(10 10))'));

SELECT ST_AsText(ST_GeomCollFromWKB(@g));
+----------------------------------------------------------------+
| ST_AsText(ST_GeomCollFromWKB(@g))                              |
+----------------------------------------------------------------+
| GEOMETRYCOLLECTION(POLYGON((5 5,10 5,10 10,5 5)),POINT(10 10)) |
+----------------------------------------------------------------+

URL: https://mariadb.com/kb/en/st_geomcollfromwkb/https://mariadb.com/kb/en/st_geomcollfromwkb/[�-"Geometry HierarchyDescription
-----------

Geometry is the base class. It is an abstract class. The instantiable
subclasses of Geometry are restricted to zero-, one-, and two-dimensional
geometric objects that exist in two-dimensional coordinate space. All
instantiable geometry classes are defined so that valid instances of a
geometry class are topologically closed (that is, all defined geometries
include their boundary).

The base Geometry class has subclasses for Point, Curve, Surface, and
GeometryCollection:

* Point represents zero-dimensional objects.
* Curve represents one-dimensional objects, and has subclass LineString, with
sub-subclasses Line and LinearRing.
* Surface is designed for two-dimensional objects and has subclass Polygon.
* GeometryCollection has specialized zero-, one-, and two-dimensional
collection classes named MultiPoint, MultiLineString, and MultiPolygon for
modeling geometries corresponding to collections of Points, LineStrings, and
Polygons, respectively. MultiCurve and MultiSurface are introduced as abstract
superclasses that generalize the collection interfaces to handle Curves and
Surfaces.

Geometry, Curve, Surface, MultiCurve, and MultiSurface are defined as
non-instantiable classes. They define a common set of methods for their
subclasses and are included for extensibility.

Point, LineString, Polygon, GeometryCollection, MultiPoint, MultiLineString,
and MultiPolygon are instantiable classes.

URL: https://mariadb.com/kb/en/geometry-hierarchy/https://mariadb.com/kb/en/geometry-hierarchy/_o
�/	@<�0�\�
Z�)"Geometry TypesDescription
-----------

MariaDB provides a standard way of creating spatial columns for geometry
types, for example, with CREATE TABLE or ALTER TABLE. Currently, spatial
columns are supported for MyISAM, InnoDB and ARCHIVE tables. See also SPATIAL
INDEX.

The basic geometry type is GEOMETRY. But the type can be more specific. The
following types are supported:

+-----------------------------------------------------------------------------+
| Geometry Types                                                              |
+-----------------------------------------------------------------------------+
| POINT                                                                       |
+-----------------------------------------------------------------------------+
| LINESTRING                                                                  |
+-----------------------------------------------------------------------------+
| POLYGON                                                                     |
+-----------------------------------------------------------------------------+
| MULTIPOINT                                                                  |
+-----------------------------------------------------------------------------+
| MULTILINESTRING                                                             |
+-----------------------------------------------------------------------------+
| MULTIPOLYGON                                                                |
+-----------------------------------------------------------------------------+
| GEOMETRYCOLLECTION                                                          |
+-----------------------------------------------------------------------------+
| GEOMETRY                                                                    |
+-----------------------------------------------------------------------------+

Examples
--------

Note: For clarity, only one type is listed per table in the examples below,
but a table row can contain multiple types. For example:

CREATE TABLE object (shapeA POLYGON, shapeB LINESTRING);

POINT
-----

CREATE TABLE gis_point  (g POINT);
SHOW FIELDS FROM gis_point;
INSERT INTO gis_point VALUES
  (PointFromText('POINT(10 10)')),
  (PointFromText('POINT(20 10)')),
  (PointFromText('POINT(20 20)')),
  (PointFromWKB(AsWKB(PointFromText('POINT(10 20)'))));

LINESTRING
----------

CREATE TABLE gis_line  (g LINESTRING);
SHOW FIELDS FROM gis_line;
INSERT INTO gis_line VALUES
  (LineFromText('LINESTRING(0 0,0 10,10 0)')),
  (LineStringFromText('LINESTRING(10 10,20 10,20 20,10 20,10 10)')),
  (LineStringFromWKB(AsWKB(LineString(Point(10, 10), Point(40, 10)))));

POLYGON
-------

CREATE TABLE gis_polygon   (g POLYGON);
SHOW FIELDS FROM gis_polygon;
INSERT INTO gis_polygon VALUES
  (PolygonFromText('POLYGON((10 10,20 10,20 20,10 20,10 10))')),
  (PolyFromText('POLYGON((0 0,50 0,50 50,0 50,0 0), (10 10,20 10,20 20,10
20,10 10))')),
  (PolyFromWKB(AsWKB(Polygon(LineString(Point(0, 0), Point(30, 0), Point(30,
30), Point(0, 0))))));

MULTIPOINT
----------

CREATE TABLE gis_multi_point (g MULTIPOINT);
SHOW FIELDS FROM gis_multi_point;
INSERT INTO gis_multi_point VALUES
  (MultiPointFromText('MULTIPOINT(0 0,10 10,10 20,20 20)')),
  (MPointFromText('MULTIPOINT(1 1,11 11,11 21,21 21)')),
  (MPointFromWKB(AsWKB(MultiPoint(Point(3, 6), Point(4, 10)))));

MULTILINESTRING
---------------

CREATE TABLE gis_multi_line (g MULTILINESTRING);
SHOW FIELDS FROM gis_multi_line;
INSERT INTO gis_multi_line VALUES
  (MultiLineStringFromText('MULTILINESTRING((10 48,10 21,10 0),(16 0,16
23,16 48))')),
  (MLineFromText('MULTILINESTRING((10 48,10 21,10 0))')),
  (MLineFromWKB(AsWKB(MultiLineString(LineString(Point(1, 2), Point(3, 5)),
LineString(Point(2, 5), Point(5, 8), Point(21, 7))))));

MULTIPOLYGON
------------

CREATE TABLE gis_multi_polygon  (g MULTIPOLYGON);
SHOW FIELDS FROM gis_multi_polygon;
INSERT INTO gis_multi_polygon VALUES
  (MultiPolygonFromText('MULTIPOLYGON(((28 26,28 0,84 0,84 42,28 26),(52
18,66 23,73 9,48 6,52 18)),((59 18,67 18,67 13,59 13,59 18)))')),
  (MPolyFromText('MULTIPOLYGON(((28 26,28 0,84 0,84 42,28 26),(52 18,66
23,73 9,48 6,52 18)),((59 18,67 18,67 13,59 13,59 18)))')),
  (MPolyFromWKB(AsWKB(MultiPolygon(Polygon(LineString(Point(0, 3), Point(3,
3), Point(3, 0), Point(0, 3)))))));

GEOMETRYCOLLECTION
------------------

CREATE TABLE gis_geometrycollection  (g GEOMETRYCOLLECTION);
SHOW FIELDS FROM gis_geometrycollection;
INSERT INTO gis_geometrycollection VALUES
  (GeomCollFromText('GEOMETRYCOLLECTION(POINT(0 0), LINESTRING(0 0,10
10))')),
  (GeometryFromWKB(AsWKB(GeometryCollection(Point(44, 6),
LineString(Point(3, 6), Point(7, 9)))))),
  (GeomFromText('GeometryCollection()')),
  (GeomFromText('GeometryCollection EMPTY'));

GEOMETRY
--------

CREATE TABLE gis_geometry (g GEOMETRY);
SHOW FIELDS FROM gis_geometry;
INSERT into gis_geometry SELECT * FROM gis_point;
INSERT into gis_geometry SELECT * FROM gis_line;
INSERT into gis_geometry SELECT * FROM gis_polygon;
INSERT into gis_geometry SELECT * FROM gis_multi_point;
INSERT into gis_geometry SELECT * FROM gis_multi_line;
INSERT into gis_geometry SELECT * FROM gis_multi_polygon;
INSERT into gis_geometry SELECT * FROM gis_geometrycollection;

URL: https://mariadb.com/kb/en/geometry-types/https://mariadb.com/kb/en/geometry-types/����
\
2("SPATIAL INDEXDescription
-----------

On MyISAM, Aria and InnoDB tables, MariaDB can create spatial indexes (an
R-tree index) using syntax similar to that for creating regular indexes, but
extended with the SPATIAL keyword. Currently, columns in spatial indexes must
be declared NOT NULL.

Spatial indexes can be created when the table is created, or added after the
fact like so:

* with CREATE TABLE: CREATE TABLE geom (g GEOMETRY NOT NULL, SPATIAL INDEX(g));

* with ALTER TABLE: ALTER TABLE geom ADD SPATIAL INDEX(g);

* with CREATE INDEX: CREATE SPATIAL INDEX sp_index ON geom (g);

SPATIAL INDEX creates an R-tree index. For storage engines that support
non-spatial indexing of spatial columns, the engine creates a B-tree index. A
B-tree index on spatial values is useful for exact-value lookups, but not for
range scans.

For more information on indexing spatial columns, see CREATE INDEX.

To drop spatial indexes, use ALTER TABLE or DROP INDEX:

* with ALTER TABLE: ALTER TABLE geom DROP INDEX g;

* with DROP INDEX: DROP INDEX sp_index ON geom;

Data-at-Rest Encyption
----------------------

Before MariaDB 10.4.3, InnoDB's spatial indexes could not be encrypted. If an
InnoDB table was encrypted and if it contained spatial indexes, then those
indexes would be unencrypted.

In MariaDB 10.4.3 and later, if innodb_checksum_algorithm is set to full_crc32
or strict_full_crc32, and if the table does not use ROW_FORMAT=COMPRESSED,
then InnoDB spatial indexes will be encrypted if the table is encrypted.

See MDEV-12026 for more information.

URL: https://mariadb.com/kb/en/spatial-index/https://mariadb.com/kb/en/spatial-index/h�&#ST_BOUNDARYMariaDB starting with 10.1.2
----------------------------
The ST_BOUNDARY function was introduced in MariaDB 10.1.2

Syntax
------

ST_BOUNDARY(g)
BOUNDARY(g)

Description
-----------

Returns a geometry that is the closure of the combinatorial boundary of the
geometry value g.

BOUNDARY() is a synonym.

Examples
--------

SELECT ST_AsText(ST_Boundary(ST_GeomFromText('LINESTRING(3 3,0 0, -3 3)')));
+----------------------------------------------------------------------+
| ST_AsText(ST_Boundary(ST_GeomFromText('LINESTRING(3 3,0 0, -3 3)'))) |
+----------------------------------------------------------------------+
| MULTIPOINT(3 3,-3 3)                                                 |
+----------------------------------------------------------------------+

SELECT ST_AsText(ST_Boundary(ST_GeomFromText('POLYGON((3 3,0 0, -3 3, 3
3))')));
+--------------------------------------------------------------------------+
| ST_AsText(ST_Boundary(ST_GeomFromText('POLYGON((3 3,0 0, -3 3, 3 3))'))) |
+--------------------------------------------------------------------------+
| LINESTRING(3 3,0 0,-3 3,3 3)                                             |
+--------------------------------------------------------------------------+

URL: https://mariadb.com/kb/en/st_boundary/https://mariadb.com/kb/en/st_boundary/i�'#ST_DIMENSIONSyntax
------

ST_Dimension(g)
Dimension(g)

Description
-----------

Returns the inherent dimension of the geometry value g. The result can be

+------------------------------------+---------------------------------------+
| Dimension                          | Definition                            |
+------------------------------------+---------------------------------------+
| -1                                 | empty geometry                        |
+------------------------------------+---------------------------------------+
| 0                                  | geometry with no length or area       |
+------------------------------------+---------------------------------------+
| 1                                  | geometry with no area but nonzero     |
|                                    | length                                |
+------------------------------------+---------------------------------------+
| 2                                  | geometry with nonzero area            |
+------------------------------------+---------------------------------------+

ST_Dimension() and Dimension() are synonyms.

Examples
--------

SELECT Dimension(GeomFromText('LineString(1 1,2 2)'));
+------------------------------------------------+
| Dimension(GeomFromText('LineString(1 1,2 2)')) |
+------------------------------------------------+
|                                              1 |
+------------------------------------------------+

URL: https://mariadb.com/kb/en/st_dimension/https://mariadb.com/kb/en/st_dimension/j&#ST_ENVELOPESyntax
------

ST_ENVELOPE(g)
ENVELOPE(g)

Description
-----------

Returns the Minimum Bounding Rectangle (MBR) for the geometry value g. The
result is returned as a Polygon value.

The polygon is defined by the corner points of the bounding box:

POLYGON((MINX MINY, MAXX MINY, MAXX MAXY, MINX MAXY, MINX MINY))

ST_ENVELOPE() and ENVELOPE() are synonyms.

Examples
--------

SELECT AsText(ST_ENVELOPE(GeomFromText('LineString(1 1,4 4)')));
+----------------------------------------------------------+
| AsText(ST_ENVELOPE(GeomFromText('LineString(1 1,4 4)'))) |
+----------------------------------------------------------+
| POLYGON((1 1,4 1,4 4,1 4,1 1))                           |
+----------------------------------------------------------+

URL: https://mariadb.com/kb/en/st_envelope/https://mariadb.com/kb/en/st_envelope/�W�+�=uX����
mz&#ST_ISCLOSEDSyntax
------

ST_IsClosed(g)
IsClosed(g)

Description
-----------

Returns 1 if a given LINESTRING's start and end points are the same, or 0 if
they are not the same. Before MariaDB 10.1.5, returns NULL if not given a
LINESTRING. After MariaDB 10.1.5, returns -1.

ST_IsClosed() and IsClosed() are synonyms.

Examples
--------

SET @ls = 'LineString(0 0, 0 4, 4 4, 0 0)';
SELECT ST_ISCLOSED(GEOMFROMTEXT(@ls));
+--------------------------------+
| ST_ISCLOSED(GEOMFROMTEXT(@ls)) |
+--------------------------------+
|                              1 |
+--------------------------------+

SET @ls = 'LineString(0 0, 0 4, 4 4, 0 1)';
SELECT ST_ISCLOSED(GEOMFROMTEXT(@ls));
+--------------------------------+
| ST_ISCLOSED(GEOMFROMTEXT(@ls)) |
+--------------------------------+
|                              0 |
+--------------------------------+

URL: https://mariadb.com/kb/en/st_isclosed/https://mariadb.com/kb/en/st_isclosed/t	�$$LOAD_FILESyntax
------

LOAD_FILE(file_name)

Description
-----------

Reads the file and returns the file contents as a string. To use this
function, the file must be located on the server host, you must specify the
full path name to the file, and you must have the FILE privilege. The file
must be readable by all and it must be less than the size, in bytes, of the
max_allowed_packet system variable. If the secure_file_priv system variable is
set to a non-empty directory name, the file to be loaded must be located in
that directory.

If the file does not exist or cannot be read because one of the preceding
conditions is not satisfied, the function returns NULL.

Since MariaDB 5.1, the character_set_filesystem system variable has controlled
interpretation of file names that are given as literal strings.

Statements using the LOAD_FILE() function are not safe for statement based
replication. This is because the slave will execute the LOAD_FILE() command
itself. If the file doesn't exist on the slave, the function will return NULL.

Examples
--------

UPDATE t SET blob_col=LOAD_FILE('/tmp/picture') WHERE id=1;

URL: https://mariadb.com/kb/en/load_file/https://mariadb.com/kb/en/load_file/v�!$REGEXPSyntax
------

expr REGEXP pat, expr RLIKE pat

Description
-----------

Performs a pattern match of a string expression expr against a pattern pat.
The pattern can be an extended regular expression. See Regular Expressions
Overview for details on the syntax for regular expressions (see also PCRE
Regular Expressions).

Returns 1 if expr matches pat or 0 if it doesn't match. If either expr or pat
are NULL, the result is NULL.

The negative form NOT REGEXP also exists, as an alias for NOT (string REGEXP
pattern). RLIKE and NOT RLIKE are synonyms for REGEXP and NOT REGEXP,
originally provided for mSQL compatibility.

The pattern need not be a literal string. For example, it can be specified as
a string expression or table column.

Note: Because MariaDB uses the C escape syntax in strings (for example, "\n"
to represent the newline character), you must double any "\" that you use in
your REGEXP strings.

REGEXP is not case sensitive, except when used with binary strings.

MariaDB 10.0.5 moved to the PCRE regex library - see PCRE Regular Expressions
for enhancements to REGEXP introduced in MariaDB 10.0.5.

The default_regex_flags variable addresses the remaining compatibilities
between PCRE and the old regex library.

Examples
--------

SELECT 'Monty!' REGEXP 'm%y%%';
+-------------------------+
| 'Monty!' REGEXP 'm%y%%' |
+-------------------------+
|                       0 |
+-------------------------+

SELECT 'Monty!' REGEXP '.*';
+----------------------+
| 'Monty!' REGEXP '.*' |
+----------------------+
|                    1 |
+----------------------+

SELECT 'new*\n*line' REGEXP 'new\\*.\\*line';
+---------------------------------------+
| 'new*\n*line' REGEXP 'new\\*.\\*line' |
+---------------------------------------+
|                                     1 |
+---------------------------------------+

SELECT 'a' REGEXP 'A', 'a' REGEXP BINARY 'A';
+----------------+-----------------------+
| 'a' REGEXP 'A' | 'a' REGEXP BINARY 'A' |
+----------------+-----------------------+
|              1 |                     0 |
+----------------+-----------------------+

SELECT 'a' REGEXP '^[a-d]';
+---------------------+
| 'a' REGEXP '^[a-d]' |
+---------------------+
|                   1 |
+---------------------+

default_regex_flags examples
----------------------------

MariaDB 10.0.11 introduced the default_regex_flags variable to address the
remaining compatibilities between PCRE and the old regex library.

The default behaviour (multiline match is off)

SELECT 'a\nb\nc' RLIKE '^b$';
+---------------------------+
| '(?m)a\nb\nc' RLIKE '^b$' |
+---------------------------+
|                         0 |
+---------------------------+

Enabling the multiline option using the PCRE option syntax:

SELECT 'a\nb\nc' RLIKE '(?m)^b$';
+---------------------------+
| 'a\nb\nc' RLIKE '(?m)^b$' |
+---------------------------+
|                         1 |
+---------------------------+

Enabling the multiline option using default_regex_flags

SET default_regex_flags='MULTILINE';
SELECT 'a\nb\nc' RLIKE '^b$';
+-----------------------+
| 'a\nb\nc' RLIKE '^b$' |
+-----------------------+
|                     1 |
+-----------------------+

URL: https://mariadb.com/kb/en/regexp/https://mariadb.com/kb/en/regexp/�����p�L���w�'$REGEXP_INSTRSyntax
------

REGEXP_INSTR(subject, pattern)

Returns the position of the first occurrence of the regular expression pattern
in the string subject, or 0 if pattern was not found.

The positions start with 1 and are measured in characters (i.e. not in bytes),
which is important for multi-byte character sets. You can cast a multi-byte
character set to BINARY to get offsets in bytes.

The function follows the case sensitivity rules of the effective collation.
Matching is performed case insensitively for case insensitive collations, and
case sensitively for case sensitive collations and for binary data.

The collation case sensitivity can be overwritten using the (?i) and (?-i)
PCRE flags.

MariaDB uses the PCRE regular expression library for enhanced regular
expression performance, and REGEXP_INSTR was introduced as part of this
enhancement.

Examples
--------

SELECT REGEXP_INSTR('abc','b');
-> 2

SELECT REGEXP_INSTR('abc','x');
-> 0

SELECT REGEXP_INSTR('BJÖRN','N');
-> 5

Casting a multi-byte character set as BINARY to get offsets in bytes:

SELECT REGEXP_INSTR(BINARY 'BJÖRN','N') AS cast_utf8_to_binary;
-> 6

Case sensitivity:

SELECT REGEXP_INSTR('ABC','b');
-> 2

SELECT REGEXP_INSTR('ABC' COLLATE utf8_bin,'b');
-> 0

SELECT REGEXP_INSTR(BINARY'ABC','b');
-> 0

SELECT REGEXP_INSTR('ABC','(?-i)b');
-> 0

SELECT REGEXP_INSTR('ABC' COLLATE utf8_bin,'(?i)b');
-> 2

URL: https://mariadb.com/kb/en/regexp_instr/https://mariadb.com/kb/en/regexp_instr/xy)$REGEXP_REPLACESyntax
------

REGEXP_REPLACE(subject, pattern, replace)

Description
-----------

REGEXP_REPLACE returns the string subject with all occurrences of the regular
expression pattern replaced by the string replace. If no occurrences are
found, then subject is returned as is.

The replace string can have backreferences to the subexpressions in the form
\N, where N is a number from 1 to 9.

The function follows the case sensitivity rules of the effective collation.
Matching is performed case insensitively for case insensitive collations, and
case sensitively for case sensitive collations and for binary data.

The collation case sensitivity can be overwritten using the (?i) and (?-i)
PCRE flags.

MariaDB uses the PCRE regular expression library for enhanced regular
expression performance, and REGEXP_REPLACE was introduced as part of this
enhancement.

The default_regex_flags variable addresses the remaining compatibilities
between PCRE and the old regex library.

Examples
--------

SELECT REGEXP_REPLACE('ab12cd','[0-9]','') AS remove_digits;
-> abcd

SELECT
REGEXP_REPLACE('<html><head><title>title</title><body>body</body></htm>',
'<.+?>',' ')
AS strip_html;
-> title  body

Backreferences to the subexpressions in the form \N, where N is a number from
1 to 9:

SELECT REGEXP_REPLACE('James Bond','^(.*) (.*)$','\\2, \\1') AS reorder_name;
-> Bond, James

Case insensitive and case sensitive matches:

SELECT REGEXP_REPLACE('ABC','b','-') AS case_insensitive;
-> A-C

SELECT REGEXP_REPLACE('ABC' COLLATE utf8_bin,'b','-') AS case_sensitive;
-> ABC

SELECT REGEXP_REPLACE(BINARY 'ABC','b','-') AS binary_data;
-> ABC

Overwriting the collation case sensitivity using the (?i) and (?-i) PCRE flags.

SELECT REGEXP_REPLACE('ABC','(?-i)b','-') AS force_case_sensitive;
-> ABC

SELECT REGEXP_REPLACE(BINARY 'ABC','(?i)b','-') AS force_case_insensitive;
-> A-C

URL: https://mariadb.com/kb/en/regexp_replace/https://mariadb.com/kb/en/regexp_replace/y
�($REGEXP_SUBSTRSyntax
------

REGEXP_SUBSTR(subject,pattern)

Description
-----------

Returns the part of the string subject that matches the regular expression
pattern, or an empty string if pattern was not found.

The function follows the case sensitivity rules of the effective collation.
Matching is performed case insensitively for case insensitive collations, and
case sensitively for case sensitive collations and for binary data.

The collation case sensitivity can be overwritten using the (?i) and (?-i)
PCRE flags.

MariaDB uses the PCRE regular expression library for enhanced regular
expression performance, and REGEXP_SUBSTR was introduced as part of this
enhancement.

The default_regex_flags variable addresses the remaining compatibilities
between PCRE and the old regex library.

Examples
--------

SELECT REGEXP_SUBSTR('ab12cd','[0-9]+');
-> 12

SELECT REGEXP_SUBSTR(
 'See https://mariadb.org/en/foundation/ for details',
 'https?://[^/]*');
-> https://mariadb.org

SELECT REGEXP_SUBSTR('ABC','b');
-> B

SELECT REGEXP_SUBSTR('ABC' COLLATE utf8_bin,'b');
->

SELECT REGEXP_SUBSTR(BINARY'ABC','b');
->

SELECT REGEXP_SUBSTR('ABC','(?i)b');
-> B

SELECT REGEXP_SUBSTR('ABC' COLLATE utf8_bin,'(?+i)b');
-> B

URL: https://mariadb.com/kb/en/regexp_substr/https://mariadb.com/kb/en/regexp_substr/|�*$BINARY OperatorThis page describes the BINARY operator. For details about the data type, see
Binary Data Type.

Syntax
------

BINARY

Description
-----------

The BINARY operator casts the string following it to a binary string. This is
an easy way to force a column comparison to be done byte by byte rather than
character by character. This causes the comparison to be case sensitive even
if the column isn't defined as BINARY or BLOB.

BINARY also causes trailing spaces to be significant.

Examples
--------

SELECT 'a' = 'A';
+-----------+
| 'a' = 'A' |
+-----------+
|         1 |
+-----------+

SELECT BINARY 'a' = 'A';
+------------------+
| BINARY 'a' = 'A' |
+------------------+
|                0 |
+------------------+

SELECT 'a' = 'a ';
+------------+
| 'a' = 'a ' |
+------------+
|          1 |
+------------+

SELECT BINARY 'a' = 'a ';
+-------------------+
| BINARY 'a' = 'a ' |
+-------------------+
|                 0 |
+-------------------+

URL: https://mariadb.com/kb/en/binary-operator/https://mariadb.com/kb/en/binary-operator/�-�
,����rs��	~$CASTSyntax
------

CAST(expr AS type)

Description
-----------

The CAST() function takes a value of one type and produces a value of another
type, similar to the CONVERT() function.

The type can be one of the following values:

* BINARY
* CHAR
* DATE
* DATETIME
* DECIMAL[(M[,D])]
* DOUBLE
* FLOAT (from MariaDB 10.4.5)
* INTEGER
Short for SIGNED INTEGER

* SIGNED [INTEGER]
* UNSIGNED [INTEGER]
* TIME
* VARCHAR (in Oracle mode, from MariaDB 10.3)

The main difference between CAST and CONVERT() is that CONVERT(expr,type) is
ODBC syntax while CAST(expr as type) and CONVERT(... USING ...) are SQL92
syntax.

In MariaDB 10.4 and later, you can use the CAST() function with the INTERVAL
keyword.

Until MariaDB 5.5.31, X'HHHH', the standard SQL syntax for binary string
literals, erroneously worked in the same way as 0xHHHH. In 5.5.31 it was
intentionally changed to behave as a string in all contexts (and never as a
number).

This introduced an incompatibility with previous versions of MariaDB, and all
versions of MySQL (see the example below).

Examples
--------

Simple casts:

SELECT CAST("abc" AS BINARY);
SELECT CAST("1" AS UNSIGNED INTEGER);
SELECT CAST(123 AS CHAR CHARACTER SET utf8)

Note that when one casts to CHAR without specifying the character set, the
collation_connection character set collation will be used. When used with CHAR
CHARACTER SET, the default collation for that character set will be used.

SELECT COLLATION(CAST(123 AS CHAR));
+------------------------------+
| COLLATION(CAST(123 AS CHAR)) |
+------------------------------+
| latin1_swedish_ci            |
+------------------------------+

SELECT COLLATION(CAST(123 AS CHAR CHARACTER SET utf8));
+-------------------------------------------------+
| COLLATION(CAST(123 AS CHAR CHARACTER SET utf8)) |
+-------------------------------------------------+
| utf8_general_ci                                 |
+-------------------------------------------------+

If you also want to change the collation, you have to use the COLLATE operator:

SELECT COLLATION(CAST(123 AS CHAR CHARACTER SET utf8) 
 COLLATE utf8_unicode_ci);
+-------------------------------------------------------------------------+
| COLLATION(CAST(123 AS CHAR CHARACTER SET utf8) COLLATE utf8_unicode_ci) |
+-------------------------------------------------------------------------+
| utf8_unicode_ci                                                         |
+-------------------------------------------------------------------------+

Using CAST() to order an ENUM field as a CHAR rather than the internal
numerical value:

CREATE TABLE enum_list (enum_field enum('c','a','b'));

INSERT INTO enum_list (enum_field) 
VALUES('c'),('a'),('c'),('b');

SELECT * FROM enum_list 
ORDER BY enum_field;
+------------+
| enum_field |
+------------+
| c          |
| c          |
| a          |
| b          |
+------------+

SELECT * FROM enum_list 
ORDER BY CAST(enum_field AS CHAR);
+------------+
| enum_field |
+------------+
| a          |
| b          |
| c          |
| c          |
+------------+

From MariaDB 5.5.31, the following will trigger warnings, since x'aa' and
'X'aa' no longer behave as a number. Previously, and in all versions of MySQL,
no warnings are triggered since they did erroneously behave as a number:

SELECT CAST(0xAA AS UNSIGNED), CAST(x'aa' AS UNSIGNED), CAST(X'aa' AS
UNSIGNED);
+------------------------+-------------------------+-------------------------+
| CAST(0xAA AS UNSIGNED) | CAST(x'aa' AS UNSIGNED) | CAST(X'aa' AS UNSIGNED) |
+------------------------+-------------------------+-------------------------+
|                    170 |                       0 |                       0 |
+------------------------+-------------------------+-------------------------+
1 row in set, 2 warnings (0.00 sec)

Warning (Code 1292): Truncated incorrect INTEGER value: '\xAA'
Warning (Code 1292): Truncated incorrect INTEGER value: '\xAA'

Casting to intervals:

SELECT CAST(2019-01-04 INTERVAL AS DAY_SECOND(2)) AS "Cast";

+-------------+
| Cast        |
+-------------+
| 00:20:17.00 |
+-------------+

URL: https://mariadb.com/kb/en/cast/https://mariadb.com/kb/en/cast/
�($CHAR FunctionSyntax
------

CHAR(N,... [USING charset_name])

Description
-----------

CHAR() interprets each argument as an INT and returns a string consisting of
the characters given by the code values of those integers. NULL values are
skipped. By default, CHAR() returns a binary string. To produce a string in a
given character set, use the optional USING clause:

SELECT CHARSET(CHAR(0x65)), CHARSET(CHAR(0x65 USING utf8));
+---------------------+--------------------------------+
| CHARSET(CHAR(0x65)) | CHARSET(CHAR(0x65 USING utf8)) |
+---------------------+--------------------------------+
| binary              | utf8                           |
+---------------------+--------------------------------+

If USING is given and the result string is illegal for the given character
set, a warning is issued. Also, if strict SQL mode is enabled, the result from
CHAR() becomes NULL.

Examples
--------

SELECT CHAR(77,97,114,'105',97,'68',66);
+----------------------------------+
| CHAR(77,97,114,'105',97,'68',66) |
+----------------------------------+
| MariaDB                          |
+----------------------------------+

SELECT CHAR(77,77.3,'77.3');
+----------------------+
| CHAR(77,77.3,'77.3') |
+----------------------+
| MMM                  |
+----------------------+
1 row in set, 1 warning (0.00 sec)

Warning (Code 1292): Truncated incorrect INTEGER value: '77.3'

URL: https://mariadb.com/kb/en/char-function/https://mariadb.com/kb/en/char-function/T�H*1����&$CHAR_LENGTHSyntax
------

CHAR_LENGTH(str)
CHARACTER_LENGTH(str)

Description
-----------

Returns the length of the given string argument, measured in characters. A
multi-byte character counts as a single character. This means that for a
string containing five two-byte characters, LENGTH() (or OCTET_LENGTH() in
Oracle mode) returns 10, whereas CHAR_LENGTH() returns 5. If the argument is
NULL, it returns NULL.

If the argument is not a string value, it is converted into a string.

It is synonymous with the CHARACTER_LENGTH() function.

Examples
--------

SELECT CHAR_LENGTH('MariaDB');
+------------------------+
| CHAR_LENGTH('MariaDB') |
+------------------------+
|                      7 |
+------------------------+

When Oracle mode from MariaDB 10.3 is not set:

SELECT CHAR_LENGTH('π'), LENGTH('π'), LENGTHB('π'), OCTET_LENGTH('π');
+-------------------+--------------+---------------+--------------------+
| CHAR_LENGTH('π')  | LENGTH('π')  | LENGTHB('π')  | OCTET_LENGTH('π')  |
+-------------------+--------------+---------------+--------------------+
|                 1 |            2 |             2 |                  2 |
+-------------------+--------------+---------------+--------------------+

In Oracle mode from MariaDB 10.3:

SELECT CHAR_LENGTH('π'), LENGTH('π'), LENGTHB('π'), OCTET_LENGTH('π');
+-------------------+--------------+---------------+--------------------+
| CHAR_LENGTH('π')  | LENGTH('π')  | LENGTHB('π')  | OCTET_LENGTH('π')  |
+-------------------+--------------+---------------+--------------------+
|                 1 |            1 |             2 |                  2 |
+-------------------+--------------+---------------+--------------------+

URL: https://mariadb.com/kb/en/char_length/https://mariadb.com/kb/en/char_length/��$CHRMariaDB starting with 10.3.1
----------------------------
The CHR() function was introduced in MariaDB 10.3.1 to provide Oracle
compatibility

Syntax
------

CHR(N)

Description
-----------

CHR() interprets each argument N as an integer and returns a VARCHAR(1) string
consisting of the character given by the code values of the integer. The
character set and collation of the string are set according to the values of
the character_set_database and collation_database system variables.

CHR() is similar to the CHAR() function, but only accepts a single argument.

CHR() is available in all sql_modes.

Examples
--------

SELECT CHR(67);
+---------+
| CHR(67) |
+---------+
| C       |
+---------+

SELECT CHR('67');
+-----------+
| CHR('67') |
+-----------+
| C         |
+-----------+

SELECT CHR('C');
+----------+
| CHR('C') |
+----------+
|          |
+----------+
1 row in set, 1 warning (0.000 sec)

SHOW WARNINGS;
+---------+------+----------------------------------------+
| Level   | Code | Message                                |
+---------+------+----------------------------------------+
| Warning | 1292 | Truncated incorrect INTEGER value: 'C' |
+---------+------+----------------------------------------+

URL: https://mariadb.com/kb/en/chr/https://mariadb.com/kb/en/chr/�k!$CONCATSyntax
------

CONCAT(str1,str2,...)

Description
-----------

Returns the string that results from concatenating the arguments. May have one
or more arguments. If all arguments are non-binary strings, the result is a
non-binary string. If the arguments include any binary strings, the result is
a binary string. A numeric argument is converted to its equivalent binary
string form; if you want to avoid that, you can use an explicit type cast, as
in this example:

SELECT CONCAT(CAST(int_col AS CHAR), char_col);

CONCAT() returns NULL if any argument is NULL.

A NULL parameter hides all information contained in other parameters from the
result. Sometimes this is not desirable; to avoid this, you can:

* Use the CONCAT_WS() function with an empty separator, because that function
is NULL-safe.
* Use IFNULL() to turn NULLs into empty strings.

Oracle Mode
-----------

MariaDB starting with 10.3
--------------------------
In Oracle mode from MariaDB 10.3, CONCAT ignores NULL.

Examples
--------

SELECT CONCAT('Ma', 'ria', 'DB');
+---------------------------+
| CONCAT('Ma', 'ria', 'DB') |
+---------------------------+
| MariaDB                   |
+---------------------------+

SELECT CONCAT('Ma', 'ria', NULL, 'DB');
+---------------------------------+
| CONCAT('Ma', 'ria', NULL, 'DB') |
+---------------------------------+
| NULL                            |
+---------------------------------+

SELECT CONCAT(42.0);
+--------------+
| CONCAT(42.0) |
+--------------+
| 42.0         |
+--------------+

Using IFNULL() to handle NULLs:

SELECT CONCAT('The value of @v is: ', IFNULL(@v, ''));
+------------------------------------------------+
| CONCAT('The value of @v is: ', IFNULL(@v, '')) |
+------------------------------------------------+
| The value of @v is:                            |
+------------------------------------------------+

In Oracle mode, from MariaDB 10.3:

SELECT CONCAT('Ma', 'ria', NULL, 'DB');
+---------------------------------+
| CONCAT('Ma', 'ria', NULL, 'DB') |
+---------------------------------+
| MariaDB                         |
+---------------------------------+

URL: https://mariadb.com/kb/en/concat/https://mariadb.com/kb/en/concat/5������[�	'$$CONCAT_WSSyntax
------

CONCAT_WS(separator,str1,str2,...)

Description
-----------

CONCAT_WS() stands for Concatenate With Separator and is a special form of
CONCAT(). The first argument is the separator for the rest of the arguments.
The separator is added between the strings to be concatenated. The separator
can be a string, as can the rest of the arguments.

If the separator is NULL, the result is NULL; all other NULL values are
skipped. This makes CONCAT_WS() suitable when you want to concatenate some
values and avoid losing all information if one of them is NULL.

Examples
--------

SELECT CONCAT_WS(',','First name','Second name','Last Name');
+-------------------------------------------------------+
| CONCAT_WS(',','First name','Second name','Last Name') |
+-------------------------------------------------------+
| First name,Second name,Last Name                      |
+-------------------------------------------------------+

SELECT CONCAT_WS('-','Floor',NULL,'Room');
+------------------------------------+
| CONCAT_WS('-','Floor',NULL,'Room') |
+------------------------------------+
| Floor-Room                         |
+------------------------------------+

In some cases, remember to include a space in the separator string:

SET @a = 'gnu', @b = 'penguin', @c = 'sea lion';
Query OK, 0 rows affected (0.00 sec)

SELECT CONCAT_WS(', ', @a, @b, @c);
+-----------------------------+
| CONCAT_WS(', ', @a, @b, @c) |
+-----------------------------+
| gnu, penguin, sea lion      |
+-----------------------------+

Using CONCAT_WS() to handle NULLs:

SET @a = 'a', @b = NULL, @c = 'c';

SELECT CONCAT_WS('', @a, @b, @c);
+---------------------------+
| CONCAT_WS('', @a, @b, @c) |
+---------------------------+
| ac                        |
+---------------------------+

URL: https://mariadb.com/kb/en/concat_ws/https://mariadb.com/kb/en/concat_ws/��"$CONVERTSyntax
------

CONVERT(expr,type), CONVERT(expr USING transcoding_name)

Description
-----------

The	CONVERT() and CAST() functions take a value of one type and produce a
value of another type.

The type can be one of the following values:

* BINARY
* CHAR
* DATE
* DATETIME
* DECIMAL[(M[,D])]
* DOUBLE
* FLOAT (from MariaDB 10.4.5)
* INTEGER
Short for SIGNED INTEGER

* SIGNED [INTEGER]
* UNSIGNED [INTEGER]
* TIME
* VARCHAR (in Oracle mode, from MariaDB 10.3)

Note that in MariaDB, INT and INTEGER are the same thing.

BINARY produces a string with the BINARY data type. If the optional length is
given, BINARY(N) causes the cast to use no more than N bytes of the argument.
Values shorter than the given number in bytes are padded with 0x00 bytes to
make them equal the length value.

CHAR(N) causes the cast to use no more than the number of characters given in
the argument.

The main difference between the CAST() and CONVERT() is that
CONVERT(expr,type) is ODBC syntax while CAST(expr as type) and CONVERT(...
USING ...) are SQL92 syntax.

CONVERT() with USING is used to convert data between different character sets.
In MariaDB, transcoding names are the same as the corresponding character set
names. For example, this statement converts the string 'abc' in the default
character set to the corresponding string in the utf8 character set:

SELECT CONVERT('abc' USING utf8);

Examples
--------

SELECT enum_col FROM tbl_name 
ORDER BY CAST(enum_col AS CHAR);

Converting a BINARY to string to permit the LOWER function to work:

SET @x = 'AardVark';

SET @x = BINARY 'AardVark';

SELECT LOWER(@x), LOWER(CONVERT (@x USING latin1));
+-----------+----------------------------------+
| LOWER(@x) | LOWER(CONVERT (@x USING latin1)) |
+-----------+----------------------------------+
| AardVark  | aardvark                         |
+-----------+----------------------------------+

URL: https://mariadb.com/kb/en/convert/https://mariadb.com/kb/en/convert/�9$ELTSyntax
------

ELT(N, str1[, str2, str3,...])

Description
-----------

Takes a numeric argument and a series of string arguments. Returns the string
that corresponds to the given numeric position. For instance, it returns str1
if N is 1, str2 if N is 2, and so on. If the numeric argument is a FLOAT,
MariaDB rounds it to the nearest INTEGER. If the numeric argument is less than
1, greater than the total number of arguments, or not a number, ELT() returns
NULL. It must have at least two arguments.

It is complementary to the FIELD() function.

Examples
--------

SELECT ELT(1, 'ej', 'Heja', 'hej', 'foo');
+------------------------------------+
| ELT(1, 'ej', 'Heja', 'hej', 'foo') |
+------------------------------------+
| ej                                 |
+------------------------------------+

SELECT ELT(4, 'ej', 'Heja', 'hej', 'foo');
+------------------------------------+
| ELT(4, 'ej', 'Heja', 'hej', 'foo') |
+------------------------------------+
| foo                                |
+------------------------------------+

URL: https://mariadb.com/kb/en/elt/https://mariadb.com/kb/en/elt/-hn�b�`A�d�
1%$EXPORT_SETSyntax
------

EXPORT_SET(bits, on, off[, separator[, number_of_bits]])

Description
-----------

Takes a minimum of three arguments. Returns a string where each bit in the
given bits argument is returned, with the string values given for on and off.

Bits are examined from right to left, (from low-order to high-order bits).
Strings are added to the result from left to right, separated by a separator
string (defaults as ','). You can optionally limit the number of bits the
EXPORT_SET() function examines using the number_of_bits option.

If any of the arguments are set as NULL, the function returns NULL.

Examples
--------

SELECT EXPORT_SET(5,'Y','N',',',4);
+-----------------------------+
| EXPORT_SET(5,'Y','N',',',4) |
+-----------------------------+
| Y,N,Y,N                     |
+-----------------------------+

SELECT EXPORT_SET(6,'1','0',',',10);
+------------------------------+
| EXPORT_SET(6,'1','0',',',10) |
+------------------------------+
| 0,1,1,0,0,0,0,0,0,0          |
+------------------------------+

URL: https://mariadb.com/kb/en/export_set/https://mariadb.com/kb/en/export_set/��'$EXTRACTVALUESyntax
------

EXTRACTVALUE(xml_frag, xpath_expr)

Description
-----------

The EXTRACTVALUE() function takes two string arguments: a fragment of XML
markup and an XPath expression, (also known as a locator). It returns the text
(That is, CDDATA), of the first text node which is a child of the element or
elements matching the XPath expression.

In cases where a valid XPath expression does not match any text nodes in a
valid XML fragment, (including the implicit /text() expression), the
EXTRACTVALUE() function returns an empty string.

Invalid Arguments
-----------------

When either the XML fragment or the XPath expression is NULL, the
EXTRACTVALUE() function returns NULL. When the XML fragment is invalid, it
raises a warning Code 1525:

Warning (Code 1525): Incorrect XML value: 'parse error at line 1 pos 11:
unexpected END-OF-INPUT'

When the XPath value is invalid, it generates an Error 1105:

ERROR 1105 (HY000): XPATH syntax error: ')'

Explicit text() Expressions
---------------------------

This function is the equivalent of performing a match using the XPath
expression after appending /text(). In other words:

SELECT
 EXTRACTVALUE('<cases><case>example</case></cases>', '/cases/case')
  AS 'Base Example',
 EXTRACTVALUE('<cases><case>example</case></cases>', '/cases/case/text()')
  AS 'text() Example';
+--------------+----------------+
| Base Example | text() Example |
+--------------+----------------+
| example      | example        |
+--------------+----------------+

Count Matches
-------------

When EXTRACTVALUE() returns multiple matches, it returns the content of the
first child text node of each matching element, in the matched order, as a
single, space-delimited string.

By design, the EXTRACTVALUE() function makes no distinction between a match on
an empty element and no match at all. If you need to determine whether no
matching element was found in the XML fragment or if an element was found that
contained no child text nodes, use the XPath count() function.

For instance, when looking for a value that exists, but contains no child text
nodes, you would get a count of the number of matching instances:

SELECT
 EXTRACTVALUE('<cases><case/></cases>', '/cases/case')
  AS 'Empty Example',
 EXTRACTVALUE('<cases><case/></cases>', 'count(/cases/case)')
  AS 'count() Example';
+---------------+-----------------+
| Empty Example | count() Example |
+---------------+-----------------+
|               |               1 |
+---------------+-----------------+

Alternatively, when looking for a value that doesn't exist, count() returns 0.

SELECT
 EXTRACTVALUE('<cases><case/></cases>', '/cases/person')
  AS 'No Match Example',
 EXTRACTVALUE('<cases><case/></cases>', 'count(/cases/person)')
  AS 'count() Example';
+------------------+-----------------+
| No Match Example | count() Example |
+------------------+-----------------+
|                  |                0|
+------------------+-----------------+

Matches
-------

Important: The EXTRACTVALUE() function only returns CDDATA. It does not return
tags that the element might contain or the text that these child elements
contain.

SELECT

EXTRACTVALUE('<cases><case>Person<email>x@example.com</email></case></cases>',
'/cases')
 AS Case;
+--------+
| Case   |
+--------+
| Person |
+--------+

Note, in the above example, while the XPath expression matches to the parent
<case> instance, it does not return the contained <email> tag or its content.

Examples
--------

SELECT
  ExtractValue('<a>ccc<b>ddd</b></a>', '/a')            AS val1,
  ExtractValue('<a>ccc<b>ddd</b></a>', '/a/b')          AS val2,
  ExtractValue('<a>ccc<b>ddd</b></a>', '//b')           AS val3,
  ExtractValue('<a>ccc<b>ddd</b></a>', '/b')            AS val4,
  ExtractValue('<a>ccc<b>ddd</b><b>eee</b></a>', '//b') AS val5;
+------+------+------+------+---------+
| val1 | val2 | val3 | val4 | val5    |
+------+------+------+------+---------+
| ccc  | ddd  | ddd  |      | ddd eee |
+------+------+------+------+---------+

URL: https://mariadb.com/kb/en/extractvalue/https://mariadb.com/kb/en/extractvalue/zn�M*��� $FIELDSyntax
------

FIELD(pattern, str1[,str2,...])

Description
-----------

Returns the index position of the string or number matching the given pattern.
Returns 0 in the event that none of the arguments match the pattern. Raises an
Error 1582 if not given at least two arguments.

When all arguments given to the FIELD() function are strings, they are treated
as case-insensitive. When all the arguments are numbers, they are treated as
numbers. Otherwise, they are treated as doubles.

If the given pattern occurs more than once, the	FIELD() function only returns
the index of the first instance. If the given pattern is NULL, the function
returns 0, as a NULL pattern always fails to match.

This function is complementary to the ELT() function.

Examples
--------

SELECT FIELD('ej', 'Hej', 'ej', 'Heja', 'hej', 'foo') 
 AS 'Field Results';
+---------------+
| Field Results | 
+---------------+
|             2 |
+---------------+

SELECT FIELD('fo', 'Hej', 'ej', 'Heja', 'hej', 'foo')
 AS 'Field Results';
+---------------+
| Field Results | 
+---------------+
|             0 |
+---------------+

SELECT FIELD(1, 2, 3, 4, 5, 1) AS 'Field Results';
+---------------+
| Field Results |
+---------------+
|             5 |
+---------------+

SELECT FIELD(NULL, 2, 3) AS 'Field Results';
+---------------+
| Field Results |
+---------------+
|             0 |
+---------------+

SELECT FIELD('fail') AS 'Field Results';
Error 1582 (42000): Incorrect parameter count in call
to native function 'field'

URL: https://mariadb.com/kb/en/field/https://mariadb.com/kb/en/field/�P&$FIND_IN_SETSyntax
------

FIND_IN_SET(pattern, strlist)

Description
-----------

Returns the index position where the given pattern occurs in a string list.
The first argument is the pattern you want to search for. The second argument
is a string containing comma-separated variables. If the second argument is of
the SET data-type, the function is optimized to use bit arithmetic.

If the pattern does not occur in the string list or if the string list is an
empty string, the function returns 0. If either argument is NULL, the function
returns NULL. The function does not return the correct result if the pattern
contains a comma (",") character.

Examples
--------

SELECT FIND_IN_SET('b','a,b,c,d') AS "Found Results";
+---------------+
| Found Results |
+---------------+
|             2 |
+---------------+

URL: https://mariadb.com/kb/en/find_in_set/https://mariadb.com/kb/en/find_in_set/�U!$FORMATSyntax
------

FORMAT(num, decimal_position[, locale])

Description
-----------

Formats the given number for display as a string, adding separators to
appropriate position and rounding the results to the given decimal position.
For instance, it would format 15233.345 to 15,233.35.

If the given decimal position is 0, it rounds to return no decimal point or
fractional part. You can optionally specify a locale value to format numbers
to the pattern appropriate for the given region.

Examples
--------

SELECT FORMAT(1234567890.09876543210, 4) AS 'Format';
+--------------------+
| Format             |
+--------------------+
| 1,234,567,890.0988 |
+--------------------+

SELECT FORMAT(1234567.89, 4) AS 'Format';
+----------------+
| Format         |
+----------------+
| 1,234,567.8900 |
+----------------+

SELECT FORMAT(1234567.89, 0) AS 'Format';
+-----------+
| Format    |
+-----------+
| 1,234,568 |
+-----------+

SELECT FORMAT(123456789,2,'rm_CH') AS 'Format';
+----------------+
| Format         |
+----------------+
| 123'456'789,00 |
+----------------+

URL: https://mariadb.com/kb/en/format/https://mariadb.com/kb/en/format/�&$FROM_BASE64Syntax
------

FROM_BASE64(str)

Description
-----------

Decodes the given base-64 encode string, returning the result as a binary
string. Returns NULL if the given string is NULL or if it's invalid.

It is the reverse of the TO_BASE64 function.

There are numerous methods to base-64 encode a string. MariaDB uses the
following:

* It encodes alphabet value 64 as '+'.
* It encodes alphabet value 63 as '/'.
* It codes output in groups of four printable characters.  Each three byte of
data encoded uses four characters.  If the final group is incomplete, it pads
the difference with the '=' character.
* It divides long output, adding a new line very 76 characters.
* In decoding, it recognizes and ignores newlines, carriage returns, tabs and
space whitespace characters.

SELECT TO_BASE64('Maria') AS 'Input';
+-----------+
| Input     |
+-----------+
| TWFyaWE=  |
+-----------+

SELECT FROM_BASE64('TWFyaWE=') AS 'Output';
+--------+
| Output |
+--------+
| Maria  |
+--------+

URL: https://mariadb.com/kb/en/from_base64/https://mariadb.com/kb/en/from_base64/�I$HEXSyntax
------

HEX(N_or_S)

Description
-----------

If N_or_S is a number, returns a string representation of the hexadecimal
value of N, where N is a longlong (BIGINT) number. This is equivalent to
CONV(N,10,16).

If N_or_S is a string, returns a hexadecimal string representation of N_or_S
where each byte of each character in N_or_S is converted to two hexadecimal
digits. If N_or_S is NULL, returns NULL. The inverse of this operation is
performed by the UNHEX() function.

MariaDB starting with 10.5.0
----------------------------
HEX() with an INET6 argument returns a hexadecimal representation of the
underlying 16-byte binary string.

Examples
--------

SELECT HEX(255);
+----------+
| HEX(255) |
+----------+
| FF       |
+----------+

SELECT 0x4D617269614442;
+------------------+
| 0x4D617269614442 |
+------------------+
| MariaDB          |
+------------------+

SELECT HEX('MariaDB');
+----------------+
| HEX('MariaDB') |
+----------------+
| 4D617269614442 |
+----------------+

From MariaDB 10.5.0:

SELECT HEX(CAST('2001:db8::ff00:42:8329' AS INET6));
+----------------------------------------------+
| HEX(CAST('2001:db8::ff00:42:8329' AS INET6)) |
+----------------------------------------------+
| 20010DB8000000000000FF0000428329             |
+----------------------------------------------+

URL: https://mariadb.com/kb/en/hex/https://mariadb.com/kb/en/hex/�x\D�	�C�7"��p��*$INSERT FunctionSyntax
------

INSERT(str,pos,len,newstr)

Description
-----------

Returns the string str, with the substring beginning at position pos and len
characters long replaced by the string newstr. Returns the original string if
pos is not within the length of the string. Replaces the rest of the string
from position pos if len is not within the length of the rest of the string.
Returns NULL if any argument is NULL.

Examples
--------

SELECT INSERT('Quadratic', 3, 4, 'What');
+-----------------------------------+
| INSERT('Quadratic', 3, 4, 'What') |
+-----------------------------------+
| QuWhattic                         |
+-----------------------------------+

SELECT INSERT('Quadratic', -1, 4, 'What');
+------------------------------------+
| INSERT('Quadratic', -1, 4, 'What') |
+------------------------------------+
| Quadratic                          |
+------------------------------------+

SELECT INSERT('Quadratic', 3, 100, 'What');
+-------------------------------------+
| INSERT('Quadratic', 3, 100, 'What') |
+-------------------------------------+
| QuWhat                              |
+-------------------------------------+

URL: https://mariadb.com/kb/en/insert-function/https://mariadb.com/kb/en/insert-function/��!$LENGTHSyntax
------

LENGTH(str)

Description
-----------

Returns the length of the string str.

In the default mode, when Oracle mode from MariaDB 10.3 is not set, the length
is measured in bytes. In this case, a multi-byte character counts as multiple
bytes. This means that for a string containing five two-byte characters,
LENGTH() returns 10, whereas CHAR_LENGTH() returns 5.

When running Oracle mode from MariaDB 10.3, the length is measured in
characters, and LENGTH is a synonym for CHAR_LENGTH().

If str is not a string value, it is converted into a string. If str is NULL,
the function returns NULL.

Examples
--------

SELECT LENGTH('MariaDB');
+-------------------+
| LENGTH('MariaDB') |
+-------------------+
|                 7 |
+-------------------+

When Oracle mode from MariaDB 10.3 is not set:

SELECT CHAR_LENGTH('π'), LENGTH('π'), LENGTHB('π'), OCTET_LENGTH('π');
+-------------------+--------------+---------------+--------------------+
| CHAR_LENGTH('π')  | LENGTH('π')  | LENGTHB('π')  | OCTET_LENGTH('π')  |
+-------------------+--------------+---------------+--------------------+
|                 1 |            2 |             2 |                  2 |
+-------------------+--------------+---------------+--------------------+

In Oracle mode from MariaDB 10.3:

SELECT CHAR_LENGTH('π'), LENGTH('π'), LENGTHB('π'), OCTET_LENGTH('π');
+-------------------+--------------+---------------+--------------------+
| CHAR_LENGTH('π')  | LENGTH('π')  | LENGTHB('π')  | OCTET_LENGTH('π')  |
+-------------------+--------------+---------------+--------------------+
|                 1 |            1 |             2 |                  2 |
+-------------------+--------------+---------------+--------------------+

URL: https://mariadb.com/kb/en/length/https://mariadb.com/kb/en/length/�]"$LENGTHBMariaDB starting with 10.3.1
----------------------------
Introduced in MariaDB 10.3.1 as part of the Oracle compatibility enhancements.

Syntax
------

LENGTHB(str)

Description
-----------

LENGTHB() returns the length of the given string, in bytes. When Oracle mode
is not set, this is a synonym for LENGTH.

A multi-byte character counts as multiple bytes. This means that for a string
containing five two-byte characters, LENGTHB() returns 10, whereas
CHAR_LENGTH() returns 5.

If str is not a string value, it is converted into a string. If str is NULL,
the function returns NULL.

Examples
--------

When Oracle mode from MariaDB 10.3 is not set:

SELECT CHAR_LENGTH('π'), LENGTH('π'), LENGTHB('π'), OCTET_LENGTH('π');
+-------------------+--------------+---------------+--------------------+
| CHAR_LENGTH('π')  | LENGTH('π')  | LENGTHB('π')  | OCTET_LENGTH('π')  |
+-------------------+--------------+---------------+--------------------+
|                 1 |            2 |             2 |                  2 |
+-------------------+--------------+---------------+--------------------+

In Oracle mode from MariaDB 10.3:

SELECT CHAR_LENGTH('π'), LENGTH('π'), LENGTHB('π'), OCTET_LENGTH('π');
+-------------------+--------------+---------------+--------------------+
| CHAR_LENGTH('π')  | LENGTH('π')  | LENGTHB('π')  | OCTET_LENGTH('π')  |
+-------------------+--------------+---------------+--------------------+
|                 1 |            1 |             2 |                  2 |
+-------------------+--------------+---------------+--------------------+

URL: https://mariadb.com/kb/en/lengthb/https://mariadb.com/kb/en/lengthb/��!$LOCATESyntax
------

LOCATE(substr,str), LOCATE(substr,str,pos)

Description
-----------

The first syntax returns the position of the first occurrence of substring
substr in string str. The second syntax returns the position of the first
occurrence of substring substr in string str, starting at position pos.
Returns 0 if substr is not in str.

LOCATE() performs a case-insensitive search.

If any argument is NULL, returns NULL.

INSTR() is the same as the two-argument form of LOCATE(), except that the
order of the arguments is reversed.

Examples
--------

SELECT LOCATE('bar', 'foobarbar');
+----------------------------+
| LOCATE('bar', 'foobarbar') |
+----------------------------+
|                          4 |
+----------------------------+

SELECT LOCATE('My', 'Maria');
+-----------------------+
| LOCATE('My', 'Maria') |
+-----------------------+
|                     0 |
+-----------------------+

SELECT LOCATE('bar', 'foobarbar', 5);
+-------------------------------+
| LOCATE('bar', 'foobarbar', 5) |
+-------------------------------+
|                             7 |
+-------------------------------+

URL: https://mariadb.com/kb/en/locate/https://mariadb.com/kb/en/locate/��/�.���<��
��$LIKESyntax
------

expr LIKE pat [ESCAPE 'escape_char']
expr NOT LIKE pat [ESCAPE 'escape_char']

Description
-----------

Tests whether expr matches the pattern pat. Returns either 1 (TRUE) or 0
(FALSE). Both expr and pat may be any valid expression and are evaluated to
strings. Patterns may use the following wildcard characters:

* % matches any number of characters, including zero.
* _ matches any single character.

Use NOT LIKE to test if a string does not match a pattern. This is equivalent
to using the NOT operator on the entire LIKE expression.

If either the expression or the pattern is NULL, the result is NULL.

LIKE performs case-insensitive substring matches if the collation for the
expression and pattern is case-insensitive. For case-sensitive matches,
declare either argument to use a binary collation using COLLATE, or coerce
either of them to a BINARY string using CAST. Use SHOW COLLATION to get a list
of available collations. Collations ending in _bin are case-sensitive.

Numeric arguments are coerced to binary strings.

The _ wildcard matches a single character, not byte. It will only match a
multi-byte character if it is valid in the expression's character set. For
example, _ will match _utf8"€", but it will not match _latin1"€" because the
Euro sign is not a valid latin1 character. If necessary, use CONVERT to use
the expression in a different character set.

If you need to match the characters _ or %, you must escape them. By default,
you can prefix the wildcard characters the backslash character \ to escape
them. The backslash is used both to encode special characters like newlines
when a string is parsed as well as to escape wildcards in a pattern after
parsing. Thus, to match an actual backslash, you sometimes need to
double-escape it as "\\\\".

To avoid difficulties with the backslash character, you can change the
wildcard escape character using ESCAPE in a LIKE expression. The argument to
ESCAPE must be a single-character string.

Examples
--------

Select the days that begin with "T":

CREATE TABLE t1 (d VARCHAR(16));
INSERT INTO t1 VALUES 
 ("Monday"), ("Tuesday"), ("Wednesday"),
 ("Thursday"), ("Friday"), ("Saturday"), ("Sunday");
SELECT * FROM t1 WHERE d LIKE "T%";

SELECT * FROM t1 WHERE d LIKE "T%";
+----------+
| d        |
+----------+
| Tuesday  |
| Thursday |
+----------+

Select the days that contain the substring "es":

SELECT * FROM t1 WHERE d LIKE "%es%";

SELECT * FROM t1 WHERE d LIKE "%es%";
+-----------+
| d         |
+-----------+
| Tuesday   |
| Wednesday |
+-----------+

Select the six-character day names:

SELECT * FROM t1 WHERE d like "___day";

SELECT * FROM t1 WHERE d like "___day";
+---------+
| d       |
+---------+
| Monday  |
| Friday  |
| Sunday  |
+---------+

With the default collations, LIKE is case-insensitive:

SELECT * FROM t1 where d like "t%";

SELECT * FROM t1 where d like "t%";
+----------+
| d        |
+----------+
| Tuesday  |
| Thursday |
+----------+

Use COLLATE to specify a binary collation, forcing case-sensitive matches:

SELECT * FROM t1 WHERE d like "t%" COLLATE latin1_bin;

SELECT * FROM t1 WHERE d like "t%" COLLATE latin1_bin;
Empty set (0.00 sec)

You can include functions and operators in the expression to match. Select
dates based on their day name:

CREATE TABLE t2 (d DATETIME);
INSERT INTO t2 VALUES
  ("2007-01-30 21:31:07"),
  ("1983-10-15 06:42:51"),
  ("2011-04-21 12:34:56"),
  ("2011-10-30 06:31:41"),
  ("2011-01-30 14:03:25"),
  ("2004-10-07 11:19:34");
SELECT * FROM t2 WHERE DAYNAME(d) LIKE "T%";

SELECT * FROM t2 WHERE DAYNAME(d) LIKE "T%";
+------------------+
| d                |
+------------------+
| 2007-01-30 21:31 |
| 2011-04-21 12:34 |
| 2004-10-07 11:19 |
+------------------+
3 rows in set, 7 warnings (0.00 sec)

Optimizing LIKE
---------------

* MariaDB can use indexes for LIKE on string columns in the case where the
LIKE doesn't start with % or _.
* Starting from MariaDB 10.0, one can set  the
optimizer_use_condition_selectivity variable to 5. If this is done, then the
optimizer will read optimizer_selectivity_sampling_limit rows to calculate the
selectivity of the LIKE expression before starting to calculate the query
plan. This can help speed up some LIKE queries by providing the optimizer with
more information about your data.

URL: https://mariadb.com/kb/en/like/https://mariadb.com/kb/en/like/�� $LOWERSyntax
------

LOWER(str)

Description
-----------

Returns the string str with all characters changed to lowercase according to
the current character set mapping. The default is latin1 (cp1252 West
European).

Examples
--------

SELECT LOWER('QUADRATICALLY');
+------------------------+
| LOWER('QUADRATICALLY') |
+------------------------+
| quadratically          |
+------------------------+

LOWER() (and UPPER()) are ineffective when applied to binary strings (BINARY,
VARBINARY, BLOB). To perform lettercase conversion, CONVERT the string to a
non-binary string:

SET @str = BINARY 'North Carolina';

SELECT LOWER(@str), LOWER(CONVERT(@str USING latin1));
+----------------+-----------------------------------+
| LOWER(@str)    | LOWER(CONVERT(@str USING latin1)) |
+----------------+-----------------------------------+
| North Carolina | north carolina                    |
+----------------+-----------------------------------+

URL: https://mariadb.com/kb/en/lower/https://mariadb.com/kb/en/lower/5)J�;�F��$LPADSyntax
------

LPAD(str, len [,padstr])

Description
-----------

Returns the string str, left-padded with the string padstr to a length of len
characters. If str is longer than len, the return value is shortened to len
characters. If padstr is omitted, the LPAD function pads spaces.

Prior to MariaDB 10.3.1, the padstr parameter was mandatory.

Returns NULL if given a NULL argument. If the result is empty (zero length),
returns either an empty string or, from MariaDB 10.3.6 with SQL_MODE=Oracle,
NULL.

The Oracle mode version of the function can be accessed outside of Oracle mode
by using LPAD_ORACLE as the function name.

Examples
--------

SELECT LPAD('hello',10,'.');
+----------------------+
| LPAD('hello',10,'.') |
+----------------------+
| .....hello           |
+----------------------+

SELECT LPAD('hello',2,'.');
+---------------------+
| LPAD('hello',2,'.') |
+---------------------+
| he                  |
+---------------------+

From MariaDB 10.3.1, with the pad string defaulting to space.

SELECT LPAD('hello',10);
+------------------+
| LPAD('hello',10) |
+------------------+
|      hello       |
+------------------+

Oracle mode version from MariaDB 10.3.6:

SELECT LPAD('',0),LPAD_ORACLE('',0);
+------------+-------------------+
| LPAD('',0) | LPAD_ORACLE('',0) |
+------------+-------------------+
|            | NULL              |
+------------+-------------------+

URL: https://mariadb.com/kb/en/lpad/https://mariadb.com/kb/en/lpad/� $LTRIMSyntax
------

LTRIM(str)

Description
-----------

Returns the string str with leading space characters removed.

Returns NULL if given a NULL argument. If the result is empty, returns either
an empty string, or, from MariaDB 10.3.6 with SQL_MODE=Oracle, NULL.

The Oracle mode version of the function can be accessed outside of Oracle mode
by using LTRIM_ORACLE as the function name.

Examples
--------

SELECT QUOTE(LTRIM('   MariaDB   '));
+-------------------------------+
| QUOTE(LTRIM('   MariaDB   ')) |
+-------------------------------+
| 'MariaDB   '                  |
+-------------------------------+

Oracle mode version from MariaDB 10.3.6:

SELECT LTRIM(''),LTRIM_ORACLE('');
+-----------+------------------+
| LTRIM('') | LTRIM_ORACLE('') |
+-----------+------------------+
|           | NULL             |
+-----------+------------------+

URL: https://mariadb.com/kb/en/ltrim/https://mariadb.com/kb/en/ltrim/�>#$MAKE_SETSyntax
------

MAKE_SET(bits,str1,str2,...)

Description
-----------

Returns a set value (a string containing substrings separated by ","
characters) consisting of the strings that have the corresponding bit in bits
set. str1 corresponds to bit 0, str2 to bit 1, and so on. NULL values in str1,
str2, ... are not appended to the result.

Examples
--------

SELECT MAKE_SET(1,'a','b','c');
+-------------------------+
| MAKE_SET(1,'a','b','c') |
+-------------------------+
| a                       |
+-------------------------+

SELECT MAKE_SET(1 | 4,'hello','nice','world');
+----------------------------------------+
| MAKE_SET(1 | 4,'hello','nice','world') |
+----------------------------------------+
| hello,world                            |
+----------------------------------------+

SELECT MAKE_SET(1 | 4,'hello','nice',NULL,'world');
+---------------------------------------------+
| MAKE_SET(1 | 4,'hello','nice',NULL,'world') |
+---------------------------------------------+
| hello                                       |
+---------------------------------------------+

SELECT QUOTE(MAKE_SET(0,'a','b','c'));
+--------------------------------+
| QUOTE(MAKE_SET(0,'a','b','c')) |
+--------------------------------+
| ''                             |
+--------------------------------+

URL: https://mariadb.com/kb/en/make_set/https://mariadb.com/kb/en/make_set/�
]($MATCH AGAINSTSyntax
------

MATCH (col1,col2,...) AGAINST (expr [search_modifier])

Description
-----------

A special construct used to perform a fulltext search on a fulltext index.

See Fulltext Index Overview for a full description, and Full-text Indexes for
more articles on the topic.

Examples
--------

CREATE TABLE ft_myisam(copy TEXT,FULLTEXT(copy)) ENGINE=MyISAM;

INSERT INTO ft_myisam(copy) VALUES ('Once upon a time'), ('There was a wicked
witch'), 
 ('Who ate everybody up');

SELECT * FROM ft_myisam WHERE MATCH(copy) AGAINST('wicked');
+--------------------------+
| copy                     |
+--------------------------+
| There was a wicked witch |
+--------------------------+

SELECT id, body, MATCH (title,body) AGAINST
  ('Security implications of running MySQL as root'
  IN NATURAL LANGUAGE MODE) AS score
  FROM articles WHERE MATCH (title,body) AGAINST
  ('Security implications of running MySQL as root'
  IN NATURAL LANGUAGE MODE);
+----+-------------------------------------+-----------------+
| id | body                                | score           |
+----+-------------------------------------+-----------------+
|  4 | 1. Never run mysqld as root. 2. ... | 1.5219271183014 |
|  6 | When configured properly, MySQL ... | 1.3114095926285 |
+----+-------------------------------------+-----------------+

URL: https://mariadb.com/kb/en/match-against/https://mariadb.com/kb/en/match-against/��	w��������+$NATURAL_SORT_KEYMariaDB starting with 10.7.0
----------------------------
NATURAL_SORT_KEY was added in MariaDB 10.7.0.

Syntax
------

NATURAL_SORT_KEY(str)

Description
-----------

The NATURAL_SORT_KEY function is used for sorting that is closer to natural
sorting. Strings are sorted in alphabetical order, while numbers are treated
in a way such that, for example, 10 is greater than 2, whereas in other forms
of sorting, 2 would be greater than 10, just like z is greater than ya.

There are multiple natural sort implementations, differing in the way they
handle leading zeroes, fractions, i18n, negatives, decimals and so on.

MariaDB's implementation ignores leading zeroes when performing the sort.

You can use also use NATURAL_SORT_KEY with generated columns. The value is not
stored permanently in the table. When using a generated column, the virtual
column must be longer than the base column to cater for embedded numbers in
the string and MDEV-24582.

Examples
--------

Strings and Numbers
-------------------

CREATE TABLE t1 (c TEXT);

INSERT INTO t1 VALUES ('b1'),('a2'),('a11'),('a1');

SELECT c FROM t1;
+------+
| c    |
+------+
| b1   |
| a2   |
| a11  |
| a1   |
+------+

SELECT c FROM t1 ORDER BY c;
+------+
| c    |
+------+
| a1   |
| a11  |
| a2   |
| b1   |
+------+

Unsorted, regular sort and natural sort:

TRUNCATE t1;

INSERT INTO t1 VALUES 
 ('5.5.31'),('10.7.0'),('10.2.1'),
 ('10.1.22'),('10.3.32'),('10.2.12');

SELECT c FROM t1;
+---------+
| c       |
+---------+
| 5.5.31  |
| 10.7.0  |
| 10.2.1  |
| 10.1.22 |
| 10.3.32 |
| 10.2.12 |
+---------+

SELECT c FROM t1 ORDER BY c;
+---------+
| c       |
+---------+
| 10.1.22 |
| 10.2.1  |
| 10.2.12 |
| 10.3.32 |
| 10.7.0  |
| 5.5.31  |
+---------+

SELECT c FROM t1 ORDER BY NATURAL_SORT_KEY(c);
+---------+
| c       |
+---------+
| 5.5.31  |
| 10.1.22 |
| 10.2.1  |
| 10.2.12 |
| 10.3.32 |
| 10.7.0  |
+---------+

IPs
---

Sorting IPs, unsorted, regular sort and natural sort::

TRUNCATE t1;

INSERT INTO t1 VALUES 
 ('192.167.3.1'),('192.167.1.12'),('100.200.300.400'),
 ('100.50.60.70'),('100.8.9.9'),('127.0.0.1'),('0.0.0.0');

SELECT c FROM t1;
+-----------------+
| c               |
+-----------------+
| 192.167.3.1     |
| 192.167.1.12    |
| 100.200.300.400 |
| 100.50.60.70    |
| 100.8.9.9       |
| 127.0.0.1       |
| 0.0.0.0         |
+-----------------+

SELECT c FROM t1 ORDER BY c;
+-----------------+
| c               |
+-----------------+
| 0.0.0.0         |
| 100.200.300.400 |
| 100.50.60.70    |
| 100.8.9.9       |
| 127.0.0.1       |
| 192.167.1.12    |
| 192.167.3.1     |
+-----------------+

SELECT c FROM t1 ORDER BY NATURAL_SORT_KEY(c);
+-----------------+
| c               |
+-----------------+
| 0.0.0.0         |
| 100.8.9.9       |
| 100.50.60.70    |
| 100.200.300.400 |
| 127.0.0.1       |
| 192.167.1.12    |
| 192.167.3.1     |
+-----------------+

Generated Columns
-----------------

Using with a generated column:

CREATE TABLE t(c VARCHAR(3), k VARCHAR(4) AS (NATURAL_SORT_KEY(c)) INVISIBLE);

INSERT INTO t(c) VALUES ('b1'),('a2'),('a11'),('a10');

SELECT * FROM t ORDER by k;
+------+
| c    |
+------+
| a2   |
| a10  |
| a11  |
| b1   |
+------+

Note that if the virtual column is not longer, results may not be as expected:

CREATE TABLE t2(c VARCHAR(3), k VARCHAR(3) AS (NATURAL_SORT_KEY(c)) INVISIBLE);

INSERT INTO t2(c) VALUES ('b1'),('a2'),('a11'),('a10');

SELECT * FROM t2 ORDER by k;
+------+
| c    |
+------+
| a2   |
| a11  |
| a10  |
| b1   |
+------+

Leading Zeroes
--------------

Ignoring leading zeroes can lead to undesirable results in certain contexts.
For example:

CREATE TABLE t3 (a VARCHAR(4));

INSERT INTO t3 VALUES 
 ('a1'), ('a001'), ('a10'), ('a001'), ('a10'),
 ('a01'), ('a01'), ('a01b'), ('a01b'), ('a1');

SELECT a FROM t3 ORDER BY a;
+------+
| a    |
+------+
| a001 |
| a001 |
| a01  |
| a01  |
| a01b |
| a01b |
| a1   |
| a1   |
| a10  |
| a10  |
+------+
10 rows in set (0.000 sec)

SELECT a FROM t3 ORDER BY NATURAL_SORT_KEY(a);
+------+
| a    |
+------+
| a1   |
| a01  |
| a01  |
| a001 |
| a001 |
| a1   |
| a01b |
| a01b |
| a10  |
| a10  |
+------+

This may not be what we were hoping for in a 'natural' sort. A workaround is
to sort by both NATURAL_SORT_KEY and regular sort.

SELECT a FROM t3 ORDER BY NATURAL_SORT_KEY(a), a;
+------+
| a    |
+------+
| a001 |
| a001 |
| a01  |
| a01  |
| a1   |
| a1   |
| a01b |
| a01b |
| a10  |
| a10  |
+------+

URL: https://mariadb.com/kb/en/natural_sort_key/https://mariadb.com/kb/en/natural_sort_key/�"'$OCTET_LENGTHSyntax
------

OCTET_LENGTH(str)

Description
-----------

OCTET_LENGTH() returns the length of the given string, in octets (bytes). This
is a synonym for LENGTHB(), and, when Oracle mode from MariaDB 10.3 is not
set, a synonym for LENGTH().

A multi-byte character counts as multiple bytes. This means that for a string
containing five two-byte characters, OCTET_LENGTH() returns 10, whereas
CHAR_LENGTH() returns 5.

If str is not a string value, it is converted into a string. If str is NULL,
the function returns NULL.

Examples
--------

When Oracle mode from MariaDB 10.3 is not set:

SELECT CHAR_LENGTH('π'), LENGTH('π'), LENGTHB('π'), OCTET_LENGTH('π');
+-------------------+--------------+---------------+--------------------+
| CHAR_LENGTH('π')  | LENGTH('π')  | LENGTHB('π')  | OCTET_LENGTH('π')  |
+-------------------+--------------+---------------+--------------------+
|                 1 |            2 |             2 |                  2 |
+-------------------+--------------+---------------+--------------------+

In Oracle mode from MariaDB 10.3:

SELECT CHAR_LENGTH('π'), LENGTH('π'), LENGTHB('π'), OCTET_LENGTH('π');
+-------------------+--------------+---------------+--------------------+
| CHAR_LENGTH('π')  | LENGTH('π')  | LENGTHB('π')  | OCTET_LENGTH('π')  |
+-------------------+--------------+---------------+--------------------+
|                 1 |            1 |             2 |                  2 |
+-------------------+--------------+---------------+--------------------+

URL: https://mariadb.com/kb/en/octet_length/https://mariadb.com/kb/en/octet_length/�c�<>t����$RPADSyntax
------

RPAD(str, len [, padstr])

Description
-----------

Returns the string str, right-padded with the string padstr to a length of len
characters. If str is longer than len, the return value is shortened to len
characters. If padstr is omitted, the RPAD function pads spaces.

Prior to MariaDB 10.3.1, the padstr parameter was mandatory.

Returns NULL if given a NULL argument. If the result is empty (a length of
zero), returns either an empty string, or, from MariaDB 10.3.6 with
SQL_MODE=Oracle, NULL.

The Oracle mode version of the function can be accessed outside of Oracle mode
by using RPAD_ORACLE as the function name.

Examples
--------

SELECT RPAD('hello',10,'.');
+----------------------+
| RPAD('hello',10,'.') |
+----------------------+
| hello.....           |
+----------------------+

SELECT RPAD('hello',2,'.');
+---------------------+
| RPAD('hello',2,'.') |
+---------------------+
| he                  |
+---------------------+

From MariaDB 10.3.1, with the pad string defaulting to space.

SELECT RPAD('hello',30);
+--------------------------------+
| RPAD('hello',30)               |
+--------------------------------+
| hello                          |
+--------------------------------+

Oracle mode version from MariaDB 10.3.6:

SELECT RPAD('',0),RPAD_ORACLE('',0);
+------------+-------------------+
| RPAD('',0) | RPAD_ORACLE('',0) |
+------------+-------------------+
|            | NULL              |
+------------+-------------------+

URL: https://mariadb.com/kb/en/rpad/https://mariadb.com/kb/en/rpad/�t $RTRIMSyntax
------

RTRIM(str)

Description
-----------

Returns the string str with trailing space characters removed.

Returns NULL if given a NULL argument. If the result is empty, returns either
an empty string, or, from MariaDB 10.3.6 with SQL_MODE=Oracle, NULL.

The Oracle mode version of the function can be accessed outside of Oracle mode
by using RTRIM_ORACLE as the function name.

Examples
--------

SELECT QUOTE(RTRIM('MariaDB    '));
+-----------------------------+
| QUOTE(RTRIM('MariaDB    ')) |
+-----------------------------+
| 'MariaDB'                   |
+-----------------------------+

Oracle mode version from MariaDB 10.3.6:

SELECT RTRIM(''),RTRIM_ORACLE('');
+-----------+------------------+
| RTRIM('') | RTRIM_ORACLE('') |
+-----------+------------------+
|           | NULL             |
+-----------+------------------+

URL: https://mariadb.com/kb/en/rtrim/https://mariadb.com/kb/en/rtrim/��"$SFORMATMariaDB starting with 10.7.0
----------------------------
SFORMAT was added in MariaDB 10.7.0.

Description
-----------

The SFORMAT function takes an input string and a formatting specification and
returns the string formatted using the rules the user passed in the
specification.

It uses the fmtlib library for Python-like (as well as Rust, C++20, etc)
string formatting.

Only fmtlib 7.0.0+ is supported.

There is no native support for temporal and decimal values:

* TIME_RESULT is handled as STRING_RESULT
* DECIMAL_RESULT as REAL_RESULT

Examples
--------

SELECT SFORMAT("The answer is {}.", 42);
+----------------------------------+
| SFORMAT("The answer is {}.", 42) |
+----------------------------------+
| The answer is 42.                |
+----------------------------------+

CREATE TABLE test_sformat(mdb_release char(6), mdev int, feature char(20));

INSERT INTO test_sformat VALUES('10.7.0', 25015, 'Python style sformat'), 
 ('10.7.0', 4958, 'UUID');

SELECT * FROM test_sformat;
+-------------+-------+----------------------+
| mdb_release | mdev  | feature              |
+-------------+-------+----------------------+
| 10.7.0      | 25015 | Python style sformat |
| 10.7.0      |  4958 | UUID                 |
+-------------+-------+----------------------+

SELECT SFORMAT('MariaDB Server {} has a preview for MDEV-{} which is about
{}', 
 mdb_release, mdev, feature) AS 'Preview Release Examples'
 FROM test_sformat;
+------------------------------------------------------------------------------
---------+
| Preview Release Examples                                                    
     |
+------------------------------------------------------------------------------
---------+
| MariaDB Server 10.7.0 has a preview for MDEV-25015 which is about Python
style sformat |
| MariaDB Server 10.7.0 has a preview for MDEV-4958 which is about UUID       
     |
+------------------------------------------------------------------------------
---------+

URL: https://mariadb.com/kb/en/sformat/https://mariadb.com/kb/en/sformat/��"$SOUNDEXSyntax
------

SOUNDEX(str)

Description
-----------

Returns a soundex string from str. Two strings that sound almost the same
should have identical soundex strings. A standard soundex string is four
characters long, but the SOUNDEX() function returns an arbitrarily long
string. You can use SUBSTRING() on the result to get a standard soundex
string. All non-alphabetic characters in str are ignored. All international
alphabetic characters outside the A-Z range are treated as vowels.

Important: When using SOUNDEX(), you should be aware of the following details:

* This function, as currently implemented, is intended to work well with
 strings that are in the English language only. Strings in other languages may
 not produce reasonable results.

* This function implements the original Soundex algorithm, not the more
popular enhanced version (also described by D. Knuth). The difference is that
original version discards vowels first and duplicates second, whereas the
enhanced version discards duplicates first and vowels second.

Examples
--------

SOUNDEX('Hello');
+------------------+
| SOUNDEX('Hello') |
+------------------+
| H400             |
+------------------+

SELECT SOUNDEX('MariaDB');
+--------------------+
| SOUNDEX('MariaDB') |
+--------------------+
| M631               |
+--------------------+

SELECT SOUNDEX('Knowledgebase');
+--------------------------+
| SOUNDEX('Knowledgebase') |
+--------------------------+
| K543212                  |
+--------------------------+

SELECT givenname, surname FROM users WHERE SOUNDEX(givenname) =
SOUNDEX("robert");
+-----------+---------+
| givenname | surname |
+-----------+---------+
| Roberto   | Castro  |
+-----------+---------+

URL: https://mariadb.com/kb/en/soundex/https://mariadb.com/kb/en/soundex/�
�	+�e�I#��
�[!$STRCMPSyntax
------

STRCMP(expr1,expr2)

Description
-----------

STRCMP() returns 0 if the strings are the same, -1 if the first argument is
smaller than the second according to the current sort order, and 1 if the
strings are otherwise not the same. Returns NULL is either argument is NULL.

Examples
--------

SELECT STRCMP('text', 'text2');
+-------------------------+
| STRCMP('text', 'text2') |
+-------------------------+
|                      -1 |
+-------------------------+

SELECT STRCMP('text2', 'text');
+-------------------------+
| STRCMP('text2', 'text') |
+-------------------------+
|                       1 |
+-------------------------+

SELECT STRCMP('text', 'text');
+------------------------+
| STRCMP('text', 'text') |
+------------------------+
|                      0 |
+------------------------+

URL: https://mariadb.com/kb/en/strcmp/https://mariadb.com/kb/en/strcmp/�	
$$SUBSTRINGSyntax
------

SUBSTRING(str,pos), 
SUBSTRING(str FROM pos), 
SUBSTRING(str,pos,len),
SUBSTRING(str FROM pos FOR len)

SUBSTR(str,pos), 
SUBSTR(str FROM pos), 
SUBSTR(str,pos,len),
SUBSTR(str FROM pos FOR len)

Description
-----------

The forms without a len argument return a substring from string str starting
at position pos.

The forms with a len argument return a substring len characters long from
string str, starting at position pos.

The forms that use FROM are standard SQL syntax.

It is also possible to use a negative value for pos. In this case, the
beginning of the substring is pos characters from the end of the string,
rather than the beginning. A negative value may be used for pos in any of the
forms of this function.

By default, the position of the first character in the string from which the
substring is to be extracted is reckoned as 1. For Oracle-compatibility, from
MariaDB 10.3.3, when sql_mode is set to 'oracle', position zero is treated as
position 1 (although the first character is still reckoned as 1).

If any argument is NULL, returns NULL.

Examples
--------

SELECT SUBSTRING('Knowledgebase',5);
+------------------------------+
| SUBSTRING('Knowledgebase',5) |
+------------------------------+
| ledgebase                    |
+------------------------------+

SELECT SUBSTRING('MariaDB' FROM 6);
+-----------------------------+
| SUBSTRING('MariaDB' FROM 6) |
+-----------------------------+
| DB                          |
+-----------------------------+

SELECT SUBSTRING('Knowledgebase',3,7);
+--------------------------------+
| SUBSTRING('Knowledgebase',3,7) |
+--------------------------------+
| owledge                        |
+--------------------------------+

SELECT SUBSTRING('Knowledgebase', -4);
+--------------------------------+
| SUBSTRING('Knowledgebase', -4) |
+--------------------------------+
| base                           |
+--------------------------------+

SELECT SUBSTRING('Knowledgebase', -8, 4);
+-----------------------------------+
| SUBSTRING('Knowledgebase', -8, 4) |
+-----------------------------------+
| edge                              |
+-----------------------------------+

SELECT SUBSTRING('Knowledgebase' FROM -8 FOR 4);
+------------------------------------------+
| SUBSTRING('Knowledgebase' FROM -8 FOR 4) |
+------------------------------------------+
| edge                                     |
+------------------------------------------+

Oracle mode from MariaDB 10.3.3:

SELECT SUBSTR('abc',0,3);
+-------------------+
| SUBSTR('abc',0,3) |
+-------------------+
|                   |
+-------------------+

SELECT SUBSTR('abc',1,2);
+-------------------+
| SUBSTR('abc',1,2) |
+-------------------+
| ab                |
+-------------------+

SET sql_mode='oracle';

SELECT SUBSTR('abc',0,3);
+-------------------+
| SUBSTR('abc',0,3) |
+-------------------+
| abc               |
+-------------------+

SELECT SUBSTR('abc',1,2);
+-------------------+
| SUBSTR('abc',1,2) |
+-------------------+
| ab                |
+-------------------+

URL: https://mariadb.com/kb/en/substring/https://mariadb.com/kb/en/substring/��*$SUBSTRING_INDEXSyntax
------

SUBSTRING_INDEX(str,delim,count)

Description
-----------

Returns the substring from string str before count occurrences of the
delimiter delim. If count is positive, everything to the left of the final
delimiter (counting from the left) is returned. If count is negative,
everything to the right of the final delimiter (counting from the right) is
returned. SUBSTRING_INDEX() performs a case-sensitive match when searching for
delim.

If any argument is NULL, returns NULL.

For example

SUBSTRING_INDEX('www.mariadb.org', '.', 2)

means "Return all of the characters up to the 2nd occurrence of ."

Examples
--------

SELECT SUBSTRING_INDEX('www.mariadb.org', '.', 2);
+--------------------------------------------+
| SUBSTRING_INDEX('www.mariadb.org', '.', 2) |
+--------------------------------------------+
| www.mariadb                                |
+--------------------------------------------+

SELECT SUBSTRING_INDEX('www.mariadb.org', '.', -2);
+---------------------------------------------+
| SUBSTRING_INDEX('www.mariadb.org', '.', -2) |
+---------------------------------------------+
| mariadb.org                                 |
+---------------------------------------------+

URL: https://mariadb.com/kb/en/substring_index/https://mariadb.com/kb/en/substring_index/�6�H�~�#a�B	�	�$$TO_BASE64Syntax
------

TO_BASE64(str)

Description
-----------

Converts the string argument str to its base-64 encoded form, returning the
result as a character string in the connection character set and collation.

The argument str will be converted to string first if it is not a string. A
NULL argument will return a NULL result.

The reverse function, FROM_BASE64(), decodes an encoded base-64 string.

There are a numerous different methods to base-64 encode a string. The
following are used by MariaDB and MySQL:

* Alphabet value 64 is encoded as '+'.
* Alphabet value 63 is encoded as '/'.
* Encoding output is made up of groups of four printable characters, with each
three bytes of data encoded using four characters. If the final group is not
complete, it is padded with '=' characters to make up a length of four.
* To divide long output, a newline is added after every 76 characters.
* Decoding will recognize and ignore newlines, carriage returns, tabs, and
spaces.

Examples
--------

SELECT TO_BASE64('Maria');
+--------------------+
| TO_BASE64('Maria') |
+--------------------+
| TWFyaWE=           |
+--------------------+

URL: https://mariadb.com/kb/en/to_base64/https://mariadb.com/kb/en/to_base64/�B
"$TO_CHARMariaDB starting with 10.6.1
----------------------------
The TO_CHAR function was introduced in MariaDB 10.6.1 to enhance Oracle
compatibility.

Syntax
------

TO_CHAR(expr[, fmt])

Description
-----------

The TO_CHAR function converts an expr of type date, datetime, time or
timestamp to a string. The optional fmt argument supports
YYYY/YYY/YY/RRRR/RR/MM/MON/MONTH/MI/DD/DY/HH/HH12/HH24/SS and special
characters. The default value is "YYYY-MM-DD HH24:MI:SS".

In Oracle, TO_CHAR can also be used to convert numbers to strings, but this is
not supported in MariaDB and will give an error.

Examples
--------

SELECT TO_CHAR('1980-01-11 04:50:39', 'YYYY-MM-DD');
+----------------------------------------------+
| TO_CHAR('1980-01-11 04:50:39', 'YYYY-MM-DD') |
+----------------------------------------------+
| 1980-01-11                                   |
+----------------------------------------------+

SELECT TO_CHAR('1980-01-11 04:50:39', 'HH24-MI-SS');
+----------------------------------------------+
| TO_CHAR('1980-01-11 04:50:39', 'HH24-MI-SS') |
+----------------------------------------------+
| 04-50-39                                     |
+----------------------------------------------+

SELECT TO_CHAR('00-01-01 00:00:00', 'YY-MM-DD HH24:MI:SS');
+-----------------------------------------------------+
| TO_CHAR('00-01-01 00:00:00', 'YY-MM-DD HH24:MI:SS') |
+-----------------------------------------------------+
| 00-01-01 00:00:00                                   |
+-----------------------------------------------------+

SELECT TO_CHAR('99-12-31 23:59:59', 'YY-MM-DD HH24:MI:SS');
+-----------------------------------------------------+
| TO_CHAR('99-12-31 23:59:59', 'YY-MM-DD HH24:MI:SS') |
+-----------------------------------------------------+
| 99-12-31 23:59:59                                   |
+-----------------------------------------------------+

SELECT TO_CHAR('9999-12-31 23:59:59', 'YY-MM-DD HH24:MI:SS');
+-------------------------------------------------------+
| TO_CHAR('9999-12-31 23:59:59', 'YY-MM-DD HH24:MI:SS') |
+-------------------------------------------------------+
| 99-12-31 23:59:59                                     |
+-------------------------------------------------------+

SELECT TO_CHAR('21-01-03 08:30:00', 'Y-MONTH-DY HH:MI:SS');
+-----------------------------------------------------+
| TO_CHAR('21-01-03 08:30:00', 'Y-MONTH-DY HH:MI:SS') |
+-----------------------------------------------------+
| 1-January  -Sun 08:30:00                            |
+-----------------------------------------------------+

URL: https://mariadb.com/kb/en/to_char/https://mariadb.com/kb/en/to_char/�$$TRIMSyntax
------

TRIM([{BOTH | LEADING | TRAILING} [remstr] FROM] str), TRIM([remstr FROM] str)

From MariaDB 10.3.6

TRIM_ORACLE([{BOTH | LEADING | TRAILING} [remstr] FROM] str), TRIM([remstr
FROM] str)

Description
-----------

Returns the string str with all remstr prefixes or suffixes removed. If none
of the specifiers BOTH, LEADING, or TRAILING is given, BOTH is assumed. remstr
is optional and, if not specified, spaces are removed.

Returns NULL if given a NULL argument. If the result is empty, returns either
an empty string, or, from MariaDB 10.3.6 with SQL_MODE=Oracle, NULL.
SQL_MODE=Oracle is not set by default.

The Oracle mode version of the function can be accessed in any mode by using
TRIM_ORACLE as the function name.

Examples
--------

SELECT TRIM('  bar   ')\G
*************************** 1. row ***************************
TRIM('  bar   '): bar

SELECT TRIM(LEADING 'x' FROM 'xxxbarxxx')\G
*************************** 1. row ***************************
TRIM(LEADING 'x' FROM 'xxxbarxxx'): barxxx

SELECT TRIM(BOTH 'x' FROM 'xxxbarxxx')\G
*************************** 1. row ***************************
TRIM(BOTH 'x' FROM 'xxxbarxxx'): bar

SELECT TRIM(TRAILING 'xyz' FROM 'barxxyz')\G
*************************** 1. row ***************************
TRIM(TRAILING 'xyz' FROM 'barxxyz'): barx

From MariaDB 10.3.6, with SQL_MODE=Oracle not set:

SELECT TRIM(''),TRIM_ORACLE('');
+----------+-----------------+
| TRIM('') | TRIM_ORACLE('') |
+----------+-----------------+
|          | NULL            |
+----------+-----------------+

From MariaDB 10.3.6, with SQL_MODE=Oracle set:

SELECT TRIM(''),TRIM_ORACLE('');
+----------+-----------------+
| TRIM('') | TRIM_ORACLE('') |
+----------+-----------------+
| NULL     | NULL            |
+----------+-----------------+

URL: https://mariadb.com/kb/en/trim/https://mariadb.com/kb/en/trim/YU�y
�Saz'��	�4.$UNCOMPRESSED_LENGTHSyntax
------

UNCOMPRESSED_LENGTH(compressed_string)

Description
-----------

Returns the length that the compressed string had before being compressed with
COMPRESS().

UNCOMPRESSED_LENGTH() returns NULL or an incorrect result if the string is not
compressed.

Until MariaDB 10.3.1, returns MYSQL_TYPE_LONGLONG, or bigint(10), in all
cases. From MariaDB 10.3.1, returns MYSQL_TYPE_LONG, or int(10), when the
result would fit within 32-bits.

Examples
--------

SELECT UNCOMPRESSED_LENGTH(COMPRESS(REPEAT('a',30)));
+-----------------------------------------------+
| UNCOMPRESSED_LENGTH(COMPRESS(REPEAT('a',30))) |
+-----------------------------------------------+
|                                            30 |
+-----------------------------------------------+

URL: https://mariadb.com/kb/en/uncompressed_length/https://mariadb.com/kb/en/uncompressed_length/�Z $UNHEXSyntax
------

UNHEX(str)

Description
-----------

Performs the inverse operation of HEX(str). That is, it interprets each pair
of hexadecimal digits in the argument as a number and converts it to the
character represented by the number. The resulting characters are returned as
a binary string.

If str is NULL, UNHEX() returns NULL.

Examples
--------

SELECT HEX('MariaDB');
+----------------+
| HEX('MariaDB') |
+----------------+
| 4D617269614442 |
+----------------+

SELECT UNHEX('4D617269614442');
+-------------------------+
| UNHEX('4D617269614442') |
+-------------------------+
| MariaDB                 |
+-------------------------+

SELECT 0x4D617269614442;
+------------------+
| 0x4D617269614442 |
+------------------+
| MariaDB          |
+------------------+

SELECT UNHEX(HEX('string'));
+----------------------+
| UNHEX(HEX('string')) |
+----------------------+
| string               |
+----------------------+

SELECT HEX(UNHEX('1267'));
+--------------------+
| HEX(UNHEX('1267')) |
+--------------------+
| 1267               |
+--------------------+

URL: https://mariadb.com/kb/en/unhex/https://mariadb.com/kb/en/unhex/�	�$$UPDATEXMLSyntax
------

UpdateXML(xml_target, xpath_expr, new_xml)

Description
-----------

This function replaces a single portion of a given fragment of XML markup
xml_target with a new XML fragment new_xml, and then returns the changed XML.
The portion of xml_target that is replaced matches an XPath expression
xpath_expr supplied by the user. If no expression matching xpath_expr is
found, or if multiple matches are found, the function returns the original
xml_target XML fragment. All three arguments should be strings.

Examples
--------

SELECT
  UpdateXML('<a><b>ccc</b><d></d></a>', '/a', '<e>fff</e>') AS val1,
  UpdateXML('<a><b>ccc</b><d></d></a>', '/b', '<e>fff</e>') AS val2,
  UpdateXML('<a><b>ccc</b><d></d></a>', '//b', '<e>fff</e>') AS val3,
  UpdateXML('<a><b>ccc</b><d></d></a>', '/a/d', '<e>fff</e>') AS val4,
  UpdateXML('<a><d></d><b>ccc</b><d></d></a>', '/a/d', '<e>fff</e>') AS val5
  \G
*************************** 1. row ***************************
val1: <e>fff</e>
val2: <a><b>ccc</b><d></d></a>
val3: <a><e>fff</e><d></d></a>
val4: <a><b>ccc</b><e>fff</e></a>
val5: <a><d></d><b>ccc</b><d></d></a>
1 row in set (0.00 sec)

URL: https://mariadb.com/kb/en/updatexml/https://mariadb.com/kb/en/updatexml/��&&ALTER EVENTModifies one or more characteristics of an existing event.

Syntax
------

ALTER
  [DEFINER = { user | CURRENT_USER }]
  EVENT event_name
  [ON SCHEDULE schedule]
  [ON COMPLETION [NOT] PRESERVE]
  [RENAME TO new_event_name]
  [ENABLE | DISABLE | DISABLE ON SLAVE]
  [COMMENT 'comment']
  [DO sql_statement]

Description
-----------

The ALTER EVENT statement is used to change one or more of the characteristics
of an existing event without the need to drop and recreate it. The syntax for
each of the DEFINER, ON SCHEDULE, ON COMPLETION, COMMENT, ENABLE / DISABLE,
and DO clauses is exactly the same as when used with CREATE EVENT.

This statement requires the EVENT privilege. When a user executes a successful
ALTER EVENT statement, that user becomes the definer for the affected event.

(In MySQL 5.1.11 and earlier, an event could be altered only by its definer,
or by a user having the SUPER privilege.)

ALTER EVENT works only with an existing event:

ALTER EVENT no_such_event ON SCHEDULE EVERY '2:3' DAY_HOUR;
ERROR 1539 (HY000): Unknown event 'no_such_event'

Examples
--------

ALTER EVENT myevent 
 ON SCHEDULE AT CURRENT_TIMESTAMP + INTERVAL 2 HOUR
 DO
  UPDATE myschema.mytable SET mycol = mycol + 1;

URL: https://mariadb.com/kb/en/alter-event/https://mariadb.com/kb/en/alter-event/��)&ALTER FUNCTIONSyntax
------

ALTER FUNCTION func_name [characteristic ...]

characteristic:
  { CONTAINS SQL | NO SQL | READS SQL DATA | MODIFIES SQL DATA }
 | SQL SECURITY { DEFINER | INVOKER }
 | COMMENT 'string'

Description
-----------

This statement can be used to change the characteristics of a stored function.
More than one change may be specified in an ALTER FUNCTION statement. However,
you cannot change the parameters or body of a stored function using this
statement; to make such changes, you must drop and re-create the function
using DROP FUNCTION and CREATE FUNCTION.

You must have the ALTER ROUTINE privilege for the function. (That privilege is
granted automatically to the function creator.) If binary logging is enabled,
the ALTER FUNCTION statement might also require the SUPER privilege, as
described in Binary Logging of Stored Routines.

Example
-------

ALTER FUNCTION hello SQL SECURITY INVOKER;

URL: https://mariadb.com/kb/en/alter-function/https://mariadb.com/kb/en/alter-function/%�+����h��"
�
.($WEIGHT_STRINGSyntax
------

WEIGHT_STRING(str [AS {CHAR|BINARY}(N)] [LEVEL levels] [flags])
 levels: N [ASC|DESC|REVERSE] [, N [ASC|DESC|REVERSE]] ...

Description
-----------

Returns a binary string representing the string's sorting and comparison
value. A string with a lower result means that for sorting purposes the string
appears before a string with a higher result.

WEIGHT_STRING() is particularly useful when adding new collations, for testing
purposes.

If str is a non-binary string (CHAR, VARCHAR or TEXT), WEIGHT_STRING returns
the string's collation weight. If str is a binary string (BINARY, VARBINARY or
BLOB), the return value is simply the input value, since the weight for each
byte in a binary string is the byte value.

WEIGHT_STRING() returns NULL if given a NULL input.

The optional AS clause permits casting the input string to a binary or
non-binary string, as well as to a particular length.

AS BINARY(N) measures the length in bytes rather than characters, and right
pads with 0x00 bytes to the desired length.

AS CHAR(N) measures the length in characters, and right pads with spaces to
the desired length.

N has a minimum value of 1, and if it is less than the length of the input
string, the string is truncated without warning.

The optional LEVEL clause specifies that the return value should contain
weights for specific collation levels. The levels specifier can either be a
single integer, a comma-separated list of integers, or a range of integers
separated by a dash (whitespace is ignored). Integers can range from 1 to a
maximum of 6, dependent on the collation, and need to be listed in ascending
order.

If the LEVEL clause is no provided, a default of 1 to the maximum for the
collation is assumed.

If the LEVEL is specified without using a range, an optional modifier is
permitted.

ASC, the default, returns the weights without any modification.

DESC returns bitwise-inverted weights.

REVERSE returns the weights in reverse order.

Examples
--------

The examples below use the HEX() function to represent non-printable results
in hexadecimal format.

SELECT HEX(WEIGHT_STRING('x'));
+-------------------------+
| HEX(WEIGHT_STRING('x')) |
+-------------------------+
| 0058                    |
+-------------------------+

SELECT HEX(WEIGHT_STRING('x' AS BINARY(4)));
+--------------------------------------+
| HEX(WEIGHT_STRING('x' AS BINARY(4))) |
+--------------------------------------+
| 78000000                             |
+--------------------------------------+

SELECT HEX(WEIGHT_STRING('x' AS CHAR(4)));
+------------------------------------+
| HEX(WEIGHT_STRING('x' AS CHAR(4))) |
+------------------------------------+
| 0058002000200020                   |
+------------------------------------+

SELECT HEX(WEIGHT_STRING(0xaa22ee LEVEL 1));
+--------------------------------------+
| HEX(WEIGHT_STRING(0xaa22ee LEVEL 1)) |
+--------------------------------------+
| AA22EE                               |
+--------------------------------------+

SELECT HEX(WEIGHT_STRING(0xaa22ee LEVEL 1 DESC));
+-------------------------------------------+
| HEX(WEIGHT_STRING(0xaa22ee LEVEL 1 DESC)) |
+-------------------------------------------+
| 55DD11                                    |
+-------------------------------------------+

SELECT HEX(WEIGHT_STRING(0xaa22ee LEVEL 1 REVERSE));
+----------------------------------------------+
| HEX(WEIGHT_STRING(0xaa22ee LEVEL 1 REVERSE)) |
+----------------------------------------------+
| EE22AA                                       |
+----------------------------------------------+

URL: https://mariadb.com/kb/en/weight_string/https://mariadb.com/kb/en/weight_string/��*&ALTER PROCEDURESyntax
------

ALTER PROCEDURE proc_name [characteristic ...]

characteristic:
  { CONTAINS SQL | NO SQL | READS SQL DATA | MODIFIES SQL DATA }
 | SQL SECURITY { DEFINER | INVOKER }
 | COMMENT 'string'

Description
-----------

This statement can be used to change the characteristics of a stored
procedure. More than one change may be specified in an ALTER PROCEDURE
statement. However, you cannot change the parameters or body of a stored
procedure using this statement. To make such changes, you must drop and
re-create the procedure using either CREATE OR REPLACE PROCEDURE (since
MariaDB 10.1.3) or DROP PROCEDURE and CREATE PROCEDURE (MariaDB 10.1.2 and
before).

You must have the ALTER ROUTINE privilege for the procedure. By default, that
privilege is granted automatically to the procedure creator. See Stored
Routine Privileges.

Example
-------

ALTER PROCEDURE simpleproc SQL SECURITY INVOKER;

URL: https://mariadb.com/kb/en/alter-procedure/https://mariadb.com/kb/en/alter-procedure/�
%&ALTER VIEWSyntax
------

ALTER
  [ALGORITHM = {UNDEFINED | MERGE | TEMPTABLE}]
  [DEFINER = { user | CURRENT_USER }]
  [SQL SECURITY { DEFINER | INVOKER }]
  VIEW view_name [(column_list)]
  AS select_statement
  [WITH [CASCADED | LOCAL] CHECK OPTION]

Description
-----------

This statement changes the definition of a view, which must exist. The syntax
is similar to that for CREATE VIEW and the effect is the same as for CREATE OR
REPLACE VIEW if the view exists. This statement requires the CREATE VIEW and
DROP privileges for the view, and some privilege for each column referred to
in the SELECT statement. ALTER VIEW is allowed only to the definer or users
with the SUPER privilege.

Example
-------

ALTER VIEW v AS SELECT a, a*3 AS a2 FROM t;

URL: https://mariadb.com/kb/en/alter-view/https://mariadb.com/kb/en/alter-view/O}q@����L�Y*$Type ConversionImplicit type conversion takes place when MariaDB is using operands or
different types, in order to make the operands compatible.

It is best practice not to rely upon implicit conversion; rather use CAST to
explicitly convert types.

Rules for Conversion on Comparison
----------------------------------

* If  either argument is NULL, the result of the comparison is NULL unless the
NULL-safe <=> equality comparison operator is used.
* If both arguments are integers, they are compared as integers.
* If both arguments are strings, they are compared as strings.
* If one argument is decimal and the other argument is decimal or integer,
they are compared as decimals.
* If one argument is decimal and the other argument is a floating point, they
are compared as floating point values.
* If one argument is string and the other argument is integer, they are
compared as decimals. This conversion was added in MariaDB 10.3.36. Prior to
10.3.36, this combination was compared as floating point values, which did not
always work well for huge 64-bit integers because of a possible precision loss
on conversion to double.
* If a hexadecimal argument is not compared to a number, it is treated as a
binary string.
* If a constant is compared to a TIMESTAMP or DATETIME, the constant is
converted to a timestamp, unless used as an argument to the IN function.
* In other cases, arguments are compared as floating point, or real, numbers.

Note that if a string column is being compared with a numeric value, MariaDB
will not use the index on the column, as there are numerous alternatives that
may evaluate as equal (see examples below).

Comparison Examples
-------------------

Converting a string to a number:

SELECT 15+'15';
+---------+
| 15+'15' |
+---------+
|      30 |
+---------+

Converting a number to a string:

SELECT CONCAT(15,'15');
+-----------------+
| CONCAT(15,'15') |
+-----------------+
| 1515            |
+-----------------+

Floating point number errors:

SELECT '9746718491924563214' = 9746718491924563213;
+---------------------------------------------+
| '9746718491924563214' = 9746718491924563213 |
+---------------------------------------------+
|                                           1 |
+---------------------------------------------+

Numeric equivalence with strings:

SELECT '5' = 5;
+---------+
| '5' = 5 |
+---------+
|       1 |
+---------+

SELECT '   5' = 5;
+------------+
| '   5' = 5 |
+------------+
|          1 |
+------------+

SELECT '   5  ' = 5;
+--------------+
| '   5  ' = 5 |
+--------------+
|            1 |
+--------------+
1 row in set, 1 warning (0.000 sec)

SHOW WARNINGS;
+-------+------+--------------------------------------------+
| Level | Code | Message                                    |
+-------+------+--------------------------------------------+
| Note  | 1292 | Truncated incorrect DOUBLE value: '   5  ' |
+-------+------+--------------------------------------------+

As a result of the above, MariaDB cannot use the index when comparing a string
with a numeric value in the example below:

CREATE TABLE t (a VARCHAR(10), b VARCHAR(10), INDEX idx_a (a));

INSERT INTO t VALUES 
 ('1', '1'), ('2', '2'), ('3', '3'),
 ('4', '4'), ('5', '5'), ('1', '5');

EXPLAIN SELECT * FROM t WHERE a = '3' \G
*************************** 1. row ***************************
     id: 1
 select_type: SIMPLE
    table: t
    type: ref
possible_keys: idx_a
     key: idx_a
   key_len: 13
     ref: const
    rows: 1
    Extra: Using index condition

EXPLAIN SELECT * FROM t WHERE a = 3 \G
*************************** 1. row ***************************
     id: 1
 select_type: SIMPLE
    table: t
    type: ALL
possible_keys: idx_a
     key: NULL
   key_len: NULL
     ref: NULL
    rows: 6
    Extra: Using where

Rules for Conversion on Dyadic Arithmetic Operations
----------------------------------------------------

Implicit type conversion also takes place on dyadic arithmetic operations
(+,-,*,/). MariaDB chooses the minimum data type that is guaranteed to fit the
result and converts both arguments to the result data type.

For addition (+), subtraction (-) and multiplication (*), the result data type
is chosen as follows:

* If either of the arguments is an approximate number (float, double), the
result is double.
* If either of the arguments is a string (char, varchar, text), the result is
double.
* If either of the arguments is a decimal number, the result is decimal.
* If either of the arguments is of a temporal type with a non-zero fractional
second precision (time(N), datetime(N), timestamp(N)), the result is decimal.
* If either of the arguments is of a temporal type with a zero fractional
second precision (time(0), date, datetime(0), timestamp(0)), the result may
vary between int, int unsigned, bigint or bigint unsigned, depending on the
exact data type combination.
* If both arguments are integer numbers (tinyint, smallint, mediumint,
bigint), the result may vary between int, int unsigned, bigint or bigint
unsigned, depending of the exact data types and their signs.

For division (/), the result data type is chosen as follows:

* If either of the arguments is an approximate number (float, double), the
result is double.
* If either of the arguments is a string (char, varchar, text), the result is
double.
* Otherwise, the result is decimal.

Arithmetic Examples
-------------------

Note, the above rules mean that when an argument of a temporal data type
appears in addition or subtraction, it's treated as a number by default.

SELECT TIME'10:20:30' + 1;
+--------------------+
| TIME'10:20:30' + 1 |
+--------------------+
|             102031 |
+--------------------+

In order to do temporal addition or subtraction instead, use the DATE_ADD() or
DATE_SUB() functions, or an INTERVAL expression as the second argument:

SELECT TIME'10:20:30' + INTERVAL 1 SECOND;
+------------------------------------+
| TIME'10:20:30' + INTERVAL 1 SECOND |
+------------------------------------+
| 10:20:31                           |
+------------------------------------+

SELECT "2.2" + 3;
+-----------+
| "2.2" + 3 |
+-----------+
|       5.2 |
+-----------+

SELECT 2.2 + 3;
+---------+
| 2.2 + 3 |
+---------+
| 5.2     |
+---------+

SELECT 2.2 / 3;
+---------+
| 2.2 / 3 |
+---------+
| 0.73333 |
+---------+

SELECT "2.2" / 3;
+--------------------+
| "2.2" / 3          |
+--------------------+
| 0.7333333333333334 |
+--------------------+

URL: https://mariadb.com/kb/en/type-conversion/https://mariadb.com/kb/en/type-conversion/��,U����_
)&ALTER DATABASEModifies a database, changing its overall characteristics.

Syntax
------

ALTER {DATABASE | SCHEMA} [db_name]
  alter_specification ...
ALTER {DATABASE | SCHEMA} db_name
  UPGRADE DATA DIRECTORY NAME

alter_specification:
  [DEFAULT] CHARACTER SET [=] charset_name
 | [DEFAULT] COLLATE [=] collation_name
 | COMMENT [=] 'comment'

Description
-----------

ALTER DATABASE enables you to change the overall characteristics of a
database. These characteristics are stored in the db.opt file in the database
directory. To use ALTER DATABASE, you need the ALTER privilege on the
database. ALTER SCHEMA is a synonym for ALTER DATABASE.

The CHARACTER SET clause changes the default database character set. The
COLLATE clause changes the default database collation. See Character Sets and
Collations for more.

You can see what character sets and collations are available using,
respectively, the SHOW CHARACTER SET and SHOW COLLATION statements.

Changing the default character set/collation of a database does not change the
character set/collation of any stored procedures or stored functions that were
previously created, and relied on the defaults. These need to be dropped and
recreated in order to apply the character set/collation changes.

The database name can be omitted from the first syntax, in which case the
statement applies to the default database.

The syntax that includes the UPGRADE DATA DIRECTORY NAME clause was added in
MySQL 5.1.23. It updates the name of the directory associated with the
database to use the encoding implemented in MySQL 5.1 for mapping database
names to database directory names (see Identifier to File Name Mapping). This
clause is for use under these conditions:

* It is intended when upgrading MySQL to 5.1 or later from older versions.
* It is intended to update a database directory name to the current encoding
format if the name contains special characters that need encoding.
* The statement is used by mariadb-check (as invoked by mariadb-upgrade).

For example,if a database in MySQL 5.0 has a name of a-b-c, the name contains
instance of the `-' character. In 5.0, the database directory is also named
a-b-c, which is not necessarily safe for all file systems. In MySQL 5.1 and
up, the same database name is encoded as a@002db@002dc to produce a file
system-neutral directory name.

When a MySQL installation is upgraded to MySQL 5.1 or later from an older
version,the server displays a name such as a-b-c (which is in the old format)
as #mysql50#a-b-c, and you must refer to the name using the #mysql50# prefix.
Use UPGRADE DATA DIRECTORY NAME in this case to explicitly tell the server to
re-encode the database directory name to the current encoding format:

ALTER DATABASE `#mysql50#a-b-c` UPGRADE DATA DIRECTORY NAME;

After executing this statement, you can refer to the database as a-b-c without
the special #mysql50# prefix.

COMMENT
-------

MariaDB starting with 10.5.0
----------------------------
From MariaDB 10.5.0, it is possible to add a comment of a maximum of 1024
bytes. If the comment length exceeds this length, a error/warning code 4144 is
thrown. The database comment is also added to the db.opt file, as well as to
the information_schema.schemata table.

Examples
--------

ALTER DATABASE test CHARACTER SET='utf8'  COLLATE='utf8_bin';

From MariaDB 10.5.0:

ALTER DATABASE p COMMENT='Presentations';

URL: https://mariadb.com/kb/en/alter-database/https://mariadb.com/kb/en/alter-database/�4'&RENAME TABLESyntax
------

RENAME TABLE[S] [IF EXISTS] tbl_name 
 [WAIT n | NOWAIT]
 TO new_tbl_name
  [, tbl_name2 TO new_tbl_name2] ...

Description
-----------

This statement renames one or more tables or views, but not the privileges
associated with them.

IF EXISTS
---------

MariaDB starting with 10.5.2
----------------------------
If this directive is used, one will not get an error if the table to be
renamed doesn't exist.

The rename operation is done atomically, which means that no other session can
access any of the tables while the rename is running. For example, if you have
an existing table old_table, you can create another table new_table that has
the same structure but is empty, and then replace the existing table with the
empty one as follows (assuming that backup_table does not already exist):

CREATE TABLE new_table (...);
RENAME TABLE old_table TO backup_table, new_table TO old_table;

tbl_name can optionally be specified as db_name.tbl_name. See Identifier
Qualifiers. This allows to use RENAME to move a table from a database to
another (as long as they are on the same filesystem):

RENAME TABLE db1.t TO db2.t;

Note that moving a table to another database is not possible if it has some
triggers. Trying to do so produces the following error:

ERROR 1435 (HY000): Trigger in wrong schema

Also, views cannot be moved to another database:

ERROR 1450 (HY000): Changing schema from 'old_db' to 'new_db' is not allowed.

Multiple tables can be renamed in a single statement. The presence or absence
of the optional S (RENAME TABLE or RENAME TABLES) has no impact, whether a
single or multiple tables are being renamed.

If a RENAME TABLE renames more than one table and one renaming fails, all
renames executed by the same statement are rolled back.

Renames are always executed in the specified order. Knowing this, it is also
possible to swap two tables' names:

RENAME TABLE t1 TO tmp_table,
  t2 TO t1,
  tmp_table TO t2;

WAIT/NOWAIT
-----------

Set the lock wait timeout. See WAIT and NOWAIT.

Privileges
----------

Executing the RENAME TABLE statement requires the DROP, CREATE and INSERT
privileges for the table or the database.

Atomic RENAME TABLE
-------------------

MariaDB starting with 10.6.1
----------------------------
From MariaDB 10.6, RENAME TABLE is atomic for most engines, including InnoDB,
MyRocks, MyISAM and Aria (MDEV-23842). This means that if there is a crash
(server down or power outage) during RENAME TABLE, all tables will revert to
their original names and any changes to trigger files will be reverted.

In older MariaDB version there was a small chance that, during a server crash
happening in the middle of RENAME TABLE, some tables could have been renamed
(in the worst case partly) while others would not be renamed.

See Atomic DDL for more information.

URL: https://mariadb.com/kb/en/rename-table/https://mariadb.com/kb/en/rename-table/�
u�
?�����
�%&DROP TABLESyntax
------

DROP [TEMPORARY] TABLE [IF EXISTS] [/*COMMENT TO SAVE*/]
  tbl_name [, tbl_name] ...
  [WAIT n|NOWAIT]
  [RESTRICT | CASCADE]

Description
-----------

DROP TABLE removes one or more tables. You must have the DROP privilege for
each table. All table data and the table definition are removed, as well as
triggers associated to the table, so be careful with this statement! If any of
the tables named in the argument list do not exist, MariaDB returns an error
indicating by name which non-existing tables it was unable to drop, but it
also drops all of the tables in the list that do exist.

Important: When a table is dropped, user privileges on the table are not
automatically dropped. See GRANT.

If another thread is using the table in an explicit transaction or an
autocommit transaction, then the thread acquires a metadata lock (MDL) on the
table. The DROP TABLE statement will wait in the "Waiting for table metadata
lock" thread state until the MDL is released. MDLs are released in the
following cases:

* If an MDL is acquired in an explicit transaction, then the MDL will be
released when the transaction ends.
* If an MDL is acquired in an autocommit transaction, then the MDL will be
released when the statement ends.
* Transactional and non-transactional tables are handled the same.

Note that for a partitioned table, DROP TABLE permanently removes the table
definition, all of its partitions, and all of the data which was stored in
those partitions. It also removes the partitioning definition (.par) file
associated with the dropped table.

For each referenced table, DROP TABLE drops a temporary table with that name,
if it exists. If it does not exist, and the TEMPORARY keyword is not used, it
drops a non-temporary table with the same name, if it exists. The TEMPORARY
keyword ensures that a non-temporary table will not accidentally be dropped.

Use IF EXISTS to prevent an error from occurring for tables that do not exist.
A NOTE is generated for each non-existent table when using IF EXISTS. See SHOW
WARNINGS.

If a foreign key references this table, the table cannot be dropped. In this
case, it is necessary to drop the foreign key first.

RESTRICT and CASCADE are allowed to make porting from other database systems
easier. In MariaDB, they do nothing.

The comment before the table names (/*COMMENT TO SAVE*/) is stored in the
binary log. That feature can be used by replication tools to send their
internal messages.

It is possible to specify table names as db_name.tab_name. This is useful to
delete tables from multiple databases with one statement. See Identifier
Qualifiers for details.

The DROP privilege is required to use DROP TABLE on non-temporary tables. For
temporary tables, no privilege is required, because such tables are only
visible for the current session.

Note: DROP TABLE automatically commits the current active transaction, unless
you use the TEMPORARY keyword.

MariaDB starting with 10.5.4
----------------------------
From MariaDB 10.5.4, DROP TABLE reliably deletes table remnants inside a
storage engine even if the .frm file is missing. Before then, a missing .frm
file would result in the statement failing.

MariaDB starting with 10.3.1
----------------------------

WAIT/NOWAIT
-----------

Set the lock wait timeout. See WAIT and NOWAIT.

DROP TABLE in replication
-------------------------

DROP TABLE has the following characteristics in replication:

* DROP TABLE IF EXISTS are always logged.
* DROP TABLE without IF EXISTS for tables that don't exist are not written to
the binary log.
* Dropping of TEMPORARY tables are prefixed in the log with TEMPORARY. These
drops are only logged when running statement or mixed mode replication.
* One DROP TABLE statement can be logged with up to 3 different DROP
statements:
DROP TEMPORARY TABLE list_of_non_transactional_temporary_tables
DROP TEMPORARY TABLE list_of_transactional_temporary_tables
DROP TABLE list_of_normal_tables

DROP TABLE on the primary is treated on the replica as DROP TABLE IF EXISTS.
You can change that by setting slave-ddl-exec-mode to STRICT.

Dropping an Internal #sql-... Table
-----------------------------------

From MariaDB 10.6, DROP TABLE is atomic and the following does not apply.
Until MariaDB 10.5, if the mariadbd/mysqld process is killed during an ALTER
TABLE you may find a table named #sql-... in your data directory. In MariaDB
10.3, InnoDB tables with this prefix will be deleted automatically during
startup. From MariaDB 10.4, these temporary tables will always be deleted
automatically.

If you want to delete one of these tables explicitly you can do so by using
the following syntax:

DROP TABLE `#mysql50##sql-...`;

When running an ALTER TABLE…ALGORITHM=INPLACE that rebuilds the table, InnoDB
will create an internal #sql-ib table. Until MariaDB 10.3.2, for these tables,
the .frm file will be called something else. In order to drop such a table
after a server crash, you must rename the #sql*.frm file to match the
#sql-ib*.ibd file.

From MariaDB 10.3.3, the same name as the .frm file is used for the
intermediate copy of the table. The #sql-ib names are used by TRUNCATE and
delayed DROP.

From MariaDB 10.2.19 and MariaDB 10.3.10, the #sql-ib tables will be deleted
automatically.

Dropping All Tables in a Database
---------------------------------

The best way to drop all tables in a database is by executing DROP DATABASE,
which will drop the database itself, and all tables in it.

However, if you want to drop all tables in the database, but you also want to
keep the database itself and any other non-table objects in it, then you would
need to execute DROP TABLE to drop each individual table. You can construct
these DROP TABLE commands by querying the TABLES table in the
information_schema database. For example:

SELECT CONCAT('DROP TABLE IF EXISTS `', TABLE_SCHEMA, '`.`', TABLE_NAME, '`;')
FROM information_schema.TABLES
WHERE TABLE_SCHEMA = 'mydb';

Atomic DROP TABLE
-----------------

MariaDB starting with 10.6.1
----------------------------
From MariaDB 10.6, DROP TABLE for a single table is atomic (MDEV-25180) for
most engines, including InnoDB, MyRocks, MyISAM and Aria.

This means that if there is a crash (server down or power outage) during DROP
TABLE, all tables that have been processed so far will be completely dropped,
including related trigger files and status entries, and the binary log will
include a DROP TABLE statement for the dropped tables. Tables for which the
drop had not started will be left intact.

In older MariaDB versions, there was a small chance that, during a server
crash happening in the middle of DROP TABLE, some storage engines that were
using multiple storage files, like MyISAM, could have only a part of its
internal files dropped.

In MariaDB 10.5, DROP TABLE was extended to be able to delete a table that was
only partly dropped (MDEV-11412) as explained above. Atomic DROP TABLE is the
final piece to make DROP TABLE fully reliable.

Dropping multiple tables is crash-safe.

See Atomic DDL for more information.

Examples
--------

DROP TABLE Employees, Customers;

Notes
-----

Beware that DROP TABLE can drop both tables and sequences. This is mainly done
to allow old tools like mariadb-dump (previously mysqldump) to work with
sequences.

URL: https://mariadb.com/kb/en/drop-table/https://mariadb.com/kb/en/drop-table/�C�0��J�))&TRUNCATE TABLESyntax
------

TRUNCATE [TABLE] tbl_name
 [WAIT n | NOWAIT]

Description
-----------

TRUNCATE TABLE empties a table completely. It requires the DROP privilege. See
GRANT.

tbl_name can also be specified in the form db_name.tbl_name (see Identifier
Qualifiers).

Logically, TRUNCATE TABLE is equivalent to a DELETE statement that deletes all
rows, but there are practical differences under some circumstances.

TRUNCATE TABLE will fail for an InnoDB table if any FOREIGN KEY constraints
from other tables reference the table, returning the error:

ERROR 1701 (42000): Cannot truncate a table referenced in a foreign key
constraint

Foreign Key constraints between columns in the same table are permitted.

For an InnoDB table, if there are no FOREIGN KEY constraints, InnoDB performs
fast truncation by dropping the original table and creating an empty one with
the same definition, which is much faster than deleting rows one by one. The
AUTO_INCREMENT counter is reset by TRUNCATE TABLE, regardless of whether there
is a FOREIGN KEY constraint.

The count of rows affected by TRUNCATE TABLE is accurate only when it is
mapped to a DELETE statement.

For other storage engines, TRUNCATE TABLE differs from DELETE in the following
ways:

* Truncate operations drop and re-create the table, which is much
 faster than deleting rows one by one, particularly for large tables.
* Truncate operations cause an implicit commit.
* Truncation operations cannot be performed if the session holds an
 active table lock.
* Truncation operations do not return a meaningful value for the number
 of deleted rows. The usual result is "0 rows affected," which should
 be interpreted as "no information."
* As long as the table format file tbl_name.frm is valid, the
 table can be re-created as an empty table
 with TRUNCATE TABLE, even if the data or index files have become
 corrupted.
* The table handler does not remember the last
 used AUTO_INCREMENT value, but starts counting
 from the beginning. This is true even for MyISAM and InnoDB, which normally
 do not reuse sequence values.
* When used with partitioned tables, TRUNCATE TABLE preserves
 the partitioning; that is, the data and index files are dropped and
 re-created, while the partition definitions (.par) file is
 unaffected.
* Since truncation of a table does not make any use of DELETE,
 the TRUNCATE statement does not invoke ON DELETE triggers.
* TRUNCATE TABLE will only reset the values in the Performance Schema summary
tables to zero or null, and will not remove the rows.

For the purposes of binary logging and replication, TRUNCATE TABLE is treated
as DROP TABLE followed by CREATE TABLE (DDL rather than DML).

TRUNCATE TABLE does not work on views. Currently, TRUNCATE TABLE drops all
historical records from a system-versioned table.

WAIT/NOWAIT
-----------

Set the lock wait timeout. See WAIT and NOWAIT.

Oracle-mode
-----------

Oracle-mode from MariaDB 10.3 permits the optional keywords REUSE STORAGE or
DROP STORAGE to be used.

TRUNCATE [TABLE] tbl_name [{DROP | REUSE} STORAGE] [WAIT n | NOWAIT]

These have no effect on the operation.

Performance
-----------

TRUNCATE TABLE is faster than DELETE, because it drops and re-creates a table.

With InnoDB, TRUNCATE TABLE is slower if innodb_file_per_table=ON is set (the
default). This is because TRUNCATE TABLE unlinks the underlying tablespace
file, which can be an expensive operation. See MDEV-8069 for more details.

The performance issues with innodb_file_per_table=ON can be exacerbated in
cases where the InnoDB buffer pool is very large and
innodb_adaptive_hash_index=ON is set. In that case, using DROP TABLE followed
by CREATE TABLE instead of TRUNCATE TABLE may perform better. Setting
innodb_adaptive_hash_index=OFF (it defaults to ON before MariaDB 10.5) can
also help. In MariaDB 10.2 only, from MariaDB 10.2.19, this performance can
also be improved by setting innodb_safe_truncate=OFF. See MDEV-9459 for more
details.

Setting innodb_adaptive_hash_index=OFF can also improve TRUNCATE TABLE
performance in general. See MDEV-16796 for more details.

URL: https://mariadb.com/kb/en/truncate-table/https://mariadb.com/kb/en/truncate-table/��*&CREATE DATABASESyntax
------

CREATE [OR REPLACE] {DATABASE | SCHEMA} [IF NOT EXISTS] db_name
  [create_specification] ...

create_specification:
  [DEFAULT] CHARACTER SET [=] charset_name
 | [DEFAULT] COLLATE [=] collation_name
 | COMMENT [=] 'comment'

Description
-----------

CREATE DATABASE creates a database with the given name. To use this statement,
you need the CREATE privilege for the database. CREATE SCHEMA is a synonym for
CREATE DATABASE.

For valid identifiers to use as database names, see Identifier Names.

OR REPLACE
----------

MariaDB starting with 10.1.3
----------------------------
The OR REPLACE clause was added in MariaDB 10.1.3

If the optional OR REPLACE clause is used, it acts as a shortcut for:

DROP DATABASE IF EXISTS db_name;
CREATE DATABASE db_name ...;

IF NOT EXISTS
-------------

When the IF NOT EXISTS clause is used, MariaDB will return a warning instead
of an error if the specified database already exists.

COMMENT
-------

MariaDB starting with 10.5.0
----------------------------
From MariaDB 10.5.0, it is possible to add a comment of a maximum of 1024
bytes. If the comment length exceeds this length, a error/warning code 4144 is
thrown. The database comment is also added to the db.opt file, as well as to
the information_schema.schemata table.

Examples
--------

CREATE DATABASE db1;
Query OK, 1 row affected (0.18 sec)

CREATE DATABASE db1;
ERROR 1007 (HY000): Can't create database 'db1'; database exists

CREATE OR REPLACE DATABASE db1;
Query OK, 2 rows affected (0.00 sec)

CREATE DATABASE IF NOT EXISTS db1;
Query OK, 1 row affected, 1 warning (0.01 sec)

SHOW WARNINGS;
+-------+------+----------------------------------------------+
| Level | Code | Message                                      |
+-------+------+----------------------------------------------+
| Note  | 1007 | Can't create database 'db1'; database exists |
+-------+------+----------------------------------------------+

Setting the character sets and collation. See Setting Character Sets and
Collations for more details.

CREATE DATABASE czech_slovak_names 
 CHARACTER SET = 'keybcs2'
 COLLATE = 'keybcs2_bin';

Comments, from MariaDB 10.5.0:

CREATE DATABASE presentations COMMENT 'Presentations for conferences';

URL: https://mariadb.com/kb/en/create-database/https://mariadb.com/kb/en/create-database/z0	n
��Q�x�3'&CREATE EVENTSyntax
------

CREATE [OR REPLACE]
  [DEFINER = { user | CURRENT_USER | role | CURRENT_ROLE }]
  EVENT
  [IF NOT EXISTS]
  event_name
  ON SCHEDULE schedule
  [ON COMPLETION [NOT] PRESERVE]
  [ENABLE | DISABLE | DISABLE ON SLAVE]
  [COMMENT 'comment']
  DO sql_statement;

schedule:
  AT timestamp [+ INTERVAL interval] ...
 | EVERY interval
  [STARTS timestamp [+ INTERVAL interval] ...]
  [ENDS timestamp [+ INTERVAL interval] ...]

interval:
  quantity {YEAR | QUARTER | MONTH | DAY | HOUR | MINUTE |
       WEEK | SECOND | YEAR_MONTH | DAY_HOUR | DAY_MINUTE |
       DAY_SECOND | HOUR_MINUTE | HOUR_SECOND | MINUTE_SECOND}

Description
-----------

This statement creates and schedules a new event. It requires the EVENT
privilege for the schema in which the event is to be created.

The minimum requirements for a valid CREATE EVENT statement are as follows:

* The keywords CREATE EVENT plus an event name, which uniquely identifies
 the event in the current schema. (Prior to MySQL 5.1.12, the event name
 needed to be unique only among events created by the same user on a given
 database.)
* An ON SCHEDULE clause, which determines when and how often the event
 executes.
* A DO clause, which contains the SQL statement to be executed by an
 event.

Here is an example of a minimal CREATE EVENT statement:

CREATE EVENT myevent
  ON SCHEDULE AT CURRENT_TIMESTAMP + INTERVAL 1 HOUR
  DO
   UPDATE myschema.mytable SET mycol = mycol + 1;

The previous statement creates an event named myevent. This event executes
once — one hour following its creation — by running an SQL statement that
increments the value of the myschema.mytable table's mycol column by 1.

The event_name must be a valid MariaDB identifier with a maximum length of 64
characters. It may be delimited using back ticks, and may be qualified with
the name of a database schema. An event is associated with both a MariaDB user
(the definer) and a schema, and its name must be unique among names of events
within that schema. In general, the rules governing event names are the same
as those for names of stored routines. See Identifier Names.

If no schema is indicated as part of event_name, the default (current) schema
is assumed.

For valid identifiers to use as event names, see Identifier Names.

OR REPLACE
----------

The OR REPLACE clause was included in MariaDB 10.1.4. If used and the event
already exists, instead of an error being returned, the existing event will be
dropped and replaced by the newly defined event.

IF NOT EXISTS
-------------

If the IF NOT EXISTS clause is used, MariaDB will return a warning instead of
an error if the event already exists. Cannot be used together with OR REPLACE.

ON SCHEDULE
-----------

The ON SCHEDULE clause can be used to specify when the event must be triggered.

AT
--

If you want to execute the event only once (one time event), you can use the
AT keyword, followed by a timestamp. If you use CURRENT_TIMESTAMP, the event
acts as soon as it is created. As a convenience, you can add one or more
intervals to that timestamp. You can also specify a timestamp in the past, so
that the event is stored but not triggered, until you modify it via ALTER
EVENT.

The following example shows how to create an event that will be triggered
tomorrow at a certain time:

CREATE EVENT example
ON SCHEDULE AT CURRENT_TIMESTAMP + INTERVAL 1 DAY + INTERVAL 3 HOUR
DO something;

You can also specify that an event must be triggered at a regular interval
(recurring event). In such cases, use the EVERY clause followed by the
interval.

If an event is recurring, you can specify when the first execution must happen
via the STARTS clause and a maximum time for the last execution via the ENDS
clause. STARTS and ENDS clauses are followed by a timestamp and, optionally,
one or more intervals. The ENDS clause can specify a timestamp in the past, so
that the event is stored but not executed until you modify it via ALTER EVENT.

In the following example, next month a recurring event will be triggered
hourly for a week:

CREATE EVENT example
ON SCHEDULE EVERY 1 HOUR
STARTS CURRENT_TIMESTAMP + INTERVAL 1 MONTH
ENDS CURRENT_TIMESTAMP + INTERVAL 1 MONTH + INTERVAL 1 WEEK
DO some_task;

Intervals consist of a quantity and a time unit. The time units are the same
used for other staments and time functions, except that you can't use
microseconds for events. For simple time units, like HOUR or MINUTE, the
quantity is an integer number, for example '10 MINUTE'. For composite time
units, like HOUR_MINUTE or HOUR_SECOND, the quantity must be a string with all
involved simple values and their separators, for example '2:30' or '2:30:30'.

ON COMPLETION [NOT] PRESERVE
----------------------------

The ON COMPLETION clause can be used to specify if the event must be deleted
after its last execution (that is, after its AT or ENDS timestamp is past). By
default, events are dropped when they are expired. To explicitly state that
this is the desired behaviour, you can use ON COMPLETION NOT PRESERVE.
Instead, if you want the event to be preserved, you can use ON COMPLETION
PRESERVE.

In you specify ON COMPLETION NOT PRESERVE, and you specify a timestamp in the
past for AT or ENDS clause, the event will be immediatly dropped. In such
cases, you will get a Note 1558: "Event execution time is in the past and ON
COMPLETION NOT PRESERVE is set. The event was dropped immediately after
creation".

ENABLE/DISABLE/DISABLE ON SLAVE
-------------------------------

Events are ENABLEd by default. If you want to stop MariaDB from executing an
event, you may specify DISABLE. When it is ready to be activated, you may
enable it using ALTER EVENT. Another option is DISABLE ON SLAVE, which
indicates that an event was created on a master and has been replicated to the
slave, which is prevented from executing the event. If DISABLE ON SLAVE is
specifically set, the event will be disabled everywhere. It will not be
executed on the mater or the slaves.

COMMENT
-------

The COMMENT clause may be used to set a comment for the event. Maximum length
for comments is 64 characters. The comment is a string, so it must be quoted.
To see events comments, you can query the INFORMATION_SCHEMA.EVENTS table (the
column is named EVENT_COMMENT).

Examples
--------

Minimal CREATE EVENT statement:

CREATE EVENT myevent
  ON SCHEDULE AT CURRENT_TIMESTAMP + INTERVAL 1 HOUR
  DO
   UPDATE myschema.mytable SET mycol = mycol + 1;

An event that will be triggered tomorrow at a certain time:

CREATE EVENT example
ON SCHEDULE AT CURRENT_TIMESTAMP + INTERVAL 1 DAY + INTERVAL 3 HOUR
DO something;

Next month a recurring event will be triggered hourly for a week:

CREATE EVENT example
ON SCHEDULE EVERY 1 HOUR
STARTS CURRENT_TIMESTAMP + INTERVAL 1 MONTH
ENDS CURRENT_TIMESTAMP + INTERVAL 1 MONTH + INTERVAL 1 WEEK
DO some_task;

OR REPLACE and IF NOT EXISTS:

CREATE EVENT myevent
  ON SCHEDULE AT CURRENT_TIMESTAMP + INTERVAL 1 HOUR
  DO
   UPDATE myschema.mytable SET mycol = mycol + 1;
ERROR 1537 (HY000): Event 'myevent' already exists

CREATE OR REPLACE EVENT myevent
  ON SCHEDULE AT CURRENT_TIMESTAMP + INTERVAL 1 HOUR
  DO
   UPDATE myschema.mytable SET mycol = mycol + 1;;
Query OK, 0 rows affected (0.00 sec)

CREATE EVENT IF NOT EXISTS myevent
  ON SCHEDULE AT CURRENT_TIMESTAMP + INTERVAL 1 HOUR
  DO
   UPDATE myschema.mytable SET mycol = mycol + 1;
Query OK, 0 rows affected, 1 warning (0.00 sec)

SHOW WARNINGS;
+-------+------+--------------------------------+
| Level | Code | Message                        |
+-------+------+--------------------------------+
| Note  | 1537 | Event 'myevent' already exists |
+-------+------+--------------------------------+

URL: https://mariadb.com/kb/en/create-event/https://mariadb.com/kb/en/create-event/t1א_����'&CREATE INDEXSyntax
------

CREATE [OR REPLACE] [UNIQUE|FULLTEXT|SPATIAL] INDEX 
 [IF NOT EXISTS] index_name
  [index_type]
  ON tbl_name (index_col_name,...)
  [WAIT n | NOWAIT]
  [index_option]
  [algorithm_option | lock_option] ...

index_col_name:
  col_name [(length)] [ASC | DESC]

index_type:
  USING {BTREE | HASH | RTREE}

index_option:
  [ KEY_BLOCK_SIZE [=] value
 | index_type
 | WITH PARSER parser_name
 | COMMENT 'string'
 | CLUSTERING={YES| NO} ]
 [ IGNORED | NOT IGNORED ]

algorithm_option:
  ALGORITHM [=] {DEFAULT|INPLACE|COPY|NOCOPY|INSTANT}

lock_option:
  LOCK [=] {DEFAULT|NONE|SHARED|EXCLUSIVE}

Description
-----------

The CREATE INDEX statement is used to add indexes to a table. Indexes can be
created at the same as the table, with the [[|create-table|CREATE TABLE]]
statement. In some cases, such as for InnoDB primary keys, doing so during
creation is preferable, as adding a primary key will involve rebuilding the
table.

The statement is mapped to an ALTER TABLE statement to create indexes. See
ALTER TABLE. CREATE INDEX cannot be used to create a PRIMARY KEY; use ALTER
TABLE instead.

If another connection is using the table, a metadata lock is active, and this
statement will wait until the lock is released. This is also true for
non-transactional tables.

Another shortcut, DROP INDEX, allows the removal of an index.

For valid identifiers to use as index names, see Identifier Names.

Note that KEY_BLOCK_SIZE is currently ignored in CREATE INDEX, although it is
included in the output of SHOW CREATE TABLE.

Privileges
----------

Executing the CREATE INDEX statement requires the INDEX privilege for the
table or the database.

Online DDL
----------

Online DDL is supported with the ALGORITHM and LOCK clauses.

See InnoDB Online DDL Overview for more information on online DDL with InnoDB.

CREATE OR REPLACE INDEX
-----------------------

If the OR REPLACE clause is used and if the index already exists, then instead
of returning an error, the server will drop the existing index and replace it
with the newly defined index.

CREATE INDEX IF NOT EXISTS
--------------------------

If the IF NOT EXISTS clause is used, then the index will only be created if an
index with the same name does not already exist. If the index already exists,
then a warning will be triggered by default.

Index Definitions
-----------------

See CREATE TABLE: Index Definitions for information about index definitions.

WAIT/NOWAIT
-----------

Set the lock wait timeout. See WAIT and NOWAIT.

ALGORITHM
---------

See ALTER TABLE: ALGORITHM for more information.

LOCK
----

See ALTER TABLE: LOCK for more information.

Progress Reporting
------------------

MariaDB provides progress reporting for CREATE INDEX statement for clients
that support the new progress reporting protocol. For example, if you were
using the mariadb client, then the progress report might look like this::

CREATE INDEX i ON tab (num);
Stage: 1 of 2 'copy to tmp table'    46% of stage

The progress report is also shown in the output of the SHOW PROCESSLIST
statement and in the contents of the information_schema.PROCESSLIST table.

See Progress Reporting for more information.

WITHOUT OVERLAPS
----------------

MariaDB starting with 10.5.3
----------------------------
The WITHOUT OVERLAPS clause allows one to constrain a primary or unique index
such that application-time periods cannot overlap.

Examples
--------

Creating a unique index:

CREATE UNIQUE INDEX HomePhone ON Employees(Home_Phone);

OR REPLACE and IF NOT EXISTS:

CREATE INDEX xi ON xx5 (x);
Query OK, 0 rows affected (0.03 sec)

CREATE INDEX xi ON xx5 (x);
ERROR 1061 (42000): Duplicate key name 'xi'

CREATE OR REPLACE INDEX xi ON xx5 (x);
Query OK, 0 rows affected (0.03 sec)

CREATE INDEX IF NOT EXISTS xi ON xx5 (x);
Query OK, 0 rows affected, 1 warning (0.00 sec)

SHOW WARNINGS;
+-------+------+-------------------------+
| Level | Code | Message                 |
+-------+------+-------------------------+
| Note  | 1061 | Duplicate key name 'xi' |
+-------+------+-------------------------+

From MariaDB 10.5.3, creating a unique index for an application-time period
table with a WITHOUT OVERLAPS constraint:

CREATE UNIQUE INDEX u ON rooms (room_number, p WITHOUT OVERLAPS);

URL: https://mariadb.com/kb/en/create-index/https://mariadb.com/kb/en/create-index/��
)&CREATE PACKAGEMariaDB starting with 10.3.5
----------------------------
Oracle-style packages were introduced in MariaDB 10.3.5.

Syntax
------

CREATE
  [ OR REPLACE]
  [DEFINER = { user | CURRENT_USER | role | CURRENT_ROLE }]
  PACKAGE [ IF NOT EXISTS ]
  [ db_name . ] package_name
  [ package_characteristic ... ]
{ AS | IS }
  [ package_specification_element ... ]
END [ package_name ]

package_characteristic:
  COMMENT 'string'
 | SQL SECURITY { DEFINER | INVOKER }

package_specification_element:
  FUNCTION_SYM package_specification_function ;
 | PROCEDURE_SYM package_specification_procedure ;

package_specification_function:
  func_name [ ( func_param [, func_param]... ) ]
  RETURNS func_return_type
  [ package_routine_characteristic... ]

package_specification_procedure:
  proc_name [ ( proc_param [, proc_param]... ) ]
  [ package_routine_characteristic... ]

func_return_type:
  type

func_param:
  param_name [ IN | OUT | INOUT | IN OUT ] type

proc_param:
  param_name [ IN | OUT | INOUT | IN OUT ] type

type:
  Any valid MariaDB explicit or anchored data type

package_routine_characteristic:
   COMMENT  'string'
  | LANGUAGE SQL
  | { CONTAINS SQL | NO SQL | READS SQL DATA | MODIFIES SQL DATA }
  | SQL SECURITY { DEFINER | INVOKER }

Description
-----------

The CREATE PACKAGE statement can be used when Oracle SQL_MODE is set.

The CREATE PACKAGE creates the specification for a stored package (a
collection of logically related stored objects). A stored package
specification declares public routines (procedures and functions) of the
package, but does not implement these routines.

A package whose specification was created by the CREATE PACKAGE statement,
should later be implemented using the CREATE PACKAGE BODY statement.

Function parameter quantifiers IN | OUT | INOUT | IN OUT
--------------------------------------------------------

MariaDB starting with 10.8.0
----------------------------
The function parameter quantifiers for IN, OUT, INOUT, and IN OUT where added
in a 10.8.0 preview release. Prior to 10.8.0 quantifiers were supported only
in procedures.

OUT, INOUT and its equivalent IN OUT, are only valid if called from SET and
not SELECT. These quantifiers are especially useful for creating functions and
procedures with more than one return value. This allows functions and
procedures to be more complex and nested.

Examples
--------

SET sql_mode=ORACLE;
DELIMITER $$
CREATE OR REPLACE PACKAGE employee_tools AS
 FUNCTION getSalary(eid INT) RETURN DECIMAL(10,2);
 PROCEDURE raiseSalary(eid INT, amount DECIMAL(10,2));
 PROCEDURE raiseSalaryStd(eid INT);
 PROCEDURE hire(ename TEXT, esalary DECIMAL(10,2));
END;
$$
DELIMITER ;

URL: https://mariadb.com/kb/en/create-package/https://mariadb.com/kb/en/create-package/�
�L��	��.&CREATE PACKAGE BODYMariaDB starting with 10.3.5
----------------------------
Oracle-style packages were introduced in MariaDB 10.3.5.

Syntax
------

CREATE [ OR REPLACE ]
  [DEFINER = { user | CURRENT_USER | role | CURRENT_ROLE }]
  PACKAGE BODY
  [ IF NOT EXISTS ]
  [ db_name . ] package_name
  [ package_characteristic... ]
{ AS | IS }
  package_implementation_declare_section
  package_implementation_executable_section
END [ package_name]

package_implementation_declare_section:
  package_implementation_item_declaration
   [ package_implementation_item_declaration... ]
   [ package_implementation_routine_definition... ]
 | package_implementation_routine_definition
   [ package_implementation_routine_definition...]

package_implementation_item_declaration:
  variable_declaration ;

variable_declaration:
  variable_name[,...] type [:= expr ]

package_implementation_routine_definition:
  FUNCTION package_specification_function
   [ package_implementation_function_body ] ;
 | PROCEDURE package_specification_procedure
   [ package_implementation_procedure_body ] ;

package_implementation_function_body:
  { AS | IS } package_routine_body [func_name]

package_implementation_procedure_body:
  { AS | IS } package_routine_body [proc_name]

package_routine_body:
  [ package_routine_declarations ]
  BEGIN
   statements [ EXCEPTION exception_handlers ]
  END

package_routine_declarations:
  package_routine_declaration ';' [package_routine_declaration ';']...

package_routine_declaration:
     variable_declaration
    | condition_name CONDITION FOR condition_value
    | user_exception_name EXCEPTION
    | CURSOR_SYM cursor_name
     [ ( cursor_formal_parameters ) ]
     IS select_statement
    ;

package_implementation_executable_section:
     END
    | BEGIN
      statement ; [statement ; ]...
     [EXCEPTION exception_handlers]
     END

exception_handlers:
     exception_handler [exception_handler...]

exception_handler:
     WHEN_SYM condition_value [, condition_value]...
      THEN_SYM statement ; [statement ;]...

condition_value:
     condition_name
    | user_exception_name
    | SQLWARNING
    | SQLEXCEPTION
    | NOT FOUND
    | OTHERS_SYM
    | SQLSTATE [VALUE] sqlstate_value
    | mariadb_error_code

Description
-----------

The CREATE PACKAGE BODY statement can be used when Oracle SQL_MODE is set.

The CREATE PACKAGE BODY statement creates the package body for a stored
package. The package specification must be previously created using the CREATE
PACKAGE statement.

A package body provides implementations of the package public routines and can
optionally have:

* package-wide private variables
* package private routines
* forward declarations for private routines
* an executable initialization section

Examples
--------

SET sql_mode=ORACLE;
DELIMITER $$
CREATE OR REPLACE PACKAGE employee_tools AS
 FUNCTION getSalary(eid INT) RETURN DECIMAL(10,2);
 PROCEDURE raiseSalary(eid INT, amount DECIMAL(10,2));
 PROCEDURE raiseSalaryStd(eid INT);
 PROCEDURE hire(ename TEXT, esalary DECIMAL(10,2));
END;
$$
CREATE PACKAGE BODY employee_tools AS
 -- package body variables
 stdRaiseAmount DECIMAL(10,2):=500;

-- private routines
 PROCEDURE log (eid INT, ecmnt TEXT) AS
 BEGIN
  INSERT INTO employee_log (id, cmnt) VALUES (eid, ecmnt);
 END;

-- public routines
 PROCEDURE hire(ename TEXT, esalary DECIMAL(10,2)) AS
  eid INT;
 BEGIN
  INSERT INTO employee (name, salary) VALUES (ename, esalary);
  eid:= last_insert_id();
  log(eid, 'hire ' || ename);
 END;

FUNCTION getSalary(eid INT) RETURN DECIMAL(10,2) AS
  nSalary DECIMAL(10,2);
 BEGIN
  SELECT salary INTO nSalary FROM employee WHERE id=eid;
  log(eid, 'getSalary id=' || eid || ' salary=' || nSalary);
  RETURN nSalary;
 END;

PROCEDURE raiseSalary(eid INT, amount DECIMAL(10,2)) AS
 BEGIN
  UPDATE employee SET salary=salary+amount WHERE id=eid;
  log(eid, 'raiseSalary id=' || eid || ' amount=' || amount);
 END;

PROCEDURE raiseSalaryStd(eid INT) AS
 BEGIN
  raiseSalary(eid, stdRaiseAmount);
  log(eid, 'raiseSalaryStd id=' || eid);
 END;

BEGIN
 -- This code is executed when the current session
 -- accesses any of the package routines for the first time
 log(0, 'Session ' || connection_id() || ' ' || current_user || ' started');
END;
$$

DELIMITER ;

URL: https://mariadb.com/kb/en/create-package-body/https://mariadb.com/kb/en/create-package-body/�
(&DROP DATABASESyntax
------

DROP {DATABASE | SCHEMA} [IF EXISTS] db_name

Description
-----------

DROP DATABASE drops all tables in the database and deletes the database. Be
very careful with this statement! To use DROP DATABASE, you need the DROP
privilege on the database. DROP SCHEMA is a synonym for DROP DATABASE.

Important: When a database is dropped, user privileges on the database are not
automatically dropped. See GRANT.

IF EXISTS
---------

Use IF EXISTS to prevent an error from occurring for databases that do not
exist. A NOTE is generated for each non-existent database when using IF
EXISTS. See SHOW WARNINGS.

Atomic DDL
----------

MariaDB starting with 10.6.1
----------------------------
MariaDB 10.6.1 supports Atomic DDL.

DROP DATABASE is implemented as

loop over all tables
 DROP TABLE table

Each individual DROP TABLE is atomic while DROP DATABASE as a whole is
crash-safe.

Examples
--------

DROP DATABASE bufg;
Query OK, 0 rows affected (0.39 sec)

DROP DATABASE bufg;
ERROR 1008 (HY000): Can't drop database 'bufg'; database doesn't exist

\W
Show warnings enabled.

DROP DATABASE IF EXISTS bufg;
Query OK, 0 rows affected, 1 warning (0.00 sec)
Note (Code 1008): Can't drop database 'bufg'; database doesn't exist

URL: https://mariadb.com/kb/en/drop-database/https://mariadb.com/kb/en/drop-database/#E�G��B�
(&CREATE SERVERSyntax
------

CREATE [OR REPLACE] SERVER [IF NOT EXISTS] server_name
  FOREIGN DATA WRAPPER wrapper_name
  OPTIONS (option [, option] ...)

option:
 { HOST character-literal
 | DATABASE character-literal
 | USER character-literal
 | PASSWORD character-literal
 | SOCKET character-literal
 | OWNER character-literal
 | PORT numeric-literal }

Description
-----------

This statement creates the definition of a server for use with the Spider,
Connect, FEDERATED or FederatedX storage engine. The CREATE SERVER statement
creates a new row within the servers table within the mysql database. This
statement requires the SUPER privilege or, from MariaDB 10.5.2, the FEDERATED
ADMIN privilege.

The server_name should be a unique reference to the server. Server definitions
are global within the scope of the server, it is not possible to qualify the
server definition to a specific database. server_name has a maximum length of
64 characters (names longer than 64 characters are silently truncated), and is
case insensitive. You may specify the name as a quoted string.

The wrapper_name may be quoted with single quotes. Supported values are:

* mysql
* mariadb (in MariaDB 10.3 and later)

For each option you must specify either a character literal or numeric
literal. Character literals are UTF-8, support a maximum length of 64
characters and default to a blank (empty) string. String literals are silently
truncated to 64 characters. Numeric literals must be a number between 0 and
9999, default value is 0.

Note: The OWNER option is currently not applied, and has no effect on the
ownership or operation of the server connection that is created.

The CREATE SERVER statement creates an entry in the mysql.servers table that
can later be used with the CREATE TABLE statement when creating a Spider,
Connect, FederatedX or FEDERATED table. The options that you specify will be
used to populate the columns in the mysql.servers table. The table columns are
Server_name, Host, Db, Username, Password, Port and Socket.

DROP SERVER removes a previously created server definition.

CREATE SERVER is not written to the binary log, irrespective of the binary log
format being used. From MariaDB 10.1.13, Galera replicates the CREATE SERVER,
ALTER SERVER and DROP SERVER statements.

For valid identifiers to use as server names, see Identifier Names.

OR REPLACE
----------

If the optional OR REPLACE clause is used, it acts as a shortcut for:

DROP SERVER IF EXISTS name;
CREATE SERVER server_name ...;

IF NOT EXISTS
-------------

If the IF NOT EXISTS clause is used, MariaDB will return a warning instead of
an error if the server already exists. Cannot be used together with OR REPLACE.

Examples
--------

CREATE SERVER s
FOREIGN DATA WRAPPER mysql
OPTIONS (USER 'Remote', HOST '192.168.1.106', DATABASE 'test');

OR REPLACE and IF NOT EXISTS:

CREATE SERVER s 
FOREIGN DATA WRAPPER mysql 
OPTIONS (USER 'Remote', HOST '192.168.1.106', DATABASE 'test');
ERROR 1476 (HY000): The foreign server, s, you are trying to create already
exists

CREATE OR REPLACE SERVER s 
FOREIGN DATA WRAPPER mysql 
OPTIONS (USER 'Remote', HOST '192.168.1.106', DATABASE 'test');
Query OK, 0 rows affected (0.00 sec)

CREATE SERVER IF NOT EXISTS s 
FOREIGN DATA WRAPPER mysql 
OPTIONS (USER 'Remote', HOST '192.168.1.106', DATABASE 'test');
Query OK, 0 rows affected, 1 warning (0.00 sec)

SHOW WARNINGS;
+-------+------+---------------------------------------------------------------
+
| Level | Code | Message                                                      
 |
+-------+------+---------------------------------------------------------------
+
| Note  | 1476 | The foreign server, s, you are trying to create already
exists |
+-------+------+---------------------------------------------------------------
+

URL: https://mariadb.com/kb/en/create-server/https://mariadb.com/kb/en/create-server/�
#%&DROP EVENTSyntax
------

DROP EVENT [IF EXISTS] event_name

Description
-----------

This statement drops the event named event_name. The event immediately ceases
being active, and is deleted completely from the server.

If the event does not exist, the error ERROR 1517 (HY000): Unknown event
'event_name' results. You can override this and cause the statement to
generate a NOTE for non-existent events instead by using IF EXISTS. See SHOW
WARNINGS.

This statement requires the EVENT privilege. In MySQL 5.1.11 and earlier, an
event could be dropped only by its definer, or by a user having the SUPER
privilege.

Examples
--------

DROP EVENT myevent3;

Using the IF EXISTS clause:

DROP EVENT IF EXISTS myevent3;
Query OK, 0 rows affected, 1 warning (0.01 sec)

SHOW WARNINGS;
+-------+------+-------------------------------+
| Level | Code | Message                       |
+-------+------+-------------------------------+
| Note  | 1305 | Event myevent3 does not exist |
+-------+------+-------------------------------+

URL: https://mariadb.com/kb/en/drop-event/https://mariadb.com/kb/en/drop-event/R`FRXp����)&CREATE TRIGGERSyntax
------

CREATE [OR REPLACE]
  [DEFINER = { user | CURRENT_USER | role | CURRENT_ROLE }]
  TRIGGER [IF NOT EXISTS] trigger_name trigger_time trigger_event
  ON tbl_name FOR EACH ROW
 [{ FOLLOWS | PRECEDES } other_trigger_name ]
 trigger_stmt;

Description
-----------

This statement creates a new trigger. A trigger is a named database object
that is associated with a table, and that activates when a particular event
occurs for the table. The trigger becomes associated with the table named
tbl_name, which must refer to a permanent table. You cannot associate a
trigger with a TEMPORARY table or a view.

CREATE TRIGGER requires the TRIGGER privilege for the table associated with
the trigger.

You can have multiple triggers for the same trigger_time and trigger_event.

For valid identifiers to use as trigger names, see Identifier Names.

OR REPLACE
----------

If used and the trigger already exists, instead of an error being returned,
the existing trigger will be dropped and replaced by the newly defined trigger.

DEFINER
-------

The DEFINER clause determines the security context to be used when checking
access privileges at trigger activation time. Usage requires the SUPER
privilege, or, from MariaDB 10.5.2, the SET USER privilege.

IF NOT EXISTS
-------------

If the IF NOT EXISTS clause is used, the trigger will only be created if a
trigger of the same name does not exist. If the trigger already exists, by
default a warning will be returned.

trigger_time
------------

trigger_time is the trigger action time. It can be BEFORE or AFTER to indicate
that the trigger activates before or after each row to be modified.

trigger_event
-------------

trigger_event indicates the kind of statement that activates the trigger. The
trigger_event can be one of the following:

* INSERT: The trigger is activated whenever a new row is inserted into the
table; for example, through INSERT, LOAD DATA, and REPLACE statements.
* UPDATE: The trigger is activated whenever a row is modified; for example,
through UPDATE statements.
* DELETE: The trigger is activated whenever a row is deleted from the table;
for example, through DELETE and REPLACE statements. However, DROP TABLE and
TRUNCATE statements on the table do not activate this trigger, because they do
not use DELETE. Dropping a partition does not activate DELETE triggers, either.

FOLLOWS/PRECEDES other_trigger_name
-----------------------------------

The FOLLOWS other_trigger_name and PRECEDES other_trigger_name options were
added in MariaDB 10.2.3 as part of supporting multiple triggers per action
time. This is the same syntax used by MySQL 5.7, although MySQL 5.7 does not
have multi-trigger support.

FOLLOWS adds the new trigger after another trigger while PRECEDES adds the new
trigger before another trigger. If neither option is used, the new trigger is
added last for the given action and time.

FOLLOWS and PRECEDES are not stored in the trigger definition. However the
trigger order is guaranteed to not change over time. mariadb-dump and other
backup methods will not change trigger order. You can verify the trigger order
from the ACTION_ORDER column in INFORMATION_SCHEMA.TRIGGERS table.

SELECT trigger_name, action_order FROM information_schema.triggers 
 WHERE event_object_table='t1';

Atomic DDL
----------

MariaDB starting with 10.6.1
----------------------------
MariaDB 10.6.1 supports Atomic DDL and CREATE TRIGGER is atomic.

Examples
--------

CREATE DEFINER=`root`@`localhost` TRIGGER increment_animal
 AFTER INSERT ON animals FOR EACH ROW
 UPDATE animal_count SET animal_count.animals = animal_count.animals+1;

OR REPLACE and IF NOT EXISTS

CREATE DEFINER=`root`@`localhost` TRIGGER increment_animal
 AFTER INSERT ON animals FOR EACH ROW
  UPDATE animal_count SET animal_count.animals = animal_count.animals+1;
ERROR 1359 (HY000): Trigger already exists

CREATE OR REPLACE DEFINER=`root`@`localhost` TRIGGER increment_animal
 AFTER INSERT ON animals  FOR EACH ROW
  UPDATE animal_count SET animal_count.animals = animal_count.animals+1;
Query OK, 0 rows affected (0.12 sec)

CREATE DEFINER=`root`@`localhost` TRIGGER IF NOT EXISTS increment_animal
 AFTER INSERT ON animals FOR EACH ROW
  UPDATE animal_count SET animal_count.animals = animal_count.animals+1;
Query OK, 0 rows affected, 1 warning (0.00 sec)

SHOW WARNINGS;
+-------+------+------------------------+
| Level | Code | Message                |
+-------+------+------------------------+
| Note  | 1359 | Trigger already exists |
+-------+------+------------------------+
1 row in set (0.00 sec)

URL: https://mariadb.com/kb/en/create-trigger/https://mariadb.com/kb/en/create-trigger/�
k(&DROP FUNCTIONSyntax
------

DROP FUNCTION [IF EXISTS] f_name

Description
-----------

The DROP FUNCTION statement is used to drop a stored function or a
user-defined function (UDF). That is, the specified routine is removed from
the server, along with all privileges specific to the function. You must have
the ALTER ROUTINE privilege for the routine in order to drop it. If the
automatic_sp_privileges server system variable is set, both the ALTER ROUTINE
and EXECUTE privileges are granted automatically to the routine creator - see
Stored Routine Privileges.

IF EXISTS
---------

The IF EXISTS clause is a MySQL/MariaDB extension. It prevents an error from
occurring if the function does not exist. A NOTE is produced that can be
viewed with SHOW WARNINGS.

For dropping a user-defined functions (UDF), see DROP FUNCTION UDF.

Examples
--------

DROP FUNCTION hello;
Query OK, 0 rows affected (0.042 sec)

DROP FUNCTION hello;
ERROR 1305 (42000): FUNCTION test.hello does not exist

DROP FUNCTION IF EXISTS hello;
Query OK, 0 rows affected, 1 warning (0.000 sec)

SHOW WARNINGS;
+-------+------+------------------------------------+
| Level | Code | Message                            |
+-------+------+------------------------------------+
| Note  | 1305 | FUNCTION test.hello does not exist |
+-------+------+------------------------------------+

URL: https://mariadb.com/kb/en/drop-function/https://mariadb.com/kb/en/drop-function/\�PV���s
�,&Invisible ColumnsMariaDB starting with 10.3.3
----------------------------
Invisible columns (sometimes also called hidden columns) first appeared in
MariaDB 10.3.3.

Columns can be given an INVISIBLE attribute in a CREATE TABLE or ALTER TABLE
statement. These columns will then not be listed in the results of a SELECT *
statement, nor do they need to be assigned a value in an INSERT statement,
unless INSERT explicitly mentions them by name.

Since SELECT * does not return the invisible columns, new tables or views
created in this manner will have no trace of the invisible columns. If
specifically referenced in the SELECT statement, the columns will be brought
into the view/new table, but the INVISIBLE attribute will not.

Invisible columns can be declared as NOT NULL, but then require a DEFAULT
value.

It is not possible for all columns in a table to be invisible.

Examples
--------

CREATE TABLE t (x INT INVISIBLE);
ERROR 1113 (42000): A table must have at least 1 column

CREATE TABLE t (x INT, y INT INVISIBLE, z INT INVISIBLE NOT NULL);
ERROR 4106 (HY000): Invisible column `z` must have a default value

CREATE TABLE t (x INT, y INT INVISIBLE, z INT INVISIBLE NOT NULL DEFAULT 4);

INSERT INTO t VALUES (1),(2);

INSERT INTO t (x,y) VALUES (3,33);

SELECT * FROM t;
+------+
| x    |
+------+
|    1 |
|    2 |
|    3 |
+------+

SELECT x,y,z FROM t;
+------+------+---+
| x    | y    | z |
+------+------+---+
|    1 | NULL | 4 |
|    2 | NULL | 4 |
|    3 |   33 | 4 |
+------+------+---+

DESC t;
+-------+---------+------+-----+---------+-----------+
| Field | Type    | Null | Key | Default | Extra     |
+-------+---------+------+-----+---------+-----------+
| x     | int(11) | YES  |     | NULL    |           |
| y     | int(11) | YES  |     | NULL    | INVISIBLE |
| z     | int(11) | NO   |     | 4       | INVISIBLE |
+-------+---------+------+-----+---------+-----------+

ALTER TABLE t MODIFY x INT INVISIBLE, MODIFY y INT, MODIFY z INT NOT NULL
DEFAULT 4;

DESC t;
+-------+---------+------+-----+---------+-----------+
| Field | Type    | Null | Key | Default | Extra     |
+-------+---------+------+-----+---------+-----------+
| x     | int(11) | YES  |     | NULL    | INVISIBLE |
| y     | int(11) | YES  |     | NULL    |           |
| z     | int(11) | NO   |     | 4       |           |
+-------+---------+------+-----+---------+-----------+

Creating a view from a table with hidden columns:

CREATE VIEW v1 AS SELECT * FROM t;

DESC v1;
+-------+---------+------+-----+---------+-------+
| Field | Type    | Null | Key | Default | Extra |
+-------+---------+------+-----+---------+-------+
| y     | int(11) | YES  |     | NULL    |       |
| z     | int(11) | NO   |     | 4       |       |
+-------+---------+------+-----+---------+-------+

CREATE VIEW v2 AS SELECT x,y,z FROM t;

DESC v2;
+-------+---------+------+-----+---------+-------+
| Field | Type    | Null | Key | Default | Extra |
+-------+---------+------+-----+---------+-------+
| x     | int(11) | YES  |     | NULL    |       |
| y     | int(11) | YES  |     | NULL    |       |
| z     | int(11) | NO   |     | 4       |       |
+-------+---------+------+-----+---------+-------+

Adding a Surrogate Primary Key:

create table t1 (x bigint unsigned not null, y varchar(16), z text);

insert into t1 values (123, 'qq11', 'ipsum');

insert into t1 values (123, 'qq22', 'lorem');

alter table t1 add pkid serial primary key invisible first;

insert into t1 values (123, 'qq33', 'amet');

select * from t1;
+-----+------+-------+
| x   | y    | z     |
+-----+------+-------+
| 123 | qq11 | ipsum |
| 123 | qq22 | lorem |
| 123 | qq33 | amet  |
+-----+------+-------+

select pkid, z from t1;
+------+-------+
| pkid | z     |
+------+-------+
|    1 | ipsum |
|    2 | lorem |
|    3 | amet  |
+------+-------+

URL: https://mariadb.com/kb/en/invisible-columns/https://mariadb.com/kb/en/invisible-columns/�
�%&DROP INDEXSyntax
------

DROP INDEX [IF EXISTS] index_name ON tbl_name 
  [WAIT n |NOWAIT]

Description
-----------

DROP INDEX drops the index named index_name from the table tbl_name. This
statement is mapped to an ALTER TABLE statement to drop the index.

If another connection is using the table, a metadata lock is active, and this
statement will wait until the lock is released. This is also true for
non-transactional tables.

See ALTER TABLE.

Another shortcut, CREATE INDEX, allows the creation of an index.

To remove the primary key, `PRIMARY` must be specified as index_name. Note
that the quotes are necessary, because PRIMARY is a keyword.

Privileges
----------

Executing the DROP INDEX statement requires the INDEX privilege for the table
or the database.

Online DDL
----------

Online DDL is used by default with InnoDB, when the drop index operation
supports it.

See InnoDB Online DDL Overview for more information on online DDL with InnoDB.

DROP INDEX IF EXISTS ...
------------------------

If the IF EXISTS clause is used, then MariaDB will return a warning instead of
an error if the index does not exist.

WAIT/NOWAIT
-----------

Sets the lock wait timeout. See WAIT and NOWAIT.

Progress Reporting
------------------

MariaDB provides progress reporting for DROP INDEX statement for clients that
support the new progress reporting protocol. For example, if you were using
the mariadb client, then the progress report might look like this::

URL: https://mariadb.com/kb/en/drop-index/https://mariadb.com/kb/en/drop-index/fZM�W���X)&DROP PROCEDURESyntax
------

DROP PROCEDURE [IF EXISTS] sp_name

Description
-----------

This statement is used to drop a stored procedure. That is, the specified
routine is removed from the server along with all privileges specific to the
procedure. You must have the ALTER ROUTINE privilege for the routine. If the
automatic_sp_privileges server system variable is set, that privilege and
EXECUTE are granted automatically to the routine creator - see Stored Routine
Privileges.

The IF EXISTS clause is a MySQL/MariaDB extension. It prevents an error from
occurring if the procedure or function does not exist. A NOTE is produced that
can be viewed with SHOW WARNINGS.

While this statement takes effect immediately, threads which are executing a
procedure can continue execution.

Examples
--------

DROP PROCEDURE simpleproc;

IF EXISTS:

DROP PROCEDURE simpleproc;
ERROR 1305 (42000): PROCEDURE test.simpleproc does not exist

DROP PROCEDURE IF EXISTS simpleproc;
Query OK, 0 rows affected, 1 warning (0.00 sec)

SHOW WARNINGS;
+-------+------+------------------------------------------+
| Level | Code | Message                                  |
+-------+------+------------------------------------------+
| Note  | 1305 | PROCEDURE test.simpleproc does not exist |
+-------+------+------------------------------------------+

URL: https://mariadb.com/kb/en/drop-procedure/https://mariadb.com/kb/en/drop-procedure/��&&DROP SERVERSyntax
------

DROP SERVER [ IF EXISTS ] server_name

Description
-----------

Drops the server definition for the server named server_name. The
corresponding row within the mysql.servers table will be deleted. This
statement requires the SUPER privilege or, from MariaDB 10.5.2, the FEDERATED
ADMIN privilege.

Dropping a server for a table does not affect any FederatedX, FEDERATED,
Connect or Spider tables that used this connection information when they were
created.

DROP SERVER is not written to the binary log, irrespective of the binary log
format being used. From MariaDB 10.1.13, Galera replicates the CREATE SERVER,
ALTER SERVER and DROP SERVER statements.

IF EXISTS
---------

If the IF EXISTS clause is used, MariaDB will not return an error if the
server does not exist. Unlike all other statements, DROP SERVER IF EXISTS does
not issue a note if the server does not exist. See MDEV-9400.

Examples
--------

DROP SERVER s;

IF EXISTS:

DROP SERVER s;
ERROR 1477 (HY000): The foreign server name you are trying to reference 
 does not exist. Data source error:  s

DROP SERVER IF EXISTS s;
Query OK, 0 rows affected (0.00 sec)

URL: https://mariadb.com/kb/en/drop-server/https://mariadb.com/kb/en/drop-server/��'&DROP TRIGGERSyntax
------

DROP TRIGGER [IF EXISTS] [schema_name.]trigger_name

Description
-----------

This statement drops a trigger. The schema (database) name is optional. If the
schema is omitted, the trigger is dropped from the default schema. Its use
requires the TRIGGER privilege for the table associated with the trigger.

Use IF EXISTS to prevent an error from occurring for a trigger that does not
exist. A NOTE is generated for a non-existent trigger when using IF EXISTS.
See SHOW WARNINGS.

Note: Triggers for a table are also dropped if you drop the table.

Atomic DDL
----------

MariaDB starting with 10.6.1
----------------------------
MariaDB 10.6.1 supports Atomic DDL and DROP TRIGGER is atomic.

Examples
--------

DROP TRIGGER test.example_trigger;

Using the IF EXISTS clause:

DROP TRIGGER IF EXISTS test.example_trigger;
Query OK, 0 rows affected, 1 warning (0.01 sec)

SHOW WARNINGS;
+-------+------+------------------------+
| Level | Code | Message                |
+-------+------+------------------------+
| Note  | 1360 | Trigger does not exist |
+-------+------+------------------------+

URL: https://mariadb.com/kb/en/drop-trigger/https://mariadb.com/kb/en/drop-trigger/�	�$&DROP VIEWSyntax
------

DROP VIEW [IF EXISTS]
  view_name [, view_name] ...
  [RESTRICT | CASCADE]

Description
-----------

DROP VIEW removes one or more views. You must have the DROP privilege for each
view. If any of the views named in the argument list do not exist, MariaDB
returns an error indicating by name which non-existing views it was unable to
drop, but it also drops all of the views in the list that do exist.

The IF EXISTS clause prevents an error from occurring for views that don't
exist. When this clause is given, a NOTE is generated for each non-existent
view. See SHOW WARNINGS.

RESTRICT and CASCADE, if given, are parsed and ignored.

It is possible to specify view names as db_name.view_name. This is useful to
delete views from multiple databases with one statement. See Identifier
Qualifiers for details.

The DROP privilege is required to use DROP TABLE on non-temporary tables. For
temporary tables, no privilege is required, because such tables are only
visible for the current session.

If a view references another view, it will be possible to drop the referenced
view. However, the other view will reference a view which does not exist any
more. Thus, querying it will produce an error similar to the following:

ERROR 1356 (HY000): View 'db_name.view_name' references invalid table(s) or 
column(s) or function(s) or definer/invoker of view lack rights to use them

This problem is reported in the output of CHECK TABLE.

Note that it is not necessary to use DROP VIEW to replace an existing view,
because CREATE VIEW has an OR REPLACE clause.

Atomic DDL
----------

MariaDB starting with 10.6.1
----------------------------
MariaDB 10.6.1 supports Atomic DDL and DROP VIEW for a singular view is
atomic. Dropping multiple views is crash-safe.

Examples
--------

DROP VIEW v,v2;

Given views v and v2, but no view v3

DROP VIEW v,v2,v3;
ERROR 1051 (42S02): Unknown table 'v3'

DROP VIEW IF EXISTS v,v2,v3;
Query OK, 0 rows affected, 1 warning (0.01 sec)

SHOW WARNINGS;
+-------+------+-------------------------+
| Level | Code | Message                 |
+-------+------+-------------------------+
| Note  | 1051 | Unknown table 'test.v3' |
+-------+------+-------------------------+

URL: https://mariadb.com/kb/en/drop-view/https://mariadb.com/kb/en/drop-view/P
	�
����dD�����
�%&CONSTRAINTMariaDB supports the implementation of constraints at the table-level using
either CREATE TABLE or ALTER TABLE statements. A table constraint restricts
the data you can add to the table. If you attempt to insert invalid data on a
column, MariaDB throws an error.

Syntax
------

[CONSTRAINT [symbol]] constraint_expression

constraint_expression:
 | PRIMARY KEY [index_type] (index_col_name, ...) [index_option] ...
 | FOREIGN KEY [index_name] (index_col_name, ...)
   REFERENCES tbl_name (index_col_name, ...)
   [ON DELETE reference_option]
   [ON UPDATE reference_option]
 | UNIQUE [INDEX|KEY] [index_name]
   [index_type] (index_col_name, ...) [index_option] ...
 | CHECK (check_constraints)

index_type:
 USING {BTREE | HASH | RTREE}

index_col_name:
 col_name [(length)] [ASC | DESC]

index_option:
 | KEY_BLOCK_SIZE [=] value
 | index_type
 | WITH PARSER parser_name
 | COMMENT 'string'
 | CLUSTERING={YES|NO}

reference_option:
 RESTRICT | CASCADE | SET NULL | NO ACTION | SET DEFAULT

Description
-----------

Constraints provide restrictions on the data you can add to a table. This
allows you to enforce data integrity from MariaDB, rather than through
application logic. When a statement violates a constraint, MariaDB throws an
error.

There are four types of table constraints:

+------------------------------------+---------------------------------------+
| Constraint                         | Description                           |
+------------------------------------+---------------------------------------+
| PRIMARY KEY                        | Sets the column for referencing       |
|                                    | rows.  Values must be unique and not  |
|                                    | null.                                 |
+------------------------------------+---------------------------------------+
| FOREIGN KEY                        | Sets the column to reference the      |
|                                    | primary key on another table.         |
+------------------------------------+---------------------------------------+
| UNIQUE                             | Requires values in column or columns  |
|                                    | only occur once in the table.         |
+------------------------------------+---------------------------------------+
| CHECK                              | Checks whether the data meets the     |
|                                    | given condition.                      |
+------------------------------------+---------------------------------------+

The Information Schema TABLE_CONSTRAINTS Table contains information about
tables that have constraints.

FOREIGN KEY Constraints
-----------------------

InnoDB supports foreign key constraints. The syntax for a foreign key
constraint definition in InnoDB looks like this:

[CONSTRAINT [symbol]] FOREIGN KEY
  [index_name] (index_col_name, ...)
  REFERENCES tbl_name (index_col_name,...)
  [ON DELETE reference_option]
  [ON UPDATE reference_option]

reference_option:
  RESTRICT | CASCADE | SET NULL | NO ACTION

The Information Schema REFERENTIAL_CONSTRAINTS table has more information
about foreign keys.

CHECK Constraints
-----------------

Constraints are enforced. Before MariaDB 10.2.1 constraint expressions were
accepted in the syntax but ignored.

You can define constraints in 2 different ways:

* CHECK(expression) given as part of a column definition.
* CONSTRAINT [constraint_name] CHECK (expression)

Before a row is inserted or updated, all constraints are evaluated in the
order they are defined. If any constraint expression returns false, then the
row will not be inserted or updated. One can use most deterministic functions
in a constraint, including UDFs.

CREATE TABLE t1 (a INT CHECK (a>2), b INT CHECK (b>2), CONSTRAINT a_greater
CHECK (a>b));

If you use the second format and you don't give a name to the constraint, then
the constraint will get an automatically generated name. This is done so that
you can later delete the constraint with ALTER TABLE DROP constraint_name.

One can disable all constraint expression checks by setting the
check_constraint_checks variable to OFF. This is useful for example when
loading a table that violates some constraints that you want to later find and
fix in SQL.

Replication
-----------

In row-based replication, only the master checks constraints, and failed
statements will not be replicated. In statement-based replication, the slaves
will also check constraints. Constraints should therefore be identical, as
well as deterministic, in a replication environment.

Auto_increment
--------------

auto_increment columns are not permitted in check constraints. Before MariaDB
10.2.6, they were permitted, but would not work correctly. See MDEV-11117.

Examples
--------

CREATE TABLE product (category INT NOT NULL, id INT NOT NULL,
           price DECIMAL,
           PRIMARY KEY(category, id)) ENGINE=INNODB;
CREATE TABLE customer (id INT NOT NULL,
           PRIMARY KEY (id)) ENGINE=INNODB;
CREATE TABLE product_order (no INT NOT NULL AUTO_INCREMENT,
              product_category INT NOT NULL,
              product_id INT NOT NULL,
              customer_id INT NOT NULL,
              PRIMARY KEY(no),
              INDEX (product_category, product_id),
              FOREIGN KEY (product_category, product_id)
               REFERENCES product(category, id)
               ON UPDATE CASCADE ON DELETE RESTRICT,
              INDEX (customer_id),
              FOREIGN KEY (customer_id)
               REFERENCES customer(id)) ENGINE=INNODB;

The following examples will work from MariaDB 10.2.1 onwards.

Numeric constraints and comparisons:

CREATE TABLE t1 (a INT CHECK (a>2), b INT CHECK (b>2), CONSTRAINT a_greater
CHECK (a>b));

INSERT INTO t1(a) VALUES (1);
ERROR 4022 (23000): CONSTRAINT `a` failed for `test`.`t1`

INSERT INTO t1(a,b) VALUES (3,4);
ERROR 4022 (23000): CONSTRAINT `a_greater` failed for `test`.`t1`

INSERT INTO t1(a,b) VALUES (4,3);
Query OK, 1 row affected (0.04 sec)

Dropping a constraint:

ALTER TABLE t1 DROP CONSTRAINT a_greater;

Adding a constraint:

ALTER TABLE t1 ADD CONSTRAINT a_greater CHECK (a>b);

Date comparisons and character length:

CREATE TABLE t2 (name VARCHAR(30) CHECK (CHAR_LENGTH(name)>2), start_date
DATE, 
 end_date DATE CHECK (start_date IS NULL OR end_date IS NULL OR
start_date<end_date));

INSERT INTO t2(name, start_date, end_date) VALUES('Ione', '2003-12-15',
'2014-11-09');
Query OK, 1 row affected (0.04 sec)

INSERT INTO t2(name, start_date, end_date) VALUES('Io', '2003-12-15',
'2014-11-09');
ERROR 4022 (23000): CONSTRAINT `name` failed for `test`.`t2`

INSERT INTO t2(name, start_date, end_date) VALUES('Ione', NULL, '2014-11-09');
Query OK, 1 row affected (0.04 sec)

INSERT INTO t2(name, start_date, end_date) VALUES('Ione', '2015-12-15',
'2014-11-09');
ERROR 4022 (23000): CONSTRAINT `end_date` failed for `test`.`t2`

A misplaced parenthesis:

CREATE TABLE t3 (name VARCHAR(30) CHECK (CHAR_LENGTH(name>2)), start_date
DATE, 
 end_date DATE CHECK (start_date IS NULL OR end_date IS NULL OR
start_date<end_date));
Query OK, 0 rows affected (0.32 sec)

INSERT INTO t3(name, start_date, end_date) VALUES('Io', '2003-12-15',
'2014-11-09');
Query OK, 1 row affected, 1 warning (0.04 sec)

SHOW WARNINGS;
+---------+------+----------------------------------------+
| Level   | Code | Message                                |
+---------+------+----------------------------------------+
| Warning | 1292 | Truncated incorrect DOUBLE value: 'Io' |
+---------+------+----------------------------------------+

Compare the definition of table t2 to table t3. CHAR_LENGTH(name)>2 is very
different to CHAR_LENGTH(name>2) as the latter mistakenly performs a numeric
comparison on the name field, leading to unexpected results.

URL: https://mariadb.com/kb/en/constraint/https://mariadb.com/kb/en/constraint/��Q�F�X
�-:&Dynamic Columns from MariaDB 10MariaDB starting with 10.0.1
----------------------------
MariaDB 10.0.1 introduced the following improvements to the dynamic columns
feature.

Column Name Support
-------------------

It is possible to refer to column by names. Names can be used everywhere where
in MariaDB 5.3 one could use only strings:

* Create a dynamic column blob:

COLUMN_CREATE('int_col', 123 as int, 'double_col', 3.14 as double,
'string_col', 'text-data' as char);

* Set a column value:

COLUMN_ADD(dyncol_blob, 'intcol', 1234);

* Get a column value:

COLUMN_GET(dynstr, 'column1' as char(10));

* Check whether a column exists

COLUMN_EXISTS(dyncol_blob, 'column_name');

Changes in Behavior
-------------------

* Column list output now includes quoting:

select column_list(column_create(1, 22, 2, 23));
+------------------------------------------+
| column_list(column_create(1, 22, 2, 23)) |
+------------------------------------------+
| `1`,`2`                                  |
+------------------------------------------+
select column_list(column_create('column1', 22, 'column2', 23)); 
+----------------------------------------------------------+
| column_list(column_create('column1', 22, 'column2', 23)) |
+----------------------------------------------------------+
| `column1`,`column2`                                      |
+----------------------------------------------------------+

* Column name interpretation has been changed so that the string now is not
converted to a number. So some "magic" tricks will not work any more, for
example, "1test" and "1" now become different column names:

select column_list(column_add(column_create('1a', 22), '1b', 23));
+------------------------------------------------------------+
| column_list(column_add(column_create('1a', 22), '1b', 23)) |
+------------------------------------------------------------+
| `1a`,`1b`                                                  |
+------------------------------------------------------------+

* Old behavior:

select column_list(column_add(column_create('1a', 22), '1b', 23));
+------------------------------------------------------------+
| column_list(column_add(column_create('1a', 22), '1b', 23)) |
+------------------------------------------------------------+
| 1                                                          |
+------------------------------------------------------------+

New Functions
-------------

The following new functions have been added to dynamic columns in MariaDB 10

COLUMN_CHECK
------------

COLUMN_CHECK is used to check a column's integrity. When it encounters an
error it does not return illegal format errors but returns false instead. It
also checks integrity more thoroughly and finds errors in the dynamic column
internal structures which might not be found by other functions.

select column_check(column_create('column1', 22));
+--------------------------------------------+
| column_check(column_create('column1', 22)) |
+--------------------------------------------+
|                                          1 |
+--------------------------------------------+
select column_check('abracadabra');
+-----------------------------+
| column_check('abracadabra') |
+-----------------------------+
|                           0 |
+-----------------------------+

COLUMN_JSON
-----------

COLUMN_JSON converts all dynamic column record content to a JSON object.

select column_json(column_create('column1', 1, 'column2', "two"));
+------------------------------------------------------------+
| column_json(column_create('column1', 1, 'column2', "two")) |
+------------------------------------------------------------+
| {"column1":1,"column2":"two"}                              |
+------------------------------------------------------------+

Other Changes
-------------

* All API functions has prefix mariadb_dyncol_ (old prefix dynamic_column_ is
depricated
* API changed to be able to work with the new format (*_named functions).
* Removed 'delete' function because deleting could be done by adding NULL
value.
* 'Time' and 'datetime' in the new format are stored without microseconds if
they are 0.
* New function added to API (except that two which are representing SQL level
functions):
'Unpack' the dynamic columns content to an arrays of values and names.
3 functions to get any column value as string, integer (long long) or floating
point (double).

* New type of "dynamic column" row added on the API level (in SQL level output
it is a string but if you use dynamic column functions to construct object it
will be added as dynamic column value) which allow to add dynamic columns
inside dynamic columns. JSON function represent such recursive constructions
correctly but limit depth of representation as current implementation limit
(internally depth of dynamic columns embedding is not limited).

Interface with Cassandra
------------------------

CassandraSE is no longer actively being developed and has been removed in
MariaDB 10.6. See MDEV-23024.

Some internal changes were added to dynamic columns to allow them to serve as
an interface to Apache Cassandra dynamic columns. The Cassandra engine may
pack all columns which were not mentioned in the MariaDB interface table
definition and even bring changes in the dynamic column contents back to the
cassandra columns family (the table analog in cassandra).

URL: https://mariadb.com/kb/en/dynamic-columns-from-mariadb-10/https://mariadb.com/kb/en/dynamic-columns-from-mariadb-10/�\|�}���V &MERGEDescription
-----------

The MERGE storage engine, also known as the MRG_MyISAM engine, is a collection
of identical MyISAM tables that can be used as one. "Identical" means that all
tables have identical column and index information. You cannot merge MyISAM
tables in which the columns are listed in a different order, do not have
exactly the same columns, or have the indexes in different order. However, any
or all of the MyISAM tables can be compressed with myisampack. Columns names
and indexes names can be different, as long as data types and NULL/NOT NULL
clauses are the same. Differences in table options such as AVG_ROW_LENGTH,
MAX_ROWS, or PACK_KEYS do not matter.

Each index in a MERGE table must match an index in underlying MyISAM tables,
but the opposite is not true. Also, a MERGE table cannot have a PRIMARY KEY or
UNIQUE indexes, because it cannot enforce uniqueness over all underlying
tables.

The following options are meaningful for MERGE tables:

* UNION. This option specifies the list of the underlying MyISAM tables. The
list is enclosed between parentheses and separated with commas.
* INSERT_METHOD. This options specifies whether, and how, INSERTs are allowed
for the table. Allowed values are: NO (INSERTs are not allowed), FIRST (new
rows will be written into the first table specified in the UNION list), LAST
(new rows will be written into the last table specified in the UNION list).
The default value is NO.

If you define a MERGE table with a definition which is different from the
underlying MyISAM tables, or one of the underlying tables is not MyISAM, the
CREATE TABLE statement will not return any error. But any statement which
involves the table will produce an error like the following:

ERROR 1168 (HY000): Unable to open underlying table which is differently
defined 
 or of non-MyISAM type or doesn't exist

A CHECK TABLE will show more information about the problem.

The error is also produced if the table is properly define, but an underlying
table's definition changes at some point in time.

If you try to insert a new row into a MERGE table with INSERT_METHOD=NO, you
will get an error like the following:

ERROR 1036 (HY000): Table 'tbl_name' is read only

It is possible to build a MERGE table on MyISAM tables which have one or more
virtual columns. MERGE itself does not support virtual columns, thus such
columns will be seen as regular columns. The data types and sizes will still
need to be identical, and they cannot be NOT NULL.

Examples
--------

CREATE TABLE t1 (
  a INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
  message CHAR(20)) ENGINE=MyISAM;

CREATE TABLE t2 (
  a INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
  message CHAR(20)) ENGINE=MyISAM;

INSERT INTO t1 (message) VALUES ('Testing'),('table'),('t1');

INSERT INTO t2 (message) VALUES ('Testing'),('table'),('t2');

CREATE TABLE total (
  a INT NOT NULL AUTO_INCREMENT,
  message CHAR(20), INDEX(a))
  ENGINE=MERGE UNION=(t1,t2) INSERT_METHOD=LAST;

SELECT * FROM total;
+---+---------+
| a | message |
+---+---------+
| 1 | Testing |
| 2 | table   |
| 3 | t1      |
| 1 | Testing |
| 2 | table   |
| 3 | t2      |
+---+---------+

In the following example, we'll create three MyISAM tables, and then a MERGE
table on them. However, one of them uses a different data type for the column
b, so a SELECT will produce an error:

CREATE TABLE t1 (
 a INT,
 b INT
) ENGINE = MyISAM;

CREATE TABLE t2 (
 a INT,
 b INT
) ENGINE = MyISAM;

CREATE TABLE t3 (
 a INT,
 b TINYINT
) ENGINE = MyISAM;

CREATE TABLE t_mrg (
 a INT,
 b INT
) ENGINE = MERGE,UNION=(t1,t2,t3);

SELECT * FROM t_mrg;
ERROR 1168 (HY000): Unable to open underlying table which is differently
defined
 or of non-MyISAM type or doesn't exist

To find out what's wrong, we'll use a CHECK TABLE:

CHECK TABLE t_mrg\G
*************************** 1. row ***************************
 Table: test.t_mrg
   Op: check
Msg_type: Error
Msg_text: Table 'test.t3' is differently defined or of non-MyISAM type or
doesn't exist
*************************** 2. row ***************************
 Table: test.t_mrg
   Op: check
Msg_type: Error
Msg_text: Unable to open underlying table which is differently defined or of
non-MyISAM type or doesn't exist
*************************** 3. row ***************************
 Table: test.t_mrg
   Op: check
Msg_type: error
Msg_text: Corrupt

Now, we know that the problem is in t3's definition.

URL: https://mariadb.com/kb/en/merge/https://mariadb.com/kb/en/merge/�
�('DROP SEQUENCESyntax
------

DROP [TEMPORARY] SEQUENCE [IF EXISTS] [/*COMMENT TO SAVE*/]
  sequence_name [, sequence_name] ...

Description
-----------

DROP SEQUENCE removes one or more sequences created with CREATE SEQUENCE. You
must have the DROP privilege for each sequence. MariaDB returns an error
indicating by name which non-existing tables it was unable to drop, but it
also drops all of the tables in the list that do exist.

Important: When a table is dropped, user privileges on the table are not
automatically dropped. See GRANT.

If another connection is using the sequence, a metadata lock is active, and
this statement will wait until the lock is released. This is also true for
non-transactional tables.

For each referenced sequence, DROP SEQUENCE drops a temporary sequence with
that name, if it exists. If it does not exist, and the TEMPORARY keyword is
not used, it drops a non-temporary sequence with the same name, if it exists.
The TEMPORARY keyword ensures that a non-temporary sequence will not
accidentally be dropped.

Use IF EXISTS to prevent an error from occurring for sequences that do not
exist. A NOTE is generated for each non-existent sequence when using IF
EXISTS. See SHOW WARNINGS.

DROP SEQUENCE requires the DROP privilege.

Notes
-----

DROP SEQUENCE only removes sequences, not tables. However, DROP TABLE can
remove both sequences and tables.

URL: https://mariadb.com/kb/en/drop-sequence/https://mariadb.com/kb/en/drop-sequence/����b��
��*'CREATE SEQUENCESyntax
------

CREATE [OR REPLACE] [TEMPORARY] SEQUENCE [IF NOT EXISTS] sequence_name
[ INCREMENT [ BY | = ] increment ]
[ MINVALUE [=] minvalue | NO MINVALUE | NOMINVALUE ]
[ MAXVALUE [=] maxvalue | NO MAXVALUE | NOMAXVALUE ]
[ START [ WITH | = ] start ] 
[ CACHE [=] cache | NOCACHE ] [ CYCLE | NOCYCLE] 
[table_options]
The options for CREATE SEQUENCE can be given in any order, optionally followed
by table_options.

table_options can be any of the normal table options in CREATE TABLE but the
most usable ones are ENGINE=... and COMMENT=.

NOMAXVALUE and NOMINVALUE are there to allow one to create SEQUENCEs using the
Oracle syntax.

Description
-----------

CREATE SEQUENCE will create a sequence that generates new values when called
with NEXT VALUE FOR sequence_name. It's an alternative to AUTO INCREMENT when
one wants to have more control of how the numbers are generated. As the
SEQUENCE caches values (up to CACHE) it can in some cases be much faster than
AUTO INCREMENT. Another benefit is that one can access the last value
generated by all used sequences, which solves one of the limitations with
LAST_INSERT_ID().

CREATE SEQUENCE requires the CREATE privilege.

DROP SEQUENCE can be used to drop a sequence, and ALTER SEQUENCE to change it.

Arguments to Create
-------------------

The following options may be used:

+---------------+------------------------------+----------------------------+
| Option        | Default value                | Description                |
+---------------+------------------------------+----------------------------+
| INCREMENT     | 1                            | Increment to use for       |
|               |                              | values. May be negative.   |
|               |                              | Setting an increment of 0  |
|               |                              | causes the sequence to     |
|               |                              | use the value of the       |
|               |                              | auto_increment_increment   |
|               |                              | system variable at the     |
|               |                              | time of creation, which    |
|               |                              | is always a positive       |
|               |                              | number. (see MDEV-16035).  |
+---------------+------------------------------+----------------------------+
| MINVALUE      | 1 if INCREMENT > 0 and       | Minimum value for the      |
|               | -9223372036854775807 if      | sequence                   |
|               | INCREMENT < 0                |                            |
+---------------+------------------------------+----------------------------+
| MAXVALUE      | 9223372036854775806 if       | Max value for sequence     |
|               | INCREMENT > 0 and -1 if      |                            |
|               | INCREMENT < 0                |                            |
+---------------+------------------------------+----------------------------+
| START         | MINVALUE if INCREMENT > 0    | First value that the       |
|               | and MAX_VALUE if INCREMENT<  | sequence will generate     |
|               | 0                            |                            |
+---------------+------------------------------+----------------------------+
| CACHE         | 1000                         | Number of values that      |
|               |                              | should be cached. 0 if no  |
|               |                              | CACHE.  The underlying     |
|               |                              | table will be updated      |
|               |                              | first time a new sequence  |
|               |                              | number is generated and    |
|               |                              | each time the cache runs   |
|               |                              | out.                       |
+---------------+------------------------------+----------------------------+

If CYCLE is used then the sequence should start again from MINVALUE after it
has run out of values. Default value is NOCYCLE.

Constraints on Create Arguments
-------------------------------

To be able to create a legal sequence, the following must hold:

* MAXVALUE >= start
* MAXVALUE > MINVALUE
* START >= MINVALUE
* MAXVALUE <= 9223372036854775806  (LONGLONG_MAX-1)
* MINVALUE >= -9223372036854775807 (LONGLONG_MIN+1)

Note that sequences can't generate the maximum/minimum 64 bit number because
of the constraint of MINVALUE and MAXVALUE.

Atomic DDL
----------

MariaDB starting with 10.6.1
----------------------------
MariaDB 10.6.1 supports Atomic DDL and CREATE SEQUENCE is atomic.

Examples
--------

CREATE SEQUENCE s START WITH 100 INCREMENT BY 10;

CREATE SEQUENCE s2 START WITH -100 INCREMENT BY -10;

The following statement fails, as the increment conflicts with the defaults

CREATE SEQUENCE s3 START WITH -100 INCREMENT BY 10;
ERROR 4082 (HY000): Sequence 'test.s3' values are conflicting

The sequence can be created by specifying workable minimum and maximum values:

CREATE SEQUENCE s3 START WITH -100 INCREMENT BY 10 MINVALUE=-100 MAXVALUE=1000;

URL: https://mariadb.com/kb/en/create-sequence/https://mariadb.com/kb/en/create-sequence/��~�����)'ALTER SEQUENCESyntax
------

ALTER SEQUENCE [IF EXISTS] sequence_name
[ INCREMENT [ BY | = ] increment ]
[ MINVALUE [=] minvalue | NO MINVALUE | NOMINVALUE ]
[ MAXVALUE [=] maxvalue | NO MAXVALUE | NOMAXVALUE ]
[ START [ WITH | = ] start ] [ CACHE [=] cache ] [ [ NO ] CYCLE ]
[ RESTART [[WITH | =] restart]

ALTER SEQUENCE allows one to change any values for a SEQUENCE created with
CREATE SEQUENCE.

The options for ALTER SEQUENCE can be given in any order.

Description
-----------

ALTER SEQUENCE changes the parameters of an existing sequence generator. Any
parameters not specifically set in the ALTER SEQUENCE command retain their
prior settings.

ALTER SEQUENCE requires the ALTER privilege.

Arguments to ALTER SEQUENCE
---------------------------

The following options may be used:

+---------------+-------------------------------+---------------------------+
| Option        | Default value                 | Description               |
+---------------+-------------------------------+---------------------------+
| INCREMENT     | 1                             | Increment to use for      |
|               |                               | values. May be negative.  |
+---------------+-------------------------------+---------------------------+
| MINVALUE      | 1 if INCREMENT > 0 and        | Minimum value for the     |
|               | -9223372036854775807 if       | sequence.                 |
|               | INCREMENT < 0                 |                           |
+---------------+-------------------------------+---------------------------+
| MAXVALUE      | 9223372036854775806 if        | Max value for sequence.   |
|               | INCREMENT > 0 and -1 if       |                           |
|               | INCREMENT < 0                 |                           |
+---------------+-------------------------------+---------------------------+
| START         | MINVALUE if INCREMENT > 0     | First value that the      |
|               | and MAX_VALUE if INCREMENT< 0 | sequence will generate.   |
+---------------+-------------------------------+---------------------------+
| CACHE         | 1000                          | Number of values that     |
|               |                               | should be cached. 0 if    |
|               |                               | no CACHE.  The            |
|               |                               | underlying table will be  |
|               |                               | updated first time a new  |
|               |                               | sequence number is        |
|               |                               | generated and each time   |
|               |                               | the cache runs out.       |
+---------------+-------------------------------+---------------------------+
| CYCLE         | 0 (= NO CYCLE)                | 1 if the sequence should  |
|               |                               | start again from          |
|               |                               | MINVALUE# after it has    |
|               |                               | run out of values.        |
+---------------+-------------------------------+---------------------------+
| RESTART       | START if restart value not    | If  RESTART option is     |
|               | is given                      | used, NEXT VALUE will     |
|               |                               | return the restart value. |
+---------------+-------------------------------+---------------------------+

The optional clause RESTART [ WITH restart ] sets the next value for the
sequence. This is equivalent to calling the SETVAL() function with the is_used
argument as 0. The specified value will be returned by the next call of
nextval. Using RESTART with no restart value is equivalent to supplying the
start value that was recorded by CREATE SEQUENCE or last set by ALTER SEQUENCE
START WITH.

ALTER SEQUENCE will not allow you to change the sequence so that it's
inconsistent. For example:

CREATE SEQUENCE s1;
ALTER SEQUENCE s1 MINVALUE 10;
ERROR 4061 (HY000): Sequence 'test.t1' values are conflicting

ALTER SEQUENCE s1 MINVALUE 10 RESTART 10;
ERROR 4061 (HY000): Sequence 'test.t1' values are conflicting

ALTER SEQUENCE s1 MINVALUE 10 START 10 RESTART 10;

INSERT
------

To allow SEQUENCE objects to be backed up by old tools, like mariadb-dump, one
can use SELECT to read the current state of a SEQUENCE object and use an
INSERT to update the SEQUENCE object. INSERT is only allowed if all fields are
specified:

CREATE SEQUENCE s1;
INSERT INTO s1 VALUES(1000,10,2000,1005,1,1000,0,0);
SELECT * FROM s1;

+------------+-----------+-----------+-------+-----------+-------+-------+-----
-+
| next_value | min_value | max_value | start | increment | cache | cycle |
round |
+------------+-----------+-----------+-------+-----------+-------+-------+-----
-+
|       1000 |        10 |      2000 |  1005 |         1 |  1000 |     0 |    
0 |
+------------+-----------+-----------+-------+-----------+-------+-------+-----
-+

SHOW CREATE SEQUENCE s1;
+-------+----------------------------------------------------------------------
---------------------------------------+
| Table | Create Table                                                        
                    |
+-------+----------------------------------------------------------------------
---------------------------------------+
| s1    | CREATE SEQUENCE `s1` start with 1005 minvalue 10 maxvalue 2000
increment by 1 cache 1000 nocycle ENGINE=Aria |
+-------+----------------------------------------------------------------------
---------------------------------------+

Notes
-----

ALTER SEQUENCE will instantly affect all future SEQUENCE operations. This is
in contrast to some other databases where the changes requested by ALTER
SEQUENCE will not be seen until the sequence cache has run out.

ALTER SEQUENCE will take a full table lock of the sequence object during its
(brief) operation. This ensures that ALTER SEQUENCE is replicated correctly.
If you only want to set the next sequence value to a higher value than
current, then you should use SETVAL() instead, as this is not blocking.

If you want to change storage engine, sequence comment or rename the sequence,
you can use ALTER TABLE for this.

URL: https://mariadb.com/kb/en/alter-sequence/https://mariadb.com/kb/en/alter-sequence/7B���	��7'NEXT VALUE for sequence_nameMariaDB starting with 10.3
--------------------------
SEQUENCEs were introduced in MariaDB 10.3

Syntax
------

NEXT VALUE FOR sequence

or

NEXTVAL(sequence_name)

or in Oracle mode (SQL_MODE=ORACLE)

sequence_name.nextval

NEXT VALUE FOR is ANSI SQL syntax while NEXTVAL() is PostgreSQL syntax.

Description
-----------

Generate next value for a SEQUENCE.

* You can greatly speed up NEXT VALUE by creating the sequence with the CACHE
option. If not, every NEXT VALUE usage will cause changes in the stored
SEQUENCE table.
* When using NEXT VALUE the value will be reserved at once and will not be
reused, except if the SEQUENCE was created with CYCLE. This means that when
you are using SEQUENCEs you have to expect gaps in the generated sequence
numbers.
* If one updates the SEQUENCE with SETVAL() or ALTER SEQUENCE ... RESTART,
NEXT VALUE FOR will notice this and start from the next requested value.
* FLUSH TABLES will close the sequence and the next sequence number generated
will be according to what's stored in the SEQUENCE object. In effect, this
will discard the cached values.
* A server restart (or closing the current connection) also causes a drop of
all cached values. The cached sequence numbers are reserved only for the
current connection.
* NEXT VALUE requires the INSERT privilege.

MariaDB starting with 10.3.3
----------------------------
* You can also use NEXT VALUE FOR sequence for column DEFAULT.

URL: https://mariadb.com/kb/en/next-value-for-sequence_name/https://mariadb.com/kb/en/next-value-for-sequence_name/� �	;'PREVIOUS VALUE FOR sequence_nameMariaDB starting with 10.3
--------------------------
SEQUENCEs were introduced in MariaDB 10.3.

Syntax
------

PREVIOUS VALUE FOR sequence_name

or

LASTVAL(sequence_name)

or in Oracle mode (SQL_MODE=ORACLE)

sequence_name.currval

PREVIOUS VALUE FOR is IBM DB2 syntax while LASTVAL() is PostgreSQL syntax.

Description
-----------

Get last value in the current connection generated from a sequence.

* If the sequence has not yet been used by the connection, PREVIOUS VALUE FOR
returns NULL (the same thing applies with a new connection which doesn't see a
last value for an existing sequence).
* If a SEQUENCE has been dropped and re-created then it's treated as a new
SEQUENCE and PREVIOUS VALUE FOR will return NULL.
* FLUSH TABLES has no effect on PREVIOUS VALUE FOR.
* Previous values for all used sequences are stored per connection until
connection ends.
* PREVIOUS VALUE FOR requires the SELECT privilege.

Example
-------

CREATE SEQUENCE s START WITH 100 INCREMENT BY 10;

SELECT PREVIOUS VALUE FOR s;
+----------------------+
| PREVIOUS VALUE FOR s |
+----------------------+
|                 NULL |
+----------------------+

# The function works for sequences only, if the table is used an error is
generated
SELECT PREVIOUS VALUE FOR t;
ERROR 4089 (42S02): 'test.t' is not a SEQUENCE

# Call the NEXT VALUE FOR s:
SELECT NEXT VALUE FOR s;
+------------------+
| NEXT VALUE FOR s |
+------------------+
|              100 |
+------------------+

SELECT PREVIOUS VALUE FOR s;
+----------------------+
| PREVIOUS VALUE FOR s |
+----------------------+
|                  100 |
+----------------------+

Now try to start the new connection and check that the last value is still
NULL, before updating the value in the new connection after the output of the
new connection gets current value (110 in the example below). Note that first
connection cannot see this change and the result of last value still remains
the same (100 in the example above).

$ .mysql -uroot test -e"SELECT PREVIOUS VALUE FOR s; SELECT NEXT VALUE FOR s;
SELECT PREVIOUS VALUE FOR s;"
+----------------------+
| PREVIOUS VALUE FOR s |
+----------------------+
|                 NULL |
+----------------------+
+------------------+
| NEXT VALUE FOR s |
+------------------+
|              110 |
+------------------+
+----------------------+
| PREVIOUS VALUE FOR s |
+----------------------+
|                  110 |
+----------------------+

URL: https://mariadb.com/kb/en/previous-value-for-sequence_name/https://mariadb.com/kb/en/previous-value-for-sequence_name/�
�((JSON_ARRAYAGGMariaDB starting with 10.5.0
----------------------------
JSON_ARRAYAGG was added in MariaDB 10.5.0.

Syntax
------

JSON_ARRAYAGG(column_or_expression)

Description
-----------

JSON_ARRAYAGG returns a JSON array containing an element for each value in a
given set of JSON or SQL values. It acts on a column or an expression that
evaluates to a single value.

Returns NULL in the case of an error, or if the result contains no rows.

JSON_ARRAYAGG cannot currently be used as a window function.

The full syntax is as follows:

JSON_ARRAYAGG([DISTINCT] expr [,expr ...]
      [ORDER BY {unsigned_integer | col_name | expr}
        [ASC | DESC] [,col_name ...]]
      [LIMIT {[offset,] row_count | row_count OFFSET offset}])

Examples
--------

CREATE TABLE t1 (a INT, b INT);

INSERT INTO t1 VALUES (1, 1),(2, 1), (1, 1),(2, 1), (3, 2),(2, 2),(2, 2),(2,
2);

SELECT JSON_ARRAYAGG(a), JSON_ARRAYAGG(b) FROM t1;
+-------------------+-------------------+
| JSON_ARRAYAGG(a)  | JSON_ARRAYAGG(b)  |
+-------------------+-------------------+
| [1,2,1,2,3,2,2,2] | [1,1,1,1,2,2,2,2] |
+-------------------+-------------------+

SELECT JSON_ARRAYAGG(a), JSON_ARRAYAGG(b) FROM t1 GROUP BY b;
+------------------+------------------+
| JSON_ARRAYAGG(a) | JSON_ARRAYAGG(b) |
+------------------+------------------+
| [1,2,1,2]        | [1,1,1,1]        |
| [3,2,2,2]        | [2,2,2,2]        |
+------------------+------------------+

URL: https://mariadb.com/kb/en/json_arrayagg/https://mariadb.com/kb/en/json_arrayagg/e?&
3�������
!'SETVALMariaDB starting with 10.3.1
----------------------------
SEQUENCEs were introduced in MariaDB 10.3.

Syntax
------

SETVAL(sequence_name, next_value, [is_used, [round]])

Description
-----------

Set the next value to be returned for a SEQUENCE.

This function is compatible with PostgreSQL syntax, extended with the round
argument.

If the is_used argument is not given or is 1 or true, then the next used value
will one after the given value. If is_used is 0 or false then the next
generated value will be the given value.

If round is used then it will set the round value (or the internal cycle
count, starting at zero) for the sequence. If round is not used, it's assumed
to be 0.

next_value must be an integer literal.

For SEQUENCE tables defined with CYCLE (see CREATE SEQUENCE) one should use
both next_value and round to define the next value. In this case the current
sequence value is defined to be round, next_value.

The result returned by SETVAL() is next_value or NULL if the given next_value
and round is smaller than the current value.

SETVAL() will not set the SEQUENCE value to a something that is less than its
current value. This is needed to ensure that SETVAL() is replication safe. If
you want to set the SEQUENCE to a smaller number use ALTER SEQUENCE.

If CYCLE is used, first round and then next_value are compared to see if the
value is bigger than the current value.

Internally, in the MariaDB server, SETVAL() is used to inform slaves that a
SEQUENCE has changed value. The slave may get SETVAL() statements out of
order, but this is ok as only the biggest one will have an effect.

SETVAL requires the INSERT privilege.

Examples
--------

SELECT setval(foo, 42);           -- Next nextval will return 43
SELECT setval(foo, 42, true);     -- Same as above
SELECT setval(foo, 42, false);    -- Next nextval will return 42

SETVAL setting higher and lower values on a sequence with an increment of 10:

SELECT NEXTVAL(s);
+------------+
| NEXTVAL(s) |
+------------+
|         50 |
+------------+

SELECT SETVAL(s, 100);
+----------------+
| SETVAL(s, 100) |
+----------------+
|            100 |
+----------------+

SELECT NEXTVAL(s);
+------------+
| NEXTVAL(s) |
+------------+
|        110 |
+------------+

SELECT SETVAL(s, 50);
+---------------+
| SETVAL(s, 50) |
+---------------+
|          NULL |
+---------------+

SELECT NEXTVAL(s);
+------------+
| NEXTVAL(s) |
+------------+
|        120 |
+------------+

Example demonstrating round:

CREATE OR REPLACE SEQUENCE s1
 START WITH 1
 MINVALUE 1
 MAXVALUE 99
 INCREMENT BY 1
 CACHE 20
 CYCLE;

SELECT SETVAL(s1, 99, 1, 0);
+----------------------+
| SETVAL(s1, 99, 1, 0) |
+----------------------+
|                   99 |
+----------------------+

SELECT NEXTVAL(s1);
+-------------+
| NEXTVAL(s1) |
+-------------+
|           1 |
+-------------+

The following statement returns NULL, as the given next_value and round is
smaller than the current value.

SELECT SETVAL(s1, 99, 1, 0);
+----------------------+
| SETVAL(s1, 99, 1, 0) |
+----------------------+
|                 NULL |
+----------------------+

SELECT NEXTVAL(s1);
+-------------+
| NEXTVAL(s1) |
+-------------+
|           2 |
+-------------+

Increasing the round from zero to 1 will allow next_value to be returned.

SELECT SETVAL(s1, 99, 1, 1);
+----------------------+
| SETVAL(s1, 99, 1, 1) |
+----------------------+
|                   99 |
+----------------------+

SELECT NEXTVAL(s1);
+-------------+
| NEXTVAL(s1) |
+-------------+
|           1 |
+-------------+

URL: https://mariadb.com/kb/en/setval/https://mariadb.com/kb/en/setval/��)(JSON_OBJECTAGGMariaDB starting with 10.5.0
----------------------------
JSON_OBJECTAGG was added in MariaDB 10.5.0.

Syntax
------

JSON_OBJECTAGG(key, value)

Description
-----------

JSON_OBJECTAGG returns a JSON object containing key-value pairs. It takes two
expressions that evaluate to a single value, or two column names, as
arguments, the first used as a key, and the second as a value.

Returns NULL in the case of an error, or if the result contains no rows.

JSON_OBJECTAGG cannot currently be used as a window function.

Examples
--------

select * from t1;
+------+-------+
| a    | b     |
+------+-------+
|    1 | Hello |
|    1 | World |
|    2 | This  |
+------+-------+

SELECT JSON_OBJECTAGG(a, b) FROM t1;
+----------------------------------------+
| JSON_OBJECTAGG(a, b)                   |
+----------------------------------------+
| {"1":"Hello", "1":"World", "2":"This"} |
+----------------------------------------+

URL: https://mariadb.com/kb/en/json_objectagg/https://mariadb.com/kb/en/json_objectagg/��,(JSON_ARRAY_APPENDSyntax
------

JSON_ARRAY_APPEND(json_doc, path, value[, path, value] ...)

Description
-----------

Appends values to the end of the specified arrays within a JSON document,
returning the result, or NULL if any of the arguments are NULL.

Evaluation is performed from left to right, with the resulting document from
the previous pair becoming the new value against which the next pair is
evaluated.

If the json_doc is not a valid JSON document, or if any of the paths are not
valid, or contain a * or ** wildcard, an error is returned.

Examples
--------

SET @json = '[1, 2, [3, 4]]';

SELECT JSON_ARRAY_APPEND(@json, '$[0]', 5)
+-------------------------------------+
| JSON_ARRAY_APPEND(@json, '$[0]', 5) |
+-------------------------------------+
| [[1, 5], 2, [3, 4]]                 |
+-------------------------------------+

SELECT JSON_ARRAY_APPEND(@json, '$[1]', 6);
+-------------------------------------+
| JSON_ARRAY_APPEND(@json, '$[1]', 6) |
+-------------------------------------+
| [1, [2, 6], [3, 4]]                 |
+-------------------------------------+

SELECT JSON_ARRAY_APPEND(@json, '$[1]', 6, '$[2]', 7);
+------------------------------------------------+
| JSON_ARRAY_APPEND(@json, '$[1]', 6, '$[2]', 7) |
+------------------------------------------------+
| [1, [2, 6], [3, 4, 7]]                         |
+------------------------------------------------+

SELECT JSON_ARRAY_APPEND(@json, '$', 5);
+----------------------------------+
| JSON_ARRAY_APPEND(@json, '$', 5) |
+----------------------------------+
| [1, 2, [3, 4], 5]                |
+----------------------------------+

SET @json = '{"A": 1, "B": [2], "C": [3, 4]}';

SELECT JSON_ARRAY_APPEND(@json, '$.B', 5);
+------------------------------------+
| JSON_ARRAY_APPEND(@json, '$.B', 5) |
+------------------------------------+
| {"A": 1, "B": [2, 5], "C": [3, 4]} |
+------------------------------------+

URL: https://mariadb.com/kb/en/json_array_append/https://mariadb.com/kb/en/json_array_append/N�:.U�9���/(JSONPath ExpressionsA number of JSON functions accept JSON Path expressions. MariaDB defines this
path as follows:

JSON Path Syntax
----------------

path : ['lax'] '$' [step]*

The path starts with an optional path mode. At the moment, MariaDB supports
only the "lax" mode, which is also the mode that is used when it is not
explicitly specified.

The $ symbol represents the context item. The search always starts from the
context item; because of that, the path always starts with $.

Then, it is followed by zero or more steps, which select element(s) in the
JSON document. A step may be one of the following:

* Object member selector
* Array element selector
* Wildcard selector

Object Member Selector
----------------------

To select member(s) in a JSON object, one can use one of the following:

* .memberName selects the value of the member with name memberName.
* ."memberName" - the same as above but allows one to select a member with a
name that's not a valid identifier (that is, has space, dot, and/or other
characters)
* .* - selects the values of all members of the object.

If the current item is an array (instead of an object), nothing will be
selected.

Array Element Selector
----------------------

To select elements of an array, one can use one of the following:

* [N] selects element number N in the array. The elements are counted from
zero.
* [*] selects all elements in the array.

If the current item is an object (instead of an array), nothing will be
selected.

Starting from MariaDB server 10.9, JSON path also supports negative index in
array, 'last' keyword and range notation ('to' keyword) for accessing array
elements. Negative index starts from -1.

* [-N] selects n th element from end.
* [last-N] selects n th element from the last element.
* [M to N] selects range of elements starting from index M to N.

Example:

SET @json='{
      "A": [0,
         [1, 2, 3],
         [4, 5, 6],
         "seven",
         0.8,
         true,
         false,
         "eleven",
         [12, [13, 14], {"key1":"value1"},[15]],
         true],
      "B": {"C": 1},
      "D": 2
     }';
SELECT JSON_EXTRACT(@json, '$.A[-8][1]');
+--------------------------------------------------+
| JSON_EXTRACT(@json, '$.A[-8][1]')                |
+--------------------------------------------------+
| 5                                                |
+--------------------------------------------------+

SELECT JSON_EXTRACT(@json, '$.A[last-7][1]');
+-----------------------------------------------+
| SELECT JSON_EXTRACT(@json, '$.A[last-7][1]'); |
+-----------------------------------------------+
| 5                                             |
+-----------------------------------------------+

SET @json= '[
      [1, {"key1": "value1"}, 3],
      [false, 5, 6],
      [7, 8, [9, {"key2": 2}, 11]],
      [15, 1.34, [14], ["string1", [16, {"key1":[1,2,3,[4,5,6]]}, 18]]],
      [19, 20],
      21, 22
      ]';

SELECT JSON_EXTRACT(@json, '$[0 to 3][2]');
+-----------------------------------------------+
| JSON_EXTRACT(@json, '$[0 to 3][2]')           |
+-----------------------------------------------+
| [3, 6, [9, {"key2": 2}, 11], [14]]            |
+-----------------------------------------------+

This will produce output for first index of eighth from last element of a two
dimensional array.

Note: In range notation, when M > N ( when M,N are greater than or equal to 0)
or (size of array - M or size of array - N when M, N are less than 0), then it
is treated as an impossible range and NULL is returned.

SET @json= '[1, 2, 3, 4, 5]';
SELECT JSON_EXTRACT(@json, '$[4 to 2]');
+-----------------------------------+
| JSON_EXTRACT(@json, '$[4 to 2]')  |
+-----------------------------------+
| NULL                              |
+-----------------------------------+

Wildcard
--------

The wildcard step, **, recursively selects all child elements of the current
element. Both array elements and object members are selected.

The wildcard step must not be the last step in the JSONPath expression. It
must be followed by an array or object member selector step.

For example:

select json_extract(@json_doc, '$**.price');

will select all object members in the document that are named price, while

select json_extract(@json_doc, '$**[2]');

will select the second element in each of the arrays present in the document.

Compatibility
-------------

MariaDB's JSONPath syntax supports a subset of JSON Path's definition in the
SQL Standard. The most notable things not supported are the strict mode and
filters.

MariaDB's JSONPath is close to MySQL's JSONPath. The wildcard step ( ** ) is a
non-standard extension that has the same meaning as in MySQL. The difference
between MariaDB and MySQL's JSONPath is: MySQL doesn't allow one to specify
the mode explicitly (but uses lax mode implicitly).

URL: https://mariadb.com/kb/en/jsonpath-expressions/https://mariadb.com/kb/en/jsonpath-expressions/]ug8K����,(JSON_ARRAY_INSERTSyntax
------

JSON_ARRAY_INSERT(json_doc, path, value[, path, value] ...)

Description
-----------

Inserts a value into a JSON document, returning the modified document, or NULL
if any of the arguments are NULL.

Evaluation is performed from left to right, with the resulting document from
the previous pair becoming the new value against which the next pair is
evaluated.

If the json_doc is not a valid JSON document, or if any of the paths are not
valid, or contain a * or ** wildcard, an error is returned.

Examples
--------

SET @json = '[1, 2, [3, 4]]';

SELECT JSON_ARRAY_INSERT(@json, '$[0]', 5);
+-------------------------------------+
| JSON_ARRAY_INSERT(@json, '$[0]', 5) |
+-------------------------------------+
| [5, 1, 2, [3, 4]]                   |
+-------------------------------------+

SELECT JSON_ARRAY_INSERT(@json, '$[1]', 6);
+-------------------------------------+
| JSON_ARRAY_INSERT(@json, '$[1]', 6) |
+-------------------------------------+
| [1, 6, 2, [3, 4]]                   |
+-------------------------------------+

SELECT JSON_ARRAY_INSERT(@json, '$[1]', 6, '$[2]', 7);
+------------------------------------------------+
| JSON_ARRAY_INSERT(@json, '$[1]', 6, '$[2]', 7) |
+------------------------------------------------+
| [1, 6, 7, 2, [3, 4]]                           |
+------------------------------------------------+

URL: https://mariadb.com/kb/en/json_array_insert/https://mariadb.com/kb/en/json_array_insert/�
�((JSON_CONTAINSSyntax
------

JSON_CONTAINS(json_doc, val[, path])

Description
-----------

Returns whether or not the specified value is found in the given JSON document
or, optionally, at the specified path within the document. Returns 1 if it
does, 0 if not and NULL if any of the arguments are null. An error occurs if
the document or path is not valid, or contains the * or ** wildcards.

Examples
--------

SET @json = '{"A": 0, "B": {"C": 1}, "D": 2}';

SELECT JSON_CONTAINS(@json, '2', '$.A');
+----------------------------------+
| JSON_CONTAINS(@json, '2', '$.A') |
+----------------------------------+
|                                0 |
+----------------------------------+

SELECT JSON_CONTAINS(@json, '2', '$.D');
+----------------------------------+
| JSON_CONTAINS(@json, '2', '$.D') |
+----------------------------------+
|                                1 |
+----------------------------------+

SELECT JSON_CONTAINS(@json, '{"C": 1}', '$.A');
+-----------------------------------------+
| JSON_CONTAINS(@json, '{"C": 1}', '$.A') |
+-----------------------------------------+
|                                       0 |
+-----------------------------------------+

SELECT JSON_CONTAINS(@json, '{"C": 1}', '$.B');
+-----------------------------------------+
| JSON_CONTAINS(@json, '{"C": 1}', '$.B') |
+-----------------------------------------+
|                                       1 |
+-----------------------------------------+

URL: https://mariadb.com/kb/en/json_contains/https://mariadb.com/kb/en/json_contains/��-(JSON_CONTAINS_PATHSyntax
------

JSON_CONTAINS_PATH(json_doc, return_arg, path[, path] ...)

Description
-----------

Indicates whether the given JSON document contains data at the specified path
or paths. Returns 1 if it does, 0 if not and NULL if any of the arguments are
null.

The return_arg can be one or all:

* one - Returns 1 if at least one path exists within the JSON document. 
* all - Returns 1 only if all paths exist within the JSON document.

Examples
--------

SET @json = '{"A": 1, "B": [2], "C": [3, 4]}';

SELECT JSON_CONTAINS_PATH(@json, 'one', '$.A', '$.D');
+------------------------------------------------+
| JSON_CONTAINS_PATH(@json, 'one', '$.A', '$.D') |
+------------------------------------------------+
|                                              1 |
+------------------------------------------------+
1 row in set (0.00 sec)

SELECT JSON_CONTAINS_PATH(@json, 'all', '$.A', '$.D');
+------------------------------------------------+
| JSON_CONTAINS_PATH(@json, 'all', '$.A', '$.D') |
+------------------------------------------------+
|                                              0 |
+------------------------------------------------+

URL: https://mariadb.com/kb/en/json_contains_path/https://mariadb.com/kb/en/json_contains_path/�
�%(JSON_DEPTHSyntax
------

JSON_DEPTH(json_doc)

Description
-----------

Returns the maximum depth of the given JSON document, or NULL if the argument
is null. An error will occur if the argument is an invalid JSON document.

* Scalar values or empty arrays or objects have a depth of 1.
* Arrays or objects that are not empty but contain only elements or member
values of depth 1 will have a depth of 2.
* In other cases, the depth will be greater than 2.

Examples
--------

SELECT JSON_DEPTH('[]'), JSON_DEPTH('true'), JSON_DEPTH('{}');
+------------------+--------------------+------------------+
| JSON_DEPTH('[]') | JSON_DEPTH('true') | JSON_DEPTH('{}') |
+------------------+--------------------+------------------+
|                1 |                  1 |                1 |
+------------------+--------------------+------------------+

SELECT JSON_DEPTH('[1, 2, 3]'), JSON_DEPTH('[[], {}, []]');
+-------------------------+----------------------------+
| JSON_DEPTH('[1, 2, 3]') | JSON_DEPTH('[[], {}, []]') |
+-------------------------+----------------------------+
|                       2 |                          2 |
+-------------------------+----------------------------+

SELECT JSON_DEPTH('[1, 2, [3, 4, 5, 6], 7]');
+---------------------------------------+
| JSON_DEPTH('[1, 2, [3, 4, 5, 6], 7]') |
+---------------------------------------+
|                                     3 |
+---------------------------------------+

URL: https://mariadb.com/kb/en/json_depth/https://mariadb.com/kb/en/json_depth/����V���
�
�((JSON_DETAILEDSyntax
------

JSON_DETAILED(json_doc[, tab_size])
JSON_PRETTY(json_doc[, tab_size])

Description
-----------

Represents JSON in the most understandable way emphasizing nested structures.

JSON_PRETTY was added as an alias for JSON_DETAILED in MariaDB 10.10.3,
MariaDB 10.9.5, MariaDB 10.8.7, MariaDB 10.7.8, MariaDB 10.6.12, MariaDB
10.5.19 and MariaDB 10.4.28.

Example
-------

SET @j = '{ "A":1,"B":[2,3]}';

SELECT @j;
+--------------------+
| @j                 |
+--------------------+
| { "A":1,"B":[2,3]} |
+--------------------+

SELECT JSON_DETAILED(@j);
+------------------------------------------------------------+
| JSON_DETAILED(@j)                                          |
+------------------------------------------------------------+
| {
  "A": 1,
  "B":
  [
    2,
    3
  ]
} |
+------------------------------------------------------------+

URL: https://mariadb.com/kb/en/json_detailed/https://mariadb.com/kb/en/json_detailed/��&(JSON_EQUALSMariaDB starting with 10.7.0
----------------------------
JSON_EQUALS was added in MariaDB 10.7.0

Syntax
------

JSON_EQUALS(json1, json2)

Description
-----------

Checks if there is equality between two json objects. Returns 1 if it there
is, 0 if not, or NULL if any of the arguments are null.

Examples
--------

SELECT JSON_EQUALS('{"a"   :[1, 2, 3],"b":[4]}', '{"b":[4],"a":[1, 2, 3.0]}');
+------------------------------------------------------------------------+
| JSON_EQUALS('{"a"   :[1, 2, 3],"b":[4]}', '{"b":[4],"a":[1, 2, 3.0]}') |
+------------------------------------------------------------------------+
|                                                                      1 |
+------------------------------------------------------------------------+

SELECT JSON_EQUALS('{"a":[1, 2, 3]}', '{"a":[1, 2, 3.01]}');
+------------------------------------------------------+
| JSON_EQUALS('{"a":[1, 2, 3]}', '{"a":[1, 2, 3.01]}') |
+------------------------------------------------------+
|                                                    0 |
+------------------------------------------------------+

URL: https://mariadb.com/kb/en/json_equals/https://mariadb.com/kb/en/json_equals/�&(JSON_EXISTSSyntax
------

Description
-----------

Determines whether a specified JSON value exists in the given data. Returns 1
if found, 0 if not, or NULL if any of the inputs were NULL.

Examples
--------

SELECT JSON_EXISTS('{"key1":"xxxx", "key2":[1, 2, 3]}', "$.key2");
+------------------------------------------------------------+
| JSON_EXISTS('{"key1":"xxxx", "key2":[1, 2, 3]}', "$.key2") |
+------------------------------------------------------------+
|                                                          1 |
+------------------------------------------------------------+

SELECT JSON_EXISTS('{"key1":"xxxx", "key2":[1, 2, 3]}', "$.key3");
+------------------------------------------------------------+
| JSON_EXISTS('{"key1":"xxxx", "key2":[1, 2, 3]}', "$.key3") |
+------------------------------------------------------------+
|                                                          0 |
+------------------------------------------------------------+

SELECT JSON_EXISTS('{"key1":"xxxx", "key2":[1, 2, 3]}', "$.key2[1]");
+---------------------------------------------------------------+
| JSON_EXISTS('{"key1":"xxxx", "key2":[1, 2, 3]}', "$.key2[1]") |
+---------------------------------------------------------------+
|                                                             1 |
+---------------------------------------------------------------+

SELECT JSON_EXISTS('{"key1":"xxxx", "key2":[1, 2, 3]}', "$.key2[10]");
+----------------------------------------------------------------+
| JSON_EXISTS('{"key1":"xxxx", "key2":[1, 2, 3]}', "$.key2[10]") |
+----------------------------------------------------------------+
|                                                              0 |
+----------------------------------------------------------------+

URL: https://mariadb.com/kb/en/json_exists/https://mariadb.com/kb/en/json_exists/�.'(JSON_EXTRACTSyntax
------

JSON_EXTRACT(json_doc, path[, path] ...)

Description
-----------

Extracts data from a JSON document. The extracted data is selected from the
parts matching the path arguments. Returns all matched values; either as a
single matched value, or, if the arguments could return multiple values, a
result autowrapped as an array in the matching order.

Returns NULL if no paths match or if any of the arguments are NULL.

An error will occur if any path argument is not a valid path, or if the
json_doc argument is not a valid JSON document.

The path expression be a JSONPath expression as supported by MariaDB

Examples
--------

SET @json = '[1, 2, [3, 4]]';

SELECT JSON_EXTRACT(@json, '$[1]');
+-----------------------------+
| JSON_EXTRACT(@json, '$[1]') |
+-----------------------------+
| 2                           |
+-----------------------------+

SELECT JSON_EXTRACT(@json, '$[2]');
+-----------------------------+
| JSON_EXTRACT(@json, '$[2]') |
+-----------------------------+
| [3, 4]                      |
+-----------------------------+

SELECT JSON_EXTRACT(@json, '$[2][1]');
+--------------------------------+
| JSON_EXTRACT(@json, '$[2][1]') |
+--------------------------------+
| 4                              |
+--------------------------------+

URL: https://mariadb.com/kb/en/json_extract/https://mariadb.com/kb/en/json_extract/�o�V����l�
���&(JSON_INSERTSyntax
------

JSON_INSERT(json_doc, path, val[, path, val] ...)

Description
-----------

Inserts data into a JSON document, returning the resulting document or NULL if
either of the json_doc or path arguments are null.

An error will occur if the JSON document is invalid, or if any of the paths
are invalid or contain a * or ** wildcard.

JSON_INSERT can only insert data while JSON_REPLACE can only update. JSON_SET
can update or insert data.

Examples
--------

SET @json = '{ "A": 0, "B": [1, 2]}';

SELECT JSON_INSERT(@json, '$.C', '[3, 4]');
+--------------------------------------+
| JSON_INSERT(@json, '$.C', '[3, 4]')  |
+--------------------------------------+
| { "A": 0, "B": [1, 2], "C":"[3, 4]"} |
+--------------------------------------+

URL: https://mariadb.com/kb/en/json_insert/https://mariadb.com/kb/en/json_insert/�	�$(JSON_KEYSSyntax
------

JSON_KEYS(json_doc[, path])

Description
-----------

Returns the keys as a JSON array from the top-level value of a JSON object or,
if the optional path argument is provided, the top-level keys from the path.

Excludes keys from nested sub-objects in the top level value. The resulting
array will be empty if the selected object is empty.

Returns NULL if any of the arguments are null, a given path does not locate an
object, or if the json_doc argument is not an object.

An error will occur if JSON document is invalid, the path is invalid or if the
path contains a * or ** wildcard.

Examples
--------

SELECT JSON_KEYS('{"A": 1, "B": {"C": 2}}');
+--------------------------------------+
| JSON_KEYS('{"A": 1, "B": {"C": 2}}') |
+--------------------------------------+
| ["A", "B"]                           |
+--------------------------------------+

SELECT JSON_KEYS('{"A": 1, "B": 2, "C": {"D": 3}}', '$.C');
+-----------------------------------------------------+
| JSON_KEYS('{"A": 1, "B": 2, "C": {"D": 3}}', '$.C') |
+-----------------------------------------------------+
| ["D"]                                               |
+-----------------------------------------------------+

URL: https://mariadb.com/kb/en/json_keys/https://mariadb.com/kb/en/json_keys/��&(JSON_LENGTHSyntax
------

JSON_LENGTH(json_doc[, path])

Description
-----------

Returns the length of a JSON document, or, if the optional path argument is
given, the length of the value within the document specified by the path.

Returns NULL if any of the arguments argument are null or the path argument
does not identify a value in the document.

An error will occur if the JSON document is invalid, the path is invalid or if
the path contains a * or ** wildcard.

Length will be determined as follow:

* A scalar's length is always 1.
* If an array, the number of elements in the array.
* If an object, the number of members in the object.

The length of nested arrays or objects are not counted.

Examples
--------

URL: https://mariadb.com/kb/en/json_length/https://mariadb.com/kb/en/json_length/��+(JSON_MERGE_PATCHMariaDB starting with 10.3.16
-----------------------------
JSON_MERGE_PATCH was introduced in MariaDB 10.3.16 and MariaDB 10.4.5.

Syntax
------

JSON_MERGE_PATCH(json_doc, json_doc[, json_doc] ...)

Description
-----------

Merges the given JSON documents, returning the merged result, or NULL if any
argument is NULL.

JSON_MERGE_PATCH is an RFC 7396-compliant replacement for JSON_MERGE, which
has been deprecated.

Example
-------

SET @json1 = '[1, 2]';
SET @json2 = '[2, 3]';
SELECT JSON_MERGE_PATCH(@json1,@json2),JSON_MERGE_PRESERVE(@json1,@json2);
+---------------------------------+------------------------------------+
| JSON_MERGE_PATCH(@json1,@json2) | JSON_MERGE_PRESERVE(@json1,@json2) |
+---------------------------------+------------------------------------+
| [2, 3]                          | [1, 2, 2, 3]                       |
+---------------------------------+------------------------------------+

URL: https://mariadb.com/kb/en/json_merge_patch/https://mariadb.com/kb/en/json_merge_patch/�.(JSON_MERGE_PRESERVEMariaDB starting with 10.3.16
-----------------------------
JSON_MERGE_PRESERVE was introduced in MariaDB 10.3.16 and MariaDB 10.4.5.

Syntax
------

JSON_MERGE_PRESERVE(json_doc, json_doc[, json_doc] ...)

Description
-----------

Merges the given JSON documents, returning the merged result, or NULL if any
argument is NULL.

JSON_MERGE_PRESERVE was introduced in MariaDB 10.2.25, MariaDB 10.3.16 and
MariaDB 10.4.5 as a synonym for JSON_MERGE, which has been deprecated.

Example
-------

SET @json1 = '[1, 2]';
SET @json2 = '[2, 3]';
SELECT JSON_MERGE_PATCH(@json1,@json2),JSON_MERGE_PRESERVE(@json1,@json2);
+---------------------------------+------------------------------------+
| JSON_MERGE_PATCH(@json1,@json2) | JSON_MERGE_PRESERVE(@json1,@json2) |
+---------------------------------+------------------------------------+
| [2, 3]                          | [1, 2, 2, 3]                       |
+---------------------------------+------------------------------------+

URL: https://mariadb.com/kb/en/json_merge_preserve/https://mariadb.com/kb/en/json_merge_preserve/�U��3j#^ۘ�����)(JSON_NORMALIZEMariaDB starting with 10.7.0
----------------------------
JSON_NORMALIZE was added in MariaDB 10.7.0.

Syntax
------

JSON_NORMALIZE(json)

Description
-----------

Recursively sorts keys and removes spaces, allowing comparison of json
documents for equality.

Examples
--------

We may wish our application to use the database to enforce a unique constraint
on the JSON contents, and we can do so using the JSON_NORMALIZE function in
combination with a unique key.

For example, if we have a table with a JSON column:

CREATE TABLE t1 (
 id BIGINT UNSIGNED NOT NULL AUTO_INCREMENT,
 val JSON,
 /* other columns here */
 PRIMARY KEY (id)
);

Add a unique constraint using JSON_NORMALIZE like this:

ALTER TABLE t1
 ADD COLUMN jnorm JSON AS (JSON_NORMALIZE(val)) VIRTUAL,
 ADD UNIQUE KEY (jnorm);

We can test this by first inserting a row as normal:

INSERT INTO t1 (val) VALUES ('{"name":"alice","color":"blue"}');

And then seeing what happens with a different string which would produce the
same JSON object:

INSERT INTO t1 (val) VALUES ('{ "color": "blue", "name": "alice" }');
ERROR 1062 (23000): Duplicate entry '{"color":"blue","name":"alice"}' for key
'jnorm'

URL: https://mariadb.com/kb/en/json_normalize/https://mariadb.com/kb/en/json_normalize/
�((JSON_OVERLAPSMariaDB starting with 10.9
--------------------------
JSON_OVERLAPS was added in MariaDB 10.9.

Syntax
------

JSON_OVERLAPS(json_doc1, json_doc2)

Description
-----------

JSON_OVERLAPS() compares two json documents and returns true if they have at
least one common key-value pair between two objects, array element common
between two arrays, or array element common with scalar if one of the
arguments is a scalar and other is an array. If two json documents are
scalars, it returns true if they have same type and value.

If none of the above conditions are satisfied then it returns false.

Examples
--------

SELECT JSON_OVERLAPS('false', 'false');
+---------------------------------+
| JSON_OVERLAPS('false', 'false') |
+---------------------------------+
| 1                               |
+---------------------------------+

SELECT JSON_OVERLAPS('true', '["abc", 1, 2, true, false]');
+----------------------------------------------------+
| JSON_OVERLAPS('true','["abc", 1, 2, true, false]') |
+----------------------------------------------------+
| 1                                                  |
+----------------------------------------------------+

SELECT JSON_OVERLAPS('{"A": 1, "B": {"C":2}}', '{"A": 2, "B": {"C":2}}') AS
is_overlap;
+---------------------+
| is_overlap          |
+---------------------+
| 1                   |
+---------------------+

Partial match is considered as no-match.

Examples
--------

SELECT JSON_OVERLAPS('[1, 2, true, false, null]', '[3, 4, [1]]') AS is_overlap;
+--------------------- +
| is_overlap           |
+----------------------+
| 0                    |
+----------------------+

URL: https://mariadb.com/kb/en/json_overlaps/https://mariadb.com/kb/en/json_overlaps/
�%(JSON_QUERYSyntax
------

JSON_QUERY(json_doc, path)

Description
-----------

Given a JSON document, returns an object or array specified by the path.
Returns NULL if not given a valid JSON document, or if there is no match.

Examples
--------

select json_query('{"key1":{"a":1, "b":[1,2]}}', '$.key1');
+-----------------------------------------------------+
| json_query('{"key1":{"a":1, "b":[1,2]}}', '$.key1') |
+-----------------------------------------------------+
| {"a":1, "b":[1,2]}                                  |
+-----------------------------------------------------+

select json_query('{"key1":123, "key1": [1,2,3]}', '$.key1');
+-------------------------------------------------------+
| json_query('{"key1":123, "key1": [1,2,3]}', '$.key1') |
+-------------------------------------------------------+
| [1,2,3]                                               |
+-------------------------------------------------------+

URL: https://mariadb.com/kb/en/json_query/https://mariadb.com/kb/en/json_query/
�%(JSON_QUOTESyntax
------

JSON_QUOTE(json_value)

Description
-----------

Quotes a string as a JSON value, usually for producing valid JSON string
literals for inclusion in JSON documents. Wraps the string with double quote
characters and escapes interior quotes and other special characters, returning
a utf8mb4 string.

Returns NULL if the argument is NULL.

Examples
--------

SELECT JSON_QUOTE('A'), JSON_QUOTE("B"), JSON_QUOTE('"C"');
+-----------------+-----------------+-------------------+
| JSON_QUOTE('A') | JSON_QUOTE("B") | JSON_QUOTE('"C"') |
+-----------------+-----------------+-------------------+
| "A"             | "B"             | "\"C\""           |
+-----------------+-----------------+-------------------+

URL: https://mariadb.com/kb/en/json_quote/https://mariadb.com/kb/en/json_quote/�8��6Z�U
&(JSON_REMOVESyntax
------

JSON_REMOVE(json_doc, path[, path] ...)

Description
-----------

Removes data from a JSON document returning the result, or NULL if any of the
arguments are null. If the element does not exist in the document, no changes
are made.

The function returns NULL and throws a warning if the JSON document is
invalid, the path is invalid, contains a range, or contains a * or ** wildcard.

Path arguments are evaluated from left to right, with the result from the
earlier evaluation being used as the value for the next.

Examples
--------

SELECT JSON_REMOVE('{"A": 1, "B": 2, "C": {"D": 3}}', '$.C');
+-------------------------------------------------------+
| JSON_REMOVE('{"A": 1, "B": 2, "C": {"D": 3}}', '$.C') |
+-------------------------------------------------------+
| {"A": 1, "B": 2}                                      |
+-------------------------------------------------------+

SELECT JSON_REMOVE('["A", "B", ["C", "D"], "E"]', '$[1]');
+----------------------------------------------------+
| JSON_REMOVE('["A", "B", ["C", "D"], "E"]', '$[1]') |
+----------------------------------------------------+
| ["A", ["C", "D"], "E"]                             |
+----------------------------------------------------+

URL: https://mariadb.com/kb/en/json_remove/https://mariadb.com/kb/en/json_remove/�'(JSON_REPLACESyntax
------

JSON_REPLACE(json_doc, path, val[, path, val] ...)

Description
-----------

Replaces existing values in a JSON document, returning the result, or NULL if
any of the arguments are NULL.

An error will occur if the JSON document is invalid, the path is invalid or if
the path contains a * or ** wildcard.

Paths and values are evaluated from left to right, with the result from the
earlier evaluation being used as the value for the next.

JSON_REPLACE can only update data, while JSON_INSERT can only insert. JSON_SET
can update or insert data.

Examples
--------

SELECT JSON_REPLACE('{ "A": 1, "B": [2, 3]}', '$.B[1]', 4);
+-----------------------------------------------------+
| JSON_REPLACE('{ "A": 1, "B": [2, 3]}', '$.B[1]', 4) |
+-----------------------------------------------------+
| { "A": 1, "B": [2, 4]}                              |
+-----------------------------------------------------+

URL: https://mariadb.com/kb/en/json_replace/https://mariadb.com/kb/en/json_replace/�,(JSON_SCHEMA_VALIDMariaDB starting with 11.1
--------------------------
JSON_SCHEMA_VALID was introduced in MariaDB 11.1.

Syntax
------

JSON_SCHEMA_VALID(schema, json);

Description
-----------

JSON_SCHEMA_VALID allows MariaDB to support JSON schema validation. If a given
json is valid against a schema it returns true. When JSON does not validate
against the schema, it does not return a message about which keyword it failed
against and only returns false.

The function supports JSON Schema Draft 2020 with a few exceptions:

* External resources are not supported
* Hyper schema keywords are not supported
* Formats like date, email etc are treated as annotations.

Examples
--------

To create validation rules for json field

CREATE TABLE obj_table(val_obj JSON CHECK(JSON_SCHEMA_VALID('{
 "type":"object",
  "properties": {
   "number1":{
    "type":"number",
    "maximum":5,
    "const":4
   },
   "string1":{
    "type":"string",
    "maxLength":5,
    "minLength":3
   },
  "object1":{
   "type":"object",
   "properties":{
    "key1": {"type":"string"},
    "key2":{"type":"array"},
    "key3":{"type":"number", "minimum":3}
   },
   "dependentRequired": { "key1":["key3"] }
  }
 },
 "required":["number1","object1"]
 }', val_obj)));

INSERT INTO obj_table VALUES(
 '{"number1":4, "string1":"abcd",
 "object1":{"key1":"val1", "key2":[1,2,3, "string1"], "key3":4}}'
);

INSERT INTO obj_table VALUES(
 '{"number1":3, "string1":"abcd",
 "object1":{"key1":"val1", "key2":[1,2,3, "string1"], "key3":4}}'
);
ERROR 4025 (23000): CONSTRAINT `obj_table.val_obj` failed for
`test`.`obj_table`

SELECT * FROM obj_table;
+------------------------------------------------------------------------------
-------------------+
| val_obj                                                                     
          |
+------------------------------------------------------------------------------
-------------------+
| {"number1":4, "string1":"abcd", "object1":{"key1":"val1", "key2":[1,2,3,
"string1"], "key3":4}} |
+------------------------------------------------------------------------------
-------------------+

SET @schema= '{
 "properties" : {
  "number1":{ "maximum":10 },
  "string1" : { "maxLength": 3}
 }
}';

SELECT JSON_SCHEMA_VALID(@schema, '{ "number1":25, "string1":"ab" }');
+----------------------------------------------------------------+
| JSON_SCHEMA_VALID(@schema, '{ "number1":25, "string1":"ab" }') |
+----------------------------------------------------------------+
|                                                              0 |
+----------------------------------------------------------------+

SELECT JSON_SCHEMA_VALID(@schema, '{ "number1":10, "string1":"ab" }');
+----------------------------------------------------------------+
| JSON_SCHEMA_VALID(@schema, '{ "number1":10, "string1":"ab" }') |
+----------------------------------------------------------------+
|                                                              1 |
+----------------------------------------------------------------+

URL: https://mariadb.com/kb/en/json_schema_valid/https://mariadb.com/kb/en/json_schema_valid/S	HMA�$\���&(JSON_SEARCHSyntax
------

JSON_SEARCH(json_doc, return_arg, search_str[, escape_char[, path] ...])

Description
-----------

Returns the path to the given string within a JSON document, or NULL if any of
json_doc, search_str or a path argument is NULL; if the search string is not
found, or if no path exists within the document.

A warning will occur if the JSON document is not valid, any of the path
arguments are not valid, if return_arg is neither one nor all, or if the
escape character is not a constant. NULL will be returned.

return_arg can be one of two values:

* 'one: Terminates after finding the first match, so will return one path
string. If there is more than one match, it is undefined which is considered
first.
* all: Returns all matching path strings, without duplicates. Multiple strings
are autowrapped as an array. The order is undefined.

Examples
--------

SET @json = '["A", [{"B": "1"}], {"C":"AB"}, {"D":"BC"}]';

SELECT JSON_SEARCH(@json, 'one', 'AB');
+---------------------------------+
| JSON_SEARCH(@json, 'one', 'AB') |
+---------------------------------+
| "$[2].C"                        |
+---------------------------------+

URL: https://mariadb.com/kb/en/json_search/https://mariadb.com/kb/en/json_search/	L$(JSON_TYPESyntax
------

JSON_TYPE(json_val)

Description
-----------

Returns the type of a JSON value (as a string), or NULL if the argument is
null.

An error will occur if the argument is an invalid JSON value.

The following is a complete list of the possible return types:

+-----------------------------------+-----------------+-----------------------+
| Return type                       | Value           | Example               |
+-----------------------------------+-----------------+-----------------------+
| ARRAY                             | JSON array      | [1, 2, {"key":        |
|                                   |                 | "value"}]             |
+-----------------------------------+-----------------+-----------------------+
| OBJECT                            | JSON object     | {"key":"value"}       |
+-----------------------------------+-----------------+-----------------------+
| BOOLEAN                           | JSON            | true, false           |
|                                   | true/false      |                       |
|                                   | literals        |                       |
+-----------------------------------+-----------------+-----------------------+
| DOUBLE                            | A number with   | 1.2                   |
|                                   | at least one    |                       |
|                                   | floating point  |                       |
|                                   | decimal.        |                       |
+-----------------------------------+-----------------+-----------------------+
| INTEGER                           | A number        | 1                     |
|                                   | without a       |                       |
|                                   | floating point  |                       |
|                                   | decimal.        |                       |
+-----------------------------------+-----------------+-----------------------+
| NULL                              | JSON null       | null                  |
|                                   | literal (this   |                       |
|                                   | is returned as  |                       |
|                                   | a string, not   |                       |
|                                   | to be confused  |                       |
|                                   | with the SQL    |                       |
|                                   | NULL value!)    |                       |
+-----------------------------------+-----------------+-----------------------+
| STRING                            | JSON String     | "a sample string"     |
+-----------------------------------+-----------------+-----------------------+

Examples
--------

SELECT JSON_TYPE('{"A": 1, "B": 2, "C": 3}');
+---------------------------------------+
| JSON_TYPE('{"A": 1, "B": 2, "C": 3}') |
+---------------------------------------+
| OBJECT                                |
+---------------------------------------+

URL: https://mariadb.com/kb/en/json_type/https://mariadb.com/kb/en/json_type/F'(JSON_UNQUOTESyntax
------

JSON_UNQUOTE(val)

Description
-----------

Unquotes a JSON value, returning a string, or NULL if the argument is null.

An error will occur if the given value begins and ends with double quotes and
is an invalid JSON string literal.

If the given value is not a JSON string, value is passed through unmodified.

Certain character sequences have special meanings within a string. Usually, a
backslash is ignored, but the escape sequences in the table below are
recognised by MariaDB, unless the SQL Mode is set to NO_BACKSLASH_ESCAPES SQL.

+-----------------------------------------------+-----------------------------+
| Escape sequence                               | Character                   |
+-----------------------------------------------+-----------------------------+
| \"                                            | Double quote (")            |
+-----------------------------------------------+-----------------------------+
| \b                                            | Backslash                   |
+-----------------------------------------------+-----------------------------+
| \f                                            | Formfeed                    |
+-----------------------------------------------+-----------------------------+
| \n                                            | Newline (linefeed)          |
+-----------------------------------------------+-----------------------------+
| \r                                            | Carriage return             |
+-----------------------------------------------+-----------------------------+
| \t                                            | Tab                         |
+-----------------------------------------------+-----------------------------+
| \\                                            | Backslash (\)               |
+-----------------------------------------------+-----------------------------+
| \uXXXX                                        | UTF-8 bytes for Unicode     |
|                                               | value XXXX                  |
+-----------------------------------------------+-----------------------------+

Examples
--------

SELECT JSON_UNQUOTE('"Monty"');
+-------------------------+
| JSON_UNQUOTE('"Monty"') |
+-------------------------+
| Monty                   |
+-------------------------+

With the default SQL Mode:

SELECT JSON_UNQUOTE('Si\bng\ting');
+-----------------------------+
| JSON_UNQUOTE('Si\bng\ting') |
+-----------------------------+
| Sng	ing                   |
+-----------------------------+

Setting NO_BACKSLASH_ESCAPES:

SET @@sql_mode = 'NO_BACKSLASH_ESCAPES';

SELECT JSON_UNQUOTE('Si\bng\ting');
+-----------------------------+
| JSON_UNQUOTE('Si\bng\ting') |
+-----------------------------+
| Si\bng\ting                 |
+-----------------------------+

URL: https://mariadb.com/kb/en/json_unquote/https://mariadb.com/kb/en/json_unquote/����H�ZI��

�%(JSON_TABLEMariaDB starting with 10.6.0
----------------------------
JSON_TABLE was added in MariaDB 10.6.0.

JSON_TABLE is a table function that converts JSON data into a relational form.

Syntax
------

JSON_TABLE(json_doc, 
     context_path COLUMNS (column_list)
) [AS] alias

column_list:
  column[, column][, ...]

column:
  name FOR ORDINALITY
  |  name type PATH path_str [on_empty] [on_error]
  |  name type EXISTS PATH path_str
  |  NESTED PATH path_str COLUMNS (column_list)

on_empty:
  {NULL | DEFAULT string | ERROR} ON EMPTY

on_error:
  {NULL | DEFAULT string | ERROR} ON ERROR

Description
-----------

JSON_TABLE can be used in contexts where a table reference can be used; in the
FROM clause of a SELECT statement, and in multi-table UPDATE/DELETE statements.

json_doc is the JSON document to extract data from. In the simplest case, it
is a string literal containing JSON. In more complex cases it can be an
arbitrary expression returning JSON. The expression may have references to
columns of other tables. However, one can only refer to tables that precede
this JSON_TABLE invocation. For RIGHT JOIN, it is assumed that its outer side
precedes the inner. All tables in outer selects are also considered preceding.

context_path is a JSON Path expression pointing to a collection of nodes in
json_doc that will be used as the source of rows.

The COLUMNS clause declares the names and types of the columns that JSON_TABLE
returns, as well as how the values of the columns are produced.

Column Definitions
------------------

The following types of columns are supported:

Path Columns
------------

name type PATH path_str [on_empty] [on_error]

Locates the JSON node pointed to by path_str and returns its value. The
path_str is evaluated using the current row source node as the context node.

set @json='
[
 {"name":"Laptop", "color":"black", "price":"1000"},
 {"name":"Jeans",  "color":"blue"}
]';

select * from json_table(@json, '$[*]' 
 columns(
 name  varchar(10) path '$.name',
 color varchar(10) path '$.color',
 price decimal(8,2) path '$.price' )
) as jt;
+--------+-------+---------+
| name   | color | price   |
+--------+-------+---------+
| Laptop | black | 1000.00 |
| Jeans  | blue  |    NULL |
+--------+-------+---------+

The on_empty and on_error clauses specify the actions to be performed when the
value was not found or there was an error condition. See the ON EMPTY and ON
ERROR clauses section for details.

ORDINALITY Columns
------------------

name FOR ORDINALITY

Counts the rows, starting from 1.

Example:

set @json='
[
 {"name":"Laptop", "color":"black"},
 {"name":"Jeans",  "color":"blue"}
]';

select * from json_table(@json, '$[*]' 
 columns(
 id for ordinality,
 name  varchar(10) path '$.name')
) as jt;
+------+--------+
| id   | name   |
+------+--------+
|    1 | Laptop |
|    2 | Jeans  |
+------+--------+

EXISTS PATH Columns
-------------------

name type EXISTS PATH path_str

Checks whether the node pointed to by value_path exists. The value_path is
evaluated using the current row source node as the context node.

set @json='
[
 {"name":"Laptop", "color":"black", "price":1000},
 {"name":"Jeans",  "color":"blue"}
]';

select * from json_table(@json, '$[*]' 
 columns(
 name  varchar(10) path '$.name',
 has_price integer exists path '$.price')
) as jt;
+--------+-----------+
| name   | has_price |
+--------+-----------+
| Laptop |         1 |
| Jeans  |         0 |
+--------+-----------+

NESTED PATHs
------------

NESTED PATH converts nested JSON structures into multiple rows.

NESTED PATH path COLUMNS (column_list)

It finds the sequence of JSON nodes pointed to by path and uses it to produce
rows. For each found node, a row is generated with column values as specified
by the NESTED PATH's COLUMNS clause. If path finds no nodes, only one row is
generated with all columns having NULL values.

For example, consider a JSON document that contains an array of items, and
each item, in turn, is expected to have an array of its available sizes:

set @json='
[
 {"name":"Jeans",  "sizes": [32, 34, 36]},
 {"name":"T-Shirt", "sizes":["Medium", "Large"]},
 {"name":"Cellphone"}
]';

NESTED PATH allows one to produce a separate row for each size each item has:

select * from json_table(@json, '$[*]' 
 columns(
  name  varchar(10) path '$.name',
  nested path '$.sizes[*]' columns (
   size varchar(32) path '$'
  )
 )
) as jt;
+-----------+--------+
| name      | size   |
+-----------+--------+
| Jeans     | 32     |
| Jeans     | 34     |
| Jeans     | 36     |
| T-Shirt   | Medium |
| T-Shirt   | Large  |
| Cellphone | NULL   |
+-----------+--------+

NESTED PATH clauses can be nested within one another. They can also be located
next to each other. In that case, the nested path clauses will produce records
one at a time. The ones that are not producing records will have all columns
set to NULL.

Example:

set @json='
[
 {"name":"Jeans",  "sizes": [32, 34, 36], "colors":["black", "blue"]}
]';

select * from json_table(@json, '$[*]' 
 columns(
  name  varchar(10) path '$.name',
  nested path '$.sizes[*]' columns (
   size varchar(32) path '$'
  ),
  nested path '$.colors[*]' columns (
   color varchar(32) path '$'
  )
 )
) as jt;

+-------+------+-------+
| name  | size | color |
+-------+------+-------+
| Jeans | 32   | NULL  |
| Jeans | 34   | NULL  |
| Jeans | 36   | NULL  |
| Jeans | NULL | black |
| Jeans | NULL | blue  |
+-------+------+-------+

ON EMPTY and ON ERROR Clauses
-----------------------------

The ON EMPTY clause specifies what will be done when the element specified by
the search path is missing in the JSON document.

on_empty:
  {NULL | DEFAULT string | ERROR} ON EMPTY

When ON EMPTY clause is not present, NULL ON EMPTY is implied.

on_error:
  {NULL | DEFAULT string | ERROR} ON ERROR

The ON ERROR clause specifies what should be done if a JSON structure error
occurs when trying to extract the value pointed to by the path expression. A
JSON structure error here occurs only when one attempts to convert a JSON
non-scalar (array or object) into a scalar value. When the ON ERROR clause is
not present, NULL ON ERROR is implied.

Note: A datatype conversion error (e.g. attempt to store a non-integer value
into an integer field, or a varchar column being truncated) is not considered
a JSON error and so will not trigger the ON ERROR behavior. It will produce
warnings, in the same way as CAST(value AS datatype) would.

Replication
-----------

In the current code, evaluation of JSON_TABLE is deterministic, that is, for a
given input string JSON_TABLE will always produce the same set of rows in the
same order. However, one can think of JSON documents that one can consider
identical which will produce different output. In order to be future-proof and
withstand changes like:

* sorting JSON object members by name (like MySQL does)
* changing the way duplicate object members are handled
the function is marked as unsafe for statement-based replication.

Extracting a Subdocument into a Column
--------------------------------------

MariaDB starting with 10.6.9
----------------------------
Prior to MariaDB 10.6.9, JSON_TABLE did not allow one to extract a JSON
"subdocument" into a JSON column.

SELECT * FROM JSON_TABLE('{"foo": [1,2,3,4]}','$' columns( jscol json path
'$.foo') ) AS T;
+-------+
| jscol |
+-------+
| NULL  |
+-------+

This is supported from MariaDB 10.6.9:

SELECT * FROM JSON_TABLE('{"foo": [1,2,3,4]}','$' columns( jscol json path
'$.foo') ) AS T;
+-----------+
| jscol     |
+-----------+
| [1,2,3,4] |
+-----------+

URL: https://mariadb.com/kb/en/json_table/https://mariadb.com/kb/en/json_table/��K\]��

%(JSON_VALIDSyntax
------

JSON_VALID(value)

Description
-----------

Indicates whether the given value is a valid JSON document or not. Returns 1
if valid, 0 if not, and NULL if the argument is NULL.

From MariaDB 10.4.3, the JSON_VALID function is automatically used as a CHECK
constraint for the JSON data type alias in order to ensure that a valid json
document is inserted.

Examples
--------

SELECT JSON_VALID('{"id": 1, "name": "Monty"}');
+------------------------------------------+
| JSON_VALID('{"id": 1, "name": "Monty"}') |
+------------------------------------------+
|                                        1 |
+------------------------------------------+

SELECT JSON_VALID('{"id": 1, "name": "Monty", "oddfield"}');
+------------------------------------------------------+
| JSON_VALID('{"id": 1, "name": "Monty", "oddfield"}') |
+------------------------------------------------------+
|                                                    0 |
+------------------------------------------------------+

URL: https://mariadb.com/kb/en/json_valid/https://mariadb.com/kb/en/json_valid/
+%(JSON_VALUESyntax
------

JSON_VALUE(json_doc, path)

Description
-----------

Given a JSON document, returns the scalar specified by the path. Returns NULL
if not given a valid JSON document, or if there is no match.

Examples
--------

select json_value('{"key1":123}', '$.key1');
+--------------------------------------+
| json_value('{"key1":123}', '$.key1') |
+--------------------------------------+
| 123                                  |
+--------------------------------------+

select json_value('{"key1": [1,2,3], "key1":123}', '$.key1');
+-------------------------------------------------------+
| json_value('{"key1": [1,2,3], "key1":123}', '$.key1') |
+-------------------------------------------------------+
| 123                                                   |
+-------------------------------------------------------+

In the SET statement below, two escape characters are needed, as a single
escape character would be applied by the SQL parser in the SET statement, and
the escaped character would not form part of the saved value.

SET @json = '{"key1":"60\\" Table", "key2":"1"}';

SELECT JSON_VALUE(@json,'$.key1') AS Name , json_value(@json,'$.key2') as ID;
+-----------+------+
| Name      | ID   |
+-----------+------+
| 60" Table | 1    |
+-----------+------+

URL: https://mariadb.com/kb/en/json_value/https://mariadb.com/kb/en/json_value/
 %)DENSE_RANKSyntax
------

DENSE_RANK() OVER (
 [ PARTITION BY partition_expression ]
 [ ORDER BY order_list ]
)

Description
-----------

DENSE_RANK() is a window function that displays the number of a given row,
starting at one and following the ORDER BY sequence of the window function,
with identical values receiving the same result. Unlike the RANK() function,
there are no skipped values if the preceding results are identical. It is also
similar to the ROW_NUMBER() function except that in that function, identical
values will receive a different row number for each result.

Examples
--------

The distinction between DENSE_RANK(), RANK() and ROW_NUMBER():

CREATE TABLE student(course VARCHAR(10), mark int, name varchar(10));

INSERT INTO student VALUES 
 ('Maths', 60, 'Thulile'),
 ('Maths', 60, 'Pritha'),
 ('Maths', 70, 'Voitto'),
 ('Maths', 55, 'Chun'),
 ('Biology', 60, 'Bilal'),
 ('Biology', 70, 'Roger');

SELECT 
 RANK() OVER (PARTITION BY course ORDER BY mark DESC) AS rank,
 DENSE_RANK() OVER (PARTITION BY course ORDER BY mark DESC) AS dense_rank,
 ROW_NUMBER() OVER (PARTITION BY course ORDER BY mark DESC) AS row_num,
 course, mark, name
FROM student ORDER BY course, mark DESC;
+------+------------+---------+---------+------+---------+
| rank | dense_rank | row_num | course  | mark | name    |
+------+------------+---------+---------+------+---------+
|    1 |          1 |       1 | Biology |   70 | Roger   |
|    2 |          2 |       2 | Biology |   60 | Bilal   |
|    1 |          1 |       1 | Maths   |   70 | Voitto  |
|    2 |          2 |       2 | Maths   |   60 | Thulile |
|    2 |          2 |       3 | Maths   |   60 | Pritha  |
|    4 |          3 |       4 | Maths   |   55 | Chun    |
+------+------------+---------+---------+------+---------+

URL: https://mariadb.com/kb/en/dense_rank/https://mariadb.com/kb/en/dense_rank/�)LAGSyntax
------

LAG (expr[, offset]) OVER ( 
 [ PARTITION BY partition_expression ]
 < ORDER BY order_list >
)

Description
-----------

The LAG function accesses data from a previous row according to the ORDER BY
clause without the need for a self-join. The specific row is determined by the
offset (default 1), which specifies the number of rows behind the current row
to use. An offset of 0 is the current row.

Examples
--------

CREATE TABLE t1 (pk int primary key, a int, b int, c char(10), d decimal(10,
3), e real);

INSERT INTO t1 VALUES
 ( 1, 0, 1,    'one',    0.1,  0.001),
 ( 2, 0, 2,    'two',    0.2,  0.002),
 ( 3, 0, 3,    'three',  0.3,  0.003),
 ( 4, 1, 2,    'three',  0.4,  0.004),
 ( 5, 1, 1,    'two',    0.5,  0.005),
 ( 6, 1, 1,    'one',    0.6,  0.006),
 ( 7, 2, NULL, 'n_one',  0.5,  0.007),
 ( 8, 2, 1,    'n_two',  NULL, 0.008),
 ( 9, 2, 2,    NULL,     0.7,  0.009),
 (10, 2, 0,    'n_four', 0.8,  0.010),
 (11, 2, 10,   NULL,     0.9,  NULL);

SELECT pk, LAG(pk) OVER (ORDER BY pk) AS l,
 LAG(pk,1) OVER (ORDER BY pk) AS l1,
 LAG(pk,2) OVER (ORDER BY pk) AS l2,
 LAG(pk,0) OVER (ORDER BY pk) AS l0,
 LAG(pk,-1) OVER (ORDER BY pk) AS lm1,
 LAG(pk,-2) OVER (ORDER BY pk) AS lm2
FROM t1;
+----+------+------+------+------+------+------+
| pk | l    | l1   | l2   | l0   | lm1  | lm2  |
+----+------+------+------+------+------+------+
|  1 | NULL | NULL | NULL |    1 |    2 |    3 |
|  2 |    1 |    1 | NULL |    2 |    3 |    4 |
|  3 |    2 |    2 |    1 |    3 |    4 |    5 |
|  4 |    3 |    3 |    2 |    4 |    5 |    6 |
|  5 |    4 |    4 |    3 |    5 |    6 |    7 |
|  6 |    5 |    5 |    4 |    6 |    7 |    8 |
|  7 |    6 |    6 |    5 |    7 |    8 |    9 |
|  8 |    7 |    7 |    6 |    8 |    9 |   10 |
|  9 |    8 |    8 |    7 |    9 |   10 |   11 |
| 10 |    9 |    9 |    8 |   10 |   11 | NULL |
| 11 |   10 |   10 |    9 |   11 | NULL | NULL |
+----+------+------+------+------+------+------+

URL: https://mariadb.com/kb/en/lag/https://mariadb.com/kb/en/lag/*��	]ehY
�����
	�$)CUME_DISTSyntax
------

CUME_DIST() OVER ( 
 [ PARTITION BY partition_expression ]
 [ ORDER BY order_list ]
)

Description
-----------

CUME_DIST() is a window function that returns the cumulative distribution of a
given row. The following formula is used to calculate the value:

(number of rows <= current row) / (total rows)

Examples
--------

create table t1 (
 pk int primary key,
 a int,
 b int
);

insert into t1 values
( 1 , 0, 10),
( 2 , 0, 10),
( 3 , 1, 10),
( 4 , 1, 10),
( 8 , 2, 10),
( 5 , 2, 20),
( 6 , 2, 20),
( 7 , 2, 20),
( 9 , 4, 20),
(10 , 4, 20);

select pk, a, b,
  rank() over (order by a) as rank,
  percent_rank() over (order by a) as pct_rank,
  cume_dist() over (order by a) as cume_dist
from t1;
+----+------+------+------+--------------+--------------+
| pk | a    | b    | rank | pct_rank     | cume_dist    |
+----+------+------+------+--------------+--------------+
|  1 |    0 |   10 |    1 | 0.0000000000 | 0.2000000000 |
|  2 |    0 |   10 |    1 | 0.0000000000 | 0.2000000000 |
|  3 |    1 |   10 |    3 | 0.2222222222 | 0.4000000000 |
|  4 |    1 |   10 |    3 | 0.2222222222 | 0.4000000000 |
|  5 |    2 |   20 |    5 | 0.4444444444 | 0.8000000000 |
|  6 |    2 |   20 |    5 | 0.4444444444 | 0.8000000000 |
|  7 |    2 |   20 |    5 | 0.4444444444 | 0.8000000000 |
|  8 |    2 |   10 |    5 | 0.4444444444 | 0.8000000000 |
|  9 |    4 |   20 |    9 | 0.8888888889 | 1.0000000000 |
| 10 |    4 |   20 |    9 | 0.8888888889 | 1.0000000000 |
+----+------+------+------+--------------+--------------+

select pk, a, b,
   percent_rank() over (order by pk) as pct_rank,
   cume_dist() over (order by pk) as cume_dist
from t1 order by pk;
+----+------+------+--------------+--------------+
| pk | a    | b    | pct_rank     | cume_dist    |
+----+------+------+--------------+--------------+
|  1 |    0 |   10 | 0.0000000000 | 0.1000000000 |
|  2 |    0 |   10 | 0.1111111111 | 0.2000000000 |
|  3 |    1 |   10 | 0.2222222222 | 0.3000000000 |
|  4 |    1 |   10 | 0.3333333333 | 0.4000000000 |
|  5 |    2 |   20 | 0.4444444444 | 0.5000000000 |
|  6 |    2 |   20 | 0.5555555556 | 0.6000000000 |
|  7 |    2 |   20 | 0.6666666667 | 0.7000000000 |
|  8 |    2 |   10 | 0.7777777778 | 0.8000000000 |
|  9 |    4 |   20 | 0.8888888889 | 0.9000000000 |
| 10 |    4 |   20 | 1.0000000000 | 1.0000000000 |
+----+------+------+--------------+--------------+

select pk, a, b,
    percent_rank() over (partition by a order by a) as pct_rank,
    cume_dist() over (partition by a order by a) as cume_dist
from t1;
+----+------+------+--------------+--------------+
| pk | a    | b    | pct_rank     | cume_dist    |
+----+------+------+--------------+--------------+
|  1 |    0 |   10 | 0.0000000000 | 1.0000000000 |
|  2 |    0 |   10 | 0.0000000000 | 1.0000000000 |
|  3 |    1 |   10 | 0.0000000000 | 1.0000000000 |
|  4 |    1 |   10 | 0.0000000000 | 1.0000000000 |
|  5 |    2 |   20 | 0.0000000000 | 1.0000000000 |
|  6 |    2 |   20 | 0.0000000000 | 1.0000000000 |
|  7 |    2 |   20 | 0.0000000000 | 1.0000000000 |
|  8 |    2 |   10 | 0.0000000000 | 1.0000000000 |
|  9 |    4 |   20 | 0.0000000000 | 1.0000000000 |
| 10 |    4 |   20 | 0.0000000000 | 1.0000000000 |
+----+------+------+--------------+--------------+

URL: https://mariadb.com/kb/en/cume_dist/https://mariadb.com/kb/en/cume_dist/�)LEADSyntax
------

LEAD (expr[, offset]) OVER ( 
 [ PARTITION BY partition_expression ]
 [ ORDER BY order_list ]
)

Description
-----------

The LEAD function accesses data from a following row in the same result set
without the need for a self-join. The specific row is determined by the offset
(default 1), which specifies the number of rows ahead the current row to use.
An offset of 0 is the current row.

Example
-------

CREATE TABLE t1 (pk int primary key, a int, b int, c char(10), d decimal(10,
3), e real);

INSERT INTO t1 VALUES
 ( 1, 0, 1,    'one',    0.1,  0.001),
 ( 2, 0, 2,    'two',    0.2,  0.002),
 ( 3, 0, 3,    'three',  0.3,  0.003),
 ( 4, 1, 2,    'three',  0.4,  0.004),
 ( 5, 1, 1,    'two',    0.5,  0.005),
 ( 6, 1, 1,    'one',    0.6,  0.006),
 ( 7, 2, NULL, 'n_one',  0.5,  0.007),
 ( 8, 2, 1,    'n_two',  NULL, 0.008),
 ( 9, 2, 2,    NULL,     0.7,  0.009),
 (10, 2, 0,    'n_four', 0.8,  0.010),
 (11, 2, 10,   NULL,     0.9,  NULL);

SELECT pk, LEAD(pk) OVER (ORDER BY pk) AS l,
 LEAD(pk,1) OVER (ORDER BY pk) AS l1,
 LEAD(pk,2) OVER (ORDER BY pk) AS l2,
 LEAD(pk,0) OVER (ORDER BY pk) AS l0,
 LEAD(pk,-1) OVER (ORDER BY pk) AS lm1,
 LEAD(pk,-2) OVER (ORDER BY pk) AS lm2
FROM t1;
+----+------+------+------+------+------+------+
| pk | l    | l1   | l2   | l0   | lm1  | lm2  |
+----+------+------+------+------+------+------+
|  1 |    2 |    2 |    3 |    1 | NULL | NULL |
|  2 |    3 |    3 |    4 |    2 |    1 | NULL |
|  3 |    4 |    4 |    5 |    3 |    2 |    1 |
|  4 |    5 |    5 |    6 |    4 |    3 |    2 |
|  5 |    6 |    6 |    7 |    5 |    4 |    3 |
|  6 |    7 |    7 |    8 |    6 |    5 |    4 |
|  7 |    8 |    8 |    9 |    7 |    6 |    5 |
|  8 |    9 |    9 |   10 |    8 |    7 |    6 |
|  9 |   10 |   10 |   11 |    9 |    8 |    7 |
| 10 |   11 |   11 | NULL |   10 |    9 |    8 |
| 11 | NULL | NULL | NULL |   11 |   10 |    9 |
+----+------+------+------+------+------+------+

URL: https://mariadb.com/kb/en/lead/https://mariadb.com/kb/en/lead/
�
��b���	�&)FIRST_VALUESyntax
------

FIRST_VALUE(expr) OVER (
 [ PARTITION BY partition_expression ]
 [ ORDER BY order_list ]
)

Description
-----------

FIRST_VALUE returns the first result from an ordered set, or NULL if no such
result exists.

Examples
--------

CREATE TABLE t1 (
 pk int primary key,
 a int,
 b int,
 c char(10),
 d decimal(10, 3),
 e real
);

INSERT INTO t1 VALUES
( 1, 0, 1,    'one',    0.1,  0.001),
( 2, 0, 2,    'two',    0.2,  0.002),
( 3, 0, 3,    'three',  0.3,  0.003),
( 4, 1, 2,    'three',  0.4,  0.004),
( 5, 1, 1,    'two',    0.5,  0.005),
( 6, 1, 1,    'one',    0.6,  0.006),
( 7, 2, NULL, 'n_one',  0.5,  0.007),
( 8, 2, 1,    'n_two',  NULL, 0.008),
( 9, 2, 2,    NULL,     0.7,  0.009),
(10, 2, 0,    'n_four', 0.8,  0.010),
(11, 2, 10,   NULL,     0.9,  NULL);

SELECT pk, FIRST_VALUE(pk) OVER (ORDER BY pk) AS first_asc,
     LAST_VALUE(pk) OVER (ORDER BY pk) AS last_asc,
     FIRST_VALUE(pk) OVER (ORDER BY pk DESC) AS first_desc,
     LAST_VALUE(pk) OVER (ORDER BY pk DESC) AS last_desc
FROM t1
ORDER BY pk DESC;

+----+-----------+----------+------------+-----------+
| pk | first_asc | last_asc | first_desc | last_desc |
+----+-----------+----------+------------+-----------+
| 11 |         1 |       11 |         11 |        11 |
| 10 |         1 |       10 |         11 |        10 |
|  9 |         1 |        9 |         11 |         9 |
|  8 |         1 |        8 |         11 |         8 |
|  7 |         1 |        7 |         11 |         7 |
|  6 |         1 |        6 |         11 |         6 |
|  5 |         1 |        5 |         11 |         5 |
|  4 |         1 |        4 |         11 |         4 |
|  3 |         1 |        3 |         11 |         3 |
|  2 |         1 |        2 |         11 |         2 |
|  1 |         1 |        1 |         11 |         1 |
+----+-----------+----------+------------+-----------+

CREATE OR REPLACE TABLE t1 (i int);
INSERT INTO t1 VALUES (1),(2),(3),(4),(5),(6),(7),(8),(9),(10);

SELECT i,
 FIRST_VALUE(i) OVER (ORDER BY i ROWS BETWEEN CURRENT ROW and 1 FOLLOWING) AS
f_1f,
 LAST_VALUE(i) OVER (ORDER BY i ROWS BETWEEN CURRENT ROW and 1 FOLLOWING) AS
l_1f,
 FIRST_VALUE(i) OVER (ORDER BY i ROWS BETWEEN 1 PRECEDING AND 1 FOLLOWING) AS
f_1p1f,
 LAST_VALUE(i) OVER (ORDER BY i ROWS BETWEEN 1 PRECEDING AND 1 FOLLOWING) AS
l_1p1f,
 FIRST_VALUE(i) OVER (ORDER BY i ROWS BETWEEN 2 PRECEDING AND 1 PRECEDING) AS
f_2p1p,
 LAST_VALUE(i) OVER (ORDER BY i ROWS BETWEEN 2 PRECEDING AND 1 PRECEDING) AS
l_2p1p,
 FIRST_VALUE(i) OVER (ORDER BY i ROWS BETWEEN 1 FOLLOWING AND 2 FOLLOWING) AS
f_1f2f,
 LAST_VALUE(i) OVER (ORDER BY i ROWS BETWEEN 1 FOLLOWING AND 2 FOLLOWING) AS
l_1f2f
FROM t1;

+------+------+------+--------+--------+--------+--------+--------+--------+
| i    | f_1f | l_1f | f_1p1f | l_1p1f | f_2p1p | l_2p1p | f_1f2f | l_1f2f |
+------+------+------+--------+--------+--------+--------+--------+--------+
|    1 |    1 |    2 |      1 |      2 |   NULL |   NULL |      2 |      3 |
|    2 |    2 |    3 |      1 |      3 |      1 |      1 |      3 |      4 |
|    3 |    3 |    4 |      2 |      4 |      1 |      2 |      4 |      5 |
|    4 |    4 |    5 |      3 |      5 |      2 |      3 |      5 |      6 |
|    5 |    5 |    6 |      4 |      6 |      3 |      4 |      6 |      7 |
|    6 |    6 |    7 |      5 |      7 |      4 |      5 |      7 |      8 |
|    7 |    7 |    8 |      6 |      8 |      5 |      6 |      8 |      9 |
|    8 |    8 |    9 |      7 |      9 |      6 |      7 |      9 |     10 |
|    9 |    9 |   10 |      8 |     10 |      7 |      8 |     10 |     10 |
|   10 |   10 |   10 |      9 |     10 |      8 |      9 |   NULL |   NULL |
+------+------+------+--------+--------+--------+--------+--------+--------+

URL: https://mariadb.com/kb/en/first_value/https://mariadb.com/kb/en/first_value/!)Median Window FunctionMariaDB starting with 10.3.3
----------------------------
The MEDIAN() window function was first introduced with in MariaDB 10.3.3.

Syntax
------

MEDIAN(median expression) OVER (
 [ PARTITION BY partition_expression ]
)

Description
-----------

MEDIAN() is a window function that returns the median value of a range of
values.

It is a specific case of PERCENTILE_CONT, with an argument of 0.5 and the
ORDER BY column the one in MEDIAN's argument.

MEDIAN(<median-arg>) OVER ( [ PARTITION BY partition_expression] )

Is equivalent to:

PERCENTILE_CONT(0.5) WITHIN 
 GROUP (ORDER BY <median-arg>) OVER ( [ PARTITION BY partition_expression ])

Examples
--------

CREATE TABLE book_rating (name CHAR(30), star_rating TINYINT);

INSERT INTO book_rating VALUES ('Lord of the Ladybirds', 5);
INSERT INTO book_rating VALUES ('Lord of the Ladybirds', 3);
INSERT INTO book_rating VALUES ('Lady of the Flies', 1);
INSERT INTO book_rating VALUES ('Lady of the Flies', 2);
INSERT INTO book_rating VALUES ('Lady of the Flies', 5);

SELECT name, median(star_rating) OVER (PARTITION BY name) FROM book_rating;
+-----------------------+----------------------------------------------+
| name                  | median(star_rating) OVER (PARTITION BY name) |
+-----------------------+----------------------------------------------+
| Lord of the Ladybirds |                                 4.0000000000 |
| Lord of the Ladybirds |                                 4.0000000000 |
| Lady of the Flies     |                                 2.0000000000 |
| Lady of the Flies     |                                 2.0000000000 |
| Lady of the Flies     |                                 2.0000000000 |
+-----------------------+----------------------------------------------+

URL: https://mariadb.com/kb/en/median/https://mariadb.com/kb/en/median/H
og���	� )NTILESyntax
------

NTILE (expr) OVER ( 
 [ PARTITION BY partition_expression ]
 [ ORDER BY order_list ]
)

Description
-----------

NTILE() is a window function that returns an integer indicating which group a
given row falls into. The number of groups is specified in the argument
(expr), starting at one. Ordered rows in the partition are divided into the
specified number of groups with as equal a size as possible.

Examples
--------

create table t1 (
  pk int primary key,
  a int,
  b int
 );

insert into t1 values
  (11 , 0, 10),
  (12 , 0, 10),
  (13 , 1, 10),
  (14 , 1, 10),
  (18 , 2, 10),
  (15 , 2, 20),
  (16 , 2, 20),
  (17 , 2, 20),
  (19 , 4, 20),
  (20 , 4, 20);

select pk, a, b,
  ntile(1) over (order by pk)
 from t1;
+----+------+------+-----------------------------+
| pk | a    | b    | ntile(1) over (order by pk) |
+----+------+------+-----------------------------+
| 11 |    0 |   10 |                           1 |
| 12 |    0 |   10 |                           1 |
| 13 |    1 |   10 |                           1 |
| 14 |    1 |   10 |                           1 |
| 15 |    2 |   20 |                           1 |
| 16 |    2 |   20 |                           1 |
| 17 |    2 |   20 |                           1 |
| 18 |    2 |   10 |                           1 |
| 19 |    4 |   20 |                           1 |
| 20 |    4 |   20 |                           1 |
+----+------+------+-----------------------------+

select pk, a, b,
  ntile(4) over (order by pk)
 from t1;
+----+------+------+-----------------------------+
| pk | a    | b    | ntile(4) over (order by pk) |
+----+------+------+-----------------------------+
| 11 |    0 |   10 |                           1 |
| 12 |    0 |   10 |                           1 |
| 13 |    1 |   10 |                           1 |
| 14 |    1 |   10 |                           2 |
| 15 |    2 |   20 |                           2 |
| 16 |    2 |   20 |                           2 |
| 17 |    2 |   20 |                           3 |
| 18 |    2 |   10 |                           3 |
| 19 |    4 |   20 |                           4 |
| 20 |    4 |   20 |                           4 |
+----+------+------+-----------------------------+

URL: https://mariadb.com/kb/en/ntile/https://mariadb.com/kb/en/ntile/�')PERCENT_RANKSyntax
------

PERCENT_RANK() OVER (
 [ PARTITION BY partition_expression ]
 [ ORDER BY order_list ]
)

Description
-----------

PERCENT_RANK() is a window function that returns the relative percent rank of
a given row. The following formula is used to calculate the percent rank:

(rank - 1) / (number of rows in the window or partition - 1)

Examples
--------

create table t1 (
 pk int primary key,
 a int,
 b int
);

insert into t1 values
( 1 , 0, 10),
( 2 , 0, 10),
( 3 , 1, 10),
( 4 , 1, 10),
( 8 , 2, 10),
( 5 , 2, 20),
( 6 , 2, 20),
( 7 , 2, 20),
( 9 , 4, 20),
(10 , 4, 20);

select pk, a, b,
  rank() over (order by a) as rank,
  percent_rank() over (order by a) as pct_rank,
  cume_dist() over (order by a) as cume_dist
from t1;
+----+------+------+------+--------------+--------------+
| pk | a    | b    | rank | pct_rank     | cume_dist    |
+----+------+------+------+--------------+--------------+
|  1 |    0 |   10 |    1 | 0.0000000000 | 0.2000000000 |
|  2 |    0 |   10 |    1 | 0.0000000000 | 0.2000000000 |
|  3 |    1 |   10 |    3 | 0.2222222222 | 0.4000000000 |
|  4 |    1 |   10 |    3 | 0.2222222222 | 0.4000000000 |
|  5 |    2 |   20 |    5 | 0.4444444444 | 0.8000000000 |
|  6 |    2 |   20 |    5 | 0.4444444444 | 0.8000000000 |
|  7 |    2 |   20 |    5 | 0.4444444444 | 0.8000000000 |
|  8 |    2 |   10 |    5 | 0.4444444444 | 0.8000000000 |
|  9 |    4 |   20 |    9 | 0.8888888889 | 1.0000000000 |
| 10 |    4 |   20 |    9 | 0.8888888889 | 1.0000000000 |
+----+------+------+------+--------------+--------------+

select pk, a, b,
   percent_rank() over (order by pk) as pct_rank,
   cume_dist() over (order by pk) as cume_dist
from t1 order by pk;
+----+------+------+--------------+--------------+
| pk | a    | b    | pct_rank     | cume_dist    |
+----+------+------+--------------+--------------+
|  1 |    0 |   10 | 0.0000000000 | 0.1000000000 |
|  2 |    0 |   10 | 0.1111111111 | 0.2000000000 |
|  3 |    1 |   10 | 0.2222222222 | 0.3000000000 |
|  4 |    1 |   10 | 0.3333333333 | 0.4000000000 |
|  5 |    2 |   20 | 0.4444444444 | 0.5000000000 |
|  6 |    2 |   20 | 0.5555555556 | 0.6000000000 |
|  7 |    2 |   20 | 0.6666666667 | 0.7000000000 |
|  8 |    2 |   10 | 0.7777777778 | 0.8000000000 |
|  9 |    4 |   20 | 0.8888888889 | 0.9000000000 |
| 10 |    4 |   20 | 1.0000000000 | 1.0000000000 |
+----+------+------+--------------+--------------+

select pk, a, b,
    percent_rank() over (partition by a order by a) as pct_rank,
    cume_dist() over (partition by a order by a) as cume_dist
from t1;
+----+------+------+--------------+--------------+
| pk | a    | b    | pct_rank     | cume_dist    |
+----+------+------+--------------+--------------+
|  1 |    0 |   10 | 0.0000000000 | 1.0000000000 |
|  2 |    0 |   10 | 0.0000000000 | 1.0000000000 |
|  3 |    1 |   10 | 0.0000000000 | 1.0000000000 |
|  4 |    1 |   10 | 0.0000000000 | 1.0000000000 |
|  5 |    2 |   20 | 0.0000000000 | 1.0000000000 |
|  6 |    2 |   20 | 0.0000000000 | 1.0000000000 |
|  7 |    2 |   20 | 0.0000000000 | 1.0000000000 |
|  8 |    2 |   10 | 0.0000000000 | 1.0000000000 |
|  9 |    4 |   20 | 0.0000000000 | 1.0000000000 |
| 10 |    4 |   20 | 0.0000000000 | 1.0000000000 |
+----+------+------+--------------+--------------+

URL: https://mariadb.com/kb/en/percent_rank/https://mariadb.com/kb/en/percent_rank/	3
	|y�'�y
*)PERCENTILE_CONTMariaDB starting with 10.3.3
----------------------------
The PERCENTILE_CONT() window function was first introduced with in MariaDB
10.3.3.

Syntax
------

Description
-----------

PERCENTILE_CONT() (standing for continuous percentile) is a window function
which returns a value which corresponds to the given fraction in the sort
order. If required, it will interpolate between adjacent input items.

Essentially, the following process is followed to find the value to return:

* Get the number of rows in the partition, denoted by N
* RN = p*(N-1), where p denotes the argument to the PERCENTILE_CONT function
* calculate the FRN(floor row number) and CRN(column row number for the group(
FRN= floor(RN) and CRN = ceil(RN))
* look up rows FRN and CRN
* If (CRN = FRN = RN) then the result is (value of expression from row at RN)
* Otherwise the result is
* (CRN - RN) * (value of expression for row at FRN) +
* (RN - FRN) * (value of expression for row at CRN)

The MEDIAN function is a specific case of PERCENTILE_CONT, equivalent to
PERCENTILE_CONT(0.5).

Examples
--------

CREATE TABLE book_rating (name CHAR(30), star_rating TINYINT);

INSERT INTO book_rating VALUES ('Lord of the Ladybirds', 5);
INSERT INTO book_rating VALUES ('Lord of the Ladybirds', 3);
INSERT INTO book_rating VALUES ('Lady of the Flies', 1);
INSERT INTO book_rating VALUES ('Lady of the Flies', 2);
INSERT INTO book_rating VALUES ('Lady of the Flies', 5);

SELECT name, PERCENTILE_CONT(0.5) WITHIN GROUP (ORDER BY star_rating) 
 OVER (PARTITION BY name) AS pc
 FROM book_rating;
+-----------------------+--------------+
| name                  | pc           |
+-----------------------+--------------+
| Lord of the Ladybirds | 4.0000000000 |
| Lord of the Ladybirds | 4.0000000000 |
| Lady of the Flies     | 2.0000000000 |
| Lady of the Flies     | 2.0000000000 |
| Lady of the Flies     | 2.0000000000 |
+-----------------------+--------------+

SELECT name, PERCENTILE_CONT(1) WITHIN GROUP (ORDER BY star_rating) 
 OVER (PARTITION BY name) AS pc
 FROM book_rating;
+-----------------------+--------------+
| name                  | pc           |
+-----------------------+--------------+
| Lord of the Ladybirds | 5.0000000000 |
| Lord of the Ladybirds | 5.0000000000 |
| Lady of the Flies     | 5.0000000000 |
| Lady of the Flies     | 5.0000000000 |
| Lady of the Flies     | 5.0000000000 |
+-----------------------+--------------+

SELECT name, PERCENTILE_CONT(0) WITHIN GROUP (ORDER BY star_rating) 
 OVER (PARTITION BY name) AS pc
 FROM book_rating;
+-----------------------+--------------+
| name                  | pc           |
+-----------------------+--------------+
| Lord of the Ladybirds | 3.0000000000 |
| Lord of the Ladybirds | 3.0000000000 |
| Lady of the Flies     | 1.0000000000 |
| Lady of the Flies     | 1.0000000000 |
| Lady of the Flies     | 1.0000000000 |
+-----------------------+--------------+

SELECT name, PERCENTILE_CONT(0.6) WITHIN GROUP (ORDER BY star_rating) 
 OVER (PARTITION BY name) AS pc
 FROM book_rating;
+-----------------------+--------------+
| name                  | pc           |
+-----------------------+--------------+
| Lord of the Ladybirds | 4.2000000000 |
| Lord of the Ladybirds | 4.2000000000 |
| Lady of the Flies     | 2.6000000000 |
| Lady of the Flies     | 2.6000000000 |
| Lady of the Flies     | 2.6000000000 |
+-----------------------+--------------+

URL: https://mariadb.com/kb/en/percentile_cont/https://mariadb.com/kb/en/percentile_cont/�
*)PERCENTILE_DISCMariaDB starting with 10.3.3
----------------------------
The PERCENTILE_DISC() window function was first introduced with in MariaDB
10.3.3.

Syntax
------

Description
-----------

PERCENTILE_DISC() (standing for discrete percentile) is a window function
which returns the first value in the set whose ordered position is the same or
more than the specified fraction.

Essentially, the following process is followed to find the value to return:

* Get the number of rows in the partition.
* Walk through the partition, in order, until finding the the first row with
CUME_DIST() >= function_argument.

Examples
--------

CREATE TABLE book_rating (name CHAR(30), star_rating TINYINT);

INSERT INTO book_rating VALUES ('Lord of the Ladybirds', 5);
INSERT INTO book_rating VALUES ('Lord of the Ladybirds', 3);
INSERT INTO book_rating VALUES ('Lady of the Flies', 1);
INSERT INTO book_rating VALUES ('Lady of the Flies', 2);
INSERT INTO book_rating VALUES ('Lady of the Flies', 5);

SELECT name, PERCENTILE_DISC(0.5) WITHIN GROUP (ORDER BY star_rating)
 OVER (PARTITION BY name) AS pc FROM book_rating;
+-----------------------+------+
| name                  | pc   |
+-----------------------+------+
| Lord of the Ladybirds |    3 |
| Lord of the Ladybirds |    3 |
| Lady of the Flies     |    2 |
| Lady of the Flies     |    2 |
| Lady of the Flies     |    2 |
+-----------------------+------+
5 rows in set (0.000 sec)

SELECT name, PERCENTILE_DISC(0) WITHIN GROUP (ORDER BY star_rating) 
 OVER (PARTITION BY name) AS pc FROM book_rating;
+-----------------------+------+
| name                  | pc   |
+-----------------------+------+
| Lord of the Ladybirds |    3 |
| Lord of the Ladybirds |    3 |
| Lady of the Flies     |    1 |
| Lady of the Flies     |    1 |
| Lady of the Flies     |    1 |
+-----------------------+------+
5 rows in set (0.000 sec)

SELECT name, PERCENTILE_DISC(1) WITHIN GROUP (ORDER BY star_rating) 
 OVER (PARTITION BY name) AS pc FROM book_rating;
+-----------------------+------+
| name                  | pc   |
+-----------------------+------+
| Lord of the Ladybirds |    5 |
| Lord of the Ladybirds |    5 |
| Lady of the Flies     |    5 |
| Lady of the Flies     |    5 |
| Lady of the Flies     |    5 |
+-----------------------+------+
5 rows in set (0.000 sec)

SELECT name, PERCENTILE_DISC(0.6) WITHIN GROUP (ORDER BY star_rating) 
 OVER (PARTITION BY name) AS pc FROM book_rating;
+-----------------------+------+
| name                  | pc   |
+-----------------------+------+
| Lord of the Ladybirds |    5 |
| Lord of the Ladybirds |    5 |
| Lady of the Flies     |    2 |
| Lady of the Flies     |    2 |
| Lady of the Flies     |    2 |
+-----------------------+------

URL: https://mariadb.com/kb/en/percentile_disc/https://mariadb.com/kb/en/percentile_disc/�
�
U�[�B
�)RANKSyntax
------

RANK() OVER (
 [ PARTITION BY partition_expression ]
 [ ORDER BY order_list ]
)

Description
-----------

RANK() is a window function that displays the number of a given row, starting
at one and following the ORDER BY sequence of the window function, with
identical values receiving the same result. It is similar to the ROW_NUMBER()
function except that in that function, identical values will receive a
different row number for each result.

Examples
--------

The distinction between DENSE_RANK(), RANK() and ROW_NUMBER():

CREATE TABLE student(course VARCHAR(10), mark int, name varchar(10));

INSERT INTO student VALUES 
 ('Maths', 60, 'Thulile'),
 ('Maths', 60, 'Pritha'),
 ('Maths', 70, 'Voitto'),
 ('Maths', 55, 'Chun'),
 ('Biology', 60, 'Bilal'),
 ('Biology', 70, 'Roger');

SELECT 
 RANK() OVER (PARTITION BY course ORDER BY mark DESC) AS rank,
 DENSE_RANK() OVER (PARTITION BY course ORDER BY mark DESC) AS dense_rank,
 ROW_NUMBER() OVER (PARTITION BY course ORDER BY mark DESC) AS row_num,
 course, mark, name
FROM student ORDER BY course, mark DESC;
+------+------------+---------+---------+------+---------+
| rank | dense_rank | row_num | course  | mark | name    |
+------+------------+---------+---------+------+---------+
|    1 |          1 |       1 | Biology |   70 | Roger   |
|    2 |          2 |       2 | Biology |   60 | Bilal   |
|    1 |          1 |       1 | Maths   |   70 | Voitto  |
|    2 |          2 |       2 | Maths   |   60 | Thulile |
|    2 |          2 |       3 | Maths   |   60 | Pritha  |
|    4 |          3 |       4 | Maths   |   55 | Chun    |
+------+------------+---------+---------+------+---------+

URL: https://mariadb.com/kb/en/rank/https://mariadb.com/kb/en/rank/
�%)ROW_NUMBERSyntax
------

ROW_NUMBER() OVER (
 [ PARTITION BY partition_expression ]
 [ ORDER BY order_list ]
)

Description
-----------

ROW_NUMBER() is a window function that displays the number of a given row,
starting at one and following the ORDER BY sequence of the window function,
with identical values receiving different row numbers. It is similar to the
RANK() and DENSE_RANK() functions except that in that function, identical
values will receive the same rank for each result.

Examples
--------

The distinction between DENSE_RANK(), RANK() and ROW_NUMBER():

CREATE TABLE student(course VARCHAR(10), mark int, name varchar(10));

INSERT INTO student VALUES 
 ('Maths', 60, 'Thulile'),
 ('Maths', 60, 'Pritha'),
 ('Maths', 70, 'Voitto'),
 ('Maths', 55, 'Chun'),
 ('Biology', 60, 'Bilal'),
 ('Biology', 70, 'Roger');

SELECT 
 RANK() OVER (PARTITION BY course ORDER BY mark DESC) AS rank,
 DENSE_RANK() OVER (PARTITION BY course ORDER BY mark DESC) AS dense_rank,
 ROW_NUMBER() OVER (PARTITION BY course ORDER BY mark DESC) AS row_num,
 course, mark, name
FROM student ORDER BY course, mark DESC;
+------+------------+---------+---------+------+---------+
| rank | dense_rank | row_num | course  | mark | name    |
+------+------------+---------+---------+------+---------+
|    1 |          1 |       1 | Biology |   70 | Roger   |
|    2 |          2 |       2 | Biology |   60 | Bilal   |
|    1 |          1 |       1 | Maths   |   70 | Voitto  |
|    2 |          2 |       2 | Maths   |   60 | Thulile |
|    2 |          2 |       3 | Maths   |   60 | Pritha  |
|    4 |          3 |       4 | Maths   |   55 | Chun    |
+------+------------+---------+---------+------+---------+

URL: https://mariadb.com/kb/en/row_number/https://mariadb.com/kb/en/row_number/ /*SPIDER_BG_DIRECT_SQLSyntax
------

SPIDER_BG_DIRECT_SQL('sql', 'tmp_table_list', 'parameters')

Description
-----------

Executes the given SQL statement in the background on the remote server, as
defined in the parameters listing. If the query returns a result-set, it
sttores the results in the given temporary table. When the given SQL statement
executes successfully, this function returns the number of called UDF's. It
returns 0 when the given SQL statement fails.

This function is a UDF installed with the Spider storage engine.

Examples
--------

SELECT SPIDER_BG_DIRECT_SQL('SELECT * FROM example_table',  '', 
 'srv "node1", port "8607"') AS "Direct Query";
+--------------+
| Direct Query | 
+--------------+
|            1 |
+--------------+

Parameters
----------

error_rw_mode
-------------

* Description: Returns empty results on network error.
0 : Return error on getting network error.
1: Return 0 records on getting network error.

* Default Table Value: 0
* DSN Parameter Name: erwm

URL: https://mariadb.com/kb/en/spider_bg_direct_sql/https://mariadb.com/kb/en/spider_bg_direct_sql/!-*SPIDER_COPY_TABLESSyntax
------

SPIDER_COPY_TABLES(spider_table_name, 
 source_link_id, destination_link_id_list [,parameters])

Description
-----------

A UDF installed with the Spider Storage Engine, this function copies table
data from source_link_id to destination_link_id_list. The service does not
need to be stopped in order to copy.

If the Spider table is partitioned, the name must be of the format
table_name#P#partition_name. The partition name can be viewed in the
mysql.spider_tables table, for example:

SELECT table_name FROM mysql.spider_tables;
+-------------+
| table_name  |
+-------------+
| spt_a#P#pt1 |
| spt_a#P#pt2 |
| spt_a#P#pt3 |
+-------------+

Returns 1 if the data was copied successfully, or 0 if copying the data failed.

URL: https://mariadb.com/kb/en/spider_copy_tables/https://mariadb.com/kb/en/spider_copy_tables/Gc�
`������
�()Window FramesSyntax
------

frame_clause:
 {ROWS | RANGE} {frame_border | BETWEEN frame_border AND frame_border}

frame_border:
 | UNBOUNDED PRECEDING
 | UNBOUNDED FOLLOWING
 | CURRENT ROW
 | expr PRECEDING
 | expr FOLLOWING

Description
-----------

A basic overview of window functions is described in Window Functions
Overview. Window frames expand this functionality by allowing the function to
include a specified a number of rows around the current row.

These include:

* All rows before the current row (UNBOUNDED PRECEDING), for example RANGE
BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW
* All rows after the current row (UNBOUNDED FOLLOWING), for example RANGE
BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING
* A set number of rows before the current row (expr PRECEDING) for example
RANGE BETWEEN 6 PRECEDING AND CURRENT ROW
* A set number of rows after the current row (expr PRECEDING AND expr
FOLLOWING)  for example RANGE BETWEEN CURRENT ROW AND 2 FOLLOWING
* A specified number of rows both before and after the current row, for
example RANGE BETWEEN 6 PRECEDING AND 3 FOLLOWING

The following functions operate on window frames:

* AVG
* BIT_AND
* BIT_OR
* BIT_XOR
* COUNT
* LEAD
* MAX
* MIN
* NTILE
* STD
* STDDEV
* STDDEV_POP
* STDDEV_SAMP
* SUM
* VAR_POP
* VAR_SAMP
* VARIANCE

Window frames are determined by the frame_clause in the window function
request.

Take the following example:

CREATE TABLE `student_test` (
 name char(10),
 test char(10),
 score tinyint(4)
);

INSERT INTO student_test VALUES 
  ('Chun', 'SQL', 75), ('Chun', 'Tuning', 73),
  ('Esben', 'SQL', 43), ('Esben', 'Tuning', 31),
  ('Kaolin', 'SQL', 56), ('Kaolin', 'Tuning', 88),
  ('Tatiana', 'SQL', 87);

SELECT name, test, score, SUM(score) 
 OVER () AS total_score
 FROM student_test;
+---------+--------+-------+-------------+
| name    | test   | score | total_score |
+---------+--------+-------+-------------+
| Chun    | SQL    |    75 |         453 |
| Chun    | Tuning |    73 |         453 |
| Esben   | SQL    |    43 |         453 |
| Esben   | Tuning |    31 |         453 |
| Kaolin  | SQL    |    56 |         453 |
| Kaolin  | Tuning |    88 |         453 |
| Tatiana | SQL    |    87 |         453 |
+---------+--------+-------+-------------+

By not specifying an OVER clause, the SUM function is run over the entire
dataset. However, if we specify an ORDER BY condition based on score (and
order the entire result in the same way for clarity), the following result is
returned:

SELECT name, test, score, SUM(score) 
 OVER (ORDER BY score) AS total_score
 FROM student_test ORDER BY score;
+---------+--------+-------+-------------+
| name    | test   | score | total_score |
+---------+--------+-------+-------------+
| Esben   | Tuning |    31 |          31 |
| Esben   | SQL    |    43 |          74 |
| Kaolin  | SQL    |    56 |         130 |
| Chun    | Tuning |    73 |         203 |
| Chun    | SQL    |    75 |         278 |
| Tatiana | SQL    |    87 |         365 |
| Kaolin  | Tuning |    88 |         453 |
+---------+--------+-------+-------------+

The total_score column represents a running total of the current row, and all
previous rows. The window frame in this example expands as the function
proceeds.

The above query makes use of the default to define the window frame. It could
be written explicitly as follows:

SELECT name, test, score, SUM(score) 
 OVER (ORDER BY score RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) AS
total_score 
 FROM student_test ORDER BY score;
+---------+--------+-------+-------------+
| name    | test   | score | total_score |
+---------+--------+-------+-------------+
| Esben   | Tuning |    31 |          31 |
| Esben   | SQL    |    43 |          74 |
| Kaolin  | SQL    |    56 |         130 |
| Chun    | Tuning |    73 |         203 |
| Chun    | SQL    |    75 |         278 |
| Tatiana | SQL    |    87 |         365 |
| Kaolin  | Tuning |    88 |         453 |
+---------+--------+-------+-------------+

Let's look at some alternatives:

Firstly, applying the window function to the current row and all following
rows can be done with the use of UNBOUNDED FOLLOWING:

SELECT name, test, score, SUM(score) 
 OVER (ORDER BY score RANGE BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING) AS
total_score 
 FROM student_test ORDER BY score;
+---------+--------+-------+-------------+
| name    | test   | score | total_score |
+---------+--------+-------+-------------+
| Esben   | Tuning |    31 |         453 |
| Esben   | SQL    |    43 |         422 |
| Kaolin  | SQL    |    56 |         379 |
| Chun    | Tuning |    73 |         323 |
| Chun    | SQL    |    75 |         250 |
| Tatiana | SQL    |    87 |         175 |
| Kaolin  | Tuning |    88 |          88 |
+---------+--------+-------+-------------+

It's possible to specify a number of rows, rather than the entire unbounded
following or preceding set. The following example takes the current row, as
well as the previous row:

SELECT name, test, score, SUM(score) 
 OVER (ORDER BY score ROWS BETWEEN 1 PRECEDING AND CURRENT ROW) AS
total_score 
 FROM student_test ORDER BY score;
+---------+--------+-------+-------------+
| name    | test   | score | total_score |
+---------+--------+-------+-------------+
| Esben   | Tuning |    31 |          31 |
| Esben   | SQL    |    43 |          74 |
| Kaolin  | SQL    |    56 |          99 |
| Chun    | Tuning |    73 |         129 |
| Chun    | SQL    |    75 |         148 |
| Tatiana | SQL    |    87 |         162 |
| Kaolin  | Tuning |    88 |         175 |
+---------+--------+-------+-------------+

The current row and the following row:

SELECT name, test, score, SUM(score) 
 OVER (ORDER BY score ROWS BETWEEN 1 PRECEDING AND 1 FOLLOWING) AS
total_score 
 FROM student_test ORDER BY score;
+---------+--------+-------+-------------+
| name    | test   | score | total_score |
+---------+--------+-------+-------------+
| Esben   | Tuning |    31 |          74 |
| Esben   | SQL    |    43 |         130 |
| Kaolin  | SQL    |    56 |         172 |
| Chun    | Tuning |    73 |         204 |
| Chun    | SQL    |    75 |         235 |
| Tatiana | SQL    |    87 |         250 |
| Kaolin  | Tuning |    88 |         175 |
+---------+--------+-------+-------------+

URL: https://mariadb.com/kb/en/window-frames/https://mariadb.com/kb/en/window-frames/�2�4��e	"�,*SPIDER_DIRECT_SQLSyntax
------

SPIDER_DIRECT_SQL('sql', 'tmp_table_list', 'parameters')

Description
-----------

A UDF installed with the Spider Storage Engine, this function is used to
execute the SQL string sql on the remote server, as defined in parameters. If
any resultsets are returned, they are stored in the tmp_table_list.

The function returns 1 if the SQL executes successfully, or 0 if it fails.

Examples
--------

SELECT SPIDER_DIRECT_SQL('SELECT * FROM s', '', 'srv "node1", port "8607"');
+----------------------------------------------------------------------+
| SPIDER_DIRECT_SQL('SELECT * FROM s', '', 'srv "node1", port "8607"') |
+----------------------------------------------------------------------+
|                                                                    1 |
+----------------------------------------------------------------------+

URL: https://mariadb.com/kb/en/spider_direct_sql/https://mariadb.com/kb/en/spider_direct_sql/$
X%+COLUMN_ADDSyntax
------

COLUMN_ADD(dyncol_blob, column_nr, value [as type], [column_nr, value [as
type]]...);
COLUMN_ADD(dyncol_blob, column_name, value [as type], [column_name, value [as
type]]...);

Description
-----------

Adds or updates dynamic columns.

* dyncol_blob must be either a valid dynamic columns blob (for example,
COLUMN_CREATE returns such blob), or an empty string.
* column_name specifies the name of the column to be added. If dyncol_blob
already has a column with this name, it will be overwritten.
* value specifies the new value for the column.  Passing a NULL value will
cause the column to be deleted.
* as type is optional. See #datatypes section for a discussion about types.

The return value is a dynamic column blob after the modifications.

Examples
--------

UPDATE t1 SET dyncol_blob=COLUMN_ADD(dyncol_blob, "column_name", "value")
WHERE id=1;

Note: COLUMN_ADD() is a regular function (just like CONCAT()), hence, in order
to update the value in the table you have to use the UPDATE ... SET
dynamic_col=COLUMN_ADD(dynamic_col, ....) pattern.

URL: https://mariadb.com/kb/en/column_add/https://mariadb.com/kb/en/column_add/&
�(+COLUMN_CREATESyntax
------

COLUMN_CREATE(column_nr, value [as type], [column_nr, value [as type]]...);
COLUMN_CREATE(column_name, value [as type], [column_name, value [as type]]...);

Description
-----------

Returns a dynamic columns blob that stores the specified columns with values.

The return value is suitable for

* storing in a table
* further modification with other dynamic columns functions

The as type part allows one to specify the value type. In most cases, this is
redundant because MariaDB will be able to deduce the type of the value.
Explicit type specification may be needed when the type of the value is not
apparent. For example, a literal '2012-12-01' has a CHAR type by default, one
will need to specify '2012-12-01' AS DATE to have it stored as a date. See
Dynamic Columns:Datatypes for further details.

Examples
--------

INSERT INTO tbl SET dyncol_blob=COLUMN_CREATE("column_name", "value");

URL: https://mariadb.com/kb/en/column_create/https://mariadb.com/kb/en/column_create/)
	%+COLUMN_GETSyntax
------

COLUMN_GET(dyncol_blob, column_nr as type);
COLUMN_GET(dyncol_blob, column_name as type);

Description
-----------

Gets the value of a dynamic column by its name. If no column with the given
name exists, NULL will be returned.

column_name as type requires that one specify the datatype of the dynamic
column they are reading.

This may seem counter-intuitive: why would one need to specify which datatype
they're retrieving? Can't the dynamic columns system figure the datatype from
the data being stored?

The answer is: SQL is a statically-typed language. The SQL interpreter needs
to know the datatypes of all expressions before the query is run (for example,
when one is using prepared statements and runs "select COLUMN_GET(...)", the
prepared statement API requires the server to inform the client about the
datatype of the column being read before the query is executed and the server
can see what datatype the column actually has).

Lengths
-------

If you're running queries like:

SELECT COLUMN_GET(blob, 'colname' as CHAR) ...

without specifying a maximum length (i.e. using as CHAR, not as CHAR(n)),
MariaDB will report the maximum length of the resultset column to be
16,777,216. This may cause excessive memory usage in some client libraries,
because they try to pre-allocate a buffer of maximum resultset width. To avoid
this problem, use CHAR(n) whenever you're using COLUMN_GET in the select list.

See Dynamic Columns:Datatypes for more information about datatypes.

URL: https://mariadb.com/kb/en/column_get/https://mariadb.com/kb/en/column_get/*�&+COLUMN_JSONSyntax
------

COLUMN_JSON(dyncol_blob)

Description
-----------

Returns a JSON representation of data in dyncol_blob. Can also be used to
display nested columns. See dynamic columns for more information.

Example
-------

select item_name, COLUMN_JSON(dynamic_cols) from assets;
+-----------------+----------------------------------------+
| item_name       | COLUMN_JSON(dynamic_cols)              |
+-----------------+----------------------------------------+
| MariaDB T-shirt | {"size":"XL","color":"blue"}           |
| Thinkpad Laptop | {"color":"black","warranty":"3 years"} |
+-----------------+----------------------------------------+

Limitation: COLUMN_JSON will decode nested dynamic columns at a nesting level
of not more than 10 levels deep. Dynamic columns that are nested deeper than
10 levels will be shown as BINARY string, without encoding.

URL: https://mariadb.com/kb/en/column_json/https://mariadb.com/kb/en/column_json/��sFu����k�H��;	.w4,WSREP_SYNC_WAIT_UPTO_GTIDMariaDB starting with 10.4.2
----------------------------
WSREP_SYNC_WAIT_UPTO_GTID was added as part of Galera 4 in MariaDB 10.4.2.

Syntax
------

WSREP_SYNC_WAIT_UPTO_GTID(gtid[,timeout])

Description
-----------

Blocks the client until the transaction specified by the given Global
Transaction ID is applied and committed by the node.

The optional timeout argument can be used to specify a block timeout in
seconds. If not provided, the timeout will be indefinite.

Returns the node that applied and committed the Global Transaction ID,
ER_LOCAL_WAIT_TIMEOUT if the function is timed out before this, or
ER_WRONG_ARGUMENTS if the function is given an invalid GTID.

The result from WSREP_LAST_SEEN_GTID can be useful to determine the
transaction to provide to WSREP_SYNC_WAIT_UPTO_GTID for waiting and unblocking
purposes.

URL: https://mariadb.com/kb/en/wsrep_sync_wait_upto_gtid/https://mariadb.com/kb/en/wsrep_sync_wait_upto_gtid/1�,-Bitemporal TablesMariaDB starting with 10.4.3
----------------------------
Bitemporal tables are tables that use versioning both at the system and
application-time period levels.

Using Bitemporal Tables
-----------------------

To create a bitemporal table, use:

CREATE TABLE test.t3 (
 date_1 DATE,
 date_2 DATE,
 row_start TIMESTAMP(6) AS ROW START INVISIBLE,
 row_end TIMESTAMP(6) AS ROW END INVISIBLE,
 PERIOD FOR application_time(date_1, date_2),
 PERIOD FOR system_time(row_start, row_end))
WITH SYSTEM VERSIONING;

Note that, while system_time here is also a time period, it cannot be used in
DELETE FOR PORTION or UPDATE FOR PORTION statements.

DELETE FROM test.t3 
FOR PORTION OF system_time 
  FROM '2000-01-01' TO '2018-01-01';
ERROR 42000: You have an error in your SQL syntax; check the manual that
corresponds 
 to your MariaDB server version for the right syntax to use near
 'of system_time from '2000-01-01' to '2018-01-01'' at line 1

URL: https://mariadb.com/kb/en/bitemporal-tables/https://mariadb.com/kb/en/bitemporal-tables/3�-.ST_GeomFromGeoJSONMariaDB starting with 10.2.4
----------------------------
ST_GeomFromGeoJSON was added in MariaDB 10.2.4

Syntax
------

ST_GeomFromGeoJSON(g[, option])

Description
-----------

Given a GeoJSON input g, returns a geometry object. The option specifies what
to do if g contains geometries with coordinate dimensions higher than 2.

+---------------------------+------------------------------------------------+
| Option                    | Description                                    |
+---------------------------+------------------------------------------------+
| 1                         | Return an error (the default)                  |
+---------------------------+------------------------------------------------+
| 2 - 4                     | The document is accepted, but the coordinates  |
|                           | for higher coordinate dimensions are stripped  |
|                           | off.                                           |
+---------------------------+------------------------------------------------+

Note that this function did not work correctly before MariaDB 10.2.8 - see
MDEV-12180.

Examples
--------

SET @j = '{ "type": "Point", "coordinates": [5.3, 15.0]}';

SELECT ST_AsText(ST_GeomFromGeoJSON(@j));
+-----------------------------------+
| ST_AsText(ST_GeomFromGeoJSON(@j)) |
+-----------------------------------+
| POINT(5.3 15)                     |
+-----------------------------------+

URL: https://mariadb.com/kb/en/st_geomfromgeojson/https://mariadb.com/kb/en/st_geomfromgeojson/4;./Operator PrecedenceThe precedence is the order in which the SQL operators are evaluated.

The following list shows the SQL operator precedence. Operators that appear
first in the list have a higher precedence. Operators which are listed
together have the same precedence.

* INTERVAL
* BINARY, COLLATE
* !
* - (unary minus), [[bitwise-not|]] (unary bit inversion)
* || (string concatenation)
* ^
* *, /, DIV, %, MOD
* -, +
* <<, >>
* &
* |
* = (comparison), <=>, >=, >, <=, <, <>, !=, IS, LIKE, REGEXP, IN
* BETWEEN, CASE, WHEN, THEN, ELSE, END
* NOT
* &&, AND
* XOR
* || (logical or), OR
* = (assignment), :=

Functions precedence is always higher than operators precedence.

In this page CASE refers to the CASE operator, not to the CASE statement.

If the HIGH_NOT_PRECEDENCE SQL_MODE is set, NOT has the same precedence as !.

The || operator's precedence, as well as its meaning, depends on the
PIPES_AS_CONCAT SQL_MODE flag: if it is on, || can be used to concatenate
strings (like the CONCAT() function) and has a higher precedence.

The = operator's precedence depends on the context - it is higher when = is
used as a comparison operator.

Parenthesis can be used to modify the operators precedence in an expression.

Short-circuit evaluation
------------------------

The AND, OR, && and || operators support short-circuit evaluation. This means
that, in some cases, the expression on the right of those operators is not
evaluated, because its result cannot affect the result. In the following
cases, short-circuit evaluation is used and x() is not evaluated:

* FALSE AND x()
* FALSE && x()
* TRUE OR x()
* TRUE || x()
* NULL BETWEEN x() AND x()

Note however that the short-circuit evaluation does not apply to NULL AND x().
Also, BETWEEN's right operands are not evaluated if the left operand is NULL,
but in all other cases all the operands are evaluated.

This is a speed optimization. Also, since functions can have side-effects,
this behavior can be used to choose whether execute them or not using a
concise syntax:

SELECT some_function() OR log_error();

URL: https://mariadb.com/kb/en/operator-precedence/https://mariadb.com/kb/en/operator-precedence/'�"�'���lB�
6,0Division Operator (/)Syntax
------

/

Description
-----------

Division operator. Dividing by zero will return NULL. By default, returns four
digits after the decimal. This is determined by the server system variable
div_precision_increment which by default is four. It can be set from 0 to 30.

Dividing by zero returns NULL. If the ERROR_ON_DIVISION_BY_ZERO SQL_MODE is
used (the default since MariaDB 10.2.4), a division by zero also produces a
warning.

Examples
--------

SELECT 4/5;
+--------+
| 4/5    |
+--------+
| 0.8000 |
+--------+

SELECT 300/(2-2);
+-----------+
| 300/(2-2) |
+-----------+
|      NULL |
+-----------+

SELECT 300/7;
+---------+
| 300/7   |
+---------+
| 42.8571 |
+---------+

Changing div_precision_increment for the session from the default of four to
six:

SET div_precision_increment = 6;

SELECT 300/7;
+-----------+
| 300/7     |
+-----------+
| 42.857143 |
+-----------+

SELECT 300/7;
+-----------+
| 300/7     |
+-----------+
| 42.857143 |
+-----------+

URL: https://mariadb.com/kb/en/division-operator/https://mariadb.com/kb/en/division-operator/8[20Multiplication Operator (*)Syntax
------

*

Description
-----------

Multiplication operator.

Examples
--------

SELECT 7*6;
+-----+
| 7*6 |
+-----+
|  42 |
+-----+

SELECT 1234567890*9876543210;
+-----------------------+
| 1234567890*9876543210 |
+-----------------------+
|  -6253480962446024716 |
+-----------------------+

SELECT 18014398509481984*18014398509481984.0;
+---------------------------------------+
| 18014398509481984*18014398509481984.0 |
+---------------------------------------+
|   324518553658426726783156020576256.0 |
+---------------------------------------+

SELECT 18014398509481984*18014398509481984;
+-------------------------------------+
| 18014398509481984*18014398509481984 |
+-------------------------------------+
|                                   0 |
+-------------------------------------+

URL: https://mariadb.com/kb/en/multiplication-operator/https://mariadb.com/kb/en/multiplication-operator/9c00Subtraction Operator (-)Syntax
------

-

Description
-----------

Subtraction. The operator is also used as the unary minus for changing sign.

If both operands are integers, the result is calculated with BIGINT precision.
If either integer is unsigned, the result is also an unsigned integer, unless
the NO_UNSIGNED_SUBTRACTION SQL_MODE is enabled, in which case the result is
always signed.

For real or string operands, the operand with the highest precision determines
the result precision.

Examples
--------

SELECT 96-9;
+------+
| 96-9 |
+------+
|   87 |
+------+

SELECT 15-17;
+-------+
| 15-17 |
+-------+
|    -2 |
+-------+

SELECT 3.66 + 1.333;
+--------------+
| 3.66 + 1.333 |
+--------------+
|        4.993 |
+--------------+

Unary minus:

SELECT - (3+5);
+---------+
| - (3+5) |
+---------+
|      -8 |
+---------+

URL: https://mariadb.com/kb/en/subtraction-operator-/https://mariadb.com/kb/en/subtraction-operator-/<
�	'1STOP SLAVEThe terms master and slave have historically been used in replication, but the
terms terms primary and replica are now preferred. The old terms are used
still used in parts of the documentation, and in MariaDB commands, although
MariaDB 10.5 has begun the process of renaming. The documentation process is
ongoing. See MDEV-18777 to follow progress on this effort.

Syntax
------

STOP SLAVE ["connection_name"] [thread_type [, thread_type] ... ] [FOR CHANNEL
"connection_name"]

STOP ALL SLAVES [thread_type [, thread_type]]

STOP REPLICA ["connection_name"] [thread_type [, thread_type] ... ] -- from
10.5.1

STOP ALL REPLICAS [thread_type [, thread_type]] -- from 10.5.1

thread_type: IO_THREAD | SQL_THREAD

Description
-----------

Stops the replica threads. STOP SLAVE requires the SUPER privilege, or, from
MariaDB 10.5.2, the REPLICATION SLAVE ADMIN privilege.

Like START SLAVE, this statement may be used with the IO_THREAD and SQL_THREAD
options to name the thread or threads to be stopped. In almost all cases, one
never need to use the thread_type options.

STOP SLAVE waits until any current replication event group affecting one or
more non-transactional tables has finished executing (if there is any such
replication group), or until the user issues a KILL QUERY or KILL CONNECTION
statement.

Note that STOP SLAVE doesn't delete the connection permanently. Next time you
execute START SLAVE or the MariaDB server restarts, the replica connection is
restored with it's original arguments. If you want to delete a connection, you
should execute RESET SLAVE.

STOP ALL SLAVES
---------------

STOP ALL SLAVES stops all your running replicas. It will give you a note for
every stopped connection. You can check the notes with SHOW WARNINGS.

connection_name
---------------

The connection_name option is used for multi-source replication.

If there is only one nameless master, or the default master (as specified by
the default_master_connection system variable) is intended, connection_name
can be omitted. If provided, the STOP SLAVE statement will apply to the
specified master. connection_name is case-insensitive.

MariaDB starting with 10.7.0
----------------------------
The FOR CHANNEL keyword was added for MySQL compatibility. This is identical
as using the channel_name directly after STOP SLAVE.

STOP REPLICA
------------

MariaDB starting with 10.5.1
----------------------------
STOP REPLICA is an alias for STOP SLAVE from MariaDB 10.5.1.

URL: https://mariadb.com/kb/en/stop-replica/https://mariadb.com/kb/en/stop-replica/�
�\�P�9�^��;�(1START SLAVEThe terms master and slave have historically been used in replication, but the
terms terms primary and replica are now preferred. The old terms are used
still used in parts of the documentation, and in MariaDB commands, although
MariaDB 10.5 has begun the process of renaming. The documentation process is
ongoing. See MDEV-18777 to follow progress on this effort.

Syntax
------

START SLAVE ["connection_name"] [thread_type [, thread_type] ... ] [FOR
CHANNEL "connection_name"]
START SLAVE ["connection_name"] [SQL_THREAD] UNTIL                
  MASTER_LOG_FILE = 'log_name', MASTER_LOG_POS = log_pos [FOR CHANNEL
"connection_name"]
START SLAVE ["connection_name"] [SQL_THREAD] UNTIL
  RELAY_LOG_FILE = 'log_name', RELAY_LOG_POS = log_pos [FOR CHANNEL
"connection_name"]
START SLAVE ["connection_name"] [SQL_THREAD] UNTIL
  MASTER_GTID_POS = <GTID position> [FOR CHANNEL "connection_name"]
START ALL SLAVES [thread_type [, thread_type]]

START REPLICA ["connection_name"] [thread_type [, thread_type] ... ] -- from
10.5.1
START REPLICA ["connection_name"] [SQL_THREAD] UNTIL                
  MASTER_LOG_FILE = 'log_name', MASTER_LOG_POS = log_pos -- from 10.5.1
START REPLICA ["connection_name"] [SQL_THREAD] UNTIL
  RELAY_LOG_FILE = 'log_name', RELAY_LOG_POS = log_pos -- from 10.5.1
START REPLICA ["connection_name"] [SQL_THREAD] UNTIL
  MASTER_GTID_POS = <GTID position> -- from 10.5.1
START ALL REPLICAS [thread_type [, thread_type]] -- from 10.5.1

thread_type: IO_THREAD | SQL_THREAD

Description
-----------

START SLAVE (START REPLICA from MariaDB 10.5.1) with no thread_type options
starts both of the replica threads (see replication). The I/O thread reads
events from the primary server and stores them in the relay log. The SQL
thread reads events from the relay log and executes them. START SLAVE requires
the SUPER privilege, or, from MariaDB 10.5.2, the REPLICATION SLAVE ADMIN
privilege.

If START SLAVE succeeds in starting the replica threads, it returns without
any error. However, even in that case, it might be that the replica threads
start and then later stop (for example, because they do not manage to connect
to the primary or read its binary log, or some other problem). START SLAVE
does not warn you about this. You must check the replica's error log for error
messages generated by the replica threads, or check that they are running
satisfactorily with SHOW SLAVE STATUS (SHOW REPLICA STATUS from MariaDB
10.5.1).

START SLAVE UNTIL
-----------------

START SLAVE UNTIL refers to the SQL_THREAD replica position at which the
SQL_THREAD replication will halt. If SQL_THREAD isn't specified both threads
are started.

START SLAVE UNTIL master_gtid_pos=xxx is also supported. See Global
Transaction ID/START SLAVE UNTIL master_gtid_pos=xxx for more details.

connection_name
---------------

If there is only one nameless primary, or the default primary (as specified by
the default_master_connection system variable) is intended, connection_name
can be omitted. If provided, the START SLAVE statement will apply to the
specified primary. connection_name is case-insensitive.

MariaDB starting with 10.7.0
----------------------------
The FOR CHANNEL keyword was added for MySQL compatibility. This is identical
as using the channel_name directly after START SLAVE.

START ALL SLAVES
----------------

START ALL SLAVES starts all configured replicas (replicas with master_host not
empty) that were not started before. It will give a note for all started
connections. You can check the notes with SHOW WARNINGS.

START REPLICA
-------------

MariaDB starting with 10.5.1
----------------------------
START REPLICA is an alias for START SLAVE from MariaDB 10.5.1.

URL: https://mariadb.com/kb/en/start-replica/https://mariadb.com/kb/en/start-replica/=�(1RESET REPLICA/SLAVEThe terms master and slave have historically been used in replication, but the
terms terms primary and replica are now preferred. The old terms are used
still used in parts of the documentation, and in MariaDB commands, although
MariaDB 10.5 has begun the process of renaming. The documentation process is
ongoing. See MDEV-18777 to follow progress on this effort.

Syntax
------

RESET REPLICA ["connection_name"] [ALL]  [FOR CHANNEL "connection_name"] --
from MariaDB 10.5.1         
RESET SLAVE ["connection_name"] [ALL]  [FOR CHANNEL "connection_name"]

Description
-----------

RESET REPLICA/SLAVE makes the replica forget its replication position in the
master's binary log. This statement is meant to be used for a clean start. It
deletes the master.info and relay-log.info files, all the relay log files, and
starts a new relay log file. To use RESET REPLICA/SLAVE, the replica threads
must be stopped (use STOP REPLICA/SLAVE if necessary).

Note: All relay log files are deleted, even if they have not been completely
executed by the slave SQL thread. (This is a condition likely to exist on a
replication slave if you have issued a STOP REPLICA/SLAVE statement or if the
slave is highly loaded.)

Note: RESET REPLICA does not reset the global gtid_slave_pos variable. This
means that a replica server configured with CHANGE MASTER TO
MASTER_USE_GTID=slave_pos will not receive events with GTIDs occurring before
the state saved in gtid_slave_pos. If the intent is to reprocess these events,
gtid_slave_pos must be manually reset, e.g. by executing set global
gtid_slave_pos="".

Connection information stored in the master.info file is immediately reset
using any values specified in the corresponding startup options. This
information includes values such as master host, master port, master user, and
master password. If the replica SQL thread was in the middle of replicating
temporary tables when it was stopped, and RESET REPLICA/SLAVE is issued, these
replicated temporary tables are deleted on the slave.

The ALL also resets the PORT, HOST, USER and PASSWORD parameters for the
slave. If you are using a connection name, it will permanently delete it and
it will not show up anymore in SHOW ALL REPLICAS/SLAVE STATUS.

connection_name
---------------

The connection_name option is used for multi-source replication.

If there is only one nameless primary, or the default primary (as specified by
the default_master_connection system variable) is intended, connection_name
can be omitted. If provided, the RESET REPLICA/SLAVE statement will apply to
the specified primary. connection_name is case-insensitive.

MariaDB starting with 10.7.0
----------------------------
The FOR CHANNEL keyword was added for MySQL compatibility. This is identical
as using the channel_name directly after RESET REPLICA.

RESET REPLICA
-------------

MariaDB starting with 10.5.1
----------------------------
RESET REPLICA is an alias for RESET SLAVE from MariaDB 10.5.1.

URL: https://mariadb.com/kb/en/reset-replica/https://mariadb.com/kb/en/reset-replica/��@f�'��?�,2EXECUTE StatementSyntax
------

EXECUTE stmt_name
  [USING expression[, expression] ...]

MariaDB starting with 10.2.3
----------------------------
EXECUTE with expression as parameters was introduced in MariaDB 10.2.3. Before
that one could only use variables (@var_name) as parameters.

Description
-----------

After preparing a statement with PREPARE, you execute it with an EXECUTE
statement that refers to the prepared statement name. If the prepared
statement contains any parameter markers, you must supply a USING clause that
lists user variables containing the values to be bound to the parameters.
Parameter values can be supplied only by user variables, and the USING clause
must name exactly as many variables as the number of parameter markers in the
statement.

You can execute a given prepared statement multiple times, passing different
variables to it or setting the variables to different values before each
execution.

If the specified statement has not been PREPAREd, an error similar to the
following is produced:

ERROR 1243 (HY000): Unknown prepared statement handler (stmt_name) given to
EXECUTE

Example
-------

See example in PREPARE.

URL: https://mariadb.com/kb/en/execute-statement/https://mariadb.com/kb/en/execute-statement/AW22DEALLOCATE / DROP PREPARESyntax
------

{DEALLOCATE | DROP} PREPARE stmt_name

Description
-----------

To deallocate a prepared statement produced with PREPARE, use a DEALLOCATE
PREPARE statement that refers to the prepared statement name.

A prepared statement is implicitly deallocated when a new PREPARE command is
issued. In that case, there is no need to use DEALLOCATE.

Attempting to execute a prepared statement after deallocating it results in an
error, as if it was not prepared at all:

ERROR 1243 (HY000): Unknown prepared statement handler (stmt_name) given to
EXECUTE

If the specified statement has not been PREPAREd, an error similar to the
following will be produced:

ERROR 1243 (HY000): Unknown prepared statement handler (stmt_name) given to
DEALLOCATE PREPARE

Example
-------

See example in PREPARE.

URL: https://mariadb.com/kb/en/deallocate-drop-prepare/https://mariadb.com/kb/en/deallocate-drop-prepare/B$,2EXECUTE IMMEDIATEMariaDB starting with 10.2.3
----------------------------
EXECUTE IMMEDIATE was introduced in MariaDB 10.2.3.

Syntax
------

EXECUTE IMMEDIATE statement

Description
-----------

EXECUTE IMMEDIATE executes a dynamic SQL statement created on the fly, which
can reduce performance overhead.

For example:

EXECUTE IMMEDIATE 'SELECT 1'

which is shorthand for:

prepare stmt from "select 1";
execute stmt;
deallocate prepare stmt;

EXECUTE IMMEDIATE supports complex expressions as prepare source and
parameters:

EXECUTE IMMEDIATE CONCAT('SELECT COUNT(*) FROM ', 't1', ' WHERE a=?') USING
5+5;

Limitations: subselects and stored function calls are not supported as a
prepare source.

The following examples return an error:

CREATE OR REPLACE FUNCTION f1() RETURNS VARCHAR(64) RETURN 'SELECT * FROM t1';
EXECUTE IMMEDIATE f1();
ERROR 1970 (42000): EXECUTE IMMEDIATE does not support subqueries or stored
functions

EXECUTE IMMEDIATE (SELECT 'SELECT * FROM t1');
ERROR 1064 (42000): You have an error in your SQL syntax; check the manual
that 
 corresponds to your MariaDB server version for the right syntax to use near
 'SELECT 'SELECT * FROM t1')' at line 1

CREATE OR REPLACE FUNCTION f1() RETURNS INT RETURN 10;
EXECUTE IMMEDIATE 'SELECT * FROM t1 WHERE a=?' USING f1();
ERROR 1970 (42000): EXECUTE..USING does not support subqueries or stored
functions

EXECUTE IMMEDIATE 'SELECT * FROM t1 WHERE a=?' USING (SELECT 10);
ERROR 1064 (42000): You have an error in your SQL syntax; check the manual
that 
 corresponds to your MariaDB server version for the right syntax to use near
 'SELECT 10)' at line 1

One can use a user or an SP variable as a workaround:

CREATE OR REPLACE FUNCTION f1() RETURNS VARCHAR(64) RETURN 'SELECT * FROM t1';
SET @stmt=f1();
EXECUTE IMMEDIATE @stmt;

SET @stmt=(SELECT 'SELECT 1');
EXECUTE IMMEDIATE @stmt;

CREATE OR REPLACE FUNCTION f1() RETURNS INT RETURN 10;
SET @param=f1();
EXECUTE IMMEDIATE 'SELECT * FROM t1 WHERE a=?' USING @param;

SET @param=(SELECT 10);
EXECUTE IMMEDIATE 'SELECT * FROM t1 WHERE a=?' USING @param;

EXECUTE IMMEDIATE supports user variables and SP variables as OUT parameters

DELIMITER $$
CREATE OR REPLACE PROCEDURE p1(OUT a INT)
BEGIN
 SET a:= 10;
END;
$$
DELIMITER ;
SET @a=2;
EXECUTE IMMEDIATE 'CALL p1(?)' USING @a;
SELECT @a;
+------+
| @a   |
+------+
|   10 |
+------+

Similar to PREPARE, EXECUTE IMMEDIATE is allowed in stored procedures but is
not allowed in stored functions.

This example uses EXECUTE IMMEDIATE inside a stored procedure:

DELIMITER $$
CREATE OR REPLACE PROCEDURE p1()
BEGIN
 EXECUTE IMMEDIATE 'SELECT 1';
END;
$$
DELIMITER ;
CALL p1;
+---+
| 1 |
+---+
| 1 |
+---+

This script returns an error:

DELIMITER $$
CREATE FUNCTION f1() RETURNS INT
BEGIN
 EXECUTE IMMEDIATE 'DO 1';
 RETURN 1;
END;
$$
ERROR 1336 (0A000): Dynamic SQL is not allowed in stored function or trigger

EXECUTE IMMEDIATE can use DEFAULT and IGNORE indicators as bind parameters:

CREATE OR REPLACE TABLE t1 (a INT DEFAULT 10);
EXECUTE IMMEDIATE 'INSERT INTO t1 VALUES (?)' USING DEFAULT;
SELECT * FROM t1;
+------+
| a    |
+------+
|   10 |
+------+

EXECUTE IMMEDIATE increments the Com_execute_immediate status variable, as
well as the Com_stmt_prepare, Com_stmt_execute and Com_stmt_close status
variables.

Note, EXECUTE IMMEDIATE does not increment the Com_execute_sql status
variable. Com_execute_sql is used only for PREPARE..EXECUTE.

This session screenshot demonstrates how EXECUTE IMMEDIATE affects status
variables:

SELECT * FROM INFORMATION_SCHEMA.SESSION_STATUS WHERE VARIABLE_NAME RLIKE 
 ('COM_(EXECUTE|STMT_PREPARE|STMT_EXECUTE|STMT_CLOSE)');

+-----------------------+----------------+
| VARIABLE_NAME         | VARIABLE_VALUE |
+-----------------------+----------------+
| COM_EXECUTE_IMMEDIATE | 0              |
| COM_EXECUTE_SQL       | 0              |
| COM_STMT_CLOSE        | 0              |
| COM_STMT_EXECUTE      | 0              |
| COM_STMT_PREPARE      | 0              |
+-----------------------+----------------+

EXECUTE IMMEDIATE 'SELECT 1';
+---+
| 1 |
+---+
| 1 |
+---+

SELECT * FROM INFORMATION_SCHEMA.SESSION_STATUS WHERE VARIABLE_NAME RLIKE 
 ('COM_(EXECUTE|STMT_PREPARE|STMT_EXECUTE|STMT_CLOSE)');
+-----------------------+----------------+
| VARIABLE_NAME         | VARIABLE_VALUE |
+-----------------------+----------------+
| COM_EXECUTE_IMMEDIATE | 1              |
| COM_EXECUTE_SQL       | 0              |
| COM_STMT_CLOSE        | 1              |
| COM_STMT_EXECUTE      | 1              |
| COM_STMT_PREPARE      | 1              |
+-----------------------+----------------+

URL: https://mariadb.com/kb/en/execute-immediate/https://mariadb.com/kb/en/execute-immediate/�o������@�,2PREPARE StatementSyntax
------

PREPARE stmt_name FROM preparable_stmt

Description
-----------

The PREPARE statement prepares a statement and assigns it a name, stmt_name,
by which to refer to the statement later. Statement names are not case
sensitive. preparable_stmt is either a string literal or a user variable (not
a local variable, an SQL expression or a subquery) that contains the text of
the statement. The text must represent a single SQL statement, not multiple
statements. Within the statement, "?" characters can be used as parameter
markers to indicate where data values are to be bound to the query later when
you execute it. The "?" characters should not be enclosed within quotes, even
if you intend to bind them to string values. Parameter markers can be used
only where expressions should appear, not for SQL keywords, identifiers, and
so forth.

The scope of a prepared statement is the session within which it is created.
Other sessions cannot see it.

If a prepared statement with the given name already exists, it is deallocated
implicitly before the new statement is prepared. This means that if the new
statement contains an error and cannot be prepared, an error is returned and
no statement with the given name exists.

Prepared statements can be PREPAREd and EXECUTEd in a stored procedure, but
not in a stored function or trigger. Also, even if the statement is PREPAREd
in a procedure, it will not be deallocated when the procedure execution ends.

A prepared statement can access user-defined variables, but not local
variables or procedure's parameters.

If the prepared statement contains a syntax error, PREPARE will fail. As a
side effect, stored procedures can use it to check if a statement is valid.
For example:

CREATE PROCEDURE `test_stmt`(IN sql_text TEXT)
BEGIN
    DECLARE EXIT HANDLER FOR SQLEXCEPTION
    BEGIN
        SELECT CONCAT(sql_text, ' is not valid');
    END;
    SET @SQL := sql_text;
    PREPARE stmt FROM @SQL;
    DEALLOCATE PREPARE stmt;
END;

The FOUND_ROWS() and ROW_COUNT() functions, if called immediatly after
EXECUTE, return the number of rows read or affected by the prepared
statements; however, if they are called after DEALLOCATE PREPARE, they provide
information about this statement. If the prepared statement produces errors or
warnings, GET DIAGNOSTICS return information about them. DEALLOCATE PREPARE
shouldn't clear the diagnostics area, unless it produces an error.

A prepared statement is executed with EXECUTE and released with DEALLOCATE
PREPARE.

The max_prepared_stmt_count server system variable determines the number of
allowed prepared statements that can be prepared on the server. If it is set
to 0, prepared statements are not allowed. If the limit is reached, an error
similar to the following will be produced:

ERROR 1461 (42000): Can't create more than max_prepared_stmt_count statements 
 (current value: 0)

Oracle Mode
-----------

MariaDB starting with 10.3
--------------------------
In Oracle mode from MariaDB 10.3, PREPARE stmt FROM 'SELECT :1, :2' is used,
instead of ?.

Permitted Statements
--------------------

MariaDB starting with 10.6.2
----------------------------
All statements can be prepared, except PREPARE, EXECUTE, and DEALLOCATE / DROP
PREPARE.

Prior to this, not all statements can be prepared. Only the following SQL
commands are permitted:

* ALTER TABLE
* ANALYZE TABLE
* BINLOG
* CACHE INDEX
* CALL
* CHANGE MASTER
* CHECKSUM {TABLE | TABLES}
* COMMIT
* {CREATE | DROP} DATABASE
* {CREATE | DROP} INDEX
* {CREATE | RENAME | DROP} TABLE
* {CREATE | RENAME | DROP} USER
* {CREATE | DROP} VIEW
* DELETE
* DESCRIBE
* DO
* EXPLAIN
* FLUSH {TABLE | TABLES | TABLES WITH READ LOCK | HOSTS | PRIVILEGES | LOGS |
STATUS | 
 MASTER | SLAVE | DES_KEY_FILE | USER_RESOURCES | QUERY CACHE |
TABLE_STATISTICS | 
 INDEX_STATISTICS | USER_STATISTICS | CLIENT_STATISTICS}
* GRANT
* INSERT
* INSTALL {PLUGIN | SONAME}
* HANDLER READ
* KILL
* LOAD INDEX INTO CACHE
* OPTIMIZE TABLE
* REPAIR TABLE
* REPLACE
* RESET {MASTER | SLAVE | QUERY CACHE}
* REVOKE
* ROLLBACK
* SELECT
* SET
* SET GLOBAL SQL_SLAVE_SKIP_COUNTER
* SET ROLE
* SET SQL_LOG_BIN
* SET TRANSACTION ISOLATION LEVEL
* SHOW EXPLAIN
* SHOW {DATABASES | TABLES | OPEN TABLES | TABLE STATUS | COLUMNS | INDEX |
TRIGGERS | 
 EVENTS | GRANTS | CHARACTER SET | COLLATION | ENGINES | PLUGINS [SONAME] |
PRIVILEGES | 
 PROCESSLIST | PROFILE | PROFILES | VARIABLES | STATUS | WARNINGS | ERRORS |
 TABLE_STATISTICS | INDEX_STATISTICS | USER_STATISTICS | CLIENT_STATISTICS |
AUTHORS | 
 CONTRIBUTORS}
* SHOW CREATE {DATABASE | TABLE | VIEW | PROCEDURE | FUNCTION | TRIGGER |
EVENT}
* SHOW {FUNCTION | PROCEDURE} CODE
* SHOW BINLOG EVENTS
* SHOW SLAVE HOSTS
* SHOW {MASTER | BINARY} LOGS
* SHOW {MASTER | SLAVE | TABLES | INNODB | FUNCTION | PROCEDURE} STATUS
* SLAVE {START | STOP}
* TRUNCATE TABLE
* SHUTDOWN
* UNINSTALL {PLUGIN | SONAME}
* UPDATE

Synonyms are not listed here, but can be used. For example, DESC can be used
instead of DESCRIBE.

Compound statements can be prepared too.

Note that if a statement can be run in a stored routine, it will work even if
it is called by a prepared statement. For example, SIGNAL can't be directly
prepared. However, it is allowed in stored routines. If the x() procedure
contains SIGNAL, you can still prepare and execute the 'CALL x();' prepared
statement.

PREPARE supports most kinds of expressions as well, for example:

PREPARE stmt FROM CONCAT('SELECT * FROM ', table_name);

When PREPARE is used with a statement which is not supported, the following
error is produced:

ERROR 1295 (HY000): This command is not supported in the prepared statement
protocol yet

Example
-------

create table t1 (a int,b char(10));
insert into t1 values (1,"one"),(2, "two"),(3,"three");
prepare test from "select * from t1 where a=?";
set @param=2;
execute test using @param;
+------+------+
| a    | b    |
+------+------+
|    2 | two  |
+------+------+
set @param=3;
execute test using @param;
+------+-------+
| a    | b     |
+------+-------+
|    3 | three |
+------+-------+
deallocate prepare test;

Since identifiers are not permitted as prepared statements parameters,
sometimes it is necessary to dynamically compose an SQL statement. This
technique is called dynamic SQL). The following example shows how to use
dynamic SQL:

CREATE PROCEDURE test.stmt_test(IN tab_name VARCHAR(64))
BEGIN
	SET @sql = CONCAT('SELECT COUNT(*) FROM ', tab_name);
	PREPARE stmt FROM @sql;
	EXECUTE stmt;
	DEALLOCATE PREPARE stmt;
END;

CALL test.stmt_test('mysql.user');
+----------+
| COUNT(*) |
+----------+
|        4 |
+----------+

Use of variables in prepared statements:

PREPARE stmt FROM 'SELECT @x;';

SET @x = 1;

EXECUTE stmt;
+------+
| @x   |
+------+
|    1 |
+------+

SET @x = 0;

EXECUTE stmt;
+------+
| @x   |
+------+
|    0 |
+------+

DEALLOCATE PREPARE stmt;

URL: https://mariadb.com/kb/en/prepare-statement/https://mariadb.com/kb/en/prepare-statement/G��