Skip to content

Commit 391f621

Browse files
committed
Support CREATE VLABEL Command with no hierarchy
1 parent 8ca54ec commit 391f621

15 files changed

Lines changed: 137 additions & 62 deletions

postgraph--0.1.0.sql

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -138,8 +138,9 @@ RETURNS void
138138
LANGUAGE c
139139
AS 'MODULE_PATHNAME';
140140

141-
CREATE FUNCTION create_vlabel(graph_name name, label_name name)
141+
CREATE FUNCTION create_vlabel(graph_name text, label_name text)
142142
RETURNS void
143+
RETURNS NULL ON NULL INPUT
143144
LANGUAGE c
144145
AS 'MODULE_PATHNAME';
145146

regress/expected/cypher_create.out

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,25 @@ MATCH () RETURN 1;
4848
1
4949
(1 row)
5050

51+
CREATE VLABEL test;
52+
NOTICE: VLabel "test" has been created
53+
create_vlabel
54+
---------------
55+
56+
(1 row)
57+
58+
SELECT * FROM postgraph.ag_label;
59+
name | graph | id | kind | relation | vertex_adjlist | label_path
60+
------------------+-------+----+------+--------------------------------+-------------------------------------+-----------------------
61+
_ag_label_vertex | 18780 | 1 | v | 18783 | 18792 | _ag_label_vertex
62+
_ag_label_edge | 18780 | 2 | e | 18796 | | _ag_label_edge
63+
_ag_label_vertex | 18805 | 1 | v | 18808 | 18817 | _ag_label_vertex
64+
_ag_label_edge | 18805 | 2 | e | 18821 | | _ag_label_edge
65+
_ag_label_vertex | 18833 | 1 | v | cypher_create._ag_label_vertex | cypher_create._adj__ag_label_vertex | _ag_label_vertex
66+
_ag_label_edge | 18833 | 2 | e | cypher_create._ag_label_edge | | _ag_label_edge
67+
test | 18833 | 3 | v | cypher_create.test | cypher_create._adj_test | _ag_label_vertex.test
68+
(7 rows)
69+
5170
CREATE ()-[]->();
5271
ERROR: CREATE doesn't work with paths
5372
CYPHER WITH 1 as a
@@ -59,10 +78,12 @@ ERROR: CREATE doesn't work with next clauses
5978
-- Clean up
6079
--
6180
DROP GRAPH cypher_create CASCADE;
62-
NOTICE: drop cascades to 3 other objects
81+
NOTICE: drop cascades to 5 other objects
6382
DETAIL: drop cascades to table cypher_create._ag_label_vertex
6483
drop cascades to table cypher_create._adj__ag_label_vertex
6584
drop cascades to table cypher_create._ag_label_edge
85+
drop cascades to table cypher_create.test
86+
drop cascades to table cypher_create._adj_test
6687
NOTICE: graph "cypher_create" has been dropped
6788
drop_graph
6889
------------

regress/sql/cypher_create.sql

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,9 @@ SELECT * FROM cypher_create._ag_label_vertex;
2929

3030
MATCH () RETURN 1;
3131

32+
CREATE VLABEL test;
33+
SELECT * FROM postgraph.ag_label;
34+
3235
CREATE ()-[]->();
3336

3437
CYPHER WITH 1 as a

src/backend/commands/label_commands.c

Lines changed: 13 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -97,81 +97,45 @@ static char *make_vertex_adjlist_alias(char *var_name);
9797

9898

