ALTER VLABEL과 ALTER ELABEL#

레이블의 이름을 바꾸고, 저장 방식을 바꾸고, 부모를 붙이거나 떼고, 인덱스를 끄고, 승격된 타입 컬럼을 추가하거나 제거합니다.

개요#

ALTER VLABEL [ IF EXISTS ] label_name action [, ... ]
ALTER VLABEL [ IF EXISTS ] label_name RENAME TO new_label_name

ALTER ELABEL [ IF EXISTS ] label_name action [, ... ]
ALTER ELABEL [ IF EXISTS ] label_name RENAME TO new_label_name

where action is one of:

    ADD [ COLUMN ] promoted_property
    DROP [ COLUMN ] column_name [ CASCADE | RESTRICT ]
    DISABLE INDEX
    SET STORAGE { PLAIN | EXTERNAL | EXTENDED | MAIN }
    SET TABLESPACE tablespace_name
    SET { LOGGED | UNLOGGED }
    CLUSTER ON index_name
    SET WITHOUT CLUSTER
    INHERIT parent_label
    NO INHERIT parent_label
    REPLICA IDENTITY { DEFAULT | USING INDEX index_name | FULL | NOTHING }
    OWNER TO role_specification

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

설명#

ALTER VLABEL은 정점 레이블에, ALTER ELABEL은 간선 레이블에 작용합니다. 키워드를 빼면 두 문장은 같습니다. 위에 나열한 모든 동작이 두 종류 모두에서 받아들여집니다. 다른 것은 그 동작이 작용할 대상을 각 레이블 종류가 무엇으로 갖고 있는가입니다.

  • 레이블이 만들어질 때 함께 생기는 인덱스가 다릅니다. 정점 레이블에는 id에 대한 기본 키가 생기고, 간선 레이블에는 (start, "end")와 ("end", start)에 걸린 btree 인덱스와 id에 걸린 BRIN 인덱스가 생깁니다. DISABLE INDEX는 어느 쪽이든 그 레이블의 모든 인덱스를 무효로 만들므로, 갓 만든 정점 레이블에서는 무효로 만들 것이 하나이고 간선 레이블에서는 셋입니다. CLUSTER ON도 고를 수 있는 이름이 다릅니다.

  • DROP COLUMN이 거부하는 구조 컬럼은 정점 레이블에서 id와 properties이고, 간선 레이블에는 start와 end가 더해집니다.

  • INHERIT와 NO INHERIT는 그 레이블과 같은 종류이고 같은 그래프에 있는 부모를 요구합니다.

레이블은 graph_path가 지정한 그래프에서 찾습니다. 그 이름은 수식할 수 없습니다.

  • RENAME TO는 그 자체로 하나의 형태입니다. 다른 어떤 동작과도 함께 쓸 수 없고, 여러 동작을 나열한 목록에 들어갈 수도 없습니다.

  • 한 문장의 여러 동작은 쉼표로 구분하며 적은 순서대로 적용됩니다.

  • 기반 레이블인 ag_vertex와 ag_edge는 아예 변경할 수 없습니다.

  • ALTER VLABEL은 간선 레이블을 거부하고 ALTER ELABEL은 정점 레이블을 거부합니다.

대신 ALTER TABLE로 레이블의 모양을 바꾸는 것은 enable_graph_ddl을 켜 두지 않으면 거부됩니다. 그래프 카탈로그가 레이블의 컬럼을 설명하는데, ALTER TABLE은 그것을 갱신하지 않습니다. 그 관문에 대해서는 그래프가 어떻게 저장되는가가 다룹니다.

매개변수#

IF EXISTS

그 레이블이 없을 때 오류가 아니라 알림을 냅니다.

label_name

변경할 레이블이며, graph_path가 지정한 그래프 안에서 찾습니다.

RENAME TO new_label_name

레이블에 새 이름을 줍니다. 정점과 간선은 자기 id를 유지하므로, 이름을 바꾸기 전에 만든 행에 대해서도 label()이 새 이름을 보고합니다. 그 테이블의 시퀀스와 인덱스는 처음 받은 이름을 유지하므로, CLUSTER ON을 쓰기 전에 그것을 확인하십시오.

ADD [ COLUMN ] promoted_property

