Skip to content

Commit fe35cf9

Browse files
committed
Support Labels for vertices in CREATE clause
1 parent 391f621 commit fe35cf9

3 files changed

Lines changed: 42 additions & 7 deletions

File tree

regress/sql/cypher_create.sql

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,18 @@ MATCH () RETURN 1;
3232
CREATE VLABEL test;
3333
SELECT * FROM postgraph.ag_label;
3434

35+
CREATE (:test);
36+
SELECT * FROM postgraph.ag_label;
37+
SELECT * FROM cypher_create.test;
38+
39+
40+
CREATE (:test2);
41+
SELECT * FROM postgraph.ag_label;
42+
SELECT * FROM cypher_create.test2;
43+
44+
45+
MATCH () RETURN 1;
46+
3547
CREATE ()-[]->();
3648

3749
CYPHER WITH 1 as a

src/backend/executor/cypher_create.c

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -165,9 +165,8 @@ static void begin_cypher_create(CustomScanState *node, EState *estate, int eflag
165165
ereport(ERROR, (errmsg_internal("executor create found a traversal")));
166166

167167
cypher_target_node *cypher_node = (cypher_target_node *)linitial(path->target_nodes);
168-
label_cache_data *lcd = search_label_name_graph_cache(AG_DEFAULT_LABEL_VERTEX, css->graph_oid);
169-
170-
Relation rel = table_open(lcd->relation, RowExclusiveLock);
168+
169+
Relation rel = table_open(cypher_node->relid, RowExclusiveLock);
171170
cypher_node->resultRelInfo = makeNode(ResultRelInfo);
172171
InitResultRelInfo(cypher_node->resultRelInfo, rel, list_length(estate->es_range_table), NULL, estate->es_instrument);
173172

src/backend/parser/cypher_clause.c

Lines changed: 28 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -253,6 +253,27 @@ static Expr *add_volatile_wrapper(Expr *node) {
253253

254254
return (Expr *)makeFuncExpr(oid, GTYPEOID, list_make1(node), InvalidOid, InvalidOid, COERCE_EXPLICIT_CALL);
255255
}
256+
257+
static void validate_or_create_vlabel(cypher_parsestate *cpstate, cypher_node *node) {
258+
ParseState *pstate = (ParseState *)cpstate;
259+
label_cache_data *lcd = search_label_name_graph_cache(node->label, cpstate->graph_oid);
260+
261+
if (lcd && lcd->kind != LABEL_KIND_VERTEX) {
262+
ereport(ERROR, (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
263+
errmsg("label %s is for edges, not vertices", node->label),
264+
parser_errposition(pstate, node->location)));
265+
} else if (!lcd) {
266+
List *parent;
267+
RangeVar *rv;
268+
269+
rv = get_label_range_var(cpstate->graph_name, cpstate->graph_oid, AG_DEFAULT_LABEL_VERTEX);
270+
271+
parent = list_make1(rv);
272+
273+
create_label(cpstate->graph_name, node->label, LABEL_TYPE_VERTEX, parent, NULL);
274+
}
275+
}
276+
256277
static Query *transform_cypher_create(cypher_parsestate *cpstate, cypher_clause *clause) {
257278
ParseState *pstate = (ParseState *)cpstate;
258279
cypher_create *self = (cypher_create *)clause->self;
@@ -291,8 +312,10 @@ static Query *transform_cypher_create(cypher_parsestate *cpstate, cypher_clause
291312

292313
cypher_node *node = (cypher_node *)linitial(path->path);
293314

294-
if (node->label)
295-
ereport(ERROR, (errmsg_internal("nodes in CREATE cannot have labels")));
315+
if (node->label)
316+
validate_or_create_vlabel(cpstate, node);
317+
else
318+
node->label = AG_DEFAULT_LABEL_VERTEX;
296319

297320
if (node->name)
298321
ereport(ERROR, (errmsg_internal("nodes in CREATE cannot have variable names")));
@@ -302,10 +325,11 @@ static Query *transform_cypher_create(cypher_parsestate *cpstate, cypher_clause
302325

303326
cypher_target_node *target = make_ag_node(cypher_target_node);
304327

305-
label_cache_data *lcd = search_label_name_graph_cache(AG_DEFAULT_LABEL_VERTEX, cpstate->graph_oid);
328+
label_cache_data *lcd = search_label_name_graph_cache(node->label, cpstate->graph_oid);
306329

307330
target->id_expr = (Expr *)build_column_default(RelationIdGetRelation(lcd->relation), 1);
308-
331+
target->relid = lcd->relation;
332+
309333
TargetEntry *te = makeTargetEntry(make_int_placeholder(cpstate), pstate->p_next_resno++, make_id_alias(get_next_default_alias(cpstate)), false);
310334

311335
ccp->target_nodes = list_make1(target);

0 commit comments

Comments
 (0)