9999
PG_FUNCTION_INFO_V1(create_vlabel);
100-
101-
/*
102-
* This is a callback function
103-
* This function will be called when the user will call SELECT create_vlabel.
104-
* The function takes two parameters
105-
* 1. Graph name
106-
* 2. Label Name
107-
* Function will create a vertex label
108-
* Function returns an error if graph or label names or not provided
109-
*/
110-
111100
Datum create_vlabel(PG_FUNCTION_ARGS)
112101
{
113102
char *graph;
114-
Name graph_name;
103+
text * graph_name;
115104
char *graph_name_str;
116105
Oid graph_oid;
117106
List *parent;
118107

119108
RangeVar *rv;
120109

121110
char *label;
122-
Name label_name;
111+
text * label_name;
123112
char *label_name_str;
124113

125-
// checking if user has not provided the graph name
126-
if (PG_ARGISNULL(0))
127-
{
128-
ereport(ERROR, (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
129-
errmsg("graph name must not be NULL")));
130-
}
131-
132-
// checking if user has not provided the label name
133-
if (PG_ARGISNULL(1))
134-
{
135-
ereport(ERROR, (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
136-
errmsg("label name must not be NULL")));
137-
}
138-
139-
graph_name = PG_GETARG_NAME(0);
140-
label_name = PG_GETARG_NAME(1);
114+
graph_name = PG_GETARG_TEXT_PP(0);
115+
label_name = PG_GETARG_TEXT_PP(1);
141116

142-
graph_name_str = NameStr(*graph_name);
143-
label_name_str = NameStr(*label_name);
117+
graph_name_str = text_to_cstring(graph_name);
118+
label_name_str = text_to_cstring(label_name);
144119

145120
// Check if graph does not exist
146121
if (!graph_exists(graph_name_str))
147-
{
148-
ereport(ERROR,
149-
(errcode(ERRCODE_UNDEFINED_SCHEMA),
150-
errmsg("graph \"%s\" does not exist.", graph_name_str)));
151-
}
122+
ereport(ERROR, (errcode(ERRCODE_UNDEFINED_SCHEMA),
123+
errmsg("graph \"%s\" does not exist.", graph_name_str)));
152124

153125
graph_oid = get_graph_oid(graph_name_str);
154126

155127
// Check if label with the input name already exists
156128
if (label_exists(label_name_str, graph_oid))
157-
{
158-
ereport(ERROR,
159-
(errcode(ERRCODE_UNDEFINED_SCHEMA),
160-
errmsg("label \"%s\" already exists", label_name_str)));
161-
}
162-
163-
//Create the default label tables
164-
graph = graph_name->data;
165-
label = label_name->data;
129+
ereport(ERROR, (errcode(ERRCODE_UNDEFINED_SCHEMA),
130+
errmsg("label \"%s\" already exists", label_name_str)));
166131

167-
rv = get_label_range_var(graph, graph_oid, AG_DEFAULT_LABEL_VERTEX);
132+
rv = get_label_range_var(graph_name_str, graph_oid, AG_DEFAULT_LABEL_VERTEX);
168133

169134
parent = list_make1(rv);
170135

171-
create_label(graph, label, LABEL_TYPE_VERTEX, parent, NULL);
136+
create_label(graph_name_str, label_name_str, LABEL_TYPE_VERTEX, parent, NULL);
172137

173-
ereport(NOTICE,
174-
(errmsg("VLabel \"%s\" has been created", NameStr(*label_name))));
138+
ereport(NOTICE, (errmsg("VLabel \"%s\" has been created", label_name_str)));
175139

176140
PG_RETURN_VOID();
177141
}

src/backend/nodes/ag_nodes.c

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,8 @@ const char *node_names[] = {
6767
"cypher_create_graph",
6868
"cypher_use_graph",
6969
"cypher_drop_graph",
70-
"cypher_label_tree_node"
70+
"cypher_label_tree_node",
71+
"cypher_create_vlabel"
7172
};
7273

