구문
name으로 handler를 생성합니다. 이 이름은 SQL 쿼리를 통해 handler를 관리하고, 진단 메시지에 표시하며, handler의 순서를 정하는 데 사용됩니다.
절
PROTOCOL— 선택 사항입니다. 프로토콜 이름을 지정하면 핸들러는 지정된 조합형 프로토콜에서만 활성화됩니다. 그렇지 않으면 핸들러는 내장http/https포트와 모든 HTTP 유형의 조합형 프로토콜 리스너를 비롯한 모든 HTTP 엔드포인트에서 활성화됩니다.PROTOCOL ANY는 후자의 기본 동작을 명시적으로 선택하며,ALTER HANDLER에서는 이전에 설정된 프로토콜 제한을 제거합니다. 문자 그대로any라는 이름의 프로토콜은 백쿼트로 참조할 수 있습니다:PROTOCOL `any`.URL— 필수입니다. 정확한 URL,URL PREFIX또는URL REGEXP형식으로 지정할 수 있습니다. 정확한 URL과 접두사는 생성 또는 변경 시점에 모호성을 검사하며, 모호성이 있으면 예외가 발생합니다. 정규식은 모호성을 검사할 수 없습니다. URL은?쿼리 문자열과#프래그먼트 식별자를 제외하고 일치시킵니다.URL PREFIX는 기본 경로로서 경로 세그먼트 경계에서 일치합니다. 이는 구성으로 정의된 핸들러의url_prefix규칙과 동일한 의미입니다.URL PREFIX '/api/v1'는/api/v1,/api/v1/,/api/v1/write와 일치하지만/api/v1beta와는 일치하지 않습니다. 접두사 끝의/는 무시되므로'/api/v1/'와'/api/v1'는 동일하게 동작합니다.METHODS— 선택 사항입니다. 허용되는 HTTP 메서드 목록입니다. 기본값은GET뿐입니다. 지원되는 메서드는GET,POST,PUT,DELETE입니다. 데이터를 변경하는 메서드인POST,PUT,DELETE는 수정 쿼리를 실행할 수 있으며,GET,HEAD와 같은 안전한 메서드는 항상readonly모드에서 실행됩니다. 따라서 데이터를 수정하는 쿼리(예:INSERT또는 DDL)를 실행하는 핸들러는 최소 하나의 데이터 변경 메서드를 허용해야 합니다. 읽기 전용 메서드만(예: 기본값인GET) 허용하는 이러한 핸들러를 생성하면 예외가 발생합니다.readonly모드에서도 부수 효과가 유지되는 쿼리는 특수한 경우입니다.BACKUP및RESTORE는 지속적인 부수 효과를 발생시키며, 세션을 변경하는 SQL 문SET,SET ROLE,USE,BEGIN TRANSACTION,COMMIT,ROLLBACK,SET TRANSACTION SNAPSHOT은session_id사용 시 요청 간에 유지되는 세션 또는 트랜잭션 상태를 변경합니다. 또한CREATE TEMPORARY TABLE/CREATE TEMPORARY VIEW는 세션 내에서 유지되는 객체를 생성하지만, 안전한 메서드의readonly모드는 이들 중 어느 것도 차단하지 않습니다. 기존 임시 테이블에 대한 변경도readonly모드에서 차단되지 않으므로, 이를 대상으로 할 수 있는 쿼리도 동일하게 처리됩니다. 데이터베이스로 한정되지 않은 대상 테이블을 가진INSERT(한정되지 않은 이름은 세션 임시 테이블로 해석될 수 있음),DROP TEMPORARY TABLE, 데이터베이스로 한정되지 않은 테이블의DROP TABLE/TRUNCATE TABLE, 데이터베이스로 한정되지 않은 테이블의ALTER이 이에 해당합니다(ALTER TEMPORARY TABLE은 동일한 SQL 문입니다). 데이터베이스로 한정된 대상은 임시 테이블일 수 없으므로 이러한 쿼리에는 이 규칙이 적용되지 않습니다. HTTP는 안전한 메서드에 부수 효과가 없을 것을 요구합니다(GET에 대해 선언된 핸들러는 응답 본문이 억제되어 효과를 확인할 수 없는HEAD에도 제공됩니다). 따라서 이러한 쿼리를 실행하는 핸들러는 데이터 변경 메서드만 나열해야 하며, 안전한 메서드를 포함하도록 생성하거나 변경하면 예외가 발생합니다. 복합 SQL 문은 내부 SQL 문까지 검사합니다.statement1 PARALLEL WITH statement2 ...및EXECUTE AS <user> <statement>에서는 실제로 실행되는 래핑된 SQL 문에 위 규칙이 적용됩니다(각 SQL 문은readonly모드를 유지하는 핸들러 컨텍스트의 복사본에서 실행됨). 단독EXECUTE AS <user>는 전체 세션을 다른 사용자로 실행하므로 자체적으로 세션 변경으로 간주됩니다. 또한 단독이거나 SQL 문을 래핑하는 모든EXECUTE AS핸들러는 최소 하나의 데이터 변경 메서드를 허용해야 합니다. 가장에는IMPERSONATE권한이 필요하며, 안전한 메서드의readonly모드는 이를 거부합니다.TYPE— 선택 사항입니다. 현재 지원되는 유일한 유형은query입니다.AS— 이 핸들러가 호출할 SQL 쿼리입니다. 쿼리는 매개변수화할 수 있습니다. 쿼리는 핸들러를 생성하거나 변경할 때 구문적 정확성만 검사하며, 분석하지는 않습니다. 예를 들어 핸들러 생성 시점에 쿼리에서 참조하는 테이블이 없을 수 있습니다.FORMAT및 유사한 절은 전체CREATE/ALTERSQL 문이 아니라 쿼리에 속합니다. 모호성을 피하기 위해 쿼리를 괄호로 묶을 수 있습니다.INSERT쿼리에는VALUES또는FORMAT절 뒤에 인라인 데이터가 포함되어서는 안 됩니다. 인라인 페이로드는 핸들러 정의에 보존할 수 없으므로, 이러한 핸들러를 생성하거나 변경하면 예외가 발생합니다. 데이터는 HTTP 본문에서 제공하거나INSERT ... SELECT로 계산해야 합니다. 본문을 읽는 쿼리가 있는 핸들러에 대한 요청, 즉 본문에서 데이터를 가져오는INSERT또는_request_body매개변수를 사용하는 쿼리는 길이를 선언해야 합니다.Content-Length헤더가 없는 청크되지 않은 요청에는411 Length Required로 응답합니다. 그렇지 않으면 본문을 스트림 끝까지 읽게 되어 연결이 끊긴 경우도 완전한 요청으로 받아들여질 수 있기 때문입니다. 이러한 핸들러의 모든 메서드도 본문을 포함하는 메서드(POST,PUT또는DELETE)여야 합니다.METHODS절에서 안전한 메서드(예: 기본값인GET)로 생성하면 예외가 발생합니다. 안전한 메서드는 요청 본문을 제공하지 않으므로 쿼리가 빈 본문을 조용히 읽게 되기 때문입니다. 선언된GET은HEAD요청에도 제공되므로, 안전한 메서드와 본문을 포함하는 메서드를 혼합하면 해당 호출을 계속 사용할 수 있습니다.INSERT ... SELECT는 본문을 읽지 않습니다(데이터는SELECT에서 가져옵니다). 따라서SELECT가 요청 본문에서 공급되는input테이블 함수를 읽는 경우를 제외하면 이러한 요구 사항이 적용되지 않습니다. 본문을 읽는INSERT는 핸들러 자체의 쿼리여야 합니다.EXECUTE AS및PARALLEL WITH는 자신이 감싼 SQL 문을 요청 본문 없이 실행하므로, 모든 업로드를 조용히 버리는 대신 이러한 구문으로 감싼 쿼리는 생성 시 거부됩니다. 본문을 읽는 쿼리는_request_body매개변수도 사용해서는 안 됩니다. 요청 본문은 하나뿐이며,_request_body를 바인딩하면 쿼리가 입력 데이터를 읽기 전에 본문을 소비하므로 모든 업로드가 조용히 손실되는 대신 이러한 핸들러는 생성 시 거부됩니다. 쿼리 자체의 본문 입력 또는_request_body중 하나만 사용하고 둘 다 사용하지 마십시오. 본문을 읽지 않는 핸들러에는 이러한 요구 사항이 없습니다. 이러한 핸들러에 대한 요청 본문은 무시되며 핸들러 쿼리에 절대 추가되지 않습니다. 저장된 쿼리 텍스트는 핸들러를 다시 로드하거나 호출할 때마다 서버에서 파서 깊이와 역추적 횟수 제한 없이 다시 구문 분석됩니다. 따라서max_parser_depth/max_parser_backtracks를 높인 세션에서 생성된 핸들러도 일반적인 세션 제한에서 계속 로드하고 호출할 수 있습니다.
우선순위
매개변수
- 쿼리 문자열의 HTTP URL 매개변수에서
param_<name>규칙을 사용합니다(예:?param_id=42는{id:Type}에 바인딩됩니다). URL REGEXP의 이름 지정 캡처 그룹을 사용합니다(예:URL REGEXP '/users/(?P<id>\d+)'는{id:Type}에 바인딩됩니다).- 쿼리에서 매개변수를 선언하는 handler의 요청 본문 양식 필드를 사용합니다.
application/x-www-form-urlencoded본문(예:curl -d 'param_id=42') 및multipart/form-data본문의 필드는 본문을 포함하는 메서드POST,PUT,DELETE에서 URL 매개변수와 동일한 방식으로{name:Type}매개변수에 바인딩됩니다. URL과 본문 모두에 있는 매개변수는 URL의 값을 사용합니다. 양식으로 파싱된 본문은 handler 계층에서 소비되므로INSERT데이터로 쿼리에 전달되지 않습니다. 본문을_request_body로만 사용하는 handler는 양식 파싱 대신 원시 본문을 받습니다. 다른 매개변수와 함께_request_body를 선언하는 handler는 둘 다 받습니다. 즉, 본문이 양식으로 파싱되기 전에 원시 본문의 복사본이_request_body에 보존됩니다(http_max_request_param_data_size의 제한을 따름).
X-ClickHouse-Database, X-ClickHouse-User, X-ClickHouse-Key)는 일반적인 방식으로 적용됩니다.
함수 currentHandler 및 currentRequestURL을 사용하면 호출된 handler와 요청 URL에 따라 쿼리 동작을 사용자 정의할 수 있습니다.
액세스 제어
CREATE HANDLER, DROP HANDLER, ALTER HANDLER를 사용하려면 각각 CREATE HANDLER, DROP HANDLER, ALTER HANDLER 권한이 필요합니다.
system.handlers 테이블을 읽으려면 SHOW HANDLERS 권한이 필요합니다. 핸들러 쿼리에 포함될 수 있는 시크릿은 사용자가 시크릿을 볼 수 있는 추가 권한을 갖고 있지 않으면 해당 테이블에서 마스킹됩니다(system.handlers 참조).
핸들러를 호출하는 데는 별도의 권한이 필요하지 않지만, 쿼리를 호출할 때는 일반적인 방식으로 권한을 확인하며 인증도 정상적으로 적용됩니다. 특정 쿼리에 대한 액세스를 캡슐화하려면 SQL SECURITY DEFINER가 포함된 VIEW를 생성하고 해당 뷰를 SELECT하는 핸들러를 정의하십시오.
스토리지
query_rules_storage 섹션에서 구성하는 로컬 또는 Keeper 스토리지에 저장됩니다:
ON CLUSTER 절은 불필요하며, 지정하면 모든 레플리카가 동일한 handler를 생성하려고 시도합니다. Storage가 복제된 경우 CREATE, ALTER, DROP HANDLER에서 ON CLUSTER를 무시하도록 ignore_on_cluster_for_replicated_handler_queries 설정을 활성화하십시오. 이는 ignore_on_cluster_for_replicated_named_collections_queries와 동일한 방식입니다.
ALTER HANDLER
ALTER 쿼리에는 일부 절만 포함할 수 있으므로, 예를 들어 URL 또는 쿼리만 변경할 수 있습니다. 지정하지 않은 절은 기존 값을 유지합니다. PROTOCOL ANY는 기존 protocol 제한을 제거하여 handler가 다시 모든 HTTP endpoint에서 활성화되도록 합니다.
DROP HANDLER
내부 검사
system.handlers 테이블에는 SQL로 정의된 모든 handler가 나열됩니다. system.query_log 테이블은 각 쿼리의 handler 이름과 HTTP 요청 경로(쿼리 문자열 제외)를 http_handler_name 및 http_request_url 컬럼에 기록합니다.
예시
CREATE HANDLER는 CREATE SQL 문 계열에 속하며, ALTER 및 DROP과 관련이 있습니다.