AgensGraph 2.18.6.0#
2.18.6.0 릴리스는 AgensGraph를 PostgreSQL 18 위로 옮기고 ISO/IEC 39075(GQL) 표준의 상당 부분을
더합니다. 또한 타입 컬럼 속성 승격을 들여와, 자주 쓰이는 jsonb 속성이 쿼리를 고치지 않고도 실제로
인덱싱할 수 있는 컬럼이 되게 합니다.
잘 돌던 2.17 애플리케이션을 망가뜨릴 변경이 여럿 있습니다. 업그레이드하기 전에 아래 2.18로 옮겨 가기를 읽고, 2.18로 업그레이드하기의 절차를 따르십시오. 2.17 데이터 디렉터리는 2.18 바이너리로 기동할 수 없습니다.
개요#
PostgreSQL 18 기반. 2.17은 PostgreSQL 17.10 위에, 2.18.6.0은 18.6 위에 만들어졌으므로 PostgreSQL 18의 새로운 것이 모두 함께 옵니다.
GQL. 새 문장
LET·NEXT·FILTER·FINISH·INSERT·FOR,CALL { }서브쿼리와CALL … YIELD,OPTIONAL CALL, 서브쿼리 값 표현식EXISTS { }·COUNT { }·COLLECT { }·ARRAY { }·VALUE { }·x IN { }, 독립 절이 된ORDER BY·SKIP·OFFSET·LIMIT,XOR연산자, 그리고CURRENT_GRAPH/CURRENT_PROPERTY_GRAPH입니다. GQL 적합성을 참고하십시오.타입 컬럼 속성 승격.
ALTER VLABEL movie ADD COLUMN year int GENERATED는 속성에 선언한 타입의, 인덱싱할 수 있는 실제 컬럼을 주고, Cypher의 속성 읽기가 쿼리를 고치지 않고도 그것으로 해석됩니다. 속성을 컬럼으로 승격하기를 참고하십시오.네이티브 배열에 담기는 그래프 요소. 정점·간선·경로에 대한
collect()가 jsonb 사본이 아니라vertex[]·edge[]·graphpath[]를 만들므로, 모은 요소를 그대로 쓸 수 있습니다.순회에 대한 플래너 작업.
ag_graphmeta에 기반한 스캔 쳐내기, 쓰이지 않는 패턴 끝점 제거, 가변 길이 간선의 추정 개선이 들어 있습니다.크래시 15종 수정. 그중 몇은 읽기 권한만으로도 닿을 수 있었습니다.
새 기능#
GQL 문장#
문장 |
하는 일 |
|---|---|
범위 안의 것을 하나도 버리지 않고 계산한 값을 행에 더합니다. |
|
한 쿼리를 다른 쿼리의 결과에 이어 붙입니다. |
|
행을 걸러 냅니다. |
|
아무것도 투영하지 않는 쿼리를 끝냅니다. |
|
요소를 만듭니다. |
|
리스트를 순회하며, 인덱스는 |
|
서브쿼리이며, 가져올 변수를 명시적으로 적습니다. |
|
함수를 호출하고 그 출력 컬럼의 이름을 정합니다. |
|
|
|
서브쿼리에 대한 |
ORDER BY·SKIP·OFFSET·LIMIT이 RETURN과 WITH의 일부가 아니라 그 자체로 절이 되었으므로
파이프라인 어디에나 놓을 수 있습니다. 쿼리를 끝맺지는 못합니다. 문장은 여전히 RETURN·FINISH나
쓰기 절로 끝나야 합니다.
그 밖에 새로 생긴 것은 XOR 연산자, NULLIF, IS [NOT] UNKNOWN, RETURN ALL / WITH ALL,
exists(property), size(value), cardinality(), toInteger(), toFloat(), 그리고 Cypher
안에서 쓰는 SQL 값 함수입니다.
이제 형 변환에 키워드 타입을 쓸 수 있습니다. ::int·::numeric·::varchar·::bit·
::interval·::boolean·::date·::timestamptz 등입니다. 그중 몇은 전에는 통하는 표기가 아예
없었습니다. ::timestamp와 ::time은 여전히 Cypher에서 쓸 수 없습니다. 그 둘은 표현식을 SQL로
감싸서 쓰십시오.
타입 컬럼 속성 승격#
속성은 요소마다의 jsonb 문서 안에 있으므로, 읽기는 JSON 문서를 훑게 되고 값 자신의 타입에 대한
인덱스를 쓸 수 없습니다. 승격은 속성 하나에 선언한 타입의, 생성되어 저장되는 컬럼을 줍니다:
ALTER VLABEL movie ADD COLUMN year int GENERATED;
CREATE PROPERTY INDEX ON movie (year);
쿼리는 바뀌지 않습니다. 이제 MATCH (m:movie) WHERE m.year > 2010은 m.year를 그 컬럼으로
해석하고 인덱스를 쓸 수 있습니다. 승격은 레이블을 만들 때도 되며, 컬럼이 이름이 다른 속성에서 값을
받을 수도 있습니다:
CREATE VLABEL doc (words int GENERATED (word_count), score numeric GENERATED);
컬럼은 괄호 안에 적은 속성을 담으므로, words로 해석되는 읽기는 d.word_count입니다. 컬럼
이름이 아니라 속성 키입니다.
확장 타입도 됩니다. 검색에서 중요해지는 것이 바로 이 경우입니다. pgvector를 설치했다면
CREATE VLABEL doc (emb vector(1024) GENERATED)가 임베딩에, 읽을 때마다 형 변환하는 jsonb
배열이 아니라 인덱싱할 수 있는 실제 컬럼을 줍니다.
승격된 키는 더 이상 스키마에서 자유롭지 않습니다. 값이 컬럼의 타입에 맞지 않는 쓰기는 중단됩니다. 그 득실은 속성을 컬럼으로 승격하기가 다룹니다.
그 밖에 더해진 것#
ALTER VLABEL … ADD COLUMN/DROP COLUMN입니다.어느 컬럼이 어느 속성을 담는지 기록하는 새 카탈로그
ag_label_property, 그리고 스캔 쳐내기의 관문이 되는 새 컬럼ag_graph.graphmeta_valid입니다. 시스템 카탈로그를 참고하십시오.새 설정 세 개 —
enable_graph_ddl·enable_property_promotion·enable_graph_endpoint_elision입니다. 서버 설정을 참고하십시오.이제
log_statement = mod가 Cypher 쓰기를 기록합니다. 전에는 데이터를 바꾸는 문장을 남기라고 한 서버가 그중 어느 것도 남기지 않았습니다. SQLINSERT는 기록되고 그 옆의 CypherCREATE는 그러지 않았습니다.
2.18로 옮겨 가기#
지금 잘 돌고 있는 것을 망가뜨릴 가능성이 가장 큰 변경들입니다. 전체 목록과 절차는 2.18로 업그레이드하기에 있습니다.
새 예약어#
이제 xor·current_graph·current_property_graph가 예약어입니다. 그 이름을 가진 식별자·
레이블·변수·별칭은 따옴표로 감싸야 하며, 여기서 따옴표란 SQL에서와 마찬가지로 Cypher에서도
큰따옴표입니다 — MATCH (n:"xor"). 백틱은 여기서 따옴표가 아니므로 `xor` 는 구문
오류입니다.
insert·finish·let도 예약어이지만, 2.16과 2.17에서 통하던 쓰임 두 가지는 일부러
되살렸습니다. 변수로 쓰는 insert, 그리고 패턴 안에서 레이블로 쓰는 insert나 finish입니다.
그런 레이블을 만들 때는 여전히 따옴표가 필요합니다. CREATE VLABEL insert; 는 구문 오류이고
CREATE VLABEL "insert"; 는 되며, 그러고 나면 따옴표 없는 패턴 표기가 그것을 찾습니다. 어느
자리에서든 여전히 따옴표가 필요한 것은 변수 이름으로 쓰는 let이나 finish, 레이블로 쓰는
let, 그리고 let이나 finish라는 별칭으로 정렬하는 것입니다.
어느 단어가 어느 자리에서 실패하는지의 전체 표는 키워드에 있습니다.
CALL은 예약어로 만들지 않았으므로 call은 컬럼·테이블·별칭·레이블·속성 키·변수로 계속 쓸 수
있습니다. 뜻이 달라져 따옴표가 필요한 표기는 정확히 둘입니다. call(...) — 이름이 글자 그대로
call인 함수를 인수와 함께 호출하는 것 — 과, 변수 이름이 call이고 레이블 없이 속성 맵만 지닌
정점 패턴 (call { ... })입니다.
키워드를 참고하십시오.
조건은 불리언만 받는다#
WHERE n.count와 FILTER n.name은 속성을 읽어 0이 아닌지, 비어 있지 않은지로 행을 골랐습니다.
이제 형 변환 오류를 냅니다:
ERROR: cannot cast "Jack" (jsonb type string) to boolean
WHERE·FILTER·AND·OR·NOT·XOR·CASE WHEN과 dijkstra()의 한정자에 적용됩니다.
명시적인 ::boolean은 여전히 변환하며, 진짜 불리언과 jsonb null, 없는 키는 영향을 받지 않습니다.
의도한 변경입니다. ISO/IEC 39075는 검색 조건을 불리언 값 표현식으로 정의합니다.
달라진 결과 타입#
정점·간선·경로에 대한
collect()는 사본을 담은 jsonb 배열이 아니라vertex[]·edge[]·graphpath[]를 반환합니다. 모은 요소에서 속성을 읽는 것이 이제 됩니다. 전에는 조용히 빈 값을 답했습니다. 속성에 대한collect는 여전히 jsonb 리스트를 반환하므로 저장된 데이터의 모양은 그대로입니다.정점이나 간선에 대한
min()과max()는 이제 오류입니다:ERROR: function min(vertex) is not uniquePostgreSQL 18이
min(record)와max(record)를 더했고, 그것이 암시적vertex → jsonb형 변환을 거쳐min(jsonb)/max(jsonb)와 경쟁하게 됐습니다. 명시적으로 변환하거나 —min(v::jsonb)— 식별자를 집계하십시오.min(id(v))입니다.range()는 정수 배열이 아니라 jsonb 배열을 반환합니다.toStringList·toIntegerList·toFloatList는 다시 작성했습니다. 각각 오버로드가 둘입니다. SQL에서 실제 배열에 대해 부르면text[]·bigint[]·double precision[]을 반환하고,jsonb인 Cypher 리스트에 대해 부르면jsonb를 반환합니다. 예전 것들은 여러 가지를 조용히 틀리게 답했습니다. bigint가 상위 비트를 잃었고, 숫자가 아닌 문자열이 0으로 변환됐으며, 원소가 하나인 리스트가 빈 채로 돌아왔고, 64자를 넘는 원소가 고정 버퍼를 넘어갔습니다.
달라진 결과 집합#
SKIP이나 LIMIT이 붙은 WITH … WHERE는 이제 걸러 낸 뒤에 나눕니다. 전에는 나누기가 먼저
일어나서 WITH x WHERE x > 1 ORDER BY x LIMIT 2가 행 하나를 반환할 수 있었습니다. 이제 순서는
WHERE, 그다음 ORDER BY, 그다음 SKIP/LIMIT입니다. 결과 집합이 달라집니다.
RETURN <expr> AS d ORDER BY d는 jsonb 형태가 아니라 값 자체를 정렬합니다. 유한하지 않은
실수를 빼면 순서가 있는 모든 타입에서 행과 정렬은 그대로입니다. 그 실수는 전에 문자열 사이에
정렬됐습니다. 얻는 것은 인덱스가 그 정렬을 맡을 수 있다는 점입니다.
쓰기 절의 변경이 같은 문장의 뒤쪽 읽기에 보입니다.
MATCH (p) SET p.age = 99 WITH p MATCH (q) RETURN q.age 는 쓰기 이전 값을 반환했고,
CREATE (:Q) WITH 1 MATCH (x:Q) RETURN count(x) 는 생성을 조용히 버리면서 0을 반환했습니다.
ALL·ANY·NONE·SINGLE이 3값 논리를 따릅니다. 이제 any([null] WHERE p)는 거짓이 아니라
null입니다. 빈 리스트는 공허하게 참인 결과를 그대로 유지합니다.
엄격해진 검사#
아래는 모두 예전에는 성공했고, 대부분의 경우 틀린 답을 내놓던 것들입니다:
ALTER TABLE은 더는 그래프 레이블의 모양을 바꿀 수 없습니다. 컬럼을 더하거나 지우는 것, 상속을 바꾸는 것, 레이블 컬럼의 이름을 바꾸는 것입니다. 레이블 DDL이 같은 일을 하며,enable_graph_ddl이 그 제한을 풉니다. 그러고도id·start·end·properties의 타입을 바꾸는 것은 거부됩니다.레이블에 대한 SQL
MERGE는 이제enable_graph_dml이 필요합니다.INSERT·UPDATE·DELETE는 이미 그랬습니다.행 수준 보안이 이제 그래프 쓰기에 실제로 적용됩니다.
UPDATE나DELETE정책의USING절이 결코 스캔되지 않는 범위 테이블 항목에 붙어 있어 아무것도 거르지 못했고,DELETE정책이 아예 없는 롤도 행을 지웠습니다.INSERT정책은 엉뚱한 행을 대상으로 검사됐고 간선 생성은 검사된 적이 없어, 행 보안이 걸린 간선 레이블이 모든 삽입을 받아들였습니다. 그래프에 RLS를 기대고 있다면 2.18에서 다시 시험하십시오. 전에는 통과하던 쓰기가 이제 거부됩니다.WITH는 같은 이름을 두 번 담을 수 없고,ORDER BY키는 휘발성 항목으로 계산할 수 없으며, 패턴 변수는 이미 범위에 있는 컬럼과 같은 이름을 쓸 수 없고, 그래프 쓰기는 속성 맵을 스칼라로 바꿔치울 수 없으며,CALL서브쿼리는 바깥에 이미 묶인 이름을 반환할 수 없습니다.
진단#
그래프 요소에 대한 count(), 속성 읽기, 그리고 가변 길이 순회 노드에서 EXPLAIN 출력이
바뀌었습니다. 가변 길이 순회 노드는 이제 자기가 따라가는 간선 레이블의 이름을 표시합니다. 계획 텍스트를
비교하는 회귀 기준이 있다면 갱신하십시오.
수정#
크래시 15종을 고쳤습니다. 그중 몇은 읽기 권한밖에 없는 사용자도 닿을 수 있었고, 그 인스턴스의 모든 세션을 함께 쓰러뜨렸습니다:
head('{}'::text[])가 계획을 짜는 도중 서버를 죽였습니다.RETURN cardinality(['a','b'])가 파싱 시점에 죽었습니다.MATCH ()-[r:e*1..2 = 5]->()— 가변 길이 간선에 맵이 아닌 조건을 붙인 것입니다.CREATE PROPERTY INDEX ON doc (tags[0])입니다.리스트 컴프리헨션 안의 집계입니다.
64자를 넘는 리스트 원소가 고정 버퍼를 넘어갔습니다.
오류가 아니라 틀린 답을 내놓고 있던 수정이 넷 더 있습니다. 2.17.0에서 vertex의 순서와 edge의
같음 판정이 틀려서, 정점에 대한 <·<=·>·>=와 간선에 대한 =가 말하는 그대로를 뜻하지
않았습니다. min(jsonb)와 max(jsonb)는 아무 원소나 반환했습니다. DELETE는 자기가 지운 요소에
대해 빈 값을 반환했고, 그것에 묶인 다른 변수도 비웠습니다. 그리고 그래프 요소에 대한
x IN <list>가 동일성이 아니라 직렬화 전체를 비교했습니다.
이 릴리스 안에서 PostgreSQL 18 회귀도 하나 고쳤습니다. 속성 읽기에 대한 DISTINCT·GROUP BY·
ORDER BY·min()·max()가 “could not determine which collation to use”로 실패했습니다. 이제
그런 키는 데이터베이스 기본값, 즉 jsonb 자신이 쓰는 것과 같은 콜레이션을 취하므로 결과는
그대로입니다.
이 릴리스에 없는 것#
문의가 있었으므로 분명히 적어 둡니다:
CALL { }안의 쓰기 절. 파서가 서브쿼리 본문의CREATE·SET과 그 밖의 쓰기 절을 거부합니다.CALL { } IN TRANSACTIONS는 없습니다.GQL의 세션과 스키마 —
SESSION_SET·USE— 그리고 타입 있는 그래프와 그래프 타입입니다.CREATE OR REPLACE CONSTRAINT. 파싱은 되지만 그다음 거부됩니다.저장되지 않거나 생성되지 않는 승격 컬럼. 승격 컬럼은
GENERATED … STORED여야 합니다.