CALL … YIELD#
GQL 절 2.18에 추가
이름 있는 함수를 호출해 그 함수가 내놓는 컬럼을 작업 행에 더하며, 그 행들을 파이프라인에 조인합니다.
개요#
굵게 키워드 · 기울임 직접 채우는 자리 · [ ] 생략 가능 · ... 반복 가능. 구문 표기 규약을 참고하십시오.
설명#
이 절은 앞선 절의 행에 조인된 함수 스캔이 되어 lateral SELECT * FROM function(arguments)처럼
동작하고, YIELD 목록은 그 결과에서 고릅니다. 내놓을 항목은 함수의 결과에서만 찾고 다른 곳에서는
찾지 않으므로, 함수가 반환하지 않는 이름은 쿼리에 같은 이름의 변수가 바인딩돼 있어도 오류입니다.
YIELD는 필수입니다.YIELD없는CALL f(x)는 구문 오류입니다.이 절은 쿼리를 시작할 수도, 끝낼 수도 없습니다. 문장 맨 앞의
CALL은 PostgreSQL의 SQLCALL로 읽히므로, 맨 앞에 온CALL f() YIELD …는 구문 오류입니다.인자가 앞서 바인딩된 변수를 가리키면 그 호출은 상관 호출이 되어 입력 행마다 한 번 실행됩니다. 인자가 상수면 함수가 한 번 실행되고 그 행들이 파이프라인에 교차 조인됩니다.
내놓인 컬럼은 그 뒤로 평범한 바인딩입니다. 걸러 내고, 집계하고, 그것으로 정렬하고, 뒤따르는
MATCH에 넘길 수 있습니다.함수가 행을 내놓지 못한 입력 행은 내부 조인이 버리는 것과 똑같이 버려집니다. 그 행을 남기려면
OPTIONAL CALL을 쓰십시오.
매개변수#
- function
호출할 함수의 이름이며,
search_path가 닿지 않으면 스키마로 수식합니다. 인자가 없어도 괄호는 필요합니다. 프로시저는<name>() is a procedure로 거부됩니다.- argument
입력 행마다 평가되는 값 표현식입니다. 속성 접근은
jsonb를 내놓으므로, 매개변수가 다른 타입인 함수에는 명시적 형 변환이 필요합니다.- column
그 함수의 출력 컬럼입니다. 스칼라 함수나 단일 컬럼 집합 반환 함수에는 하나가 있고 함수 자신의 이름을 땁니다. 복합 타입이나
RETURNS TABLE함수에는 출력 필드마다 하나가 있고 필드 이름을 그대로 씁니다.YIELD *는 그 전부를 취합니다. 함수 자신의 이름은 그 이름의 컬럼이 없을 때 행 전체를 가리키며,RETURNS SETOF vertex나RETURNS SETOF edge로 선언된 함수는 이렇게 정점이나 간선 그대로 내놓입니다. 그 밖의 이름은function f has no output column "x"로 거부됩니다.- alias
내놓인 컬럼의 새 이름입니다. 그 컬럼의 이름이 쿼리에 이미 바인딩돼 있다면 필수입니다.
예제#
모든 예제는 예제 데이터셋에서 실행됩니다.
영화 한 편의 속성을 행으로 펼칩니다. jsonb_each_text는 컬럼 두 개를 반환하고, YIELD가 둘 다
이름으로 부릅니다:
MATCH (m:movie {title: 'The Matrix'})
CALL jsonb_each_text(jsonb_build_object('title', m.title, 'year', m.year, 'genre', m.genre))
YIELD key, value
RETURN key AS property, value ORDER BY property;
property | value
----------+--------------
"genre" | "Action"
"title" | "The Matrix"
"year" | "1999"
(3 rows)
내놓인 컬럼 이름 바꾸기#
AS는 뒤따르는 모든 절에 대해 그 이름을 바꿉니다:
MATCH (m:movie {title: 'The Matrix'})
CALL jsonb_each_text(properties(m)) YIELD key AS property
RETURN property ORDER BY property;
property
-------------
"embedding"
"genre"
"plot"
"title"
"year"
(5 rows)
일부만 내놓는 것도 됩니다. 여기서 value는 바인딩되지 않습니다.
YIELD * 로 모든 컬럼 취하기#
단일 컬럼 집합 반환 함수는 자기 컬럼에 자신의 이름을 붙입니다:
MATCH (m:movie) WHERE m.genre = 'Adventure'
CALL generate_series(1, 2) YIELD *
RETURN m.title AS film, generate_series AS n ORDER BY n;
film | n
-----------------+---
"Jurassic Park" | 1
"Jurassic Park" | 2
(2 rows)
인자가 상수이므로 generate_series가 한 번 실행되고 그 두 행이 그 영화에 교차 조인됩니다.
호출을 일치한 행과 상관시키기#
행에서 값을 넘기면 함수가 행마다 실행됩니다. m.year는 jsonb이므로 형 변환이 필요합니다:
MATCH (m:movie {title: 'The Matrix'})
CALL generate_series(1, (m.year)::int) YIELD generate_series AS n
RETURN count(n) AS years;
years
-------
1999
(1 row)
형 변환이 없으면 그 함수를 찾지 못합니다:
MATCH (m:movie {title: 'The Matrix'})
CALL generate_series(1, m.year) YIELD generate_series AS n
RETURN count(n);
ERROR: function generate_series(integer, jsonb) does not exist
LINE 2: CALL generate_series(1, m.year) YIELD generate_series AS n
^
HINT: No function matches the given name and argument types. You might need to add explicit type casts.
호출 두 개 잇기#
둘째 호출은 첫 호출이 내놓은 컬럼과 상관될 수 있습니다:
MATCH (m:movie {title: 'The Matrix'})
CALL generate_series(1, 2) YIELD generate_series AS n
CALL generate_series(1, n) YIELD generate_series AS k
RETURN n, k ORDER BY n, k;
n | k
---+---
1 | 1
2 | 1
2 | 2
(3 rows)
행 전체를 내놓기#
함수 자신의 이름을 가진 출력 컬럼이 없으면 그 이름은 행 전체를 가리킵니다. jsonb_each_text는
(key, value) 행을 반환합니다:
MATCH (m:movie {title: 'The Matrix'})
CALL jsonb_each_text(jsonb_build_object('title', m.title, 'year', m.year))
YIELD jsonb_each_text AS pair
RETURN pair ORDER BY pair;
pair
-----------------------------------------
{"key": "title", "value": "The Matrix"}
{"key": "year", "value": "1999"}
(2 rows)
RETURNS SETOF vertex로 선언된 함수도 같은 방식으로, 자신의 이름 아래 정점을 내놓습니다.
참고#
실행 계획은 두 실행 모양 중 어느 것을 받았는지 보여 줍니다. 상관 호출은 내부 쪽이 함수 스캔인
Nested Loop입니다. 상관되지 않은 호출은 함수 스캔을 외부 쪽에 두고 그래프 스캔을
구체화합니다:
EXPLAIN (COSTS OFF)
MATCH (m:movie) CALL generate_series(1, (m.year)::int) YIELD generate_series AS n
RETURN m.title, n;
QUERY PLAN
----------------------------------------
Nested Loop
-> Seq Scan on movie m
-> Function Scan on generate_series
(3 rows)
내놓인 이름이 이미 유효 범위에 있는 바인딩과 충돌하면, 그것을 덮어 가리는 것이 아니라 거부됩니다.
오류는 variable "m" yielded by CALL is already bound in the outer query입니다. AS로 이름을
바꾸십시오.
그 반대도 거부됩니다. 함수의 출력 컬럼이 아닌 이름은 앞서 같은 이름의 변수가 바인딩돼 있어도
거부됩니다. 앞선 바인딩은 YIELD가 가리키는 대상이 아닙니다.
MATCH (m:movie {title: 'The Matrix'})
CALL generate_series(1, 2) YIELD m AS n
RETURN n;
ERROR: function generate_series has no output column "m"
LINE 2: CALL generate_series(1, 2) YIELD m AS n
^
참고
가상 타입 record를 반환하는 함수는 호출할 수 없습니다. PostgreSQL이 요구하는 컬럼 정의 목록을 둘
자리가 이 절에 없으므로, CALL jsonb_to_recordset(…) YIELD *는
a column definition list is required for functions returning "record"를 냅니다. 그런 호출은 대신
SQL 서브쿼리로 감싸십시오.
호환성#
GQL 적합성
§15.1의 call procedure statement 아래에서, §16.14의 yield clause와 함께 GQL의 named procedure call(ISO/IEC 39075:2024 §15.3)을 구현합니다.
지원 — 인자 목록, 상관 인자,
YIELD *와YIELD column [AS alias]형태, 내놓을 항목이 프로시저 결과의 컬럼을 가리켜야 한다는 §16.14 구문 규칙 7, 구문 규칙 6의 중복 별칭 거부, 그리고OPTIONAL접두.미지원 — GQL 프로시저 호출. §15.3은 procedure reference를 §17.5가 기술하는 카탈로그에서 찾는데 AgensGraph에는 그것이 없습니다. 이름은 대신 PostgreSQL 함수로 해석됩니다.
이탈 — §15.3은
YIELD절을 선택으로 둡니다. AgensGraph는 그 절이 작업 테이블에 컬럼을 보태야 하므로 필수로 요구합니다.
진행 상황은 GQL 적합성 표에서 확인하십시오.
openCypher#
openCypher도 같은 절을 쓰지만 그 이름을 프로시저 레지스트리(db.labels(),
dbms.components())에서 찾고, YIELD 없는 CALL proc()을 독립 문장으로 허용합니다. 여기에는 그
레지스트리도, 독립 형태도 없습니다. 이름은 PostgreSQL 함수로 해석되고 YIELD가 필수입니다.
관련 항목#
CALLGQL — 두 호출 형태, 그리고 여기서 루틴이란 무엇인가CALL { subquery }GQL — 인라인 형태OPTIONAL CALLGQL — 함수가 아무것도 내놓지 않은 행 남기기