서버 설정#
AgensGraph는 PostgreSQL의 수백 개 설정에 열한 개를 더합니다. 이 페이지는 그 열한 개를
문서화합니다. 그 밖의 모든 설정은 PostgreSQL의 것이며 바뀌지 않았고,
PostgreSQL의 서버 설정 장이 그것을
설명합니다. 무엇을 어떻게 그리고 어디에 설정하는지는 postgresql.conf·ALTER SYSTEM·
ALTER DATABASE·ALTER ROLE·SET을 다루는 설정을
참고하십시오.
열한 개 중 하나인 graph_path는 Cypher를 실행하는 모든 세션에 필요합니다. 나머지는 쓸 만한
기본값을 가지고 있으므로, 그러지 않을 이유가 생기기 전까지는 신경 쓰지 않아도 됩니다.
설정 목록#
아래의 모든 기본값은 실행 중인 서버에서 읽은 pg_settings.boot_val입니다:
SELECT name, vartype AS type, boot_val AS default, coalesce(unit,'') AS unit, context
FROM pg_settings
WHERE name IN ('allow_null_properties','auto_gather_graphmeta','cypher_allow_unsafe_ddl',
'eager_mem','enable_eager','enable_graph_ddl','enable_graph_dml',
'enable_graph_endpoint_elision','enable_multiple_update',
'enable_property_promotion','graph_path')
ORDER BY name;
name | type | default | unit | context
-------------------------------+---------+---------+------+-----------
allow_null_properties | bool | off | | user
auto_gather_graphmeta | bool | off | | superuser
cypher_allow_unsafe_ddl | bool | off | | user
eager_mem | integer | 4096 | kB | user
enable_eager | bool | on | | user
enable_graph_ddl | bool | off | | user
enable_graph_dml | bool | off | | superuser
enable_graph_endpoint_elision | bool | on | | user
enable_multiple_update | bool | on | | user
enable_property_promotion | bool | on | | user
graph_path | string | | | user
두 가지 context 값은 이렇게 읽습니다:
user어느 롤이든, 어느 세션에서든, 언제든 바꿀 수 있습니다.
postgresql.conf에서, 또는 데이터베이스별· 롤별로도 설정할 수 있습니다.superuser세션에서 이것을 바꿀 수 있는 것은 슈퍼유저, 또는 그 매개변수에
SET권한을 부여받은 롤뿐입니다. 그 밖의 모두는permission denied to set parameter를 받습니다.
postgresql.conf.sample을 읽는 대신 pg_settings를 조회하십시오. 설치 디렉터리에 함께 들어 있는
샘플 파일은 enable_eager와 enable_multiple_update를 off로 적어 두었습니다. 둘의 실제 기본값은
on이므로, 그 파일을 옮겨 적은 표는 두 행이 틀리게 됩니다.
agversion — 설정이 아니라 프리셋#
agversion은 AgensGraph 버전을 알려 줍니다. context가 internal이므로 이것은 프리셋입니다.
설정하는 것이 아니라 서버가 알려 주는 값입니다. postgresql.conf에 쓸 수 없고, 설정하려 하면
거부됩니다:
SET agversion = '1';
ERROR: parameter "agversion" cannot be changed
SELECT name, setting, context, category FROM pg_settings WHERE name = 'agversion';
name | setting | context | category
-----------+------------+----------+----------------
agversion | 2.18.6.0 | internal | Preset Options
무엇에 접속해 있는지 확인하는 보통의 방법인 SHOW로 읽습니다:
SHOW agversion;
agversion
------------
2.18.6.0
version()과 server_version은 이 릴리스가 기반으로 삼은 PostgreSQL 버전을 알려 줍니다. 둘 다
알아야 하는 클라이언트는 둘 다 읽어야 합니다.
graph_path#
string · default '' (empty) · context user
세션이 작업하는 그래프를 지정합니다. Cypher나 GQL 문장에서 한정하지 않은 모든 레이블 이름이 그
그래프에서 해석됩니다. 모든 그래프 DDL 문장이 거기에 레이블을 만들거나 변경합니다. 그래프판
search_path이며, 건너뛸 수 없는 유일한 설정입니다.
이것이 없으면 아무것도 해석되지 않습니다:
RESET graph_path;
MATCH (n:person) RETURN count(n);
ERROR: graph_path is NULL
HINT: Use SET graph_path
설정하면 같은 문장이 실행됩니다:
SET graph_path = moviekb;
SHOW graph_path;
graph_path
------------
moviekb
CURRENT_GRAPH는 문장 안에서 키워드만으로 같은 값을 읽습니다:
SELECT CURRENT_GRAPH;
current_graph
---------------
moviekb
그래프 이름은 정확히 하나#
search_path와 달리 graph_path는 목록이 아닙니다. 쉼표로 구분한 값을 이름 두 개로 해석하지
않습니다. 이름 하나로 받아들이며, 그런 이름은 존재하지 않습니다:
SET graph_path = 'moviekb, twins';
ERROR: invalid value for parameter "graph_path": "moviekb, twins"
DETAIL: graph "moviekb, twins" does not exist.
그러므로 세션 하나는 그래프 하나를 읽고 씁니다. 한 문장에서 그래프 두 개에 닿으려면 둘을 스키마 두 개로 보는 SQL을 쓰십시오. 그 방법은 SQL과 Cypher 섞어 쓰기에 있습니다.
값을 언제 검사하는가#
존재하지 않는 그래프는 쿼리를 실행할 때가 아니라 SET 하는 시점에 거부됩니다:
SET graph_path = nosuchgraph;
ERROR: invalid value for parameter "graph_path": "nosuchgraph"
DETAIL: graph "nosuchgraph" does not exist.
이름은 식별자이므로 따옴표로 감싸지 않으면 소문자로 내려갑니다. 대소문자를 섞은 이름으로 만든 그래프에는 따옴표가 필요합니다:
CREATE GRAPH "MixedCase";
SET graph_path = MixedCase;
ERROR: invalid value for parameter "graph_path": "mixedcase"
DETAIL: graph "mixedcase" does not exist.
SET graph_path = "MixedCase";
SHOW graph_path;
graph_path
------------
MixedCase
DROP GRAPH "MixedCase" CASCADE;
SET graph_path = moviekb;
데이터베이스나 롤에 값 하나 지정하기#
SET은 그 세션 동안만 유지됩니다. 더 넓은 범위 두 가지가 그 되풀이를 덜어 주며, 둘 다 지금 접속이
아니라 다음 접속부터 적용됩니다.
어떤 데이터베이스에 접속하는 모두에게 적용하려면:
ALTER DATABASE docs SET graph_path = moviekb;
ALTER DATABASE
어느 데이터베이스에 접속하든 특정 롤 하나에 적용하려면:
ALTER ROLE analyst SET graph_path = moviekb;
ALTER ROLE
둘 다 pg_db_role_setting에서 보이며, 롤 설정이 데이터베이스 설정을 이깁니다:
SELECT r.rolname, s.setconfig FROM pg_db_role_setting s
JOIN pg_roles r ON r.oid = s.setrole WHERE r.rolname = 'analyst';
rolname | setconfig
---------+----------------------
analyst | {graph_path=moviekb}
그 뒤에 접속하는 롤에는 이미 값이 들어 있습니다:
SHOW graph_path;
graph_path
------------
moviekb
ALTER DATABASE … RESET graph_path와 ALTER ROLE … RESET graph_path가 그것을 다시 없앱니다.
postgresql.conf에 클러스터 전체 기본값을 두는 것도 되지만, 원하는 바인 경우는 드뭅니다. 클러스터의
모든 데이터베이스가 그 그래프를 가진 것처럼 말하게 되기 때문입니다.
값은 카탈로그와 대조해 검사하므로, ALTER DATABASE db SET graph_path는 db에 접속한 상태에서
실행해야 합니다. 검사는 현재 데이터베이스에서 그 그래프를 찾습니다. 다른 곳에서 실행하면
실패합니다:
ALTER DATABASE docs SET graph_path = moviekb;
ERROR: invalid value for parameter "graph_path": "moviekb"
DETAIL: graph "moviekb" does not exist.
allow_null_properties#
bool · default off · context user
null 속성 값을 저장할 것인지 버릴 것인지 결정합니다.
꺼져 있으면 null을 대입하는 것이 속성을 지웁니다. 그러면 null로 설정한 속성과 애초에 없던 속성이 같은 것이 됩니다. 켜면 null이 JSON null로 저장되고 키가 남습니다.
CREATE GRAPH nulls;
SET graph_path = nulls;
CREATE VLABEL t;
CREATE (:t {name: 'a', extra: null});
SET allow_null_properties = on;
CREATE (:t {name: 'b', extra: null});
MATCH (n:t) RETURN n ORDER BY id(n);
n
------------------------------------
t[3.1]{"name": "a"}
t[3.2]{"name": "b", "extra": null}
값이 없는 것과 null인 것의 뜻이 다르고 그 구별을 지켜야 하는 데이터를 적재할 때 켜십시오. 보통 관계형 원본에서 가져오는 경우입니다.
대가는 저장된 null이 값 없이 존재하는 키가 된다는 것입니다. 검사들이 서로 다르게 답합니다:
MATCH (n:t) RETURN exists(n.extra) AS exists, n.extra IS NULL AS is_null,
properties(n) ? 'extra' AS key_present;
exists | is_null | key_present
--------+---------+-------------
f | t | t
REMOVE n.extra는 이 설정이 무엇이든 키를 지웁니다. 속성을 없애는 방법은 여전히 이것입니다.
RESET allow_null_properties;
DROP GRAPH nulls CASCADE;
SET graph_path = moviekb;
auto_gather_graphmeta#
bool · default off · context superuser
모든 그래프 쓰기의 부수 효과로 ag_graphmeta를 최신 상태로 유지합니다.
ag_graphmeta는 그래프의 (시작 레이블, 간선 레이블, 끝 레이블) 삼중마다 간선이 몇 개인지
기록합니다. 플래너는 그것으로 스캔을 쳐냅니다. 어떤 레이블과 도저히 일치할 수 없는 MATCH는 아예
스캔하지 않습니다. 이 설정이 꺼져 있으면 그 테이블은 마지막 regather_graphmeta() 호출 시점까지만
최신입니다.
켜면 즉시 전체 수집이 일어나므로, 그 시점부터 테이블이 정확해집니다:
SET auto_gather_graphmeta = on;
NOTICE: regathering graphmeta...
SET
SELECT g.graphname, se.labname AS start, e.labname AS edge, ee.labname AS "end", m.edgecount
FROM pg_catalog.ag_graphmeta m
JOIN pg_catalog.ag_graph g ON g.oid = m.graph
JOIN pg_catalog.ag_label e ON e.graphid = m.graph AND e.labid = m.edge
JOIN pg_catalog.ag_label se ON se.graphid = m.graph AND se.labid = m.start
JOIN pg_catalog.ag_label ee ON ee.graphid = m.graph AND ee.labid = m."end"
WHERE g.graphname = 'moviekb' ORDER BY 3;
graphname | start | edge | end | edgecount
-----------+--------+------------+-------+-----------
moviekb | person | acted_in | movie | 25
moviekb | person | directed | movie | 21
moviekb | movie | related_to | movie | 11
RESET auto_gather_graphmeta;
읽기가 대부분인 그래프에는 켜십시오. 쓰기마다 드는 약간의 일보다 정확한 메타데이터가 값어치가
있습니다. 쓰기가 많은 적재에는 꺼 둔 채로 두고 끝난 뒤에 regather_graphmeta()를 호출하십시오.
pg_upgrade나 복원 뒤에도 반드시 호출해야 합니다. 그 테이블과 그것이 가능하게 하는 쳐내기는
그래프 메타데이터가 다룹니다.
cypher_allow_unsafe_ddl#
bool · default off · context user
카탈로그가 더는 설명하지 못하는 그래프와 사용자 사이를 평소에 막고 서 있는 카탈로그 검사 두 개를 건너뜁니다. 그래프를 고치기 위한 것이지, 그 상태로 작업하기 위한 것이 아닙니다.
graph_path가 존재하지 않는 그래프를 가리킬 수 있게 합니다. 검사가 SET 시점에서 쿼리 실행
시점으로 옮겨 가고, 그때의 메시지는 다릅니다:
SET cypher_allow_unsafe_ddl = on;
SET graph_path = nosuchgraph;
SHOW graph_path;
graph_path
-------------
nosuchgraph
MATCH (n) RETURN count(n);
ERROR: current graph_path "nosuchgraph" is invalid
HINT: Use SET graph_path
RESET cypher_allow_unsafe_ddl;
SET graph_path = moviekb;
레이블을 잘못된 종류로 삭제할 수 있게 합니다. 간선 레이블에 DROP VLABEL을 쓰는 것은 평소에는
거부됩니다. 이 설정을 켜면 성공합니다:
CREATE GRAPH unsafe;
SET graph_path = unsafe;
CREATE ELABEL e;
DROP VLABEL e;
ERROR: DROP VLABEL cannot DROP edge label
SET cypher_allow_unsafe_ddl = on;
DROP VLABEL e;
DROP VLABEL
RESET cypher_allow_unsafe_ddl;
DROP GRAPH unsafe CASCADE;
SET graph_path = moviekb;
둘이 쓸모 있는 상황은 정확히 하나입니다. 카탈로그와 테이블이 어긋난 그래프를 해체하려는 경우입니다. 그것이 필요한 문장에만 설정하고 곧바로 되돌리십시오.
eager_mem#
integer · default 4096 · unit kB · context user · minimum 1024
eager 계획 노드 하나가 디스크로 넘기기 전에 쓸 수 있는 메모리 양입니다. eager 계획을 위한
work_mem이며, work_mem이 그렇듯 쿼리별이나 접속별이 아니라 노드별입니다.
SHOW eager_mem;
SET eager_mem = '64MB';
SHOW eager_mem;
eager_mem
-----------
4MB
(1 row)
SET
eager_mem
-----------
64MB
(1 row)
최솟값은 1 MB이며, 더 작은 값은 잘라 맞추는 것이 아니라 거부됩니다:
SET eager_mem = '512kB';
ERROR: 512 kB is outside the valid range for parameter "eager_mem" (1024 kB .. 2147483647 kB)
RESET eager_mem;
자기가 쓴 것을 읽는 쓰기가 디스크로 넘어가고 있다면 올리십시오.
enable_eager를 참고하십시오. 기본값 4 MB는 work_mem의 것과 같은 보수적인
출발점입니다. 큰 중간 결과를 구체화하는 문장은 이 값을 넘어섭니다.
enable_eager#
bool · default on · context user
플래너가 eager 계획, 즉 뒤의 절이 읽기 전에 쓰기의 출력을 구체화하는 계획을 만들 수 있게 합니다.
어떤 문장에는 그것이 필요합니다. CREATE 다음에, 그 CREATE가 방금 만든 것과 일치할 수 있는
MERGE가 오는 경우를 보십시오. 둘을 행 단위로 번갈아 실행할 수 없습니다. 두 번째 절이 절반만 쓰인
그래프를 보게 되기 때문입니다. 그래서 플래너는 첫 절의 결과를 버퍼에 담습니다. EXPLAIN은 그 노드를
eager로 표시합니다:
CREATE GRAPH eager;
SET graph_path = eager;
CREATE VLABEL src;
CREATE VLABEL dst;
CREATE (:src {n: 1}), (:src {n: 2});
EXPLAIN (COSTS OFF) MATCH (a:src) CREATE (:dst {n: a.n}) MERGE (:dst {n: a.n + 10});
QUERY PLAN
----------------------------------------------------------------------------------------------------------------
Graph Merge
-> Nested Loop CypherMerge Join
Join Filter: ("<0000000000>".properties.'n' = ((_agens_default_s_1.a).properties.'n' `+` '10'::jsonb))
-> Subquery Scan on _agens_default_s_1
-> Graph Create eager
-> Seq Scan on src a
-> Seq Scan on dst "<0000000000>"
이것을 끈다고 해서 그런 문장이 다른 방식으로 실행되지는 않습니다. 실패하게 됩니다:
SET enable_eager = off;
MATCH (a:src) CREATE (:dst {n: a.n}) MERGE (:dst {n: a.n + 10});
ERROR: eagerness plan is not allowed.
RESET enable_eager;
DROP GRAPH eager CASCADE;
SET graph_path = moviekb;
그러므로 이것은 PostgreSQL의 enable_hashjoin 같은 비용 기반 토글이 아닙니다. 켜 두십시오. 어떤
문장이 eager 계획에 의존하는지 알아보려 할 때만 끄십시오. 큰 쓰기를 더 싸게 만들려 할 때 그것이
중요해집니다.
enable_graph_ddl#
bool · default off · context user
SQL DDL이 그래프 레이블의 모양을 바꿀 수 있게 합니다.
레이블을 그래프 레이블이게 하는 것은 그 컬럼들이고, 그래프 카탈로그가 그것을 설명합니다.
ALTER TABLE은 그 카탈로그를 갱신하지 않습니다. 그것으로 레이블의 모양을 바꾸면 그래프가 더는
사실이 아닌 것을 설명하게 될 수 있습니다. 꺼져 있으면 그런 시도는 거부되고, 카탈로그를 함께 맞춰
주는 문장을 힌트로 알려 줍니다:
ALTER TABLE moviekb.movie ADD COLUMN note text;
ERROR: cannot add a column to graph label "movie" with ALTER TABLE
HINT: Use ALTER VLABEL or ALTER ELABEL instead, which keeps the graph catalog in step.
ALTER TABLE moviekb.movie DROP COLUMN properties;
ERROR: cannot drop a column of graph label "movie" with ALTER TABLE
HINT: Use ALTER VLABEL or ALTER ELABEL instead, which keeps the graph catalog in step.
ALTER TABLE moviekb.movie NO INHERIT moviekb.ag_vertex;
ERROR: cannot remove a parent label from graph label "movie" with ALTER TABLE
HINT: A label's parents are fixed when it is created.
거부되는 것의 전체 목록입니다. 컬럼을 더하거나 지우거나 타입을 바꾸는 것, 컬럼의 생성 표현식을 떼어 내거나 바꾸는 것, not-null 제약을 컬럼으로 지목하든 제약 이름으로 지목하든 지우는 것, 부모 레이블을 더하거나 없애는 것입니다. 같은 설정이 레이블의 컬럼 이름을 바꾸는 것과 레이블을 다른 스키마로 옮기는 것도 거부합니다.
켜면 그 모두가 풀립니다. 무슨 권한을 주는 것은 아닙니다. 그 레이블을 변경할 수 있는 사람이 여전히 그 레이블에 무슨 일이 일어날지 정합니다. 모양을 바꾸는 일이 의도된 것이기를 요구할 뿐입니다.
절대 풀리지 않는 것이 둘 있습니다. id·start·end·properties의 타입은 전혀 바꿀 수
없습니다. 모든 정점과 간선이 그 컬럼들로 이루어져 있기 때문입니다:
SET enable_graph_ddl = on;
ALTER TABLE moviekb.movie ALTER COLUMN properties TYPE text;
ERROR: cannot change the type of column "properties" of graph label "movie"
DETAIL: Every vertex and edge is made of that column.
RESET enable_graph_ddl;
그리고 테이블 자체의 이름을 바꾸거나 지우는 것은 각자의 메시지와 함께 계속 거부됩니다
(cannot rename table "movie", cannot drop table … because vlabel … requires it).
ALTER VLABEL … RENAME TO와 DROP VLABEL을 쓰십시오.
직접 설정하든 하지 않든 이 설정을 만나게 됩니다. 평범한 컬럼을 지닌 레이블에 대해 pg_dump는
복원이 되도록 ALTER TABLE 문장을 SET enable_graph_ddl = on으로 감쌉니다.
서버 측 도구를 참고하십시오.
enable_graph_dml#
bool · default off · context superuser
그래프 레이블에 대한 SQL INSERT·UPDATE·DELETE·MERGE를 허용합니다.
SQL로 레이블을 읽는 데는 설정이 필요 없습니다. 쓰는 데는 필요합니다. Cypher의 쓰기 경로가 그래프를 일관되게 지키기 때문입니다. 존재하는 양 끝점, 레이블과 맞는 id, 그리고 그에 딸린 메타데이터입니다. 꺼져 있으면 모든 SQL 쓰기가 거부됩니다:
INSERT INTO moviekb.movie (properties) VALUES ('{"title": "x"}');
ERROR: DML query to graph objects is not allowed
UPDATE moviekb.movie SET properties = '{}';
ERROR: DML query to graph objects is not allowed
DELETE FROM moviekb.movie;
ERROR: DML query to graph objects is not allowed
켜면 그래프가 말하는 대로라는 보장을 포기하게 됩니다. 간선 레이블에 대한 INSERT는 양 끝점이
존재하는지 검사하지 않으므로, 매달린 간선을 만들 수 있습니다. Cypher로는 그런 것을 만들 수
없습니다:
CREATE GRAPH dangling;
SET graph_path = dangling;
CREATE VLABEL v;
CREATE ELABEL e;
CREATE (:v {n: 1});
SET enable_graph_dml = on;
INSERT INTO dangling.e (start, "end", properties)
VALUES ('3.1'::graphid, '99.99'::graphid, '{}');
RESET enable_graph_dml;
INSERT 0 1
그 결과는 서로 다른 두 쿼리가 다르게 답하는 간선입니다. 양 끝점을 모두 묶는 패턴은 아무것도 찾지 못합니다. 없는 정점과의 조인이 실패하기 때문입니다:
MATCH (a)-[r:e]->(b) RETURN a, r, b;
a | r | b
---+---+---
(0 rows)
양 끝점을 아무것도 묶지 않는 패턴은 그것을 셉니다. 조인할 것이 없기 때문입니다:
MATCH ()-[r:e]->() RETURN count(r) AS edges;
edges
-------
1
DROP GRAPH dangling CASCADE;
SET graph_path = moviekb;
조심해서 작성한 대량 적재를 할 때, 또는 Cypher가 닿지 못하는 행을 고칠 때 켰다가 다시 끄십시오.
superuser 설정 둘 중 하나입니다. 평범한 롤이 SET enable_graph_dml = on을 시도하면
ERROR: permission denied to set parameter "enable_graph_dml"을 받으며, 스스로 켤 수 없습니다.
enable_graph_endpoint_elision#
bool · default on · context user
쿼리가 전혀 쓰지 않는 패턴 끝점에 대한 스캔을 플래너가 없앨 수 있게 합니다.
->() 같은 익명 끝점은 조인 말고는 보태는 것이 없습니다. 그 끝점에 레이블도 속성 조건도 없다면 그
조인은 행을 걸러 내지도 못합니다. 플래너는 그것을 없앱니다. 이름이 레이블을 제한하는 데만 쓰인
경우에는 이름 있는 끝점도 없앱니다. 간선의 끝점 id에 대한 레이블 검사는 그 간선 자체에 대한
graphid 범위 검사이기 때문입니다:
EXPLAIN (COSTS OFF) MATCH (p:person)-[r:acted_in]->() RETURN count(r);
QUERY PLAN
-----------------------------------------------------------------------------------------
Aggregate
-> Seq Scan on acted_in r
Filter: ((start >= '4.0'::graphid) AND (start <= '4.281474976710655'::graphid))
이것이 없으면 같은 쿼리가 릴레이션 세 개를 조인하고, 들여다보지도 않을 끝점을 위해 정점 계층 전체를 스캔합니다:
SET enable_graph_endpoint_elision = off;
EXPLAIN (COSTS OFF) MATCH (p:person)-[r:acted_in]->() RETURN count(r);
QUERY PLAN
-----------------------------------------------------------------------------------------------------
Aggregate
-> Hash Join
Hash Cond: (r."end" = "<0000000001>".id)
-> Hash Join
Hash Cond: (r.start = p.id)
-> Seq Scan on acted_in r
Filter: ((start >= '4.0'::graphid) AND (start <= '4.281474976710655'::graphid))
-> Hash
-> Seq Scan on person p
-> Hash
-> Append
-> Seq Scan on ag_vertex "<0000000001>_1"
-> Seq Scan on movie "<0000000001>_2"
-> Seq Scan on person "<0000000001>_3"
RESET enable_graph_endpoint_elision;
열한 개 중 EXPLAIN (SETTINGS)가 보고하는 것은 이것뿐이므로, 이 값을 바꾼 세션에서 뽑은 계획은
그 사실을 함께 알려 줍니다. 계획을 비교할 때만 끄십시오.
enable_multiple_update#
bool · default on · context user
한 문장에서 같은 요소를 두 번 이상 쓰는 것을 조용히 넘길지 경고할지 결정합니다.
패턴이 어떤 요소와 여러 번 일치하는 문장은 일치할 때마다 그것을 씁니다. 켜져 있으면 그 일이 조용히 일어납니다. 꺼져 있으면 서버가 되풀이마다 경고합니다. 쓰기는 그대로 일어나므로, 이것은 제한이 아니라 진단 장치입니다:
CREATE GRAPH repeats;
SET graph_path = repeats;
CREATE VLABEL t;
CREATE (:t {n: 0}), (:t {n: 0});
MATCH (a:t) MATCH (b:t) SET b.n = b.n + 1 RETURN count(b) AS rows;
MATCH (n:t) RETURN n ORDER BY id(n);
rows
------
4
n
----------------
t[3.1]{"n": 1}
t[3.2]{"n": 1}
크로스 조인이 행 네 개를 만들어 각 정점에 두 번씩 닿았지만, n은 하나만 올랐습니다. 설정을 끄면
같은 문장이 그 사실을 알려 줍니다:
SET enable_multiple_update = off;
MATCH (a:t) MATCH (b:t) SET b.n = b.n + 1 RETURN count(b) AS rows;
WARNING: graph element(3,1) has been SET multiple times
WARNING: graph element(3,2) has been SET multiple times
rows
------
4
RESET enable_multiple_update;
DROP GRAPH repeats CASCADE;
SET graph_path = moviekb;
SET이 기대한 대로 하지 않은 이유를 따질 때 꺼 두십시오. 되풀이된 쓰기는 대개 패턴이 의도보다
많이 일치한다는 신호입니다. 경고는 레이블 id와 로컬 id를 알려 주는데, 그것이 그 요소의
graphid입니다.
enable_property_promotion#
bool · default on · context user
승격된 타입 컬럼이 있을 때 Cypher의 속성 읽기를 그 컬럼에서 답할지 결정합니다.
속성은 실제 타입을 가진 실제 컬럼으로 구체화할 수 있습니다.
속성을 컬럼으로 승격하기를 참고하십시오. 켜져 있으면 n.key가 그
컬럼을 읽고 그 컬럼의 타입으로 돌아옵니다. 꺼져 있으면 모든 읽기가 jsonb 컬럼인 properties로 가서 jsonb로
돌아옵니다:
CREATE GRAPH promoted;
SET graph_path = promoted;
CREATE VLABEL item (score int GENERATED);
CREATE (:item {score: 3}), (:item {score: 20}), (:item {score: 100});
MATCH (n:item) RETURN n.score AS score, pg_typeof(n.score) AS type ORDER BY n.score;
score | type
-------+-----------
3 | "integer"
20 | "integer"
100 | "integer"
SET enable_property_promotion = off;
MATCH (n:item) RETURN n.score AS score, pg_typeof(n.score) AS type ORDER BY n.score;
score | type
-------+---------
3 | "jsonb"
20 | "jsonb"
100 | "jsonb"
경고
비용에만 관여하는 플래너 토글과 달리, 이것을 끄면 쿼리 결과가 달라질 수 있습니다. 해석된
n.key는 그 타입 컬럼의 고유한 의미 — 수치 또는 콜레이션 정렬, 그리고 타입을 아는 비교 — 를 쓰는
반면, jsonb 대체 경로는 jsonb의 정렬과 비교를 씁니다. 정렬이나 범위 조건, 타입이 다른 값끼리의
비교가 다르게 나올 수 있습니다.
RESET enable_property_promotion;
DROP GRAPH promoted CASCADE;
SET graph_path = moviekb;
켜 두십시오. 승격된 컬럼이 쿼리의 답을 바꿨는지 확인할 때 끄십시오. 그리고 다시 켠 뒤에 쿼리나 컬럼 쪽을 고치십시오.