승격된 타입 컬럼을 추가하고 이미 있는 행에서 그것을 채웁니다. promoted_property는 CREATE VLABEL과 같은 세 형태를 받고 제한도 같습니다. 그 레이블에서 이미 승격된 속성은 거부되며, 한 문장에서 같은 키를 두 번 승격하는 것도 거부됩니다.

DROP [ COLUMN ] column_name [ CASCADE | RESTRICT ]

컬럼을 지우고, 승격된 속성이라면 그 대응 관계도 잊습니다. 레이블의 구조 컬럼은 거부됩니다. 지운 컬럼에 걸려 있던 인덱스도 함께 사라집니다.

DISABLE INDEX

그 레이블의 모든 인덱스를 무효로 표시해, 대량 적재가 그것을 유지하지 않게 합니다. 읽기와 쓰기는 계속 동작하고 플래너는 무효 인덱스를 무시합니다. ENABLE INDEX는 없습니다. 되돌아가는 길은 REINDEX VLABEL입니다.

SET STORAGE { PLAIN | EXTERNAL | EXTENDED | MAIN }

레이블의 properties 컬럼의 저장 방식을 정합니다. 이 방식이 큰 속성 맵을 인라인으로 둘지 그 테이블의 TOAST 관계에 둘지, 그리고 압축할지를 결정합니다. 레이블은 EXTENDED로 시작하며, 그것은 인라인이 아니면서 압축하는 방식입니다. 이 문장은 이후 쓰기에 대한 전략을 바꿀 뿐, 이미 저장된 것을 다시 쓰지는 않습니다.

SET TABLESPACE tablespace_name

레이블의 테이블을 다른 테이블스페이스로 옮깁니다. 그 인덱스는 있던 자리에 남습니다.

SET { LOGGED | UNLOGGED }

레이블 테이블의 미리 쓰기 로깅을 켜거나 끕니다. 그 레이블의 id 시퀀스도 함께 영속성이 바뀝니다.

CLUSTER ON index_name

나중의 CLUSTER가 쓸 인덱스로 어떤 인덱스를 기록해 둡니다. 지금 무언가를 재배열하지는 않습니다.

SET WITHOUT CLUSTER

그 기록을 잊습니다.

INHERIT parent_label

그 레이블을 같은 그래프의 같은 종류 레이블의 자식으로 붙여, 부모에 대한 패턴이 이 레이블의 행에도 일치하기 시작하게 합니다.

NO INHERIT parent_label

그 관계를 제거합니다.

REPLICA IDENTITY { DEFAULT | USING INDEX index_name | FULL | NOTHING }

논리 복제를 위해, 쓰기가 행을 식별하려고 WAL에 기록하는 이전 값을 무엇으로 할지 고릅니다.

OWNER TO role_specification

그 레이블을 다른 롤에게 넘깁니다. 롤 이름, CURRENT_ROLE, CURRENT_USER, SESSION_USER 중 하나를 씁니다.

예제#

예제는 예제 데이터셋을 쓰지 않고 자체 그래프인 catalogue를 만들고, 끝에서 그것을 지웁니다.

CREATE GRAPH catalogue;
SET graph_path = catalogue;
CREATE VLABEL film;
CREATE (:film {title: 'Arrival', year: 2016}), (:film {title: 'Dune', year: 2021});

레이블 이름 바꾸기#

ALTER VLABEL film RENAME TO movie;
\dGl catalogue.mov*
           List of labels
   Graph   | Name  |  Type  | Owner
-----------+-------+--------+-------
 catalogue | movie | vertex | agens
(1 row)

행도 함께 따라왔습니다:

MATCH (m:movie) RETURN count(m) AS movies;
 movies 
--------
 2
(1 row)

시퀀스와 기본 키는 여전히 옛 이름을 지니고 있습니다:

\d catalogue.movie
                                                          Table "catalogue.movie"
   Column   |  Type   | Collation | Nullable |                                           Default                                            
------------+---------+-----------+----------+----------------------------------------------------------------------------------------------
 id         | graphid |           | not null | graphid(graph_labid('catalogue.movie'::cstring), nextval('catalogue.film_id_seq'::regclass))
 properties | jsonb   |           | not null | jsonb_build_object()
Indexes:
    "film_pkey" PRIMARY KEY, btree (id)
Inherits: catalogue.ag_vertex

그래서 ALTER VLABEL movie CLUSTER ON movie_pkey는 index "movie_pkey" for table "movie" does not exist로 실패하고, 써야 할 이름은 film_pkey입니다.

