INSERT INTO help_topic (help_topic_id, help_category_id, name, description, example, url) VALUES (611, 39, 'ALTER DATABASE', 'Syntax\n------\n\nALTER {DATABASE | SCHEMA} [db_name]\n    alter_specification ...\nALTER {DATABASE | SCHEMA} db_name\n    UPGRADE DATA DIRECTORY NAME\n\nalter_specification:\n    [DEFAULT] CHARACTER SET [=] charset_name\n  | [DEFAULT] COLLATE [=] collation_name\n  | COMMENT [=] ''comment''\n\nDescription\n-----------\n\nALTER DATABASE enables you to change the overall characteristics of a database. These characteristics are stored in the db.opt file in the database directory. To use ALTER DATABASE, you need the ALTER privilege on the database. ALTER SCHEMA is a synonym for ALTER DATABASE.\n\nThe CHARACTER SET clause changes the default database character set. The COLLATE clause changes the default database collation. See Character Sets and Collations for more.\n\nYou can see what character sets and collations are available using, respectively, the SHOW CHARACTER SET and SHOW COLLATION statements.\n\nChanging the default character set/collation of a database does not change the character set/collation of any stored procedures or stored functions that were previously created, and relied on the defaults. These need to be dropped and recreated in order to apply the character set/collation changes.\n\nThe database name can be omitted from the first syntax, in which case the statement applies to the default database.\n\nThe syntax that includes the UPGRADE DATA DIRECTORY NAME clause. It updates the name of the directory associated with the database to use the encoding implemented in MySQL for mapping database names to database directory names (see Identifier to File Name Mapping). This clause is for use under these conditions:\n\n It is intended when upgrading MySQL from older versions.\n It is intended to update a database directory name to the current encoding format if the name contains special characters that need encoding.\n* The statement is used by mariadb-check (as invoked by mariadb-upgrade).\n\nFor example, if a database in MySQL 5.0 has a name of a-b-c, the name contains instance of the \\-'' character. In 5.0, the database directory is also named a-b-c, which is not necessarily safe for all file systems. In MySQL, the same database name is encoded as a@002db@002dc to produce a file-system-neutral directory name.\n\nWhen a MySQL installation is upgraded from an older version, the server displays a name such as a-b-c (which is in the old format) as #mysql50#a-b-c, and you must refer to the name using the #mysql50# prefix. Use UPGRADE DATA DIRECTORY NAME in this case to explicitly tell the server to re-encode the database directory name to the current encoding format:\n\n`sql\nALTER DATABASE #mysql50#a-b-c UPGRADE DATA DIRECTORY NAME;\n`\n\nAfter executing this statement, you can refer to the database as a-b-c without the special #mysql50` prefix.\n\nMariaDB starting with 10.5.0\n\nFrom MariaDB 10.5.0, it is possible to add a comment of a maximum of 1024 bytes. If the comment length exceeds this length, a error/warning code 4144 is thrown. The database comment is also added to the db.opt file, as well as to the information_schema.schemata table.\n\nExamples\n--------\n\nALTER DATABASE p COMMENT=''Presentations'';\n\nURL: https://mariadb.com/docs/server/reference/sql-statements/data-definition/alter/alter-database', '', 'https://mariadb.com/docs/server/reference/sql-statements/data-definition/alter/alter-database');
INSERT INTO help_topic (help_topic_id, help_category_id, name, description, example, url) VALUES (612, 39, 'ALTER FUNCTION', 'Syntax\n------\n\nALTER FUNCTION func_name [characteristic ...]\n\ncharacteristic:\n    { CONTAINS SQL | NO SQL | READS SQL DATA | MODIFIES SQL DATA }\n  | SQL SECURITY { DEFINER | INVOKER }\n  | COMMENT ''string''\n\nDescription\n-----------\n\nThis statement can be used to change the characteristics of a stored function. More than one change may be specified in an ALTER FUNCTION statement. However, you cannot change the parameters or body of a stored function using this statement; to make such changes, you must drop and re-create the function using DROP FUNCTION and CREATE FUNCTION.\n\nYou must have the ALTER ROUTINE privilege for the function. (That privilege is granted automatically to the function creator.) If binary logging is enabled, the ALTER FUNCTION statement might also require\\\nthe SUPER privilege, as described in Binary Logging of Stored Routines.\n\nExamples\n--------\n\nALTER FUNCTION hello SQL SECURITY INVOKER;\n\nURL: https://mariadb.com/docs/server/reference/sql-statements/data-definition/alter/alter-function', '', 'https://mariadb.com/docs/server/reference/sql-statements/data-definition/alter/alter-function');
INSERT INTO help_topic (help_topic_id, help_category_id, name, description, example, url) VALUES (613, 39, 'ALTER LOGFILE GROUP', 'Description\n-----------\n\nThe ALTER LOGFILE GROUP statement is not supported by MariaDB. It was originally inherited from MySQL NDB Cluster. See MDEV-19295 for more information.\n\nSyntax\n\n``sql\nALTER LOGFILE GROUP logfile_group\n    ADD UNDOFILE ''file_name''\n    [INITIAL_SIZE [=] size]\n    [WAIT]\n    ENGINE [=] engine_name\n``\n\nURL: https://mariadb.com/docs/server/reference/sql-statements/data-definition/alter/alter-logfile-group', '', 'https://mariadb.com/docs/server/reference/sql-statements/data-definition/alter/alter-logfile-group');

INSERT INTO help_topic (help_topic_id, help_category_id, name, description, example, url) VALUES (615, 39, 'ALTER TABLE', 'Syntax\n------\n\nALTER [ONLINE] [IGNORE] TABLE [IF EXISTS] tbl_name\n    [WAIT n | NOWAIT]\n    alter_specification [, alter_specification] ...\n\nalter_specification:\n    table_option ...\n  | ADD [COLUMN] [IF NOT EXISTS] col_name column_definition\n        [FIRST | AFTER col_name ]\n  | ADD [COLUMN] [IF NOT EXISTS] (col_name column_definition, ...)\n  | ADD {INDEX|KEY} [IF NOT EXISTS] [index_name]\n        [index_type] (index_col_name,...) [index_option] ...\n  | ADD [CONSTRAINT [symbol]] PRIMARY KEY [IF NOT EXISTS]\n        [index_type] (index_col_name,...) [index_option] ...\n  | ADD [CONSTRAINT [symbol]]\n        UNIQUE [INDEX|KEY] [IF NOT EXISTS] [index_name]\n        [index_type] (index_col_name,...) [index_option] ...\n  | ADD FULLTEXT [INDEX|KEY] [IF NOT EXISTS [index_name]\n        (index_col_name,...) [index_option] ...\n  | ADD SPATIAL [INDEX|KEY] [IF NOT EXISTS [index_name]\n        (index_col_name,...) [index_option] ...\n  | ADD VECTOR [INDEX|KEY] [IF NOT EXISTS [index_name]\n        (index_col_name,...) [index_option] ...\n  | ADD [CONSTRAINT [symbol]]\n        FOREIGN KEY [IF NOT EXISTS] [index_name] (index_col_name,...)\n        reference_definition\n  | ADD PERIOD FOR [time_period_name|SYSTEM_TIME] (start_column_name, end_column_name)\n  | ALTER [COLUMN] col_name SET DEFAULT literal | (expression)\n  | ALTER [COLUMN] col_name DROP DEFAULT\n  | ALTER {INDEX|KEY} [IF EXISTS] index_name [NOT] IGNORED\n  | CHANGE [COLUMN] [IF EXISTS] old_col_name new_col_name column_definition\n        [FIRST|AFTER col_name]\n  | MODIFY [COLUMN] [IF EXISTS] col_name column_definition\n        [FIRST | AFTER col_name]\n  | DROP [COLUMN] [IF EXISTS] col_name [RESTRICT|CASCADE]\n  | DROP [CONSTRAINT] PRIMARY KEY\n  | DROP {INDEX|KEY} [IF EXISTS] index_name\n  | DROP FOREIGN KEY [IF EXISTS] fk_symbol\n  | DROP CONSTRAINT [IF EXISTS] constraint_name\n  | DISABLE KEYS\n  | ENABLE KEYS\n  | RENAME [TO] new_tbl_name\n  | ORDER BY col_name [, col_name] ...\n  | RENAME COLUMN [IF EXISTS] old_col_name TO new_col_name\n  | RENAME {INDEX|KEY} old_index_name TO new_index_name\n  | CONVERT TO CHARACTER SET charset_name [COLLATE collation_name]\n  | [DEFAULT] CHARACTER SET [=] charset_name\n  | [DEFAULT] COLLATE [=] collation_name\n  | DISCARD TABLESPACE\n  | IMPORT TABLESPACE\n  | ALGORITHM [=] {DEFAULT|INPLACE|COPY|NOCOPY|INSTANT}\n  | LOCK [=] {DEFAULT|NONE|SHARED|EXCLUSIVE}\n  | FORCE\n  | partition_options\n  | CONVERT TABLE normal_table TO partition_definition [{WITH | WITHOUT} VALIDATION]\n  | CONVERT PARTITION partition_name TO TABLE tbl_name\n  | ADD PARTITION [IF NOT EXISTS] (partition_definition)\n  | DROP PARTITION [IF EXISTS] partition_names\n  | TRUNCATE PARTITION partition_names\n  | COALESCE PARTITION number\n  | REORGANIZE PARTITION [partition_names INTO (partition_definitions)]\n  | ANALYZE PARTITION partition_names\n  | CHECK PARTITION partition_names\n  | OPTIMIZE PARTITION partition_names\n  | REBUILD PARTITION partition_names\n  | REPAIR PARTITION partition_names\n  | EXCHANGE PARTITION partition_name WITH TABLE tbl_name [{WITH | WITHOUT} VALIDATION]\n  | REMOVE PARTITIONING\n  | ADD SYSTEM VERSIONING\n  | DROP SYSTEM VERSIONING\n\nindex_col_name:\n    col_name [(length)] [ASC | DESC]\n\nindex_type:\n    USING {BTREE | HASH | RTREE}\n\nindex_option:\n    KEY_BLOCK_SIZE [=] value\n  | index_type\n  | WITH PARSER parser_name\n  | VISIBLE\n  | COMMENT ''string''\n  | CLUSTERING={YES | NO}\n  | { IGNORED | NOT IGNORED }\n  | DISTANCE={EUCLIDEAN | COSINE}\n  | M=number\n\n  table_option [[,] table_option] ...\n\nDescription\n-----------\n\nALTER TABLE enables you to change the structure of an existing table. For example, you can add or delete columns, create or destroy indexes, change the type of existing columns, or rename columns or the table itself. You can also change the comment for the table and the storage engine of the table.\n\nIf another connection is using the table, a metadata lock is active, and this statement will wait until the lock is released. This is also true for non-transactional tables.\n\nWhen adding a UNIQUE index on a column (or a set of columns) which have duplicated values, an error will be produced and the statement will be stopped. To suppress the error and force the creation of UNIQUE indexes, discarding duplicates, the IGNORE option can be specified. This can be useful if a column (or a set of columns) should be UNIQUE but it contains duplicate values; however, this technique provides no control on which rows are preserved and which are deleted. Also, note that IGNORE is accepted but ignored in ALTER TABLE ... EXCHANGE PARTITION statements.\n\nThis statement can also be used to rename a table. For details see RENAME TABLE.\n\nWhen an index is created, the storage engine may use a configurable buffer in the process. Incrementing the buffer speeds up the index creation. Aria and MyISAM allocate a buffer whose size is defined by aria_sort_buffer_size or myisam_sort_buffer_size, also used for REPAIR TABLE. InnoDB allocates three buffers whose size is defined by innodb_sort_buffer_size.\n\nPrivileges\n\nExecuting the ALTER TABLE statement generally requires at least the ALTER privilege for the table or the database. If you are renaming a table, this also requires the DROP, CREATE and INSERT privileges for the table or the database.\n\nOnline DDL\n\nOnline DDL is supported with the ALGORITHM and LOCK clauses.\n\nSee InnoDB Online DDL Overview for more information on online DDL with InnoDB.\n\nALTER ONLINE TABLE\n\nALTER ONLINE TABLE also works for partitioned tables.\n\nALTER ONLINE TABLE ... is equivalent to the ALTER TABLE ... LOCK = NONE.\n\nSee the LOCK alter specification for more information.\n\nWAIT/NOWAIT\n\nSet the lock wait timeout. See WAIT and NOWAIT.\n\nIF EXISTS\n\nThe IF EXISTS and IF NOT EXISTS clauses are available for the following clauses:\n\n``sql\nADD COLUMN       [IF NOT EXISTS]\nADD INDEX        [IF NOT EXISTS]\nADD FOREIGN KEY  [IF NOT EXISTS]\nADD PARTITION    [IF NOT EXISTS]\nCREATE INDEX     [IF NOT EXISTS]\nDROP COLUMN      [IF EXISTS]\nDROP INDEX       [IF EXISTS]\nDROP FOREIGN KEY [IF EXISTS]\nDROP PARTITION   [IF EXISTS]\nCHANGE COLUMN    [IF EXISTS]\nMODIFY COLUMN    [IF EXISTS]\nDROP INDEX       [IF EXISTS]\n`\n\nWhen IF EXISTS and IF NOT EXISTS are used in clauses, queries will not report errors when the condition is triggered for that clause. A warning with the same message text will be issued and the ALTER will move on to the next clause in the statement (or end if finished).\n\nIf this is directive is used after ALTER ... TABLE, you don''t get an error if the table doesn''t exist. Example:\n\n`sql\nCREATE TABLE t (i INT);\nALTER TABLE IF EXISTS t RENAME COLUMN IF EXISTS i TO k;\n`\n\nColumn Definitions\n\nSee CREATE TABLE: Column Definitions for information about column definitions.\n\nIndex Definitions\n\nSee CREATE TABLE: Index Definitions for information about index definitions.\n\nThe CREATE INDEX and DROP INDEX statements can also be used to add or remove an index.\n\nCharacter Sets and Collations\n\n`sql\nCONVERT TO CHARACTER SET charset_name [COLLATE collation_name]\n[DEFAULT] CHARACTER SET [=] charset_name\n[DEFAULT] COLLATE [=] collation_name\n`\n\nSee Setting Character Sets and Collations for details on setting the character sets and collations.\n\nAlter Specifications\n\nTable Options\n\nSee CREATE TABLE: Table Options for information about table options.\n\nADD COLUMN\n\n`sql\n... ADD COLUMN [IF NOT EXISTS]  (col_name column_definition,...)\n`\n\nAdds a column to the table. The syntax is the same as in CREATE TABLE. If you are using IF NOT_EXISTS the column will not be added if it was not there already. This is very useful when doing scripts to modify tables.\n\nThe FIRST and AFTER clauses affect the physical order of columns in the datafile. Use FIRST to add a column in the first (leftmost) position, or AFTER followed by a column name to add the new column in any other position. Note that, nowadays, the physical position of a column is usually irrelevant.\n\nSee also Instant ADD COLUMN for InnoDB.\n\nDROP COLUMN\n\n`sql\n... DROP COLUMN [IF EXISTS] col_name [CASCADE|RESTRICT]\n`\n\nDrops the column from the table. If you are using IF EXISTS you will not get an error if the column didn''t exist. If the column is part of any index, the column will be dropped from them, except if you add a new column with identical name at the same time. The index will be dropped if all columns from the index were dropped. If the column was used in a view or trigger, you will get an error next time the view or trigger is accessed. Dropping a column that is part of a multi-column UNIQUE constraint is not permitted. For example:\n\n`sql\nCREATE TABLE a (\n  a int,\n  b int,\n  primary key (a,b)\n);\n\nALTER TABLE x DROP COLUMN a;\n[42000][1072] Key column ''A'' doesn''t exist in table\n`\n\nThe reason is that dropping column a would result in the new constraint that all values in column b be unique. In order to drop the column, an explicit DROP PRIMARY KEY and ADD PRIMARY KEY would be required.\n\nMariaDB supports instant DROP COLUMN. DROP COLUMN of an indexed column would imply DROP INDEX (and in the case of a non-UNIQUE multi-column index, possibly ADD INDEX). These will not be allowed with ALGORITHM=INSTANT, but unlike prior versions, they can be allowed with ALGORITHM=NOCOPY\n\nRESTRICT and CASCADE are allowed to make porting from other database systems easier. In MariaDB, they do nothing.\n\nMODIFY COLUMN\n\nAllows you to modify the type of a column. The column will be at the same place as the original column and all indexes on the column will be kept. Note that when modifying column, you should specify all attributes for the new column.\n\n`sql\nCREATE TABLE t1 (a INT UNSIGNED AUTO_INCREMENT, PRIMARY KEY((a));\nALTER TABLE t1 MODIFY a BIGINT UNSIGNED AUTO_INCREMENT;\n`\n\nCHANGE COLUMN\n\nWorks like MODIFY COLUMN except that you can also change the name of the column. The column will be at the same place as the original column and all index on the column will be kept.\n\n`sql\nCREATE TABLE t1 (a INT UNSIGNED AUTO_INCREMENT, PRIMARY KEY(a));\nALTER TABLE t1 CHANGE a b BIGINT UNSIGNED AUTO_INCREMENT;\n`\n\nALTER COLUMN\n\nThis lets you change column options.\n\n`sql\nCREATE TABLE t1 (a INT UNSIGNED AUTO_INCREMENT, b varchar(50), PRIMARY KEY(a));\nALTER TABLE t1 ALTER b SET DEFAULT ''hello'';\n`\n\nRENAME INDEX/KEY\n\nYou can rename an index using the RENAME INDEX (or RENAME KEY) syntax:\n\n`sql\nALTER TABLE t1 RENAME INDEX i_old TO i_new;\n`\n\nRENAME INDEX/KEY is not available.\n\nRENAME COLUMN\n\nYou can rename a column using the RENAME COLUMN syntax:\n\n`sql\nALTER TABLE t1 RENAME COLUMN c_old TO c_new;\n`\n\nRENAME COLUMN is not available.\n\nADD PRIMARY KEY\n\nAdds a primary key. For PRIMARY KEY indexes, you can specify a name for the index, but it is silently ignored, and the name of the index is always PRIMARY. See Getting Started with Indexes: Primary Key for more information.\n\nDROP PRIMARY KEY\n\nDrops a primary key. For PRIMARY KEY indexes, you can specify a name for the index, but it is silently ignored, and the name of the index is always PRIMARY. See Getting Started with Indexes: Primary Key for more information.\n\nADD FOREIGN KEY\n\nAdds a foreign key. For FOREIGN KEY indexes, a reference definition must be provided. For FOREIGN KEY indexes, you can specify a name for the constraint, using the CONSTRAINT keyword. That name will be used in error messages.\n\nFirst, you have to specify the name of the target (parent) table and a column or a column list which must be indexed and whose values must match to the foreign key''s values. The MATCH clause is accepted to improve the compatibility with other DBMS''s, but has no meaning in MariaDB. The ON DELETE and ON UPDATE clauses specify what must be done when a DELETE (or a REPLACE) statements attempts to delete a referenced row from the parent table, and when an UPDATE statement attempts to modify the referenced foreign key columns in a parent table row, respectively. The following options are allowed:\n\n RESTRICT: The delete/update operation is not performed. The statement terminates with a 1451 error (SQLSTATE ''2300'').\n NO ACTION: Synonym for RESTRICT.\n CASCADE: The delete/update operation is performed in both tables.\n SET NULL: The update or delete goes ahead in the parent table, and the corresponding foreign key fields in the child table are set to NULL. (They must not be defined as NOT NULL for this to succeed).\n SET DEFAULT: This option is implemented only for the legacy PBXT storage engine, which is disabled by default and no longer maintained. It sets the child table''s foreign key fields to their DEFAULT values when the referenced parent table key entries are updated or deleted.\n\nIf either clause is omitted, the default behavior for the omitted clause is RESTRICT.\n\nSee Foreign Keys for more information.\n\nDROP FOREIGN KEY\n\nDrops a foreign key. See Foreign Keys for more information.\n\nADD INDEX\n\nAdds a plain index. Plain indexes are regular indexes that are not unique, and are not acting as a primary key or a foreign key. They are also not the "specialized" FULLTEXT or SPATIAL indexes. For limits on InnoDB indexes, see InnoDB Limitations. See Getting Started with Indexes: Plain Indexes for more information.\n\nDROP INDEX\n\nDrops a plain index. Plain indexes are regular indexes that are not unique, and are not acting as a primary key or a foreign key. They are also not the "specialized" FULLTEXT or SPATIAL indexes. See Getting Started with Indexes: Plain Indexes for more information.\n\nADD UNIQUE INDEX\n\nAdds a unique index. The UNIQUE keyword means that the index will not accept duplicated values, except for NULLs. An error will raise if you try to insert duplicate values in a UNIQUE index. For UNIQUE indexes, you can specify a name for the constraint, using the CONSTRAINT keyword. That name will be used in error messages. See Getting Started with Indexes: Unique Index for more information.\n\nDROP UNIQUE INDEX\n\nDrops a unique index. The UNIQUE keyword means that the index will not accept duplicated values, except for NULLs. An error will raise if you try to insert duplicate values in a UNIQUE index. For UNIQUE indexes, you can specify a name for the constraint, using the CONSTRAINT keyword. That name will be used in error messages. See Getting Started with Indexes: Unique Index for more information.\n\nADD FULLTEXT INDEX\n\nAdds a FULLTEXT index. See Full-Text Indexes for more information.\n\nDROP FULLTEXT INDEX\n\nDrops a FULLTEXT index. See Full-Text Indexes for more information.\n\nADD SPATIAL INDEX\n\nAdds a SPATIAL index. See SPATIAL INDEX for more information.\n\nDROP SPATIAL INDEX\n\nDrops a SPATIAL index. See SPATIAL INDEX for more information.\n\nENABLE/ DISABLE KEYS\n\nDISABLE KEYS disables all non unique keys for the table for storage engines that support this (at least MyISAM and Aria). This can be used to speed up inserts into empty tables. ENABLE KEYS enables all disabled keys.\n\nRENAME TO\n\nRenames a table. See also RENAME TABLE.\n\nADD CONSTRAINT\n\nModifies the table adding a constraint on a particular column or columns.\n\n`sql\nALTER TABLE table_name \nADD CONSTRAINT [constraint_name] CHECK(\n\n[Truncated — full content at mariadb.com/docs]', '', 'https://mariadb.com/docs/server/reference/sql-statements/data-definition/alter/alter-table/README');
INSERT INTO help_topic (help_topic_id, help_category_id, name, description, example, url) VALUES (616, 39, 'Online Schema Change', 'Description\n-----------\n\nThis functionality is available from MariaDB 11.4.\n\nThe term _Online Schema Change_ refers to the ability to update the table schema without blocking concurrent DML[^1] statements for the duration of the schema change.\n\nExamples\n--------\n\nALTER TABLE items ADD ts TIMESTAMP DEFAULT CURRENT_TIMESTAMP;\n\nURL: https://mariadb.com/docs/server/reference/sql-statements/data-definition/alter/alter-table/online-schema-change', '', 'https://mariadb.com/docs/server/reference/sql-statements/data-definition/alter/alter-table/online-schema-change');
INSERT INTO help_topic (help_topic_id, help_category_id, name, description, example, url) VALUES (617, 39, 'ALTER TABLESPACE', 'Description\n-----------\n\nThe ALTER TABLESPACE statement is not supported by MariaDB. It was originally inherited from MySQL NDB Cluster. In MySQL 5.7 and later, the statement is also supported for InnoDB. However, MariaDB has chosen not to include that specific feature. See MDEV-19294 for more information.\n\nURL: https://mariadb.com/docs/server/reference/sql-statements/data-definition/alter/alter-tablespace', '', 'https://mariadb.com/docs/server/reference/sql-statements/data-definition/alter/alter-tablespace');
INSERT INTO help_topic (help_topic_id, help_category_id, name, description, example, url) VALUES (618, 39, 'Atomic DDL', 'Description\n-----------\n\nWe improved readability for DDL (Data Definition Language) operations to make most of them atomic, and the rest crash-safe, even if the server crashes in the middle of an operation.\n\nThese improvements were made in MariaDB 10.6.1.\n\nThe design of Atomic/Crash-safe DDL (MDEV-17567) allows it to work with all storage engines.\n\nDefinitions\n\n Atomic means that either the operation succeeds (and is logged to the binary log or is completely reversed.\n Crash-safe means that in case of a crash, after the server has restarted, all tables are consistent, there are no temporary files or tables on disk and the binary log matches the status of the server.\n DDL Data definition language.\n DML Data manipulation language.\n ''DDL recovery log'' or ''DDL log'' for short, is the new log file, ddl_recovery.log by default, that stores all DDL operations in progress. This is used to recover the state of the server in case of sudden crash.\n\nBackground\n\nBefore 10.6, in case of a crash, there was a small possibility that one of the following things could happen:\n\n There could be temporary tables starting with #sql-alter or #sql-shadow or temporary files ending with '''' left.\n The table in the storage engine and the table''s .frm file could be out of sync.\n During a multi-table rename, only some of the tables were renamed.\n\nWhich DDL Operations are Now Atomic\n\n CREATE TABLE, except when used with CREATE OR REPLACE, which is only crash safe.\n RENAME TABLE and RENAME TABLES.\n CREATE VIEW\n CREATE SEQUENCE\n CREATE TRIGGER\n DROP TRIGGER\n DROP TABLE and DROP VIEW. Dropping multiple tables is only crash safe.\n ALTER TABLE\n ALTER SEQUENCE is not listed above as it is internally implemented as a DML.\n\nWhich DDL Operations are Now Crash Safe\n\nDROP TABLE of Multiple Tables.\n\nDROP TABLE over multiple tables is treated as if every DROP is a separate, atomic operation. This means that after a crash, all fully, or partly, dropped tables will be dropped and logged to the binary log. The undropped tables will be left untouched.\n\nCREATE OR REPLACE TABLE\n\nCREATE OR REPLACE TABLE foo is implemented as:\n\n``sql\nDROP TABLE IF EXISTS foo;\nCREATE TABLE foo ...\n`\n\nThis means that if there is a crash during CREATE TABLE then the original table ''foo'' will be dropped even if the new table was not created.\\\nIf the table was not re-created, the binary log will contain theDROP TABLE.\n\nDROP DATABASE\n\nDROP DATABASE is implemented as:\n\n`sql\n  DROP TABLE table\nLOOP OVER ALL tables\n`\n\nEach DROP TABLE is atomic, but in case of a crash, things will work the same way as DROP TABLE with multiple tables.\n\nAtomic with Different Storage Engines\n\nAtomic/Crash-safe DDL works with all storage engines that either have atomic DDLs internally or are able to re-execute DROP or RENAME in case of failure.\n\nThis should be true for most storage engines. The ones that still need some work are:\n\n The S3 storage engine.\n The partitioning engine. Partitioning should be atomic for most cases, but there are still some known issues that need to be tested and fixed.\n\nThe DDL Log Recovery File\n\nThe new startup option --log-ddl-recovery=path (ddl_recovery.log by default) can be used to specify the place for the DDL log file. This is mainly useful in the case when one has a filesystem on persistent memory, as there is a lot of sync on this file during DDL operations.\n\nThis file contains all DDL operations that are in progress.\n\nAt MariaDB server startup, the DDL log file is copied to a file with the same base name but with a backup.log suffix. This is mainly done to be able to find out what went wrong if recovery fails.\n\nIf the server crashes during recovery (unlikely but possible), the recovery will continue where it was before. The recovery will retry each entry up to 3 times before giving up and proceeding with the next entry.\n\nConclusions\n\n We believe that a clean separation of layers leads to an easier-to-maintain solution. The Atomic DDL implementation in MariaDB 10.6 introduced minimal changes to the storage engine API, mainly for native ALTER TABLE.\n In our InnoDB implementation, no file format changes were needed on top of the RENAME undo log that was introduced in MariaDB 10.2.19 for a backup-safe TRUNCATE re-implementation. Correct use of sound design principles (write-ahead logging and transactions; also file creation now follows the ARIES protocol) is sufficient. We removed the hacks (at most one CREATE or DROP per transaction) and correctly implemented rollback and purge` triggers for the InnoDB SYS_INDEXES table.\n Numerous DDL recovery bugs in InnoDB were found and fixed quickly thanks to rr-project.org. We are still working on one: data files must not be deleted before the DDL transaction is committed.\n\nThanks to Atomic/Crash-safe DDL, the MariaDB server is now much more stable and reliable in unstable environments. There is still ongoing work to fix the few remaining issues mentioned above to make all DDL operations Atomic.\n\nURL: https://mariadb.com/docs/server/reference/sql-statements/data-definition/atomic-ddl', '', 'https://mariadb.com/docs/server/reference/sql-statements/data-definition/atomic-ddl');
INSERT INTO help_topic (help_topic_id, help_category_id, name, description, example, url) VALUES (619, 39, 'CONSTRAINT', 'Syntax\n------\n\n[CONSTRAINT [symbol]] constraint_expression\n\nconstraint_expression:\n  | PRIMARY KEY [index_type] (index_col_name, ...) [index_option] ...\n  | FOREIGN KEY [index_name] (index_col_name, ...) \n       REFERENCES tbl_name (index_col_name, ...)\n       [ON DELETE reference_option]\n       [ON UPDATE reference_option]\n  | UNIQUE [INDEX|KEY] [index_name]\n       [index_type] (index_col_name, ...) [index_option] ...\n  | CHECK (check_constraints)\n\nindex_type:\n  USING {BTREE | HASH | RTREE}\n\nindex_col_name:\n  col_name [(length)] [ASC | DESC]\n\nindex_option:\n  | KEY_BLOCK_SIZE [=] value\n  | index_type\n  | WITH PARSER parser_name\n  | COMMENT ''string''\n  | CLUSTERING={YES|NO}\n\nreference_option:\n  RESTRICT | CASCADE | SET NULL | NO ACTION | SET DEFAULT\n\nDescription\n-----------\n\nConstraints provide restrictions on the data you can add to a table. This allows to enforce data integrity in MariaDB, rather than through application logic. When a statement violates a constraint, MariaDB throws an error.\n\nThere are four types of table constraints:\n\n PRIMARY KEY – Sets the column for referencing rows. Values must be UNIQUE and NOT NULL.&#x20;\n   This constraint is documented here.\n FOREIGN KEY – Sets the column to reference the primary key on another table.&#x20;\n   This constraint is documented here and, in more detail, here and here.\n UNIQUE – Requires values in column or columns only occur once in the table.&#x20;\n   This constraint is documented here.\n CHECK – Checks whether the data meets the given condition.&#x20;\n   This constraint is documented here and, in more detail, here.\n\nThe Information Schema TABLE_CONSTRAINTS Table contains information about tables that have constraints:\n\n``sql\nSELECT CONSTRAINT_SCHEMA, CONSTRAINT_NAME, TABLE_NAME, CONSTRAINT_TYPE  FROM information_schema.TABLE_CONSTRAINTS LIMIT 5;\n+-------------------+----------------------+---------------+-----------------+\n| CONSTRAINT_SCHEMA | CONSTRAINT_NAME      | TABLE_NAME    | CONSTRAINT_TYPE |\n+-------------------+----------------------+---------------+-----------------+\n| nation            | PRIMARY              | countries     | PRIMARY KEY     |\n| nation            | country_code2        | countries     | UNIQUE          |\n| nation            | country_code3        | countries     | UNIQUE          |\n| nation            | countries_ibfk_1     | countries     | FOREIGN KEY     |\n| nation            | PRIMARY              | regions       | PRIMARY KEY     |\n+-------------------+----------------------+---------------+-----------------+\n`\n\nFOREIGN KEY Constraints\n\nInnoDB supports foreign key constraints. The syntax for a foreign key constraint definition in InnoDB looks like this:\n\n`sql\n[CONSTRAINT [symbol]] FOREIGN KEY\n    [index_name] (index_col_name, ...)\n    REFERENCES tbl_name (index_col_name,...)\n    [ON DELETE reference_option]\n    [ON UPDATE reference_option]\n\nreference_option:\n    RESTRICT | CASCADE | SET NULL | NO ACTION\n`\n\nThe symbol clause is optional. If you omit it, MariaDB automatically sets one.&#x20;\n\nThe Information Schema REFERENTIAL_CONSTRAINTS table has more information about foreign keys:\n\n`sql\nSELECT  FROM information_schema.REFERENTIAL_CONSTRAINTS LIMIT 2 \\G\n*********************** 1. row *********************\n       CONSTRAINT_CATALOG: def\n        CONSTRAINT_SCHEMA: nation\n          CONSTRAINT_NAME: countries_ibfk_1\nUNIQUE_CONSTRAINT_CATALOG: def\n UNIQUE_CONSTRAINT_SCHEMA: nation\n   UNIQUE_CONSTRAINT_NAME: PRIMARY\n             MATCH_OPTION: NONE\n              UPDATE_RULE: RESTRICT\n              DELETE_RULE: RESTRICT\n               TABLE_NAME: countries\n    REFERENCED_TABLE_NAME: regions\n********************* 2. row ***********************\n       CONSTRAINT_CATALOG: def\n        CONSTRAINT_SCHEMA: nation\n          CONSTRAINT_NAME: regions_ibfk_1\nUNIQUE_CONSTRAINT_CATALOG: def\n UNIQUE_CONSTRAINT_SCHEMA: nation\n   UNIQUE_CONSTRAINT_NAME: PRIMARY\n             MATCH_OPTION: NONE\n              UPDATE_RULE: RESTRICT\n              DELETE_RULE: RESTRICT\n               TABLE_NAME: regions\n    REFERENCED_TABLE_NAME: continents\n`\n\nFrom MariaDB 12.1, multiple tables in the same database are allowed to use the same constraint name.\n\nConsider this example, which creates two tables, then adds constraints to them:\n\n`sql\nCREATE TABLE t1(a int, b int, key(a),key(b))engine=innodb;\nCREATE TABLE t2(a int, b int, key(a),key(b))engine=innodb;\nALTER TABLE t2 ADD CONSTRAINT c FOREIGN KEY (b) REFERENCES t1(a);\nALTER TABLE t1 ADD CONSTRAINT c FOREIGN KEY (b) REFERENCES t2(a);\n`\n\nPreviously, the last statement failed because of duplicate constraint names:\n\n`\nmysqltest: At line 5: query ''alter table t1 add constraint c foreign key (b) references t2(a)'' failed: ER_CANT_CREATE_TABLE (1005): Can''t create table test.t1 (errno: 121 "Duplicate key on write or update")\n`\n\nNow, the statement works, because internally, names are assigned that aren''t duplicates. (User-visible names can be duplicates, but internally they''re prefixed with the schema and table names.)\n\nCHECK Constraints\n\nConstraints are enforced. You can define constraints in 2 different ways:\n\n CHECK(expression) given as part of a column definition.\n* CONSTRAINT [constraint_name] CHECK (expression)\n\nBefore a row is inserted or updated, all constraints are evaluated in the order they are defined. If any constraint expression returns false, then the row is not inserted or updated. You can use most deterministic functions in a constraint, including UDFs.\n\n`sql\nCREATE TABLE t1 (a INT CHECK (a>2), b INT CHECK (b>2), CONSTRAINT a_greater CHECK (a>b));\n`\n\nIf you use the CONSTRAINT [constraint_name] CHECK (expression) format and don''t give a name to the constraint, the constraint gets an automatically generated name. This is done so that you can later delete it with ALTER TABLE DROP _constraint_.\n\nYou can disable all constraint expression checks by setting the check_constraint_checks variable to OFF`. This is useful for example when loading a table that violates some constraints that you want to later find and fix in SQL.\n\nReplication\n\nIn row-based replication, only the master checks constraints, and failed statements are not replicated. In statement-based replication, the slaves also check constraints. Constraints should therefore be identical, as well as deterministic, in a replication environment.\n\nAuto_increment\n\nauto_increment columns are not permitted in check constraints.\n\nExamples\n--------\n\nCREATE TABLE product (category INT NOT NULL, id INT NOT NULL,\n                      price DECIMAL,\n                      PRIMARY KEY(category, id)) ENGINE=INNODB;\nCREATE TABLE customer (id INT NOT NULL,\n                       PRIMARY KEY (id)) ENGINE=INNODB;\nCREATE TABLE product_order (NO INT NOT NULL AUTO_INCREMENT,\n                            product_category INT NOT NULL,\n                            product_id INT NOT NULL,\n                            customer_id INT NOT NULL,\n                            PRIMARY KEY(NO),\n                            INDEX (product_category, product_id),\n                            FOREIGN KEY (product_category, product_id)\n                              REFERENCES product(category, id)\n                              ON UPDATE CASCADE ON DELETE RESTRICT,\n                            INDEX (customer_id),\n                            FOREIGN KEY (customer_id)\n                              REFERENCES customer(id)) ENGINE=INNODB;\n\nURL: https://mariadb.com/docs/server/reference/sql-statements/data-definition/constraint', '', 'https://mariadb.com/docs/server/reference/sql-statements/data-definition/constraint');
INSERT INTO help_topic (help_topic_id, help_category_id, name, description, example, url) VALUES (620, 39, 'CREATE', 'Description\n-----------\n\ncreate-catalog.md\n\ncreate-database.md\n\ncreate-event.md\n\ncreate-function.md\n\ncreate-function-udf.md\n\ncreate-index.md\n\ncreate-logfile-group.md\n\ncreate-package.md\n\ncreate-package-body.md\n\ncreate-procedure.md\n\ncreate-role.md\n\ncreate-sequence.md\n\ncreate-server.md\n\ncreate-table.md\n\ncreate-table-with-vectors.md\n\ncreate-tablespace.md\n\ncreate-trigger.md\n\ncreate-user.md\n\ncreate-view.md\n\nURL: https://mariadb.com/docs/server/reference/sql-statements/data-definition/create/README', '', 'https://mariadb.com/docs/server/reference/sql-statements/data-definition/create/README');
INSERT INTO help_topic (help_topic_id, help_category_id, name, description, example, url) VALUES (621, 39, 'CREATE DATABASE', 'Syntax\n------\n\nCREATE [OR REPLACE] {DATABASE | SCHEMA} [IF NOT EXISTS] db_name\n    [create_specification] ...\n\ncreate_specification:\n    [DEFAULT] CHARACTER SET [=] charset_name\n  | [DEFAULT] COLLATE [=] collation_name\n  | COMMENT [=] ''comment''\n\nDescription\n-----------\n\nCREATE DATABASE creates a database with the given name. To use this statement, you need the CREATE privilege for the database. CREATE SCHEMA is a synonym for CREATE DATABASE.\n\nFor valid identifiers to use as database names, see Identifier Names.\n\nOR REPLACE\n\nIf the optional OR REPLACE clause is used, it acts as a shortcut for:\n\n``sql\nDROP DATABASE IF EXISTS db_name;\nCREATE DATABASE db_name ...;\n`\n\nIF NOT EXISTS\n\nWhen the IF NOT EXISTS clause is used, MariaDB will return a warning instead of an error if the specified database already exists.\n\nCOMMENT\n\nThe maximum length of a comment is 1024 bytes. If the comment length exceeds this length, an error/warning code 4144 is thrown. The database comment is also added to the db.opt` file, as well as to the information_schema.schemata table.\n\nComments added for databases do not exist.\n\nExamples\n--------\n\nCREATE DATABASE db1;\nQuery OK, 1 row affected (0.18 sec)\n\nCREATE DATABASE db1;\nERROR 1007 (HY000): Can''t create database ''db1''; database exists\n\nCREATE OR REPLACE DATABASE db1;\nQuery OK, 2 rows affected (0.00 sec)\n\nCREATE DATABASE IF NOT EXISTS db1;\nQuery OK, 1 row affected, 1 warning (0.01 sec)\n\nSHOW WARNINGS;\n+-------+------+----------------------------------------------+\n| Level | Code | Message                                      |\n+-------+------+----------------------------------------------+\n| Note  | 1007 | Can''t create database ''db1''; database exists |\n+-------+------+----------------------------------------------+\n\nURL: https://mariadb.com/docs/server/reference/sql-statements/data-definition/create/create-database', '', 'https://mariadb.com/docs/server/reference/sql-statements/data-definition/create/create-database');
INSERT INTO help_topic (help_topic_id, help_category_id, name, description, example, url) VALUES (622, 39, 'CREATE EVENT', 'Syntax\n------\n\nCREATE [OR REPLACE]\n    [DEFINER = { user | CURRENT_USER | role | CURRENT_ROLE }]\n    EVENT \n    [IF NOT EXISTS]\n    event_name    \n    ON SCHEDULE schedule\n    [ON COMPLETION [NOT] PRESERVE]\n    [ENABLE | DISABLE | DISABLE ON SLAVE]\n    [COMMENT ''comment'']\n    DO sql_statement;\n\nschedule:\n    AT timestamp [+ INTERVAL interval] ...\n  | EVERY interval \n    [STARTS timestamp [+ INTERVAL interval] ...] \n    [ENDS timestamp [+ INTERVAL interval] ...]\n\ninterval:\n    quantity {YEAR | QUARTER | MONTH | DAY | HOUR | MINUTE |\n              WEEK | SECOND | YEAR_MONTH | DAY_HOUR | DAY_MINUTE |\n              DAY_SECOND | HOUR_MINUTE | HOUR_SECOND | MINUTE_SECOND}\n\nDescription\n-----------\n\nThis statement creates and schedules a new event. It requires the EVENT privilege for the schema in which the event is to be created.\n\nThe minimum requirements for a valid CREATE EVENT statement are as follows:\n\n The keywords CREATE EVENT plus an event name, which uniquely identifies the event in the current schema.\n An ON SCHEDULE clause, which determines when and how often the event executes.\n* A DO clause, which contains the SQL statement to be executed by an event.\n\nHere is an example of a minimal CREATE EVENT statement:\n\n``sql\nCREATE EVENT myevent\n    ON SCHEDULE AT CURRENT_TIMESTAMP + INTERVAL 1 HOUR\n    DO\n      UPDATE myschema.mytable SET mycol = mycol + 1;\n`\n\nThe previous statement creates an event named myevent. This event executes once\\\n— one hour following its creation\\\n— by running an SQL statement that increments the value of the myschema.mytable table''s mycol column by 1.\n\nThe event_name must be a valid MariaDB identifier with a maximum length of 64 characters. It may be delimited using back ticks, and may be qualified with the name of a database schema. An event is associated with both a MariaDB user (the definer) and a schema, and its name must be unique among names of events within that schema. In general, the rules governing event names are the same as those for names of stored routines. See Identifier Names.\n\nIf no schema is indicated as part of event_name, the default (current) schema is assumed.\n\nFor valid identifiers to use as event names, see Identifier Names.\n\nOR REPLACE\n\nThe OR REPLACE clause works like this: If the event already exists, instead of an error being returned, the existing event will be dropped and replaced by the newly defined event.\n\nThe OR REPLACE clause is not available.\n\nIF NOT EXISTS\n\nIf the IF NOT EXISTS clause is used, MariaDB will return a warning instead of an error if the event already exists. Cannot be used together with OR REPLACE.\n\nON SCHEDULE\n\nThe ON SCHEDULE clause can be used to specify when the event must be triggered.\n\nAT\n\nIf you want to execute the event only once (one time event), you can use the AT keyword, followed by a timestamp. If you use CURRENT_TIMESTAMP, the event acts as soon as it is created. As a convenience, you can add one or more intervals to that timestamp. You can also specify a timestamp in the past, so that the event is stored but not triggered, until you modify it via ALTER EVENT.\n\nThe following example shows how to create an event that will be triggered tomorrow at a certain time:\n\n`sql\nCREATE EVENT example\nON SCHEDULE AT CURRENT_TIMESTAMP + INTERVAL 1 DAY + INTERVAL 3 HOUR\nDO something;\n`\n\nYou can also specify that an event must be triggered at a regular interval (recurring event). In such cases, use the EVERY clause followed by the interval.\n\nIf an event is recurring, you can specify when the first execution must happen via the STARTS clause and a maximum time for the last execution via the ENDS clause. STARTS and ENDS clauses are followed by a timestamp and, optionally, one or more intervals. The ENDS clause can specify a timestamp in the past, so that the event is stored but not executed until you modify it via ALTER EVENT.\n\nIn the following example, next month a recurring event will be triggered hourly for a week:\n\n`sql\nCREATE EVENT example\nON SCHEDULE EVERY 1 HOUR\nSTARTS CURRENT_TIMESTAMP + INTERVAL 1 MONTH\nENDS CURRENT_TIMESTAMP + INTERVAL 1 MONTH + INTERVAL 1 WEEK\nDO some_task;\n`\n\nIntervals consist of a quantity and a time unit. The time units are the same used for other statements and time functions, except that you can''t use microseconds for events. For simple time units, like HOUR or MINUTE, the quantity is an integer number, for example ''10 MINUTE''. For composite time units, like HOUR_MINUTE or HOUR_SECOND, the quantity must be a string with all involved simple values and their separators, for example ''2:30'' or ''2:30:30''.\n\nON COMPLETION \\[NOT] PRESERVE\n\nThe ON COMPLETION clause can be used to specify if the event must be deleted after its last execution (that is, after its AT or ENDS timestamp is past). By default, events are dropped when they are expired. To explicitly state that this is the desired behaviour, you can use ON COMPLETION NOT PRESERVE. Instead, if you want the event to be preserved, you can use ON COMPLETION PRESERVE.\n\nIn you specify ON COMPLETION NOT PRESERVE, and you specify a timestamp in the past for AT or ENDS clause, the event will be immediately dropped. In such cases, you will get a Note 1558: "Event execution time is in the past and ON COMPLETION NOT PRESERVE is set. The event was dropped immediately after creation".\n\nENABLE/DISABLE/DISABLE ON SLAVE\n\nEvents are ENABLEd by default. If you want to stop MariaDB from executing an event, you may specify DISABLE. When it is ready to be activated, you may enable it using ALTER EVENT. Another option is DISABLE ON SLAVE, which indicates that an event was created on a master and has been replicated to the slave, which is prevented from executing the event. If DISABLE ON SLAVE is specifically set, the event will be disabled everywhere. It will not be executed on the master or the slaves.\n\nCOMMENT\n\nThe COMMENT clause may be used to set a comment for the event. Maximum length for comments is 64 characters. The comment is a string, so it must be quoted. To see events comments, you can query the INFORMATION_SCHEMA.EVENTS table (the column is named EVENT_COMMENT`).\n\nExamples\n--------\n\nCREATE EVENT myevent\n    ON SCHEDULE AT CURRENT_TIMESTAMP + INTERVAL 1 HOUR\n    DO\n      UPDATE myschema.mytable SET mycol = mycol + 1;\n\nURL: https://mariadb.com/docs/server/reference/sql-statements/data-definition/create/create-event', '', 'https://mariadb.com/docs/server/reference/sql-statements/data-definition/create/create-event');
INSERT INTO help_topic (help_topic_id, help_category_id, name, description, example, url) VALUES (623, 39, 'CREATE FUNCTION', 'Syntax\n------\n\nCREATE [OR REPLACE]\n    [DEFINER = {user | CURRENT_USER | role | CURRENT_ROLE }]\n    [AGGREGATE] FUNCTION [IF NOT EXISTS] func_name ([func_parameter[,...]])\n    RETURNS type\n    [characteristic ...]\n    func_body\n\nfunc_parameter:\n    [ OUT | INOUT | IN OUT ] param_name type |\n    [ IN ] param_name type [DEFAULT value or expression]\n\ntype:\n    Any valid MariaDB data type\n\ncharacteristic:\n    LANGUAGE SQL\n  | [NOT] DETERMINISTIC\n  | { CONTAINS SQL | NO SQL | READS SQL DATA | MODIFIES SQL DATA }\n  | SQL SECURITY { DEFINER | INVOKER }\n  | COMMENT ''string''\n\nfunc_body:\n    Valid SQL procedure statement\n\nDescription\n-----------\n\nUse the CREATE FUNCTION statement to create a new stored function. You must have the CREATE ROUTINE database privilege to use CREATE FUNCTION. A function takes any number of arguments and returns a value from the function body. The function body can be any valid SQL expression as you would use, for example, in any select expression. If you have the appropriate privileges, you can call the function exactly as you would any built-in function. See Security below for details on privileges.\n\nYou can also use a variant of the CREATE FUNCTION statement to install a user-defined function (UDF) defined by a plugin. See CREATE FUNCTION (UDF) for details.\n\nYou can use a SELECT statement for the function body by enclosing it in parentheses, exactly as you would to use a subselect for any other expression. The SELECT statement must return a single value. If more than one column is returned when the function is called, error 1241 results. If more than one row is returned when the function is called, error 1242 results. Use a LIMIT clause to ensure only one row is returned.\n\nYou can also replace the RETURN clause with a BEGIN...END compound statement. The compound statement must contain a RETURN statement. When the function is called, the RETURN statement immediately returns its result, and any statements after RETURN are effectively ignored.\n\nBy default, a function is associated with the current database. To associate the function explicitly with a given database, specify the fully-qualified name as db_name.func_name when you create it. If the function name is the same as the name of a built-in function, you must use the fully qualified name when you call it.\n\nThe parameter list enclosed within parentheses must always be present. If there are no parameters, an empty parameter list of () should be used. Parameter names are not case-sensitive.\n\nEach parameter can be declared to use any valid data type, except that the COLLATE attribute cannot be used.\n\nFor valid identifiers to use as function names, see Identifier Names.\n\nRETURN\n\nThe RETURN clause can return a function body. In newer versions of MariaDB, it can also return a cursor (using SYS_REFCURSOR).\n\nRETURN func_body\n\nThe RETURN clause can return a function body (a valid SQL PROCEDURE statement).\n\nRETURN SYS_REFCURSOR\n\nIt can also return a cursor, if the function was declared with a SYS_REFCURSOR variable, like this:\n\n``sql\nCREATE FUNCTION f1 RETURN SYS_REFCURSOR AS\n  c SYS_REFCURSOR;\nBEGIN\n  OPEN c FOR SELECT a FROM t1 ORDER BY a;\n  RETURN c;\nEND;\n/\n`\n\nAlternatively, a cursor can be returned in an OUT parameter, see this section.\n\nRETURN func_body\n\nThe RETURN clause can return a function body (a valid SQL PROCEDURE statement).\n\nAGGREGATE\n\nIt is possible to create stored aggregate functions as well. See Stored Aggregate Functions for details.\n\nIN | OUT | INOUT | IN OUT\n\nOUT, INOUT and its equivalent IN OUT, are only valid if called from SET and not SELECT. These quantifiers are especially useful for creating functions with more than one return value. This allows functions to be more complex and nested.\n\n`sql\nDELIMITER $$\nCREATE FUNCTION add_func3(IN a INT, IN b INT, OUT c INT) RETURNS INT\nBEGIN\n  SET c = 100;\n  RETURN a + b;\nEND;\n$$\nDELIMITER ;\n \nSET @a = 2;\nSET @b = 3;\nSET @c = 0;\nSET @res= add_func3(@a, @b, @c);\n\nSELECT add_func3(@a, @b, @c);\nERROR 4186 (HY000): OUT or INOUT argument 3 for function add_func3 is not allowed here\n\nDELIMITER $$\nCREATE FUNCTION add_func4(IN a INT, IN b INT, d INT) RETURNS INT\nBEGIN\n  DECLARE c, res INT;\n  SET res = add_func3(a, b, c) + d;\n  if (c > 99) then\n    return  3;\n  else\n    return res;\n  end if;\nEND;\n$$\n\nDELIMITER ;\n\nSELECT add_func4(1,2,3);\n+------------------+\n| add_func4(1,2,3) |\n+------------------+\n|                3 |\n+------------------+\n`\n\nQuantifiers are not available.\n\nA cursor can be returned, like this:\n\n`sql\nCREATE TABLE t1 (a INT);\nINSERT INTO t1 VALUES (10),(20);\n \nCREATE FUNCTION f1 RETURN SYS_REFCURSOR AS\n  c SYS_REFCURSOR;\nBEGIN\n  OPEN c FOR SELECT a FROM t1 ORDER BY a;\n  RETURN c;\nEND;\n/\n \nCREATE PROCEDURE p1 AS\n  a INT;\n  c SYS_REFCURSOR DEFAULT f1();\nBEGIN\n  LOOP\n    FETCH c INTO a;\n    EXIT WHEN c%NOTFOUND;\n    dbms_output.put_line(a);\n  END LOOP;\n  CLOSE c;\n  END;\n/\n \nCALL p1();\n`\n\nThis feature is not available.\n\nRETURNS\n\nThe RETURNS clause specifies the return type of the function. NULL values are permitted with all return types.\n\nWhat happens if the RETURN clause returns a value of a different type? It depends on the SQL_MODE in effect at the moment of the function creation.\n\nIf the SQL_MODE is strict (STRICT_ALL_TABLES or STRICT_TRANS_TABLES flags are specified), a 1366 error will be produced.\n\nOtherwise, the value is coerced to the proper type. For example, if a function specifies an ENUM or SET value in the RETURNS clause, but the RETURN clause returns an integer, the value returned from the function is the string for the corresponding ENUM member of set of SET members.\n\nMariaDB stores the SQL_MODE system variable setting that is in effect at the time a routine is created, and always executes the routine with this setting in force, regardless of the server SQL mode in effect when the routine is invoked.\n\nLANGUAGE SQL\n\nLANGUAGE SQL is a standard SQL clause which can be used in MariaDB for portability. However that clause has no meaning, because SQL is the only supported language for stored functions.\n\nA function is deterministic if it can produce only one result for a given list of parameters. If the result may be affected by stored data, server variables, random numbers or any value that is not explicitly passed, then the function is not deterministic. Also, a function is non-deterministic if it uses nondeterministic functions like NOW() or CURRENT_TIMESTAMP(). The optimizer may choose a faster execution plan if it known that the function is deterministic. In such cases, you should declare the routine using the DETERMINISTIC keyword. If you want to explicitly state that the function is not deterministic (which is the default) you can use the NOT DETERMINISTIC keywords.\n\nIf you declare a non-deterministic function as DETERMINISTIC, you may get incorrect results. If you declare a deterministic function as NOT DETERMINISTIC, in some cases the queries will be slower.\n\nOR REPLACE\n\nIf the optional OR REPLACE clause is used, it acts as a shortcut for:\n\n`sql\nDROP FUNCTION IF EXISTS function_name;\nCREATE FUNCTION function_name ...;\n`\n\nwith the exception that any existing privileges for the function are not dropped.\n\nIF NOT EXISTS\n\nIf the IF NOT EXISTS clause is used, MariaDB will return a warning instead of an error if the function already exists. Cannot be used together with OR REPLACE.\n\n\\[NOT] DETERMINISTIC\n\nThe [NOT] DETERMINISTIC clause also affects binary logging, because the STATEMENT format can not be used to store or replicate non-deterministic statements.\n\nCONTAINS SQL, NO SQL, READS SQL DATA, and MODIFIES SQL DATA are informative clauses that tell the server what the function does. MariaDB does not check in any way whether the specified clause is correct. If none of these clauses are specified, CONTAINS SQL is used by default.\n\nMODIFIES SQL DATA\n\nMODIFIES SQL DATA means that the function contains statements that may modify data stored in databases. This happens if the function contains statements like DELETE, UPDATE, INSERT, REPLACE or DDL.\n\nREADS SQL DATA\n\nREADS SQL DATA means that the function reads data stored in databases, but does not modify any data. This happens if SELECT statements are used, but there no write operations are executed.\n\nCONTAINS SQL\n\nCONTAINS SQL means that the function contains at least one SQL statement, but it does not read or write any data stored in a database. Examples include SET or DO.\n\nNO SQL\n\nNO SQL means nothing, because MariaDB does not currently support any language other than SQL.\n\nOracle Mode\n\nA subset of Oracle''s PL/SQL language is supported in addition to the traditional SQL/PSM-based MariaDB syntax. See Oracle mode for details on changes when running Oracle mode.\n\nSecurity\n\nYou must have the EXECUTE privilege on a function to call it. MariaDB automatically grants the EXECUTE and ALTER ROUTINE privileges to the account that called CREATE FUNCTION, even if the DEFINER clause was used.\n\nEach function has an account associated as the definer. By default, the definer is the account\\\nthat created the function. Use the DEFINER clause to specify a different account as the\\\ndefiner. You must have the SET USER privilege to use the DEFINER clause. See Account Names for details on specifying accounts.\n\nThe SQL SECURITY clause specifies what privileges are used when a function is called. If SQL SECURITY is INVOKER, the function body will be evaluated using the privileges of the user calling the function. If SQL SECURITY is DEFINER, the function body is always evaluated using the privileges of the definer account. DEFINER is the default.\n\nThis allows you to create functions that grant limited access to certain data. For example, say you have a table that stores some employee information, and that you''ve granted SELECT privileges only on certain columns to the user account roger.\n\n`sql\nCREATE TABLE employees (name TINYTEXT, dept TINYTEXT, salary INT);\nGRANT SELECT (name, dept) ON employees TO roger;\n`\n\nTo allow the user the get the maximum salary for a department, define a function and grant the EXECUTE privilege:\n\n`sql\nCREATE FUNCTION max_salary (dept TINYTEXT) RETURNS INT RETURN\n  (SELECT MAX(salary) FROM employees WHERE employees.dept = dept);\nGRANT EXECUTE ON FUNCTION max_salary TO roger;\n`\n\nSince SQL SECURITY defaults to DEFINER, whenever the user roger calls this function, the subselect will execute with your privileges. As long as you have privileges to select the salary of each employee, the caller of the function will be able to get the maximum salary for each department without being able to see individual salaries.\n\nCharacter Sets and Collations\n\nFunction return types can be declared to use any valid character set and collation. If used, the COLLATE attribute needs to be preceded by a CHARACTER SET` attribute.\n\nIf the character set and collation are not specifically set in the statement, the database defaults at the time of creation will be used. If the database defaults change at a later stage, the stored function character set/collation will not be changed at the same time; the stored function needs to be dropped and recreated to ensure the same character set/collation as the database is used.\n\nExamples\n--------\n\nCREATE FUNCTION hello (s CHAR(20))\n    RETURNS CHAR(50) DETERMINISTIC\n    RETURN CONCAT(''Hello, '',s,''!'');\n\nSELECT hello(''world'');\n+----------------+\n| hello(''world'') |\n+----------------+\n| Hello, world!  |\n+----------------+\n\nURL: https://mariadb.com/docs/server/reference/sql-statements/data-definition/create/create-function', '', 'https://mariadb.com/docs/server/reference/sql-statements/data-definition/create/create-function');
INSERT INTO help_topic (help_topic_id, help_category_id, name, description, example, url) VALUES (624, 39, 'CREATE INDEX', 'Syntax\n------\n\nCREATE [OR REPLACE] [UNIQUE|FULLTEXT|SPATIAL|VECTOR] INDEX \n  [IF NOT EXISTS] index_name\n    [index_type]\n    ON tbl_name (index_col_name,...)\n    [WAIT n | NOWAIT]\n    [index_option]\n    [algorithm_option | lock_option] ...\n\nindex_col_name:\n    col_name [(length)] [ASC | DESC]\n\nindex_type:\n    USING {BTREE | HASH | RTREE}\n\nindex_option:\n    [ KEY_BLOCK_SIZE [=] value\n  | index_type\n  | WITH PARSER parser_name\n  | COMMENT ''string''\n  | CLUSTERING={YES| NO} ]\n  [ IGNORED | NOT IGNORED ]\n  | DISTANCE={EUCLIDEAN| COSINE} ]\n  | M=number ]\n\nalgorithm_option:\n    ALGORITHM [=] {DEFAULT|INPLACE|COPY|NOCOPY|INSTANT}\n\nlock_option:\n    LOCK [=] {DEFAULT|NONE|SHARED|EXCLUSIVE}\n\nDescription\n-----------\n\nThe CREATE INDEX statement is used to add indexes to a table. Indexes can be created at the same as the table, with the CREATE TABLE statement. In some cases, such as for InnoDB primary keys, doing so during creation is preferable, as adding a primary key will involve rebuilding the table.\n\nThe statement is mapped to an ALTER TABLE statement to create indexes. See ALTER TABLE. CREATE INDEX cannot be used to create a PRIMARY KEY; use ALTER TABLE instead.\n\nIf another connection is using the table, a metadata lock is active, and this statement will wait until the lock is released. This is also true for non-transactional tables.\n\nAnother shortcut, DROP INDEX, allows the removal of an index.\n\nFor valid identifiers to use as index names, see Identifier Names.\n\nFor limits on InnoDB indexes, see InnoDB Limitations.\n\nNote that KEY_BLOCK_SIZE is currently ignored in CREATE INDEX, although it is included in the output of SHOW CREATE TABLE.\n\nPrivileges\n\nExecuting the CREATE INDEX statement requires the INDEX privilege for the table or the database.\n\nOnline DDL\n\nOnline DDL is supported with the ALGORITHM and LOCK clauses.\n\nSee InnoDB Online DDL Overview for more information on online DDL with InnoDB.\n\nCREATE OR REPLACE INDEX\n\nIf the OR REPLACE clause is used and if the index already exists, then instead of returning an error, the server will drop the existing index and replace it with the newly defined index.\n\nCREATE INDEX IF NOT EXISTS\n\nIf the IF NOT EXISTS clause is used, then the index will only be created if an index with the same name does not already exist. If the index already exists, then a warning will be triggered by default.\n\nIndex Definitions\n\nSee CREATE TABLE: Index Definitions for information about index definitions.\n\nWAIT/NOWAIT\n\nSet the lock wait timeout. See WAIT and NOWAIT.\n\nALGORITHM\n\nSee ALTER TABLE: ALGORITHM for more information.\n\nLOCK\n\nSee ALTER TABLE: LOCK for more information.\n\nProgress Reporting\n\nMariaDB provides progress reporting for CREATE INDEX statement for clients that support the new progress reporting protocol. For example, if you were using the mariadb client, then the progress report might look like this::\n\n``sql\nCREATE INDEX i ON tab (num);\nStage: 1 of 2 ''copy to tmp table''    46% of stage\n`\n\nThe progress report is also shown in the output of the SHOW PROCESSLIST statement and in the contents of the information_schema.PROCESSLIST table.\n\nSee Progress Reporting for more information.\n\nWITHOUT OVERLAPS\n\nThe WITHOUT OVERLAPS clause allows you to constrain a primary or unique index such that application-time periods cannot overlap. It can be used like this:\n\n`sql\nCREATE UNIQUE INDEX u ON rooms (room_number, p WITHOUT OVERLAPS);\n`\n\nWITHOUT OVERLAPS` is not available.\n\nExamples\n--------\n\nCREATE UNIQUE INDEX HomePhone ON Employees(Home_Phone);\n\nURL: https://mariadb.com/docs/server/reference/sql-statements/data-definition/create/create-index', '', 'https://mariadb.com/docs/server/reference/sql-statements/data-definition/create/create-index');
INSERT INTO help_topic (help_topic_id, help_category_id, name, description, example, url) VALUES (625, 39, 'CREATE LOGFILE GROUP', 'Description\n-----------\n\nThe CREATE LOGFILE GROUP statement is not supported by MariaDB. It was originally inherited from MySQL NDB Cluster. See MDEV-19295 for more information.\n\nURL: https://mariadb.com/docs/server/reference/sql-statements/data-definition/create/create-logfile-group', '', 'https://mariadb.com/docs/server/reference/sql-statements/data-definition/create/create-logfile-group');
INSERT INTO help_topic (help_topic_id, help_category_id, name, description, example, url) VALUES (626, 39, 'CREATE PACKAGE BODY', 'Syntax\n------\n\nCREATE [ OR REPLACE ]\n    [DEFINER = { user | CURRENT_USER | role | CURRENT_ROLE }]\n    PACKAGE BODY\n    [ IF NOT EXISTS ]\n    [ db_name . ] package_name\n    [ package_characteristic... ]\n{ AS | IS }\n    package_implementation_declare_section\n    package_implementation_executable_section\nEND [ package_name]\n\npackage_implementation_declare_section:\n    package_implementation_item_declaration\n      [ package_implementation_item_declaration... ]\n      [ package_implementation_routine_definition... ]\n  | package_implementation_routine_definition\n      [ package_implementation_routine_definition...]\n\npackage_implementation_item_declaration:\n    variable_declaration ;\n\nvariable_declaration:\n    variable_name[,...] type [:= expr ]\n\npackage_implementation_routine_definition:\n    FUNCTION package_specification_function\n       [ package_implementation_function_body ] ;\n  | PROCEDURE package_specification_procedure\n       [ package_implementation_procedure_body ] ;\n\npackage_implementation_function_body:\n    { AS | IS } package_routine_body [func_name]\n\npackage_implementation_procedure_body:\n    { AS | IS } package_routine_body [proc_name]\n\npackage_routine_body:\n    [ package_routine_declarations ]\n    BEGIN\n      statements [ EXCEPTION exception_handlers ]\n    END\n\npackage_routine_declarations:\n    package_routine_declaration '';'' [package_routine_declaration '';'']...\n\npackage_routine_declaration:\n          variable_declaration\n        | condition_name CONDITION FOR condition_value\n        | user_exception_name EXCEPTION\n        | CURSOR_SYM cursor_name\n          [ ( cursor_formal_parameters ) ]\n          IS select_statement\n        ;\n\npackage_implementation_executable_section:\n          END\n        | BEGIN\n            statement ; [statement ; ]...\n          [EXCEPTION exception_handlers]\n          END\n\nexception_handlers:\n           exception_handler [exception_handler...]\n\nexception_handler:\n          WHEN_SYM condition_value [, condition_value]...\n            THEN_SYM statement ; [statement ;]...\n\ncondition_value:\n          condition_name\n        | user_exception_name\n        | SQLWARNING\n        | SQLEXCEPTION\n        | NOT FOUND\n        | OTHERS_SYM\n        | SQLSTATE [VALUE] sqlstate_value\n        | mariadb_error_code\n\nDescription\n-----------\n\nThe CREATE PACKAGE BODY statement creates the package body for a stored package. The package specification must be previously created using the CREATE PACKAGE statement.\n\nA package body provides implementations of the package public routines and can optionally have:\n\n package-wide private variables\n package private routines\n forward declarations for private routines\n an executable initialization section\n\n> Starting with MariaDB 13.0.1, package bodies can define RECORD and REF CURSOR types that can be used as:\n>\n>  Parameters (IN, OUT, INOUT) for procedures and functions defined in the package\n>  RETURN clause data types for package functions\n>\n> For detailed syntax and examples, see DECLARE TYPE.<br>\n\nExamples\n--------\n\nSET sql_mode=ORACLE;\nDELIMITER $$\nCREATE OR REPLACE PACKAGE employee_tools AS\n  FUNCTION getSalary(eid INT) RETURN DECIMAL(10,2);\n  PROCEDURE raiseSalary(eid INT, amount DECIMAL(10,2));\n  PROCEDURE raiseSalaryStd(eid INT);\n  PROCEDURE hire(ename TEXT, esalary DECIMAL(10,2));\nEND;\n$$\nCREATE PACKAGE BODY employee_tools AS\n  -- package body variables\n  stdRaiseAmount DECIMAL(10,2):=500;\n\n  -- private routines\n  PROCEDURE log (eid INT, ecmnt TEXT) AS\n  BEGIN\n    INSERT INTO employee_log (id, cmnt) VALUES (eid, ecmnt);\n  END;\n\n  -- public routines\n  PROCEDURE hire(ename TEXT, esalary DECIMAL(10,2)) AS\n    eid INT;\n  BEGIN\n    INSERT INTO employee (name, salary) VALUES (ename, esalary);\n    eid:= last_insert_id();\n    log(eid, ''hire '' || ename);\n  END;\n\n  FUNCTION getSalary(eid INT) RETURN DECIMAL(10,2) AS\n    nSalary DECIMAL(10,2);\n  BEGIN\n    SELECT salary INTO nSalary FROM employee WHERE id=eid;\n    log(eid, ''getSalary id='' || eid || '' salary='' || nSalary);\n    RETURN nSalary;\n  END;\n\n  PROCEDURE raiseSalary(eid INT, amount DECIMAL(10,2)) AS\n  BEGIN\n    UPDATE employee SET salary=salary+amount WHERE id=eid;\n    log(eid, ''raiseSalary id='' || eid || '' amount='' || amount);\n  END;\n\n  PROCEDURE raiseSalaryStd(eid INT) AS\n  BEGIN\n    raiseSalary(eid, stdRaiseAmount);\n    log(eid, ''raiseSalaryStd id='' || eid);\n  END;\n\nBEGIN\n  -- This code is executed when the current session\n  -- accesses any of the package routines for the first time\n  log(0, ''Session '' || connection_id() || '' '' || current_user || '' started'');\nEND;\n$$\n\nDELIMITER ;\n\nURL: https://mariadb.com/docs/server/reference/sql-statements/data-definition/create/create-package-body', '', 'https://mariadb.com/docs/server/reference/sql-statements/data-definition/create/create-package-body');
INSERT INTO help_topic (help_topic_id, help_category_id, name, description, example, url) VALUES (627, 39, 'CREATE PACKAGE', 'Syntax\n------\n\nCREATE\n    [ OR REPLACE]\n    [DEFINER = { user | CURRENT_USER | role | CURRENT_ROLE }]\n    PACKAGE [ IF NOT EXISTS ]\n    [ db_name . ] package_name\n    [ package_characteristic ... ]\n    [ package_specification_element ... ]\nEND\n\npackage_characteristic:\n    COMMENT ''string''\n  | SQL SECURITY { DEFINER | INVOKER }\n\npackage_specification_element:\n    FUNCTION_SYM package_specification_function ;\n  | PROCEDURE_SYM package_specification_procedure ;\n\npackage_specification_function:\n    func_name [ ( func_param [, func_param]... ) ]\n    RETURNS type\n    [ package_routine_characteristic... ]\n\npackage_specification_procedure:\n    proc_name [ ( proc_param [, proc_param]... ) ]\n    [ package_routine_characteristic... ]\n\nfunc_param:\n    param_name [ IN | OUT | INOUT | IN OUT ] type\n\nproc_param:\n    param_name [ IN | OUT | INOUT | IN OUT ] type\n\ntype:\n    Any valid MariaDB explicit or anchored data type\n\npackage_routine_characteristic:\n      COMMENT  ''string''\n    | LANGUAGE SQL\n    | { CONTAINS SQL | NO SQL | READS SQL DATA | MODIFIES SQL DATA }\n    | SQL SECURITY { DEFINER | INVOKER }\n\nDescription\n-----------\n\nCREATE PACKAGE creates the specification for a stored package (a collection of logically related stored objects). A stored package specification declares public routines (procedures and functions) of the package, but does not implement these routines.\n\nA package whose specification was created by the CREATE PACKAGE statement, should later be implemented using the CREATE PACKAGE BODY statement.\n\nFunction parameter quantifiers IN | OUT | INOUT | IN OUT\n\nMariaDB starting with 10.8.0\n\nThe function parameter quantifiers for IN, OUT, INOUT, and IN OUT are supported anywhere.\n\nThe function parameter quantifiers for IN, OUT, INOUT, and IN OUT are supported only in procedures.\n\nOUT, INOUT and its equivalent IN OUT, are only valid if called from SET and not SELECT. These quantifiers are especially useful for creating functions and procedures with more than one return value. This allows functions and procedures to be more complex and nested.\n\nExamples\n--------\n\nSET sql_mode=ORACLE; # unnecessary from MariaDB 11.4\nDELIMITER $$\nCREATE OR REPLACE PACKAGE employee_tools AS\n  FUNCTION getSalary(eid INT) RETURN DECIMAL(10,2);\n  PROCEDURE raiseSalary(eid INT, amount DECIMAL(10,2));\n  PROCEDURE raiseSalaryStd(eid INT);\n  PROCEDURE hire(ename TEXT, esalary DECIMAL(10,2));\nEND;\n$$\nDELIMITER ;\n\nURL: https://mariadb.com/docs/server/reference/sql-statements/data-definition/create/create-package', '', 'https://mariadb.com/docs/server/reference/sql-statements/data-definition/create/create-package');

INSERT INTO help_topic (help_topic_id, help_category_id, name, description, example, url) VALUES (629, 39, 'CREATE TABLE', 'Description\n-----------\n\nUse the CREATE TABLE statement to create a table with the given name.\n\nIn its most basic form, the CREATE TABLE statement provides a table name followed by a list of columns, indexes, and constraints. By default, the table is created in the default database. Specify a database with db_name.tbl_name. If you quote the table name, you must quote the database name and table name separately as ` db_name.tbl_name . This is particularly useful for CREATE TABLE ... SELECT, because it allows creating a table in a database that contains data from other databases. See Identifier Qualifiers.\n\nIf a table with the same name exists, error 1050 results. Use IF NOT EXISTS to suppress this error and issue a note instead. Use SHOW WARNINGS to see notes.\n\nThe CREATE TABLE statement automatically commits the current transaction, except when using the TEMPORARY keyword.\n\nFor valid identifiers to use as table names, see Identifier Names.\n\nIf the default_storage_engine is set to ColumnStore, it needs to be set on all UMs. Otherwise, when the tables using the default engine are replicated across UMs, they will use the wrong engine. You should therefore not use this option as a session variable with ColumnStore.\n\nMicrosecond precision can be between 0-6. If no precision is specified, it is assumed to be 0, for backward compatibility reasons.\n\nPrivileges\n\nExecuting the CREATE TABLE statement requires the CREATE privilege for the table or the database.\n\nCREATE OR REPLACE\n\nIf the OR REPLACE clause is used and the table already exists, then instead of returning an error, the server will drop the existing table and replace it with the newly defined table.\n\nThis syntax was originally added to make replication more robust if it has to rollback and repeat statements such as CREATE ... SELECT on slaves.\n\n`sql\nCREATE OR REPLACE TABLE table_name (a INT);\n`\n\nis basically the same as:\n\n`sql\nDROP TABLE IF EXISTS TABLE_NAME;\nCREATE TABLE TABLE_NAME (a INT);\n`\n\nwith the following exceptions:\n\n If table_name was locked with LOCK TABLES, it will continue to be locked after the statement.\n Temporary tables are only dropped if the TEMPORARY keyword was used. (With DROP TABLE, temporary tables are preferred to be dropped before normal tables).\n\nThings to be Aware of With CREATE OR REPLACE\n\n The table is dropped first (if it existed), and after that, the CREATE is done. Because of this, if the CREATE fails, then the table will not exist anymore after the statement. If the table was used with LOCK TABLES, it will be unlocked.\n One can''t use OR REPLACE together with IF EXISTS.\n Slaves will, by default, use CREATE OR REPLACE when replicating CREATE statements that don''t use IF EXISTS. This can be changed by setting the variable slave-ddl-exec-mode to STRICT.\n\nCREATE TABLE IF NOT EXISTS\n\nIf the IF NOT EXISTS clause is used, then the table will only be created if a table with the same name does not already exist. If the table already exists, then a warning will be triggered by default.\n\nCREATE TEMPORARY TABLE\n\nUse the TEMPORARY keyword to create a temporary table that is only available to the current session. Temporary tables are dropped when the session ends. Temporary table names are specific to the session. They will not conflict with other temporary tables from other sessions, even if they share the same name. They will shadow names of non-temporary tables or views, if they are identical. A temporary table can have the same name as a non-temporary table, which is located in the same database. In that case, their name will reference the temporary table when used in SQL statements. You must have the CREATE TEMPORARY TABLES privilege on the database to create temporary tables. If no storage engine is specified, the default_tmp_storage_engine setting will determine the engine.\n\nROCKSDB temporary tables cannot be created by setting the default_tmp_storage_engine system variable or using CREATE TEMPORARY TABLE LIKE. If you try, an error is returned. Explicitly creating a temporary table with ENGINE=ROCKSDB has never been permitted.\n\nROCKSDB temporary tables cannot be created by setting the default_tmp_storage_engine system variable, or using CREATE TEMPORARY TABLE LIKE. They can be specified, but fail silently, and a MyISAM table is created instead. Explicitly creating a temporary table with ENGINE=ROCKSDB has never been permitted.\n\nReplicating temporary tables\n\nBy default, temporary tables are only created on the slave if the master is using the STATEMENT binary log format.\n\nThe new deterministic rules for logging of temporary tables are:\n\n The STATEMENT binlog format is used. The user can change this behavior by setting create_tmp_table_binlog_formats to MIXED, STATEMENT in which case the create is logged in statement format also in MIXED mode (as before).\n Changes to temporary tables are only binlogged if and only if the CREATE was logged. The logging happens under STATEMENT or MIXED. If binlog_format=ROW, temporary table changes are not binlogged. A temporary table that is changed under ROW is marked as ''not up to date in binlog'' and no future row changes are logged. Any usage of this temporary table will force row logging of other tables in any future statements using the temporary table to be row logged.\n DROP TEMPORARY is binlogged only if the CREATE was binlogged.\n\nIn some contexts, temporary tables on the master and slave can become inconsistent.\\\nOne example is if a temporary table is updated with the value of a non deterministic function like UUID(), in which the change is never sent to the slave.\n\nIn some other contexts, while using MIXED mode, all changes will be logged in ROW mode while the user has any active temporary tables, even if the temporary tables are not used in the query. This depends on in which format some previous independent commands were logged.\n\nThere are many other pitfalls with logging temporary table to the slave.\n\nCREATE TABLE ... LIKE\n\nUse the LIKE clause instead of a full table definition to create an empty table with the same definition as another table, including columns, indexes, and table options. Foreign key definitions, as well as any DATA DIRECTORY or INDEX DIRECTORY table options specified on the original table, will not be created.\n\nLIKE does not preserve the TEMPORARY status of the original table. To make the new table TEMPORARY as well, use CREATE TEMPORARY TABLE ... LIKE.\n\nLIKE does not work with views, only base tables. Attempting to use it on a view will result in an error:\n\n`sql\nCREATE VIEW v (mycol) AS SELECT ''abc'';\n\nCREATE TABLE v2 LIKE v;\nERROR 1347 (HY000): ''test.v'' is not of type ''BASE TABLE''\n`\n\nThe same version of the table storage format as found in the original table is used for the new table.\n\nCREATE TABLE ... LIKE performs the same checks as CREATE TABLE. So a statement may fail if a change in the SQL_MODE renders it invalid. For example:\n\n`sql\nCREATE OR REPLACE TABLE x (d DATE DEFAULT ''0000-00-00'');\n\nSET SQL_MODE=''NO_ZERO_DATE'';\n\nCREATE OR REPLACE TABLE y LIKE x;\nERROR 1067 (42000): Invalid default value for ''d''\n`\n\nCREATE TABLE ... SELECT\n\nYou can create a table containing data from other tables using the CREATE ... SELECT statement. Columns will be created in the table for each field returned by the SELECT query.\n\nYou can also define some columns normally and add other columns from a SELECT. You can also create columns in the normal way and assign them some values using the query, this is done to force a certain type or other field characteristics. The columns that are not named in the query will be placed before the others. For example:\n\n`sql\nCREATE TABLE test (a INT NOT NULL, b CHAR(10)) ENGINE=MyISAM\n    SELECT 5 AS b, c, d FROM another_table;\n`\n\nRemember that the query just returns data. If you want to use the same indexes or the same column attributes ([NOT] NULL, DEFAULT, AUTO_INCREMENT, CHECK constraints) in the new table, you need to specify them manually. Types and sizes are not automatically preserved if no data is returned by the SELECT that requires the full size, and VARCHAR could be converted into CHAR. The CAST() function can be used to force the new table to use certain types.\n\nAliases (AS) are taken into account, and they should always be used when you SELECT an expression (function, arithmetical operation, etc.).\n\nIf an error occurs during the query, the table will not be created at all.\n\nIf the new table has a primary key or UNIQUE indexes, you can use the IGNORE or REPLACE keywords to handle duplicate key errors during the query. IGNORE means that the newer values must not be inserted if an identical value exists in the index. REPLACE means that older values must be overwritten.\n\nIf the columns in the new table are more than the rows returned by the query, the columns populated by the query will be placed after the other columns. Note that if the strict SQL_MODE is on, and the columns that are not named in the query do not have a DEFAULT value, an error will be raised and no rows will be copied.\n\nConcurrent inserts are not used during the execution of a CREATE ... SELECT.\n\nIf the table already exists, an error similar to the following will be returned:\n\n`\nERROR 1050 (42S01): Table ''t'' already exists\n`\n\nIf the IF NOT EXISTS clause is used, and the table exists, a note will be produced instead of an error.\n\nTo insert rows from a query into an existing table, INSERT ... SELECT can be used.\n\nColumn Definitions\n\n<pre class="language-bnf"><code class="lang-bnf">create_definition:\n  { col_name column_definition | <a data-footnote-ref href="#user-content-fn-5">index_definition</a> | <a data-footnote-ref href="#user-content-fn-4">period_definition</a> | CHECK (expr) }\n\ncolumn_definition:\n  <a data-footnote-ref href="#user-content-fn-6">data_type</a>\n    [NOT NULL | NULL] [DEFAULT default_value | (expression)]\n    [ON UPDATE [NOW | CURRENT_TIMESTAMP] [(precision)]]\n    [AUTO_INCREMENT] [ZEROFILL] [UNIQUE [KEY] | [PRIMARY] KEY]\n    [INVISIBLE] [{WITH|WITHOUT} SYSTEM VERSIONING]\n    [COMMENT ''string''] [REF_SYSTEM_ID = value]\n    [<a data-footnote-ref href="#user-content-fn-5">reference_definition</a>]\n  | <a data-footnote-ref href="#user-content-fn-6">data_type</a> [GENERATED ALWAYS] \n  AS [ ROW {START|END} [NOT NULL ENABLE] [[PRIMARY] KEY]\n        | (expression) [VIRTUAL | PERSISTENT | STORED] ]\n      [INVISIBLE] [UNIQUE [KEY]] [COMMENT ''string'']\n\nconstraint_definition:\n   CONSTRAINT [constraint_name] CHECK (expression)\n</code></pre>\n\nNote:\n\nMariaDB accepts the shortcut format with a REFERENCES clause only in ALTER TABLE and CREATE TABLE statements, but that syntax does nothing. For example:\n\n`sql\nCREATE TABLE b(for_key INT REFERENCES a(not_key));\n`\n\nMariaDB will attempt to apply the constraint. See Foreign Keys examples.\n\nMariaDB accepts the shortcut format with a REFERENCES clause only in ALTER TABLE and CREATE TABLE statements, but that syntax does nothing. For example:\n\n`sql\nCREATE TABLE b(for_key INT REFERENCES a(not_key));\n`\n\nEach definition either creates a column in the table or specifies an index or constraint on one or more columns. See Indexes below for details on creating indexes.\n\nCreate a column by specifying a column name and a data type, optionally followed by column options. See Data Types for a full list of data types allowed in MariaDB.\n\nNULL and NOT NULL\n\nUse the NULL or NOT NULL options to specify that values in the column may or may not be NULL, respectively. By default, values may be NULL. See also NULL Values in MariaDB.\n\nDEFAULT Column Option\n\nSpecify a default value using the DEFAULT clause. If you don''t specify DEFAULT then the following rules apply:\n\n If the column is not defined with NOT NULL, AUTO_INCREMENT or TIMESTAMP, an explicit DEFAULT NULL will be added.\\\n  Note that in MySQL, you may get an explicit DEFAULT for primary key parts, if not specified with NOT NULL.\n\nThe default value will be used if you INSERT a row without specifying a value for that column, or if you specify DEFAULT for that column.\n\nCURRENT_TIMESTAMP may also be used as the default value for a DATETIME\n\nYou can use most functions in DEFAULT. Expressions should have parentheses around them. If you use a non deterministic function in DEFAULT then all inserts to the table will be replicated in row mode. You can even refer to earlier columns in the DEFAULT expression (excluding AUTO_INCREMENT columns):\n\n`sql\nCREATE TABLE t1 (a INT DEFAULT (1+1), b INT DEFAULT (a+1));\nCREATE TABLE t2 (a BIGINT PRIMARY KEY DEFAULT UUID_SHORT());\n`\n\nThe DEFAULT clause cannot contain any stored functions or subqueries, and a column used in the clause must already have been defined earlier in the statement.\n\nIt is possible to assign BLOB or TEXT columns a DEFAULT value.\n\nYou can also use DEFAULT (NEXT VALUE FOR sequence).\n\nAUTO_INCREMENT Column Option\n\nUse AUTO_INCREMENT to create a column whose value can be set automatically from a simple counter. You can only use AUTO_INCREMENT on a column with an integer type. The column must be a key, and there can only be one AUTO_INCREMENT column in a table. If you insert a row without specifying a value for that column (or if you specify 0, NULL, or DEFAULT as the value), the actual value will be taken from the counter, with each insertion incrementing the counter by one. You can still insert a value explicitly. If you insert a value that is greater than the current counter value, the counter is\\\nset based on the new value. An AUTO_INCREMENT column is implicitly NOT NULL. Use LAST_INSERT_ID to get the AUTO_INCREMENT value most recently used by an INSERT statement.\n\nZEROFILL Column Option\n\nIf the ZEROFILL column option is specified for a column using a numeric data type, then the column will be set to UNSIGNED and the spaces used by default to pad the field are replaced with zeros. ZEROFILL is ignored in expressions or as part of a UNION, INTERSECT, or EXCEPT. ZEROFILL is a non-standard MariaDB and MySQL extension.\n\nPRIMARY KEY Column Option\n\nUse PRIMARY KEY to make a column a primary key. A primary key is a special type of a unique key. There can be at most one primary key per table, and it is implicitly NOT NULL.\n\nSpecifying a column as a unique key creates a unique index on that column. See the Index Definitions section below for more information.\n\nUNIQUE KEY Column Option\n\nUse UNIQUE KEY (or just UNIQUE) to specify that all values in the column must be distinct from each other. Unless the column is NOT NULL, there may be multiple rows with NULL in the column.\n\n`\n`\n\nWhen any inserts or updates occur in the table, reading the binlog shows the hidden column (@3). it causes confusion for the user; we can document these behaviours.\n\n`\nINSERT INTO securedb.t_long_keys\nSET\n@1=1 / INT meta=0 nullable=0 is_null=0 /\n@2=''a'' / VARSTRING(4073) meta=4073 nullable=1 is_null=0 /\n@3=580 / LONGINT meta=0 nullable=1 is_null=0 /\n`\n\n`sql\nCREATE TABLE t_long_keys (   a INT PRIMARY KEY,   b  VARCHAR(4073),   UNIQUE KEY uk_b (b) ) ENGINE=InnoDB;\nQuery OK, 0 r\n\n[Truncated — full content at mariadb.com/docs]', '', 'https://mariadb.com/docs/server/reference/sql-statements/data-definition/create/create-table');
INSERT INTO help_topic (help_topic_id, help_category_id, name, description, example, url) VALUES (630, 39, 'CREATE TABLESPACE', 'Description\n-----------\n\nThe CREATE TABLESPACE statement is not supported by MariaDB. It was originally inherited from MySQL NDB Cluster. In MySQL 5.7 and later, the statement is also supported for InnoDB. However, MariaDB has chosen not to include that specific feature. See MDEV-19294 for more information.\n\nURL: https://mariadb.com/docs/server/reference/sql-statements/data-definition/create/create-tablespace', '', 'https://mariadb.com/docs/server/reference/sql-statements/data-definition/create/create-tablespace');
INSERT INTO help_topic (help_topic_id, help_category_id, name, description, example, url) VALUES (631, 39, 'Generated Columns', 'Syntax\n------\n\n<type>  [GENERATED ALWAYS]  AS   ( <expression> )\n[VIRTUAL | PERSISTENT | STORED]  [UNIQUE] [UNIQUE KEY] [COMMENT <text>]\n\nDescription\n-----------\n\nA generated column is a column in a table that cannot explicitly be set to a specific value in a DML query. Instead, its value is automatically generated based on an expression. This expression might generate the value based on the values of other columns in the table, or it might generate the value by calling built-in functions or user-defined functions (UDFs).\n\nThere are two types of generated columns:\n\n PERSISTENT (a.k.a. STORED): This type''s value is actually stored in the table.\n VIRTUAL: This type''s value is not stored at all. Instead, the value is generated dynamically when the table is queried. This type is the default.\n\nGenerated columns are also sometimes called computed columns or virtual columns.\n\nSupported Features\n\nStorage Engine Support\n\n Generated columns can only be used with storage engines which support them. If you try to use a storage engine that does not support them, then you will see an error similar to the following:\n\n``sql\nERROR 1910 (HY000): TokuDB storage engine does not support computed columns\n`\n\n InnoDB, Aria, MyISAM and CONNECT support generated columns.\n A column in a MERGE table can be built on a PERSISTENT generated column.\n   However, a column in a MERGE table can not be defined as a VIRTUAL and PERSISTENT generated column.\n\nData Type Support\n\nAll data types are supported when defining generated columns.\n\nUsing the ZEROFILL column option is supported when defining generated columns.\n\nUsing the AUTO_INCREMENT column option is not supported when defining generated columns.\n\nUsing the AUTO_INCREMENT column option is supported when defining generated columns.\n\nIt does not work correctly, though. See MDEV-11117.\n\nIndex Support\n\nUsing a generated column as a table''s primary key is not supported. See MDEV-5590 for more information. If you try to use one as a primary key, then you will see an error similar to the following:\n\n`sql\nERROR 1903 (HY000): Primary key cannot be defined upon a computed column\n`\n\nUsing PERSISTENT generated columns as part of a foreign key is supported.\n\nReferencing PERSISTENT generated columns as part of a foreign key is also supported.\n\nHowever, using the ON UPDATE CASCADE, ON UPDATE SET NULL, or ON DELETE SET NULL clauses is not supported. If you try to use an unsupported clause, then you will see an error similar to the following:\n\n`sql\nERROR 1905 (HY000): Cannot define foreign key with ON UPDATE SET NULL clause on a computed column\n`\n\nDefining indexes on both VIRTUAL and PERSISTENT generated columns is supported.\n\nIf an index is defined on a generated column, then the optimizer considers using it in the same way as indexes based on "real" columns.\n\nThe optimizer can recognize use of indexed virtual column expressions in the WHERE clause and use them to construct range and ref(const) accesses. See Virtual Column Support in the Optimizer.\n\nThe optimizer cannot recognize use of indexed virtual column expressions in the WHERE clause and use them to construct range and ref(const) accesses. See Virtual Column Support in the Optimizer.\n\nStatement Support\n\nGenerated columns are used in DML queries just as if they were "real" columns.\n\n However, VIRTUAL and PERSISTENT generated columns differ in how their data is stored.\n   Values for PERSISTENT generated columns are generated whenever a DML queries inserts or updates the row with the special DEFAULT value. This generates the columns value, and it is stored in the table like the other "real" columns. This value can be read by other DML queries just like the other "real" columns.\n   Values for VIRTUAL generated columns are not stored in the table. Instead, the value is generated dynamically whenever the column is queried. If other columns in a row are queried, but the VIRTUAL generated column is not one of the queried columns, then the column''s value is not generated.\n\nThe SELECT statement supports generated columns.\n\nGenerated columns can be referenced in the INSERT, UPDATE, and DELETE statements.\n\n However, VIRTUAL or PERSISTENT generated columns cannot be explicitly set to any other values than NULL or DEFAULT. If a generated column is explicitly set to any other value, then the outcome depends on whether strict mode is enabled in sql_mode. If it is not enabled, then a warning will be raised and the default generated value will be used instead. If it is enabled, then an error will be raised instead.\n\nThe CREATE TABLE statement has limited support for generated columns.\n\n It supports defining generated columns in a new table.\n It supports using generated columns to partition tables.\n It does not support using the versioning clauses with generated columns.\n\nThe ALTER TABLE statement has limited support for generated columns.\n\n It supports the MODIFY and CHANGE clauses for PERSISTENT generated columns.\n It does not support the MODIFY clause for VIRTUAL generated columns if ALGORITHM is not set to COPY. See MDEV-15476 for more information.\n It does not support the CHANGE clause for VIRTUAL generated columns if ALGORITHM is not set to COPY. See MDEV-17035 for more information.\n It does not support altering a table if ALGORITHM is not set to COPY if the table has a VIRTUAL generated column that is indexed. See MDEV-14046 for more information.\n It does not support adding a VIRTUAL generated column with the ADD clause if the same statement is also adding other columns if ALGORITHM is not set to COPY. See MDEV-17468 for more information.\n It also does not support altering an existing column into a VIRTUAL generated column.\n It supports using generated columns to partition tables.\n It does not support using the versioning clauses with generated columns.\n\nThe SHOW CREATE TABLE statement supports generated columns.\n\nThe DESCRIBE statement can be used to check whether a table has generated columns.\n\n You can tell which columns are generated by looking for the ones where the Extra column is set to either VIRTUAL or PERSISTENT. For example:\n\n`sql\nDESCRIBE table1;\n+-------+-------------+------+-----+---------+------------+\n| Field | Type        | Null | Key | Default | Extra      |\n+-------+-------------+------+-----+---------+------------+\n| a     | int(11)     | NO   |     | NULL    |            |\n| b     | varchar(32) | YES  |     | NULL    |            |\n| c     | int(11)     | YES  |     | NULL    | VIRTUAL    |\n| d     | varchar(5)  | YES  |     | NULL    | PERSISTENT |\n+-------+-------------+------+-----+---------+------------+\n`\n\nGenerated columns can be properly referenced in the NEW and OLD rows in triggers.\n\nStored procedures support generated columns.\n\nThe HANDLER statement supports generated columns.\n\nExpression Support\n\nMost legal, deterministic expressions which can be calculated are supported in expressions for generated columns.\n\nMost built-in functions are supported in expressions for generated columns.\n\n However, some built-in functions can''t be supported for technical reasons. For example, If you try to use an unsupported function in an expression, an error is generated similar to the following:\n\n`sql\nERROR 1901 (HY000): Function or expression ''dayname()'' cannot be used in the GENERATED ALWAYS AS clause of v\n`\n\nSubqueries are not supported in expressions for generated columns because the underlying data can change.\n\nUsing anything that depends on data outside the row is not supported in expressions for generated columns.\n\nStored functions are not supported in expressions for generated columns. See MDEV-17587 for more information.\n\nNon-deterministic built-in functions are supported in expressions for not indexed VIRTUAL generated columns.\n\nNon-deterministic built-in functions are not supported in expressions for PERSISTENT or indexed VIRTUAL generated columns.\n\nUser-defined functions (UDFs) are supported in expressions for generated columns.\n\n However, MariaDB can''t check whether a UDF is deterministic, so it is up to the user to be sure that they do not use non-deterministic UDFs with VIRTUAL generated columns.\n\nDefining a generated column based on other generated columns defined before it in the table definition is supported. For example:\n\n`sql\nCREATE TABLE t1 (a INT AS (1), b INT AS (a));\n`\n\nHowever, defining a generated column based on other generated columns defined after in the table definition is not supported in expressions for generation columns because generated columns are calculated in the order they are defined.\n\nUsing an expression that exceeds 255 characters in length is supported in expressions for generated columns. The new limit for the entire table definition, including all expressions for generated columns, is 65,535 bytes.\n\nUsing constant expressions is supported in expressions for generated columns. For example:\n\n`sql\nCREATE TABLE t1 (a int as (1));\n`\n\nMaking Stored Values Consistent\n\nWhen a generated column is PERSISTENT or indexed, the value of the expression needs to be consistent regardless of the SQL Mode flags in the current session. If it is not, then the table will be seen as corrupted when the value that should actually be returned by the computed expression and the value that was previously stored and/or indexed using a different sql_mode setting disagree.\n\nThere are currently two affected classes of inconsistencies: character padding and unsigned subtraction:\n\n For a VARCHAR or TEXT generated column the length of the value returned can vary depending on the PAD_CHAR_TO_FULL_LENGTH sql_mode flag. To make the value consistent, create the generated column using an RTRIM() or RPAD() function. Alternately, create the generated column as a CHAR column so that its data is always fully padded.\n If a SIGNED generated column is based on the subtraction of an UNSIGNED value, the resulting value can vary depending on how large the value is and the NO_UNSIGNED_SUBTRACTION sql_mode flag. To make the value consistent, use CAST() to ensure that each UNSIGNED operand is SIGNED before the subtraction.\n\nA fatal error is generated when trying to create a generated column whose value can change depending on the SQL Mode when its data is PERSISTENT or indexed. For an existing generated column that has a potentially inconsistent value, a warning about a bad expression is generated the first time it is used (if warnings are enabled).\n\nFor an existing generated column that has a potentially inconsistent value, a warning about a bad expression is generated the first time it is used (if warnings are enabled).\n\nA potentially inconsistent generated column outputs a warning when created or first used (without restricting the creation).\n\nA potentially inconsistent generated column does not output a warning when created or first used.\n\nHere is an example of two tables that are warned about:\n\n`sql\nCREATE TABLE bad_pad (\n  txt CHAR(5),\n  -- CHAR -> VARCHAR or CHAR -> TEXT can''t be persistent or indexed:\n  vtxt VARCHAR(5) AS (txt) PERSISTENT\n);\n\nCREATE TABLE bad_sub (\n  num1 BIGINT UNSIGNED,\n  num2 BIGINT UNSIGNED,\n  -- The resulting value can vary for some large values\n  vnum BIGINT AS (num1 - num2) VIRTUAL,\n  KEY(vnum)\n);\n`\n\nThe warnings look like this:\n\n`sql\nWarning (Code 1901): Function or expression ''txt'' cannot be used in the GENERATED ALWAYS AS clause of vtxt\nWarning (Code 1105): Expression depends on the @@sql_mode value PAD_CHAR_TO_FULL_LENGTH\n\nWarning (Code 1901): Function or expression ''num1 - num2'' cannot be used in the GENERATED ALWAYS AS clause of vnum\nWarning (Code 1105): Expression depends on the @@sql_mode value NO_UNSIGNED_SUBTRACTION\n`\n\nTo work around the issue, force the padding or type to make the generated column''s expression return a consistent value. For example:\n\n`sql\nCREATE TABLE good_pad (\n  txt CHAR(5),\n  -- Using RTRIM() or RPAD() makes the value consistent:\n  vtxt VARCHAR(5) AS (RTRIM(txt)) PERSISTENT,\n  -- When not persistent or indexed, it is OK for the value to vary by mode:\n  vtxt2 VARCHAR(5) AS (txt) VIRTUAL,\n  -- CHAR -> CHAR is always OK:\n  txt2 CHAR(5) AS (txt) PERSISTENT\n);\n\nCREATE TABLE good_sub (\n  num1 BIGINT UNSIGNED,\n  num2 BIGINT UNSIGNED,\n  -- The indexed value will always be consistent in this expression:\n  vnum BIGINT AS (CAST(num1 AS SIGNED) - CAST(num2 AS SIGNED)) VIRTUAL,\n  KEY(vnum)\n);\n`\n\nHere is an example of two tables whose creation is rejected:\n\n`sql\nCREATE TABLE bad_pad (\n  txt CHAR(5),\n  -- CHAR -> VARCHAR or CHAR -> TEXT can''t be persistent or indexed:\n  vtxt VARCHAR(5) AS (txt) PERSISTENT\n);\n\nCREATE TABLE bad_sub (\n  num1 BIGINT UNSIGNED,\n  num2 BIGINT UNSIGNED,\n  -- The resulting value can vary for some large values\n  vnum BIGINT AS (num1 - num2) VIRTUAL,\n  KEY(vnum)\n);\n`\n\nMySQL Compatibility Support\n\n The STORED keyword is supported as an alias for the PERSISTENT keyword.\n Tables created with MySQL 5.7 or later that contain MySQL''s generated columns can be imported into MariaDB without a dump and restore.\n\nImplementation Differences\n\nGenerated columns are subject to various constraints in other DBMSs that are not present in MariaDB''s implementation. Generated columns may also be called computed columns or virtual columns in different implementations. The various details for a specific implementation can be found in the documentation for each specific DBMS.\n\nImplementation Differences Compared to Microsoft SQL Server\n\nMariaDB''s generated columns implementation does not enforce the following\\\nrestrictions that are present in Microsoft SQL Server''s computed columns implementation:\n\n MariaDB allows server variables in generated column expressions, including those that change dynamically, such as warning_count.\n MariaDB allows the CONVERT_TZ() function to be called with a named time zone as an argument, even though time zone names and time offsets are configurable.\n MariaDB allows the CAST() function to be used with non-unicode character sets, even though character sets are configurable and differ between binaries/versions.\n MariaDB allows FLOAT expressions to be used in generated columns. Microsoft SQL Server considers these expressions to be "imprecise" due to potential cross-platform differences in floating-point implementations and precision.\n Microsoft SQL Server requires the ARITHABORT mode to be set, so that division by zero returns an error, and not a NULL.\n Microsoft SQL Server requires QUOTED_IDENTIFIER to be set in sql_mode. In MariaDB, if data is inserted without ANSI_QUOTES` set in sql_mode, then it will be processed and stored differently in a generated column that contains quoted identifiers.\n\nMicrosoft SQL Server enforces the above restrictions by doing one of the following things:\n\n Refusing to create computed columns.\n Refusing to allow updates to a table containing them.\n* Refusing to use an index over such a column if it can not be guaranteed that the expression is fully deterministic.\n\nIn MariaDB, as long as the sql_mode, language, and other settings that were in effect duri\n\n[Truncated — full content at mariadb.com/docs]', '', 'https://mariadb.com/docs/server/reference/sql-statements/data-definition/create/generated-columns');
INSERT INTO help_topic (help_topic_id, help_category_id, name, description, example, url) VALUES (632, 39, 'Invisible Columns', 'Description\n-----------\n\nInvisible columns (sometimes also called hidden columns) are hidden in certain contexts.\n\nColumns can be given an INVISIBLE attribute in a CREATE TABLE or ALTER TABLE statement. These columns will then not be listed in the results of a SELECT \\ statement, nor do they need to be assigned a value in an INSERT statement, unless INSERT explicitly mentions them by name.\n\nSince SELECT  does not return the invisible columns, new tables or views created in this manner will have no trace of the invisible columns. If specifically referenced in the SELECT statement, the columns will be brought into the view/new table, but the INVISIBLE attribute will not.\n\nInvisible columns can be declared as NOT NULL, but then require a DEFAULT value.\n\nIt is not possible for all columns in a table to be invisible.\n\nExamples\n--------\n\nCREATE TABLE t (x INT INVISIBLE);\nERROR 1113 (42000): A table must have at least 1 column\n\nCREATE TABLE t (x INT, y INT INVISIBLE, z INT INVISIBLE NOT NULL);\nERROR 4106 (HY000): Invisible column z must have a default value\n\nCREATE TABLE t (x INT, y INT INVISIBLE, z INT INVISIBLE NOT NULL DEFAULT 4);\n\nINSERT INTO t VALUES (1),(2);\n\nINSERT INTO t (x,y) VALUES (3,33);\n\nSELECT * FROM t;\n+------+\n| x    |\n+------+\n|    1 |\n|    2 |\n|    3 |\n+------+\n\nSELECT x,y,z FROM t;\n+------+------+---+\n| x    | y    | z |\n+------+------+---+\n|    1 | NULL | 4 |\n|    2 | NULL | 4 |\n|    3 |   33 | 4 |\n+------+------+---+\n\nDESC t;\n+-------+---------+------+-----+---------+-----------+\n| Field | Type    | Null | Key | Default | Extra     |\n+-------+---------+------+-----+---------+-----------+\n| x     | int(11) | YES  |     | NULL    |           |\n| y     | int(11) | YES  |     | NULL    | INVISIBLE |\n| z     | int(11) | NO   |     | 4       | INVISIBLE |\n+-------+---------+------+-----+---------+-----------+\n\nALTER TABLE t MODIFY x INT INVISIBLE, MODIFY y INT, MODIFY z INT NOT NULL DEFAULT 4;\n\nDESC t;\n+-------+---------+------+-----+---------+-----------+\n| Field | Type    | Null | Key | Default | Extra     |\n+-------+---------+------+-----+---------+-----------+\n| x     | int(11) | YES  |     | NULL    | INVISIBLE |\n| y     | int(11) | YES  |     | NULL    |           |\n| z     | int(11) | NO   |     | 4       |           |\n+-------+---------+------+-----+---------+-----------+\n\nURL: https://mariadb.com/docs/server/reference/sql-statements/data-definition/create/invisible-columns', '', 'https://mariadb.com/docs/server/reference/sql-statements/data-definition/create/invisible-columns');
INSERT INTO help_topic (help_topic_id, help_category_id, name, description, example, url) VALUES (633, 39, 'Silent Column Changes', 'Description\n-----------\n\nWhen a CREATE TABLE or ALTER TABLE command is issued, MariaDB silently changes a column specification in the following cases:\n\n PRIMARY KEY columns are always NOT NULL.\n Any trailing spaces from SET and ENUM values are discarded.\n TIMESTAMP columns are always NOT NULL, and display sizes are discarded.\n A row-size limit of 65535 bytes applies.\n If strict SQL mode is not enabled (by default, it is), a VARCHAR column longer than 65535 become TEXT, and a VARBINARY columns longer than 65535 becomes a BLOB. If strict mode is enabled the silent changes will not be made, and an error will occur.\n If a USING clause specifies an index that''s not permitted by the storage engine, the engine will instead use another available index type that can be applied without affecting results.\n* If the CHARACTER SET binary attribute is specified, the column is created as the matching binary data type. A TEXT becomes a BLOB, CHAR a BINARY and VARCHAR a VARBINARY. ENUMs and SETs are created as defined.\n\nTo ease imports from other RDBMSs, MariaDB also silently maps the following data types:\n\n| Other Vendor Type    | MariaDB Type                                                      |\n| -------------------- | ----------------------------------------------------------------- |\n| BOOL                 | TINYINT      |\n| BOOLEAN              | TINYINT      |\n| CHARACTER VARYING(M) | VARCHAR(M)    |\n| FIXED                | DECIMAL      |\n| FLOAT4               | FLOAT          |\n| FLOAT8               | DOUBLE        |\n| INT1                 | TINYINT      |\n| INT2                 | SMALLINT    |\n| INT3                 | MEDIUMINT  |\n| INT4                 | INT              |\n| INT8                 | BIGINT        |\n| LONG VARBINARY       | MEDIUMBLOB |\n| LONG VARCHAR         | MEDIUMTEXT |\n| LONG                 | MEDIUMTEXT |\n| MIDDLEINT            | MEDIUMINT  |\n| NUMERIC              | DECIMAL      |\n\nCurrently, all MySQL types are supported in MariaDB.\n\nFor type mapping between Cassandra and MariaDB, see Cassandra storage engine.\n\nExamples\n--------\n\nCREATE TABLE SilenceIsGolden\n   (\n    f1 TEXT CHARACTER SET BINARY,\n    f2 VARCHAR(15) CHARACTER SET BINARY,\n    f3 CHAR CHARACTER SET BINARY,\n    f4 ENUM(''x'',''y'',''z'') CHARACTER SET BINARY,\n    f5 VARCHAR (65536),\n    f6 VARBINARY (65536),\n    f7 INT1\n   );\nQuery OK, 0 rows affected, 2 warnings (0.31 sec)\n\nSHOW WARNINGS;\n+-------+------+-----------------------------------------------+\n| Level | Code | Message                                       |\n+-------+------+-----------------------------------------------+\n| Note  | 1246 | Converting column ''f5'' from VARCHAR to TEXT   |\n| Note  | 1246 | Converting column ''f6'' from VARBINARY to BLOB |\n+-------+------+-----------------------------------------------+\n\nDESCRIBE SilenceIsGolden;\n+-------+-------------------+------+-----+---------+-------+\n| Field | Type              | Null | Key | Default | Extra |\n+-------+-------------------+------+-----+---------+-------+\n| f1    | blob              | YES  |     | NULL    |       |\n| f2    | varbinary(15)     | YES  |     | NULL    |       |\n| f3    | binary(1)         | YES  |     | NULL    |       |\n| f4    | enum(''x'',''y'',''z'') | YES  |     | NULL    |       |\n| f5    | mediumtext        | YES  |     | NULL    |       |\n| f6    | mediumblob        | YES  |     | NULL    |       |\n| f7    | tinyint(4)        | YES  |     | NULL    |       |\n+-------+-------------------+------+-----+---------+-------+\n\nURL: https://mariadb.com/docs/server/reference/sql-statements/data-definition/create/silent-column-changes', '', 'https://mariadb.com/docs/server/reference/sql-statements/data-definition/create/silent-column-changes');
INSERT INTO help_topic (help_topic_id, help_category_id, name, description, example, url) VALUES (634, 39, 'DROP DATABASE', 'Syntax\n------\n\nDROP {DATABASE | SCHEMA} [IF EXISTS] db_name\n\nDescription\n-----------\n\nDROP DATABASE drops all tables in the database and deletes the database. Be very careful with this statement! To use DROP DATABASE, you need the DROP privilege on the database. DROP SCHEMA is a synonym for DROP DATABASE.\n\nImportant: When a database is dropped, user privileges on the database are not automatically dropped. See GRANT.\n\nIF EXISTS\n\nUse IF EXISTS to prevent an error from occurring for databases that do not exist. A NOTE is generated for each non-existent database when using IF EXISTS. See SHOW WARNINGS.\n\nAtomic DDL\n\nMariaDB 10.6.1 supports Atomic DDL.DROP DATABASE is implemented as\n\n``sql\nLOOP OVER ALL tables\n  DROP TABLE tbl\n`\n\nEach individual DROP TABLE is atomic while DROP DATABASE as a whole is crash-safe.\n\nAtomic DROP` is not available.\n\nExamples\n--------\n\nDROP DATABASE bufg;\nQuery OK, 0 rows affected (0.39 sec)\n\nDROP DATABASE bufg;\nERROR 1008 (HY000): Can''t drop database ''bufg''; database doesn''t exist\n\n \\W\nSHOW warnings enabled.\n\nDROP DATABASE IF EXISTS bufg;\nQuery OK, 0 rows affected, 1 warning (0.00 sec)\nNote (Code 1008): Can''t DROP DATABASE ''bufg''; DATABASE doesn''t exist\n\nURL: https://mariadb.com/docs/server/reference/sql-statements/data-definition/drop/drop-database', '', 'https://mariadb.com/docs/server/reference/sql-statements/data-definition/drop/drop-database');
INSERT INTO help_topic (help_topic_id, help_category_id, name, description, example, url) VALUES (635, 39, 'DROP EVENT', 'Syntax\n------\n\nDROP EVENT [IF EXISTS] event_name\n\nDescription\n-----------\n\nThis statement drops the event named event_name. The event immediately ceases being active, and is deleted completely from the server.\n\nIf the event does not exist, the errorERROR 1517 (HY000): Unknown event ''event_name'' results. You can override this and cause the statement to generate a NOTE for non-existent events instead by usingIF EXISTS. See SHOW WARNINGS.\n\nThis statement requires the EVENT privilege.\n\nExamples\n--------\n\nDROP EVENT myevent3;\n\nURL: https://mariadb.com/docs/server/reference/sql-statements/data-definition/drop/drop-event', '', 'https://mariadb.com/docs/server/reference/sql-statements/data-definition/drop/drop-event');
INSERT INTO help_topic (help_topic_id, help_category_id, name, description, example, url) VALUES (636, 39, 'DROP INDEX', 'Syntax\n------\n\nDROP INDEX [IF EXISTS] index_name ON tbl_name \n    [WAIT n |NOWAIT]\n\nDescription\n-----------\n\nDROP INDEX drops the index named index_name from the table tbl_name. This statement is mapped to an ALTER TABLE statement to drop the index.\n\nIf another connection is using the table, a metadata lock is active, and this statement will wait until the lock is released. This is also true for non-transactional tables.\n\nSee ALTER TABLE.\n\nAnother shortcut, CREATE INDEX, allows the creation of an index.\n\nTo remove the primary key, PRIMARY must be specified as index_name. Note that the quotes are necessary, because PRIMARY is a keyword.\n\nPrivileges\n\nExecuting the DROP INDEX statement requires the INDEX privilege for the table or the database.\n\nOnline DDL\n\nOnline DDL is used by default with InnoDB, when the drop index operation supports it.\n\nSee InnoDB Online DDL Overview for more information on online DDL with InnoDB.\n\nDROP INDEX IF EXISTS ...\n\nIf the IF EXISTS clause is used, then MariaDB will return a warning instead of an error if the index does not exist.\n\nWAIT/NOWAIT\n\nSets the lock wait timeout. See WAIT and NOWAIT.\n\nProgress Reporting\n\nMariaDB provides progress reporting for DROP INDEX statement for clients\\\nthat support the new progress reporting protocol. For example, if you were using the mariadb client, then the progress report might look like this::\n\nURL: https://mariadb.com/docs/server/reference/sql-statements/data-definition/drop/drop-index', '', 'https://mariadb.com/docs/server/reference/sql-statements/data-definition/drop/drop-index');
INSERT INTO help_topic (help_topic_id, help_category_id, name, description, example, url) VALUES (637, 39, 'DROP LOGFILE GROUP', 'Description\n-----------\n\nThe DROP LOGFILE GROUP statement is not supported by MariaDB. It was originally inherited from MySQL NDB Cluster. See MDEV-19295 for more information.\n\nURL: https://mariadb.com/docs/server/reference/sql-statements/data-definition/drop/drop-logfile-group', '', 'https://mariadb.com/docs/server/reference/sql-statements/data-definition/drop/drop-logfile-group');
INSERT INTO help_topic (help_topic_id, help_category_id, name, description, example, url) VALUES (638, 39, 'DROP PACKAGE BODY', 'Syntax\n------\n\nDROP PACKAGE BODY [IF EXISTS]  [ db_name . ] package_name\n\nDescription\n-----------\n\nThe DROP PACKAGE BODY statement can be used when Oracle SQL_MODE is set.\n\nThe DROP PACKAGE BODY statement drops the package body (that is, the implementation) which was created using the CREATE PACKAGE BODY statement.\n\nNote, DROP PACKAGE BODY drops only the package implementation, but does not drop the package specification. Use DROP PACKAGE to drop the package entirely (i.e. both implementation and specification).\n\nURL: https://mariadb.com/docs/server/reference/sql-statements/data-definition/drop/drop-package-body', '', 'https://mariadb.com/docs/server/reference/sql-statements/data-definition/drop/drop-package-body');
INSERT INTO help_topic (help_topic_id, help_category_id, name, description, example, url) VALUES (639, 39, 'DROP PACKAGE', 'Syntax\n------\n\nDROP PACKAGE [IF EXISTS]  [ db_name . ] package_name\n\nDescription\n-----------\n\nThe DROP PACKAGE statement can be used when Oracle SQL_MODE is set.\n\nThe DROP PACKAGE statement drops a stored package entirely:\n\n Drops the package specification (earlier created using the CREATE PACKAGE statement).\n Drops the package implementation, if the implementation was already created using the CREATE PACKAGE BODY statement.\n\nURL: https://mariadb.com/docs/server/reference/sql-statements/data-definition/drop/drop-package', '', 'https://mariadb.com/docs/server/reference/sql-statements/data-definition/drop/drop-package');
INSERT INTO help_topic (help_topic_id, help_category_id, name, description, example, url) VALUES (640, 39, 'DROP SERVER', 'Syntax\n------\n\nDROP SERVER [ IF EXISTS ] server_name\n\nDescription\n-----------\n\nDrops the server definition for the server named _server_name_. The corresponding row within the mysql.servers table will be deleted. This statement requires the SUPER privilege or, from MariaDB 10.5.2, the FEDERATED ADMIN privilege.\n\nDropping a server for a table does not affect any FederatedX, FEDERATED, Connect or Spider tables that used this connection information when they were created.\n\nDROP SERVER is not written to the binary log, irrespective of the binary log format being used. From MariaDB 10.1.13, Galera replicates the CREATE SERVER, ALTER SERVER and DROP SERVER statements.\n\nIF EXISTS\n\nIf the IF EXISTS clause is used, MariaDB will not return an error if the server does not exist. Unlike all other statements, DROP SERVER IF EXISTS does not issue a note if the server does not exist. See MDEV-9400.\n\nExamples\n--------\n\nDROP SERVER s;\n\nURL: https://mariadb.com/docs/server/reference/sql-statements/data-definition/drop/drop-server', '', 'https://mariadb.com/docs/server/reference/sql-statements/data-definition/drop/drop-server');
INSERT INTO help_topic (help_topic_id, help_category_id, name, description, example, url) VALUES (641, 39, 'DROP TABLE', 'Syntax\n------\n\nDROP [TEMPORARY] TABLE [IF EXISTS] [/COMMENT TO SAVE/]\n    tbl_name [, tbl_name] ...\n    [WAIT n|NOWAIT]\n    [RESTRICT | CASCADE]\n\nDescription\n-----------\n\nDROP TABLE removes one or more tables. You must have the DROP privilege for each table. All table data and the table definition are removed, as well as triggers associated to the table, so be careful with this statement! If any of the tables named in the argument list do not exist, MariaDB returns an error indicating by name which non-existing tables it was unable to drop, but it also drops all of the tables in the list that do exist.\n\nImportant: When a table is dropped, user privileges on the table are not automatically dropped. See GRANT.\n\nIf another thread is using the table in an explicit transaction or an autocommit transaction, then the thread acquires a metadata lock (MDL) on the table. The DROP TABLE statement will wait in the "Waiting for table metadata lock" thread state until the MDL is released. MDLs are released in the following cases:\n\n If an MDL is acquired in an explicit transaction, then the MDL will be released when the transaction ends.\n If an MDL is acquired in an autocommit transaction, then the MDL will be released when the statement ends.\n Transactional and non-transactional tables are handled the same.\n\nNote that for a partitioned table, DROP TABLE permanently removes the table definition, all of its partitions, and all of the data which was stored in those partitions. It also removes the partitioning definition (.par) file associated with the dropped table.\n\nFor each referenced table, DROP TABLE drops a temporary table with that name, if it exists. If it does not exist, and the TEMPORARY keyword is not used, it drops a non-temporary table with the same name, if it exists. The TEMPORARY keyword ensures that a non-temporary table will not accidentally be dropped.\n\nUse IF EXISTS to prevent an error from occurring for tables that do not\\\nexist. A NOTE is generated for each non-existent table when usingIF EXISTS. See SHOW WARNINGS.\n\nIf a foreign key references this table, the table cannot be dropped. In this case, it is necessary to drop the foreign key first.\n\nRESTRICT and CASCADE are allowed to make porting from other database systems easier. In MariaDB, they do nothing.\n\nThe comment before the table names (/COMMENT TO SAVE/) is stored in the binary log. That feature can be used by replication tools to send their internal messages.\n\nIt is possible to specify table names as db_name.tab_name. This is useful to delete tables from multiple databases with one statement. See Identifier Qualifiers for details.\n\nThe DROP privilege is required to use DROP TABLE on non-temporary tables. For temporary tables, no privilege is required, because such tables are only visible for the current session.\n\nNote: DROP TABLE automatically commits the current active transaction, unless you use the TEMPORARY keyword.\n\nDROP TABLE reliably deletes table remnants inside a storage engine even if the .frm file is missing.\n\nDROP TABLE does not reliably delete table remnants inside a storage engine even if the .frm file is missing. A missing .frm file will result in the statement failing.\n\nWAIT/NOWAIT\n\nSet the lock wait timeout. See WAIT and NOWAIT.\n\nDROP TABLE in replication\n\nDROP TABLE has the following characteristics in replication:\n\n DROP TABLE IF EXISTS are always logged.\n DROP TABLE without IF EXISTS for tables that don''t exist are not written to the binary log.\n Dropping of TEMPORARY tables are prefixed in the log with TEMPORARY. These drops are only logged when running statement or mixed mode replication.\n One DROP TABLE statement can be logged with up to 3 different DROP statements:\n   DROP TEMPORARY TABLE list_of_non_transactional_temporary_tables\n   DROP TEMPORARY TABLE list_of_transactional_temporary_tables\n   DROP TABLE list_of_normal_tables\n\nDROP TABLE on the master is treated on the slave as DROP TABLE IF EXISTS. You can change that by setting slave-ddl-exec-mode to STRICT.\n\nDropping an Internal #sql-... Table\n\nDROP TABLE is atomic.\n\nif the mariadbd process is killed during an ALTER TABLE, you may find a table named #sql-... in your data directory. These temporary tables will always be deleted automatically.\n\nIf you want to delete one of these tables explicitly you can do so by using the following syntax:\n\n``\nDROP TABLE #mysql50##sql-...;\n`\n\nWhen running an ALTER TABLE…ALGORITHM=INPLACE that rebuilds the table, InnoDB will create an internal #sql-ib table.\n\nThe same name as the .frm file is used for the intermediate copy of the table. The #sql-ib names are used by TRUNCATE and delayed DROP.\n\nThe #sql-ib tables will be deleted automatically.\n\nDropping All Tables in a Database\n\nThe best way to drop all tables in a database is by executing DROP DATABASE, which will drop the database itself, and all tables in it.\n\nHowever, if you want to drop all tables in the database, but you also want to keep the database itself and any other non-table objects in it, then you would need to execute DROP TABLE to drop each individual table. You can construct these DROP TABLE commands by querying the TABLES table in the information_schema database. For example:\n\n`\nSELECT CONCAT(''DROP TABLE IF EXISTS '', TABLE_SCHEMA, ''.'', TABLE_NAME, '';'')\nFROM information_schema.TABLES\nWHERE TABLE_SCHEMA = ''mydb'';\n`\n\nAtomic DROP TABLE\n\nMariaDB starting with 10.6.1\n\nDROP TABLE for a single table is atomic (MDEV-25180) for most engines, including InnoDB, MyRocks, MyISAM and Aria. This means that if there is a crash (server down or power outage) during DROP TABLE, all tables that have been processed so far will be completely dropped, including related trigger files and status entries, and the binary log will include a DROP TABLE statement for the dropped tables. Tables for which the drop had not started will be left intact.DROP TABLE was extended to be able to delete a table that was only partly dropped (MDEV-11412), as explained above. Atomic DROP TABLE is the final piece to make DROP TABLE fully reliable. Dropping multiple tables is crash-safe. See Atomic DDL for more information.\n\nThere is a small chance that, during a server crash happening in the middle of DROP TABLE, some storage engines that were using multiple storage files, like MyISAM, could have only a part of its internal files dropped. In MariaDB 10.5, DROP TABLE was extended to be able to delete a table that was only partly dropped (MDEV-11412) as explained above. Atomic DROP TABLE is the final piece to make DROP TABLE` fully reliable. Dropping multiple tables is crash-safe. See Atomic DDL for more information.\n\nExamples\n--------\n\nDROP TABLE Employees, Customers;\n\nURL: https://mariadb.com/docs/server/reference/sql-statements/data-definition/drop/drop-table', '', 'https://mariadb.com/docs/server/reference/sql-statements/data-definition/drop/drop-table');
INSERT INTO help_topic (help_topic_id, help_category_id, name, description, example, url) VALUES (642, 39, 'DROP TABLESPACE', 'Description\n-----------\n\nThe DROP TABLESPACE statement is not supported by MariaDB. It was originally inherited from MySQL NDB Cluster. In MySQL 5.7 and later, the statement is also supported for InnoDB. However, MariaDB has chosen not to include that specific feature. See MDEV-19294 for more information.\n\nURL: https://mariadb.com/docs/server/reference/sql-statements/data-definition/drop/drop-tablespace', '', 'https://mariadb.com/docs/server/reference/sql-statements/data-definition/drop/drop-tablespace');
INSERT INTO help_topic (help_topic_id, help_category_id, name, description, example, url) VALUES (643, 39, 'DROP TRIGGER', 'Syntax\n------\n\nDROP TRIGGER [IF EXISTS] [schema_name.]trigger_name\n\nDescription\n-----------\n\nThis statement drops a trigger. The schema (database) name is optional. If the schema is omitted, the trigger is dropped from the default schema. Its use requires the TRIGGER privilege for the table associated with the trigger.\n\nUse IF EXISTS to prevent an error from occurring for a trigger that does not exist. A NOTE is generated for a non-existent trigger when using IF EXISTS. See SHOW WARNINGS.\n\nNote: Triggers for a table are also dropped if you drop the table.\n\nAtomic DDL\n\nDROP TRIGGER is atomic.\n\nDROP TRIGGER is not atomic.\n\nExamples\n--------\n\nDROP TRIGGER test.example_trigger;\n\nURL: https://mariadb.com/docs/server/reference/sql-statements/data-definition/drop/drop-trigger', '', 'https://mariadb.com/docs/server/reference/sql-statements/data-definition/drop/drop-trigger');
INSERT INTO help_topic (help_topic_id, help_category_id, name, description, example, url) VALUES (644, 39, 'RENAME TABLE', 'Syntax\n------\n\nRENAME TABLE[S] [IF EXISTS] tbl_name \n  [WAIT n | NOWAIT]\n  TO new_tbl_name\n    [, tbl_name2 TO new_tbl_name2] ...\n\nDescription\n-----------\n\nThis statement renames one or more tables or views, but not the privileges associated with them. For InnoDB tables, it also triggers a reload of InnoDB statistics.\n\nIF EXISTS\n\nIf this clause is used, you don''t get an error if the table to be renamed doesn''t exist.\n\nThe rename operation is done atomically, which means that no other session can access any of the tables while the rename is running. For example, if you have an existing table old_table, you can create another table new_table that has the same structure but is empty, and then replace the existing table with the empty one as follows (assuming that backup_table does not already exist):\n\n``sql\nCREATE TABLE new_table (...);\nRENAME TABLE old_table TO backup_table, new_table TO old_table;\n`\n\nMoving Tables to Another Database\n\ntbl_name can optionally be specified as db_name.tbl_name. See Identifier Qualifiers. This allows to use RENAME to move a table from a database to another (as long as they are on the same filesystem):\n\n`sql\nRENAME TABLE db1.t TO db2.t;\n`\n\nLimitations of Moving Tables to Another Database\n\nNote that moving a table to another database is not possible if it has triggers.\n\nTrying to do so produces the following error:\n\n`sql\nERROR 1435 (HY000): Trigger in wrong schema\n`\n\nViews cannot be moved to another database.\n\nTrying to do so produces the following error:\n\n`sql\nERROR 1450 (HY000): Changing schema from ''old_db'' to ''new_db'' is not allowed.\n`\n\nRenaming Multiple Tables at Once\n\nMultiple tables can be renamed in a single statement. The presence or absence of the optional S (RENAME TABLE or RENAME TABLES) has no impact, whether a single or multiple tables are being renamed.\n\nIf a RENAME TABLE renames more than one table and one renaming fails, all renames executed by the same statement are rolled back.\n\nRenames are always executed in the specified order. Knowing this, it is also possible to swap two tables'' names:\n\n`sql\nRENAME TABLE t1 TO tmp_table,\n    t2 TO t1,\n    tmp_table TO t2;\n`\n\nWAIT/NOWAIT\n\nSet the lock wait timeout. See WAIT and NOWAIT.\n\nPrivileges\n\nExecuting the RENAME TABLE statement requires the DROP, CREATE and INSERT privileges for the table or the database.\n\nAtomic RENAME TABLE\n\nRENAME TABLE is atomic for most storage engines, including InnoDB, MyRocks, MyISAM and Aria (MDEV-23842).\n\nThis means that if there is a crash (server down or power outage) during RENAME TABLE, all tables revert to their original names and any changes to trigger files are reverted.\\\n\\\nSee Atomic DDL for more information.\n\nRENAME TABLE is not atomic.\n\nThere is a small chance that, during a server crash happening in the middle of RENAME TABLE`, some tables could have been renamed (in the worst case partly) while others would not be renamed.\n\nURL: https://mariadb.com/docs/server/reference/sql-statements/data-definition/rename-table', '', 'https://mariadb.com/docs/server/reference/sql-statements/data-definition/rename-table');
INSERT INTO help_topic (help_topic_id, help_category_id, name, description, example, url) VALUES (645, 39, 'Renaming Databases', 'Description\n-----------\n\nThere is no RENAME DATABASE statement. To rename a database, use one of the following procedures.\n\nUsing RENAME TABLE\n\nUse this procedure only if your tables have neither triggers nor views or events.\n\nTo move your tables from a database named db1 to one named db2, run these statements:\n\n``sql\nCREATE DATABASE db2;\nDo this for every table in database db1\nRENAME TABLE db1.t TO db2.t;\nWhen no table is left in database db1, optionally drop it\nDROP DATABASE db1;\n`\n\nPrivileges are neither dropped for db1, nor are they "copied" to db2. Use SHOW PRIVILEGES to see which privileges are related to db1, then apply those privileges to db2.\n\nRenaming Databases Manually\n\nTo overcome the limitations of the previous procedure, you can do the following.\n\nIn the following steps, the source database is named PROD , and the destination database TEST.\n\n* Full Backup and Restore: If restoring to a different server, use mariadb-backup to create a full backup, then restore it to the intended server. (This step is optional. It is not necessary if your renamed database is to reside on the same computer.)\n\nDump Logical Objects.\n\nRENAME TABLE does not work for triggers, events, and routines. You need to dump these logical objects separately.\n\n`bash\nmariadb-dump PROD --no-data --routines --triggers --events \\\n> PROD_routines_triggers_events.sql\n`\n\nGenerate RENAME TABLE Commands.\n\nRun the following query to generate a script with the necessary RENAME TABLE statements. This is much faster than a full logical dump.\n\n`sql\nmysql -ss -e"SELECT CONCAT(''RENAME TABLE PROD.'', TABLE_NAME, '' TO TEST.'', \\\nTABLE_NAME, '';'') FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_SCHEMA = ''PROD''" \\\n> PROD_rename_table.sql\n`\n\nList all Existing Objects.\n\n`sql\nSELECT TABLE_SCHEMA, TABLE_NAME FROM INFORMATION_SCHEMA.TABLES \n       WHERE TABLE_SCHEMA = ''PROD'';\nSELECT EVENT_SCHEMA, EVENT_NAME FROM INFORMATION_SCHEMA.EVENTS \n       WHERE EVENT_SCHEMA = ''PROD'';\nSELECT ROUTINE_SCHEMA, ROUTINE_NAME FROM INFORMATION_SCHEMA.ROUTINES \n       WHERE ROUTINE_SCHEMA = ''PROD'';\nSELECT TRIGGER_SCHEMA, TRIGGER_NAME FROM INFORMATION_SCHEMA.TRIGGERS \n WHERE TRIGGER_SCHEMA = ''PROD'';\n`\n\nCreate the new Database.\n\n`sql\nCREATE DATABASE TEST;\n`\n\nRun the rename_table Script.\n\n`bash\nmysql TEST < PROD_rename_table.sql\n`\n\nRestore Logical Objects.\n\nAfter the rename script completes, restore the triggers, routines, and events into the new database.\n\n`bash\nmysql TEST < PROD_routines_triggers_events.sql\n`\n\nVerify all Objects are Restored.\n\nVerify that all objects have been correctly moved to the new TEST database.\n\n`sql\nSELECT TABLE_SCHEMA, TABLE_NAME FROM INFORMATION_SCHEMA.TABLES \n       WHERE TABLE_SCHEMA = ''TEST'';\nSELECT EVENT_SCHEMA, EVENT_NAME FROM INFORMATION_SCHEMA.EVENTS \n       WHERE EVENT_SCHEMA = ''TEST'';\nSELECT ROUTINE_SCHEMA, ROUTINE_NAME FROM INFORMATION_SCHEMA.ROUTINES \n       WHERE ROUTINE_SCHEMA = ''TEST'';\nSELECT TRIGGER_SCHEMA, TRIGGER_NAME FROM INFORMATION_SCHEMA.TRIGGERS \n       WHERE TRIGGER_SCHEMA = ''TEST'';\n`\n\nCleanup.\n\nOnce you have confirmed everything looks good, you can drop the old PROD database.\n\nPrivileges are neither dropped for PROD, nor are they "copied" to TEST. Use SHOW PRIVILEGES to see which privileges are related to PROD, then apply those privileges to TEST`.\n\nURL: https://mariadb.com/docs/server/reference/sql-statements/data-definition/renaming-databases', '', 'https://mariadb.com/docs/server/reference/sql-statements/data-definition/renaming-databases');
INSERT INTO help_topic (help_topic_id, help_category_id, name, description, example, url) VALUES (646, 27, 'DELETE', 'Syntax\n------\n\nDELETE [LOW_PRIORITY] [QUICK] [IGNORE] \n  FROM tbl_name [PARTITION (partition_list)]\n  [FOR PORTION OF PERIOD FROM expr1 TO expr2]\n  [AS alias]                    -- from MariaDB 11.6\n  [WHERE where_condition]\n  [ORDER BY ...]\n  [LIMIT row_count]\n  [RETURNING select_expr \n    [, select_expr ...]]\n\nDescription\n-----------\n\n| Option        | Description                                                                                                                                                                                                                                                                                                                                                                                                                                                                                             |\n| ------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |\n| LOW_PRIORITY | Wait until all SELECT statement are done before starting the statement. Used with storage engines that uses table locking (MyISAM, Aria etc). See HIGH_PRIORITY and LOW_PRIORITY clauses for details.                                                                                                                                                                                                                                                          |\n| QUICK         | Signal the storage engine that it should expect that a lot of rows are deleted. The storage engine can do things to speed up the DELETE like ignoring merging of data blocks until all rows are deleted from the block (instead of when a block is half full). This speeds up things at the expanse of lost space in data blocks. At least MyISAM and Aria support this feature. |\n| IGNORE        | Don''t stop the query even if a not-critical error occurs (like data overflow). See How IGNORE works for a full description.                                                                                                                                                                                                                                                                                                                                      |\n\nFor the single-table syntax, the DELETE statement deletes rows from tbl_name and returns a count of the number of deleted rows. This count can be obtained by calling the ROW_COUNT() function. TheWHERE clause, if given, specifies the conditions that identify which rows to delete. With no WHERE clause, all rows are deleted. If the ORDER BY clause is specified, the rows are deleted in the order that is specified. The LIMIT clause places a limit on the number of rows that can be deleted.\n\nFor the multiple-table syntax, DELETE deletes from each tbl_name the rows that satisfy the conditions. In this case, ORDER BY and LIMIT cannot be used. A DELETE can also reference tables which are located in different databases; see Identifier Qualifiers for the syntax.\n\nwhere_condition is an expression that evaluates to true for each row to be deleted. It is specified as described in SELECT.\n\nYou cannot delete from a table and select from the same table in a subquery.\n\nYou need the DELETE privilege on a table to delete rows from it. You need only the SELECT privilege for any columns that are only read, such as those named in the WHERE clause. See GRANT.\n\nAs stated, a DELETE statement with no WHERE clause deletes all rows. A faster way to do this, when you do not need to know the number of deleted rows, is to use TRUNCATE TABLE. However, within a transaction or if you have a lock on the table,TRUNCATE TABLE cannot be used whereas DELETE can. See TRUNCATE TABLE, and LOCK.\n\nAS\n\nSingle-table DELETE statements support aliases. For example:\n\n``sql\nCREATE TABLE t1 (c1 INT);\nINSERT INTO t1 VALUES (1), (2);\n\nDELETE FROM t1 AS a1 WHERE a1.c1 = 2;\n`\n\nSingle-table DELETE statements do not support aliases.\n\nPARTITION\n\nSee Partition Pruning and Selection for details.\n\nFOR PORTION OF\n\nSee Application Time Periods - Deletion by Portion.\n\nRETURNING\n\nIt is possible to return a result set of the deleted rows for a single table to the client by using the syntax DELETE ... RETURNING select_expr [, select_expr2 ...]]\n\nAny of SQL expression that can be calculated from a single row fields is allowed. Subqueries are allowed. The AS keyword is allowed, so it is possible to use aliases.\n\nThe use of aggregate functions is not allowed. RETURNING cannot be used in multi-table DELETE statements.\n\nSame Source and Target Table\n\nIt is possible to delete from a table with the same source and target. For example:\n\n`sql\nDELETE FROM t1 WHERE c1 IN (SELECT b.c1 FROM t1 b WHERE b.c2=0);\n`\n\nDELETE HISTORY\n\nYou can use DELETE HISTORY` to delete historical information from System-versioned tables.\n\nExamples\n--------\n\nDELETE FROM page_hit ORDER BY TIMESTAMP LIMIT 1000000;\n\nURL: https://mariadb.com/docs/server/reference/sql-statements/data-manipulation/changing-deleting-data/delete', '', 'https://mariadb.com/docs/server/reference/sql-statements/data-manipulation/changing-deleting-data/delete');
INSERT INTO help_topic (help_topic_id, help_category_id, name, description, example, url) VALUES (647, 27, 'HIGH\\_PRIORITY and LOW\\_PRIORITY', 'Description\n-----------\n\nThe InnoDB storage engine uses row-level locking to ensure data integrity. However some storage engines (such as MEMORY, MyISAM, Aria and MERGE) lock the whole table to prevent conflicts. These storage engines use two separate queues to remember pending statements; one is for SELECTs and the other one is for write statements (INSERT, DELETE, UPDATE). By default, the latter has a higher priority.\n\nTo give write operations a lower priority, the low_priority_updates server system variable can be set to ON. The option is available on both the global and session levels, and it can be set at startup or via the SET statement.\n\nWhen too many table locks have been set by write statements, some pending SELECTs are executed. The maximum number of write locks that can be acquired before this happens is determined by the max_write_lock_count server system variable, which is dynamic.\n\nIf write statements have a higher priority (default), the priority of individual write statements (INSERT, REPLACE, UPDATE, DELETE) can be changed via the LOW_PRIORITY attribute, and the priority of a SELECT statement can be raised via the HIGH_PRIORITY attribute. Also, LOCK TABLES supports a LOW_PRIORITY attribute for WRITE locks.\n\nIf read statements have a higher priority, the priority of an INSERT can be changed via the HIGH_PRIORITY attribute. However, the priority of other write statements cannot be raised individually.\n\nThe use of LOW_PRIORITY or HIGH_PRIORITY for an INSERT prevents Concurrent Inserts from being used.\n\nURL: https://mariadb.com/docs/server/reference/sql-statements/data-manipulation/changing-deleting-data/high_priority-and-low_priority', '', 'https://mariadb.com/docs/server/reference/sql-statements/data-manipulation/changing-deleting-data/high_priority-and-low_priority');
INSERT INTO help_topic (help_topic_id, help_category_id, name, description, example, url) VALUES (648, 27, 'REPLACE', 'Syntax\n------\n\nREPLACE [LOW_PRIORITY | DELAYED]\n [INTO] tbl_name [PARTITION (partition_list)] [(col,...)]\n {VALUES | VALUE} ({expr | DEFAULT},...),(...),...\n[RETURNING select_expr \n      [, select_expr ...]]\n\nDescription\n-----------\n\nREPLACE works exactly like INSERT, except that if an old row in the table has the same value as a new row for a PRIMARY KEY or aUNIQUE index, the old row is deleted before the new row is inserted. If the table has more than one UNIQUE keys, it is possible that the new row conflicts with more than one row. In this case, all conflicting rows will be deleted.\n\nThe table name can be specified in the form db_name.tbl_name or, if a default database is selected, in the form tbl_name (see Identifier Qualifiers). This allows to use REPLACE ... SELECT to copy rows between different databases.\n\nBasically it works like this:\n\n``sql\nBEGIN;\nSELECT 1 FROM t1 WHERE KEY=# FOR UPDATE;\nIF FOUND-ROW\n  DELETE FROM t1 WHERE KEY=# ;\nENDIF\nINSERT INTO t1 VALUES (...);\nEND;\n`\n\nThe above can be replaced with:\n\n`sql\nREPLACE INTO t1 VALUES (...)\n`\n\nREPLACE is a MariaDB/MySQL extension to the SQL standard. It either inserts, or deletes and inserts. For other MariaDB/MySQL extensions to standard SQL --- that also handle duplicate values --- see IGNORE and INSERT ON DUPLICATE KEY UPDATE.\n\nNote that unless the table has a PRIMARY KEY orUNIQUE index, using a REPLACE statement makes no sense. It becomes equivalent to INSERT, because there is no index to be used to determine whether a new row duplicates another.\n\nValues for all columns are taken from the values. See Partition Pruning and Selection for details. Specified in theREPLACE statement. Any missing columns are set to their default values, just as happens for INSERT. You cannot refer to values from the current row and use them in the new row. If you use an assignment such as ''SET col = col + 1'', the reference to the column name on the right hand side is treated asDEFAULT(col), so the assignment is equivalent to''SET col = DEFAULT(col) + 1''.\n\nTo use REPLACE, you must have both theINSERT and DELETE privileges for the table.\n\nThere are some issues you should be aware of, before using REPLACE:\n\n If there is an AUTO_INCREMENT field, a new value will be generated.\n If there are foreign keys, ON DELETE action will be activated by REPLACE.\n* Triggers on DELETE and INSERT will be activated by REPLACE.\n\nTo avoid some of these behaviors, you can use INSERT ... ON DUPLICATE KEY UPDATE.\n\nThis statement activates INSERT and DELETE triggers. See Trigger Overview for details.\n\nPARTITION\n\nSee Partition Pruning and Selection for details.\n\nREPLACE RETURNING\n\nREPLACE ... RETURNING returns a resultset of the replaced rows. This returns the listed columns for all the rows that are replaced, or alternatively, the specified SELECT expression. Any SQL expressions which can be calculated can be used in the select expression for the RETURNING` clause, including virtual columns and aliases, expressions which use various operators such as bitwise, logical and arithmetic operators, string functions, date-time functions, numeric functions, control flow functions, secondary functions and stored functions. Along with this, statements which have subqueries and prepared statements can also be used.\n\nExamples\n--------\n\nREPLACE INTO t2 VALUES (1,''Leopard''),(2,''Dog'') RETURNING id2, id2+id2 \nas Total ,id2|id2, id2&&id2;\n+-----+-------+---------+----------+\n| id2 | Total | id2|id2 | id2&&id2 |\n+-----+-------+---------+----------+\n|   1 |     2 |       1 |        1 |\n|   2 |     4 |       2 |        1 |\n+-----+-------+---------+----------+\n\nURL: https://mariadb.com/docs/server/reference/sql-statements/data-manipulation/changing-deleting-data/replace', '', 'https://mariadb.com/docs/server/reference/sql-statements/data-manipulation/changing-deleting-data/replace');
INSERT INTO help_topic (help_topic_id, help_category_id, name, description, example, url) VALUES (649, 27, 'REPLACE...RETURNING', 'Syntax\n------\n\nREPLACE [LOW_PRIORITY | DELAYED]\n [INTO] tbl_name [PARTITION (partition_list)] [(col,...)]\n {VALUES | VALUE} ({expr | DEFAULT},...),(...),...\n[RETURNING select_expr \n      [, select_expr ...]]\n\nDescription\n-----------\n\nREPLACE ... RETURNING returns a result set of the replaced rows. The statement returns the listed columns for all the rows that are replaced, or alternatively, the specified SELECT expression. Any SQL expressions which can be calculated can be used in the select expression for the RETURNING clause, including virtual columns and aliases, expressions which use various operators such as bitwise, logical and arithmetic operators, string functions, date-time functions, numeric functions, control flow functions, secondary functions and stored functions. Along with this, statements which have subqueries and prepared statements can also be used.\n\nExamples\n--------\n\nREPLACE INTO t2 VALUES (1,''Leopard''),(2,''Dog'') RETURNING id2, id2+id2 \nAS Total ,id2|id2, id2&&id2;\n+-----+-------+---------+----------+\n| id2 | Total | id2|id2 | id2&&id2 |\n+-----+-------+---------+----------+\n|   1 |     2 |       1 |        1 |\n|   2 |     4 |       2 |        1 |\n+-----+-------+---------+----------+\n\nURL: https://mariadb.com/docs/server/reference/sql-statements/data-manipulation/changing-deleting-data/replacereturning', '', 'https://mariadb.com/docs/server/reference/sql-statements/data-manipulation/changing-deleting-data/replacereturning');
INSERT INTO help_topic (help_topic_id, help_category_id, name, description, example, url) VALUES (650, 27, 'UPDATE', 'Syntax\n------\n\nUPDATE [LOW_PRIORITY] [IGNORE] table_reference \n  [PARTITION (partition_list)]\n  [FOR PORTION OF period FROM expr1 TO expr2]\n  SET col1={expr1|DEFAULT} [,col2={expr2|DEFAULT}] ...\n  [WHERE where_condition]\n  [ORDER BY ...]\n  [LIMIT row_count]\n  RETURNING OLD_VALUE(val) AS old [, val as new]\n\nDescription\n-----------\n\nFor the single-table syntax, the UPDATE statement updates columns of existing rows in the named table with new values. TheSET clause indicates which columns to modify and the values they should be given. Each value can be given as an expression, or the keywordDEFAULT to set a column explicitly to its default value. TheWHERE clause, if given, specifies the conditions that identify which rows to update. With no WHERE clause, all rows are updated. If the ORDER BY clause is specified, the rows are\\\nupdated in the order that is specified. The LIMIT clause places a limit on the number of rows that can be updated.\n\nBoth clauses can be used with multiple-table updates.\n\nBoth clauses can be used with multiple-table updates. For the multiple-table syntax, UPDATE updates rows in each table named in table_references that satisfy the conditions. In this case, ORDER BY and LIMIT could not be used.\n\nAn UPDATE can also reference tables which are located in different databases; see Identifier Qualifiers for the syntax.\n\nwhere_condition is an expression that evaluates to true for each row to be updated.\n\ntable_references and where_condition are as specified as described in SELECT.\n\nFor single-table updates, assignments are evaluated in left-to-right order, while for multi-table updates, there is no guarantee of a particular order. If the SIMULTANEOUS_ASSIGNMENT sql_mode is set, UPDATE statements evaluate all assignments simultaneously.\n\nYou need the UPDATE privilege only for columns referenced in an UPDATE that are actually updated. You need only the SELECT privilege for any columns that are read but not modified. See GRANT.\n\nThe UPDATE statement supports the following modifiers:\n\n If you use the LOW_PRIORITY keyword, execution of the UPDATE is delayed until no other clients are reading from the table. This affects only storage engines that use only table-level locking (MyISAM, MEMORY, MERGE). See HIGH_PRIORITY and LOW_PRIORITY clauses for details.\n If you use the IGNORE keyword, the update statement does not abort even if errors occur during the update. Rows for which duplicate-key conflicts occur are not updated. Rows for which columns are updated to values that would cause data conversion errors are updated to the closest valid values instead.\n\nPARTITION\n\nSee Partition Pruning and Selection for details.\n\nFOR PORTION OF\n\nSee Application Time Periods - Updating by Portion.\n\nUPDATE Statements With the Same Source and Target\n\nUPDATE statements may have the same source and target. For example, given the following table:\n\n``sql\nDROP TABLE t1;\nCREATE TABLE t1 (c1 INT, c2 INT);\nINSERT INTO t1 VALUES (10,10), (20,20);\n\nUPDATE t1 SET c1=c1+1 WHERE c2=(SELECT MAX(c2) FROM t1);\n\nSELECT * FROM t1;\n+------+------+\n| c1   | c2   |\n+------+------+\n|   10 |   10 |\n|   21 |   20 |\n+------+------+\n``\n\nExamples\n--------\n\nUPDATE table_name SET column1 = value1, column2 = value2 WHERE id=100;\n\nURL: https://mariadb.com/docs/server/reference/sql-statements/data-manipulation/changing-deleting-data/update', '', 'https://mariadb.com/docs/server/reference/sql-statements/data-manipulation/changing-deleting-data/update');
INSERT INTO help_topic (help_topic_id, help_category_id, name, description, example, url) VALUES (651, 27, 'Concurrent Inserts', 'Description\n-----------\n\nThe MyISAM storage engine supports concurrent inserts. This feature allows SELECT statements to be executed during INSERT operations, reducing contention.\n\nWhether concurrent inserts can be used or not depends on the value of the concurrent_insert server system variable:\n\n NEVER (0) disables concurrent inserts.\n AUTO (1) allows concurrent inserts only when the target table has no free blocks (no data in the middle of the table has been deleted after the last OPTIMIZE TABLE). This is the default.\n* ALWAYS (2) always enables concurrent inserts, in which case new rows are added at the end of a table if the table is being used by another thread.\n\nIf the binary log is used, CREATE TABLE ... SELECT and INSERT ... SELECT statements cannot use concurrent inserts. These statements acquire a read lock on the table, so concurrent inserts will need to wait. This way, the log can be safely used to restore data.\n\nConcurrent inserts are not used by slaves with the row-based replication (see binary log formats).\n\nIf an INSERT statement contains the HIGH_PRIORITY clause, concurrent inserts cannot be used. INSERT ... DELAYED is usually unneeded if concurrent inserts are enabled.\n\nLOAD DATA INFILE uses concurrent inserts if the CONCURRENT keyword is specified and concurrent_insert is not NEVER. This makes the statement slower (even if no other sessions access the table) but reduces contention.\n\nLOCK TABLES allows non-conflicting concurrent inserts if a READ LOCAL lock is used. Concurrent inserts are not allowed if the LOCAL keyword is omitted.\n\nNotes\n\nThe decision to enable concurrent insert for a table is done when the table is opened. If you change the value of concurrent_insert, it will only affect newly opened tables. If you want it to work for also for tables in use or cached, you should do FLUSH TABLES after setting the variable.\n\nURL: https://mariadb.com/docs/server/reference/sql-statements/data-manipulation/inserting-loading-data/concurrent-inserts', '', 'https://mariadb.com/docs/server/reference/sql-statements/data-manipulation/inserting-loading-data/concurrent-inserts');
INSERT INTO help_topic (help_topic_id, help_category_id, name, description, example, url) VALUES (652, 27, 'IGNORE', 'Description\n-----------\n\nThe IGNORE option tells the server to ignore some common errors.\n\nIGNORE can be used with the following statements:\n\n DELETE\n INSERT (see also INSERT IGNORE)\n LOAD DATA INFILE\n UPDATE\n ALTER TABLE\n CREATE TABLE ... SELECT\n INSERT ... SELECT\n\nThe logic used:\n\n Variables out of ranges are replaced with the maximum/minimum value.\n SQL_MODEs STRICT_TRANS_TABLES, STRICT_ALL_TABLES, NO_ZERO_IN_DATE, NO_ZERO_DATE are ignored.\n Inserting NULL in a NOT NULL field will insert 0 ( in a numerical field), 0000-00-00 ( in a date field) or an empty string ( in a character field).\n* Rows that cause a duplicate key error or break a foreign key constraint are not inserted, updated, or deleted.\n\nThe following errors are ignored:\n\n| Error number | Symbolic error name                              | Description                                                           |\n| ------------ | ------------------------------------------------ | --------------------------------------------------------------------- |\n| 1022         | ER_DUP_KEY                                     | Can''t write; duplicate key in table ''%s''                              |\n| 1048         | ER_BAD_NULL_ERROR                             | Column ''%s'' cannot be null                                            |\n| 1062         | ER_DUP_ENTRY                                   | Duplicate entry ''%s'' for key %d                                       |\n| 1242         | ER_SUBQUERY_NO_1_ROW                         | Subquery returns more than 1 row                                      |\n| 1264         | ER_WARN_DATA_OUT_OF_RANGE                   | Out of range value for column ''%s'' at row %ld                         |\n| 1265         | WARN_DATA_TRUNCATED                            | Data truncated for column ''%s'' at row %ld                             |\n| 1292         | ER_TRUNCATED_WRONG_VALUE                      | Truncated incorrect %s value: ''%s''                                    |\n| 1366         | ER_TRUNCATED_WRONG_VALUE_FOR_FIELD          | Incorrect integer value                                               |\n| 1369         | ER_VIEW_CHECK_FAILED                          | CHECK OPTION failed ''%s.%s''                                           |\n| 1451         | ER_ROW_IS_REFERENCED_2                       | Cannot delete or update a parent row                                  |\n| 1452         | ER_NO_REFERENCED_ROW_2                       | Cannot add or update a child row: a foreign key constraint fails (%s) |\n| 1526         | ER_NO_PARTITION_FOR_GIVEN_VALUE             | Table has no partition for value %s                                   |\n| 1586         | ER_DUP_ENTRY_WITH_KEY_NAME                  | Duplicate entry ''%s'' for key ''%s''                                     |\n| 1591         | ER_NO_PARTITION_FOR_GIVEN_VALUE_SILENT     | Table has no partition for some existing values                       |\n| 1748         | ER_ROW_DOES_NOT_MATCH_GIVEN_PARTITION_SET | Found a row not matching the given partition set                      |\n\nIgnored errors normally generate a warning.\n\nA property of the IGNORE clause consists in causing transactional engines and non-transactional engines (like InnoDB and Aria) to behave the same way. For example, normally a multi-row insert which tries to violate a UNIQUE contraint is completely rolled back on InnoDB, but might be partially executed on Aria. With the IGNORE clause, the statement will be partially executed in both engines.\n\nDuplicate key errors also generate warnings. The OLD_MODE server variable can be used to prevent this.\n\nURL: https://mariadb.com/docs/server/reference/sql-statements/data-manipulation/inserting-loading-data/ignore', '', 'https://mariadb.com/docs/server/reference/sql-statements/data-manipulation/inserting-loading-data/ignore');
INSERT INTO help_topic (help_topic_id, help_category_id, name, description, example, url) VALUES (653, 27, 'INSERT - Default & Duplicate Values', 'Description\n-----------\n\nDefault Values\n\nIf the SQL_MODE contains STRICT_TRANS_TABLES and you are inserting into a transactional table (like InnoDB), or if the SQL_MODE contains STRICT_ALL_TABLES, all NOT NULL columns which do not have a DEFAULT value (and are not AUTO_INCREMENT) must be explicitly referenced in INSERT statements. If not, an error like this is produced:\n\n``\nERROR 1364 (HY000): Field ''col'' doesn''t have a default value\n`\n\nIn all other cases, if a NOT NULL column without a DEFAULT value is not referenced, an empty value will be inserted (for example, 0 for INTEGER columns and '''' for CHAR columns). See NULL Values in MariaDB:Inserting for examples.\n\nIf a NOT NULL column having a DEFAULT value is not referenced, NULL will be inserted.\n\nIf a NULL column having a DEFAULT value is not referenced, its default value will be inserted. It is also possible to explicitly assign the default value using the DEFAULT keyword or the DEFAULT() function.\n\nIf the DEFAULT keyword is used but the column does not have a DEFAULT value, an error like this is produced:\n\n`\nERROR 1364 (HY000): Field ''col'' doesn''t have a default value\n`\n\nDuplicate Values\n\nBy default, if you try to insert a duplicate row and there is a UNIQUE index, INSERT stops and an error like this is produced:\n\n`\nERROR 1062 (23000): Duplicate entry ''dup_value'' for key ''col''\n``\n\nTo handle duplicates you can use the IGNORE clause, INSERT ON DUPLICATE KEY UPDATE or the REPLACE statement. Note that the IGNORE and DELAYED options are ignored when you use ON DUPLICATE KEY UPDATE.\n\nURL: https://mariadb.com/docs/server/reference/sql-statements/data-manipulation/inserting-loading-data/insert-default-duplicate-values', '', 'https://mariadb.com/docs/server/reference/sql-statements/data-manipulation/inserting-loading-data/insert-default-duplicate-values');
INSERT INTO help_topic (help_topic_id, help_category_id, name, description, example, url) VALUES (654, 27, 'INSERT DELAYED', 'Description\n-----------\n\nThe DELAYED option for the INSERT statement is a MariaDB/MySQL extension to standard SQL that is very useful if you have clients that cannot or need not wait for the INSERT to complete. This is a common situation when you use MariaDB for logging and you also periodically run SELECT and UPDATE statements that take a long time to complete.\n\nWhen a client uses INSERT DELAYED, it gets an okay from the server at once, and the row is queued to be inserted when the table is not in use by any other thread.\n\nAnother major benefit of using INSERT DELAYED is that inserts from many clients are bundled together and written in one block. This is much faster than performing many separate inserts.\n\nNote that INSERT DELAYED is slower than a normalINSERT if the table is not otherwise in use. There is also the additional overhead for the server to handle a separate thread for each table for which there are delayed rows. This means that you should useINSERT DELAYED only when you are really sure that you need it.\n\nThe queued rows are held only in memory until they are inserted into the table. This means that if you terminate mariadbd forcibly (for example, with kill -9) or if mariadbd dies unexpectedly, any queued rows that have not been written to disk are lost.\n\nThe number of concurrent INSERT DELAYED threads is limited by the max_delayed_threads server system variables. If it is set to 0, INSERT DELAYED is disabled. The session value can be equal to the global value, or 0 to disable this statement for the current session. If this limit has been reached, the DELAYED clause will be silently ignore for subsequent statements (no error will be produced).\n\nLimitations\n\nThere are some limitations on the use of DELAYED:\n\n INSERT DELAYED works only with MyISAM, MEMORY, ARCHIVE,\\\n  and BLACKHOLE tables. If you execute INSERT DELAYED with another storage engine, you will get an error like this: ERROR 1616 (HY000): DELAYED option not supported for table ''tab_name''\n For MyISAM tables, if there are no free blocks in the middle of the data file, concurrent SELECT and INSERT statements are supported. Under these circumstances, you very seldom need to use INSERT DELAYED with MyISAM.\n INSERT DELAYED should be used only forINSERT statements that specify value lists. The server\\\n  ignores DELAYED for INSERT ... SELECT or INSERT ... ON DUPLICATE KEY UPDATE statements.\n Because the INSERT DELAYED statement returns immediately, before the rows are inserted, you cannot useLAST_INSERT_ID() to get theAUTO_INCREMENT value that the statement might generate.\n DELAYED rows are not visible to SELECT statements until they actually have been inserted.\n After INSERT DELAYED, ROW_COUNT() returns the number of the rows you tried to insert, not the number of the successful writes.\n DELAYED is ignored on slave replication servers, so thatINSERT DELAYED is treated as a normal INSERT on slaves. This is becauseDELAYED could cause the slave to have different data than\\\n  the master. INSERT DELAYED statements are not safe for replication.\n Pending INSERT DELAYED statements are lost if a table is write locked and ALTER TABLE is used to modify the table structure.\n INSERT DELAYED is not supported for views. If you try, you will get an error like this: ERROR 1347 (HY000): ''view_name'' is not BASE TABLE\n INSERT DELAYED is not supported for partitioned tables.\n INSERT DELAYED is not supported within stored programs.\n INSERT DELAYED does not work with triggers.\n INSERT DELAYED does not work if there is a check constraint in place.\n INSERT DELAYED does not work if skip-new mode is active.\n\nURL: https://mariadb.com/docs/server/reference/sql-statements/data-manipulation/inserting-loading-data/insert-delayed', '', 'https://mariadb.com/docs/server/reference/sql-statements/data-manipulation/inserting-loading-data/insert-delayed');
INSERT INTO help_topic (help_topic_id, help_category_id, name, description, example, url) VALUES (655, 27, 'INSERT IGNORE', 'Description\n-----------\n\nIgnoring Errors\n\nNormally INSERT stops and rolls back when it encounters an error.\n\nBy using the IGNORE keyword all errors are converted to warnings, which will not stop inserts of additional rows.\n\nInvalid values are changed to the closest valid value and inserted, with a warning produced.\n\nThe IGNORE and DELAYED options are ignored when you use ON DUPLICATE KEY UPDATE.\n\nWarnings are issued for duplicate key errors when using IGNORE. You can get the old behavior if you set OLD_MODE to NO_DUP_KEY_WARNINGS_WITH_IGNORE.\n\nNo warnings are issued for duplicate key errors when using IGNORE.\n\nSee IGNORE for a full description of effects.\n\nExamples\n--------\n\nCREATE TABLE t1 (x INT UNIQUE);\n\nINSERT INTO t1 VALUES(1),(2);\n\nINSERT INTO t1 VALUES(2),(3);\nERROR 1062 (23000): Duplicate entry ''2'' for key ''x''\nSELECT  FROM t1;\n+------+\n| x    |\n+------+\n|    1 |\n|    2 |\n+------+\n\nINSERT IGNORE INTO t1 VALUES(2),(3);\nQuery OK, 1 row affected, 1 warning (0.04 sec)\n\nSHOW WARNINGS;\n+---------+------+---------------------------------+\n| Level   | Code | Message                         |\n+---------+------+---------------------------------+\n| Warning | 1062 | Duplicate entry ''2'' for key ''x'' |\n+---------+------+---------------------------------+\n\nSELECT  FROM t1;\n+------+\n| x    |\n+------+\n|    1 |\n|    2 |\n|    3 |\n+------+\n\nURL: https://mariadb.com/docs/server/reference/sql-statements/data-manipulation/inserting-loading-data/insert-ignore', '', 'https://mariadb.com/docs/server/reference/sql-statements/data-manipulation/inserting-loading-data/insert-ignore');
INSERT INTO help_topic (help_topic_id, help_category_id, name, description, example, url) VALUES (656, 27, 'INSERT ON DUPLICATE KEY UPDATE', 'Syntax\n------\n\nINSERT [LOW_PRIORITY | DELAYED | HIGH_PRIORITY] [IGNORE]\n  [INTO] tbl_name [PARTITION (partition_list)] [(col,...)]\n  {VALUES | VALUE} ({expr | DEFAULT},...),(...),...\n  [ ON DUPLICATE KEY UPDATE\n    col=expr\n      [, col=expr] ... ]\n\nDescription\n-----------\n\nINSERT ... ON DUPLICATE KEY UPDATE (often called "upsert") is a MariaDB/MySQL extension to the INSERT statement that, if it finds a duplicate unique or primary key, will instead perform an UPDATE.\n\nThe row/s affected value is reported as 1 if a row is inserted, and 2 if a row is updated, unless the API''s CLIENT_FOUND_ROWS flag is set.\n\nIf more than one unique index is matched, only the first is updated. It is not recommended to use this statement on tables with more than one unique index.\n\nIf the table has an AUTO_INCREMENT primary key and the statement inserts or updates a row, the LAST_INSERT_ID() function returns its AUTO_INCREMENT value.\n\nThe VALUES() function can only be used in a ON DUPLICATE KEY UPDATE clause and has no meaning in any other context. It returns the column values from the INSERT portion of the statement. This function is particularly useful for multi-rows inserts.\n\nThe IGNORE and DELAYED options are ignored when you use ON DUPLICATE KEY UPDATE.\n\nSee Partition Pruning and Selection for details on the PARTITION clause.\n\nThis statement activates INSERT and UPDATE triggers. See Trigger Overview for details.\n\nSee also a similar statement, REPLACE.\n\nExamples\n--------\n\nCREATE TABLE ins_duplicate (id INT PRIMARY KEY, animal VARCHAR(30));\nINSERT INTO ins_duplicate VALUES (1,''Aardvark''), (2,''Cheetah''), (3,''Zebra'');\n\nURL: https://mariadb.com/docs/server/reference/sql-statements/data-manipulation/inserting-loading-data/insert-on-duplicate-key-update', '', 'https://mariadb.com/docs/server/reference/sql-statements/data-manipulation/inserting-loading-data/insert-on-duplicate-key-update');
INSERT INTO help_topic (help_topic_id, help_category_id, name, description, example, url) VALUES (657, 27, 'INSERT SELECT', 'Syntax\n------\n\nINSERT [LOW_PRIORITY | HIGH_PRIORITY] [IGNORE]\n    [INTO] tbl_name [(col_name,...)]\n    SELECT ...\n    [ ON DUPLICATE KEY UPDATE col_name=expr, ... ]\n\nDescription\n-----------\n\nWith INSERT ... SELECT, you can quickly insert many rows into a table from one or more other tables. For example:\n\n``sql\nINSERT INTO tbl_temp2 (fld_id)\n  SELECT tbl_temp1.fld_order_id\n  FROM tbl_temp1 WHERE tbl_temp1.fld_order_id > 100;\n`\n\ntbl_name can also be specified in the form db_name.tbl_name (see Identifier Qualifiers). This allows to copy rows between different databases.\n\nIf the new table has a primary key or UNIQUE indexes, you can use IGNORE to handle duplicate key errors during the query. The newer values will not be inserted if an identical value already exists.\n\nREPLACE can be used instead of INSERT to prevent duplicates on UNIQUE indexes by deleting old values. In that case, ON DUPLICATE KEY UPDATE cannot be used.\n\nINSERT ... SELECT` works for tables which already exist. To create a table for a given resultset, you can use CREATE TABLE ... SELECT.\n\nURL: https://mariadb.com/docs/server/reference/sql-statements/data-manipulation/inserting-loading-data/insert-select', '', 'https://mariadb.com/docs/server/reference/sql-statements/data-manipulation/inserting-loading-data/insert-select');
INSERT INTO help_topic (help_topic_id, help_category_id, name, description, example, url) VALUES (658, 27, 'INSERT', 'Description\n-----------\n\nSyntax\n\n``sql\nINSERT [LOW_PRIORITY | DELAYED | HIGH_PRIORITY] [IGNORE]\n [INTO] tbl_name [PARTITION (partition_list)] [(col,...)]\n {VALUES | VALUE} ({expr | DEFAULT},...),(...),...\n [ ON DUPLICATE KEY UPDATE\n   col=expr\n     [, col=expr] ... ] [RETURNING select_expr \n      [, select_expr ...]]\n`\n\nOr:\n\n`sql\nINSERT [LOW_PRIORITY | DELAYED | HIGH_PRIORITY] [IGNORE]\n    [INTO] tbl_name [PARTITION (partition_list)]\n    SET col={expr | DEFAULT}, ...\n    [ ON DUPLICATE KEY UPDATE\n      col=expr\n        [, col=expr] ... ] [RETURNING select_expr \n      [, select_expr ...]]\n`\n\nOr:\n\n`sql\nINSERT [LOW_PRIORITY | HIGH_PRIORITY] [IGNORE]\n    [INTO] tbl_name [PARTITION (partition_list)] [(col,...)]\n    SELECT ...\n    [ ON DUPLICATE KEY UPDATE\n      col=expr\n        [, col=expr] ... ] [RETURNING select_expr \n      [, select_expr ...]]\n`\n\nThe INSERT statement is used to insert new rows into an existing table. The INSERT ... VALUES\\\nand INSERT ... SET forms of the statement insert rows based on explicitly specified values. The INSERT ... SELECT form inserts rows selected from another table or tables. INSERT ... SELECT is discussed further in the INSERT ... SELECT article.\n\nThe table name can be specified in the form db_name.tbl_name or, if a default database is selected, in the form tbl_name (see Identifier Qualifiers). This allows to use INSERT ... SELECT to copy rows between different databases.\n\nThe PARTITION clause can be used in both the INSERT and the SELECT part. See Partition Pruning and Selection for details.\n\nThe RETURNING clause can be used.\n\nThe RETURNING clause is not available.\n\nThe columns list is optional. It specifies which values are explicitly inserted, and in which order. If this clause is not specified, all values must be explicitly specified, in the same order they are listed in the table definition.\n\nThe list of value follow the VALUES or VALUE keyword (which are interchangeable, regardless how much values you want to insert), and is wrapped by parenthesis. The values must be listed in the same order as the columns list. It is possible to specify more than one list to insert more than one rows with a single statement. If many rows are inserted, this is a speed optimization.\n\nFor one-row statements, the SET clause may be more simple, because you don''t need to remember the columns order. All values are specified in the form col = expr.\n\nValues can also be specified in the form of a SQL expression or subquery. However, the subquery cannot access the same table that is named in the INTO clause.\n\nIf you use the LOW_PRIORITY keyword, execution of the INSERT is delayed until no other clients are reading from the table. If you use the HIGH_PRIORITY keyword, the statement has the same priority as SELECTs. This affects only storage engines that use only table-level locking (MyISAM, MEMORY, MERGE). However, if one of these keywords is specified, concurrent inserts cannot be used. See HIGH_PRIORITY and LOW_PRIORITY clauses for details.\n\nINSERT DELAYED\n\nFor more details on the DELAYED` option, see INSERT DELAYED.\n\nHIGH PRIORITY and LOW PRIORITY\n\nSee HIGH_PRIORITY and LOW_PRIORITY.\n\nDefaults and Duplicate Values\n\nSee INSERT - Default & Duplicate Values for details..\n\nINSERT IGNORE\n\nSee INSERT IGNORE.\n\nINSERT ON DUPLICATE KEY UPDATE\n\nSee INSERT ON DUPLICATE KEY UPDATE.\n\nExamples\n--------\n\nINSERT INTO person (first_name, last_name) VALUES (''John'', ''Doe'');\n\nURL: https://mariadb.com/docs/server/reference/sql-statements/data-manipulation/inserting-loading-data/insert', '', 'https://mariadb.com/docs/server/reference/sql-statements/data-manipulation/inserting-loading-data/insert');
INSERT INTO help_topic (help_topic_id, help_category_id, name, description, example, url) VALUES (659, 27, 'INSERT...RETURNING', 'Syntax\n------\n\nINSERT [LOW_PRIORITY | DELAYED | HIGH_PRIORITY] [IGNORE]\n [INTO] tbl_name [PARTITION (partition_list)] [(col,...)]\n {VALUES | VALUE} ({expr | DEFAULT},...),(...),...\n [ ON DUPLICATE KEY UPDATE\n   col=expr\n     [, col=expr] ... ] [RETURNING select_expr \n      [, select_expr ...]]\n\nDescription\n-----------\n\nINSERT ... RETURNING returns a resultset of the inserted rows.\n\nIt returns the listed columns for all the rows that are inserted, or alternatively, the specified SELECT expression. Any SQL expressions which can be calculated can be used in the select expression for the RETURNING clause, including virtual columns and aliases, expressions which use various operators such as bitwise, logical and arithmetic operators, string functions, date-time functions, numeric functions, control flow functions, secondary functions and stored functions. Along with this, statements which have subqueries and prepared statements can also be used.\n\nExamples\n--------\n\nCREATE OR REPLACE TABLE t2 (id INT, animal VARCHAR(20), t TIMESTAMP);\n\nINSERT INTO t2 (id) VALUES (2),(3) RETURNING id,t;\n+------+---------------------+\n| id   | t                   |\n+------+---------------------+\n|    2 | 2021-04-28 00:59:32 |\n|    3 | 2021-04-28 00:59:32 |\n+------+---------------------+\n\nURL: https://mariadb.com/docs/server/reference/sql-statements/data-manipulation/inserting-loading-data/insertreturning', '', 'https://mariadb.com/docs/server/reference/sql-statements/data-manipulation/inserting-loading-data/insertreturning');
INSERT INTO help_topic (help_topic_id, help_category_id, name, description, example, url) VALUES (660, 27, 'LOAD DATA INFILE', 'Syntax\n------\n\nLOAD DATA [LOW_PRIORITY | CONCURRENT] [LOCAL] INFILE ''file_name''\n    [REPLACE | IGNORE]\n    INTO TABLE tbl_name\n    [CHARACTER SET charset_name]\n    [{FIELDS | COLUMNS}\n        [TERMINATED BY ''string'']\n        [[OPTIONALLY] ENCLOSED BY ''CHAR'']\n        [ESCAPED BY ''CHAR'']\n    ]\n    [LINES\n        [STARTING BY ''string'']\n        [TERMINATED BY ''string'']\n    ]\n    [IGNORE number {LINES|ROWS}]\n    [(col_name_or_user_var,...)]\n    [SET col_name = expr,...]\n\nDescription\n-----------\n\nLOAD DATA INFILE is unsafe for statement-based replication.\n\nReads rows from a text file into the designated table on the database at a very high speed. The file name must be given as a literal string.\n\nFiles are written to disk using the SELECT INTO OUTFILE statement. You can then read the files back into a table using the LOAD DATA INFILE statement. The FIELDS and LINES clauses are the same in both statements and by default fields are expected to be terminated with tabs () and lines with newlines (). These clauses are optional, but if both are specified then the FIELDS clause must precede LINES.\n\nExecuting this statement activates INSERT triggers.\n\nOne must have the FILE privilege to be able to execute LOAD DATA INFILE. This is to ensure normal users cannot read system files. LOAD DATA LOCAL INFILE does not have this requirement.\n\nIf the secure_file_priv system variable is set (by default it is not), the loaded file must be present in the specified directory.\n\nNote that MariaDB''s systemd unit file restricts access to /home, /root, and /run/user by default. See Configuring access to home directories.\n\nLOAD DATA LOCAL INFILE\n\nWhen you execute the LOAD DATA INFILE statement, MariaDB Server attempts to read the input file from its own file system. By contrast, when you execute the LOAD DATA LOCAL INFILE statement, the client attempts to read the input file from its file system, and it sends the contents of the input file to the MariaDB Server. This allows you to load files from the client''s local file system into the database.\n\nIf you don''t want to permit this operation (perhaps for security reasons), you can disable the LOAD DATA LOCAL INFILE statement on either the server or the client.\n\n The LOAD DATA LOCAL INFILE statement can be disabled on the server by setting the local_infile system variable to 0.\n The LOAD DATA LOCAL INFILE statement can be disabled on the client. If you are using MariaDB Connector/C, this can be done by unsetting the CLIENT_LOCAL_FILES capability flag with the mysql_real_connect function or by unsetting the MYSQL_OPT_LOCAL_INFILE option with mysql_optionsv function. If you are using a different client or client library, then see the documentation for your specific client or client library to determine how it handles the LOAD DATA LOCAL INFILE statement.\n The LOAD DATA LOCAL INFILE strict modes like STRICT_TRANS_TABLES are disabled with keyword "local". (MDEV-11235)\n\nIf the LOAD DATA LOCAL INFILE statement is disabled by either the server or the client and if the user attempts to execute it, then the server will cause the statement to fail with the following error message:\n\n``\nThe used command is not allowed with this MariaDB version\n`\n\nNote that it is not entirely accurate to say that the MariaDB version does not support the command. It would be more accurate to say that the MariaDB configuration does not support the command. See MDEV-20500 for more information.\n\nFrom MariaDB 10.5.2, the error message is more accurate:\n\n`\nThe used command is not allowed because the MariaDB server or client \n  has disabled the local infile capability\n`\n\nREPLACE and IGNORE\n\nIf you load data from a file into a table that already contains data and has a primary key, you may encounter issues where the statement attempts to insert a row with a primary key that already exists. When this happens, the statement fails with Error 1064, protecting the data already on the table. If you want MariaDB to overwrite duplicates, use the REPLACE keyword.\n\nThe REPLACE keyword works like the REPLACE statement. Here, the statement attempts to load the data from the file. If the row does not exist, it adds it to the table. If the row contains an existing primary key, it replaces the table data. That is, in the event of a conflict, it assumes the file contains the desired row.\n\nThis operation can cause a degradation in load speed by a factor of 20 or more if the part that has already been loaded is larger than the capacity of the InnoDB Buffer Pool. This happens because it causes a lot of turnaround in the buffer pool.\n\nUse the IGNORE keyword when you want to skip any rows that contain a conflicting primary key. Here, the statement attempts to load the data from the file. If the row does not exist, it adds it to the table. If the row contains an existing primary key, it ignores the addition request and moves on to the next. That is, in the event of a conflict, it assumes the table contains the desired row.\n\nIGNORE number {LINES|ROWS}\n\nThe IGNORE number LINES syntax can be used to ignore a number of rows from the beginning of the file. Most often this is needed when the file starts with one row that includes the column headings.\n\nCharacter Sets\n\nWhen the statement opens the file, it attempts to read the contents using the default character-set, as defined by the character_set_database system variable.\n\nIn the cases where the file was written using a character-set other than the default, you can specify the character-set to use with the CHARACTER SET clause in the statement. It ignores character-sets specified by the SET NAMES statement and by the character_set_client system variable. Setting the CHARACTER SET clause to a value of binary indicates "no conversion."\n\nThe statement interprets all fields in the file as having the same character-set, regardless of the column data type. To properly interpret file contents, you must ensure that it was written with the correct character-set. If you write a data file with mariadb-dump -T or with the SELECT INTO OUTFILE statement with the mariadb client, be sure to use the --default-character-set option, so that the output is written with the desired character-set.\n\nWhen using mixed character sets, use the CHARACTER SET clause in both SELECT INTO OUTFILE and LOAD DATA INFILE to ensure that MariaDB correctly interprets the escape sequences.\n\nThe character_set_filesystem system variable controls the interpretation of the filename.\\\nIt is currently not possible to load data files that use the ucs2 character set.\n\nPreprocessing Inputs\n\n_col_name_or_user_var_ can be a column name, or a user variable. In the case of a variable, the SET statement can be used to preprocess the value before loading into the table.\n\nPriority and Concurrency\n\nIn storage engines that perform table-level locking (MyISAM, MEMORY and MERGE), using the LOW_PRIORITY keyword, MariaDB delays insertions until no other clients are reading from the table. Alternatively, when using the MyISAM storage engine, you can use the CONCURRENT keyword to perform concurrent insertion.\n\nThe LOW_PRIORITY and CONCURRENT keywords are mutually exclusive. They cannot be used in the same statement.\n\nProgress Reporting\n\nThe LOAD DATA INFILE statement supports progress reporting. You may find this useful when dealing with long-running operations. Using another client you can issue a SHOW PROCESSLIST query to check the progress of the data load.\n\nUsing mariadb-import\n\nMariaDB ships with a separate utility for loading data from files: mariadb-import. It operates by sending LOAD DATA INFILE statements to the server.\n\nMariaDB ships with a separate utility for loading data from files: mysqlimport . It operates by sending LOAD DATA INFILE statements to the server.\n\nUsing mariadb-import you can compress the file using the --compress option, to get better performance over slow networks, providing both the client and server support the compressed protocol. Use the --local option to load from the local file system.\n\nIndexing\n\nIn cases where the storage engine supports ALTER TABLE... DISABLE KEYS statements (MyISAM and Aria), the LOAD DATA INFILE` statement automatically disables indexes during the execution.\n\nExamples\n--------\n\nCREATE TABLE t1 (a INT, b INT, c INT, d INT, PRIMARY KEY (a));\nLOAD DATA LOCAL INFILE \n ''/tmp/loaddata7.dat'' INTO TABLE t1 FIELDS TERMINATED BY '','' (a,b) SET c=a+b;\nSELECT  FROM t1;\n+------+------+------+\n| a    | b    | c    |\n+------+------+------+\n|    2 |    2 |    4 |\n|    3 |    3 |    6 |\n|    4 |    4 |    8 |\n|    5 |    5 |   10 |\n|    6 |    8 |   14 |\n+------+------+------+\n\nURL: https://mariadb.com/docs/server/reference/sql-statements/data-manipulation/inserting-loading-data/load-data-into-tables-or-index/load-data-infile', '', 'https://mariadb.com/docs/server/reference/sql-statements/data-manipulation/inserting-loading-data/load-data-into-tables-or-index/load-data-infile');
INSERT INTO help_topic (help_topic_id, help_category_id, name, description, example, url) VALUES (661, 27, 'LOAD INDEX', 'Syntax\n------\n\nLOAD INDEX INTO CACHE\n  tbl_index_list [, tbl_index_list] ...\n\ntbl_index_list:\n  tbl_name\n    [[INDEX|KEY] (index_name[, index_name] ...)]\n    [IGNORE LEAVES]\n\nDescription\n-----------\n\nThe LOAD INDEX INTO CACHE statement preloads a table index into the key cache to which it has been assigned by an explicit CACHE INDEX statement, or into the default key cache otherwise.LOAD INDEX INTO CACHE is used only for MyISAM or Aria tables.\n\nThe IGNORE LEAVES modifier causes only blocks for the nonleaf nodes of the index to be preloaded.\n\nURL: https://mariadb.com/docs/server/reference/sql-statements/data-manipulation/inserting-loading-data/load-data-into-tables-or-index/load-index', '', 'https://mariadb.com/docs/server/reference/sql-statements/data-manipulation/inserting-loading-data/load-data-into-tables-or-index/load-index');

INSERT INTO help_topic (help_topic_id, help_category_id, name, description, example, url) VALUES (663, 27, 'Non-Recursive Common Table Expressions Overview', 'Description\n-----------\n\nCommon Table Expressions (CTEs) are a standard SQL feature, and are essentially temporary named result sets. There are two kinds of CTEs: Non-Recursive, which this article covers; and Recursive.\n\nNon-Recursive CTEs\n\nThe WITH keyword signifies a CTE. It is given a name, followed by a body (the main query).\n\nCTEs are similar to derived tables:\n\n``sql\nWITH engineers AS \n   ( SELECT  FROM employees\n     WHERE dept = ''Engineering'' )\n\nSELECT  FROM engineers\nWHERE ...\n`\n\n`sql\nSELECT  FROM\n   ( SELECT  FROM employees\n     WHERE dept = ''Engineering'' ) AS engineers\nWHERE\n...\n`\n\nA non-recursive CTE is basically a query-local VIEW. There are several advantages and caveats to them. The syntax is more readable than a nested FROM (SELECT ...).\\\nA CTE can refer to another and it can be referenced from multiple places.\n\nA CTE referencing Another CTE\n\nUsing this format makes for a more readable SQL than a nested FROM(SELECT ...) clause:\n\n`sql\nWITH engineers AS (\nSELECT  FROM employees\nWHERE dept IN(''Development'',''Support'') ),\neu_engineers AS ( SELECT  FROM engineers WHERE country IN(''NL'',...) )\nSELECT\n...\nFROM eu_engineers;\n`\n\nMultiple Uses of a CTE\n\nThis can be an ''anti-self join'', for example:\n\n`sql\nWITH engineers AS (\nSELECT  FROM employees\nWHERE dept IN(''Development'',''Support'') )\n\nSELECT  FROM engineers E1\nWHERE NOT EXISTS\n   (SELECT 1 FROM engineers E2\n    WHERE E2.country=E1.country\n    AND E2.name <> E1.name );\n`\n\nOr, for year-over-year comparisons, for example:\n\n`sql\nWITH sales_product_year AS (\nSELECT product, YEAR(ship_date) AS year,\nSUM(price) AS total_amt\nFROM item_sales\nGROUP BY product, year )\n\nSELECT \nFROM sales_product_year CUR,\nsales_product_year PREV,\nWHERE CUR.product=PREV.product \nAND  CUR.year=PREV.year + 1 \nAND CUR.total_amt > PREV.total_amt\n`\n\nAnother use is to compare individuals against their group. Below is an example of how this might be executed:\n\n`sql\nWITH sales_product_year AS (\nSELECT product,\nYEAR(ship_date) AS year,\nSUM(price) AS total_amt\nFROM item_sales\nGROUP BY product, year\n)\n\nSELECT  \nFROM sales_product_year S1\nWHERE\ntotal_amt > \n    (SELECT 0.1 * SUM(total_amt)\n     FROM sales_product_year S2\n     WHERE S2.year = S1.year)\n``\n\nURL: https://mariadb.com/docs/server/reference/sql-statements/data-manipulation/selecting-data/common-table-expressions/non-recursive-common-table-expressions-overview', '', 'https://mariadb.com/docs/server/reference/sql-statements/data-manipulation/selecting-data/common-table-expressions/non-recursive-common-table-expressions-overview');
INSERT INTO help_topic (help_topic_id, help_category_id, name, description, example, url) VALUES (664, 27, 'Recursive Common Table Expressions Overview', 'Description\n-----------\n\nCommon Table Expressions (CTEs) are a standard SQL feature, and are essentially temporary named result sets. They are defined using the WITH clause and can be referenced like tables within the main query. CTEs first appeared in the SQL standard in 1999, and the first implementations began appearing in 2007.\n\nMariaDB supports two types of CTEs:\n\n Non-recursive;\n Recursive, which this article covers.\n\nRecursive CTE\n\nA recursive CTE will repeatedly execute subsets of the data until it obtains the complete result set. This makes it particularly useful for handling hierarchical or tree-structured data, such as organizational charts, category trees, or parent-child relationships. max_recursive_iterations avoids infinite loops. CTEs permit a query to reference itself. SQL is generally poor at recursive structures.\n\n!trees_and_graphs\n\nRecursive CTE Syntax\n\nWITH RECURSIVE signifies a recursive CTE. It is given a name, followed by a body (the main query). The body consists of two parts:\n\n An anchor member (the initial query)\n A recursive member (which references the CTE itself).\n\n!rcte_syntax\n\nComputation\n\nGiven the following structure:\n\n!rcte_computation\n\n1. First execute the anchor part of the query:\n\n!rcte1\n\n2. Next, execute the recursive part of the query:\n\n!rcte_computation_2\n\n![](../../../../../.gitbook/assets/rcte_computation_2b.png)\n\n![](../../../../../.gitbook/assets/rcte_computation_3.png)\n\n![](../../../../../.gitbook/assets/rcte_computation_3b.png)\n\n![](../../../../../.gitbook/assets/rcte_computation_4.png)\n\nSummary\n\n``sql\nWITH RECURSIVE R AS (\n  SELECT anchor_data\n  UNION [all]\n  SELECT recursive_part\n  FROM R, ...\n)\nSELECT ...\n`\n\n1. Compute anchor_data.\n2. Compute recursive_part to get the new data.\n3. If (new data is non-empty) go to 2.\n\nRecursive CTE Examples\n\nTransitive closure - determining bus destinations\n\nSample data:\n\n!tc_1\n\n`sql\nCREATE TABLE bus_routes (origin VARCHAR(50), dst VARCHAR(50));\nINSERT INTO bus_routes VALUES \n  (''New York'', ''Boston''), \n  (''Boston'', ''New York''), \n  (''New York'', ''Washington''), \n  (''Washington'', ''Boston''), \n  (''Washington'', ''Raleigh'');\n`\n\nNow, we want to return the bus destinations with New York as the origin:\n\n`sql\nWITH RECURSIVE bus_dst as ( \n    SELECT origin as dst FROM bus_routes WHERE origin=''New York'' \n  UNION\n    SELECT bus_routes.dst FROM bus_routes JOIN bus_dst ON bus_dst.dst= bus_routes.origin \n) \nSELECT  FROM bus_dst;\n+------------+\n| dst        |\n+------------+\n| New York   |\n| Boston     |\n| Washington |\n| Raleigh    |\n+------------+\n`\n\nThe above example is computed as follows:\n\nFirst, the anchor data is calculated:\n\n Starting from New York.\n Boston and Washington are added.\n\nNext, the recursive part:\n\n Starting from Boston and then Washington.\n Raleigh is added.\n UNION excludes nodes that are already present.\n\nComputing paths - determining bus routes\n\nThis time, we are trying to get bus routes such as “New York -> Washington -> Raleigh”.\n\nUsing the same sample data as the previous example:\n\n`sql\nWITH RECURSIVE paths (cur_path, cur_dest) AS (\n    SELECT origin, origin FROM bus_routes WHERE origin=''New York'' \n  UNION\n    SELECT CONCAT(paths.cur_path, '','', bus_routes.dst), bus_routes.dst \n     FROM paths\n     JOIN bus_routes \n       ON paths.cur_dest = bus_routes.origin AND \n         NOT FIND_IN_SET(bus_routes.dst, paths.cur_path)\n) \nSELECT * FROM paths;\n+-----------------------------+------------+\n| cur_path                    | cur_dest   |\n+-----------------------------+------------+\n| New York                    | New York   |\n| New York,Boston             | Boston     |\n| New York,Washington         | Washington |\n| New York,Washington,Boston  | Boston     |\n| New York,Washington,Raleigh | Raleigh    |\n+-----------------------------+------------+\n``\n\nType Resolution and Data Truncation\n\nIn previous versions of MariaDB, the data type of a Recursive CTE column was entirely determined by the Anchor (non-recursive) part. If the Recursive part carried out calculations that generated a greater value, the data was silently truncated, leading to incorrect results.\n\nStarting with the versions listed below, MariaDB prevents silent data loss. The server now validates that the data generated by the recursive part matches the column types given by the anchor part. If a mismatch that leads to truncation is detected, the query will now fail with an error. See MDEV-12325 for more information.\n\n<table><thead><tr><th width="296">MariaDB Series </th><th>Fixed Version</th></tr></thead><tbody><tr><td>10.3</td><td>10.3.36 </td></tr><tr><td>10.4</td><td>10.4.26</td></tr><tr><td>10.5 </td><td>10.5.17</td></tr><tr><td>10.6</td><td>10.6.9</td></tr><tr><td>10.7</td><td>10.7.5</td></tr></tbody></table>\n\nExamples\n--------\n\nCREATE TABLE t1\n(\n  id INT,     -- employee ID\n  mid INT,    -- manager ID, or NULL if top level employee\n  name TEXT   -- employee name\n);\nINSERT INTO t1 VALUES (0,NULL, ''Name'');\nINSERT INTO t1 VALUES (1,0,    ''Name1'');\nINSERT INTO t1 VALUES (2,0,    ''Name2'');\nINSERT INTO t1 VALUES (11,1,   ''Name11'');\nINSERT INTO t1 VALUES (12,1,   ''Name12'');\n\nURL: https://mariadb.com/docs/server/reference/sql-statements/data-manipulation/selecting-data/common-table-expressions/recursive-common-table-expressions-overview', '', 'https://mariadb.com/docs/server/reference/sql-statements/data-manipulation/selecting-data/common-table-expressions/recursive-common-table-expressions-overview');
INSERT INTO help_topic (help_topic_id, help_category_id, name, description, example, url) VALUES (665, 27, 'WITH', 'Syntax\n------\n\nWITH [RECURSIVE] table_reference [(columns_list)] AS  (\n  SELECT ...\n)\n[CYCLE cycle_column_list RESTRICT]\nSELECT ...\n\nDescription\n-----------\n\nThe WITH keyword signifies a Common Table Expression (CTE). It allows you to refer to a subquery expression many times in a query, as if having a temporary table that only exists for the duration of a query.\n\nThere are two kinds of CTEs:\n\n Non-Recursive.\n Recursive (signified by the RECURSIVE keyword).\n\nYou can use table_reference as any normal table in the external SELECT part. You can also use WITH in subqueries, as well as with EXPLAIN and SELECT.\n\nPoorly-formed recursive CTEs can in theory cause infinite loops. The max_recursive_iterations system variable limits the number of recursions.\n\nCYCLE ... RESTRICT\n\nThe CYCLE clause enables CTE cycle detection, avoiding excessive or infinite loops,\\\nMariaDB supports a relaxed, non-standard grammar.\\\nThe SQL Standard permits a CYCLE clause, as follows:\n\n``sql\nWITH RECURSIVE ... (\n  ...\n)\nCYCLE <cycle column list>\nSET <cycle mark column> TO <cycle mark value> DEFAULT <non-cycle mark value>\nUSING <path column>\n`\n\nwhere all clauses are mandatory.\\\nMariaDB does not support this, but permits a non-standard relaxed grammar, as follows:\n\n`sql\nWITH RECURSIVE ... (\n  ...\n)\nCYCLE <cycle column list> RESTRICT\n`\n\nWith the use of CYCLE ... RESTRICT it makes no difference whether the CTE uses UNION ALL or UNION DISTINCT anymore. UNION ALL means "all rows, but without cycles", which is exactly what the CYCLE clause enables. And UNION DISTINCT means all rows should be different, which, again, is what will happen — as uniqueness is enforced over a subset of columns, complete rows will automatically all be different.\n\nCYCLE ... RESTRICT` is not available.\n\nExamples\n--------\n\nWITH t AS (SELECT a FROM t1 WHERE b >= ''c'') \n  SELECT * FROM t2, t WHERE t2.c = t.a;\n\nURL: https://mariadb.com/docs/server/reference/sql-statements/data-manipulation/selecting-data/common-table-expressions/with', '', 'https://mariadb.com/docs/server/reference/sql-statements/data-manipulation/selecting-data/common-table-expressions/with');
INSERT INTO help_topic (help_topic_id, help_category_id, name, description, example, url) VALUES (666, 27, 'DUAL', 'Description\n-----------\n\nYou can use DUAL instead of a table name in situations where no tables are referenced, such as the following SELECT statement:\n\n``sql\nSELECT 1 + 1 FROM DUAL;\n+-------+\n| 1 + 1 |\n+-------+\n|     2 |\n+-------+\n`\n\nDUAL is purely for the convenience of people who require that all SELECT statements should haveFROM and possibly other clauses. MariaDB ignores the clauses. MariaDB does not require FROM DUAL if no tables are referenced.\n\nFROM DUAL could be used when you only SELECT computed values, but require a WHERE clause, perhaps to test that a script correctly handles empty resultsets:\n\n`sql\nSELECT 1 FROM DUAL WHERE FALSE;\nEmpty set (0.00 sec)\n``\n\nURL: https://mariadb.com/docs/server/reference/sql-statements/data-manipulation/selecting-data/dual', '', 'https://mariadb.com/docs/server/reference/sql-statements/data-manipulation/selecting-data/dual');
INSERT INTO help_topic (help_topic_id, help_category_id, name, description, example, url) VALUES (667, 27, 'FOR UPDATE', 'Description\n-----------\n\nInnoDB supports row-level locking. Selected rows can be locked using LOCK IN SHARE MODE or FOR UPDATE. In both cases, a lock is acquired on the rows read by the query, and it will be released when the current transaction is committed.\n\nThe FOR UPDATE clause of SELECT applies only when autocommit is set to 0 or the SELECT is enclosed in a transaction. A lock is acquired on the rows, and other transactions are prevented from writing the rows, acquire locks, and from reading them (unless their isolation level is READ UNCOMMITTED).\n\nIf autocommit is set to 1, the LOCK IN SHARE MODE and FOR UPDATE clauses have no effect in InnoDB. For non-transactional storage engines like MyISAM and ARIA, a table level lock will be taken even if autocommit is set to 1.\n\nIf the isolation level is set to SERIALIZABLE, all plain SELECT statements are converted to SELECT ... LOCK IN SHARE MODE.\n\nExamples\n--------\n\nSELECT * FROM trans WHERE period=2001 FOR UPDATE;\n\nURL: https://mariadb.com/docs/server/reference/sql-statements/data-manipulation/selecting-data/for-update', '', 'https://mariadb.com/docs/server/reference/sql-statements/data-manipulation/selecting-data/for-update');
INSERT INTO help_topic (help_topic_id, help_category_id, name, description, example, url) VALUES (668, 27, 'GROUP BY', 'Description\n-----------\n\nUse the GROUP BY clause in a SELECT statement to group rows together that have the same value in one or more column, or the same computed value using expressions with any functions and operators except grouping functions. When you use a GROUP BY clause, you will get a single result row for each group of rows that have the same value for the expression given in GROUP BY.\n\nWhen grouping rows, grouping values are compared as if by the = operator. For string values, the = operator ignores trailing whitespace and may normalize characters and ignore case, depending on the collation in use.\n\nYou can use any of the grouping functions in your select expression. Their values will be calculated based on all the rows that have been grouped together for each result row. If you select a non-grouped column or a value computed from a non-grouped column, it is undefined which row the returned value is taken from. This is not permitted if the ONLY_FULL_GROUP_BY SQL_MODE is used.\n\nYou can use multiple expressions in the GROUP BY clause, separated by commas.\\\nRows are grouped together if they match on each of the expressions.\n\nYou can also use a single integer as the grouping expression. If you use an integer _n_,\\\nthe results will be grouped by the _n_th column in the select expression.\n\nThe WHERE clause is applied before the GROUP BY clause. It filters non-aggregated\\\nrows before the rows are grouped together. To filter grouped rows based on aggregate values, use the HAVING clause. The HAVING clause takes any expression and evaluates it as a boolean, just like the WHERE clause. You can use grouping functions in the HAVING clause. As with the select expression, if you reference non-grouped columns in the HAVING clause, the behavior is undefined.\n\nBy default, if a GROUP BY clause is present, the rows in the output will be sorted by the expressions used in the GROUP BY. You can also specify ASC or DESC (ascending, descending) after those expressions, like in ORDER BY. The default is ASC.\n\nIf you want the rows to be sorted by another field, you can add an explicit ORDER BY. If you don''t want the result to be ordered, you can add ORDER BY NULL.\n\nWITH ROLLUP\n\nThe WITH ROLLUP modifier adds extra rows to the result set that represent super-aggregate summaries. For a full description with examples, see SELECT WITH ROLLUP.\n\nGROUP BY Examples\n\nConsider the following table that records how many times each user has played and won a game:\n\n``sql\nCREATE TABLE plays (name VARCHAR(16), plays INT, wins INT);\nINSERT INTO plays VALUES \n  ("John", 20, 5), \n  ("Robert", 22, 8), \n  ("Wanda", 32, 8), \n  ("Susan", 17, 3);\n`\n\nGet a list of win counts along with a count:\n\n`sql\nSELECT wins, COUNT() FROM plays GROUP BY wins;\n+------+----------+\n| wins | COUNT() |\n+------+----------+\n|    3 |        1 |\n|    5 |        1 |\n|    8 |        2 |\n+------+----------+\n3 rows in set (0.00 sec)\n`\n\nThe GROUP BY expression can be a computed value, and can refer back to an identifier specified with AS. Get a list of win averages along with a count:\n\n`sql\nSELECT (wins / plays) AS winavg, COUNT() FROM plays GROUP BY winavg;\n+--------+----------+\n| winavg | COUNT() |\n+--------+----------+\n| 0.1765 |        1 |\n| 0.2500 |        2 |\n| 0.3636 |        1 |\n+--------+----------+\n3 rows in set (0.00 sec)\n`\n\nYou can use any grouping function in the select expression. For each win average as above, get a list of the average play count taken to get that average:\n\n`sql\nSELECT (wins / plays) AS winavg, AVG(plays) FROM plays \n  GROUP BY winavg;\n+--------+------------+\n| winavg | AVG(plays) |\n+--------+------------+\n| 0.1765 |    17.0000 |\n| 0.2500 |    26.0000 |\n| 0.3636 |    22.0000 |\n+--------+------------+\n3 rows in set (0.00 sec)\n`\n\nYou can filter on aggregate information using the HAVING clause. The HAVING clause is applied after GROUP BY and allows you to filter on aggregate data that is not available to the WHERE clause. Restrict the above example to results that involve an average number of plays over 20:\n\n`sql\nSELECT (wins / plays) AS winavg, AVG(plays) FROM plays \n  GROUP BY winavg HAVING AVG(plays) > 20;\n+--------+------------+\n| winavg | AVG(plays) |\n+--------+------------+\n| 0.2500 |    26.0000 |\n| 0.3636 |    22.0000 |\n+--------+------------+\n2 rows in set (0.00 sec)\n``\n\nURL: https://mariadb.com/docs/server/reference/sql-statements/data-manipulation/selecting-data/group-by', '', 'https://mariadb.com/docs/server/reference/sql-statements/data-manipulation/selecting-data/group-by');
INSERT INTO help_topic (help_topic_id, help_category_id, name, description, example, url) VALUES (669, 27, 'Advanced Joins', 'Description\n-----------\n\nThis article is a continuation of the Joining Tables with JOIN Clauses Guide. If you''re getting started with JOIN statements, review that page first.\n\nThe Employee Database\n\nLet us begin by using an example employee database of a fairly small family business, which does not anticipate expanding in the future.\n\nFirst, we create the table that will hold all of the employees and their contact information:\n\n``sql\nCREATE TABLE Employees (\n  ID TINYINT(3) UNSIGNED NOT NULL AUTO_INCREMENT,\n  First_Name VARCHAR(25) NOT NULL,\n  Last_Name VARCHAR(25) NOT NULL,\n  Position VARCHAR(25) NOT NULL,\n  Home_Address VARCHAR(50) NOT NULL,\n  Home_Phone VARCHAR(12) NOT NULL,\n  PRIMARY KEY (ID)\n) ENGINE=MyISAM;\n`\n\nNext, we add a few employees to the table:\n\n`sql\nINSERT INTO Employees (First_Name, Last_Name, Position, Home_Address, Home_Phone)\n  VALUES\n  (''Mustapha'', ''Mond'', ''Chief Executive Officer'', ''692 Promiscuous Plaza'', ''326-555-3492''),\n  (''Henry'', ''Foster'', ''Store Manager'', ''314 Savage Circle'', ''326-555-3847''),\n  (''Bernard'', ''Marx'', ''Cashier'', ''1240 Ambient Avenue'', ''326-555-8456''),\n  (''Lenina'', ''Crowne'', ''Cashier'', ''281 Bumblepuppy Boulevard'', ''328-555-2349''),\n  (''Fanny'', ''Crowne'', ''Restocker'', ''1023 Bokanovsky Lane'', ''326-555-6329''),\n  (''Helmholtz'', ''Watson'', ''Janitor'', ''944 Soma Court'', ''329-555-2478'');\n`\n\nNow, we create a second table, containing the hours which each employee clocked in and out during the week:\n\n`sql\nCREATE TABLE Hours (\n  ID TINYINT(3) UNSIGNED NOT NULL,\n  Clock_In DATETIME NOT NULL,\n  Clock_Out DATETIME NOT NULL\n) ENGINE=MyISAM;\n`\n\nFinally, although it is a lot of information, we add a full week of hours for each of the employees into the second table that we created:\n\n`sql\nINSERT INTO Hours\n  VALUES\n  (''1'', ''2005-08-08 07:00:42'', ''2005-08-08 17:01:36''),\n  (''1'', ''2005-08-09 07:01:34'', ''2005-08-09 17:10:11''),\n  (''1'', ''2005-08-10 06:59:56'', ''2005-08-10 17:09:29''),\n  (''1'', ''2005-08-11 07:00:17'', ''2005-08-11 17:00:47''),\n  (''1'', ''2005-08-12 07:02:29'', ''2005-08-12 16:59:12''),\n  (''2'', ''2005-08-08 07:00:25'', ''2005-08-08 17:03:13''),\n  (''2'', ''2005-08-09 07:00:57'', ''2005-08-09 17:05:09''),\n  (''2'', ''2005-08-10 06:58:43'', ''2005-08-10 16:58:24''),\n  (''2'', ''2005-08-11 07:01:58'', ''2005-08-11 17:00:45''),\n  (''2'', ''2005-08-12 07:02:12'', ''2005-08-12 16:58:57''),\n  (''3'', ''2005-08-08 07:00:12'', ''2005-08-08 17:01:32''),\n  (''3'', ''2005-08-09 07:01:10'', ''2005-08-09 17:00:26''),\n  (''3'', ''2005-08-10 06:59:53'', ''2005-08-10 17:02:53''),\n  (''3'', ''2005-08-11 07:01:15'', ''2005-08-11 17:04:23''),\n  (''3'', ''2005-08-12 07:00:51'', ''2005-08-12 16:57:52''),\n  (''4'', ''2005-08-08 06:54:37'', ''2005-08-08 17:01:23''),\n  (''4'', ''2005-08-09 06:58:23'', ''2005-08-09 17:00:54''),\n  (''4'', ''2005-08-10 06:59:14'', ''2005-08-10 17:00:12''),\n  (''4'', ''2005-08-11 07:00:49'', ''2005-08-11 17:00:34''),\n  (''4'', ''2005-08-12 07:01:09'', ''2005-08-12 16:58:29''),\n  (''5'', ''2005-08-08 07:00:04'', ''2005-08-08 17:01:43''),\n  (''5'', ''2005-08-09 07:02:12'', ''2005-08-09 17:02:13''),\n  (''5'', ''2005-08-10 06:59:39'', ''2005-08-10 17:03:37''),\n  (''5'', ''2005-08-11 07:01:26'', ''2005-08-11 17:00:03''),\n  (''5'', ''2005-08-12 07:02:15'', ''2005-08-12 16:59:02''),\n  (''6'', ''2005-08-08 07:00:12'', ''2005-08-08 17:01:02''),\n  (''6'', ''2005-08-09 07:03:44'', ''2005-08-09 17:00:00''),\n  (''6'', ''2005-08-10 06:54:19'', ''2005-08-10 17:03:31''),\n  (''6'', ''2005-08-11 07:00:05'', ''2005-08-11 17:02:57''),\n  (''6'', ''2005-08-12 07:02:07'', ''2005-08-12 16:58:23'');\n`\n\nWorking with the Employee Database\n\nNow that we have a cleanly structured database to work with, let us begin this tutorial by stepping up one notch from the last tutorial and filtering our information a little.\n\nFiltering by Name\n\nEarlier in the week, an anonymous employee reported that Helmholtz came into work almost four minutes late; to verify this, we will begin our investigation by filtering out employees whose first names are "Helmholtz":\n\n`sql\nSELECT\n  Employees.First_Name,\n  Employees.Last_Name,\n  Hours.Clock_In,\n  Hours.Clock_Out\nFROM Employees\nINNER JOIN Hours ON Employees.ID = Hours.ID\nWHERE Employees.First_Name = ''Helmholtz'';\n`\n\nThe result looks like this:\n\n`\n+------------+-----------+---------------------+---------------------+\n| First_Name | Last_Name | Clock_In            | Clock_Out           |\n+------------+-----------+---------------------+---------------------+\n| Helmholtz  | Watson    | 2005-08-08 07:00:12 | 2005-08-08 17:01:02 |\n| Helmholtz  | Watson    | 2005-08-09 07:03:44 | 2005-08-09 17:00:00 |\n| Helmholtz  | Watson    | 2005-08-10 06:54:19 | 2005-08-10 17:03:31 |\n| Helmholtz  | Watson    | 2005-08-11 07:00:05 | 2005-08-11 17:02:57 |\n| Helmholtz  | Watson    | 2005-08-12 07:02:07 | 2005-08-12 16:58:23 |\n+------------+-----------+---------------------+---------------------+\n5 rows in set (0.00 sec)\n`\n\nThis is obviously more information than we care to trudge through, considering we only care about when he arrived past 7:00:59 on any given day within this week; thus, we need to add a couple more conditions to our WHERE clause.\n\nFiltering by Name, Date and Time\n\nIn the following example, we will filter out all of the times which Helmholtz clocked in that were before 7:01:00 and during the work week that lasted from the 8th to the 12th of August:\n\n`sql\nSELECT\n  Employees.First_Name,\n  Employees.Last_Name,\n  Hours.Clock_In,\n  Hours.Clock_Out\nFROM Employees\nINNER JOIN Hours ON Employees.ID = Hours.ID\nWHERE Employees.First_Name = ''Helmholtz''\nAND DATE_FORMAT(Hours.Clock_In, ''%Y-%m-%d'') >= ''2005-08-08''\nAND DATE_FORMAT(Hours.Clock_In, ''%Y-%m-%d'') <= ''2005-08-12''\nAND DATE_FORMAT(Hours.Clock_In, ''%H:%i:%S'') > ''07:00:59'';\n`\n\nThe result looks like this:\n\n`\n+------------+-----------+---------------------+---------------------+\n| First_Name | Last_Name | Clock_In            | Clock_Out           |\n+------------+-----------+---------------------+---------------------+\n| Helmholtz  | Watson    | 2005-08-09 07:03:44 | 2005-08-09 17:00:00 |\n| Helmholtz  | Watson    | 2005-08-12 07:02:07 | 2005-08-12 16:58:23 |\n+------------+-----------+---------------------+---------------------+\n2 rows in set (0.00 sec)\n`\n\nBy merely adding a few more conditions, we eliminated all of the irrelevant information; Helmholtz was late to work on the 9th and the 12th of August.\n\nDisplaying Total Work Hours per Day\n\nSuppose you would like to—based on the information stored in both of our tables in the employee database—develop a quick list of the total hours each employee has worked for each day recorded; a simple way to estimate the time each employee worked per day is exemplified below:\n\n`sql\nSELECT\n  Employees.ID,\n  Employees.First_Name,\n  Employees.Last_Name,\n  Hours.Clock_In,\n  Hours.Clock_Out,\nDATE_FORMAT(Hours.Clock_Out, ''%T'')-DATE_FORMAT(Hours.Clock_In, ''%T'') \nAS ''Total_Hours''\nFROM Employees \nINNER JOIN Hours ON Employees.ID = Hours.ID;\n`\n\nThe result (limited to 10 rows) looks like this:\n\n`\n+----+------------+-----------+---------------------+---------------------+-------------+\n| ID | First_Name | Last_Name | Clock_In            | Clock_Out           | Total_Hours |\n+----+------------+-----------+---------------------+---------------------+-------------+\n|  1 | Mustapha   | Mond      | 2005-08-08 07:00:42 | 2005-08-08 17:01:36 |          10 |\n|  1 | Mustapha   | Mond      | 2005-08-09 07:01:34 | 2005-08-09 17:10:11 |          10 |\n|  1 | Mustapha   | Mond      | 2005-08-10 06:59:56 | 2005-08-10 17:09:29 |          11 |\n|  1 | Mustapha   | Mond      | 2005-08-11 07:00:17 | 2005-08-11 17:00:47 |          10 |\n|  1 | Mustapha   | Mond      | 2005-08-12 07:02:29 | 2005-08-12 16:59:12 |           9 |\n|  2 | Henry      | Foster    | 2005-08-08 07:00:25 | 2005-08-08 17:03:13 |          10 |\n|  2 | Henry      | Foster    | 2005-08-09 07:00:57 | 2005-08-09 17:05:09 |          10 |\n|  2 | Henry      | Foster    | 2005-08-10 06:58:43 | 2005-08-10 16:58:24 |          10 |\n|  2 | Henry      | Foster    | 2005-08-11 07:01:58 | 2005-08-11 17:00:45 |          10 |\n|  2 | Henry      | Foster    | 2005-08-12 07:02:12 | 2005-08-12 16:58:57 |           9 |\n+----+------------+-----------+---------------------+---------------------+-------------+\n10 rows in set (0.00 sec)\n``\n\nURL: https://mariadb.com/docs/server/reference/sql-statements/data-manipulation/selecting-data/joins-subqueries/joins/more-advanced-joins', '', 'https://mariadb.com/docs/server/reference/sql-statements/data-manipulation/selecting-data/joins-subqueries/joins/more-advanced-joins');
INSERT INTO help_topic (help_topic_id, help_category_id, name, description, example, url) VALUES (670, 27, 'Subqueries', 'Description\n-----------\n\nsubqueries-and-all.md\n\nCompare a value against all results from a subquery. The ALL operator returns TRUE if the comparison holds for every row returned by the subquery.\n\nsubqueries-and-any.md\n\nCompare a value against any result from a subquery. The ANY (or SOME) operator returns TRUE if the comparison holds for at least one row. IN can be used for =ANY.\n\nsubqueries-and-exists.md\n\nTest for the existence of rows. The EXISTS operator returns TRUE if the subquery returns at least one row, often used for correlated subqueries.\n\nsubqueries-and-joins.md\n\nUnderstand when to use subqueries versus joins. This guide explains performance implications and how to rewrite subqueries as joins for efficiency.\n\nsubqueries-in-a-from-clause-derived-tables.md\n\nUse a subquery as a temporary table. Derived tables allow you to select from the result set of another query within the FROM clause.\n\nsubqueries-row-subqueries.md\n\nRetrieve a single row of multiple values. A row subquery returns a tuple that can be compared against a row constructor in the outer query.\n\nsubqueries-scalar-subqueries.md\n\nReturn a single value. A scalar subquery produces a one-row, one-column result that can be used anywhere a constant or expression is valid.\n\nsubquery-limitations.md\n\nReview restrictions on subquery usage. This page details unsupported operations, such as modifying a table while selecting from it in a subquery.\n\nURL: https://mariadb.com/docs/server/reference/sql-statements/data-manipulation/selecting-data/joins-subqueries/subqueries/README', '', 'https://mariadb.com/docs/server/reference/sql-statements/data-manipulation/selecting-data/joins-subqueries/subqueries/README');
INSERT INTO help_topic (help_topic_id, help_category_id, name, description, example, url) VALUES (671, 27, 'Subqueries and ALL', 'Description\n-----------\n\nSubqueries using the ALL keyword will return true if the comparison returns true for each row returned by the subquery, or the subquery returns no rows.\n\nSyntax\n\n``sql\nscalar_expression comparison_operator ALL <Table subquery>\n`\n\n scalar_expression may be any expression that evaluates to a single value.\n comparison_operator may be any one of: =, >, <, >=, <=, <> or !=\n\nALL returns:\n\n NULL if the comparison operator returns NULL for at least one row returned by the Table subquery or scalar_expression returns NULL.\n FALSE if the comparison operator returns FALSE for at least one row returned by the Table subquery.\n TRUE if the comparison operator returns TRUE for all rows returned by the Table subquery, or if Table subquery returns no rows.\n\nNOT IN is an alias for <> ALL`.\n\nExamples\n--------\n\nCREATE TABLE sq1 (num TINYINT);\n\nCREATE TABLE sq2 (num2 TINYINT);\n\nINSERT INTO sq1 VALUES(100);\n\nINSERT INTO sq2 VALUES(40),(50),(60);\n\nSELECT  FROM sq1 WHERE num > ALL (SELECT * FROM sq2);\n+------+\n| num  |\n+------+\n|  100 |\n+------+\n\nURL: https://mariadb.com/docs/server/reference/sql-statements/data-manipulation/selecting-data/joins-subqueries/subqueries/subqueries-and-all', '', 'https://mariadb.com/docs/server/reference/sql-statements/data-manipulation/selecting-data/joins-subqueries/subqueries/subqueries-and-all');
INSERT INTO help_topic (help_topic_id, help_category_id, name, description, example, url) VALUES (672, 27, 'Subqueries With ANY and SOME', 'Description\n-----------\n\nSyntax\n\nSOME is a synonym for ANY.&#x20;\n\n``sql\nscalar_expression comparison_operator ANY <Table subquery>\nscalar_expression comparison_operator SOME <Table subquery>\n`\n\n scalar_expression may be any expression that evaluates to a single value.\n comparison_operator may be any one of =, >, <, >=, <=, <> or !=.\n\nAbout IN\n\nAlthough IN functions similarly to = ANY, it is documented separately due to unique optimization characteristics. Refer to Subqueries with IN and NOT IN for more details.\n\nANY or SOME returns:\n\n TRUE if the comparison operator returns TRUE for at least one row returned by the table subquery.\n FALSE if the comparison operator returns FALSE for all rows returned by the table subquery, or if the table subquery has no rows.\n* NULL if the comparison operator returns NULL for at least one row returned by the table subquery and doesn''t returns TRUE for any of them, or if scalar_expression returns NULL`.\n\nExamples\n--------\n\nCREATE TABLE sq1 (num1 TINYINT);\nCREATE TABLE sq2 (num2 TINYINT);\nINSERT INTO sq1 VALUES(100);\nINSERT INTO sq2 VALUES(40),(50),(120);\n\nURL: https://mariadb.com/docs/server/reference/sql-statements/data-manipulation/selecting-data/joins-subqueries/subqueries/subqueries-and-any', '', 'https://mariadb.com/docs/server/reference/sql-statements/data-manipulation/selecting-data/joins-subqueries/subqueries/subqueries-and-any');
INSERT INTO help_topic (help_topic_id, help_category_id, name, description, example, url) VALUES (673, 27, 'Subqueries and EXISTS', 'Syntax\n------\n\nSELECT ... WHERE EXISTS <Table subquery>\n\nDescription\n-----------\n\nSubqueries using the EXISTS keyword will return true if the subquery returns any rows. Conversely, subqueries using NOT EXISTS will return true only if the subquery returns no rows from the table.\n\nEXISTS subqueries ignore the columns specified by the SELECT of the subquery, since they''re not relevant. For example,\n\n``sql\nSELECT col1 FROM t1 WHERE EXISTS (SELECT  FROM t2);\n`\n\nand\n\n`sql\nSELECT col1 FROM t1 WHERE EXISTS (SELECT col2 FROM t2);\n``\n\nproduce identical results.\n\nExamples\n--------\n\nCREATE TABLE sq1 (num TINYINT);\n\nCREATE TABLE sq2 (num2 TINYINT);\n\nINSERT INTO sq1 VALUES(100);\n\nINSERT INTO sq2 VALUES(40),(50),(60);\n\nSELECT  FROM sq1 WHERE EXISTS (SELECT  FROM sq2 WHERE num2>50);\n+------+\n| num  |\n+------+\n|  100 |\n+------+\n\nSELECT  FROM sq1 WHERE NOT EXISTS (SELECT * FROM sq2 GROUP BY num2 HAVING MIN(num2)=40);\nEmpty set (0.00 sec)\n\nURL: https://mariadb.com/docs/server/reference/sql-statements/data-manipulation/selecting-data/joins-subqueries/subqueries/subqueries-and-exists', '', 'https://mariadb.com/docs/server/reference/sql-statements/data-manipulation/selecting-data/joins-subqueries/subqueries/subqueries-and-exists');
INSERT INTO help_topic (help_topic_id, help_category_id, name, description, example, url) VALUES (674, 27, 'Subqueries and JOINs', 'Description\n-----------\n\nA subquery can quite often, but not in all cases, be rewritten as a JOIN.\n\nRewriting Subqueries as JOINS\n\nA subquery using IN can be rewritten with the DISTINCT keyword. Consider this query:\n\n``sql\nSELECT  FROM table1 WHERE col1 IN (SELECT col1 FROM table2);\n`\n\nIt can be rewritten like this:\n\n`sql\nSELECT DISTINCT table1. FROM table1, table2 WHERE table1.col1=table2.col1;\n`\n\nNOT IN or NOT EXISTS queries can also be rewritten. For example, these two queries return the same result:\n\n`sql\nSELECT  FROM table1 WHERE col1 NOT IN (SELECT col1 FROM table2);\nSELECT  FROM table1 WHERE NOT EXISTS (SELECT col1 FROM table2 \n         WHERE table1.col1=table2.col1);\n`\n\nThey can both be rewritten like this:\n\n`sql\nSELECT table1. FROM table1 LEFT JOIN table2 ON table1.id=table2.id \n       WHERE table2.id IS NULL;\n`\n\nSubqueries that can be rewritten as a LEFT JOIN are sometimes more efficient.\n\nUsing Subqueries instead of JOINS\n\nThere are some scenarios, though, which call for subqueries rather than joins:\n\n When you want duplicates, but not false duplicates. Suppose Table_1 has three rows — {1,1,2}\\\n  — and Table_2 has two rows\\\n  — {1,2,2}. If you need to list the rows\\\n  in Table_1 which are also in Table_2, only this subquery-based SELECT statement will give the right answer (1,1,2):\n\n`sql\nSELECT Table_1.column_1 \nFROM   Table_1 \nWHERE  Table_1.column_1 IN \n  (SELECT Table_2.column_1 \n    FROM   Table_2);\n`\n\n This SQL statement won''t work:\n\n`sql\nSELECT Table_1.column_1 \nFROM   Table_1,Table_2 \nWHERE  Table_1.column_1 = Table_2.column_1;\n`\n\n because the result will be {1,1,2,2}\\\n  — and the duplication of 2 is an error. This SQL statement won''t work either:\n\n`sql\nSELECT DISTINCT Table_1.column_1 \nFROM   Table_1,Table_2 \nWHERE  Table_1.column_1 = Table_2.column_1;\n`\n\n because the result will be {1,2} — and the removal of the duplicated 1 is an error too.\n When the outermost statement is not a query. The SQL statement:\n\n`sql\nUPDATE Table_1 SET column_1 = (SELECT column_1 FROM Table_2);\n`\n\n can''t be expressed using a join unless some rare SQL3 features are used.\n When the join is over an expression. The SQL statement:\n\n`sql\nSELECT  FROM Table_1 \nWHERE column_1 + 5 =\n  (SELECT MAX(column_1) FROM Table_2);\n`\n\n is hard to express with a join. In fact, the only way we can think of is this SQL statement:\n\n`sql\nSELECT Table_1.\nFROM   Table_1, \n      (SELECT MAX(column_1) AS max_column_1 FROM Table_2) AS Table_2\nWHERE  Table_1.column_1 + 5 = Table_2.max_column_1;\n`\n\n which still involves a parenthesized query, so nothing is gained from the transformation.\n When you want to see the exception. For example, suppose the question is: Which books are longer than Das Kapital? These two queries are effectively almost the same:\n\n`sql\nSELECT DISTINCT Bookcolumn_1.                     \nFROM   Books AS Bookcolumn_1 JOIN Books AS Bookcolumn_2 USING(page_count) \nWHERE  title = ''Das Kapital'';\n\nSELECT DISTINCT Bookcolumn_1. \nFROM   Books AS Bookcolumn_1 \nWHERE  Bookcolumn_1.page_count > \n  (SELECT DISTINCT page_count \n  FROM   Books AS Bookcolumn_2 \n  WHERE  title = ''Das Kapital'');\n`\n\n The difference is between these two SQL statements is, if there are two editions of Das Kapital (with different page counts), then the self-join example will return the books which are longer than the shortest edition of Das Kapital. That might be the wrong answer, since the original question didn''t ask for "... longer than ANY` book named Das Kapital" (it seems to contain a false assumption that there''s only one edition).\n\nURL: https://mariadb.com/docs/server/reference/sql-statements/data-manipulation/selecting-data/joins-subqueries/subqueries/subqueries-and-joins', '', 'https://mariadb.com/docs/server/reference/sql-statements/data-manipulation/selecting-data/joins-subqueries/subqueries/subqueries-and-joins');
INSERT INTO help_topic (help_topic_id, help_category_id, name, description, example, url) VALUES (675, 27, 'Subqueries in a FROM Clause (Derived Tables)', 'Description\n-----------\n\nAlthough subqueries are more commonly placed in a WHERE clause, they can also form part of the FROM clause. Such subqueries are commonly called derived tables.\n\nIf a subquery is used in this way, you must also use an AS clause to name the result of the subquery.\n\nORACLE mode\n\nMariaDB starting with 10.6.0\n\nAnonymous subqueries in a FROM clause (no AS clause) are permitted in ORACLE mode.\n\nAnonymous subqueries in a FROM clause (no AS clause) are not permitted in ORACLE mode.\n\nCorrelation Column List\n\nMariaDB starting with 11.7.0\n\nIt is possible to assign column names in the derived table name syntax element.\n\nIt is not possible to assign column names in the derived table name syntax element.\n\nExamples\n--------\n\nCREATE TABLE student (name CHAR(10), test CHAR(10), score TINYINT); \n\nINSERT INTO student VALUES \n  (''Chun'', ''SQL'', 75), (''Chun'', ''Tuning'', 73), \n  (''Esben'', ''SQL'', 43), (''Esben'', ''Tuning'', 31), \n  (''Kaolin'', ''SQL'', 56), (''Kaolin'', ''Tuning'', 88), \n  (''Tatiana'', ''SQL'', 87), (''Tatiana'', ''Tuning'', 83);\n\nURL: https://mariadb.com/docs/server/reference/sql-statements/data-manipulation/selecting-data/joins-subqueries/subqueries/subqueries-in-a-from-clause-derived-tables', '', 'https://mariadb.com/docs/server/reference/sql-statements/data-manipulation/selecting-data/joins-subqueries/subqueries/subqueries-in-a-from-clause-derived-tables');
INSERT INTO help_topic (help_topic_id, help_category_id, name, description, example, url) VALUES (676, 27, 'Row Subqueries', 'Description\n-----------\n\nA row subquery is a subquery returning a single row, as opposed to a scalar subquery, which returns a single column from a row, or a literal.\n\nExamples\n--------\n\nCREATE TABLE staff (name VARCHAR(10), age TINYINT);\n\nCREATE TABLE customer (name VARCHAR(10), age TINYINT);\n\nINSERT INTO staff VALUES (''Bilhah'',37), (''Valerius'',61), (''Maia'',25);\n\nINSERT INTO customer VALUES (''Thanasis'',48), (''Valerius'',61), (''Brion'',51);\n\nSELECT * FROM staff WHERE (name,age) = (SELECT name,age FROM customer WHERE name=''Valerius'');\n+----------+------+\n| name     | age  |\n+----------+------+\n| Valerius |   61 |\n+----------+------+\n\nURL: https://mariadb.com/docs/server/reference/sql-statements/data-manipulation/selecting-data/joins-subqueries/subqueries/subqueries-row-subqueries', '', 'https://mariadb.com/docs/server/reference/sql-statements/data-manipulation/selecting-data/joins-subqueries/subqueries/subqueries-row-subqueries');
INSERT INTO help_topic (help_topic_id, help_category_id, name, description, example, url) VALUES (677, 27, 'Scalar Subqueries', 'Description\n-----------\n\nA scalar subquery is a subquery that returns a single value. This is the simplest form of a subquery, and can be used in most places a literal or single column value is valid.\n\nThe data type, length and character set and collation are all taken from the result returned by the subquery. The result of a subquery can always be NULL, that is, no result returned. Even if the original value is defined as NOT NULL, this is disregarded.\n\nA subquery cannot be used where only a literal is expected, for example LOAD DATA INFILE expects a literal string containing the file name, and LIMIT requires a literal integer.\n\nExamples\n--------\n\nCREATE TABLE sq1 (num TINYINT);\n\nCREATE TABLE sq2 (num TINYINT);\n\nINSERT INTO sq1 VALUES (1);\n\nINSERT INTO sq2 VALUES (10 (SELECT num FROM sq1));\n\nSELECT  FROM sq2;\n+------+\n| num  |\n+------+\n|   10 |\n+------+\n\nURL: https://mariadb.com/docs/server/reference/sql-statements/data-manipulation/selecting-data/joins-subqueries/subqueries/subqueries-scalar-subqueries', '', 'https://mariadb.com/docs/server/reference/sql-statements/data-manipulation/selecting-data/joins-subqueries/subqueries/subqueries-scalar-subqueries');
INSERT INTO help_topic (help_topic_id, help_category_id, name, description, example, url) VALUES (678, 27, 'Subquery Limitations', 'Description\n-----------\n\nThere are a number of limitations regarding subqueries, which are discussed below.\n\nThe following tables and data will be used in the examples that follow:\n\n``sql\nCREATE TABLE staff(name VARCHAR(10),age TINYINT);\n\nCREATE TABLE customer(name VARCHAR(10),age TINYINT);\n`\n\n`sql\nINSERT INTO staff VALUES \n(''Bilhah'',37), (''Valerius'',61), (''Maia'',25);\n\nINSERT INTO customer VALUES \n(''Thanasis'',48), (''Valerius'',61), (''Brion'',51);\n`\n\nORDER BY and LIMIT\n\nTo use ORDER BY or limit LIMIT in subqueries both must be used.. For example:\n\n`sql\nSELECT  FROM staff WHERE name IN (SELECT name FROM customer ORDER BY name);\n+----------+------+\n| name     | age  |\n+----------+------+\n| Valerius |   61 |\n+----------+------+\n`\n\nis valid, but\n\n`sql\nSELECT  FROM staff WHERE name IN (SELECT NAME FROM customer ORDER BY name LIMIT 1);\nERROR 1235 (42000): This version of MariaDB doesn''t \n  yet support ''LIMIT & IN/ALL/ANY/SOME subquery''\n`\n\nis not.\n\nModifying and Selecting from the Same Table\n\nIt''s not possible to both modify and select from the same table in a subquery. For example:\n\n`sql\nDELETE FROM staff WHERE name = (SELECT name FROM staff WHERE age=61);\nERROR 1093 (HY000): Table ''staff'' is specified twice, both \n  as a target for ''DELETE'' and as a separate source for data\n`\n\nRow Comparison Operations\n\nThere is only partial support for row comparison operations. The expression in\n\n`sql\nexpr op {ALL|ANY|SOME} subquery,\n`\n\nmust be scalar and the subquery can only return a single column.\n\nHowever, because of the way IN is implemented (it is rewritten as a sequence of = comparisons and AND), the expression in\n\n`sql\nexpression [NOT] IN subquery\n`\n\nis permitted to be an n-tuple and the subquery can return rows of n-tuples.\n\nFor example:\n\n`sql\nSELECT  FROM staff WHERE (name,age) NOT IN (\n  SELECT name,age FROM customer WHERE age >=51]\n);\n+--------+------+\n| name   | age  |\n+--------+------+\n| Bilhah |   37 |\n| Maia   |   25 |\n+--------+------+\n`\n\nis permitted, but\n\n`sql\nSELECT  FROM staff WHERE (name,age) = ALL (\n  SELECT name,age FROM customer WHERE age >=51\n);\nERROR 1241 (21000): Operand should contain 1 column(s)\n`\n\nis not.\n\nCorrelated Subqueries\n\nSubqueries in the FROM clause cannot be correlated subqueries. They cannot be evaluated for each row of the outer query since they are evaluated to produce a result set during when the query is executed.\n\nStored Functions\n\nA subquery can refer to a stored function which modifies data. This is an extension to the SQL standard, but can result in indeterminate outcomes. For example, take:\n\n`sql\nSELECT ... WHERE x IN (SELECT f() ...);\n``\n\nwhere _f()_ inserts rows. The function _f()_ could be executed a different number of times depending on how the optimizer chooses to handle the query.\n\nThis sort of construct is therefore not safe to use in replication that is not row-based, as there could be different results on the master and the slave.\n\nURL: https://mariadb.com/docs/server/reference/sql-statements/data-manipulation/selecting-data/joins-subqueries/subqueries/subquery-limitations', '', 'https://mariadb.com/docs/server/reference/sql-statements/data-manipulation/selecting-data/joins-subqueries/subqueries/subquery-limitations');
INSERT INTO help_topic (help_topic_id, help_category_id, name, description, example, url) VALUES (679, 27, 'Joins', 'Description\n-----------\n\njoin-syntax.md\n\nMain JOIN page, documenting all join types available in MariaDB.\n\nmariadb-join-guide.md\n\nIntroduction to joining tables in MariaDB.\n\nmore-advanced-joins.md\n\nIntroduction to advanced joins in MariaDB.\n\ncomma-vs-join.md\n\nHow to use a comma instead of a JOIN clause, and why you should always prefer the latter.\n\nURL: https://mariadb.com/docs/server/reference/sql-statements/data-manipulation/selecting-data/joins/README', '', 'https://mariadb.com/docs/server/reference/sql-statements/data-manipulation/selecting-data/joins/README');
INSERT INTO help_topic (help_topic_id, help_category_id, name, description, example, url) VALUES (680, 27, 'Comma vs JOIN', 'Description\n-----------\n\nA query to retrieve the list of phone numbers for clients who ordered in the last two weeks might be written in a couple of ways. Here are two:\n\n``sql\nSELECT \nFROM\n  clients,\n  orders,\n  phoneNumbers\nWHERE\n  clients.id = orders.clientId\n  AND clients.id = phoneNumbers.clientId\n  AND orderPlaced >= NOW() - INTERVAL 2 WEEK;\n`\n\n`sql\nSELECT \nFROM\n  clients\n  INNER JOIN orders ON clients.id = orders.clientId\n  INNER JOIN phoneNumbers ON clients.id = phoneNumbers.clientId\nWHERE\n  orderPlaced >= NOW() - INTERVAL 2 WEEK;\n`\n\nDoes it make a difference? Not much as written. But you should use the second form, for these reasons:\n\n Readability. Once the WHERE clause contains more than two conditions, it becomes tedious to pick out the difference between business logic (only dates in the last two weeks) and relational logic (which fields relate clients to orders). Using the JOIN syntax with an ON clause makes the WHERE list shorter, and makes it very easy to see how tables relate to each other.\n Flexibility. Let''s say we need to see all clients even if they don''t have a phone number in the system. With the second version, it''s easy; just change INNER JOIN phoneNumbers to LEFT JOIN phoneNumbers. Try that with the first version, and recent MySQL versions will issue a syntax error because of the change in precedence between the comma operator and the JOIN keyword. The solution is to rearrange the FROM` clause or add parentheses to override the precedence, and that quickly becomes frustrating.\n* Portability. If your queries use standard SQL syntax, you will have an easier time switching to a different database should the need ever arise.\n\nURL: https://mariadb.com/docs/server/reference/sql-statements/data-manipulation/selecting-data/joins/comma-vs-join', '', 'https://mariadb.com/docs/server/reference/sql-statements/data-manipulation/selecting-data/joins/comma-vs-join');
INSERT INTO help_topic (help_topic_id, help_category_id, name, description, example, url) VALUES (681, 27, 'JOIN Syntax', 'Description\n-----------\n\nMariaDB supports the following JOIN syntaxes for the table_references part of SELECT statements and multiple-table DELETE and UPDATE statements:\n\n``sql\ntable_references:\n    table_reference [, table_reference] ...\n\ntable_reference:\n    table_factor\n  | join_table\n\ntable_factor (<= MariaDB 11.6):\n    tbl_name [PARTITION (partition_list)]\n        [query_system_time_period_specification] [[AS] alias] [index_hint_list]\n  | table_subquery [query_system_time_period_specification] [AS] alias\n  | ( table_references )\n  | { ON table_reference LEFT OUTER JOIN table_reference\n        ON conditional_expr }\n\ntable_factor (>= MariaDB 11.7):\n    tbl_name [PARTITION (partition_list)]\n        [query_system_time_period_specification] [[AS] alias] [index_hint_list]\n  | table_subquery [query_system_time_period_specification] [AS] alias [(column_name_list)] \n  | ( table_references )\n  | { ON table_reference LEFT OUTER JOIN table_reference\n        ON conditional_expr }\n\njoin_table:\n    table_reference [INNER | CROSS] JOIN table_factor [join_condition]\n  | table_reference STRAIGHT_JOIN table_factor\n  | table_reference STRAIGHT_JOIN table_factor ON conditional_expr\n  | table_reference {LEFT|RIGHT} [OUTER] JOIN table_reference join_condition\n  | table_reference NATURAL [{LEFT|RIGHT} [OUTER]] JOIN table_factor\n\njoin_condition:\n    ON conditional_expr\n  | USING (column_list)\n\nquery_system_time_period_specification:\n    FOR SYSTEM_TIME AS OF point_in_time\n  | FOR SYSTEM_TIME BETWEEN point_in_time AND point_in_time\n  | FOR SYSTEM_TIME FROM point_in_time TO point_in_time\n  | FOR SYSTEM_TIME ALL\n\npoint_in_time:\n    [TIMESTAMP] expression\n  | TRANSACTION expression\n\nindex_hint_list:\n    index_hint [, index_hint] ...\n\nindex_hint:\n    USE {INDEX|KEY}\n      [{FOR {JOIN|ORDER BY|GROUP BY}] ([index_list])\n  | IGNORE {INDEX|KEY}\n      [{FOR {JOIN|ORDER BY|GROUP BY}] (index_list)\n  | FORCE {INDEX|KEY}\n      [{FOR {JOIN|ORDER BY|GROUP BY}] (index_list)\n\nindex_list:\n    index_name [, index_name] ...\n`\n\nA _table reference_ is also known as a _join expression_.\n\nEach table can also be specified as db_name.tabl_name. This allows to write queries which involve multiple databases. See Identifier Qualifiers for syntax details.\n\nThe syntax of table_factor is an extension to the SQL Standard. The latter accepts only table_reference, not a list of them inside a pair of parentheses.\n\nThis is a conservative extension if we consider each comma in a list of table_reference items as equivalent to an inner join. Consider this query:\n\n`sql\nSELECT  FROM t1 LEFT JOIN (t2, t3, t4)\n                 ON (t2.a=t1.a AND t3.b=t1.b AND t4.c=t1.c)\n`\n\nIt is equivalent to this query:\n\n`sql\nSELECT  FROM t1 LEFT JOIN (t2 CROSS JOIN t3 CROSS JOIN t4)\n                 ON (t2.a=t1.a AND t3.b=t1.b AND t4.c=t1.c)\n`\n\nIn MariaDB, CROSS JOIN is a syntactic equivalent toINNER JOIN (they can replace each other). In standard SQL, they are not equivalent. INNER JOIN is used with anON clause, CROSS JOIN is used otherwise.\n\nIn general, parentheses can be ignored in join expressions containing only inner join operations. MariaDB also supports nested joins (see Nested Join Optimization).\n\nSubqueries\n\nA table subquery is specified as a parenthesized query and must contain a following derived table name (specified as _alias_ in the above syntax specification).\n\nYou can optionally specify a list of column names in parenthesis.\n\n`sql\nSELECT ic1, ic2, ic3 FROM\n      (\n        SELECT c1, c2, c3 FROM t1 GROUP BY c1\n      ) dt2 (ic1, ic2, ic3)\n    JOIN t2 ON t2.c1 = dt2.ic1\n    WHERE c2 > 0\n    GROUP BY ic1\n`\n\nHere, the table subquery for t1 will be materialized and named dt2, with column names ic1, ic2, ic3. These column names are used outside the subquery.\n\nYou cannot optionally specify a list of column names in parenthesis.\n\nSee also Correlation Column List.\n\nSystem-Versioned Tabled\n\nSee System-versioned tables for more information about the FOR SYSTEM_TIME syntax.\n\nIndex Hints\n\nIndex hints can be specified to affect how the MariaDB optimizer makes use of indexes. For more information, see How to force query plans.\n\nOracle Mode\n\nThis feature is available from MariaDB 12.1.\n\nOverview\n\nWhen Oracle mode is active, the Oracle-style (+)  syntax can be used. For example, the following two queries are identical:\n\n`sql\nSELECT  FROM t1 LEFT JOIN t2 ON t1.a = t2.b;\n`\n\n`sql\nSELECT  FROM t1, t2 WHERE t1.a = t2.b(+);\n`\n\nSimilarly, the following two queries are identical:\n\n`sql\nSELECT  FROM t1 RIGHT JOIN t2 ON t1.a = t2.b;\n`\n\n`sql\nSELECT  FROM t1, t2 WHERE t1.a(+) = t2.b;\n`\n\nWith more than two tables, these two queries are identical:\n\n`sql\nSELECT  FROM t1 LEFT JOIN t2 ON t1.a = t2.a LEFT JOIN t3 ON t2.a = t3.a\n`\n\n`sql\nSELECT  FROM t1, t2, t3 WHERE t1.a = t2.a(+) AND t2.a = t3.a(+)\n`\n\nTo "rewrite" a join query using the (+) syntax, use EXPLAIN EXTENDED (the last line is an approximation at using the "regular" LEFT JOIN syntax):\n\n`sql\nEXPLAIN EXTENDED\n    SELECT  FROM t1, t2, t3 WHERE t1.a = t2.a(+) AND t2.a = t3.a(+);\nid	select_type	table	type	possible_keys	key	key_len	ref	rows	filtered	Extra\n1	SIMPLE	t1	ALL	NULL	NULL	NULL	NULL	3	100.00	\n1	SIMPLE	t2	ALL	NULL	NULL	NULL	NULL	3	100.00	Using where; Using join buffer (flat, BNL join)\n1	SIMPLE	t3	ALL	NULL	NULL	NULL	NULL	3	100.00	Using where; Using join buffer (incremental, BNL join)\nWarnings:\nNote	1003	select "test"."t1"."a" AS "a","test"."t2"."a" AS "a","test"."t3"."a" AS "a" from "test"."t1" left join "test"."t2" on("test"."t2"."a" = "test"."t1"."a") left join "test"."t3" on("test"."t3"."a" = "test"."t2"."a") where 1\n`\n\nLimitations\n\nThe table whose columns are marked with the (+) operator in a subexpression (a part of the WHERE clause divided by AND) are the inner part of the expression. A table whose columns are not marked with the operator belong to the outer part.\n\nExample of a single subexpression within a WHERE clause:\n\n`sql\n... WHERE t1.a = t2.a(+)\n`\n\nExample of two subexpressions within a WHERE clause – here, both t1.a = t2.a(+)  and t2.a = t3.a(+) are inner parts, because both contain a (+) operator:\n\n`sql\n... WHERE t1.a = t2.a(+) AND t2.a = t3.a(+)\n`\n\nExample of two subexpressions within a WHERE clause – here, t1.a = t2.a(+) is the inner part (because of the (+) operator), and t2.a = 42 is the outer part (it doesn''t have a (+) operator:\n\n`sql\n... WHERE t1.a = t2.a(+) AND t2.a = 42\n`\n\n"Rewritten" as a "regular" join, that clause looks like this:\n\n`sql\n... FROM t1 LEFT JOIN t2 ON (t1.a = t2.a) WHERE t2.a = 42\n`\n\nThe following limitations apply:\n\n The (+) operator can only be used in a WHERE clause.\n The (+) operator can only be applied to a table column, and the column should be from the local SELECT, not from an outer SELECT.\n The (+) operator cannot be used with other JOIN methods – it must be a comma-separated list in the FROM clause.\n When the WHERE clause is split into subexpressions by AND, (+) cannot be used.\n The (+) operator cannot be used on the right side of an IN function.\n The (+) operator cannot be used in row operations.\n The (+) operator cannot be used when two or more tables are on one side of and marked with the (+) operator and some are not.\n The (+) operator cannot create loops (or cycles) of dependence, where the same table appears on both sides of the operator in one expression, or through a chain of expressions.\n\nError Codes\n\nThe following errors may occur when not adhering to the (+) operator limitations or for other reasons:\n\n ER_INVALID_USE_OF_ORA_JOIN\n ER_INVALID_USE_OF_ORA_JOIN_OUTER_REF\n ER_INVALID_USE_OF_ORA_JOIN_WRONG_FUNC\n ER_INVALID_USE_OF_ORA_JOIN_ONE_TABLE\n ER_INVALID_USE_OF_ORA_JOIN_CYCLE\n\nYou can find examples of the errors by error code in these files (which are available on GitHub):\n\n mysql-test/suite/compat/oracle/t/ora_outer_join.test\n mysql-test/suite/compat/oracle/t/ora_outer_join_err.test`\n\nExamples\n--------\n\nSELECT left_tbl.*\n  FROM left_tbl LEFT JOIN right_tbl ON left_tbl.id = right_tbl.id\n  WHERE right_tbl.id IS NULL;\n\nURL: https://mariadb.com/docs/server/reference/sql-statements/data-manipulation/selecting-data/joins/join-syntax', '', 'https://mariadb.com/docs/server/reference/sql-statements/data-manipulation/selecting-data/joins/join-syntax');
INSERT INTO help_topic (help_topic_id, help_category_id, name, description, example, url) VALUES (682, 27, 'LIMIT', 'Description\n-----------\n\nUse the LIMIT clause to restrict the number of returned rows. When you use a single integer _n_ with LIMIT, the first _n_ rows will be returned. Use the ORDER BY clause to control which rows come first. You can also select a number of rows after an offset using either of the following:\n\n``sql\nLIMIT offset, row_count\nLIMIT row_count OFFSET offset\n`\n\nWhen you provide an offset _m_ with a limit _n_, the first _m_ rows will be ignored, and the following _n_ rows will be returned.\n\nExecuting an UPDATE with the LIMIT clause is not safe for replication. LIMIT 0 is an exception to this rule (see MDEV-6170).\n\nThere is a LIMIT ROWS EXAMINED optimization which provides the means to terminate the execution of SELECT statements which examine too many rows, and thus use too many resources. See LIMIT ROWS EXAMINED.\n\nMulti-Table Updates\n\nIt is possible to use LIMIT (or ORDER BY) in a multi-table UPDATE statement.\n\nIt is not possible to use LIMIT (or ORDER BY) in a multi-table UPDATE statement.\n\nGROUP_CONCAT\n\nIt is possible to use LIMIT with GROUP_CONCAT().\n\nIt is not possible to use LIMIT` with GROUP_CONCAT().\n\nExamples\n--------\n\nCREATE TABLE members (name VARCHAR(20));\nINSERT INTO members VALUES(''Jagdish''),(''Kenny''),(''Rokurou''),(''Immaculada'');\n\nSELECT * FROM members;\n+------------+\n| name       |\n+------------+\n| Jagdish    |\n| Kenny      |\n| Rokurou    |\n| Immaculada |\n+------------+\n\nURL: https://mariadb.com/docs/server/reference/sql-statements/data-manipulation/selecting-data/limit', '', 'https://mariadb.com/docs/server/reference/sql-statements/data-manipulation/selecting-data/limit');
INSERT INTO help_topic (help_topic_id, help_category_id, name, description, example, url) VALUES (683, 27, 'LOCK IN SHARE MODE', 'Description\n-----------\n\nInnoDB supports row-level locking. Selected rows can be locked using LOCK IN SHARE MODE or FOR UPDATE. In both cases, a lock is acquired on the rows read by the query, and it will be released when the current transaction is committed.\n\nWhen LOCK IN SHARE MODE is specified in a SELECT statement, MariaDB will wait until all transactions that have modified the rows are committed. Then, a read lock is acquired. All transactions can read the rows, but if they want to modify them, they have to wait until your transaction is committed.\n\nInnoDB locks index records rather than logical rows. If a SELECT is satisfied by a secondary index (a covering index read), it just locks that index. Instead, the primary key records will be locked if a concurrent UPDATE modifies columns outside of that index. These locks do not overlap under READ COMMITTED isolation level, so the update can proceed. To ensure a block is used, the SELECT query must reference columns from the primary index.\n\nFor further information and an example, see InnoDB Lock Modes.\n\nIf autocommit is set to 1 (the default), the LOCK IN SHARE MODE and FOR UPDATE clauses have no effect in InnoDB. For non-transactional storage engines like MyISAM and ARIA, a table level lock will be taken even if autocommit is set to 1.\n\nURL: https://mariadb.com/docs/server/reference/sql-statements/data-manipulation/selecting-data/lock-in-share-mode', '', 'https://mariadb.com/docs/server/reference/sql-statements/data-manipulation/selecting-data/lock-in-share-mode');
INSERT INTO help_topic (help_topic_id, help_category_id, name, description, example, url) VALUES (684, 27, 'ORDER BY', 'Description\n-----------\n\nUse the ORDER BY clause to order a resultset, such as that are returned from a SELECT statement. You can specify just a column or use any expression with functions. If you are using the GROUP BY clause, you can use grouping functions in ORDER BY. Ordering is done after grouping.\n\nYou can use multiple ordering expressions, separated by commas. Rows are sorted by the first expression, then by the second expression if they have the same value for the first, and so on.\n\nYou can use the keywords ASC and DESC after each ordering expression to force that ordering to be ascending or descending, respectively. Ordering is ascending by default.\n\nYou can also use a single integer as the ordering expression. If you use an integer _n_, the results is ordered by the n<sup>th</sup> column in the select expression.\n\nWhen string values are compared, they are compared as if by the STRCMP function. STRCMP ignores trailing whitespace and may normalize characters and ignore case, depending on the collation in use.\n\nDuplicated entries in the ORDER BY clause are removed.\n\nORDER BY can also be used to order the activities of a DELETE or UPDATE statement (usually with the LIMIT clause).\n\nIt is possible to use ORDER BY (or LIMIT) in a multi-table UPDATE statement.\n\nIt is not possible to use ORDER BY (or LIMIT) in a multi-table UPDATE statement.\n\nMariaDB allows packed sort keys and values of non-sorted fields in the sort buffer. This can make filesort temporary files much smaller when VARCHAR, CHAR or BLOB columns are used, notably speeding up some ORDER BY sorts.\n\nMariaDB does not allow packed sort keys and values of non-sorted fields in the sort buffer.\n\nExamples\n--------\n\nCREATE TABLE seq (i INT, x VARCHAR(1));\nINSERT INTO seq VALUES (1,''a''), (2,''b''), (3,''b''), (4,''f''), (5,''e'');\n\nSELECT  FROM seq ORDER BY i;\n+------+------+\n| i    | x    |\n+------+------+\n|    1 | a    |\n|    2 | b    |\n|    3 | b    |\n|    4 | f    |\n|    5 | e    |\n+------+------+\n\nSELECT  FROM seq ORDER BY i DESC;\n+------+------+\n| i    | x    |\n+------+------+\n|    5 | e    |\n|    4 | f    |\n|    3 | b    |\n|    2 | b    |\n|    1 | a    |\n+------+------+\n\nSELECT * FROM seq ORDER BY x,i;\n+------+------+\n| i    | x    |\n+------+------+\n|    1 | a    |\n|    2 | b    |\n|    3 | b    |\n|    5 | e    |\n|    4 | f    |\n+------+------+\n\nURL: https://mariadb.com/docs/server/reference/sql-statements/data-manipulation/selecting-data/order-by', '', 'https://mariadb.com/docs/server/reference/sql-statements/data-manipulation/selecting-data/order-by');
INSERT INTO help_topic (help_topic_id, help_category_id, name, description, example, url) VALUES (685, 27, 'PROCEDURE', 'Description\n-----------\n\nThe PROCEDURE clause of SELECT passes the whole result set to a Procedure which will process it. These Procedures are not Stored Procedures, and can only be written in the C language, so it is necessary to recompile the server.\n\nCurrently, the only available procedure is ANALYSE, which examines the resultset and suggests the optimal datatypes for each column. It is defined in the sql/sql_analyse.cc file, and can be used as an example to create more Procedures.\n\nThis clause cannot be used in a view definition.\n\nURL: https://mariadb.com/docs/server/reference/sql-statements/data-manipulation/selecting-data/procedure', '', 'https://mariadb.com/docs/server/reference/sql-statements/data-manipulation/selecting-data/procedure');
INSERT INTO help_topic (help_topic_id, help_category_id, name, description, example, url) VALUES (686, 27, 'SELECT INTO DUMPFILE', 'Syntax\n------\n\nSELECT ... INTO DUMPFILE ''file_path''\n\nDescription\n-----------\n\nSELECT ... INTO DUMPFILE is a SELECT clause which writes the resultset into a single unformatted row, without any separators, in a file. The results will not be returned to the client.\n\n_file_path_ can be an absolute path, or a relative path starting from the data directory. It can only be specified as a string literal, not as a variable. However, the statement can be dynamically composed and executed as a prepared statement to work around this limitation.\n\nThis statement is binary-safe and so is particularly useful for writing BLOB values to file. It can be used, for example, to copy an image or an audio document from the database to a file.\n\nThe file must not exist. It cannot be overwritten. A user needs the FILE privilege to run this statement. Also, MariaDB needs permission to write files in the specified location. If the secure_file_priv system variable is set to a non-empty directory name, the file can only be written to that directory.\n\nThe character_set_filesystem system variable has controlled interpretation of file names that are given as literal strings.\n\nThe character_set_filesystem system variable does not have controlled interpretation of file names that are given as literal strings.\n\nExamples\n--------\n\nSELECT _utf8''Hello world!'' INTO DUMPFILE ''/tmp/world'';\n\nSELECT LOAD_FILE(''/tmp/world'') AS world;\n+--------------+\n| world        |\n+--------------+\n| Hello world! |\n+--------------+\n\nURL: https://mariadb.com/docs/server/reference/sql-statements/data-manipulation/selecting-data/select-into-dumpfile', '', 'https://mariadb.com/docs/server/reference/sql-statements/data-manipulation/selecting-data/select-into-dumpfile');
INSERT INTO help_topic (help_topic_id, help_category_id, name, description, example, url) VALUES (687, 27, 'SELECT INTO OUTFILE', 'Syntax\n------\n\nSELECT ... INTO OUTFILE ''file_name''\n        [CHARACTER SET charset_name]\n        [export_options]\n\nexport_options:\n    [{FIELDS | COLUMNS}\n        [TERMINATED BY ''string'']\n        [[OPTIONALLY] ENCLOSED BY ''char'']\n        [ESCAPED BY ''char'']\n    ]\n    [LINES\n        [STARTING BY ''string'']\n        [TERMINATED BY ''string'']\n    ]\n\nDescription\n-----------\n\nSELECT INTO OUTFILE writes the resulting rows to a file, and allows the use of column and row terminators to specify a particular output format. The default is to terminate fields with tabs () and lines with newlines ().\n\nThe file must not exist. It cannot be overwritten. A user needs the FILE privilege to run this statement. Also, MariaDB needs permission to write files in the specified location. If the secure_file_priv system variable is set to a non-empty directory name, the file can only be written to that directory.\n\nThe LOAD DATA INFILE statement complements SELECT INTO OUTFILE.\n\nCharacter Sets\n\nThe CHARACTER SET clause specifies the character set in which the results are to be written. Without the clause, no conversion takes place (the binary character set). In this case, if there are multiple character sets, the output will contain these too, and may not easily be able to be reloaded.\n\nIn cases where you have two servers using different character-sets, using SELECT INTO OUTFILE to transfer data from one to the other can have unexpected results. To ensure that MariaDB correctly interprets the escape sequences, use the CHARACTER SET clause on both the SELECT INTO OUTFILE statement and the subsequent LOAD DATA INFILE statement.\n\nExamples\n--------\n\nSELECT customer_id, firstname, surname FROM customer\n  INTO OUTFILE ''/exportdata/customers.txt''\n  FIELDS TERMINATED BY '','' OPTIONALLY ENCLOSED BY ''"''\n  LINES TERMINATED BY ''\\n'';\n\nURL: https://mariadb.com/docs/server/reference/sql-statements/data-manipulation/selecting-data/select-into-outfile', '', 'https://mariadb.com/docs/server/reference/sql-statements/data-manipulation/selecting-data/select-into-outfile');
INSERT INTO help_topic (help_topic_id, help_category_id, name, description, example, url) VALUES (688, 27, 'SELECT ... OFFSET ... FETCH', 'Syntax\n------\n\nOFFSET start { ROW | ROWS }\nFETCH { FIRST | NEXT } [ count ] { ROW | ROWS } { ONLY | WITH TIES }\n\nDescription\n-----------\n\nThe OFFSET clause allows one to return only those elements of a resultset that come after a specified offset. The FETCH clause specifies the number of rows to return, while ONLY or WITH TIES specifies whether or not to also return any further results that tie for last place according to the ordered resultset.\n\nEither the singular ROW or the plural ROWS can be used after the OFFSET and FETCH clauses; the choice has no impact on the results.\n\nFIRST and NEXT give the same result.\n\nIn the case of WITH TIES, an ORDER BY clause is required, otherwise an error will be returned.\n\n``sql\nSELECT i FROM t1 FETCH FIRST 2 ROWS WITH TIES;\nERROR 4180 (HY000): FETCH ... WITH TIES requires ORDER BY clause to be present\n``\n\nExamples\n--------\n\nCREATE OR REPLACE TABLE t1 (i INT);\nINSERT INTO t1 VALUES (1),(2),(3),(4), (4), (5);\nSELECT i FROM t1 ORDER BY i ASC;\n+------+\n| i    |\n+------+\n|    1 |\n|    2 |\n|    3 |\n|    4 |\n|    4 |\n|    5 |\n+------+\n\nURL: https://mariadb.com/docs/server/reference/sql-statements/data-manipulation/selecting-data/select-offset-fetch', '', 'https://mariadb.com/docs/server/reference/sql-statements/data-manipulation/selecting-data/select-offset-fetch');
INSERT INTO help_topic (help_topic_id, help_category_id, name, description, example, url) VALUES (689, 27, 'SELECT WITH ROLLUP', 'Description\n-----------\n\nThe WITH ROLLUP modifier adds extra rows to the result set that represent super-aggregate summaries. The super-aggregated column is represented by a NULL value. Multiple aggregates over different columns will be added if there are multiple GROUP BY columns.\n\nThe LIMIT clause can be used at the same time, and is applied after the WITH ROLLUP rows have been added.\n\nWITH ROLLUP cannot be used with ORDER BY. Some sorting is still possible by using ASC or DESC clauses with the GROUP BY column, although the super-aggregate rows will always be added last.\n\nExamples\n--------\n\nCREATE TABLE booksales ( \n  country VARCHAR(35), genre ENUM(''fiction'',''non-fiction''), year YEAR, sales INT);\n\nINSERT INTO booksales VALUES\n  (''Senegal'',''fiction'',2014,12234), (''Senegal'',''fiction'',2015,15647),\n  (''Senegal'',''non-fiction'',2014,64980), (''Senegal'',''non-fiction'',2015,78901),\n  (''Paraguay'',''fiction'',2014,87970), (''Paraguay'',''fiction'',2015,76940),\n  (''Paraguay'',''non-fiction'',2014,8760), (''Paraguay'',''non-fiction'',2015,9030);\n\nURL: https://mariadb.com/docs/server/reference/sql-statements/data-manipulation/selecting-data/select-with-rollup', '', 'https://mariadb.com/docs/server/reference/sql-statements/data-manipulation/selecting-data/select-with-rollup');
INSERT INTO help_topic (help_topic_id, help_category_id, name, description, example, url) VALUES (690, 27, 'SELECT', 'Syntax\n------\n\nSELECT\n    [/+ hints /]\n    [/+ JOIN_PREFIX(argument_list) /]\n    [/+ JOIN_ORDER(argument_list) /]\n    [/+ JOIN_FIXED_ORDER(argument_list) /]\n    [/+ JOIN_SUFFIX(argument_list) /]\n    [/+ MAX_EXECUTION_TIME(milliseconds) /]\n    [ALL | DISTINCT | DISTINCTROW]\n    [HIGH_PRIORITY]\n    [STRAIGHT_JOIN]\n    [SQL_SMALL_RESULT] [SQL_BIG_RESULT] [SQL_BUFFER_RESULT]\n    [SQL_CACHE | SQL_NO_CACHE] [SQL_CALC_FOUND_ROWS]\n    select_expr [, select_expr ...]\n    [ FROM table_references\n      [WHERE where_condition]\n      [GROUP BY {col_name | expr | position} [ASC | DESC], ... [WITH ROLLUP]]\n      [HAVING where_condition]\n      [ORDER BY {col_name | expr | position} [ASC | DESC], ...]\n      [LIMIT {[offset,] row_count | row_count OFFSET offset  \n      [ROWS EXAMINED rows_limit] } |\n        [OFFSET start { ROW | ROWS }]\n        [FETCH { FIRST | NEXT } [ count ] { ROW | ROWS } { ONLY | WITH TIES }] ]\n      procedure|[PROCEDURE procedure_name(argument_list)]\n      [INTO OUTFILE ''file_name'' [CHARACTER SET charset_name] [export_options] |\n        INTO DUMPFILE ''file_name'' | INTO var_name [, var_name] ]\n      [FOR UPDATE lock_option | LOCK IN SHARE MODE lock_option]\nexport_options:\n    [{FIELDS | COLUMNS}\n        [TERMINATED BY ''string'']\n        [[OPTIONALLY] ENCLOSED BY ''char'']\n        [ESCAPED BY ''char'']\n    ]\n    [LINES\n        [STARTING BY ''string'']\n        [TERMINATED BY ''string'']\n    ]\nlock_option:\n    [WAIT n | NOWAIT | SKIP LOCKED]\n\nDescription\n-----------\n\nSELECT is used to retrieve rows selected from one or more tables, and can include UNION statements and subqueries.\n\n Each select_expr expression indicates a column or data that you want to retrieve. You must have at least one select expression. See Select Expressions below.\n The FROM clause indicates the table or tables from which to retrieve rows. Use either a single table name or a JOIN expression. See JOIN for details. If no table is involved, FROM DUAL can be specified.\n Each table can also be specified as db_name.tabl_name. Each column can also be specified as tbl_name.col_name or even db_name.tbl_name.col_name. This allows one to write queries which involve multiple databases. See Identifier Qualifiers for syntax details.\n The WHERE clause, if given, indicates the condition or conditions that rows must satisfy to be selected. The where_condition is an expression that evaluates to true for each row to be selected. The statement selects all rows if there is no WHERE clause.\n   In the WHERE clause, you can use any of the functions and operators that MariaDB supports, except for aggregate (summary) functions. See Functions and Operators and Functions and Modifiers for use with GROUP BY (aggregate).\n Use the ORDER BY clause to order the results.\n Use the LIMIT clause to restrict the results to only a certain number of rows, optionally with an offset.\n Use the GROUP BY and HAVING clauses to group rows together when they have columns or computed values in common.\n\nSELECT can also be used to retrieve rows computed without reference to any table.\n\nSelect Expressions\n\nA SELECT statement must contain one or more select expressions, separated by commas. Each select expression can be one of the following:\n\n The name of a column.\n Any expression using functions and operators.\n  to select all columns from all tables in the FROM clause.\n tbl_name. to select all columns from just the table tbl_name.\n\nWhen specifying a column, you can either use just the column name or qualify the column name with the name of the table using tbl_name.col_name. The qualified form is useful if you are joining multiple tables in the FROM clause. If you do not qualify the column names when selecting from multiple tables, MariaDB will try to find the column in each table. It is an error if that column name exists in multiple tables.\n\nYou can quote column names using backticks. If you are qualifying column names with table names, quote each part separately as `tbl_name.col_name.\n\nIf you use any grouping functions in any of the select expressions, all rows in your results will be implicitly grouped, as if you had used GROUP BY NULL. GROUP BY NULL being an expression behaves specially such that the entire result set is treated as a group.\n\nDISTINCT\n\nA query may produce some identical rows. By default, all rows are retrieved, even when their values are the same. To explicitly specify that you want to retrieve identical rows, use the ALL option. If you want duplicates to be removed from the result set, use the DISTINCT option. DISTINCTROW is a synonym for DISTINCT. See also COUNT DISTINCT and SELECT UNIQUE in Oracle mode.\n\nINTO\n\nThe INTO clause is used to specify that the query results should be written to a file or variable.\n\n SELECT INTO OUTFILE - formatting and writing the result to an external file.\n SELECT INTO DUMPFILE - binary-safe writing of the unformatted results to an external file.\n* SELECT INTO Variable - selecting and setting variables.\n\nThe reverse of SELECT INTO OUTFILE is LOAD DATA.\n\nLIMIT\n\nRestricts the number of returned rows. See LIMIT and LIMIT ROWS EXAMINED for details.\n\nLOCK IN SHARE MODE/FOR UPDATE\n\nSee LOCK IN SHARE MODE and FOR UPDATE for details on the respective locking clauses.\n\nOFFSET ... FETCH\n\nSee SELECT ... OFFSET ... FETCH.\n\nThe clause doesn''t exist.\n\nORDER BY\n\nOrder a result set. See ORDER BY for details.\n\nPARTITION\n\nSpecifies to the optimizer which partitions are relevant for the query. Other partitions will not be read. See Partition Pruning and Selection for details.\n\nPROCEDURE\n\nPasses the whole result set to a C Procedure. See PROCEDURE and PROCEDURE ANALYSE (the only built-in procedure not requiring the server to be recompiled).\n\nSKIP LOCKED\n\nThis causes rows that couldn''t be locked (LOCK IN SHARE MODE or FOR UPDATE) to be excluded from the result set. An explicit NOWAIT is implied here. This is only implemented on InnoDB tables and ignored otherwise.\n\nThe clause doesn''t exist.\n\nOptimizer Hints\n\nThese include HIGH_PRIORITY, STRAIGHT_JOIN, SQL_SMALL_RESULT | SQL_BIG_RESULT, SQL_BUFFER_RESULT, SQL_CACHE | SQL_NO_CACHE, and SQL_CALC_FOUND_ROWS.\n\nSee Optimizer Hints for details.\n\nmax_statement_time clause\n\nBy using max_statement_time in conjunction with SET STATEMENT, it is possible to limit the execution time of individual queries. For example:\n\n`sql\nSET STATEMENT max_statement_time=100 FOR \n  SELECT field1 FROM table_name ORDER BY field1;\n``\n\nWAIT/NOWAIT\n\nSet the lock wait timeout. See WAIT and NOWAIT.\n\nExamples\n--------\n\nSELECT f1,f2 FROM t1 WHERE (f3<=10) AND (f4=''y'');\n\nURL: https://mariadb.com/docs/server/reference/sql-statements/data-manipulation/selecting-data/select', '', 'https://mariadb.com/docs/server/reference/sql-statements/data-manipulation/selecting-data/select');
INSERT INTO help_topic (help_topic_id, help_category_id, name, description, example, url) VALUES (691, 27, 'EXCEPT', 'Syntax\n------\n\nSELECT ...\n(INTERSECT [ALL | DISTINCT] | EXCEPT [ALL | DISTINCT] | UNION [ALL | DISTINCT]) \n  SELECT ...\n[(INTERSECT [ALL | DISTINCT] | EXCEPT [ALL | DISTINCT] | UNION [ALL | DISTINCT]) \n  SELECT ...]\n[ORDER BY [{col_name | expr | position} [ASC | DESC] \n  [, {col_name | expr | position} [ASC | DESC] ...]]]\n[LIMIT {[offset,] row_count | row_count OFFSET offset}\n| OFFSET start { ROW | ROWS }\n| FETCH { FIRST | NEXT } [ count ] { ROW | ROWS } { ONLY | WITH TIES } ]\n\nDescription\n-----------\n\nMariaDB supports EXCEPT and INTERSECT in addition to UNION.\n\nThe queries before and after EXCEPT must be SELECT or VALUES statements.\n\nAll behavior for naming columns, ORDER BY and LIMIT is the same as for UNION. Note that the alternative SELECT ... OFFSET ... FETCH syntax is only supported. This allows us to use the WITH TIES clause.\n\nEXCEPT implicitly supposes a DISTINCT operation.\n\nThe result of EXCEPT is all records of the left SELECT result except records which are in right SELECT result set, i.e. it is subtraction of two result sets.\n\nEXCEPT and UNION have the same operation precedence and INTERSECT has a higher precedence, unless running in Oracle mode, in which case all three have the same precedence.\n\nParentheses\n\nParentheses can be used to specify precedence. Before this, a syntax error would be returned.\n\nMariaDB starting with 10.5.0\n\nALL/DISTINCT\n\nEXCEPT ALL and EXCEPT DISTINCT . The ALL operator leaves duplicates intact, while the DISTINCT operator removes duplicates. DISTINCT is the default behavior if neither operator is supplied.\n\nOnly EXCEPT DISTINCT is available.\n\nExamples\n--------\n\n(SELECT e_name AS name, email FROM customers)\nEXCEPT\n(SELECT c_name AS name, email FROM employees);\n\nURL: https://mariadb.com/docs/server/reference/sql-statements/data-manipulation/selecting-data/set-operations/except', '', 'https://mariadb.com/docs/server/reference/sql-statements/data-manipulation/selecting-data/set-operations/except');
INSERT INTO help_topic (help_topic_id, help_category_id, name, description, example, url) VALUES (692, 27, 'INTERSECT', 'Syntax\n------\n\nSELECT ...\n(INTERSECT [ALL | DISTINCT] | EXCEPT [ALL | DISTINCT] | UNION [ALL | DISTINCT]) SELECT ...\n[(INTERSECT [ALL | DISTINCT] | EXCEPT [ALL | DISTINCT] | UNION [ALL | DISTINCT]) SELECT ...]\n[ORDER BY [column [, column ...]]]\n[LIMIT {[offset,] row_count | row_count OFFSET offset}]\n\nDescription\n-----------\n\nMariaDB has supported INTERSECT (as well as EXCEPT) in addition to UNION since MariaDB 10.3.\n\nAll behavior for naming columns, ORDER BY and LIMIT is the same as for UNION.\n\nINTERSECT implicitly supposes a DISTINCT operation.\n\nThe result of an intersect is the intersection of right and left SELECT results, i.e. only records that are present in both result sets will be included in the result of the operation.\n\nINTERSECT has higher precedence than UNION and EXCEPT (unless running running in Oracle mode, in which case all three have the same precedence). If possible it will be executed linearly, but if not, it will be translated to a subquery in the FROM clause:\n\n``sql\n(SELECT a,b FROM t1)\nUNION\n(SELECT c,d FROM t2)\nINTERSECT\n(SELECT e,f FROM t3)\nUNION\n(SELECT 4,4);\n`\n\nwill be translated to:\n\n`sql\n(SELECT a,b FROM t1)\nUNION\nSELECT c,d FROM\n  ((SELECT c,d FROM t2)\n   INTERSECT\n   (SELECT e,f FROM t3)) dummy_subselect\nUNION\n(SELECT 4,4)\n`\n\nParentheses\n\nParentheses can be used to specify precedence.\n\nParentheses cannot be used to specify precedence.\n\nMariaDB starting with 10.5.0\n\nALL/DISTINCT\n\nINTERSECT ALL and INTERSECT DISTINCT . The ALL operator leaves duplicates intact, while the DISTINCT operator removes duplicates. DISTINCT is the default behavior if neither operator is supplied.\n\nDISTINCT` is the only behavior available.\n\nExamples\n--------\n\n(SELECT e_name AS name, email FROM employees)\nINTERSECT\n(SELECT c_name AS name, email FROM customers);\n\nURL: https://mariadb.com/docs/server/reference/sql-statements/data-manipulation/selecting-data/set-operations/intersect', '', 'https://mariadb.com/docs/server/reference/sql-statements/data-manipulation/selecting-data/set-operations/intersect');
INSERT INTO help_topic (help_topic_id, help_category_id, name, description, example, url) VALUES (693, 27, 'MINUS', 'Description\n-----------\n\nMINUS is available starting from MariaDB 10.6.1.\n\nMINUS is a synonym for EXCEPT when SQL_MODE=ORACLE is set.\n\n``sql\nCREATE TABLE seqs (i INT);\nINSERT INTO seqs VALUES (1),(2),(2),(3),(3),(4),(5),(6);\n\nSET SQL_MODE=''ORACLE'';\n\nSELECT i FROM seqs WHERE i <= 3 MINUS SELECT i FROM seqs WHERE i>=3;\n+------+\n| i    |\n+------+\n|    1 |\n|    2 |\n+------+\n``\n\nURL: https://mariadb.com/docs/server/reference/sql-statements/data-manipulation/selecting-data/set-operations/minus', '', 'https://mariadb.com/docs/server/reference/sql-statements/data-manipulation/selecting-data/set-operations/minus');
INSERT INTO help_topic (help_topic_id, help_category_id, name, description, example, url) VALUES (694, 27, 'Precedence Control in Table Operations', 'Syntax\n------\n\n(  expression )\n[ORDER BY [column[, column...]]]\n[LIMIT {[offset,] row_count | row_count OFFSET offset}]\n\nDescription\n-----------\n\nUsing parentheses in SQL allows to control the order of execution for SELECT statements and Table Value Constructor, including UNION, EXCEPT, and INTERSECT operations. MariaDB executes the parenthetical expression before the rest of the statement. You can then use ORDER BY and LIMIT clauses the further organize the result set.\n\nThe Optimizer may rearrange the exact order in which MariaDB executes different parts of the statement. When it calculates the result set, however, it returns values as though the parenthetical expression were executed first.\n\nExamples\n--------\n\nCREATE TABLE test.t1 (num INT);\n\nINSERT INTO test.t1 VALUES (1),(2),(3);\n\n(SELECT  FROM test.t1 \n UNION \n VALUES (10)) \nINTERSECT \nVALUES (1),(3),(10),(11);\n+------+\n| num  |\n+------+\n|    1 |\n|    3 |\n|   10 |\n+------+\n\n((SELECT  FROM test.t1 \n  UNION \n  VALUES (10)) \n INTERSECT \n VALUES (1),(3),(10),(11)) \nORDER BY 1 DESC;\n+------+\n| num  |\n+------+\n|   10 |\n|    3 |\n|    1 |\n+------+\n\nURL: https://mariadb.com/docs/server/reference/sql-statements/data-manipulation/selecting-data/set-operations/precedence-control-in-table-operations', '', 'https://mariadb.com/docs/server/reference/sql-statements/data-manipulation/selecting-data/set-operations/precedence-control-in-table-operations');
INSERT INTO help_topic (help_topic_id, help_category_id, name, description, example, url) VALUES (695, 27, 'UNION', 'Description\n-----------\n\nUNION is used to combine the results from multiple SELECT statements into a single result set.\n\nThe column names from the first SELECT statement are used as the column names for the results returned. Selected columns listed in corresponding positions of each SELECT statement should have the same data type. (For example, the first column selected by the first statement should have the same type as the first column selected by the other statements.)\n\nIf they don''t, the type and length of the columns in the result take into account the values returned by all of the SELECTs, so there is no need for explicit casting. Note that currently this is not the case for recursive CTEs - see MDEV-12325.\n\nTable names can be specified as db_name.tbl_name. This permits writing UNIONs which involve multiple databases. See Identifier Qualifiers for syntax details.\n\nUNION queries cannot be used with aggregate functions.\n\nEXCEPT and UNION have the same operation precedence and INTERSECT has a higher precedence, unless running in Oracle mode, in which case all three have the same precedence.\n\nALL/DISTINCT\n\nThe ALL keyword causes duplicate rows to be preserved. The DISTINCT keyword (the default if the keyword is omitted) causes duplicate rows to be removed by the results.\n\nUNION ALL and UNION DISTINCT can both be present in a query. In this case, UNION DISTINCT will override any UNION ALL to its left.\n\nThe server can in most cases execute UNION ALL without creating a temporary table (see MDEV-334).\n\nORDER BY and LIMIT\n\nIndividual SELECT statements can contain their own ORDER BY and LIMIT clauses. In this case, the individual queries need to be wrapped between parentheses. However, this does not affect the order of the UNION, so they only are useful to limit the record read by one SELECT.\n\nThe UNION can have global ORDER BY and LIMIT clauses, which affect the whole result set. If the columns retrieved by individual SELECT statements have an alias (AS), the ORDER BY must use that alias, not the real column names.\n\nHIGH_PRIORITY\n\nSpecifying a query as HIGH_PRIORITY does not work inside a UNION. If applied to the first SELECT, it is ignored. Applying to a later SELECT results in a syntax error:\n\n``sql\nERROR 1234 (42000): Incorrect usage/placement of ''HIGH_PRIORITY''\n`\n\nSELECT ... INTO ...\n\nIndividual SELECT statements cannot be written INTO DUMPFILE or INTO OUTFILE. If the last SELECT statement specifies INTO DUMPFILE or INTO OUTFILE, the entire result of the UNION will be written. Placing the clause after any other SELECT` will result in a syntax error.\n\nIf the result is a single row, SELECT ... INTO @var_name can also be used.\n\nParentheses\n\nParentheses can be used to specify precedence.\n\nParentheses cannot be used to specify precedence.\n\nExamples\n--------\n\n(SELECT e_name AS name, email FROM employees)\nUNION\n(SELECT c_name AS name, email FROM customers);\n\nURL: https://mariadb.com/docs/server/reference/sql-statements/data-manipulation/selecting-data/set-operations/union', '', 'https://mariadb.com/docs/server/reference/sql-statements/data-manipulation/selecting-data/set-operations/union');
INSERT INTO help_topic (help_topic_id, help_category_id, name, description, example, url) VALUES (696, 27, 'Subqueries with IN and NOT IN', 'Description\n-----------\n\nThe IN operator tests whether a value is a member of a set of values returned by a subquery. It is the most commonly used construct for equality-based subquery comparisons in MariaDB.\n\nWhile IN is logically related to the ANY and SOME operators, it has distinct semantics and receives specialized treatment from the query optimizer.\n\nSyntax\n\n``sql\nscalar_expression [NOT] IN (subquery)\n`\n\n scalar_expression: An expression that evaluates to a single value.\n subquery: A subquery that returns a single column.\n\nRelationship to ANY and SOME\n\nIn MariaDB, IN is a synonym for = ANY.\n\n IN evaluates to TRUE if the comparison returns TRUE for at least one row produced by the subquery.\n IN evaluates to FALSE if the subquery returns no rows.\n\nDespite this logical equivalence, the optimizer applies additional transformations to IN subqueries (such as semi-joins) that do not always apply to other quantitative ANY comparisons like > ANY or <= SOME.\n\nHandling NULL Values\n\nThe behavior of IN and NOT IN follows SQL three-valued logic.\n\n Source Expression is NULL: If the scalar_expression is NULL, the result is NULL.\n Subquery Contains NULL (IN): If no match is found and the subquery contains at least one NULL, the result is NULL.\n Subquery Contains NULL (NOT IN): If the subquery returns any NULL value, NOT IN will always evaluate to NULL or FALSE, never TRUE, even if no matching non-null value exists.\n\nAvoid using NOT IN if the subquery columns can contain NULL values. In such cases, NOT EXISTS is generally safer and more predictable.\n\nNOT IN vs. <> ANY\n\nNOT IN and <> ANY are not synonyms and represent different logical tests:\n\n| OperatorText | Logical MeaningText                                         | ResultText                                                                               |\n| ------------ | ----------------------------------------------------------- | ---------------------------------------------------------------------------------------- |\n| NOT IN     | "Is this value absent from the entire set?"                 | Returns TRUE only if the value matches no rows in the subquery.                        |\n| <> ANY     | "Is there at least one value in the set that is different?" | Returns TRUE if there is at least one row in the subquery that differs from the value. |\n\nOptimization and Performance\n\nMariaDB treats IN` subqueries as high-priority candidates for specific optimizations, including:\n\n Semi-join transformations: Converting the subquery into a join to improve execution speed.\n Subquery materialization: Storing the subquery result in a temporary internal table to avoid repeated execution.\n IN-to-EXISTS rewrites: Converting the predicate based on cost estimates.\n\nExamples\n--------\n\nSELECT * FROM sq1 WHERE num1 IN (SELECT num2 FROM sq2);\n\nURL: https://mariadb.com/docs/server/reference/sql-statements/data-manipulation/selecting-data/subqueries/subqueries-with-in-and-not-in', '', 'https://mariadb.com/docs/server/reference/sql-statements/data-manipulation/selecting-data/subqueries/subqueries-with-in-and-not-in');
INSERT INTO help_topic (help_topic_id, help_category_id, name, description, example, url) VALUES (697, 34, 'BUFFER', 'Description\n-----------\n\nA synonym for ST_BUFFER.\n\nURL: https://mariadb.com/docs/server/reference/sql-statements/geometry-constructors/geometry-constructors/buffer', '', 'https://mariadb.com/docs/server/reference/sql-statements/geometry-constructors/geometry-constructors/buffer');
INSERT INTO help_topic (help_topic_id, help_category_id, name, description, example, url) VALUES (698, 34, 'CONVEXHULL', 'Description\n-----------\n\nA synonym for ST_CONVEXHULL.\n\nURL: https://mariadb.com/docs/server/reference/sql-statements/geometry-constructors/geometry-constructors/convexhull', '', 'https://mariadb.com/docs/server/reference/sql-statements/geometry-constructors/geometry-constructors/convexhull');
INSERT INTO help_topic (help_topic_id, help_category_id, name, description, example, url) VALUES (699, 34, 'ST\\_AsGeoJSON', 'Syntax\n------\n\nST_AsGeoJSON(g[, max_decimals[, options]])\n\nDescription\n-----------\n\nReturns the given geometry _g_ as a GeoJSON element. The optional _max_decimals_ limits the maximum number of decimals displayed.\n\nThe optional _options_ flag can be set to 1 to add a bounding box to the output.\n\nExamples\n--------\n\nSELECT ST_AsGeoJSON(ST_GeomFromText(''POINT(5.3 7.2)''));\n+-------------------------------------------------+\n| ST_AsGeoJSON(ST_GeomFromText(''POINT(5.3 7.2)'')) |\n+-------------------------------------------------+\n| {"type": "Point", "coordinates": [5.3, 7.2]}    |\n+-------------------------------------------------+\n\nURL: https://mariadb.com/docs/server/reference/sql-statements/geometry-constructors/geometry-constructors/geojson-st_asgeojson', '', 'https://mariadb.com/docs/server/reference/sql-statements/geometry-constructors/geometry-constructors/geojson-st_asgeojson');
INSERT INTO help_topic (help_topic_id, help_category_id, name, description, example, url) VALUES (700, 34, 'GEOMETRYCOLLECTION', 'Syntax\n------\n\nGeometryCollection(g1,g2,...)\n\nDescription\n-----------\n\nConstructs a WKB GeometryCollection. If any argument is not a well-formed WKB representation of a geometry, the return value is NULL.\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/geometry-constructors/geometrycollection', '', 'https://mariadb.com/docs/server/reference/sql-statements/geometry-constructors/geometry-constructors/geometrycollection');
INSERT INTO help_topic (help_topic_id, help_category_id, name, description, example, url) VALUES (701, 34, 'LINESTRING', 'Syntax\n------\n\nLineString(pt1,pt2,...)\n\nDescription\n-----------\n\nWKB LineString from WKB Point coordinate data.\\\nConstructs a WKB LineString value from a number of WKB Point arguments. If any argument is not a WKB Point, the return value isNULL. If the number of Point arguments is less than two, the return value is NULL.\n\nExamples\n--------\n\nSET @ls = ''LineString(1 1,2 2,3 3)'';\n\nSELECT AsText(EndPoint(GeomFromText(@ls)));\n+-------------------------------------+\n| AsText(EndPoint(GeomFromText(@ls))) |\n+-------------------------------------+\n| POINT(3 3)                          |\n+-------------------------------------+\n\nCREATE TABLE gis_line  (g LINESTRING);\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/geometry-constructors/linestring', '', 'https://mariadb.com/docs/server/reference/sql-statements/geometry-constructors/geometry-constructors/linestring');
INSERT INTO help_topic (help_topic_id, help_category_id, name, description, example, url) VALUES (702, 34, 'MULTILINESTRING', 'Syntax\n------\n\nMultiLineString(ls1,ls2,...)\n\nDescription\n-----------\n\nConstructs a WKB MultiLineString value using WKB LineString arguments. If any argument is not a WKB LineString, the return value isNULL.\n\nExamples\n--------\n\nCREATE TABLE gis_multi_line (g MULTILINESTRING);\nINSERT INTO gis_multi_line VALUES\n (MultiLineStringFromText(''MULTILINESTRING((10 48,10 21,10 0),(16 0,16 23,16 48))'')),\n (MLineFromText(''MULTILINESTRING((10 48,10 21,10 0))'')),\n (MLineFromWKB(AsWKB(MultiLineString(LineString(Point(1, 2), \n    Point(3, 5)), LineString(Point(2, 5),Point(5, 8),Point(21, 7))))));\n\nURL: https://mariadb.com/docs/server/reference/sql-statements/geometry-constructors/geometry-constructors/multilinestring', '', 'https://mariadb.com/docs/server/reference/sql-statements/geometry-constructors/geometry-constructors/multilinestring');
INSERT INTO help_topic (help_topic_id, help_category_id, name, description, example, url) VALUES (703, 34, 'MULTIPOINT', 'Syntax\n------\n\nMultiPoint(pt1,pt2,...)\n\nDescription\n-----------\n\nConstructs a WKB MultiPoint value using WKB Point arguments. If any argument is not a WKB Point, the return value is NULL.\n\nExamples\n--------\n\nSET @g = ST_GEOMFROMTEXT(''MultiPoint( 1 1, 2 2, 5 3, 7 2, 9 3, 8 4, 6 6, 6 9, 4 9, 1 5 )'');\n\nCREATE TABLE gis_multi_point (g MULTIPOINT);\nINSERT INTO gis_multi_point VALUES\n    (MultiPointFromText(''MULTIPOINT(0 0,10 10,10 20,20 20)'')),\n    (MPointFromText(''MULTIPOINT(1 1,11 11,11 21,21 21)'')),\n    (MPointFromWKB(AsWKB(MultiPoint(Point(3, 6), Point(4, 10)))));\n\nURL: https://mariadb.com/docs/server/reference/sql-statements/geometry-constructors/geometry-constructors/multipoint', '', 'https://mariadb.com/docs/server/reference/sql-statements/geometry-constructors/geometry-constructors/multipoint');
INSERT INTO help_topic (help_topic_id, help_category_id, name, description, example, url) VALUES (704, 34, 'MULTIPOLYGON', 'Syntax\n------\n\nMultiPolygon(poly1,poly2,...)\n\nDescription\n-----------\n\nConstructs a WKB MultiPolygon value from a set of WKB Polygon arguments. If any argument is not a WKB Polygon, the return value is NULL.\n\nExamples\n--------\n\nCREATE TABLE gis_multi_polygon  (g MULTIPOLYGON);\nINSERT INTO gis_multi_polygon VALUES\n    (MultiPolygonFromText(''MULTIPOLYGON(((28 26,28 0,84 0,84 42,28 26),(52 18,66 23,73 9,48 6,52 18)),\n     ((59 18,67 18,67 13,59 13,59 18)))'')),\n    (MPolyFromText(''MULTIPOLYGON(((28 26,28 0,84 0,84 42,28 26),(52 18,66 23,73 9,48 6,52 18)),\n        ((59 18,67 18,67 13,59 13,59 18)))'')),\n    (MPolyFromWKB(AsWKB(MultiPolygon(Polygon(LineString(\n       Point(0, 3), Point(3, 3), Point(3, 0), Point(0, 3)))))));\n\nURL: https://mariadb.com/docs/server/reference/sql-statements/geometry-constructors/geometry-constructors/multipolygon', '', 'https://mariadb.com/docs/server/reference/sql-statements/geometry-constructors/geometry-constructors/multipolygon');
INSERT INTO help_topic (help_topic_id, help_category_id, name, description, example, url) VALUES (705, 34, 'POINT', 'Syntax\n------\n\nPoint(x,y)\n\nDescription\n-----------\n\nConstructs a WKB Point using the given coordinates.\n\nExamples\n--------\n\nSET @g = ST_GEOMFROMTEXT(''Point(1 1)'');\n\nCREATE TABLE gis_point  (g 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/geometry-constructors/point', '', 'https://mariadb.com/docs/server/reference/sql-statements/geometry-constructors/geometry-constructors/point');
INSERT INTO help_topic (help_topic_id, help_category_id, name, description, example, url) VALUES (706, 34, 'PointOnSurface', 'Description\n-----------\n\nA synonym for ST_PointOnSurface.\n\nURL: https://mariadb.com/docs/server/reference/sql-statements/geometry-constructors/geometry-constructors/pointonsurface', '', 'https://mariadb.com/docs/server/reference/sql-statements/geometry-constructors/geometry-constructors/pointonsurface');
INSERT INTO help_topic (help_topic_id, help_category_id, name, description, example, url) VALUES (707, 34, 'POLYGON', 'Syntax\n------\n\nPolygon(ls1,ls2,...)\n\nDescription\n-----------\n\nConstructs a WKB Polygon value from a number of WKB LineString\\\narguments. If any argument does not represent the WKB of a LinearRing (that is,\\\nnot a closed and simple LineString) the return value is NULL.\n\nNote that according to the OpenGIS standard, a POLYGON should have exactly one ExteriorRing and all other rings should lie within that ExteriorRing and thus be the InteriorRings. Practically, however, some systems, including MariaDB''s, permit polygons to have several ''ExteriorRings''. In the case of there being multiple, non-overlapping exterior rings ST_NUMINTERIORRINGS() will return 1.\n\nExamples\n--------\n\nSET @g = ST_GEOMFROMTEXT(''POLYGON((1 1,1 5,4 9,6 9,9 3,7 2,1 1))'');\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    (PolyFromWKB(AsWKB(Polygon(LineString(Point(0, 0), Point(30, 0), Point(30, 30), Point(0, 0))))));\n\nURL: https://mariadb.com/docs/server/reference/sql-statements/geometry-constructors/geometry-constructors/polygon', '', 'https://mariadb.com/docs/server/reference/sql-statements/geometry-constructors/geometry-constructors/polygon');
INSERT INTO help_topic (help_topic_id, help_category_id, name, description, example, url) VALUES (708, 34, 'ST\\_BUFFER', 'Syntax\n------\n\nST_BUFFER(g1,r)\nBUFFER(g1,r)\n\nDescription\n-----------\n\nReturns a geometry that represents all points whose distance from geometry _g1_ is less than or equal to distance, or radius, _r_.\n\nUses for this function could include creating for example a new geometry representing a buffer zone around an island.\n\nBUFFER() is a synonym.\n\nExamples\n--------\n\nSET @g1 = ST_GEOMFROMTEXT(''POLYGON((10 10, 10 20, 20 20, 20 10, 10 10))'');\n\nSET @g2 = ST_GEOMFROMTEXT(''POINT(8 8)'');\n\nSELECT ST_WITHIN(@g2,ST_BUFFER(@g1,5));\n+---------------------------------+\n| ST_WITHIN(@g2,ST_BUFFER(@g1,5)) |\n+---------------------------------+\n|                               1 |\n+---------------------------------+\n\nSELECT ST_WITHIN(@g2,ST_BUFFER(@g1,1));\n+---------------------------------+\n| ST_WITHIN(@g2,ST_BUFFER(@g1,1)) |\n+---------------------------------+\n|                               0 |\n+---------------------------------+\n\nURL: https://mariadb.com/docs/server/reference/sql-statements/geometry-constructors/geometry-constructors/st_buffer', '', 'https://mariadb.com/docs/server/reference/sql-statements/geometry-constructors/geometry-constructors/st_buffer');
INSERT INTO help_topic (help_topic_id, help_category_id, name, description, example, url) VALUES (709, 34, 'ST\\_CONVEXHULL', 'Syntax\n------\n\nST_ConvexHull(g)\nConvexHull(g)\n\nDescription\n-----------\n\nGiven a geometry, returns a geometry that is the minimum convex geometry enclosing all geometries within the set. Returns NULL if the geometry value is NULL or an empty value.\n\nST_ConvexHull() and ConvexHull() are synonyms.\n\nExamples\n--------\n\nSET @g = ST_GEOMFROMTEXT(''Point(0 0)'');\n\nSELECT ST_ASTEXT(ST_CONVEXHULL(@g));\n+------------------------------+\n| ST_ASTEXT(ST_CONVEXHULL(@g)) |\n+------------------------------+\n| POINT(0 0)                   |\n+------------------------------+\n\nURL: https://mariadb.com/docs/server/reference/sql-statements/geometry-constructors/geometry-constructors/st_convexhull', '', 'https://mariadb.com/docs/server/reference/sql-statements/geometry-constructors/geometry-constructors/st_convexhull');
INSERT INTO help_topic (help_topic_id, help_category_id, name, description, example, url) VALUES (710, 34, 'ST\\_GeomFromGeoJSON', 'Syntax\n------\n\nST_GeomFromGeoJSON(g[, option])\n\nDescription\n-----------\n\nGiven a GeoJSON input _g_, returns a geometry object. The _option_ specifies what to do if _g_ contains geometries with coordinate dimensions higher than 2.\n\n| Option | Description                                                                                      |\n| ------ | ------------------------------------------------------------------------------------------------ |\n| 1      | Return an error (the default)                                                                    |\n| 2 - 4  | The document is accepted, but the coordinates for higher coordinate dimensions are stripped off. |\n\nExamples\n--------\n\nSET @j = ''{ "type": "Point", "coordinates": [5.3, 15.0]}'';\n\nSELECT ST_AsText(ST_GeomFromGeoJSON(@j));\n+-----------------------------------+\n| ST_AsText(ST_GeomFromGeoJSON(@j)) |\n+-----------------------------------+\n| POINT(5.3 15)                     |\n+-----------------------------------+\n\nURL: https://mariadb.com/docs/server/reference/sql-statements/geometry-constructors/geometry-constructors/st_geomfromgeojson', '', 'https://mariadb.com/docs/server/reference/sql-statements/geometry-constructors/geometry-constructors/st_geomfromgeojson');
INSERT INTO help_topic (help_topic_id, help_category_id, name, description, example, url) VALUES (711, 34, 'ST\\_INTERSECTION', 'Syntax\n------\n\nST_INTERSECTION(g1,g2)\n\nDescription\n-----------\n\nReturns a geometry that is the intersection, or shared portion, of geometry _g1_ and geometry _g2_.\n\nExamples\n--------\n\nSET @g1 = ST_GEOMFROMTEXT(''POINT(2 1)'');\n\nSET @g2 = ST_GEOMFROMTEXT(''LINESTRING(2 1, 0 2)'');\n\nSELECT ASTEXT(ST_INTERSECTION(@g1,@g2));\n+----------------------------------+\n| ASTEXT(ST_INTERSECTION(@g1,@g2)) |\n+----------------------------------+\n| POINT(2 1)                       |\n+----------------------------------+\n\nURL: https://mariadb.com/docs/server/reference/sql-statements/geometry-constructors/geometry-constructors/st_intersection', '', 'https://mariadb.com/docs/server/reference/sql-statements/geometry-constructors/geometry-constructors/st_intersection');
INSERT INTO help_topic (help_topic_id, help_category_id, name, description, example, url) VALUES (712, 34, 'ST\\_POINTONSURFACE', 'Syntax\n------\n\nST_PointOnSurface(g)\nPointOnSurface(g)\n\nDescription\n-----------\n\nGiven a geometry, returns a POINT guaranteed to intersect a surface. However, see MDEV-7514.\n\nST_PointOnSurface() and PointOnSurface() are synonyms.\n\nURL: https://mariadb.com/docs/server/reference/sql-statements/geometry-constructors/geometry-constructors/st_pointonsurface', '', 'https://mariadb.com/docs/server/reference/sql-statements/geometry-constructors/geometry-constructors/st_pointonsurface');
INSERT INTO help_topic (help_topic_id, help_category_id, name, description, example, url) VALUES (713, 34, 'ST\\_SYMDIFFERENCE', 'Syntax\n------\n\nST_SYMDIFFERENCE(g1,g2)\n\nDescription\n-----------\n\nReturns a geometry that represents the portions of geometry _g1_ and geometry _g2_ that don''t intersect.\n\nExamples\n--------\n\nSET @g1 = ST_GEOMFROMTEXT(''LINESTRING(10 20, 10 40)'');\n\nSET @g2 = ST_GEOMFROMTEXT(''LINESTRING(10 15, 10 25)'');\n\nSELECT ASTEXT(ST_SYMDIFFERENCE(@g1,@g2));\n+----------------------------------------------+\n| ASTEXT(ST_SYMDIFFERENCE(@g1,@g2))            |\n+----------------------------------------------+\n| MULTILINESTRING((10 15,10 20),(10 25,10 40)) |\n+----------------------------------------------+\n\nSET @g2 = ST_GeomFromText(''LINESTRING(10 20, 10 41)'');\n\nSELECT ASTEXT(ST_SYMDIFFERENCE(@g1,@g2));\n+-----------------------------------+\n| ASTEXT(ST_SYMDIFFERENCE(@g1,@g2)) |\n+-----------------------------------+\n| LINESTRING(10 40,10 41)           |\n+-----------------------------------+\n\nURL: https://mariadb.com/docs/server/reference/sql-statements/geometry-constructors/geometry-constructors/st_symdifference', '', 'https://mariadb.com/docs/server/reference/sql-statements/geometry-constructors/geometry-constructors/st_symdifference');
INSERT INTO help_topic (help_topic_id, help_category_id, name, description, example, url) VALUES (714, 34, 'ST\\_UNION', 'Syntax\n------\n\nST_UNION(g1,g2)\n\nDescription\n-----------\n\nReturns a geometry that is the union of the geometry _g1_ and geometry _g2_.\n\nExamples\n--------\n\nSET @g1 = GEOMFROMTEXT(''POINT (0 2)'');\n\nSET @g2 = GEOMFROMTEXT(''POINT (2 0)'');\n\nSELECT ASTEXT(ST_UNION(@g1,@g2));\n+---------------------------+\n| ASTEXT(ST_UNION(@g1,@g2)) |\n+---------------------------+\n| MULTIPOINT(2 0,0 2)       |\n+---------------------------+\n\nURL: https://mariadb.com/docs/server/reference/sql-statements/geometry-constructors/geometry-constructors/st_union', '', 'https://mariadb.com/docs/server/reference/sql-statements/geometry-constructors/geometry-constructors/st_union');
INSERT INTO help_topic (help_topic_id, help_category_id, name, description, example, url) VALUES (715, 34, 'DIMENSION', 'Description\n-----------\n\nA synonym for ST_DIMENSION.\n\nURL: https://mariadb.com/docs/server/reference/sql-statements/geometry-constructors/geometry-properties/dimension', '', 'https://mariadb.com/docs/server/reference/sql-statements/geometry-constructors/geometry-properties/dimension');
INSERT INTO help_topic (help_topic_id, help_category_id, name, description, example, url) VALUES (716, 34, 'BOUNDARY', 'Description\n-----------\n\nA synonym for ST_BOUNDARY.\n\nURL: https://mariadb.com/docs/server/reference/sql-statements/geometry-constructors/geometry-properties/geometry-properties-boundary', '', 'https://mariadb.com/docs/server/reference/sql-statements/geometry-constructors/geometry-properties/geometry-properties-boundary');
INSERT INTO help_topic (help_topic_id, help_category_id, name, description, example, url) VALUES (717, 34, 'ENVELOPE', 'Description\n-----------\n\nA synonym for ST_ENVELOPE.\n\nURL: https://mariadb.com/docs/server/reference/sql-statements/geometry-constructors/geometry-properties/geometry-properties-envelope', '', 'https://mariadb.com/docs/server/reference/sql-statements/geometry-constructors/geometry-properties/geometry-properties-envelope');
INSERT INTO help_topic (help_topic_id, help_category_id, name, description, example, url) VALUES (718, 34, 'GeometryN', 'Description\n-----------\n\nA synonym for ST_GeometryN.\n\nURL: https://mariadb.com/docs/server/reference/sql-statements/geometry-constructors/geometry-properties/geometry-properties-geometryn', '', 'https://mariadb.com/docs/server/reference/sql-statements/geometry-constructors/geometry-properties/geometry-properties-geometryn');
INSERT INTO help_topic (help_topic_id, help_category_id, name, description, example, url) VALUES (719, 34, 'GeometryType', 'Description\n-----------\n\nA synonym for ST_GeometryType.\n\nURL: https://mariadb.com/docs/server/reference/sql-statements/geometry-constructors/geometry-properties/geometry-properties-geometrytype', '', 'https://mariadb.com/docs/server/reference/sql-statements/geometry-constructors/geometry-properties/geometry-properties-geometrytype');
INSERT INTO help_topic (help_topic_id, help_category_id, name, description, example, url) VALUES (720, 34, 'IsEmpty', 'Description\n-----------\n\nA synonym for ST_IsEmpty.\n\nURL: https://mariadb.com/docs/server/reference/sql-statements/geometry-constructors/geometry-properties/geometry-properties-isempty', '', 'https://mariadb.com/docs/server/reference/sql-statements/geometry-constructors/geometry-properties/geometry-properties-isempty');
INSERT INTO help_topic (help_topic_id, help_category_id, name, description, example, url) VALUES (721, 34, 'IsSimple', 'Description\n-----------\n\nA synonym for ST_IsSImple.\n\nURL: https://mariadb.com/docs/server/reference/sql-statements/geometry-constructors/geometry-properties/geometry-properties-issimple', '', 'https://mariadb.com/docs/server/reference/sql-statements/geometry-constructors/geometry-properties/geometry-properties-issimple');
INSERT INTO help_topic (help_topic_id, help_category_id, name, description, example, url) VALUES (722, 34, 'NumGeometries', 'Description\n-----------\n\nA synonym for ST_NumGeometries.\n\nURL: https://mariadb.com/docs/server/reference/sql-statements/geometry-constructors/geometry-properties/geometry-properties-numgeometries', '', 'https://mariadb.com/docs/server/reference/sql-statements/geometry-constructors/geometry-properties/geometry-properties-numgeometries');
INSERT INTO help_topic (help_topic_id, help_category_id, name, description, example, url) VALUES (723, 34, 'SRID', 'Description\n-----------\n\nA synonym for ST_SRID.\n\nURL: https://mariadb.com/docs/server/reference/sql-statements/geometry-constructors/geometry-properties/geometry-properties-srid', '', 'https://mariadb.com/docs/server/reference/sql-statements/geometry-constructors/geometry-properties/geometry-properties-srid');
INSERT INTO help_topic (help_topic_id, help_category_id, name, description, example, url) VALUES (724, 34, 'IsClosed', 'Description\n-----------\n\nA synonym for ST_IsClosed.\n\nURL: https://mariadb.com/docs/server/reference/sql-statements/geometry-constructors/geometry-properties/isclosed', '', 'https://mariadb.com/docs/server/reference/sql-statements/geometry-constructors/geometry-properties/isclosed');
INSERT INTO help_topic (help_topic_id, help_category_id, name, description, example, url) VALUES (725, 34, 'IsRing', 'Description\n-----------\n\nA synonym for ST_IsRing.\n\nURL: https://mariadb.com/docs/server/reference/sql-statements/geometry-constructors/geometry-properties/isring', '', 'https://mariadb.com/docs/server/reference/sql-statements/geometry-constructors/geometry-properties/isring');
INSERT INTO help_topic (help_topic_id, help_category_id, name, description, example, url) VALUES (726, 34, 'ST\\_BOUNDARY', 'Syntax\n------\n\nST_BOUNDARY(g)\nBOUNDARY(g)\n\nDescription\n-----------\n\nReturns a geometry that is the closure of the combinatorial boundary of the geometry value _g_.\n\nBOUNDARY() is a synonym.\n\nExamples\n--------\n\nSELECT ST_AsText(ST_Boundary(ST_GeomFromText(''LINESTRING(3 3,0 0, -3 3)'')));\n+----------------------------------------------------------------------+\n| ST_AsText(ST_Boundary(ST_GeomFromText(''LINESTRING(3 3,0 0, -3 3)''))) |\n+----------------------------------------------------------------------+\n| MULTIPOINT(3 3,-3 3)                                                 |\n+----------------------------------------------------------------------+\n\nSELECT ST_AsText(ST_Boundary(ST_GeomFromText(''POLYGON((3 3,0 0, -3 3, 3 3))'')));\n+--------------------------------------------------------------------------+\n| ST_AsText(ST_Boundary(ST_GeomFromText(''POLYGON((3 3,0 0, -3 3, 3 3))''))) |\n+--------------------------------------------------------------------------+\n| LINESTRING(3 3,0 0,-3 3,3 3)                                             |\n+--------------------------------------------------------------------------+\n\nURL: https://mariadb.com/docs/server/reference/sql-statements/geometry-constructors/geometry-properties/st_boundary', '', 'https://mariadb.com/docs/server/reference/sql-statements/geometry-constructors/geometry-properties/st_boundary');
INSERT INTO help_topic (help_topic_id, help_category_id, name, description, example, url) VALUES (727, 34, 'ST\\_DIMENSION', 'Syntax\n------\n\nST_Dimension(g)\nDimension(g)\n\nDescription\n-----------\n\nReturns the inherent dimension of the geometry value _g_. The result can\\\nbe\n\n| Dimension | Definition                               |\n| --------- | ---------------------------------------- |\n| -1        | empty geometry                           |\n| 0         | geometry with no length or area          |\n| 1         | geometry with no area but nonzero length |\n| 2         | geometry with nonzero area               |\n\nST_Dimension() and Dimension() are synonyms.\n\nExamples\n--------\n\nSELECT Dimension(GeomFromText(''LineString(1 1,2 2)''));\n+------------------------------------------------+\n| Dimension(GeomFromText(''LineString(1 1,2 2)'')) |\n+------------------------------------------------+\n|                                              1 |\n+------------------------------------------------+\n\nURL: https://mariadb.com/docs/server/reference/sql-statements/geometry-constructors/geometry-properties/st_dimension', '', 'https://mariadb.com/docs/server/reference/sql-statements/geometry-constructors/geometry-properties/st_dimension');
INSERT INTO help_topic (help_topic_id, help_category_id, name, description, example, url) VALUES (728, 34, 'ST\\_ENVELOPE', 'Syntax\n------\n\nST_ENVELOPE(g)\nENVELOPE(g)\n\nDescription\n-----------\n\nReturns the Minimum Bounding Rectangle (MBR) for the geometry value g. The result is returned as a Polygon value.\n\nThe polygon is defined by the corner points of the bounding box:\n\n``\nPOLYGON((MINX MINY, MAXX MINY, MAXX MAXY, MINX MAXY, MINX MINY))\n`\n\nST_ENVELOPE() and ENVELOPE()` are synonyms.\n\nExamples\n--------\n\nSELECT AsText(ST_ENVELOPE(GeomFromText(''LineString(1 1,4 4)'')));\n+----------------------------------------------------------+\n| AsText(ST_ENVELOPE(GeomFromText(''LineString(1 1,4 4)''))) |\n+----------------------------------------------------------+\n| POLYGON((1 1,4 1,4 4,1 4,1 1))                           |\n+----------------------------------------------------------+\n\nURL: https://mariadb.com/docs/server/reference/sql-statements/geometry-constructors/geometry-properties/st_envelope', '', 'https://mariadb.com/docs/server/reference/sql-statements/geometry-constructors/geometry-properties/st_envelope');
INSERT INTO help_topic (help_topic_id, help_category_id, name, description, example, url) VALUES (729, 34, 'ST\\_GEOMETRYN', 'Syntax\n------\n\nST_GeometryN(gc,N)\nGeometryN(gc,N)\n\nDescription\n-----------\n\nReturns the N-th geometry in the GeometryCollection _gc._ Geometries are numbered beginning with 1.\n\nST_GeometryN() and GeometryN() are synonyms.\n\nExamples\n--------\n\nSET @gc = ''GeometryCollection(Point(1 1),LineString(12 14, 9 11))'';\n\nSELECT AsText(GeometryN(GeomFromText(@gc),1));\n+----------------------------------------+\n| AsText(GeometryN(GeomFromText(@gc),1)) |\n+----------------------------------------+\n| POINT(1 1)                             |\n+----------------------------------------+\n\nURL: https://mariadb.com/docs/server/reference/sql-statements/geometry-constructors/geometry-properties/st_geometryn', '', 'https://mariadb.com/docs/server/reference/sql-statements/geometry-constructors/geometry-properties/st_geometryn');
INSERT INTO help_topic (help_topic_id, help_category_id, name, description, example, url) VALUES (730, 34, 'ST\\_GEOMETRYTYPE', 'Syntax\n------\n\nST_GeometryType(g)\nGeometryType(g)\n\nDescription\n-----------\n\nReturns as a string the name of the geometry type of which the geometry instance g is a member. The name corresponds to one of the instantiable Geometry subclasses.\n\nST_GeometryType() and GeometryType() are synonyms.\n\nExamples\n--------\n\nSELECT GeometryType(GeomFromText(''POINT(1 1)''));\n+------------------------------------------+\n| GeometryType(GeomFromText(''POINT(1 1)'')) |\n+------------------------------------------+\n| POINT                                    |\n+------------------------------------------+\n\nURL: https://mariadb.com/docs/server/reference/sql-statements/geometry-constructors/geometry-properties/st_geometrytype', '', 'https://mariadb.com/docs/server/reference/sql-statements/geometry-constructors/geometry-properties/st_geometrytype');
INSERT INTO help_topic (help_topic_id, help_category_id, name, description, example, url) VALUES (731, 34, 'ST\\_ISCLOSED', 'Syntax\n------\n\nST_IsClosed(g)\nIsClosed(g)\n\nDescription\n-----------\n\nReturns 1 if a given LINESTRING''s start and end points are the same, or 0 if they are not the same.\n\nST_IsClosed() and IsClosed() are synonyms.\n\nExamples\n--------\n\nSET @ls = ''LineString(0 0, 0 4, 4 4, 0 0)'';\nSELECT ST_ISCLOSED(GEOMFROMTEXT(@ls));\n+--------------------------------+\n| ST_ISCLOSED(GEOMFROMTEXT(@ls)) |\n+--------------------------------+\n|                              1 |\n+--------------------------------+\n\nSET @ls = ''LineString(0 0, 0 4, 4 4, 0 1)'';\nSELECT ST_ISCLOSED(GEOMFROMTEXT(@ls));\n+--------------------------------+\n| ST_ISCLOSED(GEOMFROMTEXT(@ls)) |\n+--------------------------------+\n|                              0 |\n+--------------------------------+\n\nURL: https://mariadb.com/docs/server/reference/sql-statements/geometry-constructors/geometry-properties/st_isclosed', '', 'https://mariadb.com/docs/server/reference/sql-statements/geometry-constructors/geometry-properties/st_isclosed');
INSERT INTO help_topic (help_topic_id, help_category_id, name, description, example, url) VALUES (732, 34, 'ST\\_ISEMPTY', 'Syntax\n------\n\nST_IsEmpty(g)\nIsEmpty(g)\n\nDescription\n-----------\n\nIsEmpty is a function defined by the OpenGIS specification, but is not fully implemented by MariaDB or MySQL.\n\nSince MariaDB and MySQL do not support GIS EMPTY values such as POINT EMPTY, as implemented it simply returns 1 if the geometry value _g_ is invalid, 0 if it is valid, and NULL if the argument is NULL.\n\nST_IsEmpty() and IsEmpty() are synonyms.\n\nURL: https://mariadb.com/docs/server/reference/sql-statements/geometry-constructors/geometry-properties/st_isempty', '', 'https://mariadb.com/docs/server/reference/sql-statements/geometry-constructors/geometry-properties/st_isempty');
INSERT INTO help_topic (help_topic_id, help_category_id, name, description, example, url) VALUES (733, 34, 'ST\\_IsRing', 'Syntax\n------\n\nST_IsRing(g)\nIsRing(g)\n\nDescription\n-----------\n\nReturns true if a given LINESTRING is a ring, that is, both ST_IsClosed and ST_IsSimple. A simple curve does not pass through the same point more than once. However, see MDEV-7510.\n\nSt_IsRing() and IsRing() are synonyms.\n\nURL: https://mariadb.com/docs/server/reference/sql-statements/geometry-constructors/geometry-properties/st_isring', '', 'https://mariadb.com/docs/server/reference/sql-statements/geometry-constructors/geometry-properties/st_isring');
INSERT INTO help_topic (help_topic_id, help_category_id, name, description, example, url) VALUES (734, 34, 'ST\\_IsSimple', 'Syntax\n------\n\nST_IsSimple(g)\nIsSimple(g)\n\nDescription\n-----------\n\nReturns true if the given Geometry has no anomalous geometric points, false if it does, or NULL if given a NULL value.\n\nST_IsSimple() and IsSimple() are synonyms.\n\nExamples\n--------\n\nSET @g = ''Point(1 2)'';\n\nSELECT ST_ISSIMPLE(GEOMFROMTEXT(@g));\n+-------------------------------+\n| ST_ISSIMPLE(GEOMFROMTEXT(@g)) |\n+-------------------------------+\n|                             1 |\n+-------------------------------+\n\nURL: https://mariadb.com/docs/server/reference/sql-statements/geometry-constructors/geometry-properties/st_issimple', '', 'https://mariadb.com/docs/server/reference/sql-statements/geometry-constructors/geometry-properties/st_issimple');
INSERT INTO help_topic (help_topic_id, help_category_id, name, description, example, url) VALUES (735, 34, 'ST\\_NUMGEOMETRIES', 'Syntax\n------\n\nST_NumGeometries(gc)\nNumGeometries(gc)\n\nDescription\n-----------\n\nReturns the number of geometries in the GeometryCollection gc.\n\nST_NumGeometries() and NumGeometries() are synonyms.\n\nExamples\n--------\n\nSET @gc = ''GeometryCollection(Point(1 1),LineString(2 2, 3 3))'';\n\nSELECT NUMGEOMETRIES(GeomFromText(@gc));\n+----------------------------------+\n| NUMGEOMETRIES(GeomFromText(@gc)) |\n+----------------------------------+\n|                                2 |\n+----------------------------------+\n\nURL: https://mariadb.com/docs/server/reference/sql-statements/geometry-constructors/geometry-properties/st_numgeometries', '', 'https://mariadb.com/docs/server/reference/sql-statements/geometry-constructors/geometry-properties/st_numgeometries');
INSERT INTO help_topic (help_topic_id, help_category_id, name, description, example, url) VALUES (736, 34, 'ST\\_RELATE', 'Syntax\n------\n\nST_Relate(g1, g2, i)\n\nDescription\n-----------\n\nReturns true if Geometry g1 is spatially related to Geometryg2 by testing for intersections between the interior, boundary and exterior of the two geometries as specified by the values in intersection matrix pattern i.\n\nURL: https://mariadb.com/docs/server/reference/sql-statements/geometry-constructors/geometry-properties/st_relate', '', 'https://mariadb.com/docs/server/reference/sql-statements/geometry-constructors/geometry-properties/st_relate');
INSERT INTO help_topic (help_topic_id, help_category_id, name, description, example, url) VALUES (737, 34, 'ST\\_SRID', 'Syntax\n------\n\nST_SRID(g)\nSRID(g)\n\nDescription\n-----------\n\nReturns an integer indicating the Spatial Reference System ID for the geometry value g.\n\nIn MariaDB, the SRID value is just an integer associated with the geometry value. All calculations are done assuming Euclidean (planar) geometry.\n\nST_SRID() and SRID() are synonyms.\n\nExamples\n--------\n\nSELECT SRID(GeomFromText(''LineString(1 1,2 2)'',101));\n+-----------------------------------------------+\n| SRID(GeomFromText(''LineString(1 1,2 2)'',101)) |\n+-----------------------------------------------+\n|                                           101 |\n+-----------------------------------------------+\n\nURL: https://mariadb.com/docs/server/reference/sql-statements/geometry-constructors/geometry-properties/st_srid', '', 'https://mariadb.com/docs/server/reference/sql-statements/geometry-constructors/geometry-properties/st_srid');
INSERT INTO help_topic (help_topic_id, help_category_id, name, description, example, url) VALUES (738, 34, 'CONTAINS', 'Syntax\n------\n\nContains(g1,g2)\n\nDescription\n-----------\n\nReturns 1 or 0 to indicate whether a geometry g1 completely contains geometry g2. CONTAINS() is based on the original MySQL implementation and uses object bounding rectangles, while ST_CONTAINS() uses object shapes.\n\nThis tests the opposite relationship to Within().\n\nURL: https://mariadb.com/docs/server/reference/sql-statements/geometry-constructors/geometry-relations/contains', '', 'https://mariadb.com/docs/server/reference/sql-statements/geometry-constructors/geometry-relations/contains');
INSERT INTO help_topic (help_topic_id, help_category_id, name, description, example, url) VALUES (739, 34, 'CROSSES', 'Syntax\n------\n\nCrosses(g1,g2)\n\nDescription\n-----------\n\nReturns 1 if g1 spatially crosses g2. Returns NULL if g1 is a Polygon or a MultiPolygon, or if g2 is a Point or a MultiPoint. Otherwise, returns 0.\n\nThe term spatially crosses denotes a spatial relation between two given geometries that has the following properties:\n\n The two geometries intersect.\n Their intersection results in a geometry that has a dimension that is one less than the maximum dimension of the two given geometries.\n* Their intersection is not equal to either of the two given geometries.\n\nCROSSES() is based on the original MySQL implementation, and uses object bounding rectangles, while ST_CROSSES() uses object shapes.\n\nURL: https://mariadb.com/docs/server/reference/sql-statements/geometry-constructors/geometry-relations/crosses', '', 'https://mariadb.com/docs/server/reference/sql-statements/geometry-constructors/geometry-relations/crosses');
INSERT INTO help_topic (help_topic_id, help_category_id, name, description, example, url) VALUES (740, 34, 'DISJOINT', 'Syntax\n------\n\nDisjoint(g1,g2)\n\nDescription\n-----------\n\nReturns 1 or 0 to indicate whether g1 is spatially disjoint from (does not intersect) g2.\n\nDISJOINT() tests the opposite relationship to INTERSECTS().\n\nDISJOINT() is based on the original MySQL implementation and uses object bounding rectangles, while ST_DISJOINT() uses object shapes.\n\nURL: https://mariadb.com/docs/server/reference/sql-statements/geometry-constructors/geometry-relations/disjoint', '', 'https://mariadb.com/docs/server/reference/sql-statements/geometry-constructors/geometry-relations/disjoint');
INSERT INTO help_topic (help_topic_id, help_category_id, name, description, example, url) VALUES (741, 34, 'EQUALS', 'Syntax\n------\n\nMBREQUALS(g1,g2)\n\nDescription\n-----------\n\nReturns 1 or 0 to indicate whether _g1_ is spatially equal to _g2_.\n\nEQUALS() is based on the original MySQL implementation and uses object bounding rectangles, while ST_EQUALS() uses object shapes.\n\nMBREQUALS is a synonym for Equals.\n\nURL: https://mariadb.com/docs/server/reference/sql-statements/geometry-constructors/geometry-relations/equals', '', 'https://mariadb.com/docs/server/reference/sql-statements/geometry-constructors/geometry-relations/equals');
INSERT INTO help_topic (help_topic_id, help_category_id, name, description, example, url) VALUES (742, 34, 'INTERSECTS', 'Syntax\n------\n\nINTERSECTS(g1,g2)\n\nDescription\n-----------\n\nReturns 1 or 0 to indicate whether geometry _g1_ spatially intersects geometry _g2_.\n\nINTERSECTS() is based on the original MySQL implementation and uses object bounding rectangles, while ST_INTERSECTS() uses object shapes.\n\nINTERSECTS() tests the opposite relationship to DISJOINT().\n\nURL: https://mariadb.com/docs/server/reference/sql-statements/geometry-constructors/geometry-relations/intersects', '', 'https://mariadb.com/docs/server/reference/sql-statements/geometry-constructors/geometry-relations/intersects');
INSERT INTO help_topic (help_topic_id, help_category_id, name, description, example, url) VALUES (743, 34, 'OVERLAPS', 'Syntax\n------\n\nOVERLAPS(g1,g2)\n\nDescription\n-----------\n\nReturns 1 or 0 to indicate whether g1 spatially overlaps g2.\\\nThe term spatially overlaps is used if two geometries of equal dimensions intersect and their intersection results in a geometry of the same dimension but not equal to either of the given geometries.\n\nOVERLAPS() is based on the original MySQL implementation and uses object bounding rectangles, while ST_OVERLAPS() uses object shapes.\n\nURL: https://mariadb.com/docs/server/reference/sql-statements/geometry-constructors/geometry-relations/overlaps', '', 'https://mariadb.com/docs/server/reference/sql-statements/geometry-constructors/geometry-relations/overlaps');
INSERT INTO help_topic (help_topic_id, help_category_id, name, description, example, url) VALUES (744, 34, 'ST\\_CONTAINS', 'Syntax\n------\n\nST_CONTAINS(g1,g2)\n\nDescription\n-----------\n\nReturns 1 or 0 to indicate whether a geometry g1 completely contains geometry g2.\n\nST_CONTAINS() uses object shapes, while CONTAINS(), based on the original MySQL implementation, uses object bounding rectangles.\n\nST_CONTAINS tests the opposite relationship to ST_WITHIN().\n\nExamples\n--------\n\nSET @g1 = ST_GEOMFROMTEXT(''POLYGON((175 150, 20 40, 50 60, 125 100, 175 150))'');\n\nSET @g2 = ST_GEOMFROMTEXT(''POINT(174 149)'');\n\nSELECT ST_CONTAINS(@g1,@g2);\n+----------------------+\n| ST_CONTAINS(@g1,@g2) |\n+----------------------+\n|                    1 |\n+----------------------+\n\nSET @g2 = ST_GEOMFROMTEXT(''POINT(175 151)'');\n\nSELECT ST_CONTAINS(@g1,@g2);\n+----------------------+\n| ST_CONTAINS(@g1,@g2) |\n+----------------------+\n|                    0 |\n+----------------------+\n\nURL: https://mariadb.com/docs/server/reference/sql-statements/geometry-constructors/geometry-relations/st-contains', '', 'https://mariadb.com/docs/server/reference/sql-statements/geometry-constructors/geometry-relations/st-contains');
INSERT INTO help_topic (help_topic_id, help_category_id, name, description, example, url) VALUES (745, 34, 'ST\\_CROSSES', 'Syntax\n------\n\nST_CROSSES(g1,g2)\n\nDescription\n-----------\n\nReturns 1 if geometry _g1_ spatially crosses geometry _g2_. Returns NULL if g1 is a Polygon or a MultiPolygon, or if g2 is a Point or a MultiPoint. Otherwise, returns 0.\n\nThe term spatially crosses denotes a spatial relation between two given geometries that has the following properties:\n\n The two geometries intersect.\n Their intersection results in a geometry that has a dimension that is one less than the maximum dimension of the two given geometries.\n* Their intersection is not equal to either of the two given geometries.\n\nST_CROSSES() uses object shapes, while CROSSES(), based on the original MySQL implementation, uses object bounding rectangles.\n\nExamples\n--------\n\nSET @g1 = ST_GEOMFROMTEXT(''LINESTRING(174 149, 176 151)'');\n\nSET @g2 = ST_GEOMFROMTEXT(''POLYGON((175 150, 20 40, 50 60, 125 100, 175 150))'');\n\nSELECT ST_CROSSES(@g1,@g2);\n+---------------------+\n| ST_CROSSES(@g1,@g2) |\n+---------------------+\n|                   1 |\n+---------------------+\n\nSET @g1 = ST_GEOMFROMTEXT(''LINESTRING(176 149, 176 151)'');\n\nSELECT ST_CROSSES(@g1,@g2);\n+---------------------+\n| ST_CROSSES(@g1,@g2) |\n+---------------------+\n|                   0 |\n+---------------------+\n\nURL: https://mariadb.com/docs/server/reference/sql-statements/geometry-constructors/geometry-relations/st-crosses', '', 'https://mariadb.com/docs/server/reference/sql-statements/geometry-constructors/geometry-relations/st-crosses');
INSERT INTO help_topic (help_topic_id, help_category_id, name, description, example, url) VALUES (746, 34, 'ST\\_EQUALS', 'Syntax\n------\n\nST_EQUALS(g1,g2)\n\nDescription\n-----------\n\nReturns 1 or 0 to indicate whether geometry _g1_ is spatially equal to geometry _g2_.\n\nST_EQUALS() uses object shapes, while EQUALS(), based on the original MySQL implementation, uses object bounding rectangles.\n\nExamples\n--------\n\nSET @g1 = ST_GEOMFROMTEXT(''LINESTRING(174 149, 176 151)'');\n\nSET @g2 = ST_GEOMFROMTEXT(''LINESTRING(176 151, 174 149)'');\n\nSELECT ST_EQUALS(@g1,@g2);\n+--------------------+\n| ST_EQUALS(@g1,@g2) |\n+--------------------+\n|                  1 |\n+--------------------+\n\nURL: https://mariadb.com/docs/server/reference/sql-statements/geometry-constructors/geometry-relations/st-equals', '', 'https://mariadb.com/docs/server/reference/sql-statements/geometry-constructors/geometry-relations/st-equals');
INSERT INTO help_topic (help_topic_id, help_category_id, name, description, example, url) VALUES (747, 34, 'ST\\_INTERSECTS', 'Syntax\n------\n\nST_INTERSECTS(g1,g2)\n\nDescription\n-----------\n\nReturns 1 or 0 to indicate whether geometry _g1_ spatially intersects geometry _g2_.\n\nST_INTERSECTS() uses object shapes, while INTERSECTS(), based on the original MySQL implementation, uses object bounding rectangles.\n\nST_INTERSECTS() tests the opposite relationship to ST_DISJOINT().\n\nExamples\n--------\n\nSET @g1 = ST_GEOMFROMTEXT(''POINT(0 0)'');\n\nSET @g2 = ST_GEOMFROMTEXT(''LINESTRING(0 0, 0 2)'');\n\nSELECT ST_INTERSECTS(@g1,@g2);\n+------------------------+\n| ST_INTERSECTS(@g1,@g2) |\n+------------------------+\n|                      1 |\n+------------------------+\n\nURL: https://mariadb.com/docs/server/reference/sql-statements/geometry-constructors/geometry-relations/st-intersects', '', 'https://mariadb.com/docs/server/reference/sql-statements/geometry-constructors/geometry-relations/st-intersects');
INSERT INTO help_topic (help_topic_id, help_category_id, name, description, example, url) VALUES (748, 34, 'ST\\_OVERLAPS', 'Syntax\n------\n\nST_OVERLAPS(g1,g2)\n\nDescription\n-----------\n\nReturns 1 or 0 to indicate whether geometry _g1_ spatially overlaps geometry _g2_.\n\nThe term spatially overlaps is used if two geometries of equal dimensions intersect and their\\\nintersection results in a geometry of the same dimension but not equal to either of the given geometries.\n\nST_OVERLAPS() uses object shapes, while OVERLAPS(), based on the original MySQL implementation, uses object bounding rectangles.\n\nURL: https://mariadb.com/docs/server/reference/sql-statements/geometry-constructors/geometry-relations/st-overlaps', '', 'https://mariadb.com/docs/server/reference/sql-statements/geometry-constructors/geometry-relations/st-overlaps');
INSERT INTO help_topic (help_topic_id, help_category_id, name, description, example, url) VALUES (749, 34, 'ST\\_TOUCHES', 'Syntax\n------\n\nST_TOUCHES(g1,g2)\n\nDescription\n-----------\n\nReturns 1 or 0 to indicate whether geometry _g1_ spatially touches geometry _g2_. Two geometries spatially touch if the interiors of the geometries do not intersect, but the boundary of one of the geometries intersects either the boundary or the interior of the other.\n\nST_TOUCHES() uses object shapes, while TOUCHES(), based on the original MySQL implementation, uses object bounding rectangles.\n\nExamples\n--------\n\nSET @g1 = ST_GEOMFROMTEXT(''POINT(2 0)'');\n\nSET @g2 = ST_GEOMFROMTEXT(''LINESTRING(2 0, 0 2)'');\n\nSELECT ST_TOUCHES(@g1,@g2);\n+---------------------+\n| ST_TOUCHES(@g1,@g2) |\n+---------------------+\n|                   1 |\n+---------------------+\n\nSET @g1 = ST_GEOMFROMTEXT(''POINT(2 1)'');\n\nSELECT ST_TOUCHES(@g1,@g2);\n+---------------------+\n| ST_TOUCHES(@g1,@g2) |\n+---------------------+\n|                   0 |\n+---------------------+\n\nURL: https://mariadb.com/docs/server/reference/sql-statements/geometry-constructors/geometry-relations/st-touches', '', 'https://mariadb.com/docs/server/reference/sql-statements/geometry-constructors/geometry-relations/st-touches');
INSERT INTO help_topic (help_topic_id, help_category_id, name, description, example, url) VALUES (750, 34, 'ST\\_WITHIN', 'Syntax\n------\n\nST_WITHIN(g1,g2)\n\nDescription\n-----------\n\nReturns 1 or 0 to indicate whether geometry _g1_ is spatially within geometry _g2_.\n\nThis tests the opposite relationship as ST_CONTAINS().\n\nST_WITHIN() uses object shapes, while WITHIN(), based on the original MySQL implementation, uses object bounding rectangles.\n\nExamples\n--------\n\nSET @g1 = ST_GEOMFROMTEXT(''POINT(174 149)'');\n\nSET @g2 = ST_GEOMFROMTEXT(''POLYGON((175 150, 20 40, 50 60, 125 100, 175 150))'');\n\nSELECT ST_WITHIN(@g1,@g2);\n+--------------------+\n| ST_WITHIN(@g1,@g2) |\n+--------------------+\n|                  1 |\n+--------------------+\n\nSET @g1 = ST_GEOMFROMTEXT(''POINT(176 151)'');\n\nSELECT ST_WITHIN(@g1,@g2);\n+--------------------+\n| ST_WITHIN(@g1,@g2) |\n+--------------------+\n|                  0 |\n+--------------------+\n\nURL: https://mariadb.com/docs/server/reference/sql-statements/geometry-constructors/geometry-relations/st-within', '', 'https://mariadb.com/docs/server/reference/sql-statements/geometry-constructors/geometry-relations/st-within');
INSERT INTO help_topic (help_topic_id, help_category_id, name, description, example, url) VALUES (751, 34, 'ST\\_DIFFERENCE', 'Syntax\n------\n\nST_DIFFERENCE(g1,g2)\n\nDescription\n-----------\n\nReturns a geometry representing the point set difference of the given geometry values.\n\nExamples\n--------\n\nSET @g1 = POINT(10,10), @g2 = POINT(20,20);\n\nSELECT ST_AsText(ST_Difference(@g1, @g2));\n+------------------------------------+\n| ST_AsText(ST_Difference(@g1, @g2)) |\n+------------------------------------+\n| POINT(10 10)                       |\n+------------------------------------+\n\nURL: https://mariadb.com/docs/server/reference/sql-statements/geometry-constructors/geometry-relations/st_difference', '', 'https://mariadb.com/docs/server/reference/sql-statements/geometry-constructors/geometry-relations/st_difference');
INSERT INTO help_topic (help_topic_id, help_category_id, name, description, example, url) VALUES (752, 34, 'ST\\_DISJOINT', 'Syntax\n------\n\nST_DISJOINT(g1,g2)\n\nDescription\n-----------\n\nReturns 1 or 0 to indicate whether geometry _g1_ is spatially disjoint from (does not intersect with) geometry _g2_.\n\nST_DISJOINT() uses object shapes, while DISJOINT(), based on the original MySQL implementation, uses object bounding rectangles.\n\nST_DISJOINT() tests the opposite relationship to ST_INTERSECTS().\n\nExamples\n--------\n\nSET @g1 = ST_GEOMFROMTEXT(''POINT(0 0)'');\n\nSET @g2 = ST_GEOMFROMTEXT(''LINESTRING(2 0, 0 2)'');\n\nSELECT ST_DISJOINT(@g1,@g2);\n+----------------------+\n| ST_DISJOINT(@g1,@g2) |\n+----------------------+\n|                    1 |\n+----------------------+\n\nSET @g2 = ST_GEOMFROMTEXT(''LINESTRING(0 0, 0 2)'');\n\nSELECT ST_DISJOINT(@g1,@g2);\n+----------------------+\n| ST_DISJOINT(@g1,@g2) |\n+----------------------+\n|                    0 |\n+----------------------+\n\nURL: https://mariadb.com/docs/server/reference/sql-statements/geometry-constructors/geometry-relations/st_disjoint', '', 'https://mariadb.com/docs/server/reference/sql-statements/geometry-constructors/geometry-relations/st_disjoint');
INSERT INTO help_topic (help_topic_id, help_category_id, name, description, example, url) VALUES (753, 34, 'ST\\_DISTANCE', 'Syntax\n------\n\nST_DISTANCE(g1,g2)\n\nDescription\n-----------\n\nReturns the distance between two geometries, or null if not given valid inputs.\n\nExamples\n--------\n\nSELECT ST_Distance(POINT(1,2),POINT(2,2));\n+------------------------------------+\n| ST_Distance(POINT(1,2),POINT(2,2)) |\n+------------------------------------+\n|                                  1 |\n+------------------------------------+\n\nURL: https://mariadb.com/docs/server/reference/sql-statements/geometry-constructors/geometry-relations/st_distance', '', 'https://mariadb.com/docs/server/reference/sql-statements/geometry-constructors/geometry-relations/st_distance');
INSERT INTO help_topic (help_topic_id, help_category_id, name, description, example, url) VALUES (754, 34, 'ST\\_DISTANCE\\_SPHERE', 'Syntax\n------\n\nST_DISTANCE_SPHERE(g1,g2,[r])\n\nDescription\n-----------\n\nReturns the spherical distance in meters between two geometries (point or multipoint) on a sphere. The optional radius _r_ is in meters, must be positive, and defaults to the Earth''s radius (6370986 meters) if not specified. If either of the two geometries are not valid, NULL is returned.\n\nExamples\n--------\n\nSET @zenica   = ST_GeomFromText(''POINT(17.907743 44.203438)'');\nSET @sarajevo = ST_GeomFromText(''POINT(18.413076 43.856258)'');\nSELECT ST_Distance_Sphere(@zenica, @sarajevo);\n+----------------------------------------+\n| ST_Distance_Sphere(@zenica, @sarajevo) |\n+----------------------------------------+\n|                      55878.59337591705 |\n+----------------------------------------+\n\nSELECT ST_Distance_Sphere(@zenica, @sarajevo, 6370986);\n+-------------------------------------------------+\n| ST_Distance_Sphere(@zenica, @sarajevo, 6370986) |\n+-------------------------------------------------+\n|                               55878.59337591705 |\n+-------------------------------------------------+\n\nSELECT ST_Distance_Sphere(@zenica, @sarajevo, 200);    \n+---------------------------------------------+\n| ST_Distance_Sphere(@zenica, @sarajevo, 200) |\n+---------------------------------------------+\n|                           1.754158410516584 |\n+---------------------------------------------+\n\nURL: https://mariadb.com/docs/server/reference/sql-statements/geometry-constructors/geometry-relations/st_distance_sphere', '', 'https://mariadb.com/docs/server/reference/sql-statements/geometry-constructors/geometry-relations/st_distance_sphere');
INSERT INTO help_topic (help_topic_id, help_category_id, name, description, example, url) VALUES (755, 34, 'ST\\_LENGTH', 'Syntax\n------\n\nST_LENGTH(ls)\n\nDescription\n-----------\n\nReturns as a double-precision number the length of the LineString value _ls_ in its associated spatial reference.\n\nExamples\n--------\n\nSET @ls = ''LineString(1 1,2 2,3 3)'';\n\nSELECT ST_LENGTH(ST_GeomFromText(@ls));\n+---------------------------------+\n| ST_LENGTH(ST_GeomFromText(@ls)) |\n+---------------------------------+\n|                2.82842712474619 |\n+---------------------------------+\n\nURL: https://mariadb.com/docs/server/reference/sql-statements/geometry-constructors/geometry-relations/st_length', '', 'https://mariadb.com/docs/server/reference/sql-statements/geometry-constructors/geometry-relations/st_length');
INSERT INTO help_topic (help_topic_id, help_category_id, name, description, example, url) VALUES (756, 34, 'TOUCHES', 'Syntax\n------\n\nTouches(g1,g2)\n\nDescription\n-----------\n\nReturns 1 or 0 to indicate whether g1 spatially touches g2. Two geometries spatially touch if the interiors of the geometries do not intersect, but the boundary of one of the geometries intersects either the boundary or the interior of the other.\n\nTOUCHES() is based on the original MySQL implementation and uses object bounding rectangles, while ST_TOUCHES() uses object shapes.\n\nURL: https://mariadb.com/docs/server/reference/sql-statements/geometry-constructors/geometry-relations/touches', '', 'https://mariadb.com/docs/server/reference/sql-statements/geometry-constructors/geometry-relations/touches');
INSERT INTO help_topic (help_topic_id, help_category_id, name, description, example, url) VALUES (757, 34, 'WITHIN', 'Syntax\n------\n\nWithin(g1,g2)\n\nDescription\n-----------\n\nReturns 1 or 0 to indicate whether g1 is spatially within g2. This tests the opposite relationship as Contains().\n\nWITHIN() is based on the original MySQL implementation, and uses object bounding rectangles, while ST_WITHIN() uses object shapes.\n\nExamples\n--------\n\nSET @g1 = GEOMFROMTEXT(''POINT(174 149)'');\nSET @g2 = GEOMFROMTEXT(''POINT(176 151)'');\nSET @g3 = GEOMFROMTEXT(''POLYGON((175 150, 20 40, 50 60, 125 100, 175 150))'');\n\nSELECT within(@g1,@g3);\n+-----------------+\n| within(@g1,@g3) |\n+-----------------+\n|               1 |\n+-----------------+\n\nSELECT within(@g2,@g3);\n+-----------------+\n| within(@g2,@g3) |\n+-----------------+\n|               0 |\n+-----------------+\n\nURL: https://mariadb.com/docs/server/reference/sql-statements/geometry-constructors/geometry-relations/within', '', 'https://mariadb.com/docs/server/reference/sql-statements/geometry-constructors/geometry-relations/within');
INSERT INTO help_topic (help_topic_id, help_category_id, name, description, example, url) VALUES (758, 34, 'GLENGTH', 'Syntax\n------\n\nGLength(ls)\n\nDescription\n-----------\n\nReturns as a double-precision number the length of the LineString value _ls_ in its associated spatial reference.\n\nExamples\n--------\n\nSET @ls = ''LineString(1 1,2 2,3 3)'';\n\nSELECT GLength(GeomFromText(@ls));\n+----------------------------+\n| GLength(GeomFromText(@ls)) |\n+----------------------------+\n|           2.82842712474619 |\n+----------------------------+\n\nURL: https://mariadb.com/docs/server/reference/sql-statements/geometry-constructors/linestring-properties/glength', '', 'https://mariadb.com/docs/server/reference/sql-statements/geometry-constructors/linestring-properties/glength');
INSERT INTO help_topic (help_topic_id, help_category_id, name, description, example, url) VALUES (759, 34, 'ENDPOINT', 'Description\n-----------\n\nA synonym for ST_ENDPOINT.\n\nURL: https://mariadb.com/docs/server/reference/sql-statements/geometry-constructors/linestring-properties/linestring-properties-endpoint', '', 'https://mariadb.com/docs/server/reference/sql-statements/geometry-constructors/linestring-properties/linestring-properties-endpoint');
INSERT INTO help_topic (help_topic_id, help_category_id, name, description, example, url) VALUES (760, 34, 'NumPoints', 'Description\n-----------\n\nA synonym for ST_NumPoints.\n\nURL: https://mariadb.com/docs/server/reference/sql-statements/geometry-constructors/linestring-properties/linestring-properties-numpoints', '', 'https://mariadb.com/docs/server/reference/sql-statements/geometry-constructors/linestring-properties/linestring-properties-numpoints');
INSERT INTO help_topic (help_topic_id, help_category_id, name, description, example, url) VALUES (761, 34, 'PointN', 'Description\n-----------\n\nA synonym for ST_PointN.\n\nURL: https://mariadb.com/docs/server/reference/sql-statements/geometry-constructors/linestring-properties/linestring-properties-pointn', '', 'https://mariadb.com/docs/server/reference/sql-statements/geometry-constructors/linestring-properties/linestring-properties-pointn');
INSERT INTO help_topic (help_topic_id, help_category_id, name, description, example, url) VALUES (762, 34, 'STARTPOINT', 'Description\n-----------\n\nA synonym for ST_STARTPOINT.\n\nURL: https://mariadb.com/docs/server/reference/sql-statements/geometry-constructors/linestring-properties/linestring-properties-startpoint', '', 'https://mariadb.com/docs/server/reference/sql-statements/geometry-constructors/linestring-properties/linestring-properties-startpoint');
INSERT INTO help_topic (help_topic_id, help_category_id, name, description, example, url) VALUES (763, 34, 'ST\\_ENDPOINT', 'Syntax\n------\n\nST_EndPoint(ls)\nEndPoint(ls)\n\nDescription\n-----------\n\nReturns the Point that is the endpoint of the LineString value ls.\n\nST_EndPoint() and EndPoint() are synonyms.\n\nExamples\n--------\n\nSET @ls = ''LineString(1 1,2 2,3 3)'';\n\nSELECT AsText(EndPoint(GeomFromText(@ls)));\n+-------------------------------------+\n| AsText(EndPoint(GeomFromText(@ls))) |\n+-------------------------------------+\n| POINT(3 3)                          |\n+-------------------------------------+\n\nURL: https://mariadb.com/docs/server/reference/sql-statements/geometry-constructors/linestring-properties/st_endpoint', '', 'https://mariadb.com/docs/server/reference/sql-statements/geometry-constructors/linestring-properties/st_endpoint');
INSERT INTO help_topic (help_topic_id, help_category_id, name, description, example, url) VALUES (764, 34, 'ST\\_NUMPOINTS', 'Syntax\n------\n\nST_NumPoints(ls)\nNumPoints(ls)\n\nDescription\n-----------\n\nReturns the number of Point objects in the LineString value ls.\n\nST_NumPoints() and NumPoints() are synonyms.\n\nExamples\n--------\n\nSET @ls = ''LineString(1 1,2 2,3 3)'';\n\nSELECT NumPoints(GeomFromText(@ls));\n+------------------------------+\n| NumPoints(GeomFromText(@ls)) |\n+------------------------------+\n|                            3 |\n+------------------------------+\n\nURL: https://mariadb.com/docs/server/reference/sql-statements/geometry-constructors/linestring-properties/st_numpoints', '', 'https://mariadb.com/docs/server/reference/sql-statements/geometry-constructors/linestring-properties/st_numpoints');
INSERT INTO help_topic (help_topic_id, help_category_id, name, description, example, url) VALUES (765, 34, 'ST\\_POINTN', 'Syntax\n------\n\nST_PointN(ls,N)\nPointN(ls,N)\n\nDescription\n-----------\n\nReturns the N-th Point in the LineString value ls. Points are numbered beginning with 1.\n\nST_PointN() and PointN() are synonyms.\n\nExamples\n--------\n\nSET @ls = ''LineString(1 1,2 2,3 3)'';\n\nSELECT AsText(PointN(GeomFromText(@ls),2));\n+-------------------------------------+\n| AsText(PointN(GeomFromText(@ls),2)) |\n+-------------------------------------+\n| POINT(2 2)                          |\n+-------------------------------------+\n\nURL: https://mariadb.com/docs/server/reference/sql-statements/geometry-constructors/linestring-properties/st_pointn', '', 'https://mariadb.com/docs/server/reference/sql-statements/geometry-constructors/linestring-properties/st_pointn');
INSERT INTO help_topic (help_topic_id, help_category_id, name, description, example, url) VALUES (766, 34, 'ST\\_STARTPOINT', 'Syntax\n------\n\nST_StartPoint(ls)\nStartPoint(ls)\n\nDescription\n-----------\n\nReturns the Point that is the start point of the LineString value ls.\n\nST_StartPoint() and StartPoint() are synonyms.\n\nExamples\n--------\n\nSET @ls = ''LineString(1 1,2 2,3 3)'';\n\nSELECT AsText(StartPoint(GeomFromText(@ls)));\n+---------------------------------------+\n| AsText(StartPoint(GeomFromText(@ls))) |\n+---------------------------------------+\n| POINT(1 1)                            |\n+---------------------------------------+\n\nURL: https://mariadb.com/docs/server/reference/sql-statements/geometry-constructors/linestring-properties/st_startpoint', '', 'https://mariadb.com/docs/server/reference/sql-statements/geometry-constructors/linestring-properties/st_startpoint');
INSERT INTO help_topic (help_topic_id, help_category_id, name, description, example, url) VALUES (767, 34, 'MBR Definition', 'Description\n-----------\n\nThe MBR (Minimum Bounding Rectangle), or Envelope is the bounding geometry, formed by the minimum and maximum (X,Y) coordinates:\n\nExamples\n--------\n\n((MINX MINY, MAXX MINY, MAXX MAXY, MINX MAXY, MINX MINY))\n\nURL: https://mariadb.com/docs/server/reference/sql-statements/geometry-constructors/mbr-minimum-bounding-rectangle/mbr-definition', '', 'https://mariadb.com/docs/server/reference/sql-statements/geometry-constructors/mbr-minimum-bounding-rectangle/mbr-definition');
INSERT INTO help_topic (help_topic_id, help_category_id, name, description, example, url) VALUES (768, 34, 'MBRContains', 'Syntax\n------\n\nMBRContains(g1,g2)\n\nDescription\n-----------\n\nReturns 1 or 0 to indicate whether the Minimum Bounding Rectangle of g1 contains the Minimum Bounding Rectangle of g2. This tests the opposite relationship as MBRWithin().\n\nExamples\n--------\n\nSET @g1 = GeomFromText(''Polygon((0 0,0 3,3 3,3 0,0 0))'');\n\nSET @g2 = GeomFromText(''Point(1 1)'');\n\nSELECT MBRContains(@g1,@g2), MBRContains(@g2,@g1);\n+----------------------+----------------------+\n| MBRContains(@g1,@g2) | MBRContains(@g2,@g1) |\n+----------------------+----------------------+\n|                    1 |                    0 |\n+----------------------+----------------------+\n\nURL: https://mariadb.com/docs/server/reference/sql-statements/geometry-constructors/mbr-minimum-bounding-rectangle/mbrcontains', '', 'https://mariadb.com/docs/server/reference/sql-statements/geometry-constructors/mbr-minimum-bounding-rectangle/mbrcontains');
INSERT INTO help_topic (help_topic_id, help_category_id, name, description, example, url) VALUES (769, 34, 'MBRCoveredBy', 'Syntax\n------\n\nMBRCoveredBy(g1, g2)\n\nDescription\n-----------\n\nReturns 1 if the minimum bounding rectangle of g1 is covered by the minimum bounding rectangle of g2, otherwise 0.\n\nReturns NULL If any argument is NULL, or an argument is an empty geometry.\n\nExamples\n--------\n\nSET @g1a = ST_GeomFromText(''Point(5 6)'');\nSET @g1b = ST_GeomFromText(''Point(5 11)'');\nSET @g2 = ST_GeomFromText(''Polygon((0 0,0 10,10 10,10 0,0 0))'');\n\nSELECT MBRCoveredby(@g1a,@g2), MBRCoveredby(@g1b,@g2);\n+------------------------+------------------------+\n| MBRCoveredby(@g1a,@g2) | MBRCoveredby(@g1b,@g2) |\n+------------------------+------------------------+\n|                      1 |                      0 |\n+------------------------+------------------------+\n\nURL: https://mariadb.com/docs/server/reference/sql-statements/geometry-constructors/mbr-minimum-bounding-rectangle/mbrcoveredby', '', 'https://mariadb.com/docs/server/reference/sql-statements/geometry-constructors/mbr-minimum-bounding-rectangle/mbrcoveredby');
INSERT INTO help_topic (help_topic_id, help_category_id, name, description, example, url) VALUES (770, 34, 'MBRDisjoint', 'Syntax\n------\n\nMBRDisjoint(g1,g2)\n\nDescription\n-----------\n\nReturns 1 or 0 to indicate whether the Minimum Bounding Rectangles of the two geometries g1 and g2 are disjoint. Two geometries are disjoint if they do not intersect, that is touch or overlap.\n\nExamples\n--------\n\nSET @g1 = GeomFromText(''Polygon((0 0,0 3,3 3,3 0,0 0))'');\nSET @g2 = GeomFromText(''Polygon((4 4,4 7,7 7,7 4,4 4))'');\nSELECTmbrdisjoint(@g1,@g2);\n+----------------------+\n| mbrdisjoint(@g1,@g2) |\n+----------------------+\n|                    1 |\n+----------------------+\n\nSET @g1 = GeomFromText(''Polygon((0 0,0 3,3 3,3 0,0 0))'');\nSET @g2 = GeomFromText(''Polygon((3 3,3 6,6 6,6 3,3 3))'');\nSELECT mbrdisjoint(@g1,@g2);\n+----------------------+\n| mbrdisjoint(@g1,@g2) |\n+----------------------+\n|                    0 |\n+----------------------+\n\nURL: https://mariadb.com/docs/server/reference/sql-statements/geometry-constructors/mbr-minimum-bounding-rectangle/mbrdisjoint', '', 'https://mariadb.com/docs/server/reference/sql-statements/geometry-constructors/mbr-minimum-bounding-rectangle/mbrdisjoint');
INSERT INTO help_topic (help_topic_id, help_category_id, name, description, example, url) VALUES (771, 34, 'MBREqual', 'Syntax\n------\n\nMBREqual(g1,g2)\nMBREquals(g1,g2)\n\nDescription\n-----------\n\nReturns 1 or 0 to indicate whether the Minimum Bounding Rectangles of the two geometries g1 and g2 are the same.\n\nMBREquals is a synonym.\n\nExamples\n--------\n\nSET @g1=GEOMFROMTEXT(''LINESTRING(0 0, 1 2)'');\nSET @g2=GEOMFROMTEXT(''POLYGON((0 0, 0 2, 1 2, 1 0, 0 0))'');\nSELECT MbrEqual(@g1,@g2);\n+-------------------+\n| MbrEqual(@g1,@g2) |\n+-------------------+\n|                 1 |\n+-------------------+\n\nSET @g1=GEOMFROMTEXT(''LINESTRING(0 0, 1 3)'');\nSET @g2=GEOMFROMTEXT(''POLYGON((0 0, 0 2, 1 4, 1 0, 0 0))'');\nSELECT MbrEqual(@g1,@g2);\n+-------------------+\n| MbrEqual(@g1,@g2) |\n+-------------------+\n|                 0 |\n+-------------------+\n\nURL: https://mariadb.com/docs/server/reference/sql-statements/geometry-constructors/mbr-minimum-bounding-rectangle/mbrequal', '', 'https://mariadb.com/docs/server/reference/sql-statements/geometry-constructors/mbr-minimum-bounding-rectangle/mbrequal');
INSERT INTO help_topic (help_topic_id, help_category_id, name, description, example, url) VALUES (772, 34, 'MBRIntersects', 'Syntax\n------\n\nMBRIntersects(g1,g2)\n\nDescription\n-----------\n\nReturns 1 or 0 to indicate whether the Minimum Bounding Rectangles of the two geometries g1 and g2 intersect.\n\nExamples\n--------\n\nSET @g1 = GeomFromText(''Polygon((0 0,0 3,3 3,3 0,0 0))'');\nSET @g2 = GeomFromText(''Polygon((3 3,3 6,6 6,6 3,3 3))'');\nSELECT mbrintersects(@g1,@g2);\n+------------------------+\n| mbrintersects(@g1,@g2) |\n+------------------------+\n|                      1 |\n+------------------------+\n\nSET @g1 = GeomFromText(''Polygon((0 0,0 3,3 3,3 0,0 0))'');\nSET @g2 = GeomFromText(''Polygon((4 4,4 7,7 7,7 4,4 4))'');\nSELECT mbrintersects(@g1,@g2);\n+------------------------+\n| mbrintersects(@g1,@g2) |\n+------------------------+\n|                      0 |\n+------------------------+\n\nURL: https://mariadb.com/docs/server/reference/sql-statements/geometry-constructors/mbr-minimum-bounding-rectangle/mbrintersects', '', 'https://mariadb.com/docs/server/reference/sql-statements/geometry-constructors/mbr-minimum-bounding-rectangle/mbrintersects');
INSERT INTO help_topic (help_topic_id, help_category_id, name, description, example, url) VALUES (773, 34, 'MBROverlaps', 'Syntax\n------\n\nMBROverlaps(g1,g2)\n\nDescription\n-----------\n\nReturns 1 or 0 to indicate whether the Minimum Bounding Rectangles of the two geometries g1 and g2 overlap. The term spatially overlaps is used if two geometries intersect and their intersection results in a geometry of the same dimension but not equal to either of the given geometries.\n\nExamples\n--------\n\nSET @g1 = GeomFromText(''Polygon((0 0,0 3,3 3,3 0,0 0))'');\nSET @g2 = GeomFromText(''Polygon((4 4,4 7,7 7,7 4,4 4))'');\nSELECT mbroverlaps(@g1,@g2);\n+----------------------+\n| mbroverlaps(@g1,@g2) |\n+----------------------+\n|                    0 |\n+----------------------+\n\nSET @g1 = GeomFromText(''Polygon((0 0,0 3,3 3,3 0,0 0))'');\nSET @g2 = GeomFromText(''Polygon((3 3,3 6,6 6,6 3,3 3))'');\nSELECT mbroverlaps(@g1,@g2);\n+----------------------+\n| mbroverlaps(@g1,@g2) |\n+----------------------+\n|                    0 |\n+----------------------+\n\nSET @g1 = GeomFromText(''Polygon((0 0,0 4,4 4,4 0,0 0))'');\nSET @g2 = GeomFromText(''Polygon((3 3,3 6,6 6,6 3,3 3))'');\nSELECT mbroverlaps(@g1,@g2);\n+----------------------+\n| mbroverlaps(@g1,@g2) |\n+----------------------+\n|                    1 |\n+----------------------+\n\nURL: https://mariadb.com/docs/server/reference/sql-statements/geometry-constructors/mbr-minimum-bounding-rectangle/mbroverlaps', '', 'https://mariadb.com/docs/server/reference/sql-statements/geometry-constructors/mbr-minimum-bounding-rectangle/mbroverlaps');
INSERT INTO help_topic (help_topic_id, help_category_id, name, description, example, url) VALUES (774, 34, 'MBRTouches', 'Syntax\n------\n\nMBRTouches(g1,g2)\n\nDescription\n-----------\n\nReturns 1 or 0 to indicate whether the Minimum Bounding Rectangles of the two geometries g1 and g2 touch. Two geometries spatially touch if the interiors of the geometries do not intersect, but the boundary of one of the geometries intersects either the boundary or the interior of the other.\n\nExamples\n--------\n\nSET @g1 = GeomFromText(''Polygon((0 0,0 3,3 3,3 0,0 0))'');\nSET @g2 = GeomFromText(''Polygon((4 4,4 7,7 7,7 4,4 4))'');\nSELECT mbrtouches(@g1,@g2);\n+---------------------+\n| mbrtouches(@g1,@g2) |\n+---------------------+\n|                   0 |\n+---------------------+\n\nSET @g1 = GeomFromText(''Polygon((0 0,0 3,3 3,3 0,0 0))'');\nSET @g2 = GeomFromText(''Polygon((3 3,3 6,6 6,6 3,3 3))'');\nSELECT mbrtouches(@g1,@g2);\n+---------------------+\n| mbrtouches(@g1,@g2) |\n+---------------------+\n|                   1 |\n+---------------------+\n\nSET @g1 = GeomFromText(''Polygon((0 0,0 4,4 4,4 0,0 0))'');\nSET @g2 = GeomFromText(''Polygon((3 3,3 6,6 6,6 3,3 3))'');\nSELECT mbrtouches(@g1,@g2);\n+---------------------+\n| mbrtouches(@g1,@g2) |\n+---------------------+\n|                   0 |\n+---------------------+\n\nURL: https://mariadb.com/docs/server/reference/sql-statements/geometry-constructors/mbr-minimum-bounding-rectangle/mbrtouches', '', 'https://mariadb.com/docs/server/reference/sql-statements/geometry-constructors/mbr-minimum-bounding-rectangle/mbrtouches');
INSERT INTO help_topic (help_topic_id, help_category_id, name, description, example, url) VALUES (775, 34, 'MBRWithin', 'Syntax\n------\n\nMBRWithin(g1,g2)\n\nDescription\n-----------\n\nReturns 1 or 0 to indicate whether the Minimum Bounding Rectangle of g1 is within the Minimum Bounding Rectangle of g2. This tests the opposite relationship as MBRContains().\n\nExamples\n--------\n\nSET @g1 = GeomFromText(''Polygon((0 0,0 3,3 3,3 0,0 0))'');\nSET @g2 = GeomFromText(''Polygon((0 0,0 5,5 5,5 0,0 0))'');\nSELECT MBRWithin(@g1,@g2), MBRWithin(@g2,@g1);\n+--------------------+--------------------+\n| MBRWithin(@g1,@g2) | MBRWithin(@g2,@g1) |\n+--------------------+--------------------+\n|                  1 |                  0 |\n+--------------------+--------------------+\n\nURL: https://mariadb.com/docs/server/reference/sql-statements/geometry-constructors/mbr-minimum-bounding-rectangle/mbrwithin', '', 'https://mariadb.com/docs/server/reference/sql-statements/geometry-constructors/mbr-minimum-bounding-rectangle/mbrwithin');
INSERT INTO help_topic (help_topic_id, help_category_id, name, description, example, url) VALUES (776, 34, 'ST\\_Collect', 'Syntax\n------\n\nST_Collect(g)\n\nDescription\n-----------\n\nST_Collect is an aggregate function that can also be used as a window function.\n\nGiven multiple geometries, returns the aggregation of the distinct geometry arguments. This function also supports the DISTINCT option. If DISTINCT is used, it returns the aggregation of the distinct geometry arguments.\n\nThe resulting value type is chosen using the following policy:\n\n If all arguments are Point values, the result is a MultiPoint value.\n If all arguments are LineString values, the result is a MultiLineString value.\n If all arguments are Polygon values, the result is a MultiPolygon value.\n Otherwise, the result is a GeometryCollection value.\n\nIf there are multiple geometry arguments and those arguments are in the same spatial reference system (SRS), the return value is in that SRS. If those arguments are not in the same SRS, an ER_GIS_DIFFERENT_SRIDS_AGGREGATION error occurs.\n\nExamples\n--------\n\nCREATE OR REPLACE TABLE t1 ( running_number INTEGER NOT NULL\n  AUTO_INCREMENT, grouping_condition INTEGER, location GEOMETRY , PRIMARY KEY (\n  running_number));\n\nINSERT INTO t1 ( grouping_condition, location ) VALUES\n  ( 0,ST_GEOMFROMTEXT(''POINT(0 0)'',4326)),\n  ( 1,ST_GEOMFROMTEXT(''POINT(0 0)'',4326)),\n  ( 0,ST_GEOMFROMTEXT(''POINT(1 0)'',4326)),\n  ( 1,ST_GEOMFROMTEXT(''POINT(2 0)'',4326)),\n  ( 0,ST_GEOMFROMTEXT(''POINT(3 0)'',4326));\n\nSELECT ST_EQUALS( (SELECT ST_COLLECT( location ) AS t FROM t1), \n  ST_GEOMFROMTEXT(''MULTIPOINT(0 0,0 0,1 0,2 0,3 0) '',4326)) AS equals;\n+--------+\n| equals |\n+--------+\n|      1 |\n+--------+\n\nURL: https://mariadb.com/docs/server/reference/sql-statements/geometry-constructors/miscellaneous-gis-functions/st_collect', '', 'https://mariadb.com/docs/server/reference/sql-statements/geometry-constructors/miscellaneous-gis-functions/st_collect');
INSERT INTO help_topic (help_topic_id, help_category_id, name, description, example, url) VALUES (777, 34, 'ST\\_GeoHash', 'Syntax\n------\n\nST_GeoHash(longitude, latitude, max_length)\nST_GeoHash(point, max_length)\n\nDescription\n-----------\n\nReturns the geohash corresponding to the input values, or NULL if any argument is NULL. Geohashes encode latitude and longitude coordinates into a text string made up only of numeric and lowercase latin letter characters.\n\nThe longitude parameter is a numeric value in the interval \\[180, -180]. latitude is a numeric value in the interval \\[90, -90].\n\nIn the case of point, the x coordinate is treated as the longitude and the y coordinate is treated as the latitude. The same constraints apply.\n\nThe max_length parameter is the upper limit on the resulting string size and cannot exceed 100.\n\nThe ST_LatFromGeoHash function decodes a given geohash and returns the latitude.\n\nExamples\n--------\n\nSELECT ST_GeoHash(ST_GeomFromText(''POINT(1 1)''),15), ST_GeoHash(0,30,15);\n+----------------------------------------------+---------------------+\n| ST_GeoHash(ST_GeomFromText(''POINT(1 1)''),15) | ST_GeoHash(0,30,15) |\n+----------------------------------------------+---------------------+\n| s00twy01mtw037m                              | sj248j248j248j2     |\n+----------------------------------------------+---------------------+\n\nURL: https://mariadb.com/docs/server/reference/sql-statements/geometry-constructors/miscellaneous-gis-functions/st_geohash', '', 'https://mariadb.com/docs/server/reference/sql-statements/geometry-constructors/miscellaneous-gis-functions/st_geohash');
INSERT INTO help_topic (help_topic_id, help_category_id, name, description, example, url) VALUES (778, 34, 'ST\\_IsValid', 'Syntax\n------\n\nST_IsValid(g)\n\nDescription\n-----------\n\nGiven a geometry input, returns 1 if the argument is geometrically valid according to the OGC specifications, 0 if the argument is not geometrically valid.\n\nUnlike ST_Validate, requires valid GIS data, or ERROR 3037 (22023): Invalid GIS data provided to function st_isvalid is returned.\n\nExamples\n--------\n\nSELECT ST_IsValid(ST_GeomFromText(''LINESTRING (0 0, 1 1)''));\n+------------------------------------------------------+\n| ST_IsValid(ST_GeomFromText(''LINESTRING (0 0, 1 1)'')) |\n+------------------------------------------------------+\n|                                                    1 |\n+------------------------------------------------------+\n\nSELECT ST_IsValid(ST_GeomFromText(''LINESTRING (0 0, 0 0)''));\n+------------------------------------------------------+\n| ST_IsValid(ST_GeomFromText(''LINESTRING (0 0, 0 0)'')) |\n+------------------------------------------------------+\n|                                                    0 |\n+------------------------------------------------------+\n\nURL: https://mariadb.com/docs/server/reference/sql-statements/geometry-constructors/miscellaneous-gis-functions/st_isvalid', '', 'https://mariadb.com/docs/server/reference/sql-statements/geometry-constructors/miscellaneous-gis-functions/st_isvalid');
INSERT INTO help_topic (help_topic_id, help_category_id, name, description, example, url) VALUES (779, 34, 'ST\\_LatFromGeoHash', 'Syntax\n------\n\nST_LatFromGeoHash(geohash)\n\nDescription\n-----------\n\nDecodes a given geohash string and returns the latitude in the interval \\[90, -90].\n\nIf the argument is NULL, the return value is NULL. If the argument is invalid, an ER_INCORRECT_TYPE error is thrown.\n\nThe ST_GeoHash function can be used to generate geohashes.\n\nExamples\n--------\n\nSELECT ST_LatFromGeoHash(''zzzzzzzzz''), ST_LatFromGeoHash(''xvrfxvrfxvrfxvr'');\n+--------------------------------+--------------------------------------+\n| ST_LatFromGeoHash(''zzzzzzzzz'') | ST_LatFromGeoHash(''xvrfxvrfxvrfxvr'') |\n+--------------------------------+--------------------------------------+\n|                             90 |                                   30 |\n+--------------------------------+--------------------------------------+\n\nURL: https://mariadb.com/docs/server/reference/sql-statements/geometry-constructors/miscellaneous-gis-functions/st_latfromgeohash', '', 'https://mariadb.com/docs/server/reference/sql-statements/geometry-constructors/miscellaneous-gis-functions/st_latfromgeohash');
INSERT INTO help_topic (help_topic_id, help_category_id, name, description, example, url) VALUES (780, 34, 'ST\\_LongFromGeoHash', 'Syntax\n------\n\nST_LongFromGeoHash(geohash)\n\nDescription\n-----------\n\nDecodes a given geohash string and returns the longitude in the interval \\[180, -180].\n\nIf the argument is NULL, the return value is NULL. If the argument is invalid, an ER_INCORRECT_TYPE error is thrown.\n\nThe ST_GeoHash function can be used to generate geohashes.\n\nExamples\n--------\n\nSELECT ST_LongFromGeoHash(''zzzzzzzzz''), ST_LongFromGeoHash(''sj248j248j248j2'');           \n+---------------------------------+---------------------------------------+\n| ST_LongFromGeoHash(''zzzzzzzzz'') | ST_LongFromGeoHash(''sj248j248j248j2'') |\n+---------------------------------+---------------------------------------+\n|                             180 |                                     0 |\n+---------------------------------+---------------------------------------+\n\nURL: https://mariadb.com/docs/server/reference/sql-statements/geometry-constructors/miscellaneous-gis-functions/st_longfromgeohash', '', 'https://mariadb.com/docs/server/reference/sql-statements/geometry-constructors/miscellaneous-gis-functions/st_longfromgeohash');
INSERT INTO help_topic (help_topic_id, help_category_id, name, description, example, url) VALUES (781, 34, 'ST\\_PointFromGeoHash', 'Syntax\n------\n\nST_PointFromGeoHash(geohash, srid)\n\nDescription\n-----------\n\nTakes a given geohash string and returns a point where the x is the longitude and the y is the latitude.\n\nThe latitude is returned as a numeric value in the interval \\[180, -180]. The longitude is returned as a numeric value in the interval \\[90, -90]. If the argument is NULL, the return value is NULL. If the argument is invalid, an ER_GIS_INVALID_DATA is thrown.\n\nExamples\n--------\n\nSELECT ST_ASTEXT(ST_POINTFROMGEOHASH("s00twy01mtw037m",0));\n+-----------------------------------------------------+\n| ST_ASTEXT(ST_POINTFROMGEOHASH("s00twy01mtw037m",0)) |\n+-----------------------------------------------------+\n| POINT(1 1)                                          |\n+-----------------------------------------------------+\n\nSELECT ST_ASTEXT(ST_POINTFROMGEOHASH(ST_GEOHASH(180,90,20),0));\n+---------------------------------------------------------+\n| ST_ASTEXT(ST_POINTFROMGEOHASH(ST_GEOHASH(180,90,20),0)) |\n+---------------------------------------------------------+\n| POINT(180 90)                                           |\n+---------------------------------------------------------+\n\nURL: https://mariadb.com/docs/server/reference/sql-statements/geometry-constructors/miscellaneous-gis-functions/st_pointfromgeohash', '', 'https://mariadb.com/docs/server/reference/sql-statements/geometry-constructors/miscellaneous-gis-functions/st_pointfromgeohash');
INSERT INTO help_topic (help_topic_id, help_category_id, name, description, example, url) VALUES (782, 34, 'ST\\_Simplify', 'Syntax\n------\n\nST_Simplify(g, max_distance)\n\nDescription\n-----------\n\nTakes as input a geometry (g) and a double (max_distance). It applies the Ramer–Douglas–Peucker algorithm on g and returns the resulting geometry.\n\nThe goal of the Douglas-Peucker algorithm is to provide generalized simplifications by returning a geometry that is similar to g but uses only a subset of points. To perform the simplification, all the vertices that are shorter than max_distance are removed.\n\nThe algorithm may produce self-intersections and therefore result in invalid geometries. ST_IsValid can be used to test validity of the result.\n\nIf the max_distance is not positive or is NULL, an ER_WRONG_ARGUMENT will occur.\n\nExamples\n--------\n\nSELECT ST_AsText(ST_Simplify(ST_GeomFromText(''LINESTRING(0 0,0 2,2 2,2 4,4 4,4 6,6 6)''), 0.5));\n+-----------------------------------------------------------------------------------------+\n| ST_AsText(ST_Simplify(ST_GeomFromText(''LINESTRING(0 0,0 2,2 2,2 4,4 4,4 6,6 6)''), 0.5)) |\n+-----------------------------------------------------------------------------------------+\n| LINESTRING(0 0,0 2,2 2,2 4,4 4,4 6,6 6)                                                 |\n+-----------------------------------------------------------------------------------------+\n\nSELECT ST_AsText(ST_Simplify(ST_GeomFromText(''LINESTRING(0 0,0 2,2 2,2 4,4 4,4 6,6 6)''), 1));  \n+---------------------------------------------------------------------------------------+\n| ST_AsText(ST_Simplify(ST_GeomFromText(''LINESTRING(0 0,0 2,2 2,2 4,4 4,4 6,6 6)''), 1)) |\n+---------------------------------------------------------------------------------------+\n| LINESTRING(0 0,0 2,2 2,2 4,6 6)                                                       |\n+---------------------------------------------------------------------------------------+\n\nURL: https://mariadb.com/docs/server/reference/sql-statements/geometry-constructors/miscellaneous-gis-functions/st_simplify', '', 'https://mariadb.com/docs/server/reference/sql-statements/geometry-constructors/miscellaneous-gis-functions/st_simplify');
INSERT INTO help_topic (help_topic_id, help_category_id, name, description, example, url) VALUES (783, 34, 'ST\\_Validate', 'Syntax\n------\n\nST_Validate(g)\n\nDescription\n-----------\n\nThe function checks that a given geometry is compliant with the Well-Known Binary (WKB) format and Spatial Reference System Identifier (SRID) syntax, and is geometrically valid.\n\nIt returns the geometry if it''s valid, or NULL if not.\n\nThe function is useful to filter out invalid geometry data.\n\nExamples\n--------\n\nSELECT ST_ASTEXT(ST_VALIDATE(ST_GeomFromText(''POINT(1 0)'')));          \n+-------------------------------------------------------+\n| ST_ASTEXT(ST_VALIDATE(ST_GeomFromText(''POINT(1 0)''))) |\n+-------------------------------------------------------+\n| POINT(1 0)                                            |\n+-------------------------------------------------------+\n\nSELECT ST_ASTEXT(ST_VALIDATE(ST_GeomFromText(''POINT(1)'')));  \n+-----------------------------------------------------+\n| ST_ASTEXT(ST_VALIDATE(ST_GeomFromText(''POINT(1)''))) |\n+-----------------------------------------------------+\n| NULL                                                |\n+-----------------------------------------------------+\n\nURL: https://mariadb.com/docs/server/reference/sql-statements/geometry-constructors/miscellaneous-gis-functions/st_validate', '', 'https://mariadb.com/docs/server/reference/sql-statements/geometry-constructors/miscellaneous-gis-functions/st_validate');
INSERT INTO help_topic (help_topic_id, help_category_id, name, description, example, url) VALUES (784, 34, 'X', 'Description\n-----------\n\nA synonym for ST_X.\n\nURL: https://mariadb.com/docs/server/reference/sql-statements/geometry-constructors/point-properties/point-properties-x', '', 'https://mariadb.com/docs/server/reference/sql-statements/geometry-constructors/point-properties/point-properties-x');
INSERT INTO help_topic (help_topic_id, help_category_id, name, description, example, url) VALUES (785, 34, 'Y', 'Description\n-----------\n\nA synonym for ST_Y.\n\nURL: https://mariadb.com/docs/server/reference/sql-statements/geometry-constructors/point-properties/point-properties-y', '', 'https://mariadb.com/docs/server/reference/sql-statements/geometry-constructors/point-properties/point-properties-y');
INSERT INTO help_topic (help_topic_id, help_category_id, name, description, example, url) VALUES (786, 34, 'ST\\_X', 'Syntax\n------\n\nST_X(p)\nX(p)\n\nDescription\n-----------\n\nReturns the X-coordinate value for the point p as a double-precision number.\n\nST_X() and X() are synonyms.\n\nExamples\n--------\n\nSET @pt = ''Point(56.7 53.34)'';\n\nSELECT X(GeomFromText(@pt));\n+----------------------+\n| X(GeomFromText(@pt)) |\n+----------------------+\n|                 56.7 |\n+----------------------+\n\nURL: https://mariadb.com/docs/server/reference/sql-statements/geometry-constructors/point-properties/st_x', '', 'https://mariadb.com/docs/server/reference/sql-statements/geometry-constructors/point-properties/st_x');
INSERT INTO help_topic (help_topic_id, help_category_id, name, description, example, url) VALUES (787, 34, 'ST\\_Y', 'Syntax\n------\n\nST_Y(p)\nY(p)\n\nDescription\n-----------\n\nReturns the Y-coordinate value for the point p as a double-precision number.\n\nST_Y() and Y() are synonyms.\n\nExamples\n--------\n\nSET @pt = ''Point(56.7 53.34)'';\n\nSELECT Y(GeomFromText(@pt));\n+----------------------+\n| Y(GeomFromText(@pt)) |\n+----------------------+\n|                53.34 |\n+----------------------+\n\nURL: https://mariadb.com/docs/server/reference/sql-statements/geometry-constructors/point-properties/st_y', '', 'https://mariadb.com/docs/server/reference/sql-statements/geometry-constructors/point-properties/st_y');
INSERT INTO help_topic (help_topic_id, help_category_id, name, description, example, url) VALUES (788, 34, 'CENTROID', 'Description\n-----------\n\nA synonym for ST_CENTROID.\n\nURL: https://mariadb.com/docs/server/reference/sql-statements/geometry-constructors/polygon-properties/centroid', '', 'https://mariadb.com/docs/server/reference/sql-statements/geometry-constructors/polygon-properties/centroid');
INSERT INTO help_topic (help_topic_id, help_category_id, name, description, example, url) VALUES (789, 34, 'AREA', 'Description\n-----------\n\nA synonym for ST_AREA.\n\nURL: https://mariadb.com/docs/server/reference/sql-statements/geometry-constructors/polygon-properties/polygon-properties-area', '', 'https://mariadb.com/docs/server/reference/sql-statements/geometry-constructors/polygon-properties/polygon-properties-area');
INSERT INTO help_topic (help_topic_id, help_category_id, name, description, example, url) VALUES (790, 34, 'ExteriorRing', 'Description\n-----------\n\nA synonym for ST_ExteriorRing.\n\nURL: https://mariadb.com/docs/server/reference/sql-statements/geometry-constructors/polygon-properties/polygon-properties-exteriorring', '', 'https://mariadb.com/docs/server/reference/sql-statements/geometry-constructors/polygon-properties/polygon-properties-exteriorring');
INSERT INTO help_topic (help_topic_id, help_category_id, name, description, example, url) VALUES (791, 34, 'InteriorRingN', 'Description\n-----------\n\nA synonym for ST_InteriorRingN.\n\nURL: https://mariadb.com/docs/server/reference/sql-statements/geometry-constructors/polygon-properties/polygon-properties-interiorringn', '', 'https://mariadb.com/docs/server/reference/sql-statements/geometry-constructors/polygon-properties/polygon-properties-interiorringn');
INSERT INTO help_topic (help_topic_id, help_category_id, name, description, example, url) VALUES (792, 34, 'NumInteriorRings', 'Description\n-----------\n\nA synonym for ST_NumInteriorRings.\n\nURL: https://mariadb.com/docs/server/reference/sql-statements/geometry-constructors/polygon-properties/polygon-properties-numinteriorrings', '', 'https://mariadb.com/docs/server/reference/sql-statements/geometry-constructors/polygon-properties/polygon-properties-numinteriorrings');
INSERT INTO help_topic (help_topic_id, help_category_id, name, description, example, url) VALUES (793, 34, 'ST\\_AREA', 'Syntax\n------\n\nST_Area(poly)\nArea(poly)\n\nDescription\n-----------\n\nReturns as a double-precision number the area of the Polygon value poly, as measured in its spatial reference system.\n\nST_Area() and Area() are synonyms.\n\nExamples\n--------\n\nSET @poly = ''Polygon((0 0,0 3,3 0,0 0),(1 1,1 2,2 1,1 1))'';\n\nSELECT Area(GeomFromText(@poly));\n+---------------------------+\n| Area(GeomFromText(@poly)) |\n+---------------------------+\n|                         4 |\n+---------------------------+\n\nURL: https://mariadb.com/docs/server/reference/sql-statements/geometry-constructors/polygon-properties/st_area', '', 'https://mariadb.com/docs/server/reference/sql-statements/geometry-constructors/polygon-properties/st_area');
INSERT INTO help_topic (help_topic_id, help_category_id, name, description, example, url) VALUES (794, 34, 'ST\\_CENTROID', 'Syntax\n------\n\nST_Centroid(mpoly)\nCentroid(mpoly)\n\nDescription\n-----------\n\nReturns a point reflecting the mathematical centroid (geometric center) for the MultiPolygon _mpoly_. The resulting point will not necessarily be on the MultiPolygon.\n\nST_Centroid() and Centroid() are synonyms.\n\nExamples\n--------\n\nSET @poly = ST_GeomFromText(''POLYGON((0 0,20 0,20 20,0 20,0 0))'');\nSELECT ST_AsText(ST_Centroid(@poly)) AS center;\n+--------------+\n| center       |\n+--------------+\n| POINT(10 10) |\n+--------------+\n\nURL: https://mariadb.com/docs/server/reference/sql-statements/geometry-constructors/polygon-properties/st_centroid', '', 'https://mariadb.com/docs/server/reference/sql-statements/geometry-constructors/polygon-properties/st_centroid');
INSERT INTO help_topic (help_topic_id, help_category_id, name, description, example, url) VALUES (795, 34, 'ST\\_ExteriorRing', 'Syntax\n------\n\nST_ExteriorRing(poly)\nExteriorRing(poly)\n\nDescription\n-----------\n\nReturns the exterior ring of the Polygon value poly as a LineString.\n\nST_ExteriorRing() and ExteriorRing() are synonyms.\n\nExamples\n--------\n\nSET @poly = ''Polygon((0 0,0 3,3 3,3 0,0 0),(1 1,1 2,2 2,2 1,1 1))'';\n\nSELECT AsText(ExteriorRing(GeomFromText(@poly)));\n+-------------------------------------------+\n| AsText(ExteriorRing(GeomFromText(@poly))) |\n+-------------------------------------------+\n| LINESTRING(0 0,0 3,3 3,3 0,0 0)           |\n+-------------------------------------------+\n\nURL: https://mariadb.com/docs/server/reference/sql-statements/geometry-constructors/polygon-properties/st_exteriorring', '', 'https://mariadb.com/docs/server/reference/sql-statements/geometry-constructors/polygon-properties/st_exteriorring');
INSERT INTO help_topic (help_topic_id, help_category_id, name, description, example, url) VALUES (796, 34, 'ST\\_InteriorRingN', 'Syntax\n------\n\nST_InteriorRingN(poly,N)\nInteriorRingN(poly,N)\n\nDescription\n-----------\n\nReturns the N-th interior ring for the Polygon value poly as a LineString. Rings are numbered beginning with 1.\n\nST_InteriorRingN() and InteriorRingN() are synonyms.\n\nExamples\n--------\n\nSET @poly = ''Polygon((0 0,0 3,3 3,3 0,0 0),(1 1,1 2,2 2,2 1,1 1))'';\n\nSELECT AsText(InteriorRingN(GeomFromText(@poly),1));\n+----------------------------------------------+\n| AsText(InteriorRingN(GeomFromText(@poly),1)) |\n+----------------------------------------------+\n| LINESTRING(1 1,1 2,2 2,2 1,1 1)              |\n+----------------------------------------------+\n\nURL: https://mariadb.com/docs/server/reference/sql-statements/geometry-constructors/polygon-properties/st_interiorringn', '', 'https://mariadb.com/docs/server/reference/sql-statements/geometry-constructors/polygon-properties/st_interiorringn');
INSERT INTO help_topic (help_topic_id, help_category_id, name, description, example, url) VALUES (797, 34, 'ST\\_NumInteriorRings', 'Syntax\n------\n\nST_NumInteriorRings(poly)\nNumInteriorRings(poly)\n\nDescription\n-----------\n\nReturns an integer containing the number of interior rings in the Polygon value poly.\n\nNote that according the OpenGIS standard, a POLYGON should have exactly one ExteriorRing and all other rings should lie within that ExteriorRing and thus be the InteriorRings. Practically, however, some systems, including MariaDB''s, permit polygons to have several ''ExteriorRings''. In the case of there being multiple, non-overlapping exterior rings ST_NumInteriorRings() will return 1.\n\nST_NumInteriorRings() and NumInteriorRings() are synonyms.\n\nExamples\n--------\n\nSET @poly = ''Polygon((0 0,0 3,3 3,3 0,0 0),(1 1,1 2,2 2,2 1,1 1))'';\n\nSELECT NumInteriorRings(GeomFromText(@poly));\n+---------------------------------------+\n| NumInteriorRings(GeomFromText(@poly)) |\n+---------------------------------------+\n|                                     1 |\n+---------------------------------------+\n\nURL: https://mariadb.com/docs/server/reference/sql-statements/geometry-constructors/polygon-properties/st_numinteriorrings', '', 'https://mariadb.com/docs/server/reference/sql-statements/geometry-constructors/polygon-properties/st_numinteriorrings');
INSERT INTO help_topic (help_topic_id, help_category_id, name, description, example, url) VALUES (798, 34, 'AsWKB', 'Description\n-----------\n\nA synonym for ST_AsBinary().\n\nURL: https://mariadb.com/docs/server/reference/sql-statements/geometry-constructors/wkb/aswkb', '', 'https://mariadb.com/docs/server/reference/sql-statements/geometry-constructors/wkb/aswkb');
INSERT INTO help_topic (help_topic_id, help_category_id, name, description, example, url) VALUES (799, 34, 'GeometryCollectionFromWKB', 'Description\n-----------\n\nA synonym for ST_GeomCollFromWKB.\n\nURL: https://mariadb.com/docs/server/reference/sql-statements/geometry-constructors/wkb/geometrycollectionfromwkb', '', 'https://mariadb.com/docs/server/reference/sql-statements/geometry-constructors/wkb/geometrycollectionfromwkb');
INSERT INTO help_topic (help_topic_id, help_category_id, name, description, example, url) VALUES (800, 34, 'GeometryFromWKB', 'Description\n-----------\n\nA synonym for ST_GeomFromWKB.\n\nURL: https://mariadb.com/docs/server/reference/sql-statements/geometry-constructors/wkb/geometryfromwkb', '', 'https://mariadb.com/docs/server/reference/sql-statements/geometry-constructors/wkb/geometryfromwkb');
INSERT INTO help_topic (help_topic_id, help_category_id, name, description, example, url) VALUES (801, 34, 'LineStringFromWKB', 'Description\n-----------\n\nA synonym for ST_LineFromWKB.\n\nURL: https://mariadb.com/docs/server/reference/sql-statements/geometry-constructors/wkb/linestringfromwkb', '', 'https://mariadb.com/docs/server/reference/sql-statements/geometry-constructors/wkb/linestringfromwkb');
INSERT INTO help_topic (help_topic_id, help_category_id, name, description, example, url) VALUES (802, 34, 'MLineFromWKB', 'Syntax\n------\n\nMLineFromWKB(wkb[,srid])\nMultiLineStringFromWKB(wkb[,srid])\n\nDescription\n-----------\n\nConstructs a MULTILINESTRING value using its WKB representation and SRID.\n\nMLineFromWKB() and MultiLineStringFromWKB() are synonyms.\n\nExamples\n--------\n\nSET @g = ST_AsBinary(MLineFromText(''MULTILINESTRING((10 48,10 21,10 0),(16 0,16 23,16 48))''));\n\nSELECT ST_AsText(MLineFromWKB(@g));\n+--------------------------------------------------------+\n| ST_AsText(MLineFromWKB(@g))                            |\n+--------------------------------------------------------+\n| MULTILINESTRING((10 48,10 21,10 0),(16 0,16 23,16 48)) |\n+--------------------------------------------------------+\n\nURL: https://mariadb.com/docs/server/reference/sql-statements/geometry-constructors/wkb/mlinefromwkb', '', 'https://mariadb.com/docs/server/reference/sql-statements/geometry-constructors/wkb/mlinefromwkb');
INSERT INTO help_topic (help_topic_id, help_category_id, name, description, example, url) VALUES (803, 34, 'MPointFromWKB', 'Syntax\n------\n\nMPointFromWKB(wkb[,srid])\nMultiPointFromWKB(wkb[,srid])\n\nDescription\n-----------\n\nConstructs a MULTIPOINT value using its WKB representation and SRID.\n\nMPointFromWKB() and MultiPointFromWKB() are synonyms.\n\nExamples\n--------\n\nSET @g = ST_AsBinary(MPointFromText(''MultiPoint( 1 1, 2 2, 5 3, 7 2, 9 3, 8 4, 6 6, 6 9, 4 9, 1 5 )''));\n\nSELECT ST_AsText(MPointFromWKB(@g));\n+-----------------------------------------------------+\n| ST_AsText(MPointFromWKB(@g))                        |\n+-----------------------------------------------------+\n| MULTIPOINT(1 1,2 2,5 3,7 2,9 3,8 4,6 6,6 9,4 9,1 5) |\n+-----------------------------------------------------+\n\nURL: https://mariadb.com/docs/server/reference/sql-statements/geometry-constructors/wkb/mpointfromwkb', '', 'https://mariadb.com/docs/server/reference/sql-statements/geometry-constructors/wkb/mpointfromwkb');
INSERT INTO help_topic (help_topic_id, help_category_id, name, description, example, url) VALUES (804, 34, 'MPolyFromWKB', 'Syntax\n------\n\nMPolyFromWKB(wkb[,srid])\nMultiPolygonFromWKB(wkb[,srid])\n\nDescription\n-----------\n\nConstructs a MULTIPOLYGON value using its WKB representation and SRID.\n\nMPolyFromWKB() and MultiPolygonFromWKB() are synonyms.\n\nExamples\n--------\n\nSET @g = ST_AsBinary(MPointFromText(''MULTIPOLYGON(((28 26,28 0,84 0,84 42,28 26),(52 18,66 23,73 9,48 6,52 18)),((59 18,67 18,67 13,59 13,59 18)))''));\n\nSELECT ST_AsText(MPolyFromWKB(@g))\\G\n************************ 1. row ************************\nST_AsText(MPolyFromWKB(@g)): MULTIPOLYGON(((28 26,28 0,84 0,84 42,28 26),(52 18,66 23,73 9,48 6,52 18)),((59 18,67 18,67 13,59 13,59 18)))\n\nURL: https://mariadb.com/docs/server/reference/sql-statements/geometry-constructors/wkb/mpolyfromwkb', '', 'https://mariadb.com/docs/server/reference/sql-statements/geometry-constructors/wkb/mpolyfromwkb');
INSERT INTO help_topic (help_topic_id, help_category_id, name, description, example, url) VALUES (805, 34, 'MultiLineStringFromWKB', 'Description\n-----------\n\nA synonym for MLineFromWKB().\n\nURL: https://mariadb.com/docs/server/reference/sql-statements/geometry-constructors/wkb/multilinestringfromwkb', '', 'https://mariadb.com/docs/server/reference/sql-statements/geometry-constructors/wkb/multilinestringfromwkb');
INSERT INTO help_topic (help_topic_id, help_category_id, name, description, example, url) VALUES (806, 34, 'MultiPointFromWKB', 'Description\n-----------\n\nA synonym for MPointFromWKB.\n\nURL: https://mariadb.com/docs/server/reference/sql-statements/geometry-constructors/wkb/multipointfromwkb', '', 'https://mariadb.com/docs/server/reference/sql-statements/geometry-constructors/wkb/multipointfromwkb');
INSERT INTO help_topic (help_topic_id, help_category_id, name, description, example, url) VALUES (807, 34, 'MultiPolygonFromWKB', 'Description\n-----------\n\nSynonym for MPolyFromWKB.\n\nURL: https://mariadb.com/docs/server/reference/sql-statements/geometry-constructors/wkb/multipolygonfromwkb', '', 'https://mariadb.com/docs/server/reference/sql-statements/geometry-constructors/wkb/multipolygonfromwkb');
INSERT INTO help_topic (help_topic_id, help_category_id, name, description, example, url) VALUES (808, 34, 'PolygonFromWKB', 'Description\n-----------\n\nA synonym for ST_PolyFromWKB.\n\nURL: https://mariadb.com/docs/server/reference/sql-statements/geometry-constructors/wkb/polygonfromwkb', '', 'https://mariadb.com/docs/server/reference/sql-statements/geometry-constructors/wkb/polygonfromwkb');
INSERT INTO help_topic (help_topic_id, help_category_id, name, description, example, url) VALUES (809, 34, 'ST\\_AsBinary', 'Syntax\n------\n\nST_AsBinary(g)\nAsBinary(g)\nST_AsWKB(g)\nAsWKB(g)\n\nDescription\n-----------\n\nConverts a value in internal geometry format to its WKB representation and returns the binary result.\n\nST_AsBinary(), AsBinary(), ST_AsWKB() and AsWKB() are synonyms,\n\nExamples\n--------\n\nSET @poly = ST_GeomFromText(''POLYGON((0 0,0 1,1 1,1 0,0 0))'');\nSELECT ST_AsBinary(@poly);\n\nSELECT ST_AsText(ST_GeomFromWKB(ST_AsWKB(@poly)));\n+--------------------------------------------+\n| ST_AsText(ST_GeomFromWKB(ST_AsWKB(@poly))) |\n+--------------------------------------------+\n| POLYGON((0 0,0 1,1 1,1 0,0 0))             |\n+--------------------------------------------+\n\nURL: https://mariadb.com/docs/server/reference/sql-statements/geometry-constructors/wkb/st_asbinary', '', 'https://mariadb.com/docs/server/reference/sql-statements/geometry-constructors/wkb/st_asbinary');
INSERT INTO help_topic (help_topic_id, help_category_id, name, description, example, url) VALUES (810, 34, 'ST\\_AsWKB', 'Description\n-----------\n\nA synonym for ST_AsBinary().\n\nURL: https://mariadb.com/docs/server/reference/sql-statements/geometry-constructors/wkb/st_aswkb', '', 'https://mariadb.com/docs/server/reference/sql-statements/geometry-constructors/wkb/st_aswkb');
INSERT INTO help_topic (help_topic_id, help_category_id, name, description, example, url) VALUES (811, 34, 'ST\\_GeomCollFromWKB', 'Syntax\n------\n\nST_GeomCollFromWKB(wkb[,srid])\nST_GeometryCollectionFromWKB(wkb[,srid])\nGeomCollFromWKB(wkb[,srid])\nGeometryCollectionFromWKB(wkb[,srid])\n\nDescription\n-----------\n\nConstructs a GEOMETRYCOLLECTION value using its WKB representation and SRID.\n\nST_GeomCollFromWKB(), ST_GeometryCollectionFromWKB(), GeomCollFromWKB() and GeometryCollectionFromWKB() are synonyms.\n\nExamples\n--------\n\nSET @g = ST_AsBinary(ST_GeomFromText(''GEOMETRYCOLLECTION(\n   POLYGON((5 5,10 5,10 10,5 5)),POINT(10 10))''));\n\nSELECT ST_AsText(ST_GeomCollFromWKB(@g));\n+----------------------------------------------------------------+\n| ST_AsText(ST_GeomCollFromWKB(@g))                              |\n+----------------------------------------------------------------+\n| GEOMETRYCOLLECTION(POLYGON((5 5,10 5,10 10,5 5)),POINT(10 10)) |\n+----------------------------------------------------------------+\n\nURL: https://mariadb.com/docs/server/reference/sql-statements/geometry-constructors/wkb/st_geomcollfromwkb', '', 'https://mariadb.com/docs/server/reference/sql-statements/geometry-constructors/wkb/st_geomcollfromwkb');
INSERT INTO help_topic (help_topic_id, help_category_id, name, description, example, url) VALUES (812, 34, 'ST\\_GeometryCollectionFromWKB', 'Description\n-----------\n\nA synonym for ST_GeomCollFromWKB.\n\nURL: https://mariadb.com/docs/server/reference/sql-statements/geometry-constructors/wkb/st_geometrycollectionfromwkb', '', 'https://mariadb.com/docs/server/reference/sql-statements/geometry-constructors/wkb/st_geometrycollectionfromwkb');
INSERT INTO help_topic (help_topic_id, help_category_id, name, description, example, url) VALUES (813, 34, 'ST\\_GeometryFromWKB', 'Description\n-----------\n\nA synonym for ST_GeomFromWKB.\n\nURL: https://mariadb.com/docs/server/reference/sql-statements/geometry-constructors/wkb/st_geometryfromwkb', '', 'https://mariadb.com/docs/server/reference/sql-statements/geometry-constructors/wkb/st_geometryfromwkb');
INSERT INTO help_topic (help_topic_id, help_category_id, name, description, example, url) VALUES (814, 34, 'ST\\_GeomFromWKB', 'Syntax\n------\n\nST_GeomFromWKB(wkb[,srid])\nST_GeometryFromWKB(wkb[,srid])\nGeomFromWKB(wkb[,srid])\nGeometryFromWKB(wkb[,srid])\n\nDescription\n-----------\n\nConstructs a geometry value of any type using its WKB representation and SRID.\n\nST_GeomFromWKB(), ST_GeometryFromWKB(), GeomFromWKB() and GeometryFromWKB() are synonyms.\n\nExamples\n--------\n\nSET @g = ST_AsBinary(ST_LineFromText(''LINESTRING(0 4, 4 6)''));\n\nSELECT ST_AsText(ST_GeomFromWKB(@g));\n+-------------------------------+\n| ST_AsText(ST_GeomFromWKB(@g)) |\n+-------------------------------+\n| LINESTRING(0 4,4 6)           |\n+-------------------------------+\n\nURL: https://mariadb.com/docs/server/reference/sql-statements/geometry-constructors/wkb/st_geomfromwkb', '', 'https://mariadb.com/docs/server/reference/sql-statements/geometry-constructors/wkb/st_geomfromwkb');
INSERT INTO help_topic (help_topic_id, help_category_id, name, description, example, url) VALUES (815, 34, 'ST\\_LineFromWKB', 'Syntax\n------\n\nST_LineFromWKB(wkb[,srid])\nLineFromWKB(wkb[,srid])\nST_LineStringFromWKB(wkb[,srid])\nLineStringFromWKB(wkb[,srid])\n\nDescription\n-----------\n\nConstructs a LINESTRING value using its WKB representation and SRID.\n\nST_LineFromWKB(), LineFromWKB(), ST_LineStringFromWKB(), and LineStringFromWKB() are synonyms.\n\nExamples\n--------\n\nSET @g = ST_AsBinary(ST_LineFromText(''LineString(0 4,4 6)''));\n\nSELECT ST_AsText(ST_LineFromWKB(@g)) AS l;\n+---------------------+\n| l                   |\n+---------------------+\n| LINESTRING(0 4,4 6) |\n+---------------------+\n\nURL: https://mariadb.com/docs/server/reference/sql-statements/geometry-constructors/wkb/st_linefromwkb', '', 'https://mariadb.com/docs/server/reference/sql-statements/geometry-constructors/wkb/st_linefromwkb');
INSERT INTO help_topic (help_topic_id, help_category_id, name, description, example, url) VALUES (816, 34, 'ST\\_LineStringFromWKB', 'Description\n-----------\n\nA synonym for ST_LineFromWKB.\n\nURL: https://mariadb.com/docs/server/reference/sql-statements/geometry-constructors/wkb/st_linestringfromwkb', '', 'https://mariadb.com/docs/server/reference/sql-statements/geometry-constructors/wkb/st_linestringfromwkb');
INSERT INTO help_topic (help_topic_id, help_category_id, name, description, example, url) VALUES (817, 34, 'ST\\_MPointFromWKB', 'Description\n-----------\n\nA synonym for ST_GeomFromWKB.\n\nURL: https://mariadb.com/docs/server/reference/sql-statements/geometry-constructors/wkb/st_mpointfromwkb', '', 'https://mariadb.com/docs/server/reference/sql-statements/geometry-constructors/wkb/st_mpointfromwkb');
INSERT INTO help_topic (help_topic_id, help_category_id, name, description, example, url) VALUES (818, 34, 'ST\\_MPolyFromWKB', 'Description\n-----------\n\nA synonym for ST_GeomFromWKB.\n\nURL: https://mariadb.com/docs/server/reference/sql-statements/geometry-constructors/wkb/st_mpolyfromwkb', '', 'https://mariadb.com/docs/server/reference/sql-statements/geometry-constructors/wkb/st_mpolyfromwkb');
INSERT INTO help_topic (help_topic_id, help_category_id, name, description, example, url) VALUES (819, 34, 'ST\\_MultiPointFromWKB', 'Description\n-----------\n\nA synonym for ST_GeomFromWKB.\n\nURL: https://mariadb.com/docs/server/reference/sql-statements/geometry-constructors/wkb/st_multipointfromwkb', '', 'https://mariadb.com/docs/server/reference/sql-statements/geometry-constructors/wkb/st_multipointfromwkb');
INSERT INTO help_topic (help_topic_id, help_category_id, name, description, example, url) VALUES (820, 34, 'ST\\_MultiPolygonFromWKB', 'Description\n-----------\n\nA synonym for ST_GeomFromWKB.\n\nURL: https://mariadb.com/docs/server/reference/sql-statements/geometry-constructors/wkb/st_multipolygonfromwkb', '', 'https://mariadb.com/docs/server/reference/sql-statements/geometry-constructors/wkb/st_multipolygonfromwkb');
INSERT INTO help_topic (help_topic_id, help_category_id, name, description, example, url) VALUES (821, 34, 'ST\\_PointFromWKB', 'Syntax\n------\n\nST_PointFromWKB(wkb[,srid])\nPointFromWKB(wkb[,srid])\n\nDescription\n-----------\n\nConstructs a POINT value using its WKB representation and SRID.\n\nST_PointFromWKB() and PointFromWKB() are synonyms.\n\nExamples\n--------\n\nSET @g = ST_AsBinary(ST_PointFromText(''POINT(0 4)''));\n\nSELECT ST_AsText(ST_PointFromWKB(@g)) AS p;\n+------------+\n| p          |\n+------------+\n| POINT(0 4) |\n+------------+\n\nURL: https://mariadb.com/docs/server/reference/sql-statements/geometry-constructors/wkb/st_pointfromwkb', '', 'https://mariadb.com/docs/server/reference/sql-statements/geometry-constructors/wkb/st_pointfromwkb');
INSERT INTO help_topic (help_topic_id, help_category_id, name, description, example, url) VALUES (822, 34, 'ST\\_PolyFromWKB', 'Syntax\n------\n\nST_PolyFromWKB(wkb[,srid])\nST_PolygonFromWKB(wkb[,srid])\nPolyFromWKB(wkb[,srid])\nPolygonFromWKB(wkb[,srid])\n\nDescription\n-----------\n\nConstructs a POLYGON value using its WKB representation and SRID.\n\nST_PolyFromWKB(), ST_PolygonFromWKB(), PolyFromWKB() and PolygonFromWKB() are synonyms.\n\nExamples\n--------\n\nSET @g = ST_AsBinary(ST_PolyFromText(''POLYGON((1 1,1 5,4 9,6 9,9 3,7 2,1 1))''));\n\nSELECT ST_AsText(ST_PolyFromWKB(@g)) AS p;\n+----------------------------------------+\n| p                                      |\n+----------------------------------------+\n| POLYGON((1 1,1 5,4 9,6 9,9 3,7 2,1 1)) |\n+----------------------------------------+\n\nURL: https://mariadb.com/docs/server/reference/sql-statements/geometry-constructors/wkb/st_polyfromwkb', '', 'https://mariadb.com/docs/server/reference/sql-statements/geometry-constructors/wkb/st_polyfromwkb');
INSERT INTO help_topic (help_topic_id, help_category_id, name, description, example, url) VALUES (823, 34, 'ST\\_PolygonFromWKB', 'Description\n-----------\n\nA synonym for ST_PolyFromWKB.\n\nURL: https://mariadb.com/docs/server/reference/sql-statements/geometry-constructors/wkb/st_polygonfromwkb', '', 'https://mariadb.com/docs/server/reference/sql-statements/geometry-constructors/wkb/st_polygonfromwkb');
INSERT INTO help_topic (help_topic_id, help_category_id, name, description, example, url) VALUES (824, 34, 'Well-Known Binary (WKB) Format', 'Description\n-----------\n\nWKB stands for Well-Known Binary, a format for representing geographical and geometrical data.\n\nWKB uses 1-byte unsigned integers, 4-byte unsigned integers, and 8-byte double-precision numbers.\n\n The first byte indicates the byte order. 00 for big endian, or 01 for little endian.\n The next 4 bytes indicate the geometry type. Values from 1 to 7 indicate whether the type is Point, LineString, Polygon, MultiPoint, MultiLineString, MultiPolygon, or GeometryCollection respectively.\n The 8-byte floats represent the co-ordinates.\n\nTake the following example, a sequence of 21 bytes each represented by two hex digits:\n\n``\n000000000140000000000000004010000000000000\n``\n\n It''s big endian\n   000000000140000000000000004010000000000000\n It''s a POINT\n   000000000140000000000000004010000000000000\n The X co-ordinate is 2.0\n   000000000140000000000000004010000000000000\n The Y-co-ordinate is 4.0\n  * 000000000140000000000000004010000000000000\n\nURL: https://mariadb.com/docs/server/reference/sql-statements/geometry-constructors/wkb/well-known-binary-wkb-format', '', 'https://mariadb.com/docs/server/reference/sql-statements/geometry-constructors/wkb/well-known-binary-wkb-format');
INSERT INTO help_topic (help_topic_id, help_category_id, name, description, example, url) VALUES (825, 34, 'AsBinary', 'Description\n-----------\n\nA synonym for ST_AsBinary().\n\nURL: https://mariadb.com/docs/server/reference/sql-statements/geometry-constructors/wkb/wkb-asbinary', '', 'https://mariadb.com/docs/server/reference/sql-statements/geometry-constructors/wkb/wkb-asbinary');
INSERT INTO help_topic (help_topic_id, help_category_id, name, description, example, url) VALUES (826, 34, 'GeomCollFromWKB', 'Description\n-----------\n\nA synonym for ST_GeomCollFromWKB.\n\nURL: https://mariadb.com/docs/server/reference/sql-statements/geometry-constructors/wkb/wkb-geomcollfromwkb', '', 'https://mariadb.com/docs/server/reference/sql-statements/geometry-constructors/wkb/wkb-geomcollfromwkb');
INSERT INTO help_topic (help_topic_id, help_category_id, name, description, example, url) VALUES (827, 34, 'GeomFromWKB', 'Description\n-----------\n\nA synonym for ST_GeomFromWKB.\n\nURL: https://mariadb.com/docs/server/reference/sql-statements/geometry-constructors/wkb/wkb-geomfromwkb', '', 'https://mariadb.com/docs/server/reference/sql-statements/geometry-constructors/wkb/wkb-geomfromwkb');
INSERT INTO help_topic (help_topic_id, help_category_id, name, description, example, url) VALUES (828, 34, 'LineFromWKB', 'Description\n-----------\n\nA synonym for ST_LineFromWKB.\n\nURL: https://mariadb.com/docs/server/reference/sql-statements/geometry-constructors/wkb/wkb-linefromwkb', '', 'https://mariadb.com/docs/server/reference/sql-statements/geometry-constructors/wkb/wkb-linefromwkb');
INSERT INTO help_topic (help_topic_id, help_category_id, name, description, example, url) VALUES (829, 34, 'PointFromWKB', 'Description\n-----------\n\nA synonym for ST_PointFromWKB.\n\nURL: https://mariadb.com/docs/server/reference/sql-statements/geometry-constructors/wkb/wkb-pointfromwkb', '', 'https://mariadb.com/docs/server/reference/sql-statements/geometry-constructors/wkb/wkb-pointfromwkb');
INSERT INTO help_topic (help_topic_id, help_category_id, name, description, example, url) VALUES (830, 34, 'PolyFromWKB', 'Description\n-----------\n\nA synonym for ST_PolyFromWKB.\n\nURL: https://mariadb.com/docs/server/reference/sql-statements/geometry-constructors/wkb/wkb-polyfromwkb', '', 'https://mariadb.com/docs/server/reference/sql-statements/geometry-constructors/wkb/wkb-polyfromwkb');
INSERT INTO help_topic (help_topic_id, help_category_id, name, description, example, url) VALUES (831, 34, 'GeometryCollectionFromText', 'Description\n-----------\n\nA synonym for ST_GeomCollFromText.\n\nURL: https://mariadb.com/docs/server/reference/sql-statements/geometry-constructors/wkt/geometrycollectionfromtext', '', 'https://mariadb.com/docs/server/reference/sql-statements/geometry-constructors/wkt/geometrycollectionfromtext');
INSERT INTO help_topic (help_topic_id, help_category_id, name, description, example, url) VALUES (832, 34, 'GeometryFromText', 'Description\n-----------\n\nA synonym for ST_GeomFromText.\n\nURL: https://mariadb.com/docs/server/reference/sql-statements/geometry-constructors/wkt/geometryfromtext', '', 'https://mariadb.com/docs/server/reference/sql-statements/geometry-constructors/wkt/geometryfromtext');
INSERT INTO help_topic (help_topic_id, help_category_id, name, description, example, url) VALUES (833, 34, 'LineStringFromText', 'Description\n-----------\n\nA synonym for ST_LineFromText.\n\nURL: https://mariadb.com/docs/server/reference/sql-statements/geometry-constructors/wkt/linestringfromtext', '', 'https://mariadb.com/docs/server/reference/sql-statements/geometry-constructors/wkt/linestringfromtext');
INSERT INTO help_topic (help_topic_id, help_category_id, name, description, example, url) VALUES (834, 34, 'MLineFromText', 'Syntax\n------\n\nMLineFromText(wkt[,srid])\nMultiLineStringFromText(wkt[,srid])\n\nDescription\n-----------\n\nConstructs a MULTILINESTRING value using its WKT representation and SRID.\n\nMLineFromText() and MultiLineStringFromText() are synonyms.\n\nExamples\n--------\n\nCREATE TABLE gis_multi_line (g MULTILINESTRING);\nSHOW FIELDS FROM gis_multi_line;\nINSERT INTO gis_multi_line VALUES\n    (MultiLineStringFromText(''MULTILINESTRING((10 48,10 21,10 0),(16 0,16 23,16 48))'')),\n    (MLineFromText(''MULTILINESTRING((10 48,10 21,10 0))'')),\n    (MLineFromWKB(AsWKB(MultiLineString(\n      LineString(Point(1, 2), Point(3, 5)), \n      LineString(Point(2, 5), Point(5, 8), Point(21, 7))))));\n\nURL: https://mariadb.com/docs/server/reference/sql-statements/geometry-constructors/wkt/mlinefromtext', '', 'https://mariadb.com/docs/server/reference/sql-statements/geometry-constructors/wkt/mlinefromtext');
INSERT INTO help_topic (help_topic_id, help_category_id, name, description, example, url) VALUES (835, 34, 'MPointFromText', 'Syntax\n------\n\nMPointFromText(wkt[,srid])\nMultiPointFromText(wkt[,srid])\n\nDescription\n-----------\n\nConstructs a MULTIPOINT value using its WKT representation and SRID.\n\nMPointFromText() and MultiPointFromText() are synonyms.\n\nExamples\n--------\n\nCREATE TABLE gis_multi_point (g MULTIPOINT);\nSHOW FIELDS FROM gis_multi_point;\nINSERT INTO gis_multi_point VALUES\n    (MultiPointFromText(''MULTIPOINT(0 0,10 10,10 20,20 20)'')),\n    (MPointFromText(''MULTIPOINT(1 1,11 11,11 21,21 21)'')),\n    (MPointFromWKB(AsWKB(MultiPoint(Point(3, 6), Point(4, 10)))));\n\nURL: https://mariadb.com/docs/server/reference/sql-statements/geometry-constructors/wkt/mpointfromtext', '', 'https://mariadb.com/docs/server/reference/sql-statements/geometry-constructors/wkt/mpointfromtext');
INSERT INTO help_topic (help_topic_id, help_category_id, name, description, example, url) VALUES (836, 34, 'MPolyFromText', 'Syntax\n------\n\nMPolyFromText(wkt[,srid])\nMultiPolygonFromText(wkt[,srid])\n\nDescription\n-----------\n\nConstructs a MULTIPOLYGON value using its WKT representation and SRID.\n\nMPolyFromText() and MultiPolygonFromText() are synonyms.\n\nExamples\n--------\n\nCREATE TABLE gis_multi_polygon  (g MULTIPOLYGON);\nSHOW FIELDS FROM gis_multi_polygon;\nINSERT INTO gis_multi_polygon VALUES\n    (MultiPolygonFromText(''MULTIPOLYGON(\n       ((28 26,28 0,84 0,84 42,28 26),(52 18,66 23,73 9,48 6,52 18)),\n       ((59 18,67 18,67 13,59 13,59 18)))'')),\n    (MPolyFromText(''MULTIPOLYGON(\n       ((28 26,28 0,84 0,84 42,28 26),(52 18,66 23,73 9,48 6,52 18)),\n       ((59 18,67 18,67 13,59 13,59 18)))'')),\n    (MPolyFromWKB(AsWKB(MultiPolygon(Polygon(\n       LineString(Point(0, 3), Point(3, 3), Point(3, 0), Point(0, 3)))))));\n\nURL: https://mariadb.com/docs/server/reference/sql-statements/geometry-constructors/wkt/mpolyfromtext', '', 'https://mariadb.com/docs/server/reference/sql-statements/geometry-constructors/wkt/mpolyfromtext');
INSERT INTO help_topic (help_topic_id, help_category_id, name, description, example, url) VALUES (837, 34, 'MultiLineStringFromText', 'Description\n-----------\n\nA synonym for MLineFromText.\n\nURL: https://mariadb.com/docs/server/reference/sql-statements/geometry-constructors/wkt/multilinestringfromtext', '', 'https://mariadb.com/docs/server/reference/sql-statements/geometry-constructors/wkt/multilinestringfromtext');
INSERT INTO help_topic (help_topic_id, help_category_id, name, description, example, url) VALUES (838, 34, 'MultiPointFromText', 'Description\n-----------\n\nA synonym for MPointFromText.\n\nURL: https://mariadb.com/docs/server/reference/sql-statements/geometry-constructors/wkt/multipointfromtext', '', 'https://mariadb.com/docs/server/reference/sql-statements/geometry-constructors/wkt/multipointfromtext');
INSERT INTO help_topic (help_topic_id, help_category_id, name, description, example, url) VALUES (839, 34, 'MultiPolygonFromText', 'Description\n-----------\n\nA synonym for MPolyFromText.\n\nURL: https://mariadb.com/docs/server/reference/sql-statements/geometry-constructors/wkt/multipolygonfromtext', '', 'https://mariadb.com/docs/server/reference/sql-statements/geometry-constructors/wkt/multipolygonfromtext');
INSERT INTO help_topic (help_topic_id, help_category_id, name, description, example, url) VALUES (840, 34, 'PolygonFromText', 'Description\n-----------\n\nA synonym for ST_PolyFromText.\n\nURL: https://mariadb.com/docs/server/reference/sql-statements/geometry-constructors/wkt/polygonfromtext', '', 'https://mariadb.com/docs/server/reference/sql-statements/geometry-constructors/wkt/polygonfromtext');
INSERT INTO help_topic (help_topic_id, help_category_id, name, description, example, url) VALUES (841, 34, 'ST\\_AsText', 'Syntax\n------\n\nST_AsText(g)\nAsText(g)\nST_AsWKT(g)\nAsWKT(g)\n\nDescription\n-----------\n\nConverts a value in internal geometry format to its WKT representation and returns the string result.\n\nST_AsText(), AsText(), ST_AsWKT() and AsWKT() are all synonyms.\n\nExamples\n--------\n\nSET @g = ''LineString(1 1,4 4,6 6)'';\n\nSELECT ST_AsText(ST_GeomFromText(@g));\n+--------------------------------+\n| ST_AsText(ST_GeomFromText(@g)) |\n+--------------------------------+\n| LINESTRING(1 1,4 4,6 6)        |\n+--------------------------------+\n\nURL: https://mariadb.com/docs/server/reference/sql-statements/geometry-constructors/wkt/st_astext', '', 'https://mariadb.com/docs/server/reference/sql-statements/geometry-constructors/wkt/st_astext');
