Skip to content

Commit ca9b8e1

Browse files
committed
Support an upper limit
1 parent 6a7f88c commit ca9b8e1

3 files changed

Lines changed: 21 additions & 74 deletions

File tree

regress/sql/cypher_create.sql

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -159,6 +159,9 @@ MATCH (a) RETURN a;
159159
MATCH ()-[*1]->() RETURN 1;
160160
MATCH ()-[]->() RETURN 1;
161161
MATCH ()-[*2]->() RETURN 1;
162+
163+
MATCH ()-[*1..2]->() RETURN 1;
164+
162165
--
163166
-- Clean up
164167
--

src/backend/parser/cypher_clause.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1252,7 +1252,7 @@ add_variable_edge_to_query(cypher_parsestate *cpstate, Query *query, cypher_rela
12521252
make_int_const(cpstate->graph_oid, -1),
12531253
scanNSItemForColumn(cpstate, vertex_pnsi, 0, AG_VERTEX_COLNAME_ID, -1),
12541254
((A_Indices *)edge->varlen)->lidx,
1255-
make_null_const(-1)),
1255+
((A_Indices *)edge->varlen)->uidx),
12561256
COERCE_EXPLICIT_CALL, -1),
12571257
edge->name,
12581258
list_make3(makeString("edges"), makeString("endid"), makeString("hashset")));

src/backend/utils/edge_searching.c

Lines changed: 17 additions & 73 deletions
Original file line numberDiff line numberDiff line change
@@ -51,34 +51,8 @@
5151
#include "utils/ag_cache.h"
5252
#include "utils/hashset.h"
5353

54-
5554
#include "ltree.h"
5655