대량 적재를 위해 레이블의 인덱스 끄기#

ALTER VLABEL movie DISABLE INDEX;
\d catalogue.movie
                                                          Table "catalogue.movie"
   Column   |  Type   | Collation | Nullable |                                           Default                                            
------------+---------+-----------+----------+----------------------------------------------------------------------------------------------
 id         | graphid |           | not null | graphid(graph_labid('catalogue.movie'::cstring), nextval('catalogue.film_id_seq'::regclass))
 properties | jsonb   |           | not null | jsonb_build_object()
Indexes:
    "film_pkey" PRIMARY KEY, btree (id) INVALID
Inherits: catalogue.ag_vertex

행을 적재하고, 그다음 인덱스를 다시 만듭니다:

REINDEX VLABEL movie;
REINDEX

행이 이미 있는 레이블에서 속성 승격하기#

ALTER VLABEL movie ADD COLUMN year int GENERATED;
\d catalogue.movie
                                                           Table "catalogue.movie"
   Column   |  Type   | Collation | Nullable |                                            Default                                            
------------+---------+-----------+----------+-----------------------------------------------------------------------------------------------
 id         | graphid |           | not null | graphid(graph_labid('catalogue.movie'::cstring), nextval('catalogue.film_id_seq'::regclass))
 properties | jsonb   |           | not null | jsonb_build_object()
 year       | integer |           |          | generated always as (ag_property_text(properties, 'year'::text, 'n'::"char")::integer) stored
Indexes:
    "film_pkey" PRIMARY KEY, btree (id)
Inherits: catalogue.ag_vertex

이미 있는 행이 채워지므로, 그 문장이 돌아오는 순간 컬럼은 이미 완전합니다:

SELECT year FROM catalogue.movie ORDER BY year;
 year 
------
 2016
 2021
(2 rows)

레이블이 무엇을 승격했는지 조회하기#

ag_label_property가 속성 키를 그것을 대신해 답하는 컬럼에 대응시킵니다:

ALTER VLABEL movie ADD COLUMN released text GENERATED (releaseDate);
SELECT p.propname, p.attnum FROM pg_catalog.ag_label_property p
  JOIN pg_catalog.ag_label l ON l.oid = p.laboid
  JOIN pg_catalog.ag_graph g ON g.oid = l.graphid
 WHERE g.graphname = 'catalogue' AND l.labname = 'movie' ORDER BY p.attnum;
  propname   | attnum 
-------------+--------
 year        |      3
 releasedate |      4
(2 rows)

attnum은 그 테이블에서 컬럼의 위치입니다. 컬럼 이름까지 원한다면 그것으로 pg_attribute와 조인하십시오. 키를 명시하는 형태를 썼다면 그 둘이 다릅니다.

승격된 컬럼 지우기#

ALTER VLABEL movie DROP COLUMN released;

그 대응 관계도 컬럼과 함께 사라집니다:

SELECT p.propname, p.attnum FROM pg_catalog.ag_label_property p
  JOIN pg_catalog.ag_label l ON l.oid = p.laboid
  JOIN pg_catalog.ag_graph g ON g.oid = l.graphid
 WHERE g.graphname = 'catalogue' AND l.labname = 'movie' ORDER BY p.attnum;
 propname | attnum 
----------+--------
 year     |      3
(1 row)

releasedate를 읽으면 properties로 돌아갑니다. properties에서 지워진 것은 없습니다.

속성 맵의 저장 방식 바꾸기#

ALTER VLABEL movie SET STORAGE external;

어느 컬럼을 예상했든, 그 방식은 properties에 설정됩니다:

SELECT attname, attstorage FROM pg_attribute
 WHERE attrelid = 'catalogue.movie'::regclass AND attnum > 0 AND NOT attisdropped;
  attname   | attstorage 
------------+------------
 id         | p
 properties | e
 year       | p
(3 rows)

부모 붙이고 떼기#

CREATE VLABEL work;
ALTER VLABEL movie INHERIT work;
\dGv catalogue.movie
           List of labels
   Graph   | Name  |  Type  | Owner
-----------+-------+--------+-------
 catalogue | movie | vertex | agens
(1 row)

Vertex label "catalogue.movie"
--
Inherits: catalogue.ag_vertex,
          catalogue.work

이제 movie에는 부모가 둘입니다. 처음부터 있던 기반 레이블과 work입니다. 떼어 내도 기반 레이블은 그대로입니다:

