9.2.4 함수 이름 구문 분석 및 해결
MySQL 5.6는 임베디드 (네이티브) 함수, 사용자 정의 함수 (UDF) 및 저장 기능을 지원합니다. 이 섹션에서는 내장 함수 이름이 함수 호출로 사용되었는지 식별자로 사용되었는지를 서버에서 인식하는 방법과 지정된 이름으로 다른 형태의 함수가 존재하는 경우에 사용하는 함수를 서버가 확인하는 방법에 대해 설명합니다.
내장 함수 이름의 구문 분석
파서는 내장 함수 이름을 구문 분석하기위한 기본 규칙을 사용합니다. 이러한 규칙은 IGNORE_SPACE
SQL 모드를 사용하여 변경할 수 있습니다.
파서는 내장 함수의 이름 인 단어를 발견하면 그 이름이 함수 호출을 나타내고있는 것인지 아니면 테이블 이름과 컬럼 이름과 같은 식별자의 식 이외의 참인지를 판별해야합니다. 예를 들어, 다음 명령문은 count
에 대한 첫 번째 참조는 함수 호출이지만, 두 번째 참조 테이블 이름입니다.
SELECT COUNT (*) FROM mytable; CREATE TABLE count (i INT);
파서는 식 것으로 예상되는 대상을 분석하는 경우에만 내장 함수 이름을 함수 호출을 보여준다 이름으로 인식해야합니다. 즉, 식 이외의 컨텍스트에서 함수 이름 식별자로 허용됩니다.
그러나 내장 함수에서 구문 분석 및 구현에 대한 특별 고려 사항을 포함하는 것이 있기 때문에 파서는 기본적으로 다음 규칙에 따라 이름이 함수 호출로 사용되고 있는지, 아니면 식 이외 컨텍스트 식별자로 사용되고 있는지를 판별합니다.
수식에서 함수 호출로 이름을 사용하려면 이름과 연속 괄호 문자 "
(
"사이에 공백이 존재하지 않는 것이 필요합니다.반대로, 함수 이름을 식별자로 사용하려면 괄호 문자 직후 계속하지 마십시오.
이름과 괄호 사이에 공백을 넣지 않고 함수 호출을 기술한다는 요구 사항은 특별한 고려 사항이있는 내장 함수에만 적용됩니다. COUNT
이 같은 이름의 하나입니다. 후행 공백에 의해 해석이 결정 함수 이름의 정확한 목록은 sql/lex.h
소스 파일의 sql_functions[]
배열에 표시됩니다. MySQL 5.1 이전 버전에서는 이러한 함수 이름이 다수 (200) 있기 때문에 공백없이 요구 사항을 모든 함수 호출에 적용시키는 방법이 가장 간단하다고 생각됩니다. MySQL 5.1 이후에서는 파서의 개선에 의해 영향을받는 함수 이름의 수는 약 30으로 감소하고 있습니다.
sql_functions[]
배열에 나열되지 않은 함수는 공백은 관계 없습니다. 그들은 식의 컨텍스트에서 사용되는 경우에만 함수 호출로 해석되며, 그 이외에서는 식별자로 자유롭게 사용할 수 있습니다. ASCII
가이 같은 이름의 하나입니다. 그러나 이러한 영향을받지 않는 함수 이름에 대한 해석은 식의 컨텍스트에 따라 달라질 수 있습니다. 즉,
는 지정된 이름이 단독으로 사용되는 경우는 내장 함수로 해석되지만, 혼자가 아닌 경우, func_name
()
는 사용자 정의 함수 또는 저장 함수 (그 이름의 함수가 존재하는 경우 )로 해석됩니다. func_name
()
IGNORE_SPACE
SQL 모드는 공백의 유무로 구별되는 함수 이름을 파서 처리 방법을 변경하는 데 사용할 수 있습니다.
IGNORE_SPACE
가 비활성화되어 있으면 이름과 괄호 사이에 공백이없는 경우, 파서는 그 이름을 함수 호출로 해석합니다. 이것은 함수 이름이 수식 이외의 문맥에서 사용되는 경우도 발생합니다.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);
IGNORE_SPACE
가 활성화되어 있으면 파서는 함수 이름과 괄호 사이에 공백이 존재하지 않는다는 요건을 완화합니다. 이것으로 함수 호출의 기술이 더 자유롭게 할 수 있습니다. 예를 들어, 다음 두 함수 호출에도 유효합니다.SELECT COUNT (*) FROM mytable; SELECT COUNT (*) FROM mytable;
그러나
IGNORE_SPACE
를 사용하면 영향을받는 함수 이름을 파서가 예약어로 다룬다는 더 늘어날 수도 있습니다 ( 섹션 9.3 "예약어" 를 참조하십시오). 즉, 이름에 계속되는 공백은 그것이 식별자로 사용되는 것을 나타내는 것은 없습니다. 후행 공백의 유무를 불문하고 이름은 함수 호출로 사용할 수 있지만 따옴표로 둘러싸여 있지 않은 한, 식 이외의 맥락에서 구문 오류가 발생합니다. 예를 들어,IGNORE_SPACE
가 활성화되어 있으면 파서가count
를 예약어로서 해석하기 위해서 다음의 명령문은 모두 구문 오류가 표시되어 실패합니다.CREATE TABLE count (i INT); CREATE TABLE count (i INT);
식 이외의 컨텍스트에서 함수 이름을 사용하려면이를 따옴표 붙은 식별자로 설명합니다.
CREATE TABLE`count` (i INT); CREATE TABLE`count` (i INT);
IGNORE_SPACE
SQL 모드를 활성화하려면 다음 문을 사용합니다.
SET sql_mode = 'IGNORE_SPACE';
IGNORE_SPACE
는 ANSI
와 같은 다른 특정 복합 모드의 값에 포함되어있는 경우에도 적용됩니다.
SET sql_mode = 'ANSI';
어떤 복합 모드가 IGNORE_SPACE
를 활성화하는 방법을 알아 보려면 섹션 5.1.7 "서버 SQL 모드" 를 참조하십시오.
IGNORE_SPACE
설정에서 SQL 코드의 종속성을 최소화하려면 다음 지침을 사용하십시오.
내장 함수와 같은 이름의 UDF 또는 스토어드 함수는 작성하지 마십시오.
식 이외의 컨텍스트에서 함수 이름을 사용하지 마십시오. 예를 들어,이 문은
count
(IGNORE_SPACE
에 영향을받는 함수 이름의 하나)을 사용하기 때문에IGNORE_SPACE
가 유효하면, 이름에 계속되는 공백의 유무에 관계없이 이러한 문은 실패합니다.CREATE TABLE count (i INT); CREATE TABLE count (i INT);
식 이외의 컨텍스트에서 함수 이름을 사용할 필요가있는 경우이를 따옴표 붙은 식별자로 설명합니다.
CREATE TABLE`count` (i INT); CREATE TABLE`count` (i INT);
MySQL 5.1.13에서는 IGNORE_SPACE
의 영향을받는 함수 이름의 수가 약 200에서 30로 크게 감소했습니다. MySQL 5.1.13 이후 IGNORE_SPACE
설정의 영향을 계속받을 다음 함수뿐입니다.
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 |
MySQL의 이전 버전에서는 sql/lex.h
소스 파일의 sql_functions[]
배열의 내용을 확인하여 어떤 함수가 IGNORE_SPACE
에 영향을 받는지를 확인하십시오.
비 호환성 경고 : MySQL 5.1.13에서는 IGNORE_SPACE
의 영향을받는 함수 이름의 수를 억제하는 것으로 파서 작업에 일관성을 가져 왔습니다. 그러나 다음의 조건에 의존하는 구형 SQL 코드와 비 호환 가능성도 생깁니다.
IGNORE_SPACE
가 비활성화되어 있습니다.함수 이름 뒤에 공백의 유무는 동일한 이름을 가진 내장 함수와 스토어드 함수 (예를 들어,
PI()
와PI ()
등)를 구별하는 데 사용됩니다.
MySQL 5.1.13 이후 IGNORE_SPACE
의 영향을받지 않게 된 함수에 대하여는 그 방법은 작동하지 않습니다. 위의 비 호환성 영향을받는 코드가있는 경우는 다음의 두 가지 접근 방식을 사용할 수 있습니다.
스토어드 함수에 내장 함수와 충돌하는 이름이 존재하는 경우, 공백의 유무에 관계없이 스키마 이름 규정이있는 스토어드 함수를 참조하십시오. 예를 들어,
또는schema_name
.PI()
라고 기술합니다.schema_name
.PI ()또는 충돌하지 않는 이름을 사용하도록 스토어드 함수의 이름을 변경하고 새 이름을 사용하도록 함수 호출을 변경합니다.
함수 이름 확인
다음 규칙은 함수 작성 및 호출을 위해 서버에서 함수 이름 참조를 해결하는 방법에 대해 설명합니다.
내장 함수와 사용자 정의 함수
내장 함수와 같은 이름으로 UDF를 작성하려고하면 오류가 발생합니다.
내장 함수와 저장 기능
내장 함수와 같은 이름의 스토어드 함수를 작성하는 것은 가능하지만,이 스토어드 함수를 호출하려면 스키마 이름으로 규정해야합니다. 예를 들어,
test
스키마에서PI
라는 이름의 스토어드 함수를 작성하는 경우 서버가PI()
을 내장 함수의 참조로 해결하기 위해test.PI()
로 호출합니다. 서버는 스토어드 함수 이름이 내장 함수 이름과 일치하지 않을 경우 경고를 생성합니다. 이 경고는SHOW WARNINGS
에서 볼 수 있습니다.사용자 정의 함수 및 저장 기능
사용자 정의 함수와 저장 함수는 같은 네임 스페이스를 공유합니다. 따라서 동명의 UDF와 스토어드 함수를 만들 수 없습니다.
위의 함수 이름 확인 규칙은 새 내장 함수를 구현하는 MySQL 버전으로 업그레이드에 영향을 미칩니다.
지정된 이름의 사용자 정의 함수가 이미 작성되어 동일한 이름으로 새 내장 함수를 구현하는 버전으로 MySQL을 업그레이드하면이 UDF에 액세스 할 수 없습니다. 이 문제를 해결하려면
DROP FUNCTION
을 사용하여 UDF를 삭제하고CREATE FUNCTION
을 사용하여 충돌하지 않는 다른 이름으로 UDF를 다시 만듭니다.새로운 버전의 MySQL에서 기존의 스토어드 함수와 같은 이름으로 내장 함수를 구현하는 경우, 스토어드 함수의 이름을 충돌하지 않는 이름으로 변경하거나 스키마 규정자를 사용하도록 함수 호출을 변경하는 (즉 ,
구문을 사용하는)라는 두 가지 선택이 있습니다.schema_name
.func_name
()