Skip to content

Commit d202fb3

Browse files
committed
feat: Support label filtering in vle match search
1 parent 9e1ad8c commit d202fb3

4 files changed

Lines changed: 57 additions & 8 deletions

File tree

postgraph--0.1.0.sql

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6892,7 +6892,7 @@ CREATE OPERATOR @> (
68926892
--JOIN = neqjoinsel
68936893
);
68946894

6895-
CREATE FUNCTION variable_edge_search(graph_oid gtype, id graphid, min gtype, max gtype, label_filter text[] DEFAULT NULL)
6895+
CREATE FUNCTION variable_edge_search(graph_oid gtype, id graphid, min gtype, max gtype, label gtype)
68966896
RETURNS TABLE (edges variable_edge, endid graphid, hset hashset)
68976897
CALLED ON NULL INPUT
68986898
STABLE

regress/sql/cypher_create.sql

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -171,6 +171,16 @@ MATCH ()-[*1..]->() RETURN 1;
171171

172172
MATCH ()-[:elabel]->() RETURN 1;
173173

174+
MATCH ()-[:elabel*1]->() RETURN 1;
175+
176+
MATCH ()-[:elabel*1..]->() RETURN 1;
177+
178+
MATCH ()-[:elabel*1..2]->() RETURN 1;
179+
180+
MATCH ()-[:elabel*2]->() RETURN 1;
181+
182+
MATCH ()-[:elabel*..2]->() RETURN 1;
183+
174184
--
175185
-- Clean up
176186
--

src/backend/parser/cypher_clause.c

Lines changed: 16 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1288,24 +1288,33 @@ add_variable_edge_to_query(cypher_parsestate *cpstate, Query *query, cypher_rela
12881288
edge->name = get_next_default_alias(cpstate);
12891289

12901290
bool is_default_label = true;
1291-
if (edge->label)
1292-
ereport(ERROR,
1293-
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
1294-
errmsg("MATCH labels are not supported")));
1295-
else
1291+
Node *label_filter = NULL;
1292+
if (edge->label) {
1293+
is_default_label = false;
1294+
label_cache_data *lcd = search_label_name_graph_cache(edge->label, cpstate->graph_oid);
1295+
if (!lcd)
1296+
ereport(ERROR,
1297+
(errcode(ERRCODE_UNDEFINED_OBJECT),
1298+
errmsg("Edge label \"%s\" does not exist", edge->label)));
1299+
1300+
label_filter = make_int_const(lcd->id, -1);
1301+
}else {
12961302
edge->label = AG_DEFAULT_LABEL_EDGE;
1303+
}
12971304

12981305
A_Indices *varlen = (A_Indices *)edge->varlen;
12991306

13001307
return add_srf_to_query(
13011308
cpstate,
13021309
makeFuncCall(
13031310
list_make2(makeString("postgraph"), makeString("variable_edge_search")),
1304-
list_make4(
1311+
list_make5(
13051312
make_int_const(cpstate->graph_oid, -1),
13061313
scanNSItemForColumn(cpstate, vertex_pnsi, 0, AG_VERTEX_COLNAME_ID, -1),
13071314
varlen->lidx ? varlen->lidx : make_null_const(-1),
1308-
varlen->uidx ? varlen->uidx : make_null_const(-1)),
1315+
varlen->uidx ? varlen->uidx : make_null_const(-1),
1316+
!is_default_label ? (Node *)label_filter : make_null_const(-1)
1317+
),
13091318
COERCE_EXPLICIT_CALL, -1),
13101319
edge->name,
13111320
list_make3(makeString("edges"), makeString("endid"), makeString("hashset")));

src/backend/utils/edge_searching.c

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -227,6 +227,7 @@ typedef struct variable_edge_search_cxt
227227
graph_stack_count *current_path;
228228
variable_edge_stack *edge_stack;
229229
int current_path_length;
230+
List *label_filter;
230231
} variable_edge_search_cxt;
231232

232233
static void
@@ -269,13 +270,32 @@ scan_and_push_neighbors(variable_edge_search_cxt *cxt, graphid id)
269270
while (table_scan_getnextslot(cxt->scan_desc, ForwardScanDirection, cxt->slot)) {
270271
cxt->slot->tts_ops->materialize(cxt->slot);
271272

273+
272274
bool isnull;
273275
graphid edge_id = DATUM_GET_GRAPHID(
274276
heap_getattr(
275277
cxt->slot->tts_ops->get_heap_tuple(cxt->slot),
276278
1,
277279
RelationGetDescr(cxt->scan_desc->rs_rd),
278280
&isnull));
281+
282+
if (cxt->label_filter != NIL) {
283+
bool isnull;
284+
Oid edge_label_oid = (edge_id >> ENTRY_ID_BITS);
285+
286+
bool found = false;
287+
ListCell *lc;
288+
foreach(lc, cxt->label_filter) {
289+
if (edge_label_oid == lfirst_oid(lc)) {
290+
found = true;
291+
break;
292+
}
293+
}
294+
if (!found)
295+
continue;
296+
}
297+
298+
279299
graphid new_id = DATUM_GET_GRAPHID(
280300
heap_getattr(
281301
cxt->slot->tts_ops->get_heap_tuple(cxt->slot),
@@ -344,7 +364,17 @@ Datum variable_edge_search(PG_FUNCTION_ARGS)
344364
cxt->current_path_length = 0;
345365

346366
cxt->hashSet = createHashSet(1024);
367+
368+
369+
cxt->label_filter = NIL;
370+
if (!PG_ARGISNULL(4)) {
371+
cxt->label_filter = lappend_oid(cxt->label_filter, GT_ARG_TO_INT4_DATUM(4));
372+
}
373+
374+
347375
scan_and_push_neighbors(cxt, id);
376+
377+
348378
funcctx->user_fctx = cxt;
349379

350380
MemoryContextSwitchTo(oldcontext);

0 commit comments

Comments
 (0)