{#call-call}
# CALL
{bdg-primary-line}`GQL 절` {bdg-secondary-line}`2.18에 추가`
쿼리 파이프라인 안에서 루틴을 실행합니다. 그 루틴은 결과 행이 작업 표에 조인되는 이름 있는
함수이거나, 그 자리에 적은 서브쿼리입니다.
{#call-synopsis}
## 개요
굵게 키워드 · 기울임 직접 채우는 자리 · [ ] 생략 가능 · ... 반복 가능. 구문 표기 규약을 참고하십시오.
{#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)