9.2.5 函数名称解析和解析

MySQL 支持内置(本机)函数,用户定义函数(UDF)和存储函数。本节描述服务器如何识别内置函数的名称是用作函数调用还是用作标识符,以及在给定名称存在不同类型的函数的情况下,服务器如何确定使用哪个函数。

内置函数名称解析

解析器使用默认规则来解析内置函数的名称。通过启用IGNORE_SPACE SQL 模式可以更改这些规则。

当解析器遇到一个单词,它是内置函数的名称时,它必须确定该名称是 table 示函数调用还是作为对 table 或列名之类的标识符的非 table 达式引用。例如,在以下语句中,对count的第一个引用是函数调用,而第二个引用是 table 名称:

SELECT COUNT(*) FROM mytable;
CREATE TABLE count (i INT);

解析器应仅在解析预期为 table 达式的内容时才将内置函数的名称识别为指示函数调用。即,在非 table 达式上下文中,允许使用函数名作为标识符。

但是,某些内置函数具有特殊的解析或实现注意事项,因此解析器默认情况下使用以下规则来区分其名称是在非 table 达式上下文中用作函数调用还是用作标识符:

名称和括号之间不得包含空格的函数调用要求仅适用于具有特殊注意事项的内置函数。 COUNT是这样的名称。 sql/lex.h源文件列出了这些特殊功能的名称,其后的空格决定了它们的解释:symbols[]数组中SYM_FN()宏定义的名称。

以下列 table 列出了受IGNORE_SPACE设置影响并在sql/lex.h源文件中以特殊方式列出的 MySQL 5.7 中的函数。您可能会发现将无空格要求应用于所有函数调用是最容易的。

对于sql/lex.h中未列出为特殊功能的功能,空格无关紧要。仅当在 table 达式上下文中使用它们时,它们才被解释为函数调用,否则可以自由用作标识符。 ASCII是这样的名称之一。但是,对于这些不受影响的函数名称,在 table 达式上下文中的解释可能有所不同:func_name ()被解释为内置函数(如果存在一个具有给定名称的函数);如果不是,则func_name ()被解释为用户定义的函数或存储的函数(如果存在具有该名称的函数)。

IGNORE_SPACE SQL 模式可用于修改解析器如何处理对空格敏感的函数名称:

mysql> CREATE TABLE count(i INT);
ERROR 1064 (42000): You have an error in your SQL syntax ...
near 'count(i INT)'

要消除该错误并使名称被视为标识符,请在名称后使用空格或将其写为带引号的标识符(或同时使用两者):

CREATE TABLE count (i INT);
CREATE TABLE `count`(i INT);
CREATE TABLE `count` (i INT);
SELECT COUNT(*) FROM mytable;
SELECT COUNT (*) FROM mytable;

但是,启用IGNORE_SPACE也会带来副作用,即解析器会将受影响的函数名称视为保留字(请参见第 9.3 节“关键字和保留字”)。这意味着名称后的空格不再 table 示其用作标识符。该名称可在带有或不带有空格的函数调用中使用,但除非在引用前加引号,否则会在非 table 达式上下文中引起语法错误。例如,在启用IGNORE_SPACE的情况下,以下两个语句均会因语法错误而失败,因为解析器会将count解释为保留字:

CREATE TABLE count(i INT);
CREATE TABLE count (i INT);

要在非 table 达式上下文中使用函数名称,请将其写为带引号的标识符:

CREATE TABLE `count`(i INT);
CREATE TABLE `count` (i INT);

要启用IGNORE_SPACE SQL 模式,请使用以下语句:

SET sql_mode = 'IGNORE_SPACE';

某些其他复合模式(例如ANSI)也将IGNORE_SPACE启用,并将它们包含在其值中:

SET sql_mode = 'ANSI';

检查第 5.1.10 节“服务器 SQL 模式”,以查看启用IGNORE_SPACE的复合模式。

为了使 SQL 代码对IGNORE_SPACE设置的依赖性最小,请使用以下准则:

CREATE TABLE count(i INT);
CREATE TABLE count (i INT);

如果必须在非 table 达式上下文中使用函数名称,请将其写为带引号的标识符:

CREATE TABLE `count`(i INT);
CREATE TABLE `count` (i INT);

函数名称解析

以下规则描述了服务器如何将对函数名称的引用解析为函数创建和调用:

如果尝试创建与内置函数同名的 UDF,则会发生错误。

可以使用与内置函数相同的名称来创建存储函数,但是要调用该存储函数,必须使用架构名称对其进行限定。例如,如果您在test模式中创建一个名为PI的存储函数,请以test.PI()的形式调用它,因为服务器在不使用限定符的情况下解析PI()作为对内置函数的引用。如果存储的函数名与内置函数名冲突,则服务器会生成警告。可以使用SHOW WARNINGS显示警告。

用户定义的函数和存储的函数共享相同的名称空间,因此您无法创建 UDF 和具有相同名称的存储函数。

前面的函数名称解析规则对升级到实现新内置函数的 MySQL 版本有影响:

首页