{#call-call} # CALL {bdg-primary-line}`GQL 절` {bdg-secondary-line}`2.18에 추가` 쿼리 파이프라인 안에서 루틴을 실행합니다. 그 루틴은 결과 행이 작업 표에 조인되는 이름 있는 함수이거나, 그 자리에 적은 서브쿼리입니다. {#call-synopsis} ## 개요
[ OPTIONAL ] CALL function( [ argument [, argument ] ... ] ) YIELD yield_list [ OPTIONAL ] CALL [ variable_scope ] { subquery }

굵게 키워드 · 기울임 직접 채우는 자리 · [ ] 생략 가능 · ... 반복 가능. 구문 표기 규약을 참고하십시오.

{#call-description} ## 설명 `CALL`에는 두 형태가 있고, 어느 쪽이 되는지는 키워드 뒤의 토큰이 결정합니다: - **이름**이 뒤따르는 `CALL`은 이름 있는 루틴 형태입니다. 함수를 호출하고, 필수인 `YIELD` 목록에 적은 컬럼을 작업 행에 더합니다. [`CALL … YIELD`](call-yield.md)를 참고하십시오. - `(`나 `{`가 뒤따르는 `CALL`은 인라인 형태입니다. 중괄호 사이의 서브쿼리를 실행하며, 입력 행마다 한 번씩 실행하게 할 수도 있습니다. [`CALL { subquery }`](call-subquery.md)를 참고하십시오. `OPTIONAL`은 두 형태 앞에 모두 붙을 수 있습니다. 루틴이나 서브쿼리가 행을 내놓지 못한 입력 행을 남겨 두고, 그 호출이 반환했을 모든 것을 null로 바인딩합니다. [`OPTIONAL CALL`](optional-call.md)을 참고하십시오. {#call-what-call-invokes} ### CALL이 호출하는 것 GQL에서 `CALL`이 호출하는 것은 *프로시저*입니다. AgensGraph에는 자체 프로시저 카탈로그가 없습니다. `CALL … YIELD`는 그 이름을 PostgreSQL의 보통 함수에서 찾으며, 기본 설치 상태에서는 프로시저가 아예 등록돼 있지 않습니다. ```sql SELECT count(*) AS procedures FROM pg_proc WHERE prokind = 'p'; ``` ``` procedures ------------ 0 (1 row) ``` 그러므로 여기서 "프로시저를 호출한다"는 것은 "함수를 호출한다"는 뜻입니다. 어떤 함수든 되고, 그 함수의 모양이 `YIELD`가 무엇을 이름으로 부를 수 있는지를 결정합니다: | 함수의 모양 | `YIELD`가 보는 것 | | --- | --- | | 스칼라, 예: `length(text)` | 함수 이름을 딴 컬럼 하나 | | 집합 반환, 예: `generate_series(int, int)` | 함수 이름을 딴 컬럼 하나, 요소마다 행 하나 | | 복합 타입이나 `RETURNS TABLE`, 예: `jsonb_each_text(jsonb)` | 출력 필드마다 컬럼 하나, 필드 이름 그대로 | | 위의 어느 모양이든, 함수 자신의 이름으로 | 그 이름의 출력 컬럼이 없을 때 행 전체. `RETURNS SETOF vertex` 함수는 이렇게 정점을 내놓습니다 | 내놓을 항목은 이들 중 하나이고 그 밖에는 없습니다. 함수가 반환하지 않는 이름은 쿼리 앞쪽에 같은 이름의 변수가 바인딩돼 있어도 거부됩니다. PostgreSQL 자체의 `CALL` 문장은 다른 것입니다. 최상위 SQL 문장이고, 실제 프로시저를 요구하며, Cypher 절이 아닙니다. 둘은 겹치지 않고, 각각 상대의 대상을 거부합니다. {#call-parameters} ## 매개변수 function : 호출할 함수의 이름입니다. `search_path`가 닿지 않는다면 스키마로 수식하십시오. 프로시저는 거부됩니다. `() is a procedure`가 나오고 힌트로 `To call a procedure, use CALL`이 따라옵니다. argument : 값 표현식이며 입력 행마다 평가됩니다. 인자는 앞서 바인딩된 변수를 가리킬 수 있고, 그러면 그 호출이 상관 호출이 됩니다. 속성 접근은 `jsonb`를 내놓으므로, 매개변수가 다른 타입이면 형 변환을 하십시오. variable_scope : 인라인 서브쿼리가 볼 수 있는 바깥 변수입니다. 이름을 적은 것만 보려면 `(v, w)`, 전부 보려면 `(*)`, 아무것도 보지 않으려면 `()`입니다. **이것을 생략하면 아무것도 가져오지 않습니다.** 그 규칙으로 시작하는 [`CALL { subquery }`](call-subquery.md)를 참고하십시오. yield_list : `*`, 또는 그 함수의 출력 컬럼 하나 이상이며, 각각 `AS`로 이름을 바꿀 수 있습니다. 필수입니다. [`CALL … YIELD`](call-yield.md)를 참고하십시오. subquery : `RETURN`으로 끝나는 읽기 전용 쿼리입니다. 쓰기 절은 거부됩니다. {#call-examples} ## 예제 모든 예제는 [예제 데이터셋](../../get_started/example-dataset.md)에서 실행됩니다. 집합 반환 함수를 호출해 그 행을 일치한 영화에 조인합니다: ```cypher MATCH (m:movie {title: 'The Matrix'}) CALL jsonb_array_elements_text(m.embedding) YIELD jsonb_array_elements_text AS d RETURN d ORDER BY d; ``` ``` d --------------- "-0.07594558" "-0.11921061" "0.04081754" "0.29592122" (4 rows) ``` {#call-compute-a-value-per-row-with-a-subquery} ### 서브쿼리로 행마다 값을 계산하기 인라인 형태는 입력 행마다 하나의 질문에 답하며, 그 본문을 주 패턴 밖에 둡니다: ```cypher MATCH (m:movie {genre: 'Adventure'}) CALL (m) { MATCH (p:person)-[:acted_in]->(m) RETURN count(p) AS cast_size } RETURN m.title AS film, cast_size; ``` ``` film | cast_size -----------------+----------- "Jurassic Park" | 1 (1 row) ``` {#call-try-to-call-a-procedure} ### 프로시저를 호출해 보기 `CALL … YIELD`가 받지 않는 유일한 루틴 종류가 프로시저입니다: ```sql CREATE PROCEDURE noop() LANGUAGE sql AS 'SELECT 1'; ``` ``` CREATE PROCEDURE ``` ```cypher MATCH (m:movie) CALL noop() YIELD * RETURN count(*); ``` ``` ERROR: noop() is a procedure LINE 1: MATCH (m:movie) CALL noop() YIELD * RETURN count(*); ^ HINT: To call a procedure, use CALL. ``` 그리고 SQL의 `CALL` 문장이 받지 않는 유일한 루틴 종류가 함수입니다: ```sql CALL generate_series(1, 3); ``` ``` ERROR: generate_series(integer, integer) is not a procedure LINE 1: CALL generate_series(1, 3); ^ HINT: To call a function, use SELECT. ``` {#call-notes} ## 참고 렉서는 토큰 하나를 앞서 보고 두 형태를 가릅니다. 덕분에 `call`을 보통 식별자로 계속 쓸 수 있습니다. `MATCH (call:movie) RETURN count(call)`도 동작하고, SQL 문장 `CALL myproc()`도 동작합니다. 이름 있는 루틴 형태는 **가운데** 절입니다. 쿼리를 시작할 수도, 끝낼 수도 없습니다. 인라인 형태는 쿼리를 시작할 수 있지만 범위 절이 없을 때만 그렇습니다. 앞에 아무것도 없는 상태의 범위 절은 `CALL has no preceding clause to import variables from`을 냅니다. {#call-compatibility} ## 호환성 ```{admonition} GQL 적합성 :class: gql-conformance §14.5 *call query statement*의 쿼리 자리에서 GQL의 *call procedure statement*와 *procedure call*(ISO/IEC 39075:2024 §15.1)을 구현합니다. - **지원** — 표준이 정의하는 프로시저 호출 두 형태, 곧 §15.2의 인라인 호출과 §15.3의 이름 호출. 각각 `OPTIONAL` 접두를 붙일 수 있습니다. - **미지원** — *call data-modifying procedure statement*(§13.6). 호출된 루틴이나 서브쿼리는 그래프에 쓸 수 없습니다. GQL 프로시저 카탈로그도 없습니다 — §17.5의 프로시저 참조는 PostgreSQL 함수로 해석되고, 표준의 `QUERY PROCEDURE` 표시에는 대응하는 것이 없습니다. - **이탈** — 표준은 이름 호출에서 `YIELD` 절을 선택으로 둡니다(§15.3). AgensGraph는 필수로 요구합니다. 진행 상황은 [GQL 적합성 표](../../appendix/gql-conformance.md)에서 확인하십시오. ``` {#call-opencypher} ### openCypher openCypher의 `CALL db.labels()` 방식 프로시저 호출은 이름 있는 형태에 대응되지만 이름이 다릅니다. 여기에는 `db.*`나 `dbms.*` 이름공간이 없습니다. 대신 PostgreSQL 카탈로그와 `\dGv` / `\dGe` 메타 명령을 쓰거나, [ag_label](../../system_catalogs/catalogs.md)을 직접 읽으십시오. 예제가 만든 루틴을 지웁니다: ```sql DROP PROCEDURE noop(); ``` {#call-see-also} ## 관련 항목 - [`CALL … YIELD`](call-yield.md) {bdg-secondary-line}`GQL` — 이름 있는 루틴 형태의 자세한 설명 - [`CALL { subquery }`](call-subquery.md) {bdg-secondary-line}`GQL` — 인라인 형태와 그 가져오기 목록 - [`OPTIONAL CALL`](optional-call.md) {bdg-secondary-line}`GQL` — 입력 행을 보존하는 형태 - [서브쿼리 값 표현식](subquery-expressions.md) {bdg-secondary-line}`GQL` — 절이 아니라 표현식 안의 서브쿼리 - [GQL 적합성 표](../../appendix/gql-conformance.md)