02_api — SQL 함수 계약 색인
이 문서가 답하는 질문
- 이 데이터베이스의 "API"는 정확히 무엇인가?
- 공개 SQL 함수는 총 몇 개이고, 각각 어디에 정의되어 있는가?
- 어떤 함수가
STABLE이고 어떤 함수가 VOLATILE인가? 병렬 실행이 가능한가?
- 함수 이름만 알 때, 어느 문서를 봐야 하는가?
1. 사실 — 이 프로젝트의 1차 계약면
Ontological의 API는 REST가 아니라 PostgreSQL 함수 시그니처다. 확장을 설치하면(CREATE EXTENSION ontological CASCADE) 세 종류의 객체가 public 스키마에 생성된다.
부가 표면(1차 계약면 위에 얹힌 얇은 층)은 두 개뿐이다.
결정(Decision): 모든 기능은 평문 SQL에서 도달 가능해야 한다. Studio와 Bolt는 이 표면 위의 편의 계층이지 특권 경로가 아니다 (docs/api.md:3, bolt/src/main.rs:3).
2. 휘발성 / 병렬 안전성 표기 규칙
pgrx #[pg_extern(...)] 속성이 그대로 CREATE FUNCTION 절이 된다.
immutable |
IMMUTABLE |
stable |
STABLE |
volatile |
VOLATILE |
parallel_safe |
PARALLEL SAFE |
parallel_restricted |
PARALLEL RESTRICTED |
parallel_unsafe |
PARALLEL UNSAFE |
strict |
STRICT |
필수(Required) 해석 규칙: 속성이 없으면 PostgreSQL CREATE FUNCTION의 기본값이 적용된다 — 즉 VOLATILE, PARALLEL UNSAFE. 아래 표에서 "기본값"이라고 적힌 칸은 이 의미다.
금지(Forbidden): 아래 표에 없는 휘발성 값을 추정해서 쓰지 말 것. STRICT 여부는 소스에 strict가 명시된 함수만 확인되었다. 그 외 함수의 STRICT 여부는 pgrx의 자동 추론에 달려 있어 소스만으로는 미확인이다.
3. Rust 타입 → SQL 타입 대응 (코드에서 확인)
&str, &'static str |
text |
i32 / Option<i32> |
int4 |
i64 |
int8 |
i8 |
"char" — engine/sql/access.sql:197의 ALTER FUNCTION og_reach(int8, int4[], "char", int4, int4)로 확정 |
f32 / f64 |
float4 / float8 |
bool |
bool |
JsonB |
jsonb |
Option<Vec<i32>>, Vec<i32> |
int4[] |
Vec<Option<String>>, Vec<String> |
text[] |
Vec<f64> |
float8[] |
pgrx::datum::TimestampWithTimeZone |
timestamptz |
TableIterator<'static, (name!(a, T), …)> |
TABLE(a T, …) |
SetOfIterator<'static, JsonB> |
SETOF jsonb |
반환 없음 () |
void |
4. 전체 함수 색인 (78 × Rust + 13 × SQL + 7 뷰)
정렬은 카테고리 → 이름. "휘발성"·"병렬" 칸은 §2 규칙으로 읽는다.
og_create_graph |
(name text) RETURNS int4 |
기본값 |
기본값 |
engine/src/catalog/types.rs:300 |
og_drop_graph |
(name text) RETURNS void |
기본값 |
기본값 |
engine/src/catalog/types.rs:321 |
og_create_type |
(graph text, name text, kind text, parents text[] DEFAULT '{}', is_abstract bool DEFAULT false) RETURNS int4 |
기본값 |
기본값 |
engine/src/catalog/types.rs:348 |
og_drop_type |
(graph text, name text, cascade bool DEFAULT false) RETURNS void |
기본값 |
기본값 |
engine/src/catalog/types.rs:685 |
og_add_property |
(graph text, type_name text, prop text, data_type text, required bool DEFAULT false, is_key bool DEFAULT false) RETURNS void |
기본값 |
기본값 |
engine/src/catalog/types.rs:510 |
og_create_index |
(graph text, type_name text, prop text) RETURNS void |
기본값 |
기본값 |
engine/src/catalog/types.rs:603 |
og_add_role |
(graph text, rel_type text, role text, player_type text, ordinal int4, card_min int4 DEFAULT 0, card_max int4 DEFAULT NULL) RETURNS void |
기본값 |
기본값 |
engine/src/catalog/types.rs:625 |
og_add_rule |
(graph text, rel_type text, characteristic text, target_type text DEFAULT NULL) RETURNS void |
기본값 |
기본값 |
engine/src/catalog/types.rs:657 |
og_subtypes |
(type_id int4) RETURNS int4[] |
STABLE |
PARALLEL SAFE STRICT |
engine/src/catalog/labeling.rs:192 |
og_supertypes |
(type_id int4) RETURNS int4[] |
STABLE |
PARALLEL SAFE STRICT |
engine/src/catalog/labeling.rs:212 |
og_is_subtype |
(sub int4, sup int4) RETURNS bool |
STABLE |
PARALLEL SAFE STRICT |
engine/src/catalog/labeling.rs:232 |
og_relabel |
(graph_id int4) RETURNS void |
기본값 |
STRICT |
engine/src/catalog/labeling.rs:247 |
og_create_node |
(graph text, type_name text, props jsonb DEFAULT '{}') RETURNS int8 |
기본값 |
기본값 |
engine/src/storage/mod.rs:246 |
og_create_edge |
(graph text, rel_type text, src int8, dst int8, props jsonb DEFAULT '{}') RETURNS int8 |
기본값 |
기본값 |
engine/src/storage/mod.rs:389 |
og_set_node_props |
(id int8, props jsonb) RETURNS void |
기본값 |
기본값 |
engine/src/storage/mod.rs:293 |
og_delete_node |
(id int8) RETURNS int8 |
기본값 |
기본값 |
engine/src/storage/mod.rs:350 |
og_delete_edge |
(id int8) RETURNS int8 |
기본값 |
기본값 |
engine/src/storage/mod.rs:496 |
og_add_role_player |
(graph text, rel_type text, edge_id int8, role text, player int8) RETURNS void |
기본값 |
기본값 |
engine/src/storage/mod.rs:531 |
og_make_id |
(shard int4, type_id int4, local int8) RETURNS int8 |
IMMUTABLE |
PARALLEL SAFE STRICT |
engine/src/id.rs:88 |
og_id_type |
(id int8) RETURNS int4 |
IMMUTABLE |
PARALLEL SAFE STRICT |
engine/src/id.rs:73 |
og_id_shard |
(id int8) RETURNS int4 |
IMMUTABLE |
PARALLEL SAFE STRICT |
engine/src/id.rs:78 |
og_id_local |
(id int8) RETURNS int8 |
IMMUTABLE |
PARALLEL SAFE STRICT |
engine/src/id.rs:83 |
og_reach |
(src int8, etypes int4[], dir "char", minhop int4, maxhop int4) RETURNS TABLE(node int8, depth int4) |
STABLE |
PARALLEL RESTRICTED |
engine/src/storage/traverse.rs:80 |
og_csr_build |
(etypes int4[], dir text DEFAULT 'o') RETURNS TABLE(nodes int8, edges int8, bytes int8, build_ms float8) |
기본값 |
기본값 |
engine/src/storage/traverse.rs:295 |
og_csr_reach |
(src int8, minhop int4, maxhop int4) RETURNS TABLE(node int8, depth int4) |
STABLE |
PARALLEL RESTRICTED |
engine/src/storage/traverse.rs:359 |
og_csr_hops |
(src int8, dst int8, maxhop int4 DEFAULT 32) RETURNS int4 |
STABLE |
PARALLEL RESTRICTED |
engine/src/storage/traverse.rs:442 |
og_csr_stats |
() RETURNS TABLE(built_for text, nodes int8, edges int8, bytes int8) |
기본값 |
기본값 |
engine/src/storage/traverse.rs:322 |
og_csr_drop |
() RETURNS void |
기본값 |
기본값 |
engine/src/storage/traverse.rs:316 |
og_degree |
(src int8, etype int4, dir text) RETURNS int8 |
STABLE |
PARALLEL SAFE STRICT |
engine/src/storage/adjacency.rs:76 |
og_degree_all |
(src int8, dir text) RETURNS int8 |
STABLE |
PARALLEL SAFE STRICT |
engine/src/storage/adjacency.rs:88 |
og_graph_stats |
(graph text) RETURNS jsonb |
STABLE |
STRICT |
engine/src/storage/stats.rs:11 |
og_degree_distribution |
(graph text) RETURNS jsonb |
STABLE |
STRICT |
engine/src/storage/stats.rs:86 |
og_reorganize |
(graph text) RETURNS int8 |
기본값 |
기본값 |
engine/src/storage/stats.rs:121 |
og_check_integrity |
() RETURNS TABLE(kind text, entity_id int8, detail text) |
STABLE |
기본값 |
engine/src/storage/stats.rs:172 |
og_add_embedding |
(graph text, type_name text, prop text, dims int4, metric text DEFAULT 'cosine', source_prop text DEFAULT NULL) RETURNS void |
기본값 |
기본값 |
engine/src/vector/mod.rs:32 |
og_vector_search |
(graph text, type_name text, prop text, query text, k int4 DEFAULT 10, filter text DEFAULT NULL) RETURNS TABLE(id int8, score float8, entity jsonb) |
기본값 |
기본값 |
engine/src/vector/mod.rs:94 |
og_vector_search_exact |
(graph text, type_name text, prop text, query text, k int4 DEFAULT 10) RETURNS TABLE(id int8, score float8) |
기본값 |
기본값 |
engine/src/vector/mod.rs:411 |
og_similar |
(graph text, id int8, prop text, k int4 DEFAULT 10) RETURNS TABLE(id int8, score float8, entity jsonb) |
기본값 |
기본값 |
engine/src/vector/mod.rs:158 |
og_hybrid_search |
(graph text, type_name text, prop text, query text, anchor int8 DEFAULT NULL, k int4 DEFAULT 10, vector_weight float8 DEFAULT 1.0, graph_weight float8 DEFAULT 1.0) RETURNS TABLE(id int8, score float8, vector_score float8, graph_score float8, entity jsonb) |
기본값 |
기본값 |
engine/src/vector/mod.rs:222 |
og_stale_embeddings |
(graph text) RETURNS TABLE(entity_id int8, type_name text, prop text) |
STABLE |
기본값 |
engine/src/vector/mod.rs:299 |
og_mark_embedded |
(entity_id int8, prop text) RETURNS void |
기본값 |
기본값 |
engine/src/vector/mod.rs:358 |
og_embedding_stats |
(graph text) RETURNS jsonb |
STABLE |
STRICT |
engine/src/vector/mod.rs:383 |
og_schema |
(graph text, token_budget int4 DEFAULT NULL) RETURNS jsonb |
STABLE |
기본값 |
engine/src/agent/mod.rs:21 |
og_schema_for |
(graph text, question text) RETURNS jsonb |
STABLE |
기본값 |
engine/src/agent/mod.rs:189 |
og_explain_error |
(graph text, query text) RETURNS jsonb |
STABLE |
기본값 |
engine/src/agent/mod.rs:261 |
og_diagnose_empty |
(graph text, query text) RETURNS jsonb |
기본값 |
기본값 |
engine/src/agent/mod.rs:339 |
og_estimate |
(graph text, query text) RETURNS jsonb |
기본값 |
기본값 |
engine/src/agent/mod.rs:350 |
og_create_role |
(name text, limits jsonb) RETURNS void |
기본값 |
기본값 |
engine/src/agent/mod.rs:404 |
og_apply_role |
(name text) RETURNS jsonb |
기본값 |
기본값 |
engine/src/agent/mod.rs:415 |
og_enable_history |
(graph text, type_name text) RETURNS void |
기본값 |
기본값 |
engine/src/agent/mod.rs:448 |
og_history |
(id int8) RETURNS TABLE(recorded_at timestamptz, op text, payload jsonb) |
STABLE |
기본값 |
engine/src/agent/mod.rs:471 |
og_as_of |
(id int8, at timestamptz) RETURNS jsonb |
STABLE |
기본값 |
engine/src/agent/mod.rs:502 |
og_set_source |
(entity_id int8, source text, confidence float4 DEFAULT NULL, author text DEFAULT NULL) RETURNS void |
기본값 |
기본값 |
engine/src/agent/mod.rs:529 |
og_set_setting |
(key text, value text) RETURNS void |
기본값 |
기본값 |
engine/src/compat/genai.rs:55 |
ontological_version |
() RETURNS text |
IMMUTABLE |
PARALLEL SAFE |
engine/src/lib.rs:40 |
og_enable_rls |
(graph text, type_name text, policy_expr text) RETURNS void |
기본값 |
기본값 |
engine/src/interop/mod.rs:18 |
og_map_table |
(graph text, source_table text, type_name text, id_column text, property_map jsonb) RETURNS void |
기본값 |
기본값 |
engine/src/interop/mod.rs:60 |
og_materialize_mapping |
(graph text, type_name text) RETURNS int8 |
기본값 |
기본값 |
engine/src/interop/mod.rs:120 |
og_interop_report |
(graph text) RETURNS jsonb |
STABLE |
기본값 |
engine/src/interop/mod.rs:171 |
og_load_rdf |
(graph text, document text, format text DEFAULT 'turtle') RETURNS jsonb |
기본값 |
기본값 |
engine/src/adapters/mod.rs:40 |
og_dump_rdf |
(graph text, format text DEFAULT 'turtle') RETURNS text |
STABLE |
기본값 |
engine/src/adapters/mod.rs:47 |
og_mapping_report |
(graph text) RETURNS jsonb |
STABLE |
기본값 |
engine/src/adapters/mod.rs:53 |
og_add_prefix |
(prefix text, iri text) RETURNS void |
기본값 |
기본값 |
engine/src/adapters/mod.rs:17 |
og_set_iri |
(graph text, type_name text, iri text) RETURNS void |
기본값 |
기본값 |
engine/src/adapters/mod.rs:28 |
CREATE INDEX / CREATE CONSTRAINT 계열은 SQL 함수가 아니라 Cypher DDL 문으로 진입한다 — engine/src/compat/ddl.rs:18. db.* / apoc.* 프로시저는 CALL ... YIELD로만 진입한다 — engine/src/compat/procs.rs:80.
og_expand |
(src int8, etypes int4[], dir "char") RETURNS TABLE(nbr int8, eid int8) |
sql STABLE PARALLEL SAFE ROWS 50 |
engine/sql/access.sql:14 |
og_expand_batch |
(srcs int8[], etypes int4[], dir "char") RETURNS TABLE(src int8, nbr int8, eid int8) |
sql STABLE PARALLEL SAFE ROWS 500 |
engine/sql/access.sql:29 |
og_subtype_ids |
(root int4) RETURNS TABLE(type_id int4) |
sql STABLE PARALLEL SAFE ROWS 8 |
engine/sql/access.sql:43 |
og_nodes |
(root int4) RETURNS TABLE(id int8, type_id int4) |
sql STABLE PARALLEL SAFE ROWS 1000 |
engine/sql/access.sql:53 |
og_edges |
(root int4) RETURNS TABLE(id int8, type_id int4, src int8, dst int8) |
sql STABLE PARALLEL SAFE ROWS 1000 |
engine/sql/access.sql:60 |
og_type_id |
(graph text, type_name text) RETURNS int4 |
sql STABLE PARALLEL SAFE |
engine/sql/access.sql:70 |
og_type_name |
(type_id int4) RETURNS text |
sql STABLE PARALLEL SAFE |
engine/sql/access.sql:203 |
og_vlp |
(src int8, etypes int4[], dir "char", minhop int, maxhop int) RETURNS TABLE(node int8, depth int, path int8[]) |
sql STABLE PARALLEL SAFE ROWS 100 |
engine/sql/access.sql:138 |
og_reach_sql |
(src int8, etypes int4[], dir "char", minhop int, maxhop int) RETURNS TABLE(node int8, depth int) |
sql STABLE PARALLEL SAFE ROWS 1000 |
engine/sql/access.sql:169 |
og_node_json |
(id int8) RETURNS jsonb |
plpgsql STABLE |
engine/sql/access.sql:208 |
og_edge_json |
(id int8) RETURNS jsonb |
plpgsql STABLE |
engine/sql/access.sql:237 |
og_prop |
(id int8, prop text) RETURNS text |
sql STABLE |
engine/sql/access.sql:267 |
og_capture_history |
() RETURNS trigger |
plpgsql |
engine/sql/access.sql:274 |
og_type_view |
graph, type_id, name, kind, is_abstract, storage_table, iri, depth, lft, rgt, parents |
engine/sql/access.sql:81 |
og_property_view |
graph, type_name, property, data_type, column_name, required, is_key |
engine/sql/access.sql:99 |
og_role_view |
graph, relation, role, player_type, ordinal, card_min, card_max |
engine/sql/access.sql:106 |
og_node_view |
id, type_name, graph |
engine/sql/access.sql:116 |
og_edge_view |
id, type_name, graph, src, dst |
engine/sql/access.sql:122 |
og_typeql_attribute |
owner_id, owner_type, attribute_type, value, attribute_id |
engine/sql/access.sql:307 |
og_typeql_role |
relation_id, relation_type, role, player_id, player_type |
engine/sql/access.sql:324 |
5. 실행 중인 데이터베이스에서 직접 확인하기
문서가 코드보다 뒤처졌을 가능성이 늘 있으므로, 정답은 항상 서버다.
-- Every public og_* function, exactly as installed.
SELECT p.proname || '(' || pg_get_function_arguments(p.oid) || ') -> '
|| pg_get_function_result(p.oid) AS signature,
p.provolatile, -- i = immutable, s = stable, v = volatile
p.proparallel, -- s = safe, r = restricted, u = unsafe
p.proisstrict
FROM pg_proc p JOIN pg_namespace n ON n.oid = p.pronamespace
WHERE n.nspname = 'public' AND p.proname LIKE 'og\_%'
ORDER BY 1;
SELECT ontological_version();
6. 금지 / 필수
- 금지: 이 색인에 없는
og_* 함수를 존재한다고 가정하고 호출 코드를 작성하지 말 것. 본 색인은 #[pg_extern] 속성 전수 조사 결과다.
- 금지:
og_catalog.* / og_data.* 테이블에 직접 INSERT / UPDATE하지 말 것. 쓰기 경로는 레지스트리·타입 테이블·양방향 인접 세그먼트를 한 트랜잭션에서 함께 갱신한다(engine/src/storage/mod.rs:1 모듈 주석, spec 001 FR-012). 직접 쓰면 og_check_integrity()가 잡아내는 불일치가 생긴다.
- 필수: 사용자 입력은 반드시
params jsonb 인자로 전달할 것. Cypher/TypeQL 질의 텍스트에 값을 문자열 연결하지 말 것(spec 003 FR-026).
- 필수:
og_vector_search(filter), og_enable_rls(policy_expr), og_map_table(source_table)는 SQL 조각을 그대로 받는다. 이 세 인자에는 신뢰할 수 없는 입력을 절대 넣지 말 것 — 12_improvements_api.md API-05 참조.
7. 관련 문서