7374
/*
@@ -137,7 +138,8 @@ const ExtensibleNodeMethods node_methods[] = {
137138
DEFINE_NODE_METHODS(cypher_create_graph),
138139
DEFINE_NODE_METHODS(cypher_use_graph),
139140
DEFINE_NODE_METHODS(cypher_drop_graph),
140-
DEFINE_NODE_METHODS(cypher_label_tree_node)
141+
DEFINE_NODE_METHODS(cypher_label_tree_node),
142+
DEFINE_NODE_METHODS(cypher_create_vlabel)
141143
};
142144

143145
static bool equal_ag_node(const ExtensibleNode *a, const ExtensibleNode *b)

src/backend/nodes/cypher_outfuncs.c

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -468,6 +468,14 @@ void out_cypher_drop_graph(StringInfo str, const ExtensibleNode *node)
468468
WRITE_BOOL_FIELD(cascade);
469469
}
470470

471+
void out_cypher_create_vlabel(StringInfo str, const ExtensibleNode *node)
472+
{
473+
DEFINE_AG_NODE(cypher_create_vlabel);
474+
475+
WRITE_STRING_FIELD(label_name);
476+
}
477+
478+
471479
/*
472480
* Copied from Postgres
473481
*

src/backend/nodes/cypher_readfuncs.c

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -322,4 +322,12 @@ void read_cypher_drop_graph(struct ExtensibleNode *node)
322322

323323
READ_STRING_FIELD(graph_name);
324324
READ_BOOL_FIELD(cascade);
325+
}
326+
327+
328+
void read_cypher_create_vlabel(struct ExtensibleNode *node)
329+
{
330+
READ_LOCALS(cypher_create_vlabel);
331+
332+
READ_STRING_FIELD(label_name);
325333
}

src/backend/parser/cypher_analyze.c

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,9 @@ static FuncExpr *make_clause_create_graph_func_expr(char *graph_name);
7878
static Query *cypher_create_graph_utility(ParseState *pstate, const char *graph_name);
7979
static FuncExpr *make_clause_use_graph_func_expr(char *graph_name);
8080
static Query *cypher_use_graph_utility(ParseState *pstate, const char *graph_name);
81+
static FuncExpr *make_clause_create_vlabel_func_expr(char *label_name);
82+
static Query *cypher_create_vlabel_utility(ParseState *pstate, const char *label_name);
83+
8184
static Oid get_session_graph_oid();
8285
static CommandTag
8386
CypherCreateCommandTag(Node *parsetree);
@@ -1223,6 +1226,10 @@ cypher_parse_analyze(RawStmt *parseTree, const char *sourceText,
12231226
cypher_drop_graph *ccg = n;
12241227

12251228
query = cypher_drop_graph_utility(pstate, ccg->graph_name);
1229+
} else if (is_ag_node(n, cypher_create_vlabel)) {
1230+
cypher_create_vlabel *ccg = n;
1231+
1232+
query = cypher_create_vlabel_utility(pstate, ccg->label_name);
12261233
} else {
12271234
query = parse_analyze((makeRawStmt(n, 0)), sourceText, paramTypes, numParams, queryEnv);
12281235

@@ -1452,6 +1459,47 @@ cypher_use_graph_utility(ParseState *pstate, const char *graph_name) {
14521459
return query;
14531460
}
14541461

1462+
1463+
1464+
/*
1465+
* Creates the function expression that represents the clause. Adds the
1466+
* extensible node that represents the metadata that the clause needs to
1467+
* handle the clause in the execution phase.
1468+
*/
1469+
static FuncExpr *make_clause_create_vlabel_func_expr(char *label_name) {
1470+
1471+
graph_cache_data *gcd = search_graph_namespace_cache(get_session_graph_oid());
1472+
1473+
Const *c = makeConst(TEXTOID, -1, InvalidOid, strlen(label_name), CStringGetTextDatum(label_name), false, false);
1474+
Const *c1 = makeConst(TEXTOID, -1, InvalidOid, strlen(gcd->name.data), CStringGetTextDatum(gcd->name.data), false, false);
1475+
1476+
1477+
Oid func_oid = get_ag_func_oid("create_vlabel", 2, TEXTOID, TEXTOID);
1478+
1479+
return makeFuncExpr(func_oid, VOIDOID, list_make2(c1, c), InvalidOid, InvalidOid, COERCE_EXPLICIT_CALL);
1480+
}
1481+
1482+
static Query *
1483+
cypher_create_vlabel_utility(ParseState *pstate, const char *label_name) {
1484+
Query *query;
1485+
TargetEntry *tle;
1486+
FuncExpr *func_expr;
1487+
1488+
query = makeNode(Query);
1489+
query->commandType = CMD_SELECT;
1490+
query->targetList = NIL;
1491+
1492+
func_expr = make_clause_create_vlabel_func_expr(label_name);
1493+
1494+
// Create the target entry
1495+
tle = makeTargetEntry((Expr *)func_expr, pstate->p_next_resno++, "create_vlabel", false);
1496+
query->targetList = lappend(query->targetList, tle);
1497+
1498+
query->rtable = pstate->p_rtable;
1499+
query->jointree = makeFromExpr(pstate->p_joinlist, NULL);
1500+
return query;
1501+
}
1502+
14551503
Oid get_session_graph_oid()
14561504
{
14571505
ScanKeyData scan_keys[1];

src/backend/parser/cypher_clause.c

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -808,11 +808,9 @@ static void transform_match_pattern(cypher_parsestate *cpstate, Query *query, Li
808808
bool is_null;
809809
rel_name = heap_getattr(tuple, Anum_ag_label_name, RelationGetDescr(label_catalog), &is_null);
810810

811-
812811
systable_endscan(scan_desc);
813812
table_close(label_catalog, AccessShareLock);
814813

815-
816814
//rel_name = get_label_relation_name(node->label, cpstate->graph_oid);
817815
label_range_var = makeRangeVar(schema_name, rel_name, -1);
818816
alias = makeAlias(node->name, NIL);
@@ -823,7 +821,6 @@ static void transform_match_pattern(cypher_parsestate *cpstate, Query *query, Li
823821
addNSItemToQuery(pstate, pnsi, true, true, true);
824822

825823
resno = pstate->p_next_resno++;
826-
827824
// XXX: End LTree Code here
828825

829826
expr = (Expr *)make_vertex_expr(cpstate, pnsi);
@@ -839,9 +836,7 @@ static void transform_match_pattern(cypher_parsestate *cpstate, Query *query, Li
839836
te = makeTargetEntry(id, resno, make_id_alias(node->name), false);
840837
query->targetList = lappend(query->targetList, te);
841838

842-
/*
843-
* properties field
844-
*/
839+
// properties field
845840
Node *props = scanNSItemForColumn(pstate, pnsi, 0, AG_VERTEX_COLNAME_PROPERTIES, -1);
846841
resno = pstate->p_next_resno++;
847842

src/backend/parser/cypher_gram.y

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -291,7 +291,7 @@ makeSimpleCypherA_Expr(A_Expr_Kind kind, char *name,
291291
UNLISTEN UNLOGGED UNTIL UNWIND UPDATE USE USER USING
292292

293293
VACUUM VALID VALIDATE VALIDATOR VALUE_P VALUES VARCHAR VARIADIC VARYING
294-
VERBOSE VERSION_P VIEW VIEWS VOLATILE
294+
VERBOSE VERSION_P VIEW VIEWS VLABEL VOLATILE
295295

296296
WHEN WHERE WHITESPACE_P WINDOW WITH WITHIN WITHOUT WORK WRAPPER WRITE
297297

@@ -345,7 +345,7 @@ makeSimpleCypherA_Expr(A_Expr_Kind kind, char *name,
345345
CreateMatViewStmt RefreshMatViewStmt CreateAmStmt
346346
CreatePublicationStmt AlterPublicationStmt
347347
CreateSubscriptionStmt AlterSubscriptionStmt DropSubscriptionStmt
348-
CreateGraphStmt UseGraphStmt DropGraphStmt
348+
CreateGraphStmt CreateVLabelStmt UseGraphStmt DropGraphStmt
349349

350350
%type <node> select_no_parens select_with_parens select_clause
351351
simple_select
@@ -936,6 +936,7 @@ toplevel_stmt:
936936
stmt:
937937
CYPHER cypher_stmt { $$ = (Node *)$2; }
938938
| CreateGraphStmt
939+
| CreateVLabelStmt
939940
| DropGraphStmt
940941
| UseGraphStmt
941942
| AlterEventTrigStmt
@@ -11431,7 +11432,18 @@ CreateGraphStmt:
1143111432
$$ = (Node *)n;
1143211433
}
1143311434
;
11435+
11436+
CreateVLabelStmt:
11437+
CREATE VLABEL BareColLabel
11438+
{
11439+
11440+
cypher_create_vlabel *n;
11441+
n = make_ag_node(cypher_create_vlabel);
11442+
n->label_name = $3;
1143411443

11444+
$$ = (Node *)n;
11445+
}
11446+
;
1143511447

1143611448
/*****************************************************************************
1143711449
*

0 commit comments

Comments
 (0)