ALTER VLABEL movie NO INHERIT work;
ALTER VLABEL

알아 둘 만한 거부 사례#

구조 컬럼은 지울 수 없습니다:

ALTER VLABEL movie DROP COLUMN properties;
ERROR:  cannot drop column "properties" of graph label "movie"
HINT:  It is a structural column of the graph label.

추가하는 컬럼은 properties에서 생성되는 것이어야 합니다:

ALTER VLABEL movie ADD COLUMN rank int;
ERROR:  a non-generated promoted column is not supported yet
HINT:  Use GENERATED to mirror the property from the jsonb bag.

이미 승격된 속성을 두 번 승격할 수는 없습니다:

ALTER VLABEL movie ADD COLUMN yr2 int GENERATED (year);
ERROR:  property "year" is already promoted on graph label "movie"
HINT:  Drop the existing promoted column first, or promote the property to a different column name.

기반 레이블은 부모로든 대상으로든 손댈 수 없습니다:

ALTER VLABEL movie INHERIT ag_vertex;
ERROR:  cannot ALTER inheritance with base label
ALTER VLABEL ag_vertex SET STORAGE main;
ERROR:  ALTER base vertex label is prohibited

각 문장은 한 종류의 레이블에만 작용합니다:

CREATE ELABEL directed;
ALTER VLABEL directed RENAME TO helmed;
ERROR:  RENAME VLABEL cannot RENAME edge label

그리고 RENAME TO는 홀로 섭니다:

ALTER VLABEL movie RENAME TO film, SET STORAGE main;
ERROR:  syntax error at or near ","
LINE 1: ALTER VLABEL movie RENAME TO film, SET STORAGE main;
                                         ^

enable_graph_ddl이 꺼져 있는 동안에는 SQL로 레이블의 테이블 모양을 바꾸는 것이 거부됩니다:

ALTER TABLE catalogue.movie ADD COLUMN rank int;
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.

마지막으로 예제가 만든 그래프를 지웁니다:

DROP GRAPH catalogue CASCADE;

참고#

SET STORAGE는 다섯이 아니라 네 개의 키워드를 받습니다. DEFAULT는 예약어이고 여기서는 구문 오류입니다. 레이블이 처음 갖는 방식으로 돌아가려면 SET STORAGE extended로 쓰십시오. 알 수 없는 단어는 invalid storage type "..."으로 보고됩니다.

IF EXISTS 알림은 두 형태에서 다릅니다. RENAME TO는 label "nosuch" does not exist, skipping을, 동작 목록은 graph label "nosuch" does not exist, skipping을 냅니다. 그다음 둘 다 성공을 보고하고 아무것도 하지 않습니다.

호환성#

ISO/IEC 39075 (GQL)#

GQL에는 레이블을 변경하는 문장이 없습니다. 변경할 레이블이 없기 때문입니다. 요소 타입은 그래프 타입에 속하고, 그래프 타입은 통째로 만들어지고 지워집니다(<create graph type statement>, §12.6). 레이블 이름 바꾸기, 속성 승격, 인덱스 끄기에 대응하는 것이 GQL에는 없습니다. 그래프 타입은 GQL 적합성 표에 계획으로 기록돼 있습니다.

PostgreSQL#

여기 있는 모든 동작은 ALTER TABLE의 동작이고, 각각 거기서와 같은 뜻이며 두 가지만 조정됐습니다. SET STORAGE는 컬럼을 지정하지 않습니다. 저장 방식을 고를 만한 컬럼은 properties 하나뿐이므로 그 컬럼에 적용됩니다. DISABLE INDEX에는 ALTER TABLE 대응물이 아예 없습니다. 그것은 레이블의 인덱스를 무효로 표시하는데, SQL에서는 CREATE INDEX CONCURRENTLY를 중단시키는 것 말고는 그렇게 만들 방법이 없습니다.

반대 방향으로는, 레이블의 테이블에 대한 ALTER TABLE이 그 모양을 바꾸는 동작에 대해서는 enable_graph_ddl을 켜 두지 않으면 거부됩니다. 컬럼을 추가하거나 지우거나 타입을 바꾸는 것이 그런 동작입니다. 위의 예제가 그 거부를 보여 줍니다. 이 페이지의 동작들은 그 설정을 결코 필요로 하지 않습니다. 그래프 카탈로그를 스스로 갱신하기 때문입니다.

관련 항목#