FOR#

GQL 절 2.18에 추가

리스트를 행으로 펼치며, 요소마다 행 하나를 만들고, 각 요소의 위치를 선택적으로 바인딩합니다. Cypher의 UNWIND에 대응하는 GQL 절입니다.

개요#

FOR variable IN list [ WITH OFFSET [ AS offset_variable ] ]

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

설명#

FOR는 각 입력 행을 리스트의 요소와 조인하므로, 요소 n개인 리스트를 만난 입력 행은 출력 행 n개가 됩니다. 리스트가 그 행에 의존한다면 펼치기가 행마다 실행됩니다.

  • 요소 변수는 새 이름이어야 합니다. 유효 범위에 있는 이름을 다시 쓰면 duplicate variable "<name>"이 나옵니다.

  • WITH OFFSET은 각 요소의 위치를 바인딩합니다. 그 위치는 0부터 셉니다.

  • 빈 리스트, null인 리스트, 없는 속성은 모두 행을 하나도 내놓지 않으므로, 아무것도 없는 것에 대한 FOR는 자기 입력 행을 떨어뜨립니다.

  • 스칼라는 리스트가 아니므로 리스트로 감싸이지 않고 거부됩니다.

  • FOR는 쿼리를 시작하거나, 가운데에 놓이거나, 쓰기 절을 돌릴 수 있습니다. 쿼리를 끝낼 수는 없습니다.

매개변수#

variable

출력 행마다 요소 하나에 바인딩되는 이름입니다. 이미 유효 범위에 있어서는 안 됩니다.

list

리스트를 내놓는 표현식이면 무엇이든 됩니다. 리터럴, range(), 리스트 값을 가진 속성, 앞선 collect()가 만든 리스트, +로 이어 붙인 두 리스트가 그렇습니다.

offset_variable

요소의 0부터 시작하는 위치에 바인딩되는 이름입니다. AS 절을 생략하면 그 위치가 offset에 바인딩됩니다. 그것은 예약어이므로 그 뒤로는 어디서나 "offset"으로 써야 합니다. AS 형태를 쓰는 편이 낫습니다.

예제#

모든 예제는 예제 데이터셋에서 실행됩니다.

제목 리스트를 펼쳐 하나씩 찾아봅니다. FOR와 Cypher의 UNWIND는 같은 리스트를 펼칩니다. 탭을 바꿔 비교해 보십시오:

FOR t IN ['The Matrix', 'Inception', 'Gattaca']
MATCH (m:movie {title: t})
RETURN t AS title, m.year AS year ORDER BY year;
UNWIND ['The Matrix', 'Inception', 'Gattaca'] AS t
MATCH (m:movie {title: t})
RETURN t AS title, m.year AS year ORDER BY year;
    title     | year
--------------+------
 "Gattaca"    | 1997
 "The Matrix" | 1999
 "Inception"  | 2010
(3 rows)

펼치면서 요소에 번호를 붙이기#

WITH OFFSET AS가 그 위치에 이름을 붙입니다. 순위가 매겨진 제목 목록처럼 리스트의 순서가 곧 답일 때 필요한 것입니다:

FOR t IN ['The Matrix', 'Inception', 'Gattaca'] WITH OFFSET AS i
MATCH (m:movie {title: t})
RETURN i, t AS title ORDER BY i;
 i |    title
---+--------------
 0 | "The Matrix"
 1 | "Inception"
 2 | "Gattaca"
(3 rows)

첫 요소는 1이 아니라 0에 있습니다.

이름을 붙이지 않고 위치에 손대기#

AS 절을 빼도 위치는 바인딩되지만, 예약 키워드인 offset이라는 이름으로 바인딩됩니다. 그 뒤의 모든 참조는 따옴표로 감싸야 합니다:

FOR t IN ['The Matrix', 'Inception'] WITH OFFSET RETURN "offset", t;
 offset |      t
--------+--------------
 0      | "The Matrix"
 1      | "Inception"
(2 rows)

따옴표를 빼면 그 쿼리는 파싱되지 않습니다:

FOR t IN ['The Matrix'] WITH OFFSET RETURN offset, t;
ERROR:  syntax error at or near "offset"
LINE 1: FOR t IN ['The Matrix'] WITH OFFSET RETURN offset, t;
                                                   ^

리스트 값을 가진 속성 펼치기#

리스트는 일치한 행에서 올 수도 있고, 그 경우 펼치기가 행마다 실행됩니다:

MATCH (m:movie {title: 'The Matrix'})
FOR e IN m.embedding
RETURN e ORDER BY e;
      e
-------------
 -0.11921061
 -0.07594558
 0.04081754
 0.29592122
(4 rows)

쿼리가 필요한 행을 만들어 내기#

range()도 다른 것과 같은 리스트이므로, FOR가 생성된 키에 대한 조회를 돌릴 수 있습니다:

FOR y IN range(1999, 2001)
MATCH (m:movie {year: y})
RETURN y, m.title AS film ORDER BY y, film;
  y   |     film
------+--------------
 1999 | "The Matrix"
(1 row)

참고#

FOR는 lateral unnest()로 컴파일되고, UNWIND는 ProjectSet으로 컴파일됩니다. 둘은 뜻으로는 바꿔 쓸 수 있지만 같은 실행 계획은 아닙니다:

EXPLAIN (COSTS OFF) FOR x IN [1, 2, 3] RETURN x;
                 QUERY PLAN
--------------------------------------------
 Function Scan on unnest _agens_default_for
(1 row)

펼치기가 unnest()를 지나므로, 스칼라 원천은 요소 하나짜리 리스트가 아니라 타입 오류입니다. 정수는 function unnest(integer) does not exist를 내고, 스칼라 속성은 cannot extract elements from a scalar를 냅니다. 반대로 null은 빈 리스트로 취급되어 행을 내놓지 않습니다.

참고

FOR는 PostgreSQL에서 이미 예약 키워드이므로, 이 절이 식별자 이름에 새 제한을 더하지는 않습니다. offset도 예약어이고, 그래서 WITH OFFSET만 쓴 형태는 다시 읽는 자리에서 따옴표로 감싸야 합니다.

호환성#

GQL 적합성

GQL FOR 문장(ISO/IEC 39075:2024 §14.8), 기능 GQ10 “FOR statement: list value support”, 기능 GQ24 “FOR statement: WITH OFFSET”를 구현합니다.

  • 지원 — 리스트 값 표현식의 전개, 입력 행마다의 평가, null 원본을 빈 리스트로 다루는 것, 그리고 표준이 규정하는 0부터 세는 위치(§14.8 일반 규칙 2의 j−1)를 주는 WITH OFFSET.

  • 미지원 — 1부터 세는 짝인 WITH ORDINALITY(기능 GQ11). 대신 오프셋에 1을 더하십시오. 원본 자리에 <binding table reference value expression>을 쓰는 것(기능 GQ23)도 지원하지 않습니다. AgensGraph에는 이름 붙은 바인딩 테이블이 없기 때문입니다.

  • 이탈 — 표준은 위치 변수를 AS 없이 씁니다(WITH OFFSET i). AgensGraph는 WITH OFFSET AS i를 요구하며, 그냥 쓴 WITH OFFSET은 이름을 offset으로 정합니다.

진행 상황은 GQL 적합성 표에서 확인하십시오.

openCypher#

openCypher는 이 절을 UNWIND … AS x로 표기하며, AgensGraph는 그것을 그대로 받습니다. 그 표기에는 위치를 주는 형태가 없습니다.

관련 항목#