INSERT INTO help_topic (help_topic_id, help_category_id, name, description, example, url) VALUES (842, 34, 'ST\\_ASWKT', 'Description\n-----------\n\nA synonym for ST_ASTEXT().\n\nURL: https://mariadb.com/docs/server/reference/sql-statements/geometry-constructors/wkt/st_aswkt', '', 'https://mariadb.com/docs/server/reference/sql-statements/geometry-constructors/wkt/st_aswkt');
INSERT INTO help_topic (help_topic_id, help_category_id, name, description, example, url) VALUES (843, 34, 'ST\\_GeomCollFromText', 'Syntax\n------\n\nST_GeomCollFromText(wkt[,srid])\nST_GeometryCollectionFromText(wkt[,srid])\nGeomCollFromText(wkt[,srid])\nGeometryCollectionFromText(wkt[,srid])\n\nDescription\n-----------\n\nConstructs a GEOMETRYCOLLECTION value using its WKT representation and SRID.\n\nST_GeomCollFromText(), ST_GeometryCollectionFromText(), GeomCollFromText() and GeometryCollectionFromText() are all synonyms.\n\nExamples\n--------\n\nCREATE TABLE gis_geometrycollection  (g GEOMETRYCOLLECTION);\nSHOW FIELDS FROM gis_geometrycollection;\nINSERT INTO gis_geometrycollection VALUES\n    (GeomCollFromText(''GEOMETRYCOLLECTION(POINT(0 0), LINESTRING(0 0,10 10))'')),\n    (GeometryFromWKB(AsWKB(GeometryCollection(Point(44, 6), LineString(Point(3, 6), Point(7, 9)))))),\n    (GeomFromText(''GeometryCollection()'')),\n    (GeomFromText(''GeometryCollection EMPTY''));\n\nURL: https://mariadb.com/docs/server/reference/sql-statements/geometry-constructors/wkt/st_geomcollfromtext', '', 'https://mariadb.com/docs/server/reference/sql-statements/geometry-constructors/wkt/st_geomcollfromtext');
INSERT INTO help_topic (help_topic_id, help_category_id, name, description, example, url) VALUES (844, 34, 'ST\\_GeometryCollectionFromText', 'Description\n-----------\n\nA synonym for ST_GeomCollFromText.\n\nURL: https://mariadb.com/docs/server/reference/sql-statements/geometry-constructors/wkt/st_geometrycollectionfromtext', '', 'https://mariadb.com/docs/server/reference/sql-statements/geometry-constructors/wkt/st_geometrycollectionfromtext');
INSERT INTO help_topic (help_topic_id, help_category_id, name, description, example, url) VALUES (845, 34, 'ST\\_GeometryFromText', 'Description\n-----------\n\nA synonym for ST_GeomFromText.\n\nURL: https://mariadb.com/docs/server/reference/sql-statements/geometry-constructors/wkt/st_geometryfromtext', '', 'https://mariadb.com/docs/server/reference/sql-statements/geometry-constructors/wkt/st_geometryfromtext');
INSERT INTO help_topic (help_topic_id, help_category_id, name, description, example, url) VALUES (846, 34, 'ST\\_GeomFromText', 'Syntax\n------\n\nST_GeomFromText(wkt[,srid])\nST_GeometryFromText(wkt[,srid])\nGeomFromText(wkt[,srid])\nGeometryFromText(wkt[,srid])\n\nST_MultiLineStringFromText(wkt[,srid])\nST_MLineFromText(wkt[,srid])\nST_MPointFromText(wkt[,srid])\nST_MultiPointFromText(wkt[,srid])\n\nDescription\n-----------\n\nConstructs a geometry value of any type using its WKT representation and SRID.\n\nGeomFromText(), GeometryFromText(), ST_GeomFromText(), ST_GeometryFromText(), ST_MultiLineStringFromText, ST_MLineFromText, ST_MultiPolyFromText and ST_MPolygonFromText are all synonyms.\n\nExamples\n--------\n\nSET @g = ST_GEOMFROMTEXT(''POLYGON((1 1,1 5,4 9,6 9,9 3,7 2,1 1))'');\n\nURL: https://mariadb.com/docs/server/reference/sql-statements/geometry-constructors/wkt/st_geomfromtext', '', 'https://mariadb.com/docs/server/reference/sql-statements/geometry-constructors/wkt/st_geomfromtext');
INSERT INTO help_topic (help_topic_id, help_category_id, name, description, example, url) VALUES (847, 34, 'ST\\_LineFromText', 'Syntax\n------\n\nST_LineFromText(wkt[,srid])\nST_LineStringFromText(wkt[,srid])\nLineFromText(wkt[,srid])\nLineStringFromText(wkt[,srid])\n\nDescription\n-----------\n\nConstructs a LINESTRING value using its WKT representation and SRID.\n\nST_LineFromText(), ST_LineStringFromText(), ST_LineFromText() and ST_LineStringFromText() are all synonyms.\n\nExamples\n--------\n\nCREATE TABLE gis_line  (g LINESTRING);\nSHOW FIELDS FROM gis_line;\nINSERT INTO gis_line VALUES\n    (LineFromText(''LINESTRING(0 0,0 10,10 0)'')),\n    (LineStringFromText(''LINESTRING(10 10,20 10,20 20,10 20,10 10)'')),\n    (LineStringFromWKB(AsWKB(LineString(Point(10, 10), Point(40, 10)))));\n\nURL: https://mariadb.com/docs/server/reference/sql-statements/geometry-constructors/wkt/st_linefromtext', '', 'https://mariadb.com/docs/server/reference/sql-statements/geometry-constructors/wkt/st_linefromtext');
INSERT INTO help_topic (help_topic_id, help_category_id, name, description, example, url) VALUES (848, 34, 'ST\\_LineStringFromText', 'Description\n-----------\n\nA synonym for ST_LineFromText.\n\nURL: https://mariadb.com/docs/server/reference/sql-statements/geometry-constructors/wkt/st_linestringfromtext', '', 'https://mariadb.com/docs/server/reference/sql-statements/geometry-constructors/wkt/st_linestringfromtext');
INSERT INTO help_topic (help_topic_id, help_category_id, name, description, example, url) VALUES (849, 34, 'ST\\_MPointFromText', 'Description\n-----------\n\nA synonym for ST_GeomFromText.\n\nURL: https://mariadb.com/docs/server/reference/sql-statements/geometry-constructors/wkt/st_mpointfromtext', '', 'https://mariadb.com/docs/server/reference/sql-statements/geometry-constructors/wkt/st_mpointfromtext');
INSERT INTO help_topic (help_topic_id, help_category_id, name, description, example, url) VALUES (850, 34, 'ST\\_MPolyFromText', 'Description\n-----------\n\nA synonym for ST_GeomFromText.\n\nURL: https://mariadb.com/docs/server/reference/sql-statements/geometry-constructors/wkt/st_mpolyfromtext', '', 'https://mariadb.com/docs/server/reference/sql-statements/geometry-constructors/wkt/st_mpolyfromtext');
INSERT INTO help_topic (help_topic_id, help_category_id, name, description, example, url) VALUES (851, 34, 'ST\\_MultiLineStringFromText', 'Description\n-----------\n\nA synonym for ST_GeomFromText.\n\nURL: https://mariadb.com/docs/server/reference/sql-statements/geometry-constructors/wkt/st_multilinestringfromtext', '', 'https://mariadb.com/docs/server/reference/sql-statements/geometry-constructors/wkt/st_multilinestringfromtext');
INSERT INTO help_topic (help_topic_id, help_category_id, name, description, example, url) VALUES (852, 34, 'ST\\_MultiPointFromText', 'Description\n-----------\n\nA synonym for ST_GeomFromText.\n\nURL: https://mariadb.com/docs/server/reference/sql-statements/geometry-constructors/wkt/st_multipointfromtext', '', 'https://mariadb.com/docs/server/reference/sql-statements/geometry-constructors/wkt/st_multipointfromtext');
INSERT INTO help_topic (help_topic_id, help_category_id, name, description, example, url) VALUES (853, 34, 'ST\\_MultiPolygonFromText', 'Description\n-----------\n\nA synonym for ST_GeomFromText.\n\nURL: https://mariadb.com/docs/server/reference/sql-statements/geometry-constructors/wkt/st_multipolygonfromtext', '', 'https://mariadb.com/docs/server/reference/sql-statements/geometry-constructors/wkt/st_multipolygonfromtext');
INSERT INTO help_topic (help_topic_id, help_category_id, name, description, example, url) VALUES (854, 34, 'ST\\_PointFromText', 'Syntax\n------\n\nST_PointFromText(wkt[,srid])\nPointFromText(wkt[,srid])\n\nDescription\n-----------\n\nConstructs a POINT value using its WKT representation and SRID.\n\nST_PointFromText() and PointFromText() are synonyms.\n\nExamples\n--------\n\nCREATE TABLE gis_point  (g POINT);\nSHOW FIELDS FROM gis_point;\nINSERT INTO gis_point VALUES\n    (PointFromText(''POINT(10 10)'')),\n    (PointFromText(''POINT(20 10)'')),\n    (PointFromText(''POINT(20 20)'')),\n    (PointFromWKB(AsWKB(PointFromText(''POINT(10 20)''))));\n\nURL: https://mariadb.com/docs/server/reference/sql-statements/geometry-constructors/wkt/st_pointfromtext', '', 'https://mariadb.com/docs/server/reference/sql-statements/geometry-constructors/wkt/st_pointfromtext');
INSERT INTO help_topic (help_topic_id, help_category_id, name, description, example, url) VALUES (855, 34, 'ST\\_PolyFromText', 'Syntax\n------\n\nST_PolyFromText(wkt[,srid])\nST_PolygonFromText(wkt[,srid])\nPolyFromText(wkt[,srid])\nPolygonFromText(wkt[,srid])\n\nDescription\n-----------\n\nConstructs a POLYGON value using its WKT representation and SRID.\n\nST_PolyFromText(), ST_PolygonFromText(), PolyFromText() and ST_PolygonFromText() are all synonyms.\n\nExamples\n--------\n\nCREATE TABLE gis_polygon   (g POLYGON);\nINSERT INTO gis_polygon VALUES\n    (PolygonFromText(''POLYGON((10 10,20 10,20 20,10 20,10 10))'')),\n    (PolyFromText(''POLYGON((0 0,50 0,50 50,0 50,0 0), (10 10,20 10,20 20,10 20,10 10))''));\n\nURL: https://mariadb.com/docs/server/reference/sql-statements/geometry-constructors/wkt/st_polyfromtext', '', 'https://mariadb.com/docs/server/reference/sql-statements/geometry-constructors/wkt/st_polyfromtext');
INSERT INTO help_topic (help_topic_id, help_category_id, name, description, example, url) VALUES (856, 34, 'ST\\_PolygonFromText', 'Description\n-----------\n\nA synonym for ST_PolyFromText.\n\nURL: https://mariadb.com/docs/server/reference/sql-statements/geometry-constructors/wkt/st_polygonfromtext', '', 'https://mariadb.com/docs/server/reference/sql-statements/geometry-constructors/wkt/st_polygonfromtext');
INSERT INTO help_topic (help_topic_id, help_category_id, name, description, example, url) VALUES (857, 34, 'AsText', 'Description\n-----------\n\nA synonym for ST_AsText().\n\nURL: https://mariadb.com/docs/server/reference/sql-statements/geometry-constructors/wkt/wkt-astext', '', 'https://mariadb.com/docs/server/reference/sql-statements/geometry-constructors/wkt/wkt-astext');
INSERT INTO help_topic (help_topic_id, help_category_id, name, description, example, url) VALUES (858, 34, 'AsWKT', 'Description\n-----------\n\nA synonym for ST_AsText().\n\nURL: https://mariadb.com/docs/server/reference/sql-statements/geometry-constructors/wkt/wkt-aswkt', '', 'https://mariadb.com/docs/server/reference/sql-statements/geometry-constructors/wkt/wkt-aswkt');
INSERT INTO help_topic (help_topic_id, help_category_id, name, description, example, url) VALUES (859, 34, 'WKT Definition', 'Description\n-----------\n\nThe Well-Known Text (WKT) representation of Geometry is designed to exchange geometry data in ASCII form. Examples of the basic geometry types include:\n\n| Geometry Types                                                       |\n| -------------------------------------------------------------------- |\n| POINT                           |\n| LINESTRING                 |\n| POLYGON                       |\n| MULTIPOINT                 |\n| MULTILINESTRING       |\n| MULTIPOLYGON             |\n| GEOMETRYCOLLECTION |\n| GEOMETRY        |\n\nURL: https://mariadb.com/docs/server/reference/sql-statements/geometry-constructors/wkt/wkt-definition', '', 'https://mariadb.com/docs/server/reference/sql-statements/geometry-constructors/wkt/wkt-definition');
INSERT INTO help_topic (help_topic_id, help_category_id, name, description, example, url) VALUES (860, 34, 'GeomCollFromText', 'Description\n-----------\n\nA synonym for ST_GeomCollFromText.\n\nURL: https://mariadb.com/docs/server/reference/sql-statements/geometry-constructors/wkt/wkt-geomcollfromtext', '', 'https://mariadb.com/docs/server/reference/sql-statements/geometry-constructors/wkt/wkt-geomcollfromtext');
INSERT INTO help_topic (help_topic_id, help_category_id, name, description, example, url) VALUES (861, 34, 'GeomFromText', 'Description\n-----------\n\nA synonym for ST_GeomFromText.\n\nURL: https://mariadb.com/docs/server/reference/sql-statements/geometry-constructors/wkt/wkt-geomfromtext', '', 'https://mariadb.com/docs/server/reference/sql-statements/geometry-constructors/wkt/wkt-geomfromtext');
INSERT INTO help_topic (help_topic_id, help_category_id, name, description, example, url) VALUES (862, 34, 'LineFromText', 'Description\n-----------\n\nA synonym for ST_LineFromText.\n\nURL: https://mariadb.com/docs/server/reference/sql-statements/geometry-constructors/wkt/wkt-linefromtext', '', 'https://mariadb.com/docs/server/reference/sql-statements/geometry-constructors/wkt/wkt-linefromtext');
INSERT INTO help_topic (help_topic_id, help_category_id, name, description, example, url) VALUES (863, 34, 'PointFromText', 'Description\n-----------\n\nA synonym for ST_PointFromText.\n\nURL: https://mariadb.com/docs/server/reference/sql-statements/geometry-constructors/wkt/wkt-pointfromtext', '', 'https://mariadb.com/docs/server/reference/sql-statements/geometry-constructors/wkt/wkt-pointfromtext');
INSERT INTO help_topic (help_topic_id, help_category_id, name, description, example, url) VALUES (864, 34, 'PolyFromText', 'Description\n-----------\n\nA synonym for ST_PolyFromText.\n\nURL: https://mariadb.com/docs/server/reference/sql-statements/geometry-constructors/wkt/wkt-polyfromtext', '', 'https://mariadb.com/docs/server/reference/sql-statements/geometry-constructors/wkt/wkt-polyfromtext');
INSERT INTO help_topic (help_topic_id, help_category_id, name, description, example, url) VALUES (865, 34, 'ST\\_MLineFromText', 'Description\n-----------\n\nA synonym for ST_GeomFromText.\n\nURL: https://mariadb.com/docs/server/reference/sql-statements/geometry-constructors/wkt/wkt-st_mlinefromtext', '', 'https://mariadb.com/docs/server/reference/sql-statements/geometry-constructors/wkt/wkt-st_mlinefromtext');
INSERT INTO help_topic (help_topic_id, help_category_id, name, description, example, url) VALUES (866, 35, 'DEALLOCATE / DROP PREPARE', 'Syntax\n------\n\n{DEALLOCATE | DROP} PREPARE stmt_name\n\nDescription\n-----------\n\nTo deallocate a prepared statement produced with PREPARE, use aDEALLOCATE PREPARE statement that refers to the prepared statement name.\n\nA prepared statement is implicitly deallocated when a new PREPARE command is issued. In that case, there is no need to use DEALLOCATE.\n\nAttempting to execute a prepared statement after deallocating it results in an error, as if it was not prepared at all:\n\n``sql\nERROR 1243 (HY000): Unknown prepared statement handler (stmt_name) given to EXECUTE\n`\n\nIf the specified statement has not been PREPAREd, an error similar to the following will be produced:\n\n`sql\nERROR 1243 (HY000): Unknown prepared statement handler (stmt_name) given to DEALLOCATE PREPARE\n``\n\nURL: https://mariadb.com/docs/server/reference/sql-statements/prepared-statements/deallocate-drop-prepare', '', 'https://mariadb.com/docs/server/reference/sql-statements/prepared-statements/deallocate-drop-prepare');
INSERT INTO help_topic (help_topic_id, help_category_id, name, description, example, url) VALUES (867, 35, 'EXECUTE IMMEDIATE', 'Syntax\n------\n\nEXECUTE IMMEDIATE statement\n    [USING param[, param] ...]\n\nparam:\n    expression | IGNORE | DEFAULT\n\nDescription\n-----------\n\nEXECUTE IMMEDIATE executes a dynamic SQL statement created on the fly, which can reduce performance overhead. For example:\n\n``sql\nEXECUTE IMMEDIATE ''SELECT 1''\n`\n\nwhich is shorthand for:\n\n`sql\nPREPARE stmt FROM "select 1";\nEXECUTE stmt;\nDEALLOCATE PREPARE stmt;\n`\n\nEXECUTE IMMEDIATE supports complex expressions as prepare source and parameters:\n\n`sql\nEXECUTE IMMEDIATE CONCAT(''SELECT COUNT() FROM '', ''t1'', '' WHERE a=?'') USING 5+5;\n`\n\nLimitations: subselects and stored function calls are not supported as a prepare source.\n\nThe following examples return an error:\n\n`sql\nCREATE OR REPLACE FUNCTION f1() RETURNS VARCHAR(64) RETURN ''SELECT  FROM t1'';\nEXECUTE IMMEDIATE f1();\nERROR 1970 (42000): EXECUTE IMMEDIATE does not support subqueries or stored functions\n\nEXECUTE IMMEDIATE (SELECT ''SELECT  FROM t1'');\nERROR 1064 (42000): You have an error in your SQL syntax; check the manual that \n  corresponds to your MariaDB server version for the right syntax to use near \n  ''SELECT ''SELECT  FROM t1'')'' at line 1\n\nCREATE OR REPLACE FUNCTION f1() RETURNS INT RETURN 10;\nEXECUTE IMMEDIATE ''SELECT  FROM t1 WHERE a=?'' USING f1();\nERROR 1970 (42000): EXECUTE..USING does not support subqueries or stored functions\n\nEXECUTE IMMEDIATE ''SELECT  FROM t1 WHERE a=?'' USING (SELECT 10);\nERROR 1064 (42000): You have an error in your SQL syntax; check the manual that \n  corresponds to your MariaDB server version for the right syntax to use near \n  ''SELECT 10)'' at line 1\n`\n\nOne can use a user or an SP variable as a workaround:\n\n`sql\nCREATE OR REPLACE FUNCTION f1() RETURNS VARCHAR(64) RETURN ''SELECT  FROM t1'';\nSET @stmt=f1();\nEXECUTE IMMEDIATE @stmt;\n\nSET @stmt=(SELECT ''SELECT 1'');\nEXECUTE IMMEDIATE @stmt;\n\nCREATE OR REPLACE FUNCTION f1() RETURNS INT RETURN 10;\nSET @param=f1();\nEXECUTE IMMEDIATE ''SELECT  FROM t1 WHERE a=?'' USING @param;\n\nSET @param=(SELECT 10);\nEXECUTE IMMEDIATE ''SELECT  FROM t1 WHERE a=?'' USING @param;\n`\n\nEXECUTE IMMEDIATE supports user variables and SP variables as OUT parameters:\n\n`sql\nDELIMITER $$\nCREATE OR REPLACE PROCEDURE p1(OUT a INT)\nBEGIN\n  SET a:= 10;\nEND;\n$$\nDELIMITER ;\nSET @a=2;\nEXECUTE IMMEDIATE ''CALL p1(?)'' USING @a;\nSELECT @a;\n+------+\n| @a   |\n+------+\n|   10 |\n+------+\n`\n\nSimilar to PREPARE, EXECUTE IMMEDIATE is allowed in stored procedures but is not allowed in stored functions.\n\nThis example uses EXECUTE IMMEDIATE inside a stored procedure:\n\n`sql\nDELIMITER $$\nCREATE OR REPLACE PROCEDURE p1()\nBEGIN\n  EXECUTE IMMEDIATE ''SELECT 1'';\nEND;\n$$\nDELIMITER ;\nCALL p1;\n+---+\n| 1 |\n+---+\n| 1 |\n+---+\n`\n\nThis script returns an error:\n\n`sql\nDELIMITER $$\nCREATE FUNCTION f1() RETURNS INT\nBEGIN\n  EXECUTE IMMEDIATE ''DO 1'';\n  RETURN 1;\nEND;\n$$\nERROR 1336 (0A000): Dynamic SQL is not allowed in stored function or trigger\n`\n\nEXECUTE IMMEDIATE can use DEFAULT and IGNORE indicators as bind parameters:\n\n`sql\nCREATE OR REPLACE TABLE t1 (a INT DEFAULT 10);\nEXECUTE IMMEDIATE ''INSERT INTO t1 VALUES (?)'' USING DEFAULT;\nSELECT  FROM t1;\n+------+\n| a    |\n+------+\n|   10 |\n+------+\n`\n\nEXECUTE IMMEDIATE increments the Com_execute_immediate status variable, as well as the Com_stmt_prepare, Com_stmt_execute and Com_stmt_close status variables.\n\nNote, EXECUTE IMMEDIATE does not increment the Com_execute_sql status variable. _Com_execute_sql_ is used only for PREPARE..EXECUTE.\n\nThis session screenshot demonstrates how EXECUTE IMMEDIATE affects status variables:\n\n`sql\nSELECT  FROM INFORMATION_SCHEMA.SESSION_STATUS WHERE VARIABLE_NAME RLIKE \n  (''COM_(EXECUTE|STMT_PREPARE|STMT_EXECUTE|STMT_CLOSE)'');\n\n+-----------------------+----------------+\n| VARIABLE_NAME         | VARIABLE_VALUE |\n+-----------------------+----------------+\n| COM_EXECUTE_IMMEDIATE | 0              |\n| COM_EXECUTE_SQL       | 0              |\n| COM_STMT_CLOSE        | 0              |\n| COM_STMT_EXECUTE      | 0              |\n| COM_STMT_PREPARE      | 0              |\n+-----------------------+----------------+\n\nEXECUTE IMMEDIATE ''SELECT 1'';\n+---+\n| 1 |\n+---+\n| 1 |\n+---+\n\nSELECT  FROM INFORMATION_SCHEMA.SESSION_STATUS WHERE VARIABLE_NAME RLIKE \n  (''COM_(EXECUTE|STMT_PREPARE|STMT_EXECUTE|STMT_CLOSE)'');\n+-----------------------+----------------+\n| VARIABLE_NAME         | VARIABLE_VALUE |\n+-----------------------+----------------+\n| COM_EXECUTE_IMMEDIATE | 1              |\n| COM_EXECUTE_SQL       | 0              |\n| COM_STMT_CLOSE        | 1              |\n| COM_STMT_EXECUTE      | 1              |\n| COM_STMT_PREPARE      | 1              |\n+-----------------------+----------------+\n``\n\nURL: https://mariadb.com/docs/server/reference/sql-statements/prepared-statements/execute-immediate', '', 'https://mariadb.com/docs/server/reference/sql-statements/prepared-statements/execute-immediate');
INSERT INTO help_topic (help_topic_id, help_category_id, name, description, example, url) VALUES (868, 35, 'EXECUTE Statement', 'Syntax\n------\n\nEXECUTE stmt_name\n    [USING expression[, expression] ...]\n\nDescription\n-----------\n\nAfter preparing a statement with PREPARE, you execute it with anEXECUTE statement that refers to the prepared statement name. If the prepared statement contains any parameter markers, you must supply aUSING clause that lists expressions containing the values to be bound to the parameters. The USING clause must name exactly as many expressions as the number of parameter markers in the statement.\n\nYou can execute a given prepared statement multiple times, passing different variables to it or setting the variables to different values before each execution.\n\nIf the specified statement has not been PREPAREd, an error similar to the following is produced:\n\n``sql\nERROR 1243 (HY000): Unknown prepared statement handler (stmt_name) given to EXECUTE\n`\n\nEXECUTE` with arbitrary expression as parameters can be used, not just user variables (@var_name).\n\nYou can only use user variables (@var_name) as parameters.\n\nURL: https://mariadb.com/docs/server/reference/sql-statements/prepared-statements/execute-statement', '', 'https://mariadb.com/docs/server/reference/sql-statements/prepared-statements/execute-statement');
INSERT INTO help_topic (help_topic_id, help_category_id, name, description, example, url) VALUES (869, 35, 'PREPARE Statement', 'Syntax\n------\n\nPREPARE stmt_name FROM preparable_stmt\n\nDescription\n-----------\n\nThe 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 an expression with the text of the statement. It cannot contain stored function calls or subqueries. 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.\n\nThe scope of a prepared statement is the session within which it is created. Other sessions cannot see it.\n\nIf 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.\n\nPrepared statements can be PREPARE and EXECUTE in a stored procedure, but not in a stored function or trigger. Also, even if the statement is prepared with PREPARE in a procedure, it will not be deallocated when the procedure execution ends.\n\nA prepared statement can access user-defined variables, but not local variables or procedure''s parameters.\n\nIf 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:\n\n``sql\nCREATE PROCEDURE test_stmt(IN sql_text TEXT)\nBEGIN\n        DECLARE EXIT HANDLER FOR SQLEXCEPTION\n        BEGIN\n                SELECT CONCAT(sql_text, '' is not valid'');\n        END;\n        SET @SQL := sql_text;\n        PREPARE stmt FROM @SQL;\n        DEALLOCATE PREPARE stmt;\nEND;\n`\n\nThe FOUND_ROWS() and ROW_COUNT() functions, if called immediately 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.\n\nA prepared statement is executed with EXECUTE and released with DEALLOCATE PREPARE.\n\nThe 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:\n\n`sql\nERROR 1461 (42000): Can''t create more than max_prepared_stmt_count statements \n  (current value: 0)\n`\n\nOracle Mode\n\nIn Oracle mode, PREPARE stmt FROM ''SELECT :1, :2'' is used instead of ?.\n\nPermitted Statements\n\nThe following is valid from MariaDB 10.6.2.\n\nAll statements can be prepared, except PREPARE, EXECUTE, and DEALLOCATE / DROP PREPARE.\n\nPrior to this, not all statements can be prepared. Only the following SQL commands are permitted:\n\n ALTER TABLE\n ANALYZE TABLE\n BINLOG\n CACHE INDEX\n CALL\n CHANGE MASTER\n CHECKSUM {TABLE | TABLES}\n COMMIT\n {CREATE | DROP} DATABASE\n {CREATE | DROP} INDEX\n {CREATE | RENAME | DROP} TABLE\n {CREATE | RENAME | DROP} USER\n {CREATE | DROP} VIEW\n DELETE\n DESCRIBE\n DO\n EXPLAIN\n FLUSH {TABLE | TABLES | TABLES WITH READ LOCK | HOSTS | PRIVILEGES | LOGS | STATUS |\\\n  MASTER | SLAVE | DES_KEY_FILE | USER_RESOURCES | QUERY CACHE | TABLE_STATISTICS |\\\n  INDEX_STATISTICS | USER_STATISTICS | CLIENT_STATISTICS}\n GRANT\n INSERT\n INSTALL {PLUGIN | SONAME}\n HANDLER READ\n KILL\n LOAD INDEX INTO CACHE\n OPTIMIZE TABLE\n REPAIR TABLE\n REPLACE\n RESET {MASTER | SLAVE | QUERY CACHE}\n REVOKE\n ROLLBACK\n SELECT\n SET\n SET GLOBAL SQL_SLAVE_SKIP_COUNTER\n SET ROLE\n SET SQL_LOG_BIN\n SET TRANSACTION ISOLATION LEVEL\n SHOW EXPLAIN\n 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}\n SHOW CREATE {DATABASE | TABLE | VIEW | PROCEDURE | FUNCTION | TRIGGER | EVENT}\n SHOW {FUNCTION | PROCEDURE} CODE\n SHOW BINLOG EVENTS\n SHOW SLAVE HOSTS\n SHOW {MASTER | BINARY} LOGS\n SHOW {MASTER | SLAVE | TABLES | INNODB | FUNCTION | PROCEDURE} STATUS\n SLAVE {START | STOP}\n TRUNCATE TABLE\n SHUTDOWN\n UNINSTALL {PLUGIN | SONAME}\n UPDATE\n\nSynonyms are not listed here, but can be used. For example, DESC can be used instead of DESCRIBE.\n\nCompound statements can be prepared too.\n\nNote 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.\n\nPREPARE supports most kinds of expressions as well, for example:\n\n`sql\nPREPARE stmt FROM CONCAT(''SELECT  FROM '', table_name);\n`\n\nWhen PREPARE is used with a statement which is not supported, the following error is produced:\n\n`sql\nERROR 1295 (HY000): This command is not supported in the prepared statement protocol yet\n``\n\nExamples\n--------\n\nCREATE TABLE t1 (a INT,b CHAR(10));\nINSERT INTO t1 VALUES (1,"one"),(2, "two"),(3,"three");\nPREPARE test FROM "select * from t1 where a=?";\nSET @param=2;\nEXECUTE test USING @param;\n+------+------+\n| a    | b    |\n+------+------+\n|    2 | two  |\n+------+------+\nSET @param=3;\nEXECUTE test USING @param;\n+------+-------+\n| a    | b     |\n+------+-------+\n|    3 | three |\n+------+-------+\nDEALLOCATE PREPARE test;\n\nURL: https://mariadb.com/docs/server/reference/sql-statements/prepared-statements/prepare-statement', '', 'https://mariadb.com/docs/server/reference/sql-statements/prepared-statements/prepare-statement');
INSERT INTO help_topic (help_topic_id, help_category_id, name, description, example, url) VALUES (870, 35, 'BEGIN END', 'Syntax\n------\n\n[begin_label:] BEGIN [NOT ATOMIC]\n    [statement_list]\nEND [end_label]\n\nDescription\n-----------\n\nBEGIN ... 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\\\noptional, which means that the empty compound statement (BEGIN END) is legal.\n\nNote that END will perform a commit. If you are running in autocommit mode, 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.\n\nUse 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.\\\nChanging the ; end-of-statement delimiter (for example, to//) allows ; to be used in a program body.\n\nA 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.\n\nBEGIN ... 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).\n\nThe declarations order is the following:\n\n DECLARE local variables\n DECLARE CONDITIONs\n DECLARE CURSORs\n DECLARE HANDLERs\n\nNote that DECLARE HANDLER contains another BEGIN ... END construct.\n\nHere is an example of a very simple, anonymous block:\n\n``sql\nBEGIN NOT ATOMIC\nSET @a=1;\nCREATE TABLE test.t1(a INT);\nEND|\n`\n\nBelow is an example of nested blocks in a stored procedure:\n\n`sql\nCREATE PROCEDURE t( )\nBEGIN\n   DECLARE x TINYINT UNSIGNED DEFAULT 1;\n   BEGIN\n      DECLARE x CHAR(2) DEFAULT ''02'';\n       DECLARE y TINYINT UNSIGNED DEFAULT 10;\n       SELECT x, y;\n   END;\n   SELECT x;\nEND;\n`\n\nIn 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.\n\nURL: https://mariadb.com/docs/server/reference/sql-statements/programmatic-compound-statements/begin-end', '', 'https://mariadb.com/docs/server/reference/sql-statements/programmatic-compound-statements/begin-end');
INSERT INTO help_topic (help_topic_id, help_category_id, name, description, example, url) VALUES (871, 35, 'CASE Statement', 'Syntax\n------\n\nCASE case_value\n    WHEN when_value THEN statement_list\n    [WHEN when_value THEN statement_list] ...\n    [ELSE statement_list]\nEND CASE\n\nDescription\n-----------\n\nThe 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.\n\nThe 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.\n\nThe 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.\n\nIf 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.\n\nEach 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:\n\n``sql\nDELIMITER |\nCREATE PROCEDURE p()\nBEGIN\n  DECLARE v INT DEFAULT 1;\n  CASE v\n    WHEN 2 THEN SELECT v;\n    WHEN 3 THEN SELECT 0;\n    ELSE BEGIN END;\n  END CASE;\nEND;\n|\n`\n\nThe 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.\n\nNote: 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`.\n\nURL: https://mariadb.com/docs/server/reference/sql-statements/programmatic-compound-statements/case-statement', '', 'https://mariadb.com/docs/server/reference/sql-statements/programmatic-compound-statements/case-statement');
INSERT INTO help_topic (help_topic_id, help_category_id, name, description, example, url) VALUES (872, 35, 'DECLARE CONDITION', 'Syntax\n------\n\nDECLARE condition_name CONDITION FOR condition_value\n\ncondition_value:\n    SQLSTATE [VALUE] sqlstate_value\n  | mysql_error_code\n\nDescription\n-----------\n\nThe DECLARE ... CONDITION statement defines a named error condition. It 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).\n\nConditions must be declared after local variables, but before CURSORs and HANDLERs.\n\nA 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 success rather than an error condition. If you try, or if you specify an invalid SQLSTATE value, an error like this is produced:\n\n``sql\nERROR 1407 (42000): Bad SQLSTATE: ''00000''\n`\n\nFor a list of SQLSTATE` values and MariaDB error codes, see MariaDB Error Codes.\n\nURL: https://mariadb.com/docs/server/reference/sql-statements/programmatic-compound-statements/declare-condition', '', 'https://mariadb.com/docs/server/reference/sql-statements/programmatic-compound-statements/declare-condition');
INSERT INTO help_topic (help_topic_id, help_category_id, name, description, example, url) VALUES (873, 35, 'DECLARE HANDLER', 'Syntax\n------\n\nDECLARE handler_type HANDLER\n    FOR condition_value [, condition_value] ...\n    statement\n\nhandler_type:\n    CONTINUE\n  | EXIT \n  | UNDO\n\ncondition_value:\n    SQLSTATE [VALUE] sqlstate_value\n  | condition_name\n  | SQLWARNING\n  | NOT FOUND\n  | SQLEXCEPTION\n  | mariadb_error_code\n\nDescription\n-----------\n\nThe DECLARE ... HANDLER statement specifies handlers that each may deal with 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.\n\nHandlers must be declared after local variables, a CONDITION and a CURSOR.\n\nFor a CONTINUE handler, execution of the current program continues after 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.\n\nIf a condition occurs for which no handler has been declared, the default action is EXIT.\n\nA condition_value for DECLARE ... HANDLER can be any of the following values:\n\n An SQLSTATE value (a 5-character string literal) or a MariaDB error code (a number). You should not use SQLSTATE value ''00000'' or MariaDB error code 0, because those indicate success rather than an error condition. For a list of SQLSTATE values and MariaDB error codes, see MariaDB Error Codes.\n A condition name previously specified with DECLARE ... CONDITION. It must be in the same stored program. See DECLARE CONDITION.\n SQLWARNING is shorthand for the class of SQLSTATE values that begin with ''01''.\n 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.\n SQLEXCEPTION is shorthand for the class of SQLSTATE values that do not begin with ''00'', ''01'', or ''02''.\n\nWhen 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:\n\n Handlers which refer to an error code have the highest precedence.\n Handlers which refer to a SQLSTATE come next.\n Handlers which refer to an error class have the lowest precedence.\n\nIn some cases, a statement could produce multiple errors. If this happens, in some cases multiple handlers could have the highest precedence. In such cases, the choice of the handler is indeterminate.\n\nNote 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.\n\nWhen 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.\n\nAn error that is handled by a DECLARE HANDLER construct can be issued again using the RESIGNAL statement.\n\nBelow is an example using DECLARE HANDLER:\n\n``sql\nCREATE TABLE test.t (s1 INT, PRIMARY KEY (s1));\n\nDELIMITER //\n\nCREATE PROCEDURE handlerdemo ( )\n     BEGIN\n       DECLARE CONTINUE HANDLER FOR SQLSTATE ''23000'' SET @x2 = 1;\n       SET @x = 1;\n       INSERT INTO test.t VALUES (1);\n       SET @x = 2;\n       INSERT INTO test.t VALUES (1);\n       SET @x = 3;\n     END;\n     //\n\nDELIMITER ;\n\nCALL handlerdemo( );\n\nSELECT @x;\n+------+\n| @x   |\n+------+\n|    3 |\n+------+\n``\n\nURL: https://mariadb.com/docs/server/reference/sql-statements/programmatic-compound-statements/declare-handler', '', 'https://mariadb.com/docs/server/reference/sql-statements/programmatic-compound-statements/declare-handler');
INSERT INTO help_topic (help_topic_id, help_category_id, name, description, example, url) VALUES (874, 35, 'DECLARE TYPE', 'Description\n-----------\n\nThe DECLARE TYPE declaration specifies user-defined data types that must be compatible with Oracle within stored procedures and anonymous blocks. It provides Oracle-compatible type declarations, such as record types, associative arrays, and REF CURSOR types, which allows for more flexible data handling and better compatibility with Oracle PL/SQL.\n\nAssociative arrays (INDEX BY tables) offer an in-memory key-value structure for quick data storage and effective lookups. REF CURSOR types allow for the creation of cursor variables that refer to query result sets and can be passed between program blocks.\n\nThe general syntax for defining associative array types is as follows:\n\n``sql\nDECLARE\n   TYPE type_name TABLE OF rec_type_name INDEX BY idx_type_name\n`\n\n type_name supports explicit and anchored data types (for instance, t1.col1%TYPE).\n rec_type_name supports scalar and record data types.\n The INDEX BY clause defines the key type using idx_type_name, which supports integer and string data types.\n\nAssociative Arrays\n\nIn Oracle, associative arrays (called index-by tables) are sparse collections of elements indexed by keys, which can be integers or strings.\n\nHere’s an example of how to declare an associative array in Oracle:\n\n`sql\nDECLARE\n  TYPE array_t IS TABLE OF VARCHAR2(64) INDEX BY PLS_INTEGER;\n  array array_t;\nBEGIN\n  array(1) := ''Hello'';\n  array(2) := ''World'';\n  DBMS_OUTPUT.PUT_LINE(array(1));\nEND;\n`\n\nMethods\n\nAssociative arrays support the following methods:\n\n FIRST — a function that returns the first key\n LAST — a function that returns the last key\n NEXT — a function that returns the key after the given one\n PRIOR — a function that returns the key before the given one\n COUNT — a function that returns the number of elements\n EXISTS — a function that returns TRUE if the key exists\n DELETE — a procedure that removes a specific key, or clears the array\n\nWhile the MariaDB implementation is largely aligned with Oracle’s implementation, there are a few differences:\n\n Only literals as keys in the constructor: When using constructors, keys must be literals — Oracle allows expressions.\n Collation control: Instead of NLS_SORT or NLS_COMP, MariaDB uses the SQL-standard COLLATE` clause.\n* No nested associative arrays: Arrays of arrays are not supported.\n\nThese differences are largely rooted in architectural constraints — MariaDB is aiming at staying as close to Oracle semantics as possible while maintaining performance and predictability.\n\nExamples\n--------\n\nDECLARE\n  TYPE salary IS TABLE OF NUMBER INDEX BY VARCHAR2(20);\n  salary_list salary;\n  name VARCHAR2(20);\nBEGIN\n  salary_list(''Rajnisj'') := 62000;\n  salary_list(''James'') := 78000;\n  name:= salary_list.FIRST;\n  WHILE name IS NOT NULL\n  LOOP\n    dbms_output.put_line(name || '' '' || TO_CHAR(salary_list(name)));\n    name:= salary_list.NEXT(name);\n  END LOOP;\nEND;\n/\n\nURL: https://mariadb.com/docs/server/reference/sql-statements/programmatic-compound-statements/declare-type', '', 'https://mariadb.com/docs/server/reference/sql-statements/programmatic-compound-statements/declare-type');
INSERT INTO help_topic (help_topic_id, help_category_id, name, description, example, url) VALUES (875, 35, 'DECLARE Variable', 'Syntax\n------\n\nDECLARE var_name [, var_name] ... [[ROW] TYPE OF]] type [DEFAULT value]\n\nDescription\n-----------\n\nThis statement is used to declare local variables within stored programs. To 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 theDEFAULT clause is missing, the initial value is NULL.\n\nLocal variables are treated like stored routine parameters with respect to data type and overflow checking. See CREATE PROCEDURE.\n\nLocal variables must be declared before CONDITIONs, CURSORs and HANDLERs.\n\nLocal variable names are not case sensitive.\n\nThe scope of a local variable is within the BEGIN ... END block where it is 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.\n\nTYPE OF / ROW TYPE OF\n\nAnchored 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.\n\nVariables 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.\n\nThe 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.\n\nThe 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.\n\nThe 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.\n\nDynamic Cursors Limitation&#x20;\n\nROW TYPE OF is not supported for dynamic cursors (cursors declared for a prepared statement). This is because the cursor''s structure is dependent on the prepared statement, which is not known at the time the stored procedure context is created.\n\nExamples\n--------\n\nDECLARE name VARCHAR(5) DEFAULT ''monty'';\n  DECLARE x INT DEFAULT 10;\n  DECLARE Y SMALLINT;\n\nURL: https://mariadb.com/docs/server/reference/sql-statements/programmatic-compound-statements/declare-variable', '', 'https://mariadb.com/docs/server/reference/sql-statements/programmatic-compound-statements/declare-variable');
INSERT INTO help_topic (help_topic_id, help_category_id, name, description, example, url) VALUES (876, 35, 'FOR', 'Syntax\n------\n\n[begin_label:]\nFOR var_name IN [ REVERSE ] lower_bound .. upper_bound\nDO statement_list\nEND FOR [ end_label ]\n\nDescription\n-----------\n\nFOR loops allow code to be executed a fixed number of times.\n\nIn an integer range FOR loop, MariaDB will compare the lower bound and upper 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.\n\nDynamic Cursors Limitation\n\nFOR loops cannot be used with dynamic cursors (cursors declared for prepared statement names). To handle dynamic cursors, employ explicit OPEN, FETCH, and CLOSE statements inside a LOOP or similar construct.\n\nIf REVERSE is specified, the counter is decremented, and the upper bound value needs to be less than or equal for the loop to continue.\n\nExamples\n--------\n\nCREATE TABLE t1 (a INT);\n\nDELIMITER //\n\nFOR i IN 1..3\nDO\n  INSERT INTO t1 VALUES (i);\nEND FOR;\n//\n\nDELIMITER ;\n\nSELECT * FROM t1;\n+------+\n| a    |\n+------+\n|    1 |\n|    2 |\n|    3 |\n+------+\n\nURL: https://mariadb.com/docs/server/reference/sql-statements/programmatic-compound-statements/for', '', 'https://mariadb.com/docs/server/reference/sql-statements/programmatic-compound-statements/for');
INSERT INTO help_topic (help_topic_id, help_category_id, name, description, example, url) VALUES (877, 35, 'GOTO', 'Syntax\n------\n\nGOTO label\n\nDescription\n-----------\n\nThe GOTO statement causes the code to jump to the specified label, and continue operating from there. It is only accepted when in Oracle mode.\n\nExamples\n--------\n\nSET sql_mode=ORACLE;\n\nDELIMITER //\n\nCREATE OR REPLACE PROCEDURE p1 AS\n\nBEGIN\n\n  SELECT 1;\n  GOTO label;\n  SELECT 2;\n  <<label>>\n  SELECT 3;\n\nEND;\n\n//\n\nDELIMITER \n\nCALL p1();\n+---+\n| 1 |\n+---+\n| 1 |\n+---+\n1 row in set (0.000 sec)\n\n+---+\n| 3 |\n+---+\n| 3 |\n+---+\n1 row in set (0.000 sec)\n\nURL: https://mariadb.com/docs/server/reference/sql-statements/programmatic-compound-statements/goto', '', 'https://mariadb.com/docs/server/reference/sql-statements/programmatic-compound-statements/goto');
INSERT INTO help_topic (help_topic_id, help_category_id, name, description, example, url) VALUES (878, 35, 'IF', 'Syntax\n------\n\nIF search_condition THEN statement_list\n    [ELSEIF search_condition THEN statement_list] ...\n    [ELSE statement_list]\nEND IF;\n\nDescription\n-----------\n\nIF 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.\n\nURL: https://mariadb.com/docs/server/reference/sql-statements/programmatic-compound-statements/if', '', 'https://mariadb.com/docs/server/reference/sql-statements/programmatic-compound-statements/if');
INSERT INTO help_topic (help_topic_id, help_category_id, name, description, example, url) VALUES (879, 35, 'ITERATE', 'Description\n-----------\n\nSyntax\n\n``sql\nITERATE label\n`\n\nITERATE 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.\n\nIf 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:\n\n`sql\nERROR 1308 (42000): ITERATE with no matching label: <label_name>\n`\n\nBelow is an example of how ITERATE might be used:\n\n`sql\nCREATE PROCEDURE doiterate(p1 INT)\nBEGIN\n  label1: LOOP\n    SET p1 = p1 + 1;\n    IF p1 < 10 THEN ITERATE label1; END IF;\n    LEAVE label1;\n  END LOOP label1;\n  SET @x = p1;\nEND\n``\n\nURL: https://mariadb.com/docs/server/reference/sql-statements/programmatic-compound-statements/iterate', '', 'https://mariadb.com/docs/server/reference/sql-statements/programmatic-compound-statements/iterate');

INSERT INTO help_topic (help_topic_id, help_category_id, name, description, example, url) VALUES (881, 35, 'LEAVE', 'Description\n-----------\n\nSyntax\n\n``sql\nLEAVE label\n`\n\nThis 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.\n\nLEAVE cannot be used to exit a DECLARE HANDLER block.\n\nIf you try to LEAVE a non-existing label, or if you try to LEAVE a HANDLER block, the following error will be produced:\n\n`sql\nERROR 1308 (42000): LEAVE with no matching label: <label_name>\n`\n\nThe following example uses LEAVE to exit the procedure if a condition is true:\n\n`sql\nCREATE PROCEDURE proc(IN p TINYINT)\nCONTAINS SQL\nwhole_proc:\nBEGIN\n   SELECT 1;\n   IF p < 1 THEN\n      LEAVE whole_proc;\n   END IF;\n   SELECT 2;\nEND;\n\nCALL proc(0);\n+---+\n| 1 |\n+---+\n| 1 |\n+---+\n``\n\nURL: https://mariadb.com/docs/server/reference/sql-statements/programmatic-compound-statements/leave', '', 'https://mariadb.com/docs/server/reference/sql-statements/programmatic-compound-statements/leave');
INSERT INTO help_topic (help_topic_id, help_category_id, name, description, example, url) VALUES (882, 35, 'LOOP', 'Syntax\n------\n\n[begin_label:] LOOP\n    statement_list\nEND LOOP [end_label]\n\nDescription\n-----------\n\nLOOP 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.\n\nA LOOP statement can be labeled. end_label cannot be given unlessbegin_label also is present. If both are present, they must be the same.\n\nSee Delimiters in the mariadb client for more on delimiter usage in the client.\n\nURL: https://mariadb.com/docs/server/reference/sql-statements/programmatic-compound-statements/loop', '', 'https://mariadb.com/docs/server/reference/sql-statements/programmatic-compound-statements/loop');
INSERT INTO help_topic (help_topic_id, help_category_id, name, description, example, url) VALUES (883, 35, 'CLOSE', 'Syntax\n------\n\nCLOSE cursor_name\n\nDescription\n-----------\n\nThis statement closes a previously opened cursor. The cursor must have been previously opened or else an error occurs.\n\nIf not closed explicitly, a cursor is closed at the end of the compound statement in which it was declared.\n\nSee Cursor Overview for an example.\n\nURL: https://mariadb.com/docs/server/reference/sql-statements/programmatic-compound-statements/programmatic-compound-statements-cursors/close', '', 'https://mariadb.com/docs/server/reference/sql-statements/programmatic-compound-statements/programmatic-compound-statements-cursors/close');
INSERT INTO help_topic (help_topic_id, help_category_id, name, description, example, url) VALUES (884, 35, 'Cursor Overview', 'Description\n-----------\n\nA cursor is a structure that allows you to go over records sequentially, and perform processing based on the result.\n\nMariaDB permits cursors inside stored programs, and MariaDB cursors are non-scrollable, read-only and case-insensitive.\n\n 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.\n Read-only means that data cannot be updated through the cursor.\n Assensitive 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.\n\nCursors 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.\n\nWhen FETCH is issued and there are no more rows to extract, the following error is produced:\n\n``sql\nERROR 1329 (02000): No data - zero rows fetched, selected, or processed\n`\n\nTo 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.\n\nCursors can be declared for a prepared statement name, enabling full support for Dynamic SQL within stored routines. The SQL Standard syntax for  <dynamic declare cursor> is supported: a cursor is declared with the FOR clause to bind it to a prepared statement name, which is then prepared and opened normally. Cursors may also still SELECT from views, which can be created dynamically via prepared statements.&#x20;\n\nOnly 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.&#x20;\n\nCursors 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.\n\nCursors cannot have parameters.\n\nExamples\n--------\n\nCREATE TABLE c1(i INT);\n\nCREATE TABLE c2(i INT);\n\nCREATE TABLE c3(i INT);\n\nDELIMITER //\n\nCREATE PROCEDURE p1()\nBEGIN\n  DECLARE done INT DEFAULT FALSE;\n  DECLARE x, y INT;\n  DECLARE cur1 CURSOR FOR SELECT i FROM test.c1;\n  DECLARE cur2 CURSOR FOR SELECT i FROM test.c2;\n  DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = TRUE;\n\n  OPEN cur1;\n  OPEN cur2;\n\n  read_loop: LOOP\n    FETCH cur1 INTO x;\n    FETCH cur2 INTO y;\n    IF done THEN\n      LEAVE read_loop;\n    END IF;\n    IF x < y THEN\n      INSERT INTO test.c3 VALUES (x);\n    ELSE\n      INSERT INTO test.c3 VALUES (y);\n    END IF;\n  END LOOP;\n\n  CLOSE cur1;\n  CLOSE cur2;\nEND; //\n\nDELIMITER ;\n\nINSERT INTO c1 VALUES(5),(50),(500);\n\nINSERT INTO c2 VALUES(10),(20),(30);\n\nCALL p1;\n\nSELECT  FROM c3;\n\nURL: https://mariadb.com/docs/server/reference/sql-statements/programmatic-compound-statements/programmatic-compound-statements-cursors/cursor-overview', '', 'https://mariadb.com/docs/server/reference/sql-statements/programmatic-compound-statements/programmatic-compound-statements-cursors/cursor-overview');
INSERT INTO help_topic (help_topic_id, help_category_id, name, description, example, url) VALUES (885, 35, 'DECLARE CURSOR', 'Syntax\n------\n\nDECLARE cursor_name CURSOR [(cursor_formal_parameter[,...])] FOR {select_statement | prepared_statement_name}\n\ncursor_formal_parameter:\n    [IN] name type [collate clause]\n\nDescription\n-----------\n\nThis 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.\n\nselect_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.\n\nA 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.\n\nStarting with MariaDB 12.3, the query can also be a prepared statement name, which allows the query to be dynamically composed. The SELECT statement cannot have an INTO clause.\n\nCursors must be declared before HANDLERs, but after local variables and CONDITIONs.\n\n> The DECLARE CURSOR statement provides a cursor to a specified SELECT statement.\n>\n> To declare a cursor variable type that can be connected with multiple queries at runtime (REF CURSOR), use DECLARE TYPE... IS REF CURSOR in Oracle mode. See DECLARE TYPE.\n\nDynamic Cursors\n\nStarting with MariaDB 12.3, a cursor can be declared for a prepared statement. This allows the use of Dynamic SQL within stored routines. The cursor is bound to a prepared statement name, which must be defined using the PREPARE statement before the cursor is opened.\n\n``sql\nCREATE OR REPLACE PROCEDURE p1(tab VARCHAR(64), min_id INTEGER)\nBEGIN\n  DECLARE v_id INT;\n  DECLARE v_c1 VARCHAR(100);\n  DECLARE no_data BOOL DEFAULT FALSE;\n  \n  -- 1. Declare cursor for the statement name ''s1''\n  DECLARE c1 CURSOR FOR s1;\n  DECLARE CONTINUE HANDLER FOR NOT FOUND SET no_data = TRUE;\n\n  -- 2. Prepare the statement dynamically\n  PREPARE s1 FROM CONCAT(''SELECT id, c1 FROM '', tab, '' WHERE id >= ?'');\n  \n  -- 3. Open cursor and bind parameters\n  OPEN c1 USING min_id;\n  \n  fetch_loop: LOOP\n    FETCH c1 INTO v_id, v_c1;\n    IF no_data THEN\n      LEAVE fetch_loop;\n    END IF;\n    SELECT v_id, v_c1;\n  END LOOP;\n  \n  CLOSE c1;\n  DEALLOCATE PREPARE s1;\nEND;\n$$\n\nDELIMITER ;\n`\n\nParameters\n\nCursors 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 , and so forth).\n\nIN\n\nThe IN qualifier is supported in the cursor_formal_parameter part of the syntax.\n\nThe IN qualifier is not supported in the cursor_formal_parameter` part of the syntax.\n\nSee Cursor Overview for an example.\n\nURL: https://mariadb.com/docs/server/reference/sql-statements/programmatic-compound-statements/programmatic-compound-statements-cursors/declare-cursor', '', 'https://mariadb.com/docs/server/reference/sql-statements/programmatic-compound-statements/programmatic-compound-statements-cursors/declare-cursor');
INSERT INTO help_topic (help_topic_id, help_category_id, name, description, example, url) VALUES (886, 35, 'FETCH', 'Syntax\n------\n\nFETCH cursor_name INTO var_name [, var_name] ...\n\nDescription\n-----------\n\nThis statement fetches the next row (if a row exists) using the specified open cursor, and advances the cursor pointer.\n\nvar_name can be a local variable, but _not_ a user-defined variable.\n\nIf no more rows are available, a No Data condition occurs withSQLSTATE value 02000. To detect this condition, you can set up a handler for it (or for a NOT FOUND condition).\n\nSee Cursor Overview for an example.\n\nURL: https://mariadb.com/docs/server/reference/sql-statements/programmatic-compound-statements/programmatic-compound-statements-cursors/fetch', '', 'https://mariadb.com/docs/server/reference/sql-statements/programmatic-compound-statements/programmatic-compound-statements-cursors/fetch');
INSERT INTO help_topic (help_topic_id, help_category_id, name, description, example, url) VALUES (887, 35, 'OPEN', 'Syntax\n------\n\nOPEN cursor_name [[USING variable[,...]] | [expression[,...]]];\n\nDescription\n-----------\n\nThis statement opens a cursor which was previously declared with DECLARE CURSOR.\n\nThe 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.\n\nThis is necessary in order to FETCH rows from a cursor.\n\nSee Cursor Overview for an example.\n\nURL: https://mariadb.com/docs/server/reference/sql-statements/programmatic-compound-statements/programmatic-compound-statements-cursors/open', '', 'https://mariadb.com/docs/server/reference/sql-statements/programmatic-compound-statements/programmatic-compound-statements-cursors/open');
INSERT INTO help_topic (help_topic_id, help_category_id, name, description, example, url) VALUES (888, 35, 'Diagnostics Area', 'Description\n-----------\n\nThe diagnostics area contains information about the error conditions which were produced by an SQL statement, as well as some information about the statement which generated them.\n\nStatement Information\n\nThe statement information area contains the following data:\n\n NUMBER is the number of conditions which are present in the diagnostics area.\n ROW_COUNT has the same value as the ROW_COUNT() function for the statement that produced the conditions.\n\nCondition Information\n\nEach condition has several properties, which are explained here.\n\nData Types and Sizes\n\nThe following table shows the type and size of all the properties:\n\n| Property name       | Property type     |\n| ------------------- | ----------------- |\n| RETURNED_SQLSTATE  | VARCHAR(5)        |\n| MYSQL_ERRNO        | SMALLINT UNSIGNED |\n| MESSAGE_TEXT       | VARCHAR(512)      |\n| CLASS_ORIGIN       | VARCHAR(64)       |\n| SUBCLASS_ORIGIN    | VARCHAR(64)       |\n| CONSTRAINT_CATALOG | VARCHAR(64)       |\n| CONSTRAINT_SCHEMA  | VARCHAR(64)       |\n| CONSTRAINT_NAME    | VARCHAR(64)       |\n| CATALOG_NAME       | VARCHAR(64)       |\n| SCHEMA_NAME        | VARCHAR(64)       |\n| TABLE_NAME         | VARCHAR(64)       |\n| COLUMN_NAME        | VARCHAR(64)       |\n| CURSOR_NAME        | VARCHAR(64)       |\n\nThese properties can never be set to NULL. If they are empty, the empty string is used.\n\nCommon Condition Properties\n\nThe most common ones have a value for all built-in errors, and can be read both via SQL and via the API:\n\nRETURNED_SQLSTATE is the SQLSTATE of the condition. It is a five characters code, composed by a class (first two characters) and a subclass (last three characters). For more information about this property, refer to the SQLSTATE page.\n\nMYSQL_ERRNO is the error code. Each built-in condition has a unique numeric code. 0 indicates success, but it cannot be explicitly set or read via SQL. For a list of built-in error codes, refer to MariaDB Error Codes. The API function to read it is mysql_errno().\n\nMESSAGE_TEXT is a descriptive, human-readable message. For built-in errors, parsing this string is the only way to get more information about the error. For example, parsing a message like "Table ''tab1'' already exists", a program can find out that the missing table is tab1. The API function to read it is mysql_error().\n\nFor conditions generated by the user via SIGNAL, if MYSQL_ERRNO and MESSAGE_TEXT are not specified, their default values depend on the first two SQLSTATE characters:\n\n ''00'' means ''success''. It can not be set in any way, and can only be read via the API.\n For ''01'' class, default MYSQL_ERRNO is 1642 and default MESSAGE_TEXT is ''Unhandled user-defined warning condition''.\n For ''02'' class, default MYSQL_ERRNO is 1643 and default MESSAGE_TEXT is ''Unhandled user-defined not found condition''.\n For all other cases, including the ''45000'' value, default MYSQL_ERRNO is 1644 and default MESSAGE_TEXT is ''Unhandled user-defined exception condition''.\n\nSpecial Condition Properties\n\nThere are more condition properties, which are never set for built-in errors. They can only be set via SIGNAL and RESIGNAL statements, and can only be read via GET DIAGNOSTICS - not via the API. Such properties are:\n\nCLASS_ORIGIN indicates whether the SQLSTATE uses a standard class or a software-specific class. If it is defined in the SQL standards document ISO 9075-2 (section 24.1, SQLSTATE), this property''s value is supposed to be ''ISO 9075'', otherwise it is supposed to be ''MySQL''. However, any string is accepted.\n\nSUBCLASS_ORIGIN indicates whether the SQLSTATE uses a standard subclass or a software-specific class. If the SQLSTATE is defined in the SQL standards document ISO 9075-2 (section 24.1, SQLSTATE), this property''s value is supposed to be ''ISO 9075'', otherwise it is supposed to be ''MySQL''. However, any string is accepted.\n\nSCHEMA_NAME indicates in which schema (database) the error occurred.\n\nTABLE_NAME indicates the name of the table which was accessed by the failed statement.\n\nCOLUMN_NAME indicates the name of the column which was accessed by the failed statement.\n\nCONSTRAINT_NAME indicates the name of the constraint that was violated.\n\nCONSTRAINT_SCHEMA indicates in which schema the violated constraint is located.\n\nCURSOR_NAME indicates the name of the cursor which caused the error.\n\nThe following properties can be used and are defined in the standard SQL, but have no meaning because MariaDB doesn''t currently support catalogs:\n\nCATALOG_NAME is used by the standard SQL to indicate in which catalog the error occurred.\n\nCONSTRAINT_CATALOG is used by the standard SQL to indicate in which catalog the violated constraint is located.\n\nHow the Diagnostics Area is Populated and Cleared\n\nWhen a statement produces one or more error conditions (errors, warnings, notes) the conditions are inserted into the diagnostics area, and the statement information area is updated with that statement’s information. Usually, this also clears all the old conditions from the diagnostics area, but there is an exception: if the new statement is a correctly parsed RESIGNAL or GET DIAGNOSTICS, the old contents will remain in the diagnostics area. SIGNAL clears the old conditions.\n\nWhen a table-based statement (like INSERT) is executed, the old data in the diagnostics area is cleared even if the statement doesn''t produce any condition. However, statements which don''t access any table (like SET, or a SELECT with no FROM clause) is executed and produces no warnings, the diagnostics area remains unchanged.\n\nThe maximum number of conditions that can be in the diagnostics area is max_error_count. If this value is 0, the diagnostics area is empty. If this variable is changed, the new value takes effect with the next statement (that is, the diagnostics area is not immediately truncated).\n\nHow to Access the Diagnostics Area\n\nThe following statements explicitly add conditions to the diagnostics area:\n\n SIGNAL: produces a custom error.\n RESIGNAL: after an error is produced, generates a modified version of that error.\n\nThe following statements read contents from the diagnostics area:\n\n GET DIAGNOSTICS is the only way to read all information.\n SHOW WARNINGS shows a summary of errors, warnings and notes.\n* SHOW ERRORS shows a summary of errors.\n\nDECLARE HANDLER can be used to handle error conditions within stored programs.\n\nDECLARE CONDITION can be used to associate an SQLSTATE or an error code to a name. That name can be referenced in DECLARE HANDLER, SIGNAL and RESIGNAL statements.\n\nAll these statements can also be executed inside a stored routine. However, only SHOW WARNINGS and SHOW ERRORS can be executed as a prepared statement. After an EXECUTE statement, the diagnostics area contains information about the prepared statement, if it produces error conditions.\n\nURL: https://mariadb.com/docs/server/reference/sql-statements/programmatic-compound-statements/programmatic-compound-statements-diagnostics/diagnostics-area', '', 'https://mariadb.com/docs/server/reference/sql-statements/programmatic-compound-statements/programmatic-compound-statements-diagnostics/diagnostics-area');
INSERT INTO help_topic (help_topic_id, help_category_id, name, description, example, url) VALUES (889, 35, 'GET DIAGNOSTICS', 'Description\n-----------\n\n``sql\nGET [CURRENT] DIAGNOSTICS\n{\n    statement_property\n    [, statement_property] ... \n  | CONDITION condition_number\n    condition_property\n    [, condition_property] ...\n}\n\nstatement_property:\n    variable = statement_property_name\n\ncondition_property:\n    variable  = condition_property_name\n\nstatement_property_name:\n    NUMBER\n  | ROW_COUNT\n\ncondition_property_name:\n    CLASS_ORIGIN\n  | SUBCLASS_ORIGIN\n  | RETURNED_SQLSTATE\n  | MESSAGE_TEXT\n  | MYSQL_ERRNO\n  | CONSTRAINT_CATALOG\n  | CONSTRAINT_SCHEMA\n  | CONSTRAINT_NAME\n  | CATALOG_NAME\n  | SCHEMA_NAME\n  | TABLE_NAME\n  | COLUMN_NAME\n  | CURSOR_NAME\n  | ROW_NUMBER\n`\n\nThe diagnostics area contains information about the errors, warnings and notes which were produced by the last SQL statement. If that statement didn''t produce any warnings, the diagnostics area contains information about the last executed statement which involved a table. The GET DIAGNOSTICS statement copies the requested information from the diagnostics area to the specified variables. It is possible to use both user variables or local variables.\n\nTo use GET DIAGNOSTICS, it is important to know how the diagnostics area is structured. It has two sub-areas: the statement information area and the error conditions information area. For details, please refer to the diagnostics area page.\n\nEach single GET DIAGNOSTICS command can read information from the statement information area or from a single error condition. This means that, if you have two warnings and you want to know the number of warnings, and read both the warnings, you need to issue GET DIAGNOSTICS three times.\n\nThe CURRENT keywords adds nothing to the statement, because MariaDB has only one diagnostics area.\n\nIf GET DIAGNOSTICS produces an error condition (because the command is properly parsed but not correctly used), the diagnostics area is not emptied, and the new condition is added.\n\nGetting Information from a Condition\n\nTo read information from a condition, the CONDITION keyword must be specified and it must be followed by the condition number. This number can be specified as a constant value or as a variable. The first condition''s index is 1. If the error condition does not exist, the variables will not change their value and a 1758 error will be produced ("Invalid condition number").\n\nThe condition properties that can be read with GET DIAGNOSTICS are the same that can be set with SIGNAL and RESIGNAL statements. They are explained in the diagnostics area page. However, there is one more property: RETURNED_SQLSTATE, which indicates the condition''s SQLSTATE.\n\nFor a list of SQLSTATE values and MariaDB error codes, see MariaDB Error Codes.\n\nThe type for all the condition properties is VARCHAR(64), except for MYSQL_ERRNO, whose valid range is 1 to 65534.\n\nROW_NUMBER\n\nYou can use the ROW_NUMBER property to retrieve the row number, too, even if the error text does not mention it. This property is named ERROR_INDEX . ROW_NUMBER is a reserved word.\n\nThere is no way, short of parsing the error text, to know in what row an error had happened.\n\nExamples\n--------\n\nCREATE TABLE test.t (c` INT) ENGINE = x;\nQuery OK, 0 rows affected, 2 warnings (0.19 sec)\n\nGET DIAGNOSTICS @num_conditions = NUMBER;\n\nSELECT @num_conditions;\n+-----------------+\n| @num_conditions |\n+-----------------+\n|               2 |\n+-----------------+\n\nURL: https://mariadb.com/docs/server/reference/sql-statements/programmatic-compound-statements/programmatic-compound-statements-diagnostics/get-diagnostics', '', 'https://mariadb.com/docs/server/reference/sql-statements/programmatic-compound-statements/programmatic-compound-statements-diagnostics/get-diagnostics');
INSERT INTO help_topic (help_topic_id, help_category_id, name, description, example, url) VALUES (890, 35, 'SQLSTATE', 'Description\n-----------\n\nSQLSTATE is a code which identifies SQL error conditions. It composed by five characters, which can be numbers or uppercase ASCII letters. An SQLSTATE value consists of a class (first two characters) and a subclass (last three characters).\n\nThere are three important standard classes. They all indicate in which logical group of errors the condition falls. They match to a particular keyword which can be used with DECLARE HANDLER. Also, the SQLSTATE class determines the default value for the MYSQL_ERRNO and MESSAGE_TEXT condition properties.\n\n ''00'' means ''success''. It can not be set in any way and can only be read via the API.\n ''01'' contains all warnings and matches to the SQLWARNING keyword. The default MYSQL_ERRNO is 1642 and default MESSAGE_TEXT is ''Unhandled user-defined warning condition''.\n ''02'' is the NOT FOUND class. The default MYSQL_ERRNO is 1643 and default MESSAGE_TEXT is ''Unhandled user-defined not found condition''.\n All other classes match the SQLEXCEPTION keyword. The default MYSQL_ERRNO is 1644 and default MESSAGE_TEXT is ''Unhandled user-defined exception condition''.\n\nThe subclass, if it is set, indicates a particular condition, or a particular group of conditions within the class. However, the ''000'' sequence means ''no subclass''.\n\nFor example, if you try to SELECT from a table which does not exist, a 1109 error is produced, with a ''42S02'' SQLSTATE. ''42'' is the class and ''S02'' is the subclass. This value matches to the SQLEXCEPTION keyword. When FETCH is called for a cursor which has already reached the end, a 1329 error is produced, with a ''02000'' SQLSTATE. The class is ''02'' and there is no subclass (because ''000'' means ''no subclass''). It can be handled by a NOT FOUND handlers.\n\nThe standard SQL specification says that classes beginning with 0, 1, 2, 3, 4, A, B, C, D, E, F and G are reserved for standard-defined classes, while other classes are vendor-specific. It also says that, when the class is standard-defined, subclasses starting with those characters (except for ''000'') are standard-defined subclasses, while other subclasses are vendor-defined. However, MariaDB and MySQL do not strictly obey this rule.\n\nTo read the SQLSTATE of a particular condition which is in the diagnostics area, the GET DIAGNOSTICS statement can be used: the property is called RETURNED_SQLSTATE. For user-defined conditions (SIGNAL and RESIGNAL statements), a SQLSTATE value must be set via the SQLSTATE clause. However, SHOW WARNINGS and SHOW ERRORS do not display the SQLSTATE.\n\nFor user-defined conditions, MariaDB and MySQL recommend the ''45000'' SQLSTATE class.\n\n''HY000'' is called the "general error": it is the class used for built-in conditions which do not have a specific SQLSTATE class.\n\nA partial list of error codes and matching SQLSTATE values can be found under MariaDB Error Codes.\n\nURL: https://mariadb.com/docs/server/reference/sql-statements/programmatic-compound-statements/programmatic-compound-statements-diagnostics/sqlstate', '', 'https://mariadb.com/docs/server/reference/sql-statements/programmatic-compound-statements/programmatic-compound-statements-diagnostics/sqlstate');
INSERT INTO help_topic (help_topic_id, help_category_id, name, description, example, url) VALUES (891, 35, 'REPEAT LOOP', 'Description\n-----------\n\nSyntax\n\n``sql\n[begin_label:] REPEAT\n    statement_list\nUNTIL search_condition\nEND REPEAT [end_label]\n`\n\nThe 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\\\nterminated by a semicolon (i.e., ;) statement delimiter.\n\nA REPEAT statement can be labeled. end_label cannot be given unless begin_label is also present. If both are present, they must be the same.\n\nSee Delimiters in the mariadb client for more on client delimiter usage.\n\n`sql\nDELIMITER //\n\nCREATE PROCEDURE dorepeat(p1 INT)\n  BEGIN\n    SET @x = 0;\n    REPEAT SET @x = @x + 1; UNTIL @x > p1 END REPEAT;\n  END\n//\n\nCALL dorepeat(1000)//\n\nSELECT @x//\n+------+\n| @x   |\n+------+\n| 1001 |\n+------+\n``\n\nURL: https://mariadb.com/docs/server/reference/sql-statements/programmatic-compound-statements/repeat-loop', '', 'https://mariadb.com/docs/server/reference/sql-statements/programmatic-compound-statements/repeat-loop');
INSERT INTO help_topic (help_topic_id, help_category_id, name, description, example, url) VALUES (892, 35, 'RESIGNAL', 'Syntax\n------\n\nRESIGNAL [error_condition]\n    [SET error_property\n    [, error_property] ...]\n\nerror_condition:\n    SQLSTATE [VALUE] ''sqlstate_value''\n  | condition_name\n\nerror_property:\n    error_property_name = <error_property_value>\n\nerror_property_name:\n    CLASS_ORIGIN\n  | SUBCLASS_ORIGIN\n  | MESSAGE_TEXT\n  | MYSQL_ERRNO\n  | CONSTRAINT_CATALOG\n  | CONSTRAINT_SCHEMA\n  | CONSTRAINT_NAME\n  | CATALOG_NAME\n  | SCHEMA_NAME\n  | TABLE_NAME\n  | COLUMN_NAME\n  | CURSOR_NAME\n\nDescription\n-----------\n\nThe 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.\n\nRESIGNAL does not empty the diagnostics area. It just appends another error condition.\n\nRESIGNAL, without any clauses, produces an error which is identical to the error that was received by HANDLER.\n\nIf used out of a HANDLER construct, RESIGNAL produces the following error:\n\n``sql\nERROR 1645 (0K000): RESIGNAL when handler not active\n`\n\nIf a HANDLER contains a CALL to another procedure, that procedure can use RESIGNAL, but trying to do this raises the above error.\n\nIf a HANDLER contains a CALL to another procedure, that procedure can use RESIGNAL.\n\nFor a list of SQLSTATE values and MariaDB error codes, see MariaDB Error Codes.\n\nThe 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.\n\n`sql\nCREATE PROCEDURE test_error( )\nBEGIN\n   DECLARE CONTINUE HANDLER\n      FOR 1146\n   BEGIN\n   IF @hide_errors IS FALSE THEN\n      RESIGNAL;\n   END IF;\n   END;\n   SET @hide_errors = TRUE;\n   SELECT ''Next error will be ignored'' AS msg;\n   SELECT c FROM temptab_one;\n   SELECT ''Next error won''''t be ignored'' AS msg;\n   SET @hide_errors = FALSE;\n   SELECT c FROM temptab_two;\nEND;\n\nCALL test_error( );\n\n+----------------------------+\n| msg                        |\n+----------------------------+\n| Next error will be ignored |\n+----------------------------+\n\n+-----------------------------+\n| msg                         |\n+-----------------------------+\n| Next error won''t be ignored |\n+-----------------------------+\n\nERROR 1146 (42S02): Table ''test.temptab_two'' doesn''t exist\n`\n\nThe following procedure re-signals an error, modifying only the error message to clarify the cause of the problem.\n\n`sql\nCREATE PROCEDURE test_error()\nBEGIN\n   DECLARE CONTINUE HANDLER\n   FOR 1146\n   BEGIN\n      RESIGNAL SET\n      MESSAGE_TEXT = ''temptab does not exist'';\n   END;\n   SELECT c FROM temptab;\nEND;\n\nCALL test_error( );\nERROR 1146 (42S02): temptab does not exist\n`\n\n`sql\nCREATE PROCEDURE handle_error()\nBEGIN\n  RESIGNAL;\nEND;\nCREATE PROCEDURE p()\nBEGIN\n  DECLARE EXIT HANDLER FOR SQLEXCEPTION CALL p();\n  SIGNAL SQLSTATE ''45000'';\nEND;\n``\n\nURL: https://mariadb.com/docs/server/reference/sql-statements/programmatic-compound-statements/resignal', '', 'https://mariadb.com/docs/server/reference/sql-statements/programmatic-compound-statements/resignal');
INSERT INTO help_topic (help_topic_id, help_category_id, name, description, example, url) VALUES (893, 35, 'RETURN', 'Description\n-----------\n\nSyntax\n\n``sql\nRETURN expr\n`\n\nThe 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.\n\nThis statement is not used in stored procedures, triggers, or events. LEAVE can be used instead.\n\nThe following example shows that RETURN can return the result of a scalar subquery:\n\n`sql\nCREATE FUNCTION users_count() RETURNS BOOL\n   READS SQL DATA\nBEGIN\n   RETURN (SELECT COUNT(DISTINCT User) FROM mysql.user);\nEND;\n``\n\nURL: https://mariadb.com/docs/server/reference/sql-statements/programmatic-compound-statements/return', '', 'https://mariadb.com/docs/server/reference/sql-statements/programmatic-compound-statements/return');
INSERT INTO help_topic (help_topic_id, help_category_id, name, description, example, url) VALUES (894, 35, 'SELECT INTO', 'Syntax\n------\n\nSELECT col_name [, col_name] ...\n    INTO var_name [, var_name] ...\n    table_expr\n\nDescription\n-----------\n\nSELECT ... 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 useLIMIT 1 to limit the result set to a single row.\n\nThe INTO clause can also be specified at the end of the statement.\n\nIn 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\\\nWindows, to the application event log.\n\nThis statement can be used with both local variables and user-defined variables.\n\nFor the complete syntax, see SELECT.\n\nAnother way to set a variable''s value is the SET statement.\n\nSELECT ... INTO results are not stored in the query cache even if SQL_CACHE is specified.\n\nExamples\n--------\n\nSELECT id, data INTO @x,@y \nFROM test.t1 LIMIT 1;\nSELECT * FROM t1 WHERE t1.a=@x AND t1.b=@y\n\nURL: https://mariadb.com/docs/server/reference/sql-statements/programmatic-compound-statements/selectinto', '', 'https://mariadb.com/docs/server/reference/sql-statements/programmatic-compound-statements/selectinto');
INSERT INTO help_topic (help_topic_id, help_category_id, name, description, example, url) VALUES (895, 35, 'SET Variable', 'Syntax\n------\n\nSET var_name = expr [, var_name = expr] ...\n\nDescription\n-----------\n\nThe 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.\n\nThe 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.\n\nSET can be used with both local variables and user-defined variables.\n\nWhen setting several variables using the columns returned by a query, SELECT INTO should be preferred.\n\nTo set many variables to the same value, the LAST_VALUE( ) function can be used.\n\nBelow is an example of how a user-defined variable may be set:\n\n``sql\nSET @x = 1;\n``\n\nURL: https://mariadb.com/docs/server/reference/sql-statements/programmatic-compound-statements/set-variable', '', 'https://mariadb.com/docs/server/reference/sql-statements/programmatic-compound-statements/set-variable');
INSERT INTO help_topic (help_topic_id, help_category_id, name, description, example, url) VALUES (896, 35, 'SIGNAL', 'Description\n-----------\n\nSyntax\n\n``sql\nSIGNAL error_condition\n    [SET error_property\n    [, error_property] ...]\n\nerror_condition:\n    SQLSTATE [VALUE] ''sqlstate_value''\n  | condition_name\n\nerror_property:\n    error_property_name = <error_property_value>\n\nerror_property_name:\n    CLASS_ORIGIN\n  | SUBCLASS_ORIGIN\n  | MESSAGE_TEXT\n  | MYSQL_ERRNO\n  | CONSTRAINT_CATALOG\n  | CONSTRAINT_SCHEMA\n  | CONSTRAINT_NAME\n  | CATALOG_NAME\n  | SCHEMA_NAME\n  | TABLE_NAME\n  | COLUMN_NAME\n  | CURSOR_NAME\n`\n\nSIGNAL 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.\n\nSometimes 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.\n\nerror_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( ).\n\nTo 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).\n\nThe error properties, their type and their default values are explained in the diagnostics area page.\n\nErrors\n\nIf the SQLSTATE is not valid, the following error like this will be produced:\n\n`sql\nERROR 1407 (42000): Bad SQLSTATE: ''123456''\n`\n\nIf a property is specified more than once, an error like this will be produced:\n\n`sql\nERROR 1641 (42000): Duplicate condition information item ''MESSAGE_TEXT''\n`\n\nIf you specify a condition name which is not declared, an error like this will be produced:\n\n`sql\nERROR 1319 (42000): Undefined CONDITION: cond_name\n`\n\nIf MYSQL_ERRNO is out of range, you will get an error like this:\n\n`sql\nERROR 1231 (42000): Variable ''MYSQL_ERRNO'' can''t be set to the value of ''0''\n``\n\nExamples\n--------\n\nSIGNAL SQLSTATE ''01000'';\nQuery OK, 0 rows affected, 1 warning (0.00 sec)\n\nSHOW WARNINGS;\n\n+---------+------+------------------------------------------+\n| Level   | Code | Message                                  |\n+---------+------+------------------------------------------+\n| Warning | 1642 | Unhandled user-defined warning condition |\n+---------+------+------------------------------------------+\n1 row in set (0.06 sec)\n\nSIGNAL SQLSTATE ''02000'';\nERROR 1643 (02000): Unhandled user-defined not found condition\n\nURL: https://mariadb.com/docs/server/reference/sql-statements/programmatic-compound-statements/signal', '', 'https://mariadb.com/docs/server/reference/sql-statements/programmatic-compound-statements/signal');
INSERT INTO help_topic (help_topic_id, help_category_id, name, description, example, url) VALUES (897, 35, 'Using Compound Statements Outside of Stored Programs', 'Description\n-----------\n\nCompound statements can also be used outside of stored programs.\n\n``sql\ndelimiter |\nIF @have_innodb THEN\n  CREATE TABLE IF NOT EXISTS innodb_index_stats (\n    database_name    VARCHAR(64) NOT NULL,\n    table_name       VARCHAR(64) NOT NULL,\n    index_name       VARCHAR(64) NOT NULL,\n    last_update      TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,\n    stat_name        VARCHAR(64) NOT NULL,\n    stat_value       BIGINT UNSIGNED NOT NULL,\n    sample_size      BIGINT UNSIGNED,\n    stat_description VARCHAR(1024) NOT NULL,\n    PRIMARY KEY (database_name, table_name, index_name, stat_name)\n  ) ENGINE=INNODB DEFAULT CHARSET=utf8 COLLATE=utf8_bin STATS_PERSISTENT=0;\nEND IF|\nQuery OK, 0 rows affected, 2 warnings (0.00 sec)\n`\n\nUsing compound statements this way is subject to following limitations:\n\n Only BEGIN, IF, CASE, LOOP, WHILE, REPEAT statements may start a compound statement outside of stored programs.\n BEGIN must use the BEGIN NOT ATOMIC syntax (otherwise it''ll be confused with BEGIN that starts a transaction).\n A compound statement might not start with a label.\n 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.\n\nInside 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:\n\n`sql\nBEGIN NOT ATOMIC\n    DECLARE foo CONDITION FOR 1146;\n    DECLARE x INT DEFAULT 0;\n    DECLARE CONTINUE HANDLER FOR SET x=1;\n    INSERT INTO test.t1 VALUES ("hndlr1", val, 2);\n    END|\n`\n\nExample how to use IF:\n\n`sql\nIF (1>0) THEN BEGIN NOT ATOMIC SELECT 1; END ; END IF;;\n`\n\nExample of how to use WHILE loop:\n\n`sql\nDELIMITER |\nBEGIN NOT ATOMIC\n    DECLARE x INT DEFAULT 0;\n    WHILE x <= 10 DO\n        SET x = x + 1;\n        SELECT x;\n    END WHILE;\nEND|\nDELIMITER ;\n``\n\nURL: https://mariadb.com/docs/server/reference/sql-statements/programmatic-compound-statements/using-compound-statements-outside-of-stored-programs', '', 'https://mariadb.com/docs/server/reference/sql-statements/programmatic-compound-statements/using-compound-statements-outside-of-stored-programs');
INSERT INTO help_topic (help_topic_id, help_category_id, name, description, example, url) VALUES (898, 35, 'WHILE', 'Syntax\n------\n\n[begin_label:] WHILE search_condition DO\n    statement_list\nEND WHILE [end_label]\n\nDescription\n-----------\n\nThe statement list within a WHILE statement is repeated as long as thesearch_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.\n\nA 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.\n\nExamples\n--------\n\nCREATE PROCEDURE dowhile()\nBEGIN\n  DECLARE v1 INT DEFAULT 5;\n\n  WHILE v1 > 0 DO\n    ...\n    SET v1 = v1 - 1;\n  END WHILE;\nEND\n\nURL: https://mariadb.com/docs/server/reference/sql-statements/programmatic-compound-statements/while', '', 'https://mariadb.com/docs/server/reference/sql-statements/programmatic-compound-statements/while');
INSERT INTO help_topic (help_topic_id, help_category_id, name, description, example, url) VALUES (899, 35, 'Stored Routine Statements', 'Description\n-----------\n\ncall.md\n\nInvoke a stored procedure. This statement executes a previously created stored procedure, optionally passing parameters and returning results.\n\ndo.md\n\nExecute expressions without returning a result set. This statement runs functions or expressions, often used for side effects like releasing locks.\n\ncreate-procedure.md\n\nDefine a new stored procedure, specifying its name, parameters (IN, OUT, INOUT), and the SQL statements it executes.\n\nalter-procedure.md\n\nModify the characteristics of an existing stored procedure, such as its security context or comment, without changing its logic.\n\ndrop-procedure.md\n\nRemove a stored procedure and its associated privileges from the database.\n\ndrop-function.md\n\nRemove a stored function from the database, deleting its definition and associated privileges.\n\nURL: https://mariadb.com/docs/server/reference/sql-statements/stored-routine-statements/README', '', 'https://mariadb.com/docs/server/reference/sql-statements/stored-routine-statements/README');
INSERT INTO help_topic (help_topic_id, help_category_id, name, description, example, url) VALUES (900, 35, 'CALL', 'Syntax\n------\n\nCALL sp_name([parameter[,...]])\nCALL sp_name[()]\n\nDescription\n-----------\n\nThe CALL statement invokes a stored procedure that was defined previously with CREATE PROCEDURE.\n\nStored 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.\n\nCALL p() and CALL p are equivalent.\n\nIf parentheses are used, any number of spaces, tab characters and newline characters are allowed between the procedure''s name and the open parenthesis.\n\nCALL can pass back values to its caller using parameters that are declared as OUT or INOUT\\\nparameters. 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.\n\nCALL 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.\n\nWhen 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\\\nAPI, call the mysql_affected_rows() function.\n\nIf the CLIENT_MULTI_RESULTS API flag is set, CALL can return any number of result sets and the called stored procedure can execute prepared statements. If it is not set, at most one result set can be returned and prepared statements cannot be used within procedures.\n\nURL: https://mariadb.com/docs/server/reference/sql-statements/stored-routine-statements/call', '', 'https://mariadb.com/docs/server/reference/sql-statements/stored-routine-statements/call');
INSERT INTO help_topic (help_topic_id, help_category_id, name, description, example, url) VALUES (901, 35, 'DO', 'Syntax\n------\n\nDO expr [, expr] ...\n\nDescription\n-----------\n\nDO executes the expressions but does not return any results. In most respects, DO is shorthand forSELECT expr, ..., but has the advantage that it is slightly faster when you do not care about the result.\n\nDO is useful primarily with functions that have side effects, such as RELEASE_LOCK().\n\nURL: https://mariadb.com/docs/server/reference/sql-statements/stored-routine-statements/do', '', 'https://mariadb.com/docs/server/reference/sql-statements/stored-routine-statements/do');
INSERT INTO help_topic (help_topic_id, help_category_id, name, description, example, url) VALUES (902, 35, 'Table Statements', 'Description\n-----------\n\nalter\n\nAccess the reference for ALTER statements. This section lists commands to modify existing database objects, including tables, databases, users, and servers.\n\nalter-table\n\nComplete ALTER TABLE guide for MariaDB. Complete syntax for modifying columns, indexes, constraints, and table properties with comprehensive examples.\n\nanalyze-table.md\n\nAnalyze and store key distribution. This statement updates index statistics used by the optimizer to choose the best execution plan.\n\ncheck-table.md\n\nCheck tables or views for errors. This statement verifies the integrity of table structure and data for supported storage engines.\n\ncheck-view.md\n\nVerify the validity of a view''s algorithm. This statement checks if the view definition is correct and references existing tables.\n\nchecksum-table.md\n\nReport a checksum for table contents. This statement calculates a value to compare tables, useful for verifying replication consistency.\n\ncreate-table.md\n\nComplete guide to creating tables in MariaDB. Complete CREATE TABLE syntax for data types, constraints, indexes, and storage engines for production use.\n\ndelete.md\n\nComplete guide to deleting data in MariaDB. Complete DELETE syntax with WHERE filtering, JOIN operations, and safety considerations for production use.\n\ndrop-table.md\n\nComplete DROP TABLE syntax: TEMPORARY, IF EXISTS, WAIT/NOWAIT, RESTRICT/CASCADE options, metadata locks, atomic DROP, and replication behavior.\n\ninsert.md\n\nComplete guide to inserting data in MariaDB. Complete INSERT syntax for single rows, bulk operations, and ON DUPLICATE KEY handling for production use.\n\noptimize-table.md\n\nComplete MariaDB performance optimization guide. Complete reference for query tuning, indexing strategies, and configuration improvements for production use.\n\nrename-table.md\n\nChange the name of one or more tables atomically. This command moves tables within or between databases while preserving their data and structure.\n\nrepair-table.md\n\nRepair corrupted tables. This statement fixes errors in tables for supported storage engines like MyISAM, Aria, and Archive.\n\nrepair-view.md\n\nCheck and correct a view''s algorithm. This statement is primarily used by upgrade scripts to ensure view definitions are compatible.\n\nreplace.md\n\nInsert or replace rows based on unique keys. This statement acts like INSERT, but if a duplicate key exists, it deletes the old row and inserts the new one.\n\nshow-columns.md\n\nComplete guide to displaying table columns in MariaDB. Complete SHOW COLUMNS syntax with field types, keys, and filtering options for production use.\n\nshow-create-table.md\n\nGet the SQL statement to recreate a table. This statement shows the complete CREATE TABLE syntax, including column definitions and indexes.\n\nshow-index.md\n\nComplete SHOW INDEX reference: SHOW INDEX FROM _tbl_name_ syntax, output fields, and WHERE/LIKE filters.\n\ntruncate-table.md\n\nComplete TRUNCATE TABLE reference with [WAIT n|NOWAIT] syntax, InnoDB FOREIGN KEY constraints, implicit commit, and AUTO_INCREMENT reset.\n\nupdate.md\n\nComplete UPDATE statement guide for MariaDB. Complete syntax reference with WHERE conditions, JOIN operations, and multi-table updates for production use.\n\nURL: https://mariadb.com/docs/server/reference/sql-statements/table-statements/README', '', 'https://mariadb.com/docs/server/reference/sql-statements/table-statements/README');
INSERT INTO help_topic (help_topic_id, help_category_id, name, description, example, url) VALUES (903, 35, 'ANALYZE TABLE', 'Syntax\n------\n\nANALYZE [NO_WRITE_TO_BINLOG | LOCAL] TABLE tbl_name [,tbl_name ...]\n  [PERSISTENT FOR \n    { ALL\n      | COLUMNS ([col_name [,col_name ...]]) INDEXES ([index_name [,index_name ...]])\n    }\n  ]\n\nDescription\n-----------\n\nANALYZE 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.\n\nANALYZE uses histograms, which can provide a better selectivity than InnoDB statistics offer. InnoDB statistics work with a limited sample set and are therefore not as accurate as persistent statistics can be. For more information on how the analysis works within InnoDB, see InnoDB Limitations.\n\nMariaDB 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.\n\nThis statement requires SELECT and INSERT privileges for the table.\n\nBy default, ANALYZE TABLE statements are written to the binary log and will be replicated. The NO_WRITE_TO_BINLOG keyword (LOCAL is an alias) will ensure the statement is not written to the binary log.\n\nANALYZE TABLE statements are not logged to the binary log if read_only is set. See also Read-Only Slaves.\n\nANALYZE TABLE is non-blocking and non-intrusive. A connection will start using new statistics for the query following the completion of the ANALYZE TABLE.\n\nANALYZE TABLE is blocking and intrusive.\n\nANALYZE TABLE is also supported for partitioned tables. You can use ALTER TABLE ... ANALYZE PARTITION to analyze one or more partitions.\n\nThe Aria storage engine supports progress reporting for the ANALYZE TABLE statement.\n\nSkipping Long CHAR/VARCHAR Columns\n\nWhen using ANALYZE TABLE PERSISTENT, MariaDB skips long CHAR/VARCHAR columns during statistics collection if they exceed the value of the analyze_max_length system variable.\n\nThis prevents excessive disk usage when analyzing tables with large text columns.\n\n If a column is longer than analyze_max_length, it is excluded from stats.\n If a long column is explicitly specified in FOR COLUMNS(), it is still analyzed, regardless of its size.\n\nExample:\n\n``sql\nSET GLOBAL analyze_max_length = 50000;\nANALYZE TABLE large_text_table PERSISTENT;\n`\n\n`sql\nANALYZE TABLE large_text_table PERSISTENT FOR COLUMNS(long_description);\n`\n\n`sql\nCREATE TABLE product_data (\n    id INT PRIMARY KEY,\n    name VARCHAR(100),\n    description VARCHAR(50000), -- long column\n    specs VARCHAR(1000)\n);\n\n-- Set limit\nSET SESSION analyze_max_length = 10000;\n\n-- Run analysis without explicitly selecting columns\nANALYZE TABLE product_data PERSISTENT;\n\n-- ''description'' will be skipped due to length > 10000\n\n-- To include it anyway\nANALYZE TABLE product_data PERSISTENT FOR COLUMNS(description);\n`\n\nThe functionality for skipping long CHAR and VARCHAR columns isn''t available.\n\nPerformance Impact\n\nNote that analyzing tables with ANALYZE can have a performance impact and can use a lot of disk space for big tables. As column statistics usually do not change much over time, even when the table grows, there is no benefit to running ANALYZE very often.\n\nRunning ANALYZE is indicated:\n\n for newly populated tables,\n for tables that have additional columns added that are used in WHERE clauses,\n when a table has doubled in size,\n when you note that a query becomes slow because the table order has changed, and you can see from EXPLAIN or ANALYZE FORMAT=JSON that the selectivity is wrong for a table,\n when the distribution of data in a table has changed significantly, for example, if you have loaded a batch of data or deleted a large amount of data.\n\nANALYZE isn’t useful for table columns of type UNIQUE, PRIMARY KEY, TIME, or CURRENT_TIME. In ANALYZE queries, you should omit columns of those types.\n\nEITS Statistics / PERSISTENT FOR\n\nOverview\n\nANALYZE TABLE supports engine-independent table statistics (EITS). See Engine-Independent Table Statistics: Collecting Statistics with the ANALYZE TABLE Statement for more information.\n\nYou can run the statement on all columns with this statement — however, be aware that this can take a long time for very large (500+ GB) tables:\n\n`sql\nANALYZE TABLE tbl PERSISTENT FOR ALL\n`\n\nFocusing on particular columns, the statement looks like this — it collects statistics only for the specified table columns:\n\n`sql\nANALYZE TABLE tbl PERSISTENT FOR COLUMS (column1, column2, ...) INDEXES (index1, ...)\n`\n\nFocusing on columns helps, among other things, avoid including BLOB columns, for which MariaDB doesn''t collect statistics.\n\nIt''s recommended to collect statistics for columns that do _not_ have an index starting from that column (if the index starts with a column, the index itself is used as a source for statistics), and which are used in WHERE conditions of your queries.\n\nQueries That Benefit\n\nQueries that benefit most are those where the query plan depends on the optimizer knowing condition selectivities, the most important ones being JOIN queries and those with an ORDER BY ... LIMIT clause. To benefit, the query must have a condition that may or may not be selective, for example:\n\n`sql\nSELECT \nFROM orders, customer\nWHERE\n       orders.o_custkey = customer.c_custkey  -- join condition\n  AND  customer.c_area = ''EMEA''  -- (1)\n  AND  orders.o_priority= ''URGENT'' -- (2)\n`\n\nHere, the optimizer benefits from knowing these statistics:\n\n1. Which fraction of customers are in the EMEA region?\n2. Which fraction of orders are URGENT?\n\nFor that situation, you can issue this statement:\n\n`sql\nANALYZE TABLE orders, customer PERSISTENT FOR ALL\n`\n\nEITS vs. InnoDB-Internal Statistics\n\nEITS (engine-independent table statistics) provide way more data than InnoDB-internal statistics. The downside is that EITS are never automatically updated, and it takes time to collect them.\n\nInnoDB statistics, on the other hand, provide less data, but they are automatically updated.\n\nControlling Statistics\n\nEngine-independent statistics can be controlled (enabled and disabled) using the use_stat_tables variable and the optimizer_use_condition_selectivity variable. InnoDB-persistent statistics are controlled with the innodb_stats_persistent variable (allowing you to turn InnoDB statistics on or off). Combining both kinds of statistics is possible.\n\nThe server relies on InnoDB statistics by default. That way, it can use some statistics even if ANALYZE TABLE is never run (or not often enough). This gives good enough results for the majority of queries. Some queries, however, need more statistical data so the optimizer can create a good plan. Slow queries indicate there aren''t enough statistical data. Those queries can be accelerated by running ANALYZE TABLE tbl PERSISTENT FOR ..., where tbl indicates a table used by a slow query. You can also run ANALYZE TABLE ... PERSISTENT FOR ALL, but that has a significant performance impact.\n\nUseful Variables\n\nThe following overview indicates when a particular variable was introduced. When multiple versions are given, it means variable options (like the default value) changed between the indicated versions.\n\n| Variable                                                                                                                                                  | Introduced in MariaDB version                                  | Description                                                                                                                                                                                                                                                                                                                                            |\n| --------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |\n| analyze_max_length                | MariaDB 10.6.23 / 10.11.14 / 11.4.8 / 11.8.3 / 12.0.2 / 12.1.1 | Prevents the collection of column statistics for CHAR/VARCHAR columns that can be analyzed automatically by ANALYZE TABLE PERSISTENT. Columns exceeding this threshold in bytes will be skipped unless included explicitly in FOR COLUMNS(...)`. |\n| analyze_sample_percentage  | 10.4.3                                                         | Percentage of rows from the table ANALYZE TABLE will sample to collect table statistics. Set to 0 to let MariaDB decide what percentage of rows to sample.                                                                                                                                                                                             |\n| histogram_type                         | 10.4.3-11.0                                                    | Specifies the type of histograms created by ANALYZE. Options are #SINGLE_PREC_HB,DOUBLE_PREC_HB or JSON_HB.                                                                                                                                                                                                                                       |\n| histogram_size                         | 10.7                                                           | Number of bytes or buckets (in case of JSON_HB) used for storing the histogram. If set to 0, no histograms are created by ANALYZE.]]                                                                                                                                                                                                                  |\n| log_slow_admin_statements | 11.0.1                                                         | Log slow OPTIMIZE, ANALYZE, ALTER, and other administrative statements to the slow log if it is open. Deprecated. Use log_slow_filter instead.                                                                                    |\n| log_slow_filter                      | (all versions)                                                 | Having an admin in the log_slow_filter will add slow ANALYZE_TABLE statements to the slow log.                                                                                                                                                                                                                                                      |\n| sort_buffer_size                    | (all versions)                                                 | 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.                                    |\n\nExamples\n--------\n\n-- update all engine-independent statistics for all columns and indexes\nANALYZE TABLE tbl PERSISTENT FOR ALL;\n\n-- update specific columns and indexes:\nANALYZE TABLE tbl PERSISTENT FOR COLUMNS (col1,col2,...) INDEXES (idx1,idx2,...);\n\n-- empty lists are allowed:\nANALYZE TABLE tbl PERSISTENT FOR COLUMNS (col1,col2,...) INDEXES ();\nANALYZE TABLE tbl PERSISTENT FOR COLUMNS () INDEXES (idx1,idx2,...);\n\n-- the following will only update mysql.table_stats fields:\nANALYZE TABLE tbl PERSISTENT FOR COLUMNS () INDEXES ();\n\n-- when use_stat_tables is set to ''COMPLEMENTARY'' or ''PREFERABLY'', \n-- a simple ANALYZE TABLE  collects engine-independent statistics for all columns and indexes.\nSET SESSION use_stat_tables=''COMPLEMENTARY'';\nANALYZE TABLE tbl;\n\nURL: https://mariadb.com/docs/server/reference/sql-statements/table-statements/analyze-table', '', 'https://mariadb.com/docs/server/reference/sql-statements/table-statements/analyze-table');
INSERT INTO help_topic (help_topic_id, help_category_id, name, description, example, url) VALUES (904, 35, 'CHECK TABLE', 'Syntax\n------\n\nCHECK TABLE tbl_name [, tbl_name] ... [option] ...\n\noption = {FOR UPGRADE | QUICK | FAST | MEDIUM | EXTENDED | CHANGED}\n\nDescription\n-----------\n\nCHECK TABLE checks a table or tables for errors. CHECK TABLE works for Archive, Aria, CSV, InnoDB, MyISAM, and, from MariaDB 12.0, Sequence tables. For Aria and MyISAM tables, the key statistics are updated as well. For CSV, see also Checking and Repairing CSV Tables.\n\nAs an alternative, myisamchk is a command-line tool for checking MyISAM tables when the tables are not being accessed. For Aria tables, there is a similar tool: aria_chk.\n\nFor checking dynamic columns'' integrity, COLUMN_CHECK() can be used.\n\nCHECK TABLE can also check views for problems, such as tables that are referenced in the view definition that no longer exist.\n\nCHECK TABLE is also supported for partitioned tables. You can use ALTER TABLE ... CHECK PARTITION to check one or more partitions.\n\nThe meaning of the different options is as follows - note that this can vary a bit between storage engines:\n\n| Option      | Explanation                                                                                                                                                                                                                                                                        |\n| ----------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |\n| FOR UPGRADE | Do a very quick check if the storage format for the table has changed so that one needs to do a REPAIR. This is only needed when one upgrades between major versions of MariaDB or MySQL. This is usually done by running mariadb-upgrade. |\n| FAST        | 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                                                                                                       |\n| CHANGED     | Check only tables that have changed since the last REPAIR / CHECK. Only supported by the MyISAM and Aria engines. For other engines, the table is checked normally.                                                                                                            |\n| QUICK       | Do a fast check. For MyISAM and Aria, this means skipping the check of the delete link chain, which may take some time.                                                                                                                                                            |\n| MEDIUM      | Scan also the data files. Checks the integrity between data and index files with checksums. In most cases, this should find all possible errors.                                                                                                                                   |\n| EXTENDED    | Does a full check to verify every possible error. For InnoDB, Aria, and MyISAM, verify for each row that all its keys exist, and for those index keys, they point back to the primary clustered key. This may take a long time on large tables.                                    |\n\nThe EXTENDED option is available to InnoDB, too.\n\nThe EXTENDED option is ignored by InnoDB.\n\nWhen the EXTENDED option is given, MariaDB also checks for referential integrity.\n\nMariaDB does not check for referential integrity, even if the EXTENDED option is given.\n\nFor most cases, running CHECK TABLE without options or MEDIUM should be good enough.\n\nThe Aria storage engine supports progress reporting for this statement.\n\nIf you want to know if two tables are identical, take a look at CHECKSUM TABLE.\n\nInnoDB\n\nIf CHECK TABLE finds an error in an InnoDB table, MariaDB might shut down 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.\n\nEach tablespace contains a header with metadata. This header is not checked by this statement.\n\nDuring the execution of CHECK TABLE, other threads may be blocked.\n\nExamples\n--------\n\nCHECK TABLE y EXTENDED;\n+--------+-------+----------+----------+\n| Table  | Op    | Msg_type | Msg_text |\n+--------+-------+----------+----------+\n| test.y | check | status   | OK       |\n+--------+-------+----------+----------+\n\nURL: https://mariadb.com/docs/server/reference/sql-statements/table-statements/check-table', '', 'https://mariadb.com/docs/server/reference/sql-statements/table-statements/check-table');
INSERT INTO help_topic (help_topic_id, help_category_id, name, description, example, url) VALUES (905, 35, 'CHECK VIEW', 'Syntax\n------\n\nCHECK VIEW view_name\n\nDescription\n-----------\n\nThe CHECK VIEW statement checks whether the view algorithm is correct. It is run as part of mariadb-upgrade, and should not normally be required in regular use.\n\nURL: https://mariadb.com/docs/server/reference/sql-statements/table-statements/check-view', '', 'https://mariadb.com/docs/server/reference/sql-statements/table-statements/check-view');
INSERT INTO help_topic (help_topic_id, help_category_id, name, description, example, url) VALUES (906, 35, 'CHECKSUM TABLE', 'Syntax\n------\n\nCHECKSUM TABLE tbl_name [, tbl_name] ... [ QUICK | EXTENDED ]\n\nDescription\n-----------\n\nCHECKSUM TABLE reports a table checksum. This is very useful if you want to know if two tables are the same (for example on a master and a slave).\n\nWith 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.\n\nWith EXTENDED, the entire table is read row by row and the checksum is calculated. This can be very slow for large tables.\n\nIf neither QUICK nor EXTENDED is specified, MariaDB returns a live checksum if the table storage engine supports it and scans the table otherwise.\n\nCHECKSUM TABLE requires the SELECT privilege for the table.\n\nFor a nonexistent table, CHECKSUM TABLE returnsNULL and generates a warning.\n\nThe 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.\n\nTwo 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.\n\nIdentical Tables\n\nIdentical 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:\n\n* mysql56-temporal-format\n\nDifferences Between MariaDB and MySQL\n\nCHECKSUM TABLE may give a different result as MariaDB doesn''t ignore NULLs in the columns like MySQL 5.1 does (later MySQL versions should calculate checksums the same way as MariaDB).\n\nYou can get the ''old style'' checksum in MariaDB by setting old_mode to COMPAT_5_1_CHECKSUM. Note, however, that the MyISAM and Aria storage engines in MariaDB are using the new checksum internally, so if you are using this old mode, the CHECKSUM command will be slower as it needs to calculate the checksum row by row.\n\nYou can get the ''old style'' checksum in MariaDB by starting mariadbd with the --old option. Note, however, that the MyISAM and Aria storage engines in MariaDB are using the new checksum internally, so if you are using this old mode, the CHECKSUM command will be slower as it needs to calculate the checksum row by row.\n\nURL: https://mariadb.com/docs/server/reference/sql-statements/table-statements/checksum-table', '', 'https://mariadb.com/docs/server/reference/sql-statements/table-statements/checksum-table');
INSERT INTO help_topic (help_topic_id, help_category_id, name, description, example, url) VALUES (907, 35, 'BACKUP TABLE (removed)', 'Syntax\n------\n\nBACKUP TABLE tbl_name [, tbl_name] ... TO ''/path/to/backup/directory''\n\nDescription\n-----------\n\nNote: Like RESTORE TABLE, this command was not reliable and has been removed in current versions of MariaDB.\n\nFor doing a backup of MariaDB use mysqldump or MariaDB Backup. See Backing Up and Restoring.\n\nURL: https://mariadb.com/docs/server/reference/sql-statements/table-statements/obsolete-table-commands/backup-table-removed', '', 'https://mariadb.com/docs/server/reference/sql-statements/table-statements/obsolete-table-commands/backup-table-removed');
INSERT INTO help_topic (help_topic_id, help_category_id, name, description, example, url) VALUES (908, 35, 'RESTORE TABLE (removed)', 'Syntax\n------\n\nRESTORE TABLE tbl_name [, tbl_name] ... FROM ''/path/to/backup/directory''\n\nDescription\n-----------\n\nNote:\n\nLike BACKUP TABLE, this command was not reliable and has been removed from MariaDB. For doing a backup of MariaDB use mysqldump, mysqlhotcopy or XtraBackup. See Backing Up and Restoring.\n\nRESTORE TABLE restores the table or tables from a backup that was made with BACKUP TABLE. The\\\ndirectory should be specified as a full path name.\n\nExisting tables are not overwritten; if you try to restore over an existing table, an error occurs. Just as for BACKUP TABLE,RESTORE TABLE works only for MyISAM tables. Restored tables are not replicated from master to slave.\n\nThe backup for each table consists of its .frm format file and .MYD data file. The restore operation restores those files, and then uses them to rebuild the .MYI index file. Restoring takes longer than\\\nbacking up due to the need to rebuild the indexes. The more indexes the table has, the longer it takes.\n\nURL: https://mariadb.com/docs/server/reference/sql-statements/table-statements/obsolete-table-commands/restore-table-removed', '', 'https://mariadb.com/docs/server/reference/sql-statements/table-statements/obsolete-table-commands/restore-table-removed');
INSERT INTO help_topic (help_topic_id, help_category_id, name, description, example, url) VALUES (909, 35, 'REPAIR TABLE', 'Syntax\n------\n\nREPAIR [NO_WRITE_TO_BINLOG | LOCAL] TABLE\n    tbl_name [, tbl_name] ...\n    [QUICK] [EXTENDED] [USE_FRM] FORCE\n\nDescription\n-----------\n\nREPAIR TABLE repairs a possibly corrupted table. By default, it has the same effect as\n\n``sql\nmyisamchk --recover tbl_name\n`\n\nor\n\n`sql\naria_chk --recover tbl_name\n`\n\nSee [aria_chk and myisamchk for more.\n\nREPAIR 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.\n\nThis statement requires SELECT and INSERT privileges for the table.\n\nBy default, REPAIR TABLE statements are written to the binary log and will be replicated. The NO_WRITE_TO_BINLOG keyword (LOCAL is an alias) will ensure the statement is not written to the binary log.\n\nREPAIR TABLE statements are not logged to the binary log if read_only is set. See also Read-Only Slaves.\n\nREPAIR TABLE statements are logged to the binary log.\n\nWhen 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.\n\nQUICK\n\nWhen specified, REPAIR TABLE will not modify the data file, only attempting to repair the index file. The same behavior can be achieved with myisamchk --recover --quick.\n\nEXTENDED\n\nCreates the index row by row rather than sorting and creating a single index. Similar to myisamchk --safe-recover.\n\nUSE_FRM\n\nFor use only when the index file is missing or its header corrupted. MariaDB then attempts to recreate it using the .frm file. There is no equivalent myisamchk option.\n\nFORCE\n\nThe FORCE argument allows to first run internal repair to fix damaged blocks and then follow it up with ALTER TABLE (MDEV-33449).\n\nThe FORCE option is not available.\n\nPartitioned Tables\n\nREPAIR TABLE is also supported for partitioned tables with the ALTER TABLE ... REPAIR PARTITION statement. However, the USE_FRM` option cannot be used with this statement on a partitioned table. See Repairing Partitions for details.\n\nProgress Reporting\n\nThe Aria storage engine supports progress reporting for this statement.\n\nURL: https://mariadb.com/docs/server/reference/sql-statements/table-statements/repair-table', '', 'https://mariadb.com/docs/server/reference/sql-statements/table-statements/repair-table');
INSERT INTO help_topic (help_topic_id, help_category_id, name, description, example, url) VALUES (910, 35, 'REPAIR VIEW', 'Syntax\n------\n\nREPAIR [NO_WRITE_TO_BINLOG | LOCAL] VIEW  view_name[, view_name] ... [FROM MYSQL]\n\nDescription\n-----------\n\nThe REPAIR VIEW statement checks whether the view algorithm is correct. It is run as part of mariadb-upgrade, and should not normally be required in regular use.\n\nBy 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.\n\nBy 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.\n\nURL: https://mariadb.com/docs/server/reference/sql-statements/table-statements/repair-view', '', 'https://mariadb.com/docs/server/reference/sql-statements/table-statements/repair-view');
INSERT INTO help_topic (help_topic_id, help_category_id, name, description, example, url) VALUES (911, 35, 'TRUNCATE TABLE', 'Syntax\n------\n\nTRUNCATE [TABLE] tbl_name\n  [WAIT n | NOWAIT]\n\nDescription\n-----------\n\nTRUNCATE TABLE empties a table completely. It requires the DROP privilege. See GRANT.\n\ntbl_name can also be specified in the form db_name.tbl_name (see Identifier Qualifiers).\n\nLogically, TRUNCATE TABLE is equivalent to a DELETE statement that deletes all rows, but there are practical differences under some circumstances.\n\nTRUNCATE TABLE will fail for an InnoDB table if any FOREIGN KEY constraints from other tables reference the table, returning the error:\n\n``sql\nERROR 1701 (42000): Cannot truncate a table referenced in a foreign key constraint\n`\n\nForeign Key constraints between columns in the same table are permitted.\n\nFor an InnoDB table, if there are no FOREIGN KEY constraints, InnoDB performs 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.\n\nThe count of rows affected by TRUNCATE TABLE is accurate only when it is mapped to a DELETE statement.\n\nFor other storage engines, TRUNCATE TABLE differs fromDELETE in the following ways:\n\n Truncate operations drop and re-create the table, which is much faster than deleting rows one by one, particularly for large tables.\n Truncate operations cause an implicit commit.\n Truncation operations cannot be performed if the session holds an active table lock.\n 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."\n 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.\n The table handler does not remember the last used AUTO_INCREMENT value, but starts counting\\\n  from the beginning. This is true even for MyISAM and InnoDB, which normally do not reuse sequence values.\n 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.\n Since truncation of a table does not make any use of DELETE, the TRUNCATE statement does not invoke ON DELETE triggers.\n* TRUNCATE TABLE will only reset the values in the Performance Schema summary tables to zero or null, and will not remove the rows.\n\nFor the purposes of binary logging and replication, TRUNCATE TABLE is treated as DROP TABLE followed by CREATE TABLE (DDL rather than DML).\n\nTRUNCATE TABLE does not work on views. Currently, TRUNCATE TABLE drops all historical records from a system-versioned table.\n\nWAIT/NOWAIT\n\nSet the lock wait timeout. See WAIT and NOWAIT.\n\nOracle-mode\n\nOracle-mode permits the optional keywords REUSE STORAGE or DROP STORAGE to be used.\n\n`sql\nTRUNCATE [TABLE] tbl_name [{DROP | REUSE} STORAGE] [WAIT n | NOWAIT]\n`\n\nThese have no effect on the operation.\n\nPerformance\n\nTRUNCATE TABLE is faster than DELETE, because it drops and re-creates a table.\n\nWith InnoDB, TRUNCATE TABLE is slower if innodb_file_per_table=ON is set (the default). This is because TRUNCATE TABLE unlinks the underlying tablespace file, which can be an expensive operation. See MDEV-8069 for more details.\n\nThe performance issues with innodb_file_per_table=ON can be exacerbated in 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 can also help.\n\nSetting innodb_adaptive_hash_index=OFF can also improve TRUNCATE TABLE` performance in general. See MDEV-16796 for more details.\n\nURL: https://mariadb.com/docs/server/reference/sql-statements/table-statements/truncate-table', '', 'https://mariadb.com/docs/server/reference/sql-statements/table-statements/truncate-table');
INSERT INTO help_topic (help_topic_id, help_category_id, name, description, example, url) VALUES (912, 8, 'COMMIT', 'Description\n-----------\n\nThe 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.\n\nThe required syntax for the COMMIT statement is as follows:\n\n``sql\nCOMMIT [WORK] [AND [NO] CHAIN] [[NO] RELEASE]\n`\n\nCOMMIT 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).\n\nThe 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.\n\nRELEASE tells the server to disconnect the client immediately after the current transaction.\n\nThere 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.\n\nURL: https://mariadb.com/docs/server/reference/sql-statements/transactions/commit', '', 'https://mariadb.com/docs/server/reference/sql-statements/transactions/commit');
INSERT INTO help_topic (help_topic_id, help_category_id, name, description, example, url) VALUES (913, 8, 'LOCK TABLES', 'Syntax\n------\n\nLOCK TABLE[S]\n    tbl_name [[AS] alias] lock_type\n    [, tbl_name [[AS] alias] lock_type] ...\n    [WAIT n|NOWAIT]\n\nlock_type:\n    READ [LOCAL]\n  | [LOW_PRIORITY] WRITE\n  | WRITE CONCURRENT\n\nUNLOCK TABLES\n\nDescription\n-----------\n\nThe _lock_type_ can be one of:\n\n| Option              | Description                                                                                                  |\n| ------------------- | ------------------------------------------------------------------------------------------------------------ |\n| READ                | Read lock, no writes allowed                                                                                 |\n| READ LOCAL          | Read lock, but allow concurrent inserts |\n| WRITE               | Exclusive write lock. No other connections can read or write to this table                                   |\n| LOW_PRIORITY WRITE | Exclusive write lock, but allow new read locks on the table until we get the write lock.                     |\n| WRITE CONCURRENT    | Exclusive write lock, but allow READ LOCAL locks to the table.                                               |\n\nMariaDB 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.\n\nLocks may be used to emulate transactions or to get more speed when updating tables.\n\nLOCK 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.\n\nFor 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.\n\nUNLOCK TABLES explicitly releases any table locks held by the current session.\n\nAliases\n\nAliases need to correspond to the aliases used in prior SQL statements in the session. For example:\n\n``sql\nLOCK TABLE t1 AS t1_alias1 READ;\n\nSELECT  FROM t1;\nERROR 1100 (HY000): Table ''t1'' was not locked with LOCK TABLES\n\nSELECT  FROM t1 AS t1_alias2;\nERROR 1100 (HY000): Table ''t1_alias2'' was not locked with LOCK TABLES\n\nSELECT  FROM t1 AS t1_alias1;\n`\n\nWAIT/NOWAIT\n\nSet the lock wait timeout. See WAIT and NOWAIT.\n\nLimitations\n\n LOCK TABLES doesn''t work when using Galera cluster. You may experience crashes or locks when used with Galera.\n 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.\n 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.\n When using LOCK TABLES on a TEMPORARY table, it will always be locked with a WRITE lock.\n While a connection holds an explicit read lock on a table, it cannot modify it. If you try, the following error will be produced:\n\n`sql\nERROR 1099 (HY000): Table ''tab_name'' was locked with a READ lock and can''t be updated\n`\n\n 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:\n\n`sql\nERROR 1100 (HY000): Table ''tab_name'' was not locked with LOCK TABLES\n`\n\n 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:\n\n`sql\nERROR 1192 (HY000): Can''t execute the given command because you have active locked tables or an active transaction\n`\n\n* LOCK TABLES can not be used in stored routines - if you try, the following error will be produced on creation:\n\n`sql\nERROR 1314 (0A000): LOCK is not allowed in stored procedures\n``\n\nURL: https://mariadb.com/docs/server/reference/sql-statements/transactions/lock-tables', '', 'https://mariadb.com/docs/server/reference/sql-statements/transactions/lock-tables');
INSERT INTO help_topic (help_topic_id, help_category_id, name, description, example, url) VALUES (914, 8, 'Metadata Locking', 'Description\n-----------\n\nMariaDB 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.\n\nLOCK TABLES ... WRITE are also queued. Some wrong statements which produce an error may not need to wait for the lock to be freed.\n\nThe 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). If this timeout is exceeded, the following error is returned:\n\n``sql\nERROR 1205 (HY000): Lock wait timeout exceeded; try restarting transaction\n`\n\nIf the metadata_lock_info plugin is installed, the Information Schema metadata_lock_info table stores information about existing metadata locks.\n\nThe Performance Schema metadata_locks table contains metadata lock information.\n\nExample\n\nLet''s use the following MEMORY (non-transactional) table:\n\n`sql\nCREATE TABLE t (a INT) ENGINE = MEMORY;\n`\n\nConnection 1 starts a transaction, and INSERTs a row into t:\n\n`sql\nSTART TRANSACTION;\n\nINSERT INTO t SET a=1;\n`\n\nt''s metadata is now locked by connection 1. Connection 2 tries to alter t, but has to wait:\n\n`sql\nALTER TABLE t ADD COLUMN b INT;\n`\n\nConnection 2''s prompt is blocked now.\n\nNow connection 1 ends the transaction:\n\n`sql\nCOMMIT;\n`\n\n...and connection 2 finally gets the output of its command:\n\n`sql\nQuery OK, 1 row affected (35.23 sec)\nRecords: 1  Duplicates: 0  Warnings: 0\n``\n\nThe Performance Schema metadata_locks table does not contain metadata lock information.\n\nURL: https://mariadb.com/docs/server/reference/sql-statements/transactions/metadata-locking', '', 'https://mariadb.com/docs/server/reference/sql-statements/transactions/metadata-locking');
INSERT INTO help_topic (help_topic_id, help_category_id, name, description, example, url) VALUES (915, 8, 'ROLLBACK', 'Description\n-----------\n\nThe 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.\n\n``sql\nROLLBACK [ WORK ] [ AND [ NO ] CHAIN ] \n[ TO [ SAVEPOINT ] {<savepoint name> | <simple target specification>} ]\n`\n\nThe 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).\n\nThe 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:\n\n`sql\nROLLBACK; \nROLLBACK WORK; \nROLLBACK AND NO CHAIN; \nROLLBACK WORK AND NO CHAIN;\n`\n\nAll of them end a transaction without saving any transaction characteristics. The only other options, the equivalent statements ...\n\n`sql\nROLLBACK AND CHAIN;\nROLLBACK WORK AND CHAIN;\n`\n\n... both tell your DBMS to end a transaction, but to save that transaction''s characteristics for the next transaction.\n\nROLLBACK 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).\n\nROLLBACK 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.\n\nHere 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.\n\nMariaDB (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.\n\n`sql\nINSERT INTO Table_2 VALUES(5); \nDROP TABLE Table_3 CASCADE; \nROLLBACK;\n`\n\nThe result will be that both the INSERT and the DROP will go through as separate transactions so the ROLLBACK` will have no effect.\n\nURL: https://mariadb.com/docs/server/reference/sql-statements/transactions/rollback', '', 'https://mariadb.com/docs/server/reference/sql-statements/transactions/rollback');
INSERT INTO help_topic (help_topic_id, help_category_id, name, description, example, url) VALUES (916, 8, 'SAVEPOINT', 'Syntax\n------\n\nSAVEPOINT identifier\nROLLBACK [WORK] TO [SAVEPOINT] identifier\nRELEASE SAVEPOINT identifier\n\nDescription\n-----------\n\nInnoDB supports the SQL statements SAVEPOINT,ROLLBACK TO SAVEPOINT, RELEASE SAVEPOINT\\\nand the optional WORK keyword forROLLBACK.\n\nEach savepoint must have a legal MariaDB identifier. A savepoint is a named sub-transaction.\n\nNormally 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.\n\nWhen 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.\n\nWhen 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.\n\nErrors\n\nIf COMMIT or ROLLBACK is issued and no transaction was started, no error is reported.\n\nIf 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:\n\n``sql\nERROR 1305 (42000): SAVEPOINT svp_name does not exist\n``\n\nURL: https://mariadb.com/docs/server/reference/sql-statements/transactions/savepoint', '', 'https://mariadb.com/docs/server/reference/sql-statements/transactions/savepoint');
INSERT INTO help_topic (help_topic_id, help_category_id, name, description, example, url) VALUES (917, 8, 'SET TRANSACTION', 'Syntax\n------\n\nSET [GLOBAL | SESSION] TRANSACTION\n    transaction_property [, transaction_property] ...\n\ntransaction_property:\n    ISOLATION LEVEL level\n  | READ WRITE\n  | READ ONLY\n\nlevel:\n     REPEATABLE READ\n   | READ COMMITTED\n   | READ UNCOMMITTED\n   | SERIALIZABLE\n\nDescription\n-----------\n\nThis statement sets the transaction isolation level or the transaction access mode globally, for the current session, or for the next transaction:\n\n With the GLOBAL keyword, the statement sets the default transaction level globally for all subsequent sessions. Existing sessions are unaffected.\n With the SESSION keyword, the statement sets the default transaction level for all subsequent transactions performed within the current session.\n Without any SESSION or GLOBAL keyword, the statement sets the isolation level for only the next (not started) transaction performed within the current session. After that it reverts to using the session value.\n\nA 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.\n\nIsolation Level\n\nTo 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 [mariadb] section of an option file:\n\n``ini\n[mariadb]\ntransaction-isolation = REPEATABLE-READ\n`\n\nTo determine the global and session transaction isolation levels at runtime, check the value of the transaction_isolation variable.\n\nTo determine the global and session transaction isolation levels at runtime, check the value of the tx_isolation system variable.\n\n`sql\nSELECT @@GLOBAL.transaction_isolation, @@tx_isolation;\n`\n\nInnoDB supports each of the translation isolation levels described here using different locking strategies. The default level isREPEATABLE 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 innodb-locks-set.html.\n\nIsolation Levels\n\nThe following sections describe how MariaDB supports the different transaction levels.\n\nREAD UNCOMMITTED\n\nSELECT 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 likeREAD COMMITTED.\n\nREAD COMMITTED\n\nA 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 innodb-consistent-read.html.\n\nFor 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 MariaDB replication and recovery to work.\n\nIf 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\\\nduplicate-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.\n\nRows that don''t match are not being locked in a so called semiconsistent read. This means you might see only a partially consistent read when the transaction isolation level is READ COMMITTED or READ UNCOMMITTED.\n\n(A semiconsistent read applies to UPDATE and DELETE statements. Those statements skip locked rows, provided the version in the current read does not match the WHERE condition. Also, if the latest version of a record was successfully locked, but found not to match the condition, the lock is released.)\n\nREPEATABLE READ\n\nThis 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\\\nsnapshot 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\\\nalso with respect to each other. See innodb-consistent-read.html.\n\nFor 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. MariaDB does not relax the gap locking for unique indexes.\n\nFor 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.\n\nFor 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.\n\nThis is the minimum isolation level for non-distributed XA transactions.\n\nSnapshot Isolation and DML Operations\n\nThis behavior is available from MariaDB 11.6.2 and 12.3.\n\nThe innodb_snapshot_isolation system variable is enabled by default. This introduces a stricter enforcement of REPEATABLE READ for UPDATE and DELETE statements:<br>\n\n Conflict Detection: If an UPDATE or DELETE attempts to modify a row that has been changed by a concurrent transaction since your snapshot was established, the operation is rejected.\n ER_CHECKREAD (1020): This rejection triggers error ER_CHECKREAD. The revised error message suggests that the user should try restarting the transaction.\n Automatic Rollback: Unlike a simple statement error, ER_CHECKREAD is treated similarly to a deadlock: the entire transaction is rolled back.\n* Purpose: This prevents the transaction from switching to "current-read" mode for that row, which would otherwise allow the transaction to observe concurrent changes it did not make, violating the pure repeatable read invariant.\n\nTraditional Locking Behavior\n\nIf innodb_snapshot_isolation is disabled (set to OFF), InnoDB follows traditional behavior where locking reads (SELECT ... FOR UPDATE), UPDATE, and DELETE statements read the latest committed version of rows. In this mode, subsequent non-locking SELECT statements for those same rows also return the current version rather than the snapshot version, which can lead to non-repeatable read anomalies.\n\nSERIALIZABLE\n\nThis 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.)\n\nDistributed XA transactions should always use this isolation level.\n\ninnodb_snapshop_isolation\n\nIf the innodb_snapshot_isolation system variable is not set to ON, strictly-speaking anything other than READ UNCOMMITTED is not clearly defined. innodb_snapshot_isolation defaults to OFF for backwards compatibility. Setting to ON will result in attempts to acquire a lock on a record that does not exist in the current read view raising an error, and the transaction being rolled back.\n\nIf the innodb_snapshot_isolation system variable is not set to ON, strictly-speaking anything other than READ UNCOMMITTED is not clearly defined.\n\nAccess Mode\n\nThe 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, the READ_ONLY ADMIN privilege doesn''t allow writes, and DDL statements on temporary tables are not allowed either.\n\nThe 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, the SUPER privilege doesn''t allow writes, and DDL statements on temporary tables are not allowed either.\n\nIt is not permitted to specify both READ WRITE and READ ONLY in the same statement.\n\nREAD 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.\n\nExamples\n--------\n\nSET GLOBAL TRANSACTION ISOLATION LEVEL SERIALIZABLE;\n\nURL: https://mariadb.com/docs/server/reference/sql-statements/transactions/set-transaction', '', 'https://mariadb.com/docs/server/reference/sql-statements/transactions/set-transaction');
INSERT INTO help_topic (help_topic_id, help_category_id, name, description, example, url) VALUES (918, 8, 'SQL statements Causing an Implicit Commit', 'Description\n-----------\n\nSome SQL statements cause an implicit commit. As a rule of thumb, such statements are DDL statements. The same statements (except for SHUTDOWN) produce a 1400 error (SQLSTATE ''XAE09'') if a XA transaction is in effect.\n\nHere is the list:\n\n``sql\nALTER DATABASE ... UPGRADE DATA DIRECTORY NAME\nALTER EVENT\nALTER FUNCTION\nALTER PROCEDURE\nALTER SEQUENCE\nALTER SERVER\nALTER TABLE\nALTER VIEW\nANALYZE TABLE\nBEGIN\nCACHE INDEX\nCHANGE MASTER TO\nCHECK TABLE\nCREATE DATABASE\nCREATE EVENT\nCREATE FUNCTION\nCREATE INDEX\nCREATE PROCEDURE\nCREATE ROLE\nCREATE SEQUENCE\nCREATE SERVER\nCREATE TABLE\nCREATE TRIGGER\nCREATE USER\nCREATE VIEW\nDROP DATABASE\nDROP EVENT\nDROP FUNCTION\nDROP INDEX\nDROP PROCEDURE\nDROP ROLE\nDROP SEQUENCE\nDROP SERVER\nDROP TABLE\nDROP TRIGGER\nDROP USER\nDROP VIEW\nFLUSH\nGRANT\nLOAD INDEX INTO CACHE\nLOCK TABLES\nOPTIMIZE TABLE\nRENAME TABLE\nRENAME USER\nREPAIR TABLE\nRESET\nREVOKE\nSET PASSWORD\nSHUTDOWN\nSTART SLAVE\nSTART TRANSACTION\nSTOP SLAVE\nTRUNCATE TABLE\n`\n\nSET autocommit = 1 causes an implicit commit if the value was 0.\n\nAll these statements cause an implicit commit before execution. This means that, even if the statement fails with an error, the transaction is committed. Some of them, like CREATE TABLE ... SELECT, also cause a commit immediatly after execution. Such statements couldn''t be rollbacked in any case.\n\nIf you are not sure whether a statement has implicitly committed the current transaction, you can query the in_transaction server system variable.\n\nNote that when a transaction starts (not in autocommit mode), all locks acquired with LOCK TABLES are released. And acquiring such locks always commits the current transaction. To preserve the data integrity between transactional and non-transactional tables, the GET_LOCK() function can be used.\n\nExceptions\n\nThese statements do not cause an implicit commit in the following cases:\n\n CREATE TABLE and DROP TABLE, when the TEMPORARY` keyword is used.\n   However, TRUNCATE TABLE causes an implicit commit even when used on a temporary table.\n CREATE FUNCTION and DROP FUNCTION, when used to create a UDF (instead of a stored function). However, CREATE INDEX and DROP INDEX cause commits even when used with temporary tables.\n UNLOCK TABLES causes a commit only if a LOCK TABLES was used on non-transactional tables.\n\nURL: https://mariadb.com/docs/server/reference/sql-statements/transactions/sql-statements-that-cause-an-implicit-commit', '', 'https://mariadb.com/docs/server/reference/sql-statements/transactions/sql-statements-that-cause-an-implicit-commit');
INSERT INTO help_topic (help_topic_id, help_category_id, name, description, example, url) VALUES (919, 8, 'START TRANSACTION', 'Syntax\n------\n\nSTART TRANSACTION [transaction_property [, transaction_property] ...] | BEGIN [WORK]\nCOMMIT [WORK] [AND [NO] CHAIN] [[NO] RELEASE]\nROLLBACK [WORK] [AND [NO] CHAIN] [[NO] RELEASE]\nSET autocommit = {0 | 1}\n\ntransaction_property:\n    WITH CONSISTENT SNAPSHOT\n  | READ WRITE\n  | READ ONLY\n\nDescription\n-----------\n\nThe START TRANSACTION or BEGIN statement begins a new transaction. COMMIT 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.\n\nSTART TRANSACTION and SET autocommit = 1 implicitly commit the current transaction, if there is one.\n\nThe optional WORK keyword is supported forCOMMIT and ROLLBACK, as are theCHAIN 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.\n\nThe 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 suppressesCHAIN or RELEASE completion, which can be useful if the completion_type system variable is set to cause chaining or release completion by default.\n\nAccess Mode\n\nThe 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, the READ_ONLY ADMIN privilege doesn''t allow writes and DDL statements on temporary tables are not allowed either.\n\nThe 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, the SUPER privilege doesn''t allow writes and DDL statements on temporary tables are not allowed either.\n\nIt is not permitted to specify both READ WRITE and READ ONLY in the same statement.\n\nREAD 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.\n\nautocommit\n\nBy 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:\n\n``sql\nSET autocommit=0;\n`\n\nAfter disabling autocommit mode by setting the autocommit variable to zero, changes to transaction-safe tables (such as those for InnoDB orNDBCLUSTER) are not made permanent immediately. You must use COMMIT to store your changes to disk or ROLLBACK to ignore the changes.\n\nTo disable autocommit mode for a single series of statements, use the START TRANSACTION statement.\n\nDDL Statements\n\nDDL 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.\n\nTransactions cannot be used in Stored Functions or Triggers. In Stored Procedures and Events BEGIN is not allowed, so you should use START TRANSACTION instead.\n\nA 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.\n\nin_transaction\n\nThe in_transaction system variable is a session-only, read-only variable that returns 1 inside a transaction, and 0 if not in a transaction.\n\nWITH CONSISTENT SNAPSHOT\n\nThe 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.\n\nSee Enhancements for START TRANSACTION WITH CONSISTENT SNAPSHOT.\n\nExamples\n--------\n\nSTART TRANSACTION;\nSELECT @A:=SUM(salary) FROM table1 WHERE type=1;\nUPDATE table2 SET summary=@A WHERE type=1;\nCOMMIT;\n\nURL: https://mariadb.com/docs/server/reference/sql-statements/transactions/start-transaction', '', 'https://mariadb.com/docs/server/reference/sql-statements/transactions/start-transaction');
INSERT INTO help_topic (help_topic_id, help_category_id, name, description, example, url) VALUES (920, 8, 'Transaction Timeouts', 'Description\n-----------\n\nMariaDB has always had the wait_timeout and interactive_timeout settings, which close connections after a certain period of inactivity.\n\nHowever, 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.\n\nThese variables help handle this situation:\n\n idle_transaction_timeout (all transactions)\n idle_write_transaction_timeout (write transactions)\n idle_readonly_transaction_timeout (read transactions)\n\nThere is no variables for more granular control.\n\nThese 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.\n\nidle_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.\n\nExamples\n--------\n\nSET SESSION idle_transaction_timeout=2;\nBEGIN;\nSELECT  FROM t;\nEmpty set (0.000 sec)\nwait 3 seconds\nSELECT * FROM t;\nERROR 2006 (HY000): MySQL server has gone away\n\nURL: https://mariadb.com/docs/server/reference/sql-statements/transactions/transaction-timeouts', '', 'https://mariadb.com/docs/server/reference/sql-statements/transactions/transaction-timeouts');
INSERT INTO help_topic (help_topic_id, help_category_id, name, description, example, url) VALUES (921, 8, 'READ COMMITTED', 'Description\n-----------\n\nREAD COMMITTED is one of the transaction isolation levels. Each consistent read, even within the same transaction, sets and reads its own fresh snapshot.\n\nSee Isolation Levels for details.\n\nURL: https://mariadb.com/docs/server/reference/sql-statements/transactions/transactions-read-committed', '', 'https://mariadb.com/docs/server/reference/sql-statements/transactions/transactions-read-committed');
INSERT INTO help_topic (help_topic_id, help_category_id, name, description, example, url) VALUES (922, 8, 'READ UNCOMMITTED', 'Description\n-----------\n\nREAD UNCOMMITTED is one of the transaction isolation levels. SELECT statements are performed in a non-locking fashion, but a possible earlier version of a row might be used.\n\nSee Isolation Levels for details.\n\nURL: https://mariadb.com/docs/server/reference/sql-statements/transactions/transactions-read-uncommitted', '', 'https://mariadb.com/docs/server/reference/sql-statements/transactions/transactions-read-uncommitted');
INSERT INTO help_topic (help_topic_id, help_category_id, name, description, example, url) VALUES (923, 8, 'REPEATABLE READ', 'Description\n-----------\n\nREPEATABLE READ is one of the transaction isolation levels. All consistent reads within the same transaction read the snapshot established by the first read.\n\nSee Isolation Levels for details.\n\nURL: https://mariadb.com/docs/server/reference/sql-statements/transactions/transactions-repeatable-read', '', 'https://mariadb.com/docs/server/reference/sql-statements/transactions/transactions-repeatable-read');
INSERT INTO help_topic (help_topic_id, help_category_id, name, description, example, url) VALUES (924, 8, 'SERIALIZABLE', 'Description\n-----------\n\nSERIALIZABLE is one of the transaction isolation levels. Similar to REPEATABLE READ, but InnoDB implicitly converts all plain SELECT statements to SELECT ... LOCK IN SHARE MODE if autocommit is disabled.\n\nSee Isolation Levels for details.\n\nURL: https://mariadb.com/docs/server/reference/sql-statements/transactions/transactions-serializable', '', 'https://mariadb.com/docs/server/reference/sql-statements/transactions/transactions-serializable');
INSERT INTO help_topic (help_topic_id, help_category_id, name, description, example, url) VALUES (925, 8, 'UNLOCK TABLES', 'Syntax\n------\n\nUNLOCK TABLES\n\nDescription\n-----------\n\nUNLOCK TABLES explicitly releases any table locks held by the current session. See LOCK TABLES for more information.\n\nIn 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.\n\nURL: https://mariadb.com/docs/server/reference/sql-statements/transactions/transactions-unlock-tables', '', 'https://mariadb.com/docs/server/reference/sql-statements/transactions/transactions-unlock-tables');
INSERT INTO help_topic (help_topic_id, help_category_id, name, description, example, url) VALUES (926, 8, 'WAIT and NOWAIT', 'Syntax\n------\n\nALTER TABLE tbl_name [WAIT n|NOWAIT] ...\nCREATE ... INDEX ON tbl_name (index_col_name, ...) [WAIT n|NOWAIT] ...\nDROP INDEX ... [WAIT n|NOWAIT]\nDROP TABLE tbl_name [WAIT n|NOWAIT] ...\nLOCK TABLE ... [WAIT n|NOWAIT]\nOPTIMIZE TABLE tbl_name [WAIT n|NOWAIT]\nRENAME TABLE tbl_name [WAIT n|NOWAIT] ...\nSELECT ... FOR UPDATE [WAIT n|NOWAIT]\nSELECT ... LOCK IN SHARE MODE [WAIT n|NOWAIT]\nTRUNCATE TABLE tbl_name [WAIT n|NOWAIT]\n\nDescription\n-----------\n\nThe lock wait timeout can be explicitly set in the statement by using either 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.\n\nURL: https://mariadb.com/docs/server/reference/sql-statements/transactions/wait-and-nowait', '', 'https://mariadb.com/docs/server/reference/sql-statements/transactions/wait-and-nowait');
INSERT INTO help_topic (help_topic_id, help_category_id, name, description, example, url) VALUES (927, 8, 'XA Transactions', 'Description\n-----------\n\nThe 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 c193.htm.\n\nXA 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.\n\nIn MariaDB, XA transactions can only be used with storage engines that support them. At least InnoDB, TokuDB, SPIDER and MyRocks support them. XA transactions are always supported.\n\nLike regular transactions, XA transactions create metadata locks on accessed tables.\n\nXA transactions require REPEATABLE READ as a minimum isolation level. However, distributed transactions should always use SERIALIZABLE.\n\nTrying 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'').\n\nThe statements that cause an implicit COMMIT for regular transactions produce a 1400 error (SQLSTATE ''XAE09'') if a XA transaction is in effect.\n\nInternal XA vs External XA\n\nXA transactions are an overloaded term in MariaDB. If a storage engine is XA-capable, it can mean one or both of these:\n\n 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.\n 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.\n\nTransaction Coordinator Log\n\nIf you have two or more XA-capable storage engines enabled, then a transaction coordinator log must be available.\n\nThere are currently two implementations of the transaction coordinator log:\n\n Binary log-based transaction coordinator log\n Memory-mapped file-based transaction coordinator log\n\nIf the binary log is enabled on a server, then the server will use the binary log-based transaction coordinator log. Otherwise, it will use the memory-mapped file-based transaction coordinator log.\n\nSee Transaction Coordinator Log for more information.\n\nSyntax\n\n``sql\nXA {START|BEGIN} xid [JOIN|RESUME]\n\nXA END xid [SUSPEND [FOR MIGRATE]]\n\nXA PREPARE xid\n\nXA COMMIT xid [ONE PHASE]\n\nXA ROLLBACK xid\n\nXA RECOVER [FORMAT=[''RAW''|''SQL'']]\n\nxid: gtrid [, bqual [, formatID ]]\n`\n\nThe 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.\n\nWhen trying to execute an operation which is not allowed for the transaction''s current state, an error is produced:\n\n`sql\nXA COMMIT ''test'' ONE PHASE;\nERROR 1399 (XAE07): XAER_RMFAIL: The command cannot be executed when global transaction is in the  ACTIVE state\n\nXA COMMIT ''test2'';\nERROR 1399 (XAE07): XAER_RMFAIL: The command cannot be executed when global transaction is in the  NON-EXISTING state\n`\n\nXA START\n\n`sql\nXA {START|BEGIN} xid [JOIN|RESUME]\n`\n\nXA START (or BEGIN) starts a transaction and defines its xid (a transaction identifier). The new transaction will be in ACTIVE state.\n\nThe 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.\n\nUsing the JOIN or RESUME keywords will currently cause an error to be returned.\n\n`sql\nXA START ''test'' RESUME;\nERROR 1398 (XAE05): XAER_INVAL: Invalid arguments (or unsupported command)\nXA START ''test'' JOIN;\nERROR 1398 (XAE05): XAER_INVAL: Invalid arguments (or unsupported command)\n`\n\nAn exception to this is that XA START xid RESUME will resume the transaction if the xid is the same as the previous xid used in XA END xid. This simply undoes the XA END and moves it from the IDLE state back into ACTIVE.\n\n`sql\nXA START ''test'';\nINSERT INTO t VALUES (1,2);\nXA END ''test'';\nXA START ''test'' RESUME; -- This reverts the XA END and continues the transaction\nINSERT INTO t VALUES (3,4);\nXA END ''test'';\nXA PREPARE ''test'';\nXA COMMIT ''test'';\n`\n\nXA END\n\n`sql\nXA END xid [SUSPEND [FOR MIGRATE]]\n`\n\nXA END declares that the specified ACTIVE transaction is finished and it changes its state to IDLE. SUSPEND [FOR MIGRATE] has no effect.\n\nXA PREPARE\n\n`sql\nXA PREPARE xid\n`\n\nXA PREPARE prepares an IDLE transaction for commit, changing its state to PREPARED. Prepared transactions are stored persistently and will survive disconnects and server crashes, and must be explicitly committed or rolled back.\n\nPrepared transactions were automatically rolled back on client disconnect, but were not rolled back if the server was crashed or killed. This violated XA guarantees and could have caused inconsistent data, if the transaction in question was already irrevocably committed in another XA participant.\n\nPrepared transactions are automatically rolled back on client disconnect, but are not rolled back if the server was crashed or killed. This violated XA guarantees and can cause inconsistent data, if the transaction in question was already irrevocably committed in another XA participant.\n\nXA COMMIT\n\n`sql\nXA COMMIT xid [ONE PHASE]\n`\n\nXA 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.\n\nXA ROLLBACK\n\n`sql\nXA ROLLBACK xid\n`\n\nXA ROLLBACK rolls back and terminates an IDLE or PREPARED transaction.\n\nXA RECOVER\n\n`sql\nXA RECOVER [FORMAT=[''RAW''|''SQL'']]\n`\n\nThe 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.\n\nXA RECOVER produces four columns:\n\n`sql\nXA RECOVER;\n+----------+--------------+--------------+------+\n| formatID | gtrid_length | bqual_length | data |\n+----------+--------------+--------------+------+\n|        1 |            4 |            0 | test |\n+----------+--------------+--------------+------+\n`\n\nYou 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.\n\nformatID is the formatID part of xid.\n\ndata are the gtrid and bqual parts of xid, concatenated.\n\ngtrid_length and bqual_length are the lengths of gtrid and bqual`, respectively.\n\nExamples\n--------\n\nXA START ''test'';\n\nINSERT INTO t VALUES (1,2);\n\nXA END ''test'';\n\nXA PREPARE ''test'';\n\nXA COMMIT ''test'';\n\nURL: https://mariadb.com/docs/server/reference/sql-statements/transactions/xa-transactions', '', 'https://mariadb.com/docs/server/reference/sql-statements/transactions/xa-transactions');
INSERT INTO help_topic (help_topic_id, help_category_id, name, description, example, url) VALUES (928, 34, 'Geometry Hierarchy', 'Description\n-----------\n\nGeometry 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\\\ncoordinate 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).\n\nThe base Geometry class has subclasses for Point, Curve, Surface, and GeometryCollection:\n\n Point represents zero-dimensional objects.\n Curve represents one-dimensional objects, and has a subclass LineString, with sub-subclasses Line and LinearRing.\n Surface is designed for two-dimensional objects and has a subclass Polygon.\n 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.\n\nGeometry, 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.\n\nPoint, LineString, Polygon, GeometryCollection, MultiPoint,MultiLineString, and MultiPolygon are instantiable classes.\n\nURL: https://mariadb.com/docs/server/reference/sql-structure/geometry/geometry-hierarchy', '', 'https://mariadb.com/docs/server/reference/sql-structure/geometry/geometry-hierarchy');
INSERT INTO help_topic (help_topic_id, help_category_id, name, description, example, url) VALUES (929, 34, 'Geometry Types', 'Description\n-----------\n\nMariaDB provides a standard way of creating spatial columns for geometry types, for example, with CREATE TABLE or ALTER TABLE. Spatial columns are supported for MyISAM, InnoDB and ARCHIVE\\\ntables. See also SPATIAL INDEX.\n\nThe basic geometry type is GEOMETRY, but the type can be more specific. The following types are supported:\n\n POINT\n LINESTRING\n POLYGON\n MULTIPOINT\n MULTILINESTRING\n MULTIPOLYGON\n GEOMETRYCOLLECTION\n GEOMETRY\n\nExamples\n--------\n\nCREATE TABLE object (shapeA POLYGON, shapeB LINESTRING);\n\nURL: https://mariadb.com/docs/server/reference/sql-structure/geometry/geometry-types', '', 'https://mariadb.com/docs/server/reference/sql-structure/geometry/geometry-types');
INSERT INTO help_topic (help_topic_id, help_category_id, name, description, example, url) VALUES (930, 34, 'GIS Features', 'Description\n-----------\n\nGIS stands for Geographic Information System.\n\nMySQL operates on spatial data based on the OpenGIS standards, particularly the OpenGIS SFS (Simple feature access, SQL option).\n\nInitial support was based on version 05-134 of the standard. MariaDB implements a subset of the ''SQL with Geometry Types'' environment proposed by the OGC. And the SQL environment was extended with a set of geometry types.\n\nMariaDB supports spatial extensions to operate on spatial features. These features are available for Aria, MyISAM, InnoDB, NDB, and ARCHIVE tables.\n\nFor spatial columns, Aria and MyISAM supports both SPATIAL and non-SPATIAL indexes. Other storage engines support non-SPATIAL indexes.\n\nWe aim at meeting the OpenGIS requirements. One thing missed in previous MariaDB versions is that the functions which check spatial relations didn''t consider the actual shape of an object, instead they operate only on their bounding rectangles. These legacy functions have been left as they are and new, properly-working functions are named with an ''ST_'' prefix, in accordance with the latest OpenGIS requirements. Also, operations over geometry features were added.\n\nSpatial Operators\n\nSpatial operators produce new geometries.\n\n| Name                                                                                                            | Description                                                                    |\n| --------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------ |\n| ST_UNION(A, B)                 | union of A and B                                                               |\n| ST_INTERSECTION(A, B)   | intersection of A and B                                                        |\n| ST_SYMDIFFERENCE(A, B) | symdifference, notintersecting parts of A and B                                |\n| ST_BUFFER(A, radius)          | returns the shape of the area that lies in ''radius'' distance from the shape A. |\n\nPredicates\n\nPredicates return a boolean result of the relationship.\n\n| Name                                                                                                   | Description                     |\n| ------------------------------------------------------------------------------------------------------ | ------------------------------- |\n| ST_INTERSECTS(A, B) | if A and B have an intersection |\n| ST_CROSSES(A, B)       | if A and B cross                |\n| ST_EQUALS(A, B)         | if A and B are equal            |\n| ST_WITHIN(A, B)         | if A lies within B              |\n| ST_CONTAINS(A,B)      | if B lies within A              |\n| ST_DISJOINT(A,B)      | if A and B have no intersection |\n| ST_TOUCHES(A,B)        | if A touches B                  |\n\nURL: https://mariadb.com/docs/server/reference/sql-structure/geometry/gis-features-in-533', '', 'https://mariadb.com/docs/server/reference/sql-structure/geometry/gis-features-in-533');
INSERT INTO help_topic (help_topic_id, help_category_id, name, description, example, url) VALUES (931, 34, 'GIS Resources', 'Description\n-----------\n\nGIS stands for Geographic Information System.\n\nFurther reading:\n\n OGC Simple Feature Access - the Open Geospatial Consortium''s OpenGIS Simple Features Specifications For SQL.\n Geo/Spatial Search with MySQL - a presentation by Alexander Rubin, from the MySQL Conference in 2006.\n\nThere are no differences between GIS in stable versions of MariaDB and GIS in MySQL. There are, however, some extensions and enhancements being worked on.\n\nURL: https://mariadb.com/docs/server/reference/sql-structure/geometry/gis-resources', '', 'https://mariadb.com/docs/server/reference/sql-structure/geometry/gis-resources');
INSERT INTO help_topic (help_topic_id, help_category_id, name, description, example, url) VALUES (932, 34, 'SPATIAL INDEX', 'Description\n-----------\n\nOn 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. Columns in spatial indexes must be declared NOT NULL.\n\nSpatial indexes can be created when the table is created, or added after the fact:\n\n``sql\nCREATE TABLE geom (g GEOMETRY NOT NULL, SPATIAL INDEX(g));\n`\n\n`sql\nALTER TABLE geom ADD SPATIAL INDEX(g);\n`\n\n`sql\nCREATE SPATIAL INDEX sp_index ON geom (g);\n`\n\nSPATIAL 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\\\nexact-value lookups, but not for range scans.\n\nFor more information on indexing spatial columns, see CREATE INDEX.\n\nTo drop spatial indexes, use ALTER TABLE or DROP INDEX:\n\n`sql\nALTER TABLE geom DROP INDEX g;\n`\n\n`sql\nDROP INDEX sp_index ON geom;\n`\n\nData-at-Rest Encryption\n\nIf innodb_checksum_algorithm is set to full_crc32 or strict_full_crc32`, and if the table does not use ROW_FORMAT=COMPRESSED, InnoDB spatial indexes are encrypted if the table is encrypted.\n\nSee MDEV-12026 for more information.\n\nURL: https://mariadb.com/docs/server/reference/sql-structure/geometry/spatial-index', '', 'https://mariadb.com/docs/server/reference/sql-structure/geometry/spatial-index');
INSERT INTO help_topic (help_topic_id, help_category_id, name, description, example, url) VALUES (933, 35, 'Joins, Subqueries, and Set', 'Description\n-----------\n\nSQL (Structured Query Language) is a highly potent language used in the realm of databases and data analytics. It allows us to create, manipulate, and retrieve data stored in relational databases. While simple SQL commands can handle straightforward tasks, one must delve into advanced aspects such as multiple joins, subqueries, and set operations to unravel the full potential of SQL.\n\nMultiple Joins\n\nJoins are fundamental to SQL, as they enable us to combine rows from two or more tables based on related columns. Several types of joins exist, including INNER JOIN, LEFT JOIN, RIGHT JOIN, and FULL JOIN.\n\nIn real-world scenarios, finding database schemas with multiple tables linked through relationships is common. In such cases, we often need to write SQL queries with multiple joins to fetch the required data.\n\nFor instance, consider a database for a bookstore with three tables: Books, Authors, and Publishers. If we want to get a list of books along with their author names and publishers, you would require multiple joins.\n\n``sql\nSELECT Books.title, Authors.name, Publishers.name\nFROM Books\nINNER JOIN Authors ON Books.author_id = Authors.id\nINNER JOIN Publishers ON Books.publisher_id = Publishers.id;\n`\n\nIn that query, we used two INNER JOIN operations to combine data from the three tables.\n\nSubqueries\n\nA subquery, also known as a nested query or inner query, is a query embedded within another SQL query. The result of the subquery can be used in the outer query. Subqueries can be used in SELECT, INSERT, UPDATE, and DELETE statements and also in conjunction with WHERE and HAVING clauses.\n\nSubqueries can prove powerful in many scenarios. For example, suppose we want to find books that are above the average price in our bookstore database. We could achieve this using a subquery.\n\n`sql\nSELECT title, price\nFROM Books\nWHERE price > (SELECT AVG(price) FROM Books);\n`\n\nIn this query, the subquery calculates the average book price, which the outer query then uses to filter books that are priced above average.\n\nSet Operations\n\nSQL also provides several set operations to combine rows from two or more tables, including UNION, UNION ALL, INTERSECT, and EXCEPT. These operations are instrumental when dealing with large databases where data is spread across multiple tables and we need to perform set-based operations.\n\nFor example, suppose we have two tables, _Books_2019_ and _Books_2020_, listing the books sold in the respective years. If we want to find books sold in both years, we can use the INTERSECT operation.\n\n`sql\nSELECT title FROM Books_2019\nINTERSECT\nSELECT title FROM Books_2020;\n``\n\nIn the above query, INTERSECT returns the common book titles sold in both 2019 and 2020.\n\nConclusion\n\nAdvanced SQL queries that involve multiple joins, subqueries, and set operations can be daunting at first glance. However, these incredibly powerful tools in our SQL toolkit enable us to craft complex data retrieval and manipulation commands. To truly excel in data analytics, mastering these aspects of SQL is not only beneficial but essential.\n\nRemember, practice is the key to mastering these advanced SQL concepts, like any other technical skill. Write queries, solve problems, make mistakes, and learn from them. Over time, you''ll find yourself not only comfortable but proficient in creating intricate SQL queries.\n\nURL: https://mariadb.com/docs/server/reference/sql-structure/joins-subqueries-set', '', 'https://mariadb.com/docs/server/reference/sql-structure/joins-subqueries-set');
INSERT INTO help_topic (help_topic_id, help_category_id, name, description, example, url) VALUES (934, 35, 'NoSQL', 'Description\n-----------\n\ndynamic-columns.md\n\ndynamic-column-api.md\n\nhandler\n\nhandlersocket\n\njson-functions\n\ncassandra\n\nconnect\n\nURL: https://mariadb.com/docs/server/reference/sql-structure/nosql/README', '', 'https://mariadb.com/docs/server/reference/sql-structure/nosql/README');

INSERT INTO help_topic (help_topic_id, help_category_id, name, description, example, url) VALUES (936, 35, 'Dynamic Columns', 'Description\n-----------\n\nDynamic 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.\n\nDynamic columns should be used when it is not possible to use regular columns.\n\nA 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.\n\nDynamic Columns Basics\n\nThe table should have a blob column which will be used as storage for dynamic columns:\n\n``sql\nmain\nCREATE TABLE assets (\n  item_name VARCHAR(32) PRIMARY KEY, -- A common attribute for all items\n  dynamic_cols  BLOB  -- Dynamic columns will be stored here\n);\n`\n\nOnce created, you can access dynamic columns via dynamic column functions.\n\nInsert a row with two dynamic columns: color=blue, size=XL:\n\n`sql\nINSERT INTO assets VALUES \n  (''MariaDB T-shirt'', COLUMN_CREATE(''color'', ''blue'', ''size'', ''XL''));\n`\n\nInsert another row with dynamic columns: color=black, price=500:\n\n`sql\nINSERT INTO assets VALUES\n  (''Thinkpad Laptop'', COLUMN_CREATE(''color'', ''black'', ''price'', 500));\n`\n\nSelect the dynamic column ''color'' for all items:\n\n`sql\nSELECT item_name, COLUMN_GET(dynamic_cols, ''color'' as char) \n  AS color FROM assets;\n+-----------------+-------+\n| item_name       | color |\n+-----------------+-------+\n| MariaDB T-shirt | blue  |\n| Thinkpad Laptop | black |\n+-----------------+-------+\n`\n\nIt is possible to add and remove dynamic columns from a row:\n\n`sql\n-- Remove a column:\nUPDATE assets SET dynamic_cols=COLUMN_DELETE(dynamic_cols, "price") \nWHERE COLUMN_GET(dynamic_cols, ''color'' AS CHAR)=''black''; \n\n-- Add a column:\nUPDATE assets SET dynamic_cols=COLUMN_ADD(dynamic_cols, ''warranty'', ''3 years'')\nWHERE item_name=''Thinkpad Laptop'';\n`\n\nYou can also list all columns, or get them together with their values in JSON format:\n\n`sql\nSELECT item_name, column_list(dynamic_cols) FROM assets;\n+-----------------+---------------------------+\n| item_name       | column_list(dynamic_cols) |\n+-----------------+---------------------------+\n| MariaDB T-shirt | size,color            |\n| Thinkpad Laptop | color,warranty        |\n+-----------------+---------------------------+\n\nSELECT item_name, COLUMN_JSON(dynamic_cols) FROM assets;\n+-----------------+----------------------------------------+\n| item_name       | COLUMN_JSON(dynamic_cols)              |\n+-----------------+----------------------------------------+\n| MariaDB T-shirt | {"size":"XL","color":"blue"}           |\n| Thinkpad Laptop | {"color":"black","warranty":"3 years"} |\n+-----------------+----------------------------------------+\n`\n\nDynamic Columns Reference\n\nThis is a complete reference of dynamic columns in MariaDB.\n\nColumn can be referred to by name (column_name in the following code blocks). This is the preferred method.\\\nIf you need support for old (< 10.0) MariaDB versions, you have to refer to columns by number. In that case, replace _column_name_ with _column_nr_. This method is not recommended.\n\nDynamic Columns Functions\n\nCOLUMN_CREATE\n\n`sql\nCOLUMN_CREATE(column_name, value [as type], [column_name, value \n  [as type]]...);\n`\n\nReturns a dynamic columns blob that stores the specified columns with values. The return value is suitable for\n\n storing in a table,\n further modification with other dynamic columns functions.\n\nThe 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.\n\nTypical usage:\n\n`sql\nINSERT INTO tbl SET dyncol_blob=COLUMN_CREATE("column_name", "value");\n`\n\nCOLUMN_ADD\n\n`sql\nCOLUMN_ADD(dyncol_blob, column_name, value [as type], \n  [column_name, value [as type]]...);\n`\n\nAdds or updates dynamic columns.\n\n dyncol_blob must be either a valid dynamic columns blob (for example, COLUMN_CREATE returns such blob), or an empty string.\n 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.\n value specifies the new value for the column. Passing a NULL value will cause the column to be deleted.\n as type is optional. See the datatypes section for a discussion about types.\n\nThe return value is a dynamic column blob after the modifications.\n\nTypical usage:\n\n`sql\nUPDATE t1 SET dyncol_blob=COLUMN_ADD(dyncol_blob, "column_name", "value") \n  WHERE id=1;\n`\n\nNote: 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.\n\nCOLUMN_GET\n\n`sql\nCOLUMN_GET(dyncol_blob, column_name as type);\n`\n\nRetrieves the value of a dynamic column by its name. If no column with the given name exists, NULL is returned.\n\ncolumn_name as type requires that one specify the datatype of the dynamic column they are reading.\n\nThis may seem counter-intuitive: Why would you need to specify which datatype they''re retrieving? Can''t the dynamic columns system figure the datatype from the data being stored?\n\nThe 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).\n\nSee the Datatypes section for more information about datatypes.\n\nCOLUMN_DELETE\n\n`sql\nCOLUMN_DELETE(dyncol_blob, column_name, column_name...);\n`\n\nDeletes a dynamic column with the specified name. Multiple names can be given.\n\nThe return value is a dynamic column blob after the modification.\n\nCOLUMN_EXISTS\n\n`sql\nCOLUMN_EXISTS(dyncol_blob, column_name);\n`\n\nChecks if a column with name column_name exists in dyncol_blob. If yes, return 1, otherwise return 0.\n\nCOLUMN_LIST\n\n`sql\nCOLUMN_LIST(dyncol_blob);\n`\n\nReturns a comma-separated list of column names. The names are quoted with backticks.\n\n`sql\nSELECT column_list(column_create(''col1'',''val1'',''col2'',''val2''));\n+---------------------------------------------------------+\n| column_list(column_create(''col1'',''val1'',''col2'',''val2'')) |\n+---------------------------------------------------------+\n| col1,col2                                           |\n+---------------------------------------------------------+\n`\n\nCOLUMN_CHECK\n\n`sql\nCOLUMN_CHECK(dyncol_blob);\n`\n\nChecks if dyncol_blob is a valid packed dynamic columns blob. A return value of 1 means the blob is valid, a return value of 0 means it is not.\n\nRationale:\\\nNormally, you work with valid dynamic column blobs. Functions likeCOLUMN_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 is corrupted. This function can be used to check if a value in a blob field is a valid dynamic column blob.\n\nIt is possible that a truncation cuts a Dynamic Column "clearly" so that COLUMN_CHECK does not notice the corruption, but, in any case of truncation, a warning is issued during value storing.\n\nCOLUMN_JSON\n\n`sql\nCOLUMN_JSON(dyncol_blob);\n`\n\nReturns a JSON representation of data in dyncol_blob :\n\n`sql\nSELECT item_name, COLUMN_JSON(dynamic_cols) FROM assets;\n+-----------------+----------------------------------------+\n| item_name       | COLUMN_JSON(dynamic_cols)              |\n+-----------------+----------------------------------------+\n| MariaDB T-shirt | {"size":"XL","color":"blue"}           |\n| Thinkpad Laptop | {"color":"black","warranty":"3 years"} |\n+-----------------+----------------------------------------+\n`\n\nLimitation: COLUMN_JSON decodes nested dynamic columns at a nesting level of not more than 10 levels deep. Dynamic columns that are nested deeper than 10 levels are shown as a BINARY string, without encoding.\n\nNesting Dynamic Columns\n\nIt is possible to use nested dynamic columns by putting one dynamic column blob inside another. The COLUMN_JSON function will display nested columns.\n\n`sql\nSET @tmp= column_create(''parent_column'', \n  column_create(''child_column'', 12345));\nQuery OK, 0 rows affected (0.00 sec)\n\nSELECT column_json(@tmp);\n+------------------------------------------+\n| column_json(@tmp)                        |\n+------------------------------------------+\n| {"parent_column":{"child_column":12345}} |\n+------------------------------------------+\n\nSELECT column_get(column_get(@tmp, ''parent_column'' AS char), \n  ''child_column'' AS int);\n+------------------------------------------------------------------------------+\n| column_get(column_get(@tmp, ''parent_column'' as char), ''child_column'' as int) |\n+------------------------------------------------------------------------------+\n|                                                                        12345 |\n+------------------------------------------------------------------------------+\n`\n\nIf 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:\n\n`sql\nSELECT column_json( column_get(\n  column_create(''test1'', \n    column_create(''key1'',''value1'',''key2'',''value2'',''key3'',''value3'')),\n  ''test1'' AS BINARY));\n`\n\nDatatypes\n\nIn 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.\n\nThe set of possible datatypes is mostly the same as that used by the CAST and CONVERT functions. However, note that there are currently some differences - see MDEV-597.\n\n| Type                | Dynamic column internal type | Description                                                                                                                 |\n| ------------------- | ---------------------------- | --------------------------------------------------------------------------------------------------------------------------- |\n| BINARY\\[(N)]        | DYN_COL_STRING             | (variable length string with binary charset)                                                                                |\n| CHAR\\[(N)]          | DYN_COL_STRING             | (variable length string with charset)                                                                                       |\n| DATE                | DYN_COL_DATE               | (date - 3 bytes)                                                                                                            |\n| DATETIME\\[(D)]      | DYN_COL_DATETIME           | (date and time (with microseconds) - 9 bytes)         |\n| DECIMAL\\[(M\\[,D])]  | DYN_COL_DECIMAL            | (variable length binary decimal representation with MariaDB limitation)                                                     |\n| DOUBLE\\[(M,D)]      | DYN_COL_DOUBLE             | (64 bit double-precision floating point)                                                                                    |\n| INTEGER             | DYN_COL_INT                | (variable length, up to 64-bit signed integer)                                                                              |\n| SIGNED \\[INTEGER]   | DYN_COL_INT                | (variable length, up to 64-bit signed integer)                                                                              |\n| TIME\\[(D)]          | DYN_COL_TIME               | (time (with microseconds, may be negative) - 6 bytes) |\n| UNSIGNED \\[INTEGER] | DYN_COL_UINT               | (variable length, up to 64bit unsigned integer)                                                                             |\n\nA Note About Lengths\n\nIf you''re running queries without specifying a maximum length (i.e. using #as CHAR#, not as CHAR(n)), MariaDB reports the maximum length of the result set column to be53,6870,911 (bytes or characters?). This may cause excessive memory usage in some client libraries, because they try to pre-allocate a buffer of maximum result set width. If you suspect you''re hitting this problem, use CHAR(n)\\\nwhenever you''re using COLUMN_GET in the select list.\n\n`sql\nSELECT COLUMN_GET(blob, ''colname'' as CHAR) ...\n`\n\nClient-side API\n\nIt 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.\n\nLimitations\n\n| Description                                   | Limit                                                                                                                                           |\n| --------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------- |\n| Max number of columns                         | 65535                                                                                                                                           |\n| Maximum total length of packed dynamic column | max_allowed_packet (1G) |\n\nURL: https://mariadb.com/docs/server/reference/sql-structure/nosql/dynamic-columns', '', 'https://mariadb.com/docs/server/reference/sql-structure/nosql/dynamic-columns');
INSERT INTO help_topic (help_topic_id, help_category_id, name, description, example, url) VALUES (937, 35, 'HANDLER', 'Syntax\n------\n\nHANDLER tbl_name OPEN [ [AS] alias]\nHANDLER tbl_name READ index_name { = | >= | <= | < } (value1,value2,...)\n    [ WHERE where_condition ] [LIMIT ... ]\nHANDLER tbl_name READ index_name { FIRST | NEXT | PREV | LAST }\n    [ WHERE where_condition ] [LIMIT ... ]\nHANDLER tbl_name READ { FIRST | NEXT }\n    [ WHERE where_condition ] [LIMIT ... ]\nHANDLER tbl_name CLOSE\n\nDescription\n-----------\n\nThe 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).\n\nHANDLER ... OPEN opens a table, allowing it to be accessible to subsequent HANDLER ... READ statements. The table can either be opened using an alias, or a table name. If opened with an alias, references to this table by further HANDLER statements must use this alias, and not the table name. If opened with a table name qualified by database name, further references to this table must use the unqualified table name. For example, if a table is opened with db1.t1, further references must use t1.\n\nThe table object is only closed when HANDLER ... CLOSE is called by the session, or the session closes, and is not shared by other sessions.\n\nPrepared 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).\n\nThe HANDLER command does not work with partitioned tables.\n\nKey Lookup\n\nA key lookup is started with:\n\n``sql\nHANDLER tbl_name READ index_name { = | >= | <= | < }  (value,value) [LIMIT...]\n`\n\nThe 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 its columns.\n\nIf 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.\n\nAfter the initial read, you can use the following to scan rows in key order:\n\n`sql\nHANDLER tbl_name READ index_name NEXT [ LIMIT ... ]\nor\nHANDLER tbl_name READ index_name PREV [ LIMIT ... ]\n`\n\nNote that the row order is not defined for keys with duplicated values, and will vary from engine to engine.\n\nKey Scans\n\nYou can scan a table in key order by doing this:\n\n`sql\nHANDLER tbl_name READ index_name FIRST [ LIMIT ... ]\nHANDLER tbl_name READ index_name NEXT  [ LIMIT ... ]\n`\n\nAlternatively, if the handler supports backwards key scans (which most do), you can use this:\n\n`sql\nHANDLER tbl_name READ index_name LAST [ LIMIT ... ]\nHANDLER tbl_name READ index_name PREV [ LIMIT ... ]\n`\n\nTable Scans\n\nYou can scan a table in row order by doing this:\n\n`sql\nHANDLER tbl_name READ FIRST [ LIMIT ... ]\nHANDLER tbl_name READ NEXT  [ LIMIT ... ]\n`\n\nLimitations\n\nAs 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 are some of the common limitations.\n\nFinding ''Old Rows''\n\nHANDLER READ is not transaction-safe, consistent or atomic. It''s okay for the storage engine to return 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.\n\nYou may also find rows committed since the scan originally started.\n\nInvisible Columns\n\nHANDLER ... READ also reads the data of invisible columns.\n\nSystem-Versioned Tables\n\nHANDLER ... 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.\n\nOther Limitations\n\n If you do an ALTER TABLE, all your HANDLERs for that table are automatically closed.\n If you do an ALTER TABLE for a table that is used by some other connection with HANDLER, the ALTER TABLE query waits for the HANDLER to be closed.\n For HASH keys, you must use all key parts when searching for a row.\n For HASH keys, you can''t do a key scan of all values. You can only find all rows with the same key value.\n While each HANDLER READ command is atomic, if you do a scan in many steps, 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.\n\nError Codes\n\n Error 1031 (ER_ILLEGAL_HA) Table storage engine for ''t1'' doesn''t have this option\n   If you get this for HANDLER OPEN it means the storage engine doesn''t support HANDLER calls.\n   If you get this for HANDLER READ , it means you are trying to use an incomplete HASH key.\n Error 1020 (ER_CHECKREAD`) Record has changed since last read in table ''...''\n   This means that the table changed between two reads, and the handler can''t handle this case for the given scan.\n\nExamples\n--------\n\nCREATE TABLE t1 (f1 INT);\n\nINSERT INTO t1 VALUES (1),(2),(3);\n\nHANDLER t1 OPEN;\n\nHANDLER t1 READ NEXT;\n+------+\n| f1   |\n+------+\n|    1 |\n+------+\n\nHANDLER t1 READ NEXT;\n+------+\n| f1   |\n+------+\n|    2 |\n+------+\n\nURL: https://mariadb.com/docs/server/reference/sql-structure/nosql/handler/handler-commands', '', 'https://mariadb.com/docs/server/reference/sql-structure/nosql/handler/handler-commands');
INSERT INTO help_topic (help_topic_id, help_category_id, name, description, example, url) VALUES (938, 35, 'HANDLER for MEMORY Tables', 'Description\n-----------\n\nThis article explains how to use HANDLER commands efficiently with MEMORY/HEAP tables.\n\nIf you want to scan a table for different key values, not just search for exact key values, you should create your keys with USING BTREE:\n\n``sql\nCREATE TABLE t1 (a INT, b INT, KEY(a), KEY b USING BTREE (b)) ENGINE=memory;\n`\n\nIn 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.\n\nThe limitations for HANDLER READ with MEMORY|HEAP tables are:\n\nLimitations for HASH keys\n\n You must use all key parts when searching for a row.\n You can''t do a key scan of all values. You can only find all rows with the same key value.\n READ NEXT gives an error 1031 if the tables changed since last read.\n\nLimitations for BTREE keys\n\n READ NEXT gives an error 1031 if the tables changed since last read. This limitation can be lifted in the future.\n\nLimitations for table scans\n\n* READ NEXT gives an error 1031 if the table was truncated since last READ` call.\n\nURL: https://mariadb.com/docs/server/reference/sql-structure/nosql/handler/handler-for-memory-tables', '', 'https://mariadb.com/docs/server/reference/sql-structure/nosql/handler/handler-for-memory-tables');
INSERT INTO help_topic (help_topic_id, help_category_id, name, description, example, url) VALUES (939, 35, 'HandlerSocket Client Libraries', 'Description\n-----------\n\nIn order to make use of the HandlerSocket plugin in your applications, you will need to use the appropriate client library. The following client libraries are available:\n\n C++\n   libhsclient (included with the HandlerSocket plugin source)\n Perl\n   perl-Net-HandlerSocket (included with the HandlerSocket plugin source)\n PHP\n   Net_HandlerSocket\n   HSPHP\n   php-ext-handlersocketi\n Java\n   hs4j\n   handlersocketforjava\n Python\n   python-handler-socket\n   pyhandlersocket\n Ruby\n   ruby-handlersocket\n   handlersocket\n JavaScript\n   node-handlersocket\n Scala\n   hs2client\n Haskell\n  * HandlerSocket-Haskell-Client\n\nURL: https://mariadb.com/docs/server/reference/sql-structure/nosql/handlersocket/handlersocket-client-libraries', '', 'https://mariadb.com/docs/server/reference/sql-structure/nosql/handlersocket/handlersocket-client-libraries');
INSERT INTO help_topic (help_topic_id, help_category_id, name, description, example, url) VALUES (940, 35, 'HandlerSocket Configuration Options', 'Description\n-----------\n\nThe HandlerSocket plugin has the following options.\n\nSee also the Full list of MariaDB options, system and status variables.\n\nAdd the options to the [mysqld] section of your my.cnf file.\n\nhandlersocket_accept_balance\n\n Description: When set to a value other than zero (''0''), handlersocket will try to balance accepted connections among threads. Default is 0 , but if you use persistent connections (for example if you use client-side connection pooling), a non-zero value is recommended.\n Command line: --handlersocket-accept-balance="value"\n Scope: Global\n Dynamic: No\n Type: number\n Range: 0 to 10000\n Default Value: 0\n\nhandlersocket_address\n\n Description: Specify the IP address to bind to.\n Command line: --handlersocket-address="value"\n Scope: Global\n Dynamic: No\n Type: IP Address\n Default Value: Empty, previously 0.0.0.0\n\nhandlersocket_backlog\n\n Description: Specify the listen backlog length.\n Command line: --handlersocket-backlog="value"\n Scope: Global\n Dynamic: No\n Type: number\n Range: 5 to 1000000\n Default Value: 32768\n\nhandlersocket_epoll\n\n Description: Specify whether to use epoll for I/O multiplexing.\n Command line: --handlersocket-epoll="value"\n Scope: Global\n Dynamic: No\n Type: number\n Valid values:\n   Min: 0\n   Max: 1\n Default Value: 1\n\nhandlersocket_plain_secret\n\n Description: When set, enables plain-text authentication for the listener for read requests, with the value of the option specifying the secret authentication key.\n Command line: --handlersocket-plain-secret="value"\n Dynamic: No\n Type: string\n Default Value: Empty\n\nhandlersocket_plain_secret_wr\n\n Description: When set, enables plain-text authentication for the listener for write requests, with the value of the option specifying the secret authentication key.\n Command line: --handlersocket-plain-secret-wr="value"\n Dynamic: No\n Type: string\n Default Value: Empty\n\nhandlersocket_port\n\n Description: Specify the port to bind to for reads. An empty value disables the listener.\n Command line: --handlersocket-port="value"\n Scope: Global\n Dynamic: No\n Type: number\n Default Value: Empty, previously 9998\n\nhandlersocket_port_wr\n\n Description: Specify the port to bind to for writes. An empty value disables the listener.\n Command line: --handlersocket-port-wr="value"\n Scope: Global\n Dynamic: No\n Type: number\n Default Value: Empty, previously 9999\n\nhandlersocket_rcvbuf\n\n Description: Specify the maximum socket receive buffer (in bytes). If ''0'' then the system default is used.\n Command line: --handlersocket-rcvbuf="value"\n Scope: Global\n Dynamic: No\n Type: number\n Range: 0 to 1677216\n Default Value: 0\n\nhandlersocket_readsize\n\n Description: Specify the minimum length of the request buffer. Larger values consume available memory but can make handlersocket faster for large requests.\n Command line: --handlersocket-readsize="value"\n Scope: Global\n Dynamic: No\n Type: number\n Range: 0 to 1677216\n Default Value: 0 (possibly 4096)\n\nhandlersocket_sndbuf\n\n Description: Specify the maximum socket send buffer (in bytes). If ''0'' then the system default is used.\n Command line: --handlersocket-sndbuf="value"\n Scope: Global\n Dynamic: No\n Type: number\n Range: 0 to 1677216\n Default Value: 0\n\nhandlersocket_threads\n\n Description: Specify the number of worker threads for reads. \\\n  Recommended value = number of CPU cores \\ 2.\n Command line: --handlersocket-threads="value"\n Scope: Global\n Dynamic: No\n Type: number\n Range: 1 to 3000\n Default Value: 16\n\nhandlersocket_threads_wr\n\n Description: Specify the number of worker threads for writes. Recommended value = 1.\n Command line: --handlersocket-threads-wr="value"\n Scope: Global\n Dynamic: No\n Type: number\n Range: 1 to 3000\n Default Value: 1\n\nhandlersocket_timeout\n\n Description: Specify the socket timeout in seconds.\n Command line: --handlersocket-timeout="value"\n Scope: Global\n Dynamic: No\n Type: number\n Range: 30 to 3600\n Default Value: 300\n\nhandlersocket_verbose\n\n Description: Specify the logging verbosity.\n Command line: --handlersocket-verbose="value"\n Scope: Global\n Dynamic: No\n Type: number\n Valid values:\n   Min: 0\n   Max: 10000\n Default Value: 10\n\nhandlersocket_wrlock_timeout\n\n Description: The write lock timeout in seconds. When acting on write requests, handlersocket locks an advisory lock named ''handlersocket_wr'' and this option sets the timeout for it.\n Command line: --handlersocket-wrlock-timeout="value"\n Scope: Global\n Dynamic: No\n Type: number\n* Range: 0 to 3600\n\nURL: https://mariadb.com/docs/server/reference/sql-structure/nosql/handlersocket/handlersocket-configuration-options', '', 'https://mariadb.com/docs/server/reference/sql-structure/nosql/handlersocket/handlersocket-configuration-options');
INSERT INTO help_topic (help_topic_id, help_category_id, name, description, example, url) VALUES (941, 35, 'HandlerSocket External Resources', 'Description\n-----------\n\nSome resources and documentation about HandlerSocket.\n\n The home of HandlerSocket is here.\n The story of handlersocket can be found here.\n Comparison of HANDLER and HandlerSocket can be found here.\n HandlerSocket plugin for MySQL presentation by Akira Higuchi of DeNA - June 29 2010 - DeNA Technology Seminar\n* HandlerSocket plugin for MySQL presentation by Akira Higuchi of DeNA - June 29 2011 - in Japanese\n\nURL: https://mariadb.com/docs/server/reference/sql-structure/nosql/handlersocket/handlersocket-external-resources', '', 'https://mariadb.com/docs/server/reference/sql-structure/nosql/handlersocket/handlersocket-external-resources');
INSERT INTO help_topic (help_topic_id, help_category_id, name, description, example, url) VALUES (942, 35, 'HandlerSocket Installation', 'Description\n-----------\n\nAfter MariaDB is installed, use the INSTALL PLUGIN command (as the root user) to install\\\nthe HandlerSocket plugin. This command only needs to be run once, like so:\n\n``sql\nINSTALL PLUGIN handlersocket SONAME ''handlersocket.so'';\n`\n\nAfter installing the plugin, SHOW PROCESSLIST shows you first need to configure some settings. All HandlerSocket configuration options are placed in the [mysqld] section of your my.cnf file.\n\nAt least the handlersocket_address, handlersocket_port and handlersocket_port_wr options need to be set:\n\n`ini\nhandlersocket_address="127.0.0.1"\nhandlersocket_port="9998"\nhandlersocket_port_wr="9999"\n``\n\nAfter updating the configuration options, restart MariaDB.\n\nOn the client side, to make use of the plugin you will need to install the appropriate client library (that is,  libhsclient for C++ applications and perl-Net-HandlerSocket for perl applications).\n\nURL: https://mariadb.com/docs/server/reference/sql-structure/nosql/handlersocket/handlersocket-installation', '', 'https://mariadb.com/docs/server/reference/sql-structure/nosql/handlersocket/handlersocket-installation');
INSERT INTO help_topic (help_topic_id, help_category_id, name, description, example, url) VALUES (943, 38, 'Addition Operator (+)', 'Syntax\n------\n\n+\n\nDescription\n-----------\n\nAddition.\n\nIf both operands are integers, the result is calculated with BIGINT precision. If either integer is unsigned, the result is also an unsigned integer.\n\nFor real or string operands, the operand with the highest precision determines the result precision.\n\nExamples\n--------\n\nSELECT 3+5;\n+-----+\n| 3+5 |\n+-----+\n|   8 |\n+-----+\n\nURL: https://mariadb.com/docs/server/reference/sql-structure/operators/arithmetic-operators/addition-operator', '', 'https://mariadb.com/docs/server/reference/sql-structure/operators/arithmetic-operators/addition-operator');
INSERT INTO help_topic (help_topic_id, help_category_id, name, description, example, url) VALUES (944, 38, 'Division Operator (/)', 'Syntax\n------\n\n/\n\nDescription\n-----------\n\nDivision 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.\n\nDividing by zero returns NULL. If the default ERROR_ON_DIVISION_BY_ZERO SQL_MODE is used, a division by zero also produces a warning.\n\nExamples\n--------\n\nSELECT 4/5;\n+--------+\n| 4/5    |\n+--------+\n| 0.8000 |\n+--------+\n\nSELECT 300/(2-2);\n+-----------+\n| 300/(2-2) |\n+-----------+\n|      NULL |\n+-----------+\n\nSELECT 300/7;\n+---------+\n| 300/7   |\n+---------+\n| 42.8571 |\n+---------+\n\nURL: https://mariadb.com/docs/server/reference/sql-structure/operators/arithmetic-operators/division-operator', '', 'https://mariadb.com/docs/server/reference/sql-structure/operators/arithmetic-operators/division-operator');
INSERT INTO help_topic (help_topic_id, help_category_id, name, description, example, url) VALUES (945, 38, 'Modulo Operator (%)', 'Syntax\n------\n\nN % M\n\nDescription\n-----------\n\nModulo operator. Returns the remainder of N divided by M. See also MOD.\n\nExamples\n--------\n\nSELECT 1042 % 50;\n+-----------+\n| 1042 % 50 |\n+-----------+\n|        42 |\n+-----------+\n\nURL: https://mariadb.com/docs/server/reference/sql-structure/operators/arithmetic-operators/modulo-operator', '', 'https://mariadb.com/docs/server/reference/sql-structure/operators/arithmetic-operators/modulo-operator');
INSERT INTO help_topic (help_topic_id, help_category_id, name, description, example, url) VALUES (946, 38, 'Multiplication Operator (\\*)', 'Syntax\n------\n\nDescription\n-----------\n\nMultiplication operator.\n\nExamples\n--------\n\nSELECT 76;\n+-----+\n| 76 |\n+-----+\n|  42 |\n+-----+\n\nSELECT 12345678909876543210;\n+-----------------------+\n| 12345678909876543210 |\n+-----------------------+\n|  -6253480962446024716 |\n+-----------------------+\n\nSELECT 1801439850948198418014398509481984.0;\n+---------------------------------------+\n| 1801439850948198418014398509481984.0 |\n+---------------------------------------+\n|   324518553658426726783156020576256.0 |\n+---------------------------------------+\n\nSELECT 1801439850948198418014398509481984;\n+-------------------------------------+\n| 18014398509481984*18014398509481984 |\n+-------------------------------------+\n|                                   0 |\n+-------------------------------------+\n\nURL: https://mariadb.com/docs/server/reference/sql-structure/operators/arithmetic-operators/multiplication-operator', '', 'https://mariadb.com/docs/server/reference/sql-structure/operators/arithmetic-operators/multiplication-operator');
INSERT INTO help_topic (help_topic_id, help_category_id, name, description, example, url) VALUES (947, 38, 'Subtraction Operator (-)', 'Syntax\n------\n\n-\n\nDescription\n-----------\n\nSubtraction. The operator is also used as the unary minus for changing sign.\n\nIf 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.\n\nFor real or string operands, the operand with the highest precision determines the result precision.\n\nExamples\n--------\n\nSELECT 96-9;\n+------+\n| 96-9 |\n+------+\n|   87 |\n+------+\n\nSELECT 15-17;\n+-------+\n| 15-17 |\n+-------+\n|    -2 |\n+-------+\n\nSELECT 3.66 + 1.333;\n+--------------+\n| 3.66 + 1.333 |\n+--------------+\n|        4.993 |\n+--------------+\n\nURL: https://mariadb.com/docs/server/reference/sql-structure/operators/arithmetic-operators/subtraction-operator', '', 'https://mariadb.com/docs/server/reference/sql-structure/operators/arithmetic-operators/subtraction-operator');
INSERT INTO help_topic (help_topic_id, help_category_id, name, description, example, url) VALUES (948, 38, 'Assignment Operator (:=)', 'Syntax\n------\n\nvar_name := expr\n\nDescription\n-----------\n\nAssignment operator for assigning a value. The value on the right is assigned to the variable on left.\n\nUnlike the = operator, := can always be used to assign a value to a variable.\n\nThis operator works with both user-defined variables and local variables.\n\nWhen assigning the same value to several variables, LAST_VALUE() can be useful.\n\nExamples\n--------\n\nSELECT @x := 10;\n+----------+\n| @x := 10 |\n+----------+\n|       10 |\n+----------+\n\nSELECT @x, @y := @x;\n+------+----------+\n| @x   | @y := @x |\n+------+----------+\n|   10 |       10 |\n+------+----------+\n\nURL: https://mariadb.com/docs/server/reference/sql-structure/operators/assignment-operators/assignment-operator', '', 'https://mariadb.com/docs/server/reference/sql-structure/operators/assignment-operators/assignment-operator');
INSERT INTO help_topic (help_topic_id, help_category_id, name, description, example, url) VALUES (949, 38, 'Assignment Operator (=)', 'Syntax\n------\n\nidentifier = expr\n\nDescription\n-----------\n\nThe equal sign is used as both an assignment operator in certain contexts, and 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.\n\nSince 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\n\nThis operator works with both user-defined variables and local variables.\n\nExamples\n--------\n\nUPDATE table_name SET x = 2 WHERE x > 100;\n\nURL: https://mariadb.com/docs/server/reference/sql-structure/operators/assignment-operators/assignment-operators-assignment-operator', '', 'https://mariadb.com/docs/server/reference/sql-structure/operators/assignment-operators/assignment-operators-assignment-operator');
INSERT INTO help_topic (help_topic_id, help_category_id, name, description, example, url) VALUES (950, 38, 'BETWEEN AND', 'Syntax\n------\n\nexpr BETWEEN min AND max\n\nDescription\n-----------\n\nIf expr is greater than or equal to min and expr is less than or equal to max, 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.\n\nExamples\n--------\n\nSELECT 1 BETWEEN 2 AND 3;\n+-------------------+\n| 1 BETWEEN 2 AND 3 |\n+-------------------+\n|                 0 |\n+-------------------+\n\nURL: https://mariadb.com/docs/server/reference/sql-structure/operators/comparison-operators/between-and', '', 'https://mariadb.com/docs/server/reference/sql-structure/operators/comparison-operators/between-and');
INSERT INTO help_topic (help_topic_id, help_category_id, name, description, example, url) VALUES (951, 38, 'COALESCE', 'Syntax\n------\n\nCOALESCE(value,...)\n\nDescription\n-----------\n\nReturns the first non-NULL value in the list, or NULL if there are no non-NULL values. At least one parameter must be passed.\n\nThe function is useful when substituting a default value for null values when displaying data.\n\nSee also NULL Values in MariaDB.\n\nExamples\n--------\n\nSELECT COALESCE(NULL,1);\n+------------------+\n| COALESCE(NULL,1) |\n+------------------+\n|                1 |\n+------------------+\n\nURL: https://mariadb.com/docs/server/reference/sql-structure/operators/comparison-operators/coalesce', '', 'https://mariadb.com/docs/server/reference/sql-structure/operators/comparison-operators/coalesce');
INSERT INTO help_topic (help_topic_id, help_category_id, name, description, example, url) VALUES (952, 38, '=', 'Syntax\n------\n\nleft_expr = right_expr\n\nDescription\n-----------\n\nEqual 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.\n\nWhen used in row comparisons these two queries are synonymous and return the same results:\n\n``sql\nSELECT (t1.a, t1.b) = (t2.x, t2.y) FROM t1 INNER JOIN t2;\n\nSELECT (t1.a = t2.x) AND (t1.b = t2.y) FROM t1 INNER JOIN t2;\n`\n\nTo perform a NULL-safe comparison, use the <=> operator.\n\n=` can also be used as an assignment operator.\n\nExamples\n--------\n\nSELECT 1 = 0;\n+-------+\n| 1 = 0 |\n+-------+\n|     0 |\n+-------+\n\nSELECT ''0'' = 0;\n+---------+\n| ''0'' = 0 |\n+---------+\n|       1 |\n+---------+\n\nSELECT ''0.0'' = 0;\n+-----------+\n| ''0.0'' = 0 |\n+-----------+\n|         1 |\n+-----------+\n\nSELECT ''0.01'' = 0;\n+------------+\n| ''0.01'' = 0 |\n+------------+\n|          0 |\n+------------+\n\nSELECT ''.01'' = 0.01;\n+--------------+\n| ''.01'' = 0.01 |\n+--------------+\n|            1 |\n+--------------+\n\nSELECT (5  2) = CONCAT(''1'', ''0'');\n+----------------------------+\n| (5  2) = CONCAT(''1'', ''0'') |\n+----------------------------+\n|                          1 |\n+----------------------------+\n\nSELECT 1 = NULL;\n+----------+\n| 1 = NULL |\n+----------+\n|     NULL |\n+----------+\n\nSELECT NULL = NULL;\n+-------------+\n| NULL = NULL |\n+-------------+\n|        NULL |\n+-------------+\n\nURL: https://mariadb.com/docs/server/reference/sql-structure/operators/comparison-operators/equal', '', 'https://mariadb.com/docs/server/reference/sql-structure/operators/comparison-operators/equal');
INSERT INTO help_topic (help_topic_id, help_category_id, name, description, example, url) VALUES (953, 38, '>=', 'Syntax\n------\n\n>=\n\nDescription\n-----------\n\nGreater 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.\n\nWhen used in row comparisons, these two queries return the same results:\n\n``sql\nSELECT (t1.a, t1.b) >= (t2.x, t2.y) \nFROM t1 INNER JOIN t2;\n\nSELECT (t1.a > t2.x) OR ((t1.a = t2.x) AND (t1.b >= t2.y))\nFROM t1 INNER JOIN t2;\n``\n\nExamples\n--------\n\nSELECT 2 >= 2;\n+--------+\n| 2 >= 2 |\n+--------+\n|      1 |\n+--------+\n\nSELECT ''A'' >= ''a'';\n+------------+\n| ''A'' >= ''a'' |\n+------------+\n|          1 |\n+------------+\n\nURL: https://mariadb.com/docs/server/reference/sql-structure/operators/comparison-operators/greater-than-or-equal', '', 'https://mariadb.com/docs/server/reference/sql-structure/operators/comparison-operators/greater-than-or-equal');
INSERT INTO help_topic (help_topic_id, help_category_id, name, description, example, url) VALUES (954, 38, '>', 'Syntax\n------\n\n>\n\nDescription\n-----------\n\nGreater 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.\n\nWhen used in row comparisons these two queries return the same results:\n\n``sql\nSELECT (t1.a, t1.b) > (t2.x, t2.y) \nFROM t1 INNER JOIN t2;\n\nSELECT (t1.a > t2.x) OR ((t1.a = t2.x) AND (t1.b > t2.y))\nFROM t1 INNER JOIN t2;\n``\n\nExamples\n--------\n\nSELECT 2 > 2;\n+-------+\n| 2 > 2 |\n+-------+\n|     0 |\n+-------+\n\nSELECT ''b'' > ''a'';\n+-----------+\n| ''b'' > ''a'' |\n+-----------+\n|         1 |\n+-----------+\n\nURL: https://mariadb.com/docs/server/reference/sql-structure/operators/comparison-operators/greater-than', '', 'https://mariadb.com/docs/server/reference/sql-structure/operators/comparison-operators/greater-than');
INSERT INTO help_topic (help_topic_id, help_category_id, name, description, example, url) VALUES (955, 38, 'GREATEST', 'Syntax\n------\n\nGREATEST(value1,value2,...)\n\nDescription\n-----------\n\nWith two or more arguments, returns the largest (maximum-valued) argument. The arguments are compared using the same rules as for LEAST().\n\nExamples\n--------\n\nSELECT GREATEST(2,0);\n+---------------+\n| GREATEST(2,0) |\n+---------------+\n|             2 |\n+---------------+\n\nURL: https://mariadb.com/docs/server/reference/sql-structure/operators/comparison-operators/greatest', '', 'https://mariadb.com/docs/server/reference/sql-structure/operators/comparison-operators/greatest');
INSERT INTO help_topic (help_topic_id, help_category_id, name, description, example, url) VALUES (956, 38, 'IN', 'Syntax\n------\n\nexpr IN (value,...)\n\nDescription\n-----------\n\nReturns 1 if _expr_ is equal to any of the values in the IN list, else returns 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\\\nusing 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\\\napplied to all the arguments.\n\nIf _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.\n\nExamples\n--------\n\nSELECT 2 IN (0,3,5,7);\n+----------------+\n| 2 IN (0,3,5,7) |\n+----------------+\n|              0 |\n+----------------+\n\nURL: https://mariadb.com/docs/server/reference/sql-structure/operators/comparison-operators/in', '', 'https://mariadb.com/docs/server/reference/sql-structure/operators/comparison-operators/in');
INSERT INTO help_topic (help_topic_id, help_category_id, name, description, example, url) VALUES (957, 38, 'INTERVAL', 'Syntax\n------\n\nINTERVAL(N0,N1,N2,N3,...)\n\nDescription\n-----------\n\nReturns the index of the last argument that is less than or equal to the first argument, or is NULL.\n\nReturns 0 if N0 < N1, 1 if N1 <= N0 < N2, 2 if N2 <= N0 < N3 and so on or -1 if N0 is NULL. All arguments are treated as integers. It is required that N1 <= N2 <= N3 <= ... <= Nn for this function to work correctly because a fast binary search is used.\n\nExamples\n--------\n\nSELECT INTERVAL(22, 24, 26, 28);\n\nURL: https://mariadb.com/docs/server/reference/sql-structure/operators/comparison-operators/interval', '', 'https://mariadb.com/docs/server/reference/sql-structure/operators/comparison-operators/interval');
INSERT INTO help_topic (help_topic_id, help_category_id, name, description, example, url) VALUES (958, 38, 'IS JSON', 'Description\n-----------\n\nThe IS JSON predicate checks whether a given string expression evaluates to valid JSON data in accordance with the SQL:2016 standard (based on RFC 8259).&#x20;\n\nThe predicate returns:\n\n 1  (TRUE) if the JSON expression is valid and satisfies any type constraint that is specified (e.g., OBJECT, ARRAY)\n 0 (FALSE) if the expression is not valid JSON or does not match the  specified type constraints\n &#x20;NULL (UNKNOWN) if the JSON expression itself evaluates to NULL\n\nWhen the value is invalid JSON, the predicate does not show errors. Any valid JSON value is accepted since VALUE is considered when no type constraint is mentioned.\n\nType Constraints\n\nTo limit the permitted top-level JSON value, use the optional type constraints listed below:\n\n| Type     | Description                                                                   |\n| -------- | ----------------------------------------------------------------------------- |\n| VALUE  | Any valid JSON value (object, array, number, string, true, false, null) |\n| ARRAY  | Only JSON arrays (e.g., [1,2,3]                                             |\n| OBJECT | Only JSON objects (e.g., {"key": "value"} = {"a": "42"})                      |\n| SCALAR | A JSON scalar value (strings, numbers, Boolean, or null)                    |\n\nUnique Keys\n\nThe object keys must be unique in order to use WITH UNIQUE KEYS option. WITHOUT UNIQUE KEYS, duplicate keys are accepted.&#x20;\n\nNotes\n\n JSON Validation is based on RFC 8259.\n JSON literal names must be all lowercase: true, false, null.\n Other literal names are not permitted.\n* IS JSON works in in generated columns, CHECK constraints, and DEFAULT expressions.\n\nURL: https://mariadb.com/docs/server/reference/sql-structure/operators/comparison-operators/is-json', '', 'https://mariadb.com/docs/server/reference/sql-structure/operators/comparison-operators/is-json');
INSERT INTO help_topic (help_topic_id, help_category_id, name, description, example, url) VALUES (959, 38, 'IS NOT NULL', 'Syntax\n------\n\nIS NOT NULL\n\nDescription\n-----------\n\nTests whether a value is not NULL. See also NULL Values in MariaDB.\n\nExamples\n--------\n\nSELECT 1 IS NOT NULL, 0 IS NOT NULL, NULL IS NOT NULL;\n+---------------+---------------+------------------+\n| 1 IS NOT NULL | 0 IS NOT NULL | NULL IS NOT NULL |\n+---------------+---------------+------------------+\n|             1 |             1 |                0 |\n+---------------+---------------+------------------+\n\nURL: https://mariadb.com/docs/server/reference/sql-structure/operators/comparison-operators/is-not-null', '', 'https://mariadb.com/docs/server/reference/sql-structure/operators/comparison-operators/is-not-null');
INSERT INTO help_topic (help_topic_id, help_category_id, name, description, example, url) VALUES (960, 38, 'IS NOT', 'Syntax\n------\n\nIS NOT boolean_value\n\nDescription\n-----------\n\nTests a value against a boolean value, where boolean_value can be TRUE, FALSE, or UNKNOWN.\n\nExamples\n--------\n\nSELECT 1 IS NOT UNKNOWN, 0 IS NOT UNKNOWN, NULL IS NOT UNKNOWN;\n+------------------+------------------+---------------------+\n| 1 IS NOT UNKNOWN | 0 IS NOT UNKNOWN | NULL IS NOT UNKNOWN |\n+------------------+------------------+---------------------+\n|                1 |                1 |                   0 |\n+------------------+------------------+---------------------+\n\nURL: https://mariadb.com/docs/server/reference/sql-structure/operators/comparison-operators/is-not', '', 'https://mariadb.com/docs/server/reference/sql-structure/operators/comparison-operators/is-not');
INSERT INTO help_topic (help_topic_id, help_category_id, name, description, example, url) VALUES (961, 38, 'IS NULL', 'Syntax\n------\n\nIS NULL\n\nDescription\n-----------\n\nTests whether a value is NULL. See also NULL Values in MariaDB.\n\nExamples\n--------\n\nSELECT 1 IS NULL, 0 IS NULL, NULL IS NULL;\n+-----------+-----------+--------------+\n| 1 IS NULL | 0 IS NULL | NULL IS NULL |\n+-----------+-----------+--------------+\n|         0 |         0 |            1 |\n+-----------+-----------+--------------+\n\nURL: https://mariadb.com/docs/server/reference/sql-structure/operators/comparison-operators/is-null', '', 'https://mariadb.com/docs/server/reference/sql-structure/operators/comparison-operators/is-null');
INSERT INTO help_topic (help_topic_id, help_category_id, name, description, example, url) VALUES (962, 38, 'IS', 'Syntax\n------\n\nIS boolean_value\n\nDescription\n-----------\n\nTests a value against a boolean value, where boolean_value can be TRUE, FALSE, or UNKNOWN.\n\nThere 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.\n\nExamples\n--------\n\nSELECT 1 IS TRUE, 0 IS FALSE, NULL IS UNKNOWN;\n+-----------+------------+-----------------+\n| 1 IS TRUE | 0 IS FALSE | NULL IS UNKNOWN |\n+-----------+------------+-----------------+\n|         1 |          1 |               1 |\n+-----------+------------+-----------------+\n\nURL: https://mariadb.com/docs/server/reference/sql-structure/operators/comparison-operators/is', '', 'https://mariadb.com/docs/server/reference/sql-structure/operators/comparison-operators/is');
INSERT INTO help_topic (help_topic_id, help_category_id, name, description, example, url) VALUES (963, 38, 'ISNULL', 'Syntax\n------\n\nISNULL(expr)\n\nDescription\n-----------\n\nIf _expr_ is NULL, ISNULL() returns 1, otherwise it returns 0.\n\nSee also NULL Values in MariaDB.\n\nExamples\n--------\n\nSELECT ISNULL(1+1);\n+-------------+\n| ISNULL(1+1) |\n+-------------+\n|           0 |\n+-------------+\n\nSELECT ISNULL(1/0);\n+-------------+\n| ISNULL(1/0) |\n+-------------+\n|           1 |\n+-------------+\n\nURL: https://mariadb.com/docs/server/reference/sql-structure/operators/comparison-operators/isnull', '', 'https://mariadb.com/docs/server/reference/sql-structure/operators/comparison-operators/isnull');
INSERT INTO help_topic (help_topic_id, help_category_id, name, description, example, url) VALUES (964, 38, 'LEAST', 'Syntax\n------\n\nLEAST(value1,value2,...)\n\nDescription\n-----------\n\nWith two or more arguments, returns the smallest (minimum-valued) argument. The arguments are compared using the following rules:\n\n If the return value is used in an INTEGER context or all arguments are integer-valued, they are compared as integers.\n If the return value is used in a REAL context or all arguments are real-valued, they are compared as reals.\n If any argument is a case-sensitive string, the arguments are compared as case-sensitive strings.\n In all other cases, the arguments are compared as case-insensitive strings.\n\nLEAST() returns NULL if any argument is NULL.\n\nExamples\n--------\n\nSELECT LEAST(2,0);\n+------------+\n| LEAST(2,0) |\n+------------+\n|          0 |\n+------------+\n\nURL: https://mariadb.com/docs/server/reference/sql-structure/operators/comparison-operators/least', '', 'https://mariadb.com/docs/server/reference/sql-structure/operators/comparison-operators/least');
INSERT INTO help_topic (help_topic_id, help_category_id, name, description, example, url) VALUES (965, 38, '<=', 'Syntax\n------\n\n<=\n\nDescription\n-----------\n\nLess 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.\n\nWhen used in row comparisons these two queries return the same results:\n\n``sql\nSELECT (t1.a, t1.b) <= (t2.x, t2.y) \nFROM t1 INNER JOIN t2;\n\nSELECT (t1.a < t2.x) OR ((t1.a = t2.x) AND (t1.b <= t2.y))\nFROM t1 INNER JOIN t2;\n``\n\nExamples\n--------\n\nSELECT 0.1 <= 2;\n+----------+\n| 0.1 <= 2 |\n+----------+\n|        1 |\n+----------+\n\nURL: https://mariadb.com/docs/server/reference/sql-structure/operators/comparison-operators/less-than-or-equal', '', 'https://mariadb.com/docs/server/reference/sql-structure/operators/comparison-operators/less-than-or-equal');
INSERT INTO help_topic (help_topic_id, help_category_id, name, description, example, url) VALUES (966, 38, '<', 'Syntax\n------\n\n<\n\nDescription\n-----------\n\nLess 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.\n\nWhen used in row comparisons, these two queries return the same results:\n\n``sql\nSELECT (t1.a, t1.b) < (t2.x, t2.y) \nFROM t1 INNER JOIN t2;\n\nSELECT (t1.a < t2.x) OR ((t1.a = t2.x) AND (t1.b < t2.y))\nFROM t1 INNER JOIN t2;\n``\n\nExamples\n--------\n\nSELECT 2 < 2;\n+-------+\n| 2 < 2 |\n+-------+\n|     0 |\n+-------+\n\nURL: https://mariadb.com/docs/server/reference/sql-structure/operators/comparison-operators/less-than', '', 'https://mariadb.com/docs/server/reference/sql-structure/operators/comparison-operators/less-than');
INSERT INTO help_topic (help_topic_id, help_category_id, name, description, example, url) VALUES (967, 38, 'NOT BETWEEN', 'Syntax\n------\n\nexpr NOT BETWEEN min AND max\n\nDescription\n-----------\n\nThis is the same as NOT (expr BETWEEN min AND max).\n\nNote that the meaning of the alternative form NOT expr BETWEEN min AND max is affected by the HIGH_NOT_PRECEDENCE SQL_MODE flag.\n\nExamples\n--------\n\nSELECT 1 NOT BETWEEN 2 AND 3;\n+-----------------------+\n| 1 NOT BETWEEN 2 AND 3 |\n+-----------------------+\n|                     1 |\n+-----------------------+\n\nURL: https://mariadb.com/docs/server/reference/sql-structure/operators/comparison-operators/not-between', '', 'https://mariadb.com/docs/server/reference/sql-structure/operators/comparison-operators/not-between');
INSERT INTO help_topic (help_topic_id, help_category_id, name, description, example, url) VALUES (968, 38, '!=', 'Syntax\n------\n\n<>, !=\n\nDescription\n-----------\n\nNot 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.\n\nWhen used in row comparisons these two queries return the same results:\n\n``sql\nSELECT (t1.a, t1.b) != (t2.x, t2.y) \nFROM t1 INNER JOIN t2;\n\nSELECT (t1.a != t2.x) OR (t1.b != t2.y)\nFROM t1 INNER JOIN t2;\n``\n\nExamples\n--------\n\nSELECT ''.01'' <> ''0.01'';\n+-----------------+\n| ''.01'' <> ''0.01'' |\n+-----------------+\n|               1 |\n+-----------------+\n\nSELECT .01 <> ''0.01'';\n+---------------+\n| .01 <> ''0.01'' |\n+---------------+\n|             0 |\n+---------------+\n\nSELECT ''zapp'' <> ''zappp'';\n+-------------------+\n| ''zapp'' <> ''zappp'' |\n+-------------------+\n|                 1 |\n+-------------------+\n\nURL: https://mariadb.com/docs/server/reference/sql-structure/operators/comparison-operators/not-equal', '', 'https://mariadb.com/docs/server/reference/sql-structure/operators/comparison-operators/not-equal');
INSERT INTO help_topic (help_topic_id, help_category_id, name, description, example, url) VALUES (969, 38, 'NOT IN', 'Syntax\n------\n\nexpr NOT IN (value,...)\n\nDescription\n-----------\n\nThis is the same as NOT (expr IN (value,...)).\n\nExamples\n--------\n\nSELECT 2 NOT IN (0,3,5,7);\n+--------------------+\n| 2 NOT IN (0,3,5,7) |\n+--------------------+\n|                  1 |\n+--------------------+\n\nURL: https://mariadb.com/docs/server/reference/sql-structure/operators/comparison-operators/not-in', '', 'https://mariadb.com/docs/server/reference/sql-structure/operators/comparison-operators/not-in');
INSERT INTO help_topic (help_topic_id, help_category_id, name, description, example, url) VALUES (970, 38, '<=>', 'Syntax\n------\n\n<=>\n\nDescription\n-----------\n\nNULL-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.\n\na <=> b is equivalent to a = b OR (a IS NULL AND b IS NULL).\n\nWhen used in row comparisons, these two queries return the same results:\n\n``sql\nSELECT (t1.a, t1.b) <=> (t2.x, t2.y) \nFROM t1 INNER JOIN t2;\n\nSELECT (t1.a <=> t2.x) AND (t1.b <=> t2.y)\nFROM t1 INNER JOIN t2;\n``\n\nSee also NULL Values in MariaDB.\n\nExamples\n--------\n\nSELECT 1 <=> 1, NULL <=> NULL, 1 <=> NULL;\n+---------+---------------+------------+\n| 1 <=> 1 | NULL <=> NULL | 1 <=> NULL |\n+---------+---------------+------------+\n|       1 |             1 |          0 |\n+---------+---------------+------------+\n\nSELECT 1 = 1, NULL = NULL, 1 = NULL;\n+-------+-------------+----------+\n| 1 = 1 | NULL = NULL | 1 = NULL |\n+-------+-------------+----------+\n|     1 |        NULL |     NULL |\n+-------+-------------+----------+\n\nURL: https://mariadb.com/docs/server/reference/sql-structure/operators/comparison-operators/null-safe-equal', '', 'https://mariadb.com/docs/server/reference/sql-structure/operators/comparison-operators/null-safe-equal');
INSERT INTO help_topic (help_topic_id, help_category_id, name, description, example, url) VALUES (971, 38, '&&', 'Syntax\n------\n\nAND, &&\n\nDescription\n-----------\n\nLogical AND. Evaluates to 1 if all operands are non-zero and not NULL, to 0 if one or more operands are 0, otherwise NULL is returned.\n\nFor this operator, short-circuit evaluation can be used.\n\nExamples\n--------\n\nSELECT 1 && 1;\n+--------+\n| 1 && 1 |\n+--------+\n|      1 |\n+--------+\n\nSELECT 1 && 0;\n+--------+\n| 1 && 0 |\n+--------+\n|      0 |\n+--------+\n\nSELECT 1 && NULL;\n+-----------+\n| 1 && NULL |\n+-----------+\n|      NULL |\n+-----------+\n\nSELECT 0 && NULL;\n+-----------+\n| 0 && NULL |\n+-----------+\n|         0 |\n+-----------+\n\nSELECT NULL && 0;\n+-----------+\n| NULL && 0 |\n+-----------+\n|         0 |\n+-----------+\n\nURL: https://mariadb.com/docs/server/reference/sql-structure/operators/logical-operators/and', '', 'https://mariadb.com/docs/server/reference/sql-structure/operators/logical-operators/and');
INSERT INTO help_topic (help_topic_id, help_category_id, name, description, example, url) VALUES (972, 38, '!', 'Syntax\n------\n\nNOT, !\n\nDescription\n-----------\n\nLogical NOT. Evaluates to 1 if the operand is 0, to 0 if the operand is non-zero, and NOT NULL returns NULL.\n\nBy default, the ! operator has a higher precedence. If the HIGH_NOT_PRECEDENCE SQL_MODE flag is set, NOT and ! have the same precedence.\n\nExamples\n--------\n\nSELECT NOT 10;\n+--------+\n| NOT 10 |\n+--------+\n|      0 |\n+--------+\n\nSELECT NOT 0;\n+-------+\n| NOT 0 |\n+-------+\n|     1 |\n+-------+\n\nSELECT NOT NULL;\n+----------+\n| NOT NULL |\n+----------+\n|     NULL |\n+----------+\n\nSELECT ! (1+1);\n+---------+\n| ! (1+1) |\n+---------+\n|       0 |\n+---------+\n\nSELECT ! 1+1;\n+-------+\n| ! 1+1 |\n+-------+\n|     1 |\n+-------+\n\nURL: https://mariadb.com/docs/server/reference/sql-structure/operators/logical-operators/not', '', 'https://mariadb.com/docs/server/reference/sql-structure/operators/logical-operators/not');
INSERT INTO help_topic (help_topic_id, help_category_id, name, description, example, url) VALUES (973, 38, '||', 'Syntax\n------\n\nOR, ||\n\nDescription\n-----------\n\nLogical 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.\n\nFor this operator, short-circuit evaluation can be used.\n\nNote that, if the PIPES_AS_CONCAT SQL_MODE is set, || is used as a string concatenation operator. This means that a || b is the same as CONCAT(a,b). See CONCAT() for details.\n\nOracle Mode\n\nIn Oracle mode, || ignores null.\n\nExamples\n--------\n\nSELECT 1 || 1;\n+--------+\n| 1 || 1 |\n+--------+\n|      1 |\n+--------+\n\nSELECT 1 || 0;\n+--------+\n| 1 || 0 |\n+--------+\n|      1 |\n+--------+\n\nSELECT 0 || 0;\n+--------+\n| 0 || 0 |\n+--------+\n|      0 |\n+--------+\n\nSELECT 0 || NULL;\n+-----------+\n| 0 || NULL |\n+-----------+\n|      NULL |\n+-----------+\n\nSELECT 1 || NULL;\n+-----------+\n| 1 || NULL |\n+-----------+\n|         1 |\n+-----------+\n\nURL: https://mariadb.com/docs/server/reference/sql-structure/operators/logical-operators/or', '', 'https://mariadb.com/docs/server/reference/sql-structure/operators/logical-operators/or');
INSERT INTO help_topic (help_topic_id, help_category_id, name, description, example, url) VALUES (974, 38, 'XOR', 'Syntax\n------\n\nXOR\n\nDescription\n-----------\n\nXOR 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.\n\nExamples\n--------\n\nSELECT 1 XOR 1;\n+---------+\n| 1 XOR 1 |\n+---------+\n|       0 |\n+---------+\n\nSELECT 1 XOR 0;\n+---------+\n| 1 XOR 0 |\n+---------+\n|       1 |\n+---------+\n\nSELECT 1 XOR NULL;\n+------------+\n| 1 XOR NULL |\n+------------+\n|       NULL |\n+------------+\n\nURL: https://mariadb.com/docs/server/reference/sql-structure/operators/logical-operators/xor', '', 'https://mariadb.com/docs/server/reference/sql-structure/operators/logical-operators/xor');
INSERT INTO help_topic (help_topic_id, help_category_id, name, description, example, url) VALUES (975, 38, 'Operator Precedence', 'Description\n-----------\n\nThe precedence is the order in which the SQL operators are evaluated.\n\nThe 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.\n\n INTERVAL\n BINARY, COLLATE\n !\n - (unary minus), bitwise not (unary bit inversion)\n || (string concatenation)\n ^ (bitwise XOR)\n \\, /, DIV, %, MOD (multiplication, division, modulo)\n -, + (subtraction, addition)\n <<, >>\n & (bitwise AND)\n | (bitwise OR)\n LIKE, REGEXP, IN\n BETWEEN\n = (comparison), <=>, >=, >, <=, <, <>, !=, IS\n NOT\n &&, AND\n XOR\n || (logical or), OR\n = (assignment), :=\n\nFunctions precedence is always higher than operators precedence.\n\nIf the HIGH_NOT_PRECEDENCE SQL_MODE is set, NOT has the same precedence as !.\n\nThe || 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.\n\nThe = operator''s precedence depends on the context - it is higher when = is used as a comparison operator.\n\nParentheses can be used to modify the operators precedence in an expression.\n\nShort-Circuit Evaluation\n\nThe 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:\n\n FALSE AND x()\n FALSE && x()\n TRUE OR x()\n TRUE || x()\n* NULL BETWEEN x() AND x()\n\nNote 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.\n\nThis 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:\n\n``sql\nSELECT some_function() OR log_error();\n``\n\nURL: https://mariadb.com/docs/server/reference/sql-structure/operators/operator-precedence', '', 'https://mariadb.com/docs/server/reference/sql-structure/operators/operator-precedence');
INSERT INTO help_topic (help_topic_id, help_category_id, name, description, example, url) VALUES (976, 35, 'Sequences', 'Description\n-----------\n\nsequence-overview.md\n\ncreate-sequence.md\n\nshow-create-sequence.md\n\nalter-sequence.md\n\ndrop-sequence.md\n\nsequence-functions\n\ninformation-schema-sequences-table.md\n\nshow-tables.md\n\ne4084.md\n\nURL: https://mariadb.com/docs/server/reference/sql-structure/sequences/README', '', 'https://mariadb.com/docs/server/reference/sql-structure/sequences/README');
INSERT INTO help_topic (help_topic_id, help_category_id, name, description, example, url) VALUES (977, 35, 'ALTER SEQUENCE', 'Syntax\n------\n\nALTER SEQUENCE [IF EXISTS] sequence_name\n[AS { TINYINT | SMALLINT | |MEDIUMINT | INT | INTEGER | BIGINT } [SIGNED | UNSIGNED]]\n[ INCREMENT [ BY | = ] number ]\n[ MINVALUE [=] number | NO MINVALUE | NOMINVALUE ]\n[ MAXVALUE [=] number | NO MAXVALUE | NOMAXVALUE ]\n[ START [ WITH | = ] number ] [ CACHE [=] number ] [ [ NO ] CYCLE ]\n[ RESTART [[WITH | =] number]\n\nDescription\n-----------\n\nALTER SEQUENCE changes the parameters of an existing sequence generator. Any parameters not specifically set in the ALTER SEQUENCE command retain their prior settings.\n\nALTER SEQUENCE requires the ALTER privilege.\n\nOptions to ALTER SEQUENCE\n\n| Option    | Default value                                                | Description                                                                                                                                                                 |\n| --------- | ------------------------------------------------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |\n| INCREMENT | 1                                                            | Increment to use for values. May be negative.                                                                                                                               |\n| MINVALUE  | 1 if INCREMENT > 0 and -9223372036854775807 if INCREMENT < 0 | Minimum value for the sequence.                                                                                                                                             |\n| MAXVALUE  | 9223372036854775806 if INCREMENT > 0 and -1 if INCREMENT < 0 | Max value for sequence.                                                                                                                                                     |\n| START     | MINVALUE if INCREMENT > 0 and MAX_VALUE if INCREMENT< 0     | First value that the sequence will generate.                                                                                                                                |\n| 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. |\n| CYCLE     | 0 (= NO CYCLE)                                               | 1 if the sequence should start again from MINVALUE                                                                                                                          |\n\nThe 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.\n\nALTER SEQUENCE does not allow to change the sequence so that it''s inconsistent:\n\n``sql\nCREATE SEQUENCE s1;\nALTER SEQUENCE s1 MINVALUE 10;\nERROR 4061 (HY000): Sequence ''test.t1'' values are conflicting\n\nALTER SEQUENCE s1 MINVALUE 10 RESTART 10;\nERROR 4061 (HY000): Sequence ''test.t1'' values are conflicting\n\nALTER SEQUENCE s1 MINVALUE 10 START 10 RESTART 10;\n`\n\nINSERT\n\nTo 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:\n\n`sql\nCREATE SEQUENCE s1;\nINSERT INTO s1 VALUES(1000,10,2000,1005,1,1000,0,0);\nSELECT * FROM s1;\n\n+------------+-----------+-----------+-------+-----------+-------+-------+-------+\n| next_value | min_value | max_value | start | increment | cache | cycle | round |\n+------------+-----------+-----------+-------+-----------+-------+-------+-------+\n|       1000 |        10 |      2000 |  1005 |         1 |  1000 |     0 |     0 |\n+------------+-----------+-----------+-------+-----------+-------+-------+-------+\n\nSHOW CREATE SEQUENCE s1;\n+-------+--------------------------------------------------------------------------------------------------------------+\n| Table | Create Table                                                                                                 |\n+-------+--------------------------------------------------------------------------------------------------------------+\n| s1    | CREATE SEQUENCE s1 start with 1005 minvalue 10 maxvalue 2000 increment by 1 cache 1000 nocycle ENGINE=Aria |\n+-------+--------------------------------------------------------------------------------------------------------------+\n`\n\nNotes\n\nALTER 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.\n\nALTER 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.\n\nIf you want to change the storage engine or sequence comment, or rename the sequence, you can use ALTER TABLE for this.\n\nURL: https://mariadb.com/docs/server/reference/sql-structure/sequences/alter-sequence', '', 'https://mariadb.com/docs/server/reference/sql-structure/sequences/alter-sequence');
INSERT INTO help_topic (help_topic_id, help_category_id, name, description, example, url) VALUES (978, 35, 'CREATE SEQUENCE', 'Syntax\n------\n\nCREATE [OR REPLACE] [TEMPORARY] SEQUENCE [IF NOT EXISTS] sequence_name\n[AS { TINYINT | SMALLINT | |MEDIUMINT | INT | INTEGER | BIGINT } [SIGNED | UNSIGNED]]\n[ INCREMENT [ BY | = ] number ]\n[ MINVALUE [=] number | NO MINVALUE | NOMINVALUE ]\n[ MAXVALUE [=] number | NO MAXVALUE | NOMAXVALUE ]\n[ START [ WITH | = ] number ] \n[ CACHE [=] number | NOCACHE ] [ CYCLE | NOCYCLE] \ntable_options\n\nDescription\n-----------\n\nCREATE SEQUENCE creates a sequence that generates new values when called with NEXT VALUE FOR sequence_name. It''s an alternative to AUTO INCREMENT if you want 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 you can access the last value generated by all used sequences, which solves one of the limitations with LAST_INSERT_ID().\n\nCREATE SEQUENCE requires the CREATE privilege.\n\nDROP SEQUENCE can be used to drop a sequence, and ALTER SEQUENCE to change it.\n\nCREATE Options\n\nAS\n\nINT type, that is, one of TINYINT, SMALLINT, MEDIUMINT, INT, INTEGER, BIGINT. Can be signed or unsigned. Maximum value is based on the data type. The use of BIGINT UNSIGNED with this option extends the possible maximum value from 9223372036854775806 to 18446744073709551614. Default is BIGINT.\n\nThe AS option is not available.\n\nINCREMENT\n\nIncrement 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). Default 1.\n\nMINVALUE\n\nMinimum value for the sequence. From MariaDB 11.5, the parser permits much smaller numbers, such as -9999999999999999999999999999, but converts to the minimum permitted for the INT type, with a note. Default 1 if INCREMENT > 0 , and -9223372036854775807 (or based on int type) if INCREMENT < 0.\n\nMAXVALUE\n\nMaximum value for sequence. From MariaDB 11.5, the parser permits much larger numbers, such as 9999999999999999999999999999 used in Oracle examples, but converts to the maximum permitted for the INT type, with a note. Default 9223372036854775806 (or based on int type) if INCREMENT > 0 , and -1 if INCREMENT < 0.\n\nSTART\n\nFirst value the sequence will generate. Default MINVALUE if INCREMENT > 0, and MAX_VALUE if INCREMENT< 0.\n\nCACHE / NOCACHE\n\nNumber 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. Default 1000. FLUSH TABLES, shutting down the server, etc. will discard the cached values, 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.\n\nNote that setting the cache to 1 from 1000 can make inserts to tables using sequences for default values 2x slower and increase the binary log sizes up to 7x.\n\nCYCLE / NOCYCLE\n\nIf CYCLE is used, then the sequence should start again from MINVALUE after it has run out of values. Default value is NOCYCLE.\n\nConstraints on Create Arguments\n\nTo be able to create a legal sequence, the following must hold:\n\n MAXVALUE >= start\n MAXVALUE > MINVALUE\n START >= MINVALUE\n MAXVALUE <= 9223372036854775806 (LONGLONG_MAX-1). From MariaDB 11.5, the parser accepts values beyond this, and converts based on the int type.\n* MINVALUE >= -9223372036854775807 (LONGLONG_MIN+1). From MariaDB 11.5, the parser accepts values beyond this, and converts based on the int type.\n\nNote that sequences can''t generate the maximum/minimum 64 bit number because of the constraint ofMINVALUE and MAXVALUE.\n\nAtomic DDL\n\nMariaDB supports Atomic DDL and CREATE SEQUENCE is atomic.\n\nMariaDB does not support Atomic DDL and CREATE SEQUENCE is atomic.\n\nExamples\n--------\n\nCREATE SEQUENCE s START WITH 100 INCREMENT BY 10;\n\nCREATE SEQUENCE s2 START WITH -100 INCREMENT BY -10;\n\nURL: https://mariadb.com/docs/server/reference/sql-structure/sequences/create-sequence', '', 'https://mariadb.com/docs/server/reference/sql-structure/sequences/create-sequence');
INSERT INTO help_topic (help_topic_id, help_category_id, name, description, example, url) VALUES (979, 35, 'DROP SEQUENCE', 'Syntax\n------\n\nDROP [TEMPORARY] SEQUENCE [IF EXISTS] [/COMMENT TO SAVE/]\n    sequence_name [, sequence_name] ...\n\nDescription\n-----------\n\nDROP SEQUENCE removes one or more sequences created with CREATE SEQUENCE. You 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.\n\nImportant: When a table is dropped, user privileges on the table are not automatically dropped. See GRANT.\n\nIf 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.\n\nFor 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.\n\nUse 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.\n\nDROP SEQUENCE requires the DROP privilege.\n\nNotes\n\nDROP SEQUENCE only removes sequences, not tables. However, DROP TABLE can remove both sequences and tables.\n\nURL: https://mariadb.com/docs/server/reference/sql-structure/sequences/drop-sequence', '', 'https://mariadb.com/docs/server/reference/sql-structure/sequences/drop-sequence');
INSERT INTO help_topic (help_topic_id, help_category_id, name, description, example, url) VALUES (980, 35, 'LASTVAL', 'Description\n-----------\n\nLASTVAL is a synonym for PREVIOUS VALUE for sequence_name.\n\nURL: https://mariadb.com/docs/server/reference/sql-structure/sequences/sequence-functions/lastval', '', 'https://mariadb.com/docs/server/reference/sql-structure/sequences/sequence-functions/lastval');
INSERT INTO help_topic (help_topic_id, help_category_id, name, description, example, url) VALUES (981, 35, 'NEXT VALUE FOR', 'Syntax\n------\n\nNEXT VALUE FOR sequence\n\nDescription\n-----------\n\nGenerate next value for a SEQUENCE.\n\n You can greatly speed up NEXT VALUE by creating the sequence with the CACHE option. If not, every NEXT VALUE usage will cause changes in the stored SEQUENCE table.\n 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.\n If one updates the SEQUENCE with SETVAL() or ALTER SEQUENCE ... RESTART, NEXT VALUE FOR will notice this and start from the next requested value.\n FLUSH TABLES will close the sequence and the next sequence number generated will be according to what''s stored in the SEQUENCE object. In effect, this will discard the cached values.\n 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.\n NEXT VALUE requires the INSERT privilege.\n* You can also use NEXT VALUE FOR sequence for column DEFAULT.\n\nOnce the sequence is complete, unless the sequence has been created with the CYCLE attribute (not the default), calling the function will result in Error 4084: Sequence has run out.\n\nExamples\n--------\n\nCREATE OR REPLACE SEQUENCE s MAXVALUE=2;\n\nSELECT NEXTVAL(s);\n+------------+\n| NEXTVAL(s) |\n+------------+\n|          1 |\n+------------+\n\nSELECT NEXTVAL(s);\n+------------+\n| NEXTVAL(s) |\n+------------+\n|          2 |\n+------------+\n\nSELECT NEXTVAL(s);\nERROR 4084 (HY000): Sequence ''test.s'' has run out\n\nALTER SEQUENCE s MAXVALUE=2 CYCLE;\n\nSELECT NEXTVAL(s);\n+------------+\n| NEXTVAL(s) |\n+------------+\n|          1 |\n+------------+\n\nURL: https://mariadb.com/docs/server/reference/sql-structure/sequences/sequence-functions/next-value-for-sequence_name', '', 'https://mariadb.com/docs/server/reference/sql-structure/sequences/sequence-functions/next-value-for-sequence_name');
INSERT INTO help_topic (help_topic_id, help_category_id, name, description, example, url) VALUES (982, 35, 'NEXTVAL', 'Description\n-----------\n\nNEXTVAL is a synonym for NEXT VALUE for sequence_name.\n\nURL: https://mariadb.com/docs/server/reference/sql-structure/sequences/sequence-functions/nextval', '', 'https://mariadb.com/docs/server/reference/sql-structure/sequences/sequence-functions/nextval');
INSERT INTO help_topic (help_topic_id, help_category_id, name, description, example, url) VALUES (983, 35, 'PREVIOUS VALUE FOR', 'Syntax\n------\n\nPREVIOUS VALUE FOR sequence_name\n\nDescription\n-----------\n\nGets the most recent value in the current connection generated from a sequence.\n\n If the sequence has not yet been used by the connection, PREVIOUS VALUE FOR returns NULL (the same thing applies with a new connection which doesn''t see a last value for an existing sequence).\n If a SEQUENCE has been dropped and re-created then it''s treated as a new SEQUENCE and PREVIOUS VALUE FOR will return NULL.\n Returns NULL if the sequence is complete.\n FLUSH TABLES has no effect on PREVIOUS VALUE FOR.\n Previous values for all used sequences are stored per connection until connection ends.\n PREVIOUS VALUE FOR requires the SELECT privilege.\n\nExamples\n--------\n\nCREATE SEQUENCE s START WITH 100 INCREMENT BY 10;\n\nSELECT PREVIOUS VALUE FOR s;\n+----------------------+\n| PREVIOUS VALUE FOR s |\n+----------------------+\n|                 NULL |\n+----------------------+\n\nThe function works for sequences only, if the table is used an error is generated\nSELECT PREVIOUS VALUE FOR t;\nERROR 4089 (42S02): ''test.t'' is not a SEQUENCE\n\nCall the NEXT VALUE FOR s:\nSELECT NEXT VALUE FOR s;\n+------------------+\n| NEXT VALUE FOR s |\n+------------------+\n|              100 |\n+------------------+\n\nSELECT PREVIOUS VALUE FOR s;\n+----------------------+\n| PREVIOUS VALUE FOR s |\n+----------------------+\n|                  100 |\n+----------------------+\n\nURL: https://mariadb.com/docs/server/reference/sql-structure/sequences/sequence-functions/previous-value-for-sequence_name', '', 'https://mariadb.com/docs/server/reference/sql-structure/sequences/sequence-functions/previous-value-for-sequence_name');
INSERT INTO help_topic (help_topic_id, help_category_id, name, description, example, url) VALUES (984, 35, 'SETVAL', 'Syntax\n------\n\nSETVAL(sequence_name, next_value, [is_used, [round]])\n\nDescription\n-----------\n\nSet the next value to be returned for a SEQUENCE.\n\nThis function is compatible with PostgreSQL syntax, extended with the round argument.\n\nIf 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.\n\nIf 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.\n\nnext_value must be an integer literal.\n\nFor 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.\n\nThe result returned by SETVAL() is next_value or NULL if the given next_value and round is smaller than the current value.\n\nSETVAL() 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.\n\nIf CYCLE is used, first round and then next_value are compared to see if the value is bigger than the current value.\n\nInternally, in the MariaDB server, SETVAL() is used to inform slaves that a SEQUENCE has changed value. The slave may getSETVAL() statements out of order, but this is ok as only the biggest one will have an effect.\n\nSETVAL requires the INSERT privilege.\n\nExamples\n--------\n\nSELECT setval(foo, 42);           -- Next nextval will return 43\nSELECT setval(foo, 42, TRUE);     -- Same as above\nSELECT setval(foo, 42, FALSE);    -- Next nextval will return 42\n\nURL: https://mariadb.com/docs/server/reference/sql-structure/sequences/sequence-functions/setval', '', 'https://mariadb.com/docs/server/reference/sql-structure/sequences/sequence-functions/setval');
INSERT INTO help_topic (help_topic_id, help_category_id, name, description, example, url) VALUES (985, 35, 'Sequence Overview', 'Description\n-----------\n\nThis page is about sequence objects. For details about the storage engine, see Sequence Storage Engine.\n\nIntroduction\n\nA sequence is an object that generates a sequence of numeric values, as specified by the CREATE SEQUENCE statement.\n\nCREATE SEQUENCE creates 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().\n\nSequences should not be used with statement-based logging; see this section for details.\n\nCreating a Sequence\n\nThe CREATE SEQUENCE statement is used to create a sequence. Here is an example of a sequence starting at 100, incrementing by 10 each time:\n\n``sql\nCREATE SEQUENCE s START WITH 100 INCREMENT BY 10;\n`\n\nThe CREATE SEQUENCE statement, along with defaults, can be viewd with the SHOW CREATE SEQUENCE STATEMENT, for example:\n\n`sql\nSHOW CREATE SEQUENCE s\\G\n************************ 1. row ***********************\n       Table: s\nCreate Table: CREATE SEQUENCE s start with 100 minvalue 1 maxvalue 9223372036854775806 \n  increment by 10 cache 1000 nocycle ENGINE=InnoDB\n`\n\nUsing Sequence Objects\n\nTo get the next value from a sequence, use\n\n`sql\nNEXT VALUE FOR sequence_name\n`\n\nor\n\n`sql\nNEXTVAL(sequence_name)\n`\n\nor in Oracle mode (SQL_MODE=ORACLE)\n\n`\nsequence_name.nextval\n`\n\nFor retrieving the last value used by the current connection from a sequence use:\n\n`sql\nPREVIOUS VALUE FOR sequence_name\n`\n\nor\n\n`sql\nLASTVAL(sequence_name)\n`\n\nor in Oracle mode (SQL_MODE=ORACLE)\n\n`\nsequence_name.currval\n`\n\nFor example:\n\n`sql\nSELECT NEXTVAL(s);\n+------------+\n| NEXTVAL(s) |\n+------------+\n|        100 |\n+------------+\n\nSELECT NEXTVAL(s);\n+------------+\n| NEXTVAL(s) |\n+------------+\n|        110 |\n+------------+\n\nSELECT LASTVAL(s);\n+------------+\n| LASTVAL(s) |\n+------------+\n|        110 |\n+------------+\n`\n\nUsing Sequences in DEFAULT\n\nSequences can be used in DEFAULT:\n\n`sql\nCREATE SEQUENCE s1;\nCREATE TABLE t1 (a INT PRIMARY KEY DEFAULT (NEXT VALUE FOR s1), b INT);\nINSERT INTO t1 (b) VALUES (1),(2);\nSELECT  FROM t1;\n+---+------+\n| a | b    |\n+---+------+\n| 1 |    1 |\n| 2 |    2 |\n+---+------+\n`\n\nChanging a Sequence\n\nThe ALTER SEQUENCE statement is used for changing sequences. For example, to restart the sequence at another value:\n\n`sql\nALTER SEQUENCE s RESTART 50;\n\nSELECT NEXTVAL(s);\n+------------+\n| NEXTVAL(s) |\n+------------+\n|         50 |\n+------------+\n`\n\nThe SETVAL function can also be used to set the next value to be returned for a SEQUENCE, for example:\n\n`sql\nSELECT SETVAL(s, 100);\n+----------------+\n| SETVAL(s, 100) |\n+----------------+\n|            100 |\n+----------------+\n`\n\nSETVAL can only be used to increase the sequence value. Attempting to set a lower value will fail, returning NULL:\n\n`sql\nSELECT SETVAL(s, 50);\n+---------------+\n| SETVAL(s, 50) |\n+---------------+\n|          NULL |\n+---------------+\n`\n\nDropping a Sequence\n\nThe DROP SEQUENCE statement is used to drop a sequence, for example:\n\n`sql\nDROP SEQUENCE s;\n`\n\nReplication\n\nIf you want to use Sequences in a master-master setup or with Galera, you should use INCREMENT=0. This tells the Sequence to use auto_increment_increment and auto_increment_offset to generate unique values for each server.\n\nStatement-Based Replication Limitation\n\nUsing SELECT NEXT VALUE causes an error for statement-based logging:\n\n`\nERROR 1665 (HY000): Cannot execute statement: impossible to write to binary log since BINLOG_FORMAT = STATEMENT and at least one table uses a storage engine limited to row-based logging.\n`\n\nThis happens because SELECT modifies objects.\n\nStandards Compliance\n\nMariaDB supports both ANSI SQL and Oracle syntax for sequences.\n\nHowever 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.\n\nSince 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.\n\nNotes\n\nOne 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.\n\nTo make this possible, sequence is currently implemented as a table with a few exclusive properties.\n\nThe special properties for sequence tables are:\n\n A sequence table has always one row.\n When one creates a sequence, either with CREATE TABLE or CREATE SEQUENCE, one row will be inserted.\n 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.\n UPDATE or DELETE can''t be performed on Sequence objects.\n Doing a select on the sequence shows the current state of the sequence, except the values that are reserved in the cache. The next_value column shows the next value not reserved by the cache.\n 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.\n A number of normal table operations work on Sequence tables. See next section.\n\nTable Operations that Work with Sequences\n\n 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.\n CREATE TABLE sequence-structure ... SEQUENCE=1\n ALTER TABLE sequence RENAME TO sequence2\n RENAME TABLE sequence_name TO new_sequence_name\n DROP TABLE sequence_name. This is allowed mainly to get old tools like mariadb-dump to work with sequence tables.\n SHOW TABLES\n\nImplementation\n\nInternally, 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\\\nalmost no performance impact for normal tables. (The cost is one ''if'' per insert if the binary log is enabled).\n\nUnderlying Table Structure\n\nThe following example shows the table structure of sequences and how it can be used as a table.\\\n(Output of results are slightly edited to make them easier to read.)\n\n`sql\nCREATE SEQUENCE t1;\nSHOW CREATE SEQUENCE t1\\G\n*********************** 1. row *********************\n  CREATE SEQUENCE t1 start with 1 minvalue 1 maxvalue 9223372036854775806\n  increment by 1 cache 1000 nocycle ENGINE=InnoDB\n\nSHOW CREATE TABLE t1\\G\n********************* 1. row ***********************\nCreate Table: CREATE TABLE t1 (\n  next_not_cached_value bigint(21) NOT NULL,\n  minimum_value bigint(21) NOT NULL,\n  maximum_value bigint(21) NOT NULL,\n  start_value bigint(21) NOT NULL COMMENT ''start value when sequences is created or value if RESTART is used'',\n  increment bigint(21) NOT NULL COMMENT ''increment value'',\n  cache_size bigint(21) unsigned NOT NULL,\n  cycle_option tinyint(1) unsigned NOT NULL COMMENT ''0 if no cycles are allowed, 1 if the sequence should begin a new cycle when maximum_value is passed'',\n  cycle_count bigint(21) NOT NULL COMMENT ''How many cycles have been done''\n) ENGINE=InnoDB SEQUENCE=1\n\nSELECT  FROM t1\\G\nnext_not_cached_value: 1\n minimum_value: 1\n maximum_value: 9223372036854775806\n  start_value: 1\n  increment: 1\n  cache_size: 1000\n  cycle_option: 0\n  cycle_count: 0\n`\n\nThe cycle_count column is incremented every time the sequence wraps around.\n\nCredits\n\n Thanks to Jianwe Zhao from Aliyun for his work on SEQUENCE` in AliSQL, which gave ideas and inspiration for this work.\n Thanks to Peter Gulutzan, who helped test and gave useful comments about the implementation.\n\nURL: https://mariadb.com/docs/server/reference/sql-structure/sequences/sequence-overview', '', 'https://mariadb.com/docs/server/reference/sql-structure/sequences/sequence-overview');
INSERT INTO help_topic (help_topic_id, help_category_id, name, description, example, url) VALUES (986, 29, 'Binary Literals', 'Description\n-----------\n\nBinary 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.\n\nBinary literals are interpreted as binary strings, and are convenient to represent VARBINARY, BINARY or BIT values.\n\nTo convert a binary literal into an integer, just add 0.\n\nExamples\n--------\n\nSELECT 0b1000001;\n+-----------+\n| 0b1000001 |\n+-----------+\n| A         |\n+-----------+\n\nURL: https://mariadb.com/docs/server/reference/sql-structure/sql-language-structure/binary-literals', '', 'https://mariadb.com/docs/server/reference/sql-structure/sql-language-structure/binary-literals');
INSERT INTO help_topic (help_topic_id, help_category_id, name, description, example, url) VALUES (987, 29, 'Date and Time Literals', 'Description\n-----------\n\nStandard syntaxes\n\nMariaDB supports the SQL standard and ODBC syntaxes for DATE, TIME, and TIMESTAMP literals.\n\nSQL standard syntax:\n\n DATE ''string''\n TIME ''string''\n TIMESTAMP ''string''\n\nODBC syntax:\n\n {d ''string''}\n {t ''string''}\n {ts ''string''}\n\nThe timestamp literals are treated as DATETIME literals, because in MariaDB the range of DATETIME is closer to the TIMESTAMP range in the SQL standard.\n\nstring is a string in a proper format, as explained below.\n\nDATE literals\n\nA 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).\n\nA DATE literal can also be an integer, in one of the following formats: YYYYMMDD or YYMMDD.\n\nAll the following DATE literals are valid, and they all represent the same value:\n\n``\n''19940101''\n''940101''\n''1994-01-01''\n''94/01/01''\n''1994-01/01''\n''94:01!01''\n19940101\n940101\n`\n\nDATETIME literals\n\nA 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.\n\nThe 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).\n\nA 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.\n\nAll the following DATE literals are valid, and they all represent the same value:\n\n`\n''1994-01-01T12:30:03''\n''1994/01/01\\n\\t 12+30+03''\n''1994/01\\\\01\\n\\t 12+30-03''\n''1994-01-01 12:30:3''\n`\n\nTIME literals\n\nA 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.\n\nA TIME literal can also be a number in one of the following formats: HHMMSS, MMSS, or SS.\n\nThe following literals are equivalent:\n\n`\n''09:05:00''\n''9:05:0''\n''9:5:0''\n''090500''\n`\n\n2-digit years\n\nThe year part in DATE and DATETIME literals is determined as follows:\n\n 70 - 99 = 1970 - 1999\n 00 - 69 = 2000 - 2069\n\nMicroseconds\n\nDATETIME 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:\n\n`\n''12:30:00.123456''\n123000.123456\n`\n\nSee Microseconds in MariaDB for details.\n\nDate and time literals and the SQL_MODE\n\nUnless 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.\n\nIf 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.\n\nUnless the NO_ZERO_IN_DATE flag is set, each subpart of a date or time value (years, hours...) can be set to 0`.\n\nURL: https://mariadb.com/docs/server/reference/sql-structure/sql-language-structure/date-and-time-literals', '', 'https://mariadb.com/docs/server/reference/sql-structure/sql-language-structure/date-and-time-literals');
INSERT INTO help_topic (help_topic_id, help_category_id, name, description, example, url) VALUES (988, 29, 'Hexadecimal Literals', 'Description\n-----------\n\nHexadecimal literals can be written using any of the following syntaxes:\n\n x''value''\n X''value'' (SQL standard)\n* 0xvalue (ODBC)\n\nvalue 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.\n\nNormally, 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.\n\nThe first two syntaxes; X''_value_'' and x''_value_, follow the SQL standard, and behave as a string in all contexts in MariaDB. The latter syntax, 0x_value_, 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).\n\nExamples\n--------\n\nSELECT x''61'', X''61'', 0x61;\n+-------+-------+------+\n| x''61'' | X''61'' | 0x61 |\n+-------+-------+------+\n| a     | a     | a    |\n+-------+-------+------+\n\nURL: https://mariadb.com/docs/server/reference/sql-structure/sql-language-structure/hexadecimal-literals', '', 'https://mariadb.com/docs/server/reference/sql-structure/sql-language-structure/hexadecimal-literals');
INSERT INTO help_topic (help_topic_id, help_category_id, name, description, example, url) VALUES (989, 29, 'Identifier Case Sensitivity', 'Description\n-----------\n\nWhether 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.\n\nDatabase, table, table aliases, and trigger names are affected by the system''s case sensitivity, while index, column, column aliases, stored routine, and event names are never case sensitive.\n\nLog file group names are case sensitive.\n\nIn some cases, the table exists but that you are referring to it incorrectly:\n\n  Because MariaDB uses directories and files to store databases and tables, database and table names are case-sensitive if they are located on a file system that has case-sensitive file names.\n Even for file systems that are not case-sensitive, such as on Windows, all references to a given table within a query must use the same lettercase. \n\nThe 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.\n\nIt is thus possible to make Unix-based systems behave like Windows and ignore case-sensitivity. The reverse is not true before Windows 10, as the underlying Windows filesystem could not support this. It is possible since Windows 10, although case insensitivity is still the default operating system setting.\n\nEven 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.\n\n``sql\nSELECT * FROM a_table WHERE A_table.id>10;\n``\n\nFor a full list of identifiers naming rules, see Identifier Names.\n\nPlease 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.\n\nURL: https://mariadb.com/docs/server/reference/sql-structure/sql-language-structure/identifier-case-sensitivity', '', 'https://mariadb.com/docs/server/reference/sql-structure/sql-language-structure/identifier-case-sensitivity');
INSERT INTO help_topic (help_topic_id, help_category_id, name, description, example, url) VALUES (990, 29, 'Identifier Names', 'Description\n-----------\n\nDatabases, 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.\n\nIdentifiers 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.\n\nEven 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.\n\nUnquoted\n\nThe following characters are valid, and allow identifiers to be unquoted:\n\n ASCII: \\[0-9,a-z,A-Z$_] (numerals 0-9, basic Latin letters, both lowercase and uppercase, dollar sign, underscore)\n Extended: U+0080 .. U+FFFF\n\nQuoted\n\nThe following characters are valid, but identifiers using them must be quoted:\n\n ASCII: U+0001 .. U+007F (full Unicode Basic Multilingual Plane (BMP) except for U+0000)\n Extended: U+0080 .. U+FFFF\n Identifier quotes can themselves be used as part of an identifier, as long as they are quoted.\n\nFurther Rules\n\nThere are a number of other rules for identifiers:\n\n Identifiers are stored as Unicode (UTF-8)\n Identifiers may or may not be case-sensitive. See Indentifier Case-sensitivity.\n Database, table and column names can''t end with space characters\n Identifier names may begin with a numeral, but can''t only contain numerals unless quoted.\n An identifier starting with a numeral, followed by an ''e'', may be parsed as a floating point number, and needs to be quoted.\n Identifiers are not permitted to contain the ASCII NUL character (U+0000) and supplementary characters (U+10000 and higher).\n 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.\n User variables cannot be used as part of an identifier, or as an identifier in an SQL statement.\n\nQuote Character\n\nThe 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.\n\nThe 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.\n\nMaximum Length\n\n Databases, tables, columns, indexes, constraints, stored routines, triggers, events, views, tablespaces, servers and log file groups have a maximum length of 64 characters.\n Compound statement labels have a maximum length of 16 characters.\n 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).\n Users have a maximum length of 80 characters.\n Roles have a maximum length of 128 characters.\n* Multi-byte characters do not count extra towards the character limit.\n\nMultiple Identifiers\n\nMariaDB 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.\n\nExamples\n--------\n\nCREATE TABLE t1 (i int);\n\nINSERT INTO t1(i) VALUES (10);\n\nSELECT i FROM t1;\n+------+\n| i    |\n+------+\n|   10 |\n+------+\n\nSELECT t1.i FROM t1;\n+------+\n| i    |\n+------+\n|   10 |\n+------+\n\nSELECT test.t1.i FROM t1;\n+------+\n| i    |\n+------+\n|   10 |\n+------+\n\nURL: https://mariadb.com/docs/server/reference/sql-structure/sql-language-structure/identifier-names', '', 'https://mariadb.com/docs/server/reference/sql-structure/sql-language-structure/identifier-names');
INSERT INTO help_topic (help_topic_id, help_category_id, name, description, example, url) VALUES (991, 29, 'Identifier Qualifiers', 'Description\n-----------\n\nQualifiers 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.\n\nQualifiers can be composed by one or more identifiers, where the initial parts affect the context within which the final identifier is interpreted:\n\n For a database, only the database identifier needs to be specified.\n 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.\n 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.\n 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.\n\nIf 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.\n\nAll the following examples are valid:\n\n db_name.tbl_name.col_name\n tbl_name\n db_name.tbl_name.col_name\n db_name . tbl_name\n db_name. tbl_name\n\nIf 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:\n\n tbl_name\n . tbl_name\n .tbl_name\n* . tbl_name\n\nFor DML statements, it is possible to specify a list of the partitions using the PARTITION clause. See Partition Pruning and Selection for details.\n\nURL: https://mariadb.com/docs/server/reference/sql-structure/sql-language-structure/identifier-qualifiers', '', 'https://mariadb.com/docs/server/reference/sql-structure/sql-language-structure/identifier-qualifiers');
INSERT INTO help_topic (help_topic_id, help_category_id, name, description, example, url) VALUES (992, 29, 'Identifier to File Name Mapping', 'Description\n-----------\n\nSome 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.\n\nNot 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.\n\nThis 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.\n\nThe 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:\n\n| Code Range | Pattern            | Number     | Used | Unused | Blocks                                |\n| ---------- | ------------------ | ---------- | ---- | ------ | ------------------------------------- |\n| 00C0..017F | \\[@]\\[0..4]\\[g..z] | 5\\20= 100 | 97   | 3      | Latin-1 Supplement + Latin Extended-A |\n| 0370..03FF | \\[@]\\[5..9]\\[g..z] | 5\\20= 100 | 88   | 12     | Greek and Coptic                      |\n| 0400..052F | \\[@]\\[g..z]\\[0..6] | 20\\7= 140 | 137  | 3      | Cyrillic + Cyrillic Supplement        |\n| 0530..058F | \\[@]\\[g..z]\\[7..8] | 20\\2= 40  | 38   | 2      | Armenian                              |\n| 2160..217F | \\[@]\\[g..z]\\[9]    | 20\\1= 20  | 16   | 4      | Number Forms                          |\n| 0180..02AF | \\[@]\\[g..z]\\[a..k] | 20\\11=220 | 203  | 17     | Latin Extended-B + IPA Extensions     |\n| 1E00..1EFF | \\[@]\\[g..z]\\[l..r] | 20\\7= 140 | 136  | 4      | Latin Extended Additional             |\n| 1F00..1FFF | \\[@]\\[g..z]\\[s..z] | 20\\8= 160 | 144  | 16     | Greek Extended                        |\n| .... ....  | \\[@]\\[a..f]\\[g..z] | 6\\*20= 120 | 0    | 120    | RESERVED                              |\n| 24B6..24E9 | \\[@]\\[@]\\[a..z]    | 26         | 26   | 0      | Enclosed Alphanumerics                |\n| FF21..FF5A | \\[@]\\[a..z]\\[@]    | 26         | 26   | 0      | Halfwidth and Fullwidth forms         |\n\nCode Range values are UCS-2.\n\nAll of this encoding happens transparently at the filesystem level with one exception.\n\nExamples\n--------\n\nSELECT CAST(CONVERT("this_is_таблица" USING filename) AS BINARY);\n+------------------------------------------------------------------+\n| CAST(CONVERT("this_is_таблица" USING filename) AS BINARY)        |\n+------------------------------------------------------------------+\n| this_is_@y0@g0@h0@r0@o0@i1@g0                                    |\n+------------------------------------------------------------------+\n\nURL: https://mariadb.com/docs/server/reference/sql-structure/sql-language-structure/identifier-to-file-name-mapping', '', 'https://mariadb.com/docs/server/reference/sql-structure/sql-language-structure/identifier-to-file-name-mapping');
INSERT INTO help_topic (help_topic_id, help_category_id, name, description, example, url) VALUES (993, 29, 'Numeric Literals', 'Description\n-----------\n\nNumeric 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 (.).\n\nIf the integer part is zero, it can be omitted, but the literal must begin with a dot.\n\nThe 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).\n\nIn 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.\n\nHexadecimal literals are interpreted as numbers when used in numeric contexts.\n\nURL: https://mariadb.com/docs/server/reference/sql-structure/sql-language-structure/numeric-iterals', '', 'https://mariadb.com/docs/server/reference/sql-structure/sql-language-structure/numeric-iterals');
INSERT INTO help_topic (help_topic_id, help_category_id, name, description, example, url) VALUES (994, 29, 'Reserved Words', 'Description\n-----------\n\nThe following is a list of all reserved words in MariaDB.\n\nReserved words cannot be used as Identifiers, unless they are quoted.\n\nThe definitive list of reserved words for each version can be found by examining the sql/lex.h and sql/sql_yacc.yy files.\n\nReserved Words\n\n| Keyword                           |\n| --------------------------------- |\n| ACCESSIBLE                        |\n| ADD                               |\n| ALL                               |\n| ALTER                             |\n| ANALYZE                           |\n| AND                               |\n| AS                                |\n| ASC                               |\n| ASENSITIVE                        |\n| BEFORE                            |\n| BETWEEN                           |\n| BIGINT                            |\n| BINARY                            |\n| BLOB                              |\n| BOTH                              |\n| BY                                |\n| CALL                              |\n| CASCADE                           |\n| CASE                              |\n| CHANGE                            |\n| CHAR                              |\n| CHARACTER                         |\n| CHECK                             |\n| COLLATE                           |\n| COLUMN                            |\n| CONDITION                         |\n| CONSTRAINT                        |\n| CONTINUE                          |\n| CONVERT                           |\n| CREATE                            |\n| CROSS                             |\n| CURRENT_DATE                     |\n| CURRENT_ROLE                     |\n| CURRENT_TIME                     |\n| CURRENT_TIMESTAMP                |\n| CURRENT_USER                     |\n| CURSOR                            |\n| DATABASE                          |\n| DATABASES                         |\n| DAY_HOUR                         |\n| DAY_MICROSECOND                  |\n| DAY_MINUTE                       |\n| DAY_SECOND                       |\n| DEC                               |\n| DECIMAL                           |\n| DECLARE                           |\n| DEFAULT                           |\n| DELAYED                           |\n| DELETE                            |\n| DELETE_DOMAIN_ID                |\n| DESC                              |\n| DESCRIBE                          |\n| DETERMINISTIC                     |\n| DISTINCT                          |\n| DISTINCTROW                       |\n| DIV                               |\n| DO_DOMAIN_IDS                   |\n| DOUBLE                            |\n| DROP                              |\n| DUAL                              |\n| EACH                              |\n| ELSE                              |\n| ELSEIF                            |\n| ENCLOSED                          |\n| ESCAPED                           |\n| EXCEPT                            |\n| EXISTS                            |\n| EXIT                              |\n| EXPLAIN                           |\n| FALSE                             |\n| FETCH                             |\n| FLOAT                             |\n| FLOAT4                            |\n| FLOAT8                            |\n| FOR                               |\n| FORCE                             |\n| FOREIGN                           |\n| FROM                              |\n| FULLTEXT                          |\n| GENERAL                           |\n| GRANT                             |\n| GROUP                             |\n| HAVING                            |\n| HIGH_PRIORITY                    |\n| HOUR_MICROSECOND                 |\n| HOUR_MINUTE                      |\n| HOUR_SECOND                      |\n| IF                                |\n| IGNORE                            |\n| IGNORE_DOMAIN_IDS               |\n| IGNORE_SERVER_IDS               |\n| IN                                |\n| INDEX                             |\n| INFILE                            |\n| INNER                             |\n| INOUT                             |\n| INSENSITIVE                       |\n| INSERT                            |\n| INT                               |\n| INT1                              |\n| INT2                              |\n| INT3                              |\n| INT4                              |\n| INT8                              |\n| INTEGER                           |\n| INTERSECT                         |\n| INTERVAL                          |\n| INTO                              |\n| IS                                |\n| ITERATE                           |\n| JOIN                              |\n| KEY                               |\n| KEYS                              |\n| KILL                              |\n| LEADING                           |\n| LEAVE                             |\n| LEFT                              |\n| LIKE                              |\n| LIMIT                             |\n| LINEAR                            |\n| LINES                             |\n| LOAD                              |\n| LOCALTIME                         |\n| LOCALTIMESTAMP                    |\n| LOCK                              |\n| LONG                              |\n| LONGBLOB                          |\n| LONGTEXT                          |\n| LOOP                              |\n| LOW_PRIORITY                     |\n| MASTER_HEARTBEAT_PERIOD         |\n| MASTER_SSL_VERIFY_SERVER_CERT |\n| MATCH                             |\n| MAXVALUE                          |\n| MEDIUMBLOB                        |\n| MEDIUMINT                         |\n| MEDIUMTEXT                        |\n| MIDDLEINT                         |\n| MINUTE_MICROSECOND               |\n| MINUTE_SECOND                    |\n| MOD                               |\n| MODIFIES                          |\n| NATURAL                           |\n| NOT                               |\n| NO_WRITE_TO_BINLOG             |\n| NULL                              |\n| NUMERIC                           |\n| OFFSET (> 10.6)                   |\n| ON                                |\n| OPTIMIZE                          |\n| OPTION                            |\n| OPTIONALLY                        |\n| OR                                |\n| ORDER                             |\n| OUT                               |\n| OUTER                             |\n| OUTFILE                           |\n| OVER                              |\n| PAGE_CHECKSUM                    |\n| PARSE_VCOL_EXPR                 |\n| PARTITION                         |\n| PRECISION                         |\n| PRIMARY                           |\n| PROCEDURE                         |\n| PURGE                             |\n| RANGE                             |\n| READ                              |\n| READS                             |\n| READ_WRITE                       |\n| REAL                              |\n| RECURSIVE                         |\n| REF_SYSTEM_ID                   |\n| REFERENCES                        |\n| REGEXP                            |\n| RELEASE                           |\n| RENAME                            |\n| REPEAT                            |\n| REPLACE                           |\n| REQUIRE                           |\n| RESIGNAL                          |\n| RESTRICT                          |\n| RETURN                            |\n| RETURNING                         |\n| REVOKE                            |\n| RIGHT                             |\n| RLIKE                             |\n| ROW_NUMBER (> 10.7)              |\n| ROWS                              |\n| SCHEMA                            |\n| SCHEMAS                           |\n| SECOND_MICROSECOND               |\n| SELECT                            |\n| SENSITIVE                         |\n| SEPARATOR                         |\n| SET                               |\n| SHOW                              |\n| SIGNAL                            |\n| SLOW                              |\n| SMALLINT                          |\n| SPATIAL                           |\n| SPECIFIC                          |\n| SQL                               |\n| SQLEXCEPTION                      |\n| SQLSTATE                          |\n| SQLWARNING                        |\n| SQL_BIG_RESULT                  |\n| SQL_CALC_FOUND_ROWS            |\n| SQL_SMALL_RESULT                |\n| SSL                               |\n| STARTING                          |\n| STATS_AUTO_RECALC               |\n| STATS_PERSISTENT                 |\n| STATS_SAMPLE_PAGES              |\n| STRAIGHT_JOIN                    |\n| TABLE                             |\n| TERMINATED                        |\n| THEN                              |\n| TINYBLOB                          |\n| TINYINT                           |\n| TINYTEXT                          |\n| TO                                |\n| TRAILING                          |\n| TRIGGER                           |\n| TRUE                              |\n| UNDO                              |\n| UNION                             |\n| UNIQUE                            |\n| UNLOCK                            |\n| UNSIGNED                          |\n| UPDATE                            |\n| USAGE                             |\n| USE                               |\n| USING                             |\n| UTC_DATE                         |\n| UTC_TIME                         |\n| UTC_TIMESTAMP                    |\n| VALUES                            |\n| VARBINARY                         |\n| VARCHAR                           |\n| VARCHARACTER                      |\n| VARYING                           |\n| VECTOR (> 11.6)                   |\n| WHEN                              |\n| WHERE                             |\n| WHILE                             |\n| WINDOW                            |\n| WITH                              |\n| WRITE                             |\n| XOR                               |\n| YEAR_MONTH                       |\n| ZEROFILL                          |\n\nExceptions\n\nSome keywords are exceptions for historical reasons, and are permitted as unquoted identifiers. These include:\n\n| Keyword                                                             |\n| ------------------------------------------------------------------- |\n| ACTION                                                              |\n| BIT                   |\n| DATE           |\n| ENUM                  |\n| NO                                                                  |\n| TEXT                  |\n| TIME           |\n| TIMESTAMP |\n\nOracle Mode\n\nIn Oracle mode, there are a number of extra reserved words:\n\n| Keyword          |\n| ---------------- |\n| BODY             |\n| ELSIF            |\n| GOTO             |\n| HISTORY          |\n| MINUS (> 10.6.0) |\n| OTHERS           |\n| PACKAGE          |\n| PERIOD           |\n| RAISE            |\n| ROWNUM           |\n| ROWTYPE          |\n| SYSDATE          |\n| SYSTEM           |\n| SYSTEM_TIME     |\n| VERSIONING       |\n| WITHOUT          |\n\nContextual Keywords and Parser Limitations\n\nThe lists above indicate words that are always reserved and must be quoted. Some keywords, though, are reserved for specific contexts. In most SQL statements, they operate normally, but in some cases, they activate unique parser rules.\n\nThe Oracle mode term SYSTEM is a prime example. Although it is not a fully reserved word, the parser expects the VERSIONING keyword to follow (as part of the SYSTEM VERSIONING clause for system-versioned tables), which results in a syntax error in an ALTER TABLE ... ADD command.\n\nExample of unexpected behavior\n\nThe following examples show how the keyword SYSTEM behaves as an identifier:\n\n``sql\nCREATE TABLE t1 (system INT);\n`\n\nThis statement works because SYSTEM is a valid column name in this situation.\n\nInvalid usage\n\n`sql\nALTER TABLE t1 ADD system VARCHAR(64);\n`\n\nThis statement fails due to a syntax error.\n\n`\nERROR 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 ''VARCHAR(64)'' at line 1\n`\n\nTo avoid any conflict, always quote such keywords when using them as identifiers in statements.\n\n`\nALTER TABLE t1 ADD system VARCHAR(64);\n`\n\nIt is recommended that all identifiers listed as keywords (including those indicated as non-reserved or version-specific) be quoted for maximum compatibility and to prevent unexpected parser errors, especially in ALTER statements.\n\nFunction Names\n\nIf the IGNORE_SPACE` SQL_MODE flag is set, function names become reserved words.\n\nURL: https://mariadb.com/docs/server/reference/sql-structure/sql-language-structure/reserved-words', '', 'https://mariadb.com/docs/server/reference/sql-structure/sql-language-structure/reserved-words');
INSERT INTO help_topic (help_topic_id, help_category_id, name, description, example, url) VALUES (995, 29, 'Schema Qualifiers', 'Description\n-----------\n\nMariaDB offers schema qualifiers that allow you to define how data types and functions are managed when SQL modes result in operational differences.\n\nThese qualifiers are used as prefixes and are part of the SQL language structure. These are not system databases or tables.&#x20;\n\nThe schema qualifiers listed below are supported:\n\n mariadb_schema\n oracle_schema\n\nBoth prefixes describe the same mechanism, however the behavior differs based on the desired compatibility.\n\nCertain SQL modes, such as SQL_MODE=ORACLE, affect how MariaDB understands data type and functions. MariaDB translates several data type names and function behaviors according to Oracle Database standards when SQL_MODE=ORACLE is active. This translation may lead to ambiguity: depending on the SQL mode in use, a data type or function name written without a qualifier could be interpreted differently.\n\nFor example, in Oracle mode, the data type DATE is interpreted as DATETIME. This behavior can be explicitly overridden at the statement level using schema qualifiers, without modifying the SQL mode session.\n\nVersion Support\n\n mariadb_schema for data type qualification is supported since:\n   MariaDB 10.3.24\n   MariaDB 10.4.14\n   MariaDB 10.5.5\n oracle_schema is supported as part of the same schema qualifier mechanism.\n Functional qualification using schema qualifiers is supported since:\n   MariaDB 10.6.17 (see MDEV-27744)\n\nWhy Schema Qualifiers are Needed\n\nSpecific SQL modes, for example SQL_MODE=ORACLE, determine how MariaDB handles data types and functions.\n\nThis may result in ambiguity when:\n\n Switching between SQL modes\n Evaluating table definitions using SHOW CREATE TABLE\n Syncing data across servers\n\nRegardless of the SQL mode that is currently in use, schema qualifiers provide explicit control over interpretation, ensuring reliable and consistent behavior.\n\nmariadb_schema\n\nThe mariadb_schema qualifier forces MariaDB-native interpretation of the data type or function, regardless of the active SQL mode.\n\nWhen the server sees the mariadb_schema qualifier, it disables sql_mode-specific data type translation and interprets the data type literally. For example, mariadb_schema.DATE is interpreted as the traditional MariaDB DATE data type, regardless of the current SQL mode.\n\nData Type Qualification\n\nIn Oracle mode, the DATE type is translated to DATETIME:\n\n``sql\nSET sql_mode=ORACLE;\n\nCREATE TABLE t1 (\nd DATE\n);\n`\n\nTo specifically use the MariaDB-native DATE type while in Oracle mode:\n\n`sql\nCREATE TABLE t1 (\n  d mariadb_schema.DATE\n);\n`\n\nExample\n\n`sql\nSET sql_mode=ORACLE;\n\nCREATE TABLE t1 (\n  d DATE,\n  d_m mariadb_schema.DATE\n);\n\nDESCRIBE t1;\n`\n\nOutput\n\n`sql\n+-------+----------+\n| Field | Type     | \n+-------+----------+\n| d     | datetime |\n| d_m   | date     |\n+-------+----------+\n`\n\noracle_schema\n\nThe oracle_schema qualifier enforces Oracle-compatible behavior of the data type or function, regardless of the active SQL mode. It supports Oracle semantics but acts similarly to mariadb_schema.\n\nFor example:\n\n In Oracle mode, the DATE data types behaves like DATETIME.\n Using oracle_schema.DATE ensures Oracle-compatible interpretation even when Oracle mode is not enabled.\n\nData Type Qualification\n\n`sql\nSET sql_mode=ORACLE;\n\nCREATE TABLE t1 (\n  d DATE,\n  d_m mariadb_schema.DATE,\n  d_o oracle_schema.DATE\n);\n\nDESCRIBE t1;\n`\n\nOutput\n\n`sql\n+-------+----------+\n| Field | Type     | \n+-------+----------+\n| d     | datetime |\n| d_m   | date     |\n| d_o   | datetime |\n+-------+----------+\n`\n\nUsing Both Qualifiers Together\n\nThe following example demonstrates how to use both qualifiers together in a single table definition to control data type behavior.&#x20;\n\nTo explicitly use Oracle-compatible behavior outside Oracle mode:\n\n`sql\nSET sql_mode=DEFAULT;\n\nCREATE TABLE t1 (\nd oracle_schema.DATE\n);\n`\n\nWhen running in Oracle mode, both qualifiers can be used to explicitly control behavior.\n\n`sql\nSET sql_mode=ORACLE;\n\nCREATE TABLE t1 (\nd DATE,                  # Oracle-compatible (stored as DATETIME)\nd_m mariadb_schema.DATE, # MariaDB-native DATE\nd_o oracle_schema.DATE   # Oracle-compatible DATE\n);\n\nDESCRIBE t1;\n`\n\nOutput\n\n`sql\n+-------+----------+------+-----+---------+-------+\n| Field | Type     | Null | Key | Default | Extra |\n+-------+----------+------+-----+---------+-------+\n| d     | datetime | YES  |     | NULL    |       |\n| d_m   | date     | YES  |     | NULL    |       |\n| d_o   | datetime | YES  |     | NULL    |       |\n+-------+----------+------+-----+---------+-------+  \n`\n\nFunction Qualification\n\nStarting with MariaDB 10.6.17, schema qualifiers can also be added to functions.&#x20;\n\nRegardless of the current SQL mode, this enables the explicit selection of MariaDB-native or Oracle-compatible behavior.\n\nExample syntax:\n\n`sql\nMariaDB-native function behavior in any SQL mode\nmariadb_schema.function_name(...) \n\nOracle-compatible function behavior in any SQL mode\noracle_schema.function_name(...)\n`\n\nBehavior\n\n mariadb_schema.function_name(...): MariaDB-native behavior\n oracle_schema.function_name(...): Oracle-compatible behavior\n\nNote: Function behavior varies depending on the SQL mode and function.\n\\\nDetailed function-level differences are not fully listed here and may differ by version.\n\nSHOW CREATE TABLE\n\nTo prevent ambiguity in data type interpretation, MariaDB may display schema qualifiers when SHOW CREATE TABLE is executed.\n\n`sql\nSET sql_mode=DEFAULT;\nCREATE OR REPLACE TABLE t1 (\n  d DATE\n);\nSET SQL_mode=ORACLE;\nSHOW CREATE TABLE t1;\n+-------+--------------------------------------------------------------+\n| Table | Create Table                                                 |\n+-------+--------------------------------------------------------------+\n| t1    | CREATE TABLE "t1" (                                          |\n|       |   "d" mariadb_schema.DATE DEFAULT NULL                       |\n|       |  )                                                           |\n+-------+--------------------------------------------------------------+\n`\n\nThe prefix is displayed to indicate that the column uses MariaDB''s native DATE type rather than the Oracle-compatible translated version.\n\nThe mariadb_schema prefix is only displayed when the data type is ambiguous. When the type is non-ambiguous or the SQL mode is set to default, it is not displayed.\n\nThis makes it easier to determine whether a column uses MariaDB-native or Oracle-compatible semantics.\n\nHistory\n\nWhen running with SQL_MODE=ORACLE, MariaDB server translates the DATE data type to DATETIME, for Oracle compatibility.&#x20;\n\n`sql\nSET SQL_mode=ORACLE;\nCREATE OR REPLACE TABLE t1 (\n  d DATE\n);\nSHOW CREATE TABLE t1;\n+-------+--------------------------------------------------------------+\n| Table | Create Table                                                 |\n+-------+--------------------------------------------------------------+\n| t1    | CREATE TABLE "t1" (                                          |\n|       |   "d" datetime DEFAULT NULL                       |\n|       |  )                                                           |\n+-------+--------------------------------------------------------------+\n`\n\nNote: DATE was converted to DATETIME.\n\nThis translation can cause ambiguity. For example, if a table is created in default SQL mode and then evaluated in Oracle mode:\n\n`sql\nSET sql_mode=DEFAULT;\nCREATE OR REPLACE TABLE t1 (\n  d DATE\n);\nSET SQL_mode=ORACLE;\nSHOW CREATE TABLE t1;\n`\n\nBefore schema qualifiers were introduced, this would display:\n\n`sql\nCREATE TABLE "t1" (\n  "d" DATE DEFAULT NULL\n);\n`\n\nThis created two problems:\n\n It was not clear whether DATE referred to the MariaDB DATE type or the Oracle-compatible DATETIME.\n It broke replication, causing a data type mismatch between the master and the slave. (see MDEV-19632).\n\nTo address this problem, MariaDB included schema qualifiers to explicitly qualify data types:\n\n`sql\nSET sql_mode=DEFAULT;\nCREATE OR REPLACE TABLE t1 (\n  d DATE\n);\nSET SQL_mode=ORACLE;\nSHOW CREATE TABLE t1;\n+-------+--------------------------------------------------------------+\n| Table | Create Table                                                 |\n+-------+--------------------------------------------------------------+\n| t1    | CREATE TABLE "t1" (                                          |\n|       |   "d" mariadb_schema.DATE DEFAULT NULL                       |\n|       |  )                                                           |\n+-------+--------------------------------------------------------------+\n``\n\nThis enables consistent and unambiguous behavior across all SQL modes.\n\nURL: https://mariadb.com/docs/server/reference/sql-structure/sql-language-structure/schema-qualifiers', '', 'https://mariadb.com/docs/server/reference/sql-structure/sql-language-structure/schema-qualifiers');
INSERT INTO help_topic (help_topic_id, help_category_id, name, description, example, url) VALUES (996, 29, 'Boolean Literals', 'Description\n-----------\n\nIn 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.\n\nThese 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).\n\nThe IS operator accepts a third constant exists: UNKNOWN. It is always a synonym of NULL.\n\nTRUE and FALSE are reserved words, while UNKNOWN is not.\n\nURL: https://mariadb.com/docs/server/reference/sql-structure/sql-language-structure/sql-language-structure-boolean-literals', '', 'https://mariadb.com/docs/server/reference/sql-structure/sql-language-structure/sql-language-structure-boolean-literals');
INSERT INTO help_topic (help_topic_id, help_category_id, name, description, example, url) VALUES (997, 29, 'String Literals', 'Description\n-----------\n\nStrings are sequences of characters and enclosed with quotes.\n\nThe syntax is:\n\n``sql\n[_charset_name]''string'' [COLLATE collation_name]\n`\n\nFor example:\n\n`sql\n''The MariaDB Foundation''\n_utf8 ''Foundation'' COLLATE utf8_unicode_ci;\n`\n\nStrings can either be enclosed in single quotes or in double quotes (the same character must be used to both open and close the string).\n\nThe 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.\n\nStrings that are next to each other are automatically concatenated. The following are equivalent:\n\n`\n''The '' ''MariaDB '' ''Foundation''\n`\n\n`\n''The MariaDB Foundation''\n`\n\nThe \\ (backslash character) is used to escape characters (unless the SQL_MODE hasn''t been set to NO_BACKSLASH_ESCAPES):\n\n`\n''MariaDB''s new features''\n`\n\nThat 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:\n\n`\n''MariaDB\\''s new features''\n`\n\nThat is now a valid string, and if displayed, will appear without the backslash.\n\n`sql\nSELECT ''MariaDB\\''s new features'';\n+------------------------+\n| MariaDB''s new features |\n+------------------------+\n| MariaDB''s new features |\n+------------------------+\n`\n\nAnother way to escape the quoting character is repeating it twice:\n\n`sql\nSELECT ''I''''m here'', """Double""";\n+----------+----------+\n| I''m here | "Double" |\n+----------+----------+\n| I''m here | "Double" |\n+----------+----------+\n`\n\nEscape Sequences\n\nThere are other escape sequences:\n\n| Escape sequence | Character                                           |\n| --------------- | --------------------------------------------------- |\n| \\0              | ASCII NUL (0x00).                                   |\n| ''               | Single quote (“''”).                                 |\n| "               | Double quote (“"”).                                 |\n| \\b              | Backspace.                                          |\n|                 | Newline, or linefeed,.                              |\n|                 | Carriage return.                                    |\n|                 | Tab.                                                |\n| \\Z              | ASCII 26 (Control+Z). See note following the table. |\n| \\\\              | Backslash (“\\”).                                    |\n| %               | “%” character. See note following the table.        |\n| _              | A “_” character. See note following the table.     |\n\nEscaping the % and _ characters can be necessary when using the LIKE operator, which treats them as special characters.\n\nThe 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).\n\nBackslash (\\`), 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.\n\nURL: https://mariadb.com/docs/server/reference/sql-structure/sql-language-structure/string-literals', '', 'https://mariadb.com/docs/server/reference/sql-structure/sql-language-structure/string-literals');
INSERT INTO help_topic (help_topic_id, help_category_id, name, description, example, url) VALUES (998, 29, 'Table Value Constructors', 'Syntax\n------\n\nVALUES ( row_value[, row_value...]), (...)...\n\nDescription\n-----------\n\nIn Unions, Views, and subqueries, 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.\n\nExamples\n--------\n\nCREATE TABLE test.t1 (val1 INT, val2 INT);\nINSERT INTO test.t1 VALUES(5, 8), (3, 4), (1, 2);\n\nSELECT * FROM test.t1\nUNION\nVALUES (70, 90), (100, 110);\n\n+------+------+\n| val1 | val2 |\n+------+------+\n|    5 |    8 | \n|    3 |    4 |\n|    1 |    2 |\n|   70 |   90 |\n|  100 |  110 |\n+------+------+\n\nURL: https://mariadb.com/docs/server/reference/sql-structure/sql-language-structure/table-value-constructors', '', 'https://mariadb.com/docs/server/reference/sql-structure/sql-language-structure/table-value-constructors');
INSERT INTO help_topic (help_topic_id, help_category_id, name, description, example, url) VALUES (999, 29, 'User-Defined Variables', 'Description\n-----------\n\nUser-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.\n\nUser-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:\n\n @var_name\n @''var_name''\n @"var_name"\n\nThese characters can be escaped as usual.\n\nUser-variables names are case insensitive.\n\nUser-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:\n\n SET statement;\n := operator within a SQL statement;\n SELECT ... INTO.\n\nSince user-defined variables type cannot be declared, the only way to force their type is using CAST() or CONVERT():\n\n``sql\nSET @str = CAST(123 AS CHAR(5));\n`\n\nIf a variable has not been used yet, its value is NULL:\n\n`sql\nSELECT @x IS NULL;\n+------------+\n| @x IS NULL |\n+------------+\n|          1 |\n+------------+\n`\n\nIt 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.\n\nUser-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.\n\nThey must be used to PREPARE a prepared statement:\n\n`sql\n@sql = ''DELETE FROM my_table WHERE c>1;'';\nPREPARE stmt FROM @sql;\nEXECUTE stmt;\nDEALLOCATE PREPARE stmt;\n`\n\nAnother common use is to include a counter in a query:\n\n`sql\nSET @var = 0;\nSELECT a, b, c, (@var:=@var+1) AS counter FROM my_table;\n`\n\nViewing\n\nUser-defined variables can be viewed by either querying the USER_VARIABLES, or by running SHOW USER_VARIABLES`.\n\nFlushing User-Defined Variables\n\nUser-defined variables are reset and the Information Schema table emptied with the FLUSH USER_VARIABLES statement.\n\nExamples\n--------\n\nSET @v1 = 0;\nSET @v2 = ''abc'';\nSET @v3 = CAST(123 AS CHAR(5));\n\nSHOW USER_VARIABLES;\n+---------------+-------+\n| Variable_name | Value |\n+---------------+-------+\n| v3            | 123   |\n| v2            | abc   |\n| v1            | 0     |\n+---------------+-------+\n\nSELECT  FROM information_schema.USER_VARIABLES ORDER BY VARIABLE_NAME;\n+---------------+----------------+---------------+--------------------+\n| VARIABLE_NAME | VARIABLE_VALUE | VARIABLE_TYPE | CHARACTER_SET_NAME |\n+---------------+----------------+---------------+--------------------+\n| v1            | 0              | INT           | latin1             |\n| v2            | abc            | VARCHAR       | utf8               |\n| v3            | 123            | VARCHAR       | utf8               |\n+---------------+----------------+---------------+--------------------+\n\nFLUSH USER_VARIABLES;\n\nSELECT  FROM information_schema.USER_VARIABLES ORDER BY VARIABLE_NAME;\nEmpty set (0.000 sec)\n\nURL: https://mariadb.com/docs/server/reference/sql-structure/sql-language-structure/user-defined-variables', '', 'https://mariadb.com/docs/server/reference/sql-structure/sql-language-structure/user-defined-variables');
INSERT INTO help_topic (help_topic_id, help_category_id, name, description, example, url) VALUES (1000, 35, 'Temporal Tables', 'Description\n-----------\n\nsystem-versioned-tables.md\n\napplication-time-periods.md\n\nbitemporal-tables.md\n\nURL: https://mariadb.com/docs/server/reference/sql-structure/temporal-tables/README', '', 'https://mariadb.com/docs/server/reference/sql-structure/temporal-tables/README');
INSERT INTO help_topic (help_topic_id, help_category_id, name, description, example, url) VALUES (1001, 35, 'Application-Time Periods', 'Description\n-----------\n\nExtending system-versioned tables, MariaDB 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.\n\nUsing 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.\n\nCreating Tables with Time Periods\n\nTo create a table with a time period, use a CREATE TABLE statement with the PERIOD table option.\n\n``sql\nCREATE TABLE t1(\n   name VARCHAR(50), \n   date_1 DATE,\n   date_2 DATE,\n   PERIOD FOR date_period(date_1, date_2));\n`\n\nThis creates a table with a time_period period and populates the table with some basic temporal values.\n\nExamples are available in the MariaDB Server source code, at mysql-test/suite/period/r/create.result.\n\nAdding and Removing Time Periods\n\nThe ALTER TABLE statement now supports syntax for adding and removing time periods from a table. To add a period, use the ADD PERIOD clause:\n\n`sql\nCREATE OR REPLACE TABLE rooms (\n room_number INT,\n guest_name VARCHAR(255),\n checkin DATE,\n checkout DATE\n );\n\nALTER TABLE rooms ADD PERIOD FOR p(checkin,checkout);\n`\n\nTo remove a period, use the DROP PERIOD clause:\n\n`sql\nALTER TABLE rooms DROP PERIOD FOR p;\n`\n\nBoth ADD PERIOD and DROP PERIOD clauses include an option to handle whether the period already exists:\n\n`sql\nALTER TABLE rooms ADD PERIOD IF NOT EXISTS FOR p(checkin,checkout);\n\nALTER TABLE rooms DROP PERIOD IF EXISTS FOR p;\n`\n\nDeletion by Portion\n\nYou can also remove rows that fall within certain time periods.\n\nWhen MariaDB executes a DELETE FOR PORTION statement, it removes the row:\n\n When the row period falls completely within the delete period, it removes the row.\n When the row period overlaps the delete period, it shrinks the row, removing the overlap from the first or second row period value.\n 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.\n\nTo test this, first populate the table with some data to operate on:\n\n`sql\nCREATE TABLE t1(\n   name VARCHAR(50), \n   date_1 DATE,\n   date_2 DATE,\n   PERIOD FOR date_period(date_1, date_2));\n\nINSERT INTO t1 (name, date_1, date_2) VALUES\n    (''a'', ''1999-01-01'', ''2000-01-01''),\n    (''b'', ''1999-01-01'', ''2018-12-12''),\n    (''c'', ''1999-01-01'', ''2017-01-01''),\n    (''d'', ''2017-01-01'', ''2019-01-01'');\n\nSELECT  FROM t1;\n+------+------------+------------+\n| name | date_1     | date_2     |\n+------+------------+------------+\n| a    | 1999-01-01 | 2000-01-01 |\n| b    | 1999-01-01 | 2018-12-12 |\n| c    | 1999-01-01 | 2017-01-01 |\n| d    | 2017-01-01 | 2019-01-01 |\n+------+------------+------------+\n`\n\nThen, run the DELETE FOR PORTION statement:\n\n`sql\nDELETE FROM t1\nFOR PORTION OF date_period\n    FROM ''2001-01-01'' TO ''2018-01-01'';\nQuery OK, 3 rows affected (0.028 sec)\n\nSELECT  FROM t1 ORDER BY name;\n+------+------------+------------+\n| name | date_1     | date_2     |\n+------+------------+------------+\n| a    | 1999-01-01 | 2000-01-01 |\n| b    | 1999-01-01 | 2001-01-01 |\n| b    | 2018-01-01 | 2018-12-12 |\n| c    | 1999-01-01 | 2001-01-01 |\n| d    | 2018-01-01 | 2019-01-01 |\n+------+------------+------------+\n`\n\nHere:\n\n a is unchanged, as the range falls entirely out of the specified portion to be deleted.\n b, with values ranging from 1999 to 2018, is split into two rows, 1999 to 2000 and 2018-01 to 2018-12 (i.e. one extra row has been inserted).\n 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.\n 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.\n\nThe DELETE FOR PORTION statement has the following restrictions\n\n The FROM...TO clause must be constant.\n Multi-delete is not supported.\n\nIf there are DELETE or INSERT triggers, any matched row is deleted, and then one or two rows are inserted. If the record is deleted completely, nothing is inserted.\n\nUpdating by Portion\n\nThe UPDATE syntax now supports UPDATE FOR PORTION, which modifies rows based on their occurrence in a range:\n\nTo test it, first populate the table with some data:\n\n`sql\nTRUNCATE t1;\n\nINSERT INTO t1 (name, date_1, date_2) VALUES\n    (''a'', ''1999-01-01'', ''2000-01-01''),\n    (''b'', ''1999-01-01'', ''2018-12-12''),\n    (''c'', ''1999-01-01'', ''2017-01-01''),\n    (''d'', ''2017-01-01'', ''2019-01-01'');\n\nSELECT  FROM t1;\n+------+------------+------------+\n| name | date_1     | date_2     |\n+------+------------+------------+\n| a    | 1999-01-01 | 2000-01-01 |\n| b    | 1999-01-01 | 2018-12-12 |\n| c    | 1999-01-01 | 2017-01-01 |\n| d    | 2017-01-01 | 2019-01-01 |\n+------+------------+------------+\n`\n\nThen run the update:\n\n`sql\nUPDATE t1 FOR PORTION OF date_period\n  FROM ''2000-01-01'' TO ''2018-01-01'' \nSET name = CONCAT(name,''_original'');\n\nSELECT  FROM t1 ORDER BY name;\n+------------+------------+------------+\n| name       | date_1     | date_2     |\n+------------+------------+------------+\n| a          | 1999-01-01 | 2000-01-01 |\n| b          | 1999-01-01 | 2000-01-01 |\n| b          | 2018-01-01 | 2018-12-12 |\n| b_original | 2000-01-01 | 2018-01-01 |\n| c          | 1999-01-01 | 2000-01-01 |\n| c_original | 2000-01-01 | 2017-01-01 |\n| d          | 2018-01-01 | 2019-01-01 |\n| d_original | 2017-01-01 | 2018-01-01 |\n+------------+------------+------------+\n`\n\n a is unchanged, as the range falls entirely out of the specified portion to be updated.\n For b, with years ranging from 1999 to 2018, two extra rows are inserted, with ranges 1999-01 to 2000-01 and 2018-01 to 2018-12. The original row''s period has been shrunk to years 2000 and 2018, and the name field has got "_original" appended.\n c, with values ranging from 1999 to 2017, where only the upper value falls within the portion to be updated, has been shrunk to 1999 to 2001.\n d, with values ranging from 2017 to 2019, where only the lower value falls within the portion to be updated, has been shrunk to 2018 to 2019.\n Original rows affected by the update have "_original" appended to the name.\n\nThe UPDATE FOR PORTION statement has the following limitations:\n\n The operation cannot modify the two temporal columns used by the time period.\n The operation cannot reference period values in the SET expression.\n FROM...TO expressions must be constant.\n\nWITHOUT OVERLAPS\n\nThis clause is available from MariaDB 10.5.3.\n\nWITHOUT OVERLAPS allows 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.\n\nTake the following example, an application time period table for a booking system:\n\n`sql\nCREATE OR REPLACE TABLE rooms (\n room_number INT,\n guest_name VARCHAR(255),\n checkin DATE,\n checkout DATE,\n PERIOD FOR p(checkin,checkout)\n );\n\nINSERT INTO rooms VALUES \n (1, ''Regina'', ''2020-10-01'', ''2020-10-03''),\n (2, ''Cochise'', ''2020-10-02'', ''2020-10-05''),\n (1, ''Nowell'', ''2020-10-03'', ''2020-10-07''),\n (2, ''Eusebius'', ''2020-10-04'', ''2020-10-06'');\n`\n\nOur 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 to specify this constraint in the table definition.\n\n`sql\nCREATE OR REPLACE TABLE rooms (\n room_number INT,\n guest_name VARCHAR(255),\n checkin DATE,\n checkout DATE,\n PERIOD FOR p(checkin,checkout),\n UNIQUE (room_number, p WITHOUT OVERLAPS)\n );\n\nINSERT INTO rooms VALUES \n (1, ''Regina'', ''2020-10-01'', ''2020-10-03''),\n (2, ''Cochise'', ''2020-10-02'', ''2020-10-05''),\n (1, ''Nowell'', ''2020-10-03'', ''2020-10-07''),\n (2, ''Eusebius'', ''2020-10-04'', ''2020-10-06'');\nERROR 1062 (23000): Duplicate entry ''2-2020-10-06-2020-10-04'' for key ''room_number''\n`\n\nInformation Schema\n\nInformation Schema support for application time period tables is available from MariaDB 11.4.\n\nInformation Schema contains the following support for application time period tables:\n\n INFORMATION_SCHEMA.PERIODS view.\n INFORMATION_SCHEMA.KEY_PERIOD_USAGE view.\n Additional columns IS_SYSTEM_TIME_PERIOD_START and IS_SYSTEM_TIME_PERIOD_END in the INFORMATION_SCHEMA.COLUMNS view.\n\nFurther Examples\n\nThe implicit change from NULL to NOT NULL:\n\n`sql\nCREATE TABLE t2 (\n  id int(11) DEFAULT NULL,\n  d1 datetime DEFAULT NULL,\n  d2 datetime DEFAULT NULL\n) ENGINE=InnoDB DEFAULT CHARSET=latin1;\n\nALTER TABLE t2 ADD PERIOD FOR p(d1,d2);\n\nSHOW CREATE TABLE t2\\G\n************************ 1. row ***********************\n       Table: t2\nCreate Table: CREATE TABLE t2 (\n //a// is unchanged, as the range falls entirely out of the specified portion to be updated.\n For //b//, with years ranging from 1999 to 2018, two extra rows are inserted, with ranges 1999-01 to 2000-01 and 2018-01 to 2018-12. The original row''s period has been shrunk to years 2000 and 2018, and the _name_ field has got "_original" appended.\n //c//, with values ranging from 1999 to 2017, where only the upper value falls within the portion to be updated, has been shrunk to 1999 to 2001.\n //d//, with values ranging from 2017 to 2019, where only the lower value falls within the portion to be updated, has been shrunk to 2018 to 2019. \n Original rows affected by the update have "_original" appended to the ##name## field.\n  id int(11) DEFAULT NULL,\n  d1 datetime NOT NULL,\n  d2 datetime NOT NULL,\n  PERIOD FOR p (d1, d2)\n) ENGINE=InnoDB DEFAULT CHARSET=latin1\n`\n\nDue to this constraint, trying to add a time period where NULL data already exist fails:\n\n`sql\nCREATE OR REPLACE TABLE t2 (\n  id int(11) DEFAULT NULL,\n  d1 datetime DEFAULT NULL,\n  d2 datetime DEFAULT NULL\n) ENGINE=InnoDB DEFAULT CHARSET=latin1;\n\nINSERT INTO t2(id) VALUES(1);\n\nALTER TABLE t2 ADD PERIOD FOR p(d1,d2);\nERROR 1265 (01000): Data truncated for column ''d1'' at row 1\n``\n\nURL: https://mariadb.com/docs/server/reference/sql-structure/temporal-tables/application-time-periods', '', 'https://mariadb.com/docs/server/reference/sql-structure/temporal-tables/application-time-periods');
INSERT INTO help_topic (help_topic_id, help_category_id, name, description, example, url) VALUES (1002, 35, 'Bitemporal Tables', 'Description\n-----------\n\nBitemporal tables are tables that use versioning both at the system and application-time period levels.\n\nUsing Bitemporal Tables\n\nTo create a bitemporal table, use:\n\n``sql\nCREATE TABLE test.t3 (\n   date_1 DATE,\n   date_2 DATE,\n   row_start TIMESTAMP(6) AS ROW START INVISIBLE,\n   row_end TIMESTAMP(6) AS ROW END INVISIBLE,\n   PERIOD FOR application_time(date_1, date_2),\n   PERIOD FOR system_time(row_start, row_end))\nWITH SYSTEM VERSIONING;\n`\n\nNote that, while system_time here is also a time period, it cannot be used in DELETE FOR PORTION or UPDATE FOR PORTION statements:\n\n`sql\nDELETE FROM test.t3 \nFOR PORTION OF system_time \n    FROM ''2000-01-01'' TO ''2018-01-01'';\nERROR 42000: You have an error in your SQL syntax; check the manual that corresponds \n  to your MariaDB server version for the right syntax to use near\n  ''of system_time from ''2000-01-01'' to ''2018-01-01'''' at line 1\n``\n\nURL: https://mariadb.com/docs/server/reference/sql-structure/temporal-tables/bitemporal-tables', '', 'https://mariadb.com/docs/server/reference/sql-structure/temporal-tables/bitemporal-tables');
INSERT INTO help_topic (help_topic_id, help_category_id, name, description, example, url) VALUES (1003, 35, 'System-Versioned Tables', 'Description\n-----------\n\nMariaDB 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).\n\nSystem-Versioned Tables\n\nSystem-versioned tables store the history of all changes, not only data which is currently applicable. 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:\n\n Forensic analysis & legal requirements to store data for N years.\n Data analytics (retrospective, trends etc.), e.g. to get your staff information as of one year ago.\n Point-in-time recovery - recover a table state as of particular point in time.\n\nSystem-versioned tables were first introduced in the SQL:2011 standard.\n\nThe keyword SYSTEM is used in the SYSTEM VERSIONING clause. Using SYSTEM as an unquoted column name in an ALTER TABLE is not permitted by some parser rules. Even though SYSTEM is not a fully reserved word in Oracle mode, the ADD statement will result in a syntax error.\n\nAlways provide SYSTEM when using it as a column name: system. See the Reserved Words page for additional examples and a detailed explanation.\n\nCreating a System-Versioned Table\n\nThe 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:\n\n``sql\nCREATE TABLE t(\n   x INT,\n   start_timestamp TIMESTAMP(6) GENERATED ALWAYS AS ROW START,\n   end_timestamp TIMESTAMP(6) GENERATED ALWAYS AS ROW END,\n   PERIOD FOR SYSTEM_TIME(start_timestamp, end_timestamp)\n) WITH SYSTEM VERSIONING;\n`\n\nIn MariaDB, you can use a simplified syntax:\n\n`sql\nCREATE TABLE t (\n   x INT\n) WITH SYSTEM VERSIONING;\n`\n\nIn 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:\n\n`sql\nSELECT x, ROW_START, ROW_END FROM t;\n`\n\nAdding or Removing System Versioning To/From a Table\n\nAn existing table can be altered to enable system versioning for it.\n\n`sql\nCREATE TABLE t(\n  x INT\n);\n`\n\n`sql\nALTER TABLE t ADD SYSTEM VERSIONING;\n`\n\n`sql\nSHOW CREATE TABLE t\\G\n************************ 1. row *********************\n       Table: t\nCreate Table: CREATE TABLE t (\n  x int(11) DEFAULT NULL\n) ENGINE=InnoDB DEFAULT CHARSET=latin1 WITH SYSTEM VERSIONING\n`\n\nSimilarly, system versioning can be removed from a table:\n\n`sql\nALTER TABLE t DROP SYSTEM VERSIONING;\n`\n\n`sql\nSHOW CREATE TABLE t\\G\n********************* 1. row *********************\n       Table: t\nCreate Table: CREATE TABLE t (\n  x int(11) DEFAULT NULL\n) ENGINE=InnoDB DEFAULT CHARSET=latin1\n`\n\nYou can also add system versioning with all columns created explicitly:\n\n`sql\nALTER TABLE t ADD COLUMN ts TIMESTAMP(6) GENERATED ALWAYS AS ROW START,\n              ADD COLUMN te TIMESTAMP(6) GENERATED ALWAYS AS ROW END,\n              ADD PERIOD FOR SYSTEM_TIME(ts, te),\n              ADD SYSTEM VERSIONING;\n`\n\n`sql\nSHOW CREATE TABLE t\\G\n********************* 1. row *********************\n       Table: t\nCreate Table: CREATE TABLE t (\n  x int(11) DEFAULT NULL,\n  ts timestamp(6) GENERATED ALWAYS AS ROW START,\n  te timestamp(6) GENERATED ALWAYS AS ROW END,\n  PERIOD FOR SYSTEM_TIME (ts, te)\n) ENGINE=InnoDB DEFAULT CHARSET=latin1 WITH SYSTEM VERSIONING\n`\n\nMariaDB starting with 11.7\n\nIt is possible to convert a versioned table from implicit to explicit row_start/row_end columns. Note that, in order to do any ALTER on a system versioned table, system_versioning_alter_history must be set to KEEP.\n\n`sql\nCREATE OR REPLACE TABLE t1 (x INT) WITH SYSTEM VERSIONING;\n\nSET system_versioning_alter_history = keep;\n\nALTER TABLE t1 ADD COLUMN rs TIMESTAMP(6) AS ROW START, \n  ADD COLUMN re TIMESTAMP(6) AS ROW END, ADD PERIOD FOR SYSTEM_TIME (rs,re)\n`\n\nIt is not possible to convert a versioned table from implicit to explicit row_start/row_end columns. Doing so results in a duplicate row error:\n\n`sql\nCREATE OR REPLACE TABLE t1 (x INT) WITH SYSTEM VERSIONING;\n\nSET system_versioning_alter_history = keep;\n\nALTER TABLE t1 ADD COLUMN rs TIMESTAMP(6) AS ROW START, \n  ADD COLUMN re TIMESTAMP(6) AS ROW END, ADD PERIOD FOR SYSTEM_TIME (rs,re);\n\nERROR 4134 (HY000): Duplicate ROW START column rs\n`\n\nInserting Data\n\nWhen 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:\n\n`sql\nSELECT NOW();\n+---------------------+\n| NOW()               |\n+---------------------+\n| 2022-10-24 23:09:38 |\n+---------------------+\n \nINSERT INTO t VALUES(1);\n \nSET @@timestamp = UNIX_TIMESTAMP(''2033-10-24'');\n\nINSERT INTO t VALUES(2);\n \nSET @@timestamp = default;\n\nINSERT INTO t VALUES(3);\n \nSELECT a,row_start,row_end FROM t;\n+------+----------------------------+----------------------------+\n| a    | row_start                  | row_end                    |\n+------+----------------------------+----------------------------+\n|    1 | 2022-10-24 23:09:38.951347 | 2038-01-19 05:14:07.999999 |\n|    2 | 2033-10-24 00:00:00.000000 | 2038-01-19 05:14:07.999999 |\n|    3 | 2022-10-24 23:09:38.961857 | 2038-01-19 05:14:07.999999 |\n+------+----------------------------+----------------------------+\n`\n\nQuerying Historical Data\n\nSELECT\n\nTo 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:\n\n AS OF is used to see the table as it was at a specific point in time in the past:\n\n`sql\nSELECT  FROM t FOR SYSTEM_TIME AS OF TIMESTAMP''2016-10-09 08:07:06'';\n`\n\n 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.\n\n`sql\nSELECT  FROM t FOR SYSTEM_TIME BETWEEN (NOW() - INTERVAL 1 YEAR) AND NOW();\n`\n\n 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.\n\n`sql\nSELECT  FROM t FOR SYSTEM_TIME FROM ''2016-01-01 00:00:00'' TO ''2017-01-01 00:00:00'';\n`\n\nAdditionally, MariaDB implements a non-standard extension.\n\n ALL will show all rows, historical and current.\n\n`sql\nSELECT  FROM t FOR SYSTEM_TIME ALL;\n`\n\nIf the FOR SYSTEM_TIME clause is not used, the table shows the _current_ data. This is usually the same as if you had specified FOR SYSTEM_TIME AS OF CURRENT_TIMESTAMP, unless you''ve adjusted the _row_start_ value:\n\n`sql\nCREATE OR REPLACE TABLE t (a int) WITH SYSTEM VERSIONING;\n\nSELECT NOW();\n+---------------------+\n| NOW()               |\n+---------------------+\n| 2022-10-24 23:43:37 |\n+---------------------+\n\nINSERT INTO t VALUES (1);\n\nSET @@timestamp = UNIX_TIMESTAMP(''2033-03-03'');\n\nINSERT INTO t VALUES (2);\n\nDELETE FROM t;\n\nSET @@timestamp = default;\n\nSELECT a, row_start, row_end FROM t FOR SYSTEM_TIME ALL;\n+------+----------------------------+----------------------------+\n| a    | row_start                  | row_end                    |\n+------+----------------------------+----------------------------+\n|    1 | 2022-10-24 23:43:37.192725 | 2033-03-03 00:00:00.000000 |\n|    2 | 2033-03-03 00:00:00.000000 | 2033-03-03 00:00:00.000000 |\n+------+----------------------------+----------------------------+\n2 rows in set (0.000 sec)\n\nSELECT a, row_start, row_end FROM t FOR SYSTEM_TIME AS OF CURRENT_TIMESTAMP;\n+------+----------------------------+----------------------------+\n| a    | row_start                  | row_end                    |\n+------+----------------------------+----------------------------+\n|    1 | 2022-10-24 23:43:37.192725 | 2033-03-03 00:00:00.000000 |\n+------+----------------------------+----------------------------+\n1 row in set (0.000 sec)\n\nSELECT a, row_start, row_end FROM t;\nEmpty set (0.001 sec)\n`\n\nIf the FOR SYSTEM_TIME clause is not used, the table shows the _current_ data. This is usually the same as if you had specified FOR SYSTEM_TIME AS OF CURRENT_TIMESTAMP, unless you''ve adjusted the _row_start_ value (only possible by setting the secure_timestamp variable):\n\n`sql\nCREATE OR REPLACE TABLE t (a int) WITH SYSTEM VERSIONING;\n\nSELECT NOW();\n+---------------------+\n| NOW()               |\n+---------------------+\n| 2022-10-24 23:43:37 |\n+---------------------+\n\nINSERT INTO t VALUES (1);\n\nSET @@timestamp = UNIX_TIMESTAMP(''2033-03-03'');\n\nINSERT INTO t VALUES (2);\n\nDELETE FROM t;\n\nSET @@timestamp = default;\n\nSELECT a, row_start, row_end FROM t FOR SYSTEM_TIME ALL;\n+------+----------------------------+----------------------------+\n| a    | row_start                  | row_end                    |\n+------+----------------------------+----------------------------+\n|    1 | 2022-10-24 23:43:37.192725 | 2033-03-03 00:00:00.000000 |\n|    2 | 2033-03-03 00:00:00.000000 | 2033-03-03 00:00:00.000000 |\n+------+----------------------------+----------------------------+\n2 rows in set (0.000 sec)\n\nSELECT a, row_start, row_end FROM t FOR SYSTEM_TIME AS OF CURRENT_TIMESTAMP;\n+------+----------------------------+----------------------------+\n| a    | row_start                  | row_end                    |\n+------+----------------------------+----------------------------+\n|    1 | 2022-10-24 23:43:37.192725 | 2033-03-03 00:00:00.000000 |\n+------+----------------------------+----------------------------+\n1 row in set (0.000 sec)\n\nSELECT a, row_start, row_end FROM t;\nEmpty set (0.001 sec)\n`\n\nViews and Subqueries\n\nWhen a system-versioned table 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:\n\n`sql\nCREATE VIEW v1 AS SELECT  FROM t FOR SYSTEM_TIME AS OF TIMESTAMP''2016-10-09 08:07:06'';\n`\n\nOr:\n\n`sql\nCREATE VIEW v1 AS SELECT  FROM t;\nSELECT  FROM v1 FOR SYSTEM_TIME AS OF TIMESTAMP''2016-10-09 08:07:06'';\n`\n\nUse in Replication and Binary Logs\n\nTables 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 master retries an SQL statement on the slave.\n\nSpecifically, 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.\n\nTo mitigate this with MariaDB Replication, set the secure_timestamp system variable to YES on the slave. When set, the slave 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.\n\nTransaction-Precise History in InnoDB\n\nA 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.\n\nFor 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.\n\nMariaDB 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.\n\nTo 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):\n\n`sql\nCREATE TABLE t(\n   x INT,\n   start_trxid BIGINT UNSIGNED GENERATED ALWAYS AS ROW START,\n   end_trxid BIGINT UNSIGNED GENERATED ALWAYS AS ROW END,\n   PERIOD FOR SYSTEM_TIME(start_trxid, end_trxid)\n) WITH SYSTEM VERSIONING;\n`\n\nThese columns must be specified explicitly, but they can be made INVISIBLE to avoid cluttering SELECT  output.\n\nNote that if you are using an engine that does not support system versioning with transaction ids, you will get an error like "start_trxid must be of type TIMESTAMP(6) for system-versioned table t".\n\nWhen one uses transaction-precise history, one can optionally use transaction identifiers in the FOR SYSTEM_TIME clause:\n\n`sql\nSELECT  FROM t FOR SYSTEM_TIME AS OF TRANSACTION 12345;\n`\n\nThis shows the data, exactly as it was seen by the transaction with the identifier 12345.\n\nData for this feature is stored in the mysql.transaction_registry table.\n\nLimitations\n\nPARTITION BY SYSTEM_TIME is not supported when using transaction-precise system versioning. Transaction-precise history tracks row versions using transaction identifiers instead of timestamps, so, SYSTEM_TIME cannot be used to partition transaction-precise system history. If partitioning is required, use the default timestamp-based versioning.\n\nStoring the History Separately\n\nWhen 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.\n\nThis 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.\n\nThis example shows how to create such a partitioned table:\n\n`sql\nCREATE TABLE t (x INT) WITH SYSTEM VERSIONING\n  PARTITION BY SYSTEM_TIME (\n    PARTITION p_hist HISTORY,\n    PARTITION p_cur CURRENT\n  );\n`\n\nIn 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.\n\nPartitioning by SYSTEM_TIME also supports automatic partition rotation. You can rotate historical partitions by time or by size. This example shows how to rotate partitions by size:\n\n`sql\nCREATE TABLE t (x INT) WITH SYSTEM VERSIONING\n  PARTITION BY SYSTEM_TIME LIMIT 100000 (\n    PARTITION p0 HISTORY,\n    PARTITION p1 HISTORY,\n    PARTITION pcur CURRENT\n  );\n`\n\nMariaDB starts writing history rows into partition p0, and at the end of the statement that wrote the 100000th row, MariaDB will s\n\n[Truncated — full content at mariadb.com/docs]', '', 'https://mariadb.com/docs/server/reference/sql-structure/temporal-tables/system-versioned-tables');
INSERT INTO help_topic (help_topic_id, help_category_id, name, description, example, url) VALUES (1004, 35, 'Vectors', 'Description\n-----------\n\nvector-overview.md\n\ncreate-table-with-vectors.md\n\nvector-system-variables.md\n\nvector-functions\n\nvector.md\n\nvector-framework-integrations.md\n\nURL: https://mariadb.com/docs/server/reference/sql-structure/vectors/README', '', 'https://mariadb.com/docs/server/reference/sql-structure/vectors/README');
INSERT INTO help_topic (help_topic_id, help_category_id, name, description, example, url) VALUES (1005, 35, 'CREATE TABLE with Vectors', 'Description\n-----------\n\nMariaDB has a dedicated VECTOR(N) data type with a built-in data validation. N is the number of dimensions that all vector values in the column have.\n\n Vector indexes are dimensionality-specific.\n All vectors inserted into an indexed column must match the index''s target dimensionality.\n Inserting vectors with different dimensionalities will result in an error.\n\nConsider the following table:\n\n``sql\nCREATE TABLE embeddings (\n        doc_id BIGINT UNSIGNED PRIMARY KEY,\n        embedding VECTOR(1536)\n);\n`\n\nTo have a fast vector search, you have to index the vector column, creating a VECTOR index:\n\n`sql\nCREATE TABLE embeddings (\n        doc_id BIGINT UNSIGNED PRIMARY KEY,\n        embedding VECTOR(1536) NOT NULL,\n        VECTOR INDEX (embedding)\n);\n`\n\nNote that there can be only one vector index in the table, and the indexed vector column must be NOT NULL.\n\nThere are two options that can be used to configure the vector index:\n\n M — Larger values mean slower SELECT and INSERT statements, larger index size and higher memory consumption, but more accurate results. The valid range is from 3 to 200.\n* DISTANCE — Distance function to build the vector index for. Searches using a different distance function will not be able to use a vector index. Valid values are cosine and euclidean (the default).\n\n`sql\nCREATE TABLE embeddings (\n        doc_id BIGINT UNSIGNED PRIMARY KEY,\n        embedding VECTOR(1536) NOT NULL,\n        VECTOR INDEX (embedding) M=8 DISTANCE=cosine\n);\n``\n\nURL: https://mariadb.com/docs/server/reference/sql-structure/vectors/create-table-with-vectors', '', 'https://mariadb.com/docs/server/reference/sql-structure/vectors/create-table-with-vectors');
INSERT INTO help_topic (help_topic_id, help_category_id, name, description, example, url) VALUES (1006, 35, 'Optimizing Hybrid Search Query with Reciprocal Rank Fusion (RRF)', 'Description\n-----------\n\nHybrid search combines the keyword precision of full-text search with the conceptual understanding of vector search to produce a single, superior set of results.\n\nFull-Text Search\n\nFull-text search is the traditional keyword-based search, excelling at finding documents that contain the exact words from your query. Behind the scenes, it relies on a data structure called an inverted index—a dictionary that maps each word to a list of documents it appears in, allowing for very fast lookups. For instance, a search for ''apple pie recipe'' will instantly find all documents indexed under those three words: ‘apple‘, ‘pie‘ & ‘recipe‘.\n\nVector Search\n\nVector search is a modern search method based on meaning. It finds documents that are conceptually similar to your query, even if they don''t share any keywords. It works by converting both the query and the documents into numerical representations called "vector embeddings." These vectors exist as points in a high-dimensional conceptual space. A search then finds the "nearest neighbors"—the document points that are closest to the query point. For instance, a vector search for "apple pie recipe" might also return a document titled "how to bake a Granny Smith tart," because the model understands that "tart" is similar to "pie" and "Granny Smith" is a type of "apple."\n\nThe Power of Hybrid Search\n\nFull-text search offers precise keyword matching, while vector search provides nuanced understanding of concepts. Together, they handle ambiguity and ensure critical queries aren''t missed, resulting in a robust, intelligent search experience.\n\nCombining Full-Text and Vector Search\n\nA Search for "Sustainable Coffee Pods"\n\nWhen a user searches for "sustainable coffee pods," the two search systems return the following ranked lists.\n\nFull-Text Search Results\n\n| Rank | ID | Title                         |\n| ---- | -- | ----------------------------- |\n| 1    | 1  | ''Eco Coffee Pods - 100 Count'' |\n| 2    | 3  | ''Recyclable Coffee Capsules''  |\n| 3    | 4  | ''Morning Roast Coffee Beans''  |\n\nVector Search Results\n\n| Rank | ID | Title                           |\n| ---- | -- | ------------------------------- |\n| 1    | 2  | ''Compostable Espresso Pods''     |\n| 2    | 3  | ''Recyclable Coffee Capsules''    |\n| 3    | 6  | ''Bamboo Reusable Coffee Filter'' |\n\nWhen two search systems produce distinct lists of titles, a traditional merging approach would prioritize titles that appear in both lists, similar to an INNER JOIN operation.\n\nWhy a Simple INNER JOIN Is Insufficient\n\nAn INNER JOIN only returns results found by both search systems, discarding valuable items that appear in only one list.\n\nIf we were to INNER JOIN the two lists from our "sustainable coffee pods" search, the result would be:\n\n| ID | Title                        |\n| -- | ---------------------------- |\n| 3  | ''Recyclable Coffee Capsules'' |\n\nThis result is severely incomplete. It correctly finds the one common item but completely discards the #1 ranked result from both searches (''Eco Coffee Pods'' and ''Compostable Espresso Pods'') simply because they were specialists found by only one system.\n\nReciprocal Rank Fusion (RRF)\n\nTo solve the problem of discarded results, we use Reciprocal Rank Fusion (RRF). The power of RRF lies in its simplicity: it operates on the rank of an item (1st, 2nd, 3rd) in a list, not its raw, non-comparable score. This makes it highly effective for merging lists from different systems without needing to normalize their scores.\n\nA helpful way to think of this is to imagine your different search systems as a "panel of expert advisors"; RRF intelligently combines their opinions using the formula:\n\n$$\nRRF_{score} = \\sum_{i} \\frac{1}{k + \\text{rank}_i}\n$$\n\nWhere rank is the position of a document in a list, and k is a tuning constant that moderates the influence of that rank.\n\nRRF''s k Parameter\n\nThe k parameter is the primary tuning knob for the RRF algorithm, acting as a smoothing factor that controls how results are weighted. A low k gives immense power to a top-ranked result, while a high k is more skeptical of a single top pick and rewards items found by multiple systems (consensus). A value of k=60 is a robust and effective baseline for general use.\n\nA key advantage of RRF is that it ignores the raw scores from the search systems and uses only the rank. The table below shows the partial RRF score for the top items in our "sustainable coffee pods" search, calculated with k=60.\n\nBuilding the Hybrid Query Optimization model with CTEs\n\n``mermaid\n\ngraph TD\n    subgraph "1. Configuration & Parameters"\n        param_k[/"Parameter: k (e.g., 60)"/]\n    end\n    subgraph "2. Initial Searches (CTEs)"\n        A[CTE: vector_limit_search] -->|Outputs ''dist'' score| C\n        B[CTE: fulltext_limit_search] -->|Outputs ''match_score''| D\n    end\n    subgraph "3. Score Calculation & Merging (CTEs)"\n        C[CTE: vector_score]\n        D[CTE: fulltext_score]\n        param_k --> C & D\n        C -->|"Calculates partial_rrf"| E[CTE: full_outer_join_output <br> Implemented with UNION]\n        D -->|"Calculates partial_rrf"| E\n    end\n    subgraph "4. Final Output"\n        E --> F[Final SELECT & ORDER BY total_rrf]\n    end\n    style F fill:#f5ddb3\n`\n\nTo build the model, our query uses the following Common Table Expressions (CTEs). \n\n| CTE Name                  | Purpose                                                                                    |\n| ------------------------- | ------------------------------------------------------------------------------------------ |\n| vector_limit_search     | Runs the initial vector search to retrieve the top N conceptually similar items.           |\n| fulltext_limit_search   | Runs the initial full-text search to retrieve the top N keyword matches.                   |\n| vector_score             | Calculates a partial_rrf score for each item from the vector search based on its rank.    |\n| fulltext_score           | Calculates a partial_rrf score for each item from the full-text search based on its rank. |\n| full_outer_join_output | Merges the two score lists and sums the partial scores into a total_rrf.                  |\n\nThe annotated SQL query uses the CTEs to perform the hybrid search:\n\n`sql\n-- Set the parameters for our query.\nSET @k = 60; -- The RRF smoothing constant.\nSET @search_term = "sustainable coffee pods";\n-- The vector for the search term would be set here.\n-- SET @search_term_vector = VEC_FromText("...");\n\n-- Use CTEs to break the logic into sequential steps.\nWITH\n-- STEP 1: Get top results from each search method.\nvector_limit_search AS (\n  SELECT id, title, VEC_DISTANCE_EUCLIDEAN(embedding, @search_term_vector) AS dist\n  FROM products ORDER BY dist ASC LIMIT 10\n),\nfulltext_limit_search AS (\n  SELECT id, title, MATCH(title) AGAINST (@search_term) AS match_score\n  FROM products WHERE MATCH(title) AGAINST (@search_term)\n  ORDER BY match_score DESC LIMIT 10\n),\n-- STEP 2: Calculate partial RRF scores for each list.\nvector_score AS (\n  SELECT id, title, 1 / (@k + RANK() OVER (ORDER BY dist ASC)) AS partial_rrf\n  FROM vector_limit_search\n),\nfulltext_score AS (\n  SELECT id, title, 1 / (@k + RANK() OVER (ORDER BY match_score DESC)) AS partial_rrf\n  FROM fulltext_limit_search\n),\n-- STEP 3: Merge the two lists and sum the scores.\nfull_outer_join_output AS (\n  SELECT v.id, v.title, (v.partial_rrf + IFNULL(f.partial_rrf, 0)) AS total_rrf\n  FROM vector_score v LEFT JOIN fulltext_score f USING (id)\n  UNION\n  SELECT f.id, f.title, (IFNULL(v.partial_rrf, 0) + f.partial_rrf) AS total_rrf\n  FROM fulltext_score f LEFT JOIN vector_score v USING (id)\n)\n-- STEP 4: Select the final, unified list.\nSELECT id, title, total_rrf FROM full_outer_join_output\nORDER BY total_rrf DESC\nLIMIT 10;\n``\n\nFinal Calculation for "Sustainable Coffee Pods"\n\nWith k=60, the final CTE merges and sums the partial scores. The consensus item, found in both lists, rises to the top.\n\n| ID | Title                      | fulltext_rrf | vector_rrf | total_rrf | Final Rank |\n| -- | -------------------------- | ------------- | ----------- | ---------- | ---------- |\n| 3  | Recyclable Coffee Capsules | 0.01613       | 0.01613     | 0.03226    | 1          |\n| 1  | Eco Coffee Pods            | 0.01639       | 0           | 0.01639    | 2          |\n| 2  | Compostable Espresso Pods  | 0             | 0.01639     | 0.01639    | 2          |\n\nTuning the k Parameter\n\nAs introduced earlier, the k parameter can be fine-tuned for specific situations. Here are three common scenarios to consider.\n\n1. Combining Diverse, Specialist Systems\n\nFor merging results from different methods like keyword and vector search, a higher k (such as 60) is ideal to balance their contributions. Our main "sustainable coffee pods" search is a perfect illustration of this, where the consensus item wins but the high-quality specialists are ranked immediately after.\n\n| Final Rank | ID | Title                      | Total RRF | Note             |\n| ---------- | -- | -------------------------- | --------- | ---------------- |\n| 1          | 3  | Recyclable Coffee Capsules | 0.03226   | Consensus Winner |\n| 2          | 1  | Eco Coffee Pods            | 0.01639   | Specialist       |\n| 2          | 2  | Compostable Espresso Pods  | 0.01639   | Specialist       |\n\n2. Handling Mixed-Quality or "Noisy" Systems\n\nIf you are fusing results from reliable systems and one experimental, less predictable system, a higher k (60 or more) is the safest choice to prevent an outlier from disproportionately influencing the final rank.\n\nConsider our search with a third, "noisy" system that incorrectly ranks ''Eco-Friendly Car Wax'' (ID 8) at #1. A high k value minimizes the impact of this error.\n\n<table><thead><tr><th>Product</th><th>FT Rank</th><th width="129.44140625">Vector Rank</th><th width="122.640625">Noisy Rank</th><th>Total RRF (k=60)</th></tr></thead><tbody><tr><td>Recyclable Coffee Capsules</td><td>2</td><td>2</td><td>-</td><td>1/62 + 1/62 = 0.03226</td></tr><tr><td>Eco-Friendly Car Wax</td><td>-</td><td>-</td><td>1</td><td>1/61 = 0.01639</td></tr></tbody></table>\n\nThe high k value correctly ensures that the consensus result from the two reliable systems easily beats the single, erroneous result from the noisy system.\n\n3. Fusing High-Quality, Similar Systems\n\nIf you are combining lists from two very similar, high-performing algorithms, you can experiment with a slightly lower k (30-50) to give more weight to a top-ranked document.\n\nConsider a case where we fuse two similar vector models (Vector_A, Vector_B) that both rank ''Compostable Espresso Pods'' as #1 and ''Recyclable Coffee Capsules'' as #2. A lower k makes the winner more decisive.\n\n| Product             | Ranks       | Total RRF (k=30)     | Total RRF (k=60)     |\n| ------------------- | ----------- | -------------------- | -------------------- |\n| Compostable Pods    | 1, 1        | 1/31 + 1/31 = 0.0645 | 1/61 + 1/61 = 0.0328 |\n| Recyclable Capsules | 2, 2        | 1/32 + 1/32 = 0.0625 | 1/62 + 1/62 = 0.0322 |\n| Score Difference    | <p><br></p> | 0.0020               | 0.0006               |\n\nWith k=30, the score separation between the #1 and #2 results is more than three times larger, showing higher confidence in the top result, which is desirable when you trust both systems.\n\nDetermining the Best k (The Experimental Method)\n\nA formal, 3-step process can be used to scientifically determine the best k value for your data through offline evaluation. To illustrate this process, which requires a pre-judged "ground truth" set with graded relevance, we will use a separate, self-contained case study.\n\n1. Gather Prerequisites\n\nYou need: Multiple Ranked Lists, a "Ground Truth" Set, and an Evaluation Metric (like NDCG). With a query like "healthy breakfast", your ground truth might look like this:\n\n| Doc ID | Title                  | Relevance  |\n| ------ | ---------------------- | ---------- |\n| A      | ''Oatmeal with Berries'' | 3 (High)   |\n| B      | ''Green Smoothie''       | 3 (High)   |\n| C      | ''Avocado Toast''        | 2 (Medium) |\n| D      | ''Bacon and Eggs''       | 1 (Low)    |\n| E      | ''Cinnamon Roll''        | 0 (None)   |\n\nAnd your raw ranked lists might be:\n\n Full-Text Results: \\[D, A, E]\n Vector Results: \\[B, C, A]\n\n2. Run the Experiment\n\nYou iterate through k values, applying the RRF formula to the raw lists to generate a final ranking for each k.\n\n Final Ranked List (k=10):\n\n| Rank | ID | Title                  |\n| ---- | -- | ---------------------- |\n| 1    | B  | ''Green Smoothie''       |\n| 2    | D  | ''Bacon and Eggs''       |\n| 3    | A  | ''Oatmeal with Berries'' |\n| 4    | C  | ''Avocado Toast''        |\n| 5    | E  | ''Cinnamon Roll''        |\n\n Final Ranked List (k=60):\n\n| Rank | ID | Title                  |\n| ---- | -- | ---------------------- |\n| 1    | A  | ''Oatmeal with Berries'' |\n| 2    | B  | ''Green Smoothie''       |\n| 3    | C  | ''Avocado Toast''        |\n| 4    | D  | ''Bacon and Eggs''       |\n| 5    | E  | ''Cinnamon Roll''        |\n\n3. Analyze and Select\n\nYou use your metric to "grade" each list against the Ground Truth and choose the k with the highest score. The k=60 list is clearly better as it placed the two "Highly Relevant" documents (A and B) at the top.\n\n| k Value | Performance Score (NDCG) |\n| ------- | ------------------------ |\n| 10      | 0.85                     |\n| 60      | 0.92                     |\n\nIn this experiment, k=60 is the winner. A key advantage of RRF is that its performance is "not critically sensitive to the choice of k, making it a robust and reliable method" for improving search relevance.\n\nFurther Reading\n\n* Reciprocal Rank Fusion for IR (SIGIR ''09): The original research paper that proposed the RRF method.\n\nURL: https://mariadb.com/docs/server/reference/sql-structure/vectors/optimizing-hybrid-search-query-with-reciprocal-rank-fusion-rrf', '', 'https://mariadb.com/docs/server/reference/sql-structure/vectors/optimizing-hybrid-search-query-with-reciprocal-rank-fusion-rrf');
INSERT INTO help_topic (help_topic_id, help_category_id, name, description, example, url) VALUES (1007, 35, 'Vector Framework Integrations', 'Description\n-----------\n\nMariaDB Vector has integrations in several frameworks.\n\nAI Framework Integrations\n\n LangChain, MariaDB Vector Store - Python\n LangChain.js, MariaDB Vector Store - Node.js\n LangChain4j, MariaDB Embedding Store - Java\n LlamaIndex, MariaDB Vector Store - Python\n MCP (Model Context Protocol), MariaDB MCP server - Python\n Spring AI, MariaDB Vector Store - Java\n VectorDBBench - benchmarking for vector databases\n\nPotential Future Vector or AI Integrations\n AutoGen - Agent to agent, Python\n DB-GPT - private LLM, vector search and text2sql, see integration docs, Python\n DSPy - Workflow, not accepting external integrations anymore, Python\n Feast - machine learning (not GenAI), Python\n Firebase Studio template for MariaDB Vector - visit link to vote for suggestion\n LangGraph - Agentic workflow, Python\n MindSQL - Text-to-SQL RAG Library simplifying database interactions, Python\n Open WebUI - AI Interface, Python & Javascript\n Vanna AI - Vector search and text2sql, Python\n\nFor further alternatives, see Qdrant''s list of framework integrations.\n\nURL: https://mariadb.com/docs/server/reference/sql-structure/vectors/vector-framework-integrations', '', 'https://mariadb.com/docs/server/reference/sql-structure/vectors/vector-framework-integrations');
INSERT INTO help_topic (help_topic_id, help_category_id, name, description, example, url) VALUES (1008, 35, 'Vector Overview', 'Description\n-----------\n\nMariaDB Vector is a feature that allows MariaDB Server to perform as a relational vector database. Vectors generated by an AI model can be stored and searched in MariaDB.\n\nThe initial implementation uses the modified HNSW[^1] algorithm for searching in the vector index (to solve the so-called Approximate Nearest Neighbor problem), and defaults to Euclidean distance. Concurrent reads/writes and all transaction isolation levels are supported.\n\nMariaDB uses int16 for indexes, which gives 15 bits to store the value, rather than 10 bits for float16.\n\nCreating\n\nVectors can be defined using VECTOR INDEX for the index definition, and using the VECTOR data type in the CREATE TABLE statement.\n\n``sql\nCREATE TABLE v (\n     id INT PRIMARY KEY,\n     v VECTOR(5) NOT NULL,\n     VECTOR INDEX (v)\n);\n`\n\nThe distance function used to build the vector index can be euclidean (the default) or cosine. An additional option, M, can be used to configure the vector index. Larger values mean slower SELECT and INSERT statements, larger index size and higher memory consumption but more accurate results. The valid range is from 3 to 200.\n\n`sql\nCREATE TABLE embeddings (\n        doc_id BIGINT UNSIGNED PRIMARY KEY,\n        embedding VECTOR(1536) NOT NULL,\n        VECTOR INDEX (embedding) M=8 DISTANCE=cosine\n);\n`\n\nInserting\n\nVector columns store 32-bit IEEE 754 floating point numbers.\n\n`sql\nINSERT INTO v VALUES \n     (1, x''e360d63ebe554f3fcdbc523f4522193f5236083d''),\n     (2, x''f511303f72224a3fdd05fe3eb22a133ffae86a3f''),\n     (3,x''f09baa3ea172763f123def3e0c7fe53e288bf33e''),\n     (4,x''b97a523f2a193e3eb4f62e3f2d23583e9dd60d3f''),\n     (5,x''f7c5df3e984b2b3e65e59d3d7376db3eac63773e''),\n     (6,x''de01453ffa486d3f10aa4d3fdd66813c71cb163f''),\n     (7,x''76edfc3e4b57243f10f8423fb158713f020bda3e''),\n     (8,x''56926c3fdf098d3e2c8c5e3d1ad4953daa9d0b3e''),\n     (9,x''7b713f3e5258323f80d1113d673b2b3f66e3583f''),\n     (10,x''6ca1d43e9df91b3fe580da3e1c247d3f147cf33e'');\n`\n\nAlternatively, you can use VEC_FromText() function:\n\n`sql\nINSERT INTO v VALUES\n  (1,Vec_FromText(''[0.418708,0.809902,0.823193,0.598179,0.0332549]'')),\n  (2,Vec_FromText(''[0.687774,0.789588,0.496138,0.57487,0.917617]'')),\n  (3,Vec_FromText(''[0.333221,0.962687,0.467263,0.448235,0.475671]'')),\n  (4,Vec_FromText(''[0.822185,0.185643,0.683452,0.211072,0.554056]'')),\n  (5,Vec_FromText(''[0.437057,0.167281,0.0770977,0.428638,0.241591]'')),\n  (6,Vec_FromText(''[0.76956,0.926895,0.803376,0.0157961,0.589042]'')),\n  (7,Vec_FromText(''[0.493999,0.641957,0.761598,0.94276,0.425865]'')),\n  (8,Vec_FromText(''[0.924108,0.275466,0.0543329,0.0731585,0.136344]'')),\n  (9,Vec_FromText(''[0.186956,0.69666,0.0356002,0.668875,0.84722]'')),\n  (10,Vec_FromText(''[0.415294,0.609278,0.426765,0.988832,0.475556]''));\n`\n\nQuerying\n\nFor vector indexes built with the euclidean function, VEC_DISTANCE_EUCLIDEAN can be used. It calculates a Euclidean (L2) distance between two points:\n\n`sql\nSELECT id FROM v ORDER BY \n  VEC_DISTANCE_EUCLIDEAN(v, x''6ca1d43e9df91b3fe580da3e1c247d3f147cf33e'');\n+----+\n| id |\n+----+\n| 10 |\n|  7 |\n|  3 |\n|  9 |\n|  2 |\n|  1 |\n|  5 |\n|  4 |\n|  6 |\n|  8 |\n+----+\n`\n\nMost commonly, this kind of query is done with a limit, for example to return vectors that are closest to a given vector, such as from a user search query, image or a song fragment:\n\n`sql\nSELECT id FROM v \n  ORDER BY VEC_DISTANCE_EUCLIDEAN(v, x''6ca1d43e9df91b3fe580da3e1c247d3f147cf33e'') \n  LIMIT 2;\n+----+\n| id |\n+----+\n| 10 |\n|  7 |\n+----+\n`\n\nFor vector indexes built with the cosine function, VEC_DISTANCE_COSINE can be used. It calculates a Cosine distance between two vectors:\n\n`sql\nSELECT VEC_DISTANCE_COSINE(VEC_FROMTEXT(''[1,2,3]''), VEC_FROMTEXT(''[3,5,7]''));\n`\n\nThe VEC_DISTANCE function is a generic function that behaves either as VEC_DISTANCE_EUCLIDEAN or VEC_DISTANCE_COSINE, depending on the underlying index type:\n\n`sql\nSELECT id FROM v \n  ORDER BY VEC_DISTANCE(v, x''6ca1d43e9df91b3fe580da3e1c247d3f147cf33e'');\n+----+\n| id |\n+----+\n| 10 |\n|  7 |\n|  3 |\n|  9 |\n|  2 |\n|  1 |\n|  5 |\n|  4 |\n|  6 |\n|  8 |\n+----+\n``\n\nThere is no function for _dot product_ (also called _inner product_) distance available in many other vector databases. Dot product is not a proper distance measure (for example, vector''s closest match is not necessarily itself) and is only used for performance reasons, because it is often faster than cosine or euclidean and produces the same results if vectors are normalized. In MariaDB optimized implementation euclidean and cosine measures are the fastest, and dot product, if implemented, would not provide any performance benefits. Use euclidean or cosine (they are equally fast) for normalized vectors.\n\nSystem Variables\n\nThere are a number of system variables used for vectors. See Vector System Variables.\n\nVector Framework Integrations\n\nMariaDB Vector is integrated in several frameworks, see Vector Framework Integrations.\n\nWhat is a Vector?\n\nWhat exactly is a vector in AI and RAG (1 minute • 2026)\n\nVideo summary\n\n A vector (an _embedding_) is an ordered list of numbers.\n AI models map content (like text) into vectors.\n Similar meanings end up close together in vector space.\n RAG and semantic search retrieve relevant items by finding the nearest vectors.\n\nURL: https://mariadb.com/docs/server/reference/sql-structure/vectors/vector-overview', '', 'https://mariadb.com/docs/server/reference/sql-structure/vectors/vector-overview');
INSERT INTO help_topic (help_topic_id, help_category_id, name, description, example, url) VALUES (1009, 35, 'Vector System Variables', 'Description\n-----------\n\nThis page documents system variables related to Vectors.\n\nSee Server System Variables for instructions on setting them.\n\nAlso see the Full list of MariaDB options, system and status variables.\n\nmhnsw_default_distance\n\n Description: Specifies the default distance metric for MHNSW vector indexing. This is used when the DISTANCE option is not explicitly defined during index creation.\n Command line: --mhnsw-default-distance=val\n Scope: Global, Session\n Dynamic: Yes\n Data Type: enum\n Default Value: euclidean\n Valid Values:\n   euclidean Calculates straight-line distance between vectors. Best for spatial data, images, etc, when absolute magnitude matters.\n   cosine Measures directional similarity between vectors. Ideal for text embeddings, semantic search, and when vector magnitude is less important.\n Introduced: MariaDB 11.7.1\n\nmhnsw_default_m\n\n Description: Defines the default value for the M parameter in MHNSW vector indexing. The M parameter controls the number of connections per layer in the graph structure, influencing the balance between search performance and index size.\n   Larger M → Better search accuracy, but larger index size and slower updates and searches.\n   Smaller M → Faster updates and searches, smaller index, but potentially less accurate search.\n Command line: --mhnsw-default-m=#\n Scope: Global, Session\n Dynamic: Yes\n Data Type: int unsigned\n Default Value: 6\n Range: 3 to 200\n Introduced: MariaDB 11.7.1\n\nmhnsw_ef_search\n\n Description: Defines the minimal number of result candidates to look for in the vector index for ORDER BY ... LIMIT N queries. The search will never search for less rows than that, even if LIMIT is smaller. This notably improves the search quality at low LIMIT values, at the expense of search time. Higher values may increase search quality but will also impact query performance.\n Command line: --mhnsw-ef-search=#\n Scope: Global, Session\n Dynamic: Yes\n Data Type: int unsigned\n Default Value: 20\n Range: 1 to 10000\n Introduced: MariaDB 11.7.1\n\nmhnsw_max_cache_size\n\n Description: Upper limit for one MHNSW vector index cache. This limits the amount of memory that can be used for caching the index, ensuring efficient memory utilization.\n Command line: --mhnsw-max-cache-size=#\n Scope: Global\n Dynamic: Yes\n Data Type: bigint unsigned\n Default Value: 16777216 (16 MB)\n Range: 1048576 to 18446744073709551615\n Introduced: MariaDB 11.7.1\n\nURL: https://mariadb.com/docs/server/reference/sql-structure/vectors/vector-system-variables', '', 'https://mariadb.com/docs/server/reference/sql-structure/vectors/vector-system-variables');

insert into help_keyword (help_keyword_id,name) values (0,'AUTO_INCREMENT');
insert into help_keyword (help_keyword_id,name) values (1,'FAQ');
insert into help_keyword (help_keyword_id,name) values (2,'DATA');
insert into help_keyword (help_keyword_id,name) values (3,'TYPE');
insert into help_keyword (help_keyword_id,name) values (4,'STORAGE');
insert into help_keyword (help_keyword_id,name) values (5,'REQUIREMENTS');
insert into help_keyword (help_keyword_id,name) values (6,'DATE');
insert into help_keyword (help_keyword_id,name) values (7,'DATETIME');
insert into help_keyword (help_keyword_id,name) values (8,'SQL_TSI_YEAR');
insert into help_keyword (help_keyword_id,name) values (9,'TIME');
insert into help_keyword (help_keyword_id,name) values (10,'TIMESTAMP');
