Loading...
MySQL 9.5 Reference Manual 9.5의 11.2.5 Function Name Parsing and Resolution의 한국어 번역본입니다.
아래의 경우에 피드백에서 신고해주신다면 반영하겠습니다.
감사합니다 :)
MySQL은 내장(built-in, native) 함수, 로더블 함수, 스토어드 함수를 지원합니다. 이 섹션에서는 서버가 내장 함수의 이름이 함수 호출로 사용되는지, 아니면 식이 아닌(identifier에 대한) 참조(예: 테이블 또는 컬럼 이름)로 사용되는지를 어떻게 인식하는지, 그리고 동일한 이름을 가진 서로 다른 타입의 함수가 존재하는 경우 서버가 어떤 함수를 사용할지 어떻게 결정하는지를 설명합니다.
파서는 내장 함수 이름을 파싱하기 위한 기본 규칙을 사용합니다. 이 규칙은 IGNORE_SPACE SQL 모드를 활성화하여 변경할 수 있습니다.
파서가 내장 함수 이름인 단어를 만나면, 해당 이름이 함수 호출을 의미하는지, 아니면 테이블이나 컬럼 이름과 같은 식이 아닌(nonexpression) 식별자 참조인지를 결정해야 합니다. 예를 들어, 다음 문장에서 첫 번째 count 참조는 함수 호출인 반면, 두 번째 참조는 테이블 이름입니다:
1SELECT COUNT(*) FROM mytable; 2CREATE TABLE count (i INT);
파서는 식이 올 것으로 예상되는 부분을 파싱할 때에만 내장 함수의 이름을 함수 호출을 나타내는 것으로 인식해야 합니다. 즉, 식이 아닌(nonexpression) 컨텍스트에서는 함수 이름을 식별자로 사용하는 것이 허용됩니다.
그러나 일부 내장 함수에는 특별한 파싱 또는 구현상의 고려 사항이 있으므로, 파서는 기본적으로 다음 규칙을 사용하여 그 이름이 함수 호출로 사용되는지, 아니면 식이 아닌(nonexpression) 컨텍스트에서 식별자로 사용되는지를 구분합니다:
식에서 함수 호출로 이름을 사용하려면, 이름과 그 뒤에 오는 ( 괄호 문자 사이에 공백이 없어야 합니다.
반대로, 함수 이름을 식별자로 사용하려면 이름 뒤에 바로 괄호가 따라오지 않아야 합니다.
함수 호출이 이름과 괄호 사이에 공백 없이 작성되어야 한다는 요구 사항은, 특별한 고려 사항이 있는 내장 함수에만 적용됩니다. COUNT가 그러한 이름 중 하나입니다. sql/lex.h 소스 파일은 공백의 유무에 따라 해석이 결정되는 이러한 특수 함수들의 이름을 나열합니다. 이들은 symbols[] 배열 안에서 SYM_FN() 매크로로 정의된 이름들입니다.
다음 목록은 MySQL 9.5에서 IGNORE_SPACE 설정의 영향을 받으며 sql/lex.h 소스 파일에 특수로 나열된 함수들의 이름입니다. 모든 함수 호출에 대해 공백을 허용하지 않는다고 취급하는 것이 가장 편리할 수 있습니다.
ADDDATE
BIT_AND
BIT_OR
BIT_XOR
CAST
COUNT
CURDATE
CURTIME
DATE_ADD
DATE_SUB
EXTRACT
GROUP_CONCAT
MAX
MID
MIN
NOW
POSITION
SESSION_USER
STD
STDDEV
STDDEV_POP
STDDEV_SAMP
SUBDATE
SUBSTR
SUBSTRING
SUM
SYSDATE
SYSTEM_USER
TRIM
VARIANCE
VAR_POP
VAR_SAMP
sql/lex.h에 특수로 나열되지 않은 함수의 경우, 공백은 중요하지 않습니다. 이러한 함수들은 식 컨텍스트에서 사용될 때에만 함수 호출로 해석되며, 그 외의 경우에는 자유롭게 식별자로 사용할 수 있습니다. ASCII가 그러한 이름 중 하나입니다. 그러나 이러한 비대상(nonaffected) 함수 이름의 경우, 식 컨텍스트에서 해석이 달라질 수 있습니다:
func_name ()은 동일한 이름을 가진 내장 함수가 존재하면 그 내장 함수로 해석됩니다. 존재하지 않는 경우,
func_name ()은 같은 이름을 가진 로더블 함수 또는 스토어드 함수가 있다면 그 함수로 해석됩니다.
IGNORE_SPACE SQL 모드를 사용하여 파서가 공백에 민감한 함수 이름을 처리하는 방식을 변경할 수 있습니다:
IGNORE_SPACE가 비활성화(disabled)된 경우, 파서는 이름과 그 뒤에 오는 괄호 사이에 공백이 없으면 이름을 함수 호출로 해석합니다. 이는 함수 이름이 식이 아닌(nonexpression) 컨텍스트에서 사용될 때에도 발생합니다:1mysql> CREATE TABLE count(i INT); 2ERROR 1064 (42000): You have an error in your SQL syntax ... 3near 'count(i INT)'
이 오류를 제거하고 이름이 식별자로 처리되도록 하려면, 이름 뒤에 공백을 사용하거나, 이름을 인용된 식별자(quoted identifier)로 작성(또는 둘 다)하십시오:
1CREATE TABLE count (i INT); 2CREATE TABLE `count`(i INT); 3CREATE TABLE `count` (i INT);
IGNORE_SPACE가 활성화(enabled)되면, 파서는 함수 이름과 그 뒤에 오는 괄호 사이에 공백이 없어야 한다는 요구 사항을 완화합니다. 이는 함수 호출을 작성할 때 더 많은 유연성을 제공합니다. 예를 들어, 다음 두 함수 호출 모두 허용됩니다:1SELECT COUNT(*) FROM mytable; 2SELECT COUNT (*) FROM mytable;
그러나 IGNORE_SPACE를 활성화하면, 파서가 영향을 받는 함수 이름을 예약어로 처리하는 부작용이 발생합니다(자세한 내용은 Section 11.3, “Keywords and Reserved Words” 참조). 이는 이름 뒤에 오는 공백이 더 이상 식별자로 사용됨을 나타내지 않는다는 뜻입니다. 이름은 공백의 유무와 관계없이 함수 호출에서 사용할 수 있지만, 식이 아닌(nonexpression) 컨텍스트에서는 인용되지 않는 한 구문 오류를 발생시킵니다. 예를 들어, IGNORE_SPACE가 활성화된 경우, 파서가 count를 예약어로 해석하기 때문에 다음 두 문장 모두 구문 오류로 실패합니다:
1CREATE TABLE count(i INT); 2CREATE TABLE count (i INT);
함수 이름을 식이 아닌(nonexpression) 컨텍스트에서 사용하려면, 이를 인용된 식별자(quoted identifier)로 작성하십시오:
1CREATE TABLE `count`(i INT); 2CREATE TABLE `count` (i INT);
IGNORE_SPACE SQL 모드를 활성화하려면 다음 문장을 사용하십시오:
1SET sql_mode = 'IGNORE_SPACE';
IGNORE_SPACE는 또한 ANSI와 같이 그 값을 구성하는 여러 복합(composite) 모드에 의해 함께 활성화되기도 합니다:
1SET sql_mode = 'ANSI';
어떤 복합(composite) 모드가 IGNORE_SPACE를 활성화하는지 알아보려면 Section 7.1.11, “Server SQL Modes”를 확인하십시오.
SQL 코드가 IGNORE_SPACE 설정에 의존하는 정도를 최소화하려면 다음 지침을 따르십시오:
내장 함수와 동일한 이름을 가진 로더블 함수나 스토어드 함수를 생성하지 마십시오.
함수 이름을 식이 아닌(nonexpression) 컨텍스트에서 사용하는 것을 피하십시오. 예를 들어, 다음 문장은 IGNORE_SPACE의 영향을 받는 함수 이름 중 하나인 count를 사용하므로, 이름 뒤에 공백이 있든 없든 IGNORE_SPACE가 활성화되어 있으면 실패합니다:
1CREATE TABLE count(i INT); 2CREATE TABLE count (i INT);
함수 이름을 식이 아닌(nonexpression) 컨텍스트에서 반드시 사용해야 한다면, 이를 인용된 식별자(quoted identifier)로 작성하십시오:
1CREATE TABLE `count`(i INT); 2CREATE TABLE `count` (i INT);
다음 규칙은 함수 생성 및 호출 시 서버가 함수 이름에 대한 참조를 어떻게 해석(resolve)하는지 설명합니다:
내장 함수와 로더블 함수
내장 함수와 동일한 이름을 가진 로더블 함수를 생성하려고 하면 오류가 발생합니다.
이러한 경우 IF NOT EXISTS는 아무런 효과가 없습니다. 자세한 내용은 Section 15.7.4.1, “CREATE FUNCTION Statement for Loadable Functions”을 참조하십시오.
내장 함수와 스토어드 함수
내장 함수와 동일한 이름을 가진 스토어드 함수를 생성하는 것은 가능하지만, 해당 스토어드 함수를 호출하려면 스키마 이름을 사용하여 한정자(qualifier)를 붙여야 합니다. 예를 들어, test 스키마에 PI라는 스토어드 함수를 생성한 경우, 서버는 한정자 없이 PI()를 내장 함수에 대한 참조로 해석하므로 스토어드 함수를 호출할 때는 test.PI()로 호출해야 합니다. 스토어드 함수 이름이 내장 함수 이름과 충돌할 경우 서버는 경고를 생성합니다. 이 경고는 SHOW WARNINGS로 확인할 수 있습니다.
이러한 경우에도 IF NOT EXISTS는 아무런 효과가 없습니다. Section 15.1.21, “CREATE PROCEDURE and CREATE FUNCTION Statements”를 참조하십시오.
로더블 함수와 스토어드 함수
이미 존재하는 로더블 함수와 동일한 이름의 스토어드 함수를 생성하거나, 그 반대로 하는 것도 가능합니다. 제안된 스토어드 함수 이름이 기존 로더블 함수 이름과 충돌하거나, 제안된 로더블 함수 이름이 기존 스토어드 함수 이름과 동일하게 되는 경우, 서버는 경고를 생성합니다. 어느 경우든, 두 함수가 모두 존재하게 되면 이후 스토어드 함수를 호출할 때는 스키마 이름으로 한정자를 붙여 호출해야 합니다. 이 경우 서버는 한정자 없는 이름이 로더블 함수를 가리키는 것으로 간주합니다.
MySQL 9.5는 CREATE FUNCTION 문장에서 IF NOT EXISTS를 지원하지만, 이러한 경우에는 아무런 효과가 없습니다.
앞에서 언급한 함수 이름 해석(function name resolution) 규칙은 새로운 내장 함수를 구현하는 MySQL 버전으로 업그레이드할 때 다음과 같은 영향을 미칩니다:
DROP FUNCTION을 사용하여 로더블 함수를 삭제한 다음, CREATE FUNCTION을 사용하여 충돌하지 않는 다른 이름으로 로더블 함수를 다시 생성하십시오.그런 다음 영향을 받는 코드를 모두 수정하여 새 이름을 사용하도록 변경해야 합니다.
schema_name.func_name()
구문)를 사용하도록 변경하는 것입니다. 어느 경우든, 이에 따라 영향을 받는 코드를 적절히 수정해야 합니다.11.2.4 Mapping of Identifiers to File Names
11.3 Keywords and Reserved Words