57-
static Datum get_vertex(Oid graph_oid, int64 graphid, bool *isnull)
58-
{
59-
label_cache_data *lcd = search_label_graph_oid_cache(graph_oid, (graphid >> ENTRY_ID_BITS));
60-
61-
ScanKeyData scan_keys[1];
62-
ScanKeyInit(&scan_keys[0], 1, BTEqualStrategyNumber, F_OIDEQ, Int64GetDatum(graphid));
63-
64-
Relation rel = table_open(lcd->relation, ShareLock);
65-
66-
TableScanDesc scan_desc = table_beginscan(rel, GetActiveSnapshot(), 1, scan_keys);
67-
68-
HeapTuple tuple;
69-
if (!HeapTupleIsValid(tuple = heap_getnext(scan_desc, ForwardScanDirection)))
70-
ereport(ERROR, (errcode(ERRCODE_UNDEFINED_TABLE), errmsg("id %lu does not exist", graphid)));
71-
72-
Datum properties = heap_getattr(tuple, 2, RelationGetDescr(rel), isnull);
73-
//*isnull = false;
74-
table_endscan(scan_desc);
75-
table_close(rel, ShareLock);
76-
77-
return properties;
78-
}
79-
80-
81-
8256
PG_FUNCTION_INFO_V1(retrieve_vertex);
8357
Datum retrieve_vertex(PG_FUNCTION_ARGS) {
8458
Oid graph_oid = GT_ARG_TO_INT4_DATUM(0);
@@ -110,30 +84,6 @@ Datum retrieve_vertex(PG_FUNCTION_ARGS) {
11084

11185
}
11286

113-
/*
114-
PG_FUNCTION_INFO_V1(retrieve_vertex);
115-
Datum retrieve_vertex(PG_FUNCTION_ARGS) {
116-
117-
FuncCallContext *funcctx;
118-
if (SRF_IS_FIRSTCALL()) {
119-
funcctx = SRF_FIRSTCALL_INIT();
120-
121-
TupleDesc tupdesc = CreateTemplateTupleDesc(1);
122-
TupleDescInitEntry(tupdesc, 1, "properties", GTYPEOID, -1, 0);
123-
funcctx->tuple_desc = BlessTupleDesc(tupdesc);
124-
125-
funcctx = SRF_PERCALL_SETUP();
126-
127-
Datum values[1];
128-
bool nulls[1];
129-
values[0] = get_vertex(GT_ARG_TO_INT4_DATUM(0), AG_GETARG_GRAPHID(1), &nulls[0]);
130-
SRF_RETURN_NEXT(funcctx, HeapTupleGetDatum(heap_form_tuple(funcctx->tuple_desc, values, nulls)));
131-
}
132-
133-
SRF_RETURN_DONE(funcctx);
134-
}
135-
*/
136-
13787
typedef struct edge_search_cxt
13888
{
13989
ScanKey scanKey;
@@ -145,8 +95,6 @@ typedef struct edge_search_cxt
14595
PG_FUNCTION_INFO_V1(edge_search);
14696
Datum edge_search(PG_FUNCTION_ARGS)
14797
{
148-
//ereport(WARNING, (errmsg("edge_search called with graphid %lu", AG_GETARG_GRAPHID(1))));
149-
15098
FuncCallContext *funcctx;
15199
if (SRF_IS_FIRSTCALL()) {
152100
MemoryContext oldcontext;
@@ -214,23 +162,6 @@ Datum edge_search(PG_FUNCTION_ARGS)
214162
//ereport(WARNING, (errmsg("edge_search sending graphid %lu", DATUM_GET_GRAPHID(values[2]))));
215163
SRF_RETURN_NEXT(funcctx, HeapTupleGetDatum(heap_form_tuple(funcctx->tuple_desc, values, nulls)));
216164
}
217-
/*
218-
// Node for the linked list to handle collisions (chaining)
219-
typedef struct HashSetNode {
220-
graphid key;
221-
struct HashSetNode* next;
222-
} HashSetNode;
223-
224-
// The main Hash Set structure
225-
typedef struct HashSetValue {
226-
HashSetNode** buckets; // Array of pointers to HashSetNodes (the buckets)
227-
int capacity; // The total number of buckets
228-
int size; // The current number of elements in the set
229-
} HashSetValue;
230-
*/
231-
232-
233-
234165

235166
typedef struct variable_edge_stack
236167
{
@@ -251,6 +182,7 @@ typedef struct variable_edge_search_cxt
251182
Relation rel;
252183
TupleTableSlot *slot;
253184
int min;
185+
int max;
254186
Oid graph_oid;
255187
HashSetValue *hashSet;
256188
variable_edge_stack *stack;
@@ -351,6 +283,11 @@ Datum variable_edge_search(PG_FUNCTION_ARGS)
351283
cxt->graph_oid = GT_ARG_TO_INT4_DATUM(0);
352284
cxt->min = GT_ARG_TO_INT4_DATUM(2);
353285

286+
if (PG_ARGISNULL(3))
287+
cxt->max = -1;
288+
else
289+
cxt->max = GT_ARG_TO_INT4_DATUM(3);
290+
354291
cxt->stack = palloc0(sizeof(variable_edge_stack));
355292
cxt->stack->array = palloc0(sizeof(graphid) * (1024));
356293
cxt->stack->top = 0;
@@ -361,8 +298,11 @@ Datum variable_edge_search(PG_FUNCTION_ARGS)
361298
cxt->edge_stack->top = 0;
362299
cxt->edge_stack->capacity = 1024;
363300

301+
if (cxt->max == -1)
302+
cxt->current_path = palloc(sizeof(graph_stack_count) * (cxt->min + 1));
303+
else
304+
cxt->current_path = palloc(sizeof(graph_stack_count) * (cxt->max + 1));
364305

365-
cxt->current_path = palloc(sizeof(graph_stack_count) * (cxt->min + 1));
366306
cxt->current_path_length = 0;
367307

368308
cxt->hashSet = createHashSet(1024);
@@ -391,7 +331,7 @@ Datum variable_edge_search(PG_FUNCTION_ARGS)
391331

392332
insert(cxt->hashSet, edge_id);
393333
//ereport(WARNING, errmsg("cxt->hashSet->size %i, %lu", cxt->hashSet->size, id));
394-
if (cxt->hashSet->size == cxt->min) {
334+
if (cxt->hashSet->size >= cxt->min) {
395335
Datum values[3];
396336
bool nulls[3];
397337
values[0] = NULL;
@@ -406,10 +346,14 @@ Datum variable_edge_search(PG_FUNCTION_ARGS)
406346

407347
values[2] = HASHSET_P_GET_DATUM(hset);
408348
nulls[2] = false;
409-
removeElement(cxt->hashSet, edge_id);
349+
if (cxt->max == -1 || cxt->current_path_length < cxt->max) {
350+
scan_and_push_neighbors(cxt, id);
351+
} else {
352+
removeElement(cxt->hashSet, edge_id);
353+
}
410354
//ereport(WARNING, errmsg("sending %lu", id));
411355
SRF_RETURN_NEXT(funcctx, HeapTupleGetDatum(heap_form_tuple(funcctx->tuple_desc, values, nulls)));
412-
} else {
356+
} else if (cxt->max == -1 || cxt->current_path_length < cxt->max) {
413357
scan_and_push_neighbors(cxt, id);
414358
}
415359

0 commit comments

Comments
 (0)