32 #include "utils/array.h"
44 PGDLLEXPORT Datum
_pgr_astar(PG_FUNCTION_ARGS);
53 if (heuristic > 5 || heuristic < 0) {
55 (errmsg(
"Unknown heuristic"),
56 errhint(
"Valid values: 0~5")));
60 (errmsg(
"Factor value out of range"),
61 errhint(
"Valid values: positive non zero")));
65 (errmsg(
"Epsilon value out of range"),
66 errhint(
"Valid values: 1 or greater than 1")));
74 char* combinations_sql,
84 size_t *result_count) {
89 int64_t* start_vidsArr = NULL;
90 size_t size_start_vidsArr = 0;
92 int64_t* end_vidsArr = NULL;
93 size_t size_end_vidsArr = 0;
96 size_t total_edges = 0;
99 size_t total_combinations = 0;
103 if (starts && ends) {
104 start_vidsArr = (int64_t*)
106 end_vidsArr = (int64_t*)
108 }
else if (combinations_sql) {
113 end_vidsArr = (int64_t*)
115 start_vidsArr = (int64_t*)
119 if (total_edges == 0) {
122 (*result_tuples) = NULL;
127 PGR_DBG(
"Starting processing");
128 char *log_msg = NULL;
129 char *notice_msg = NULL;
130 char *err_msg = NULL;
131 clock_t start_t = clock();
135 combinations, total_combinations,
137 start_vidsArr, size_start_vidsArr,
138 end_vidsArr, size_end_vidsArr,
145 result_tuples, result_count,
151 time_msg(
"processing pgr_astarCost", start_t, clock());
153 time_msg(
"processing pgr_astar", start_t, clock());
157 if (err_msg && (*result_tuples)) {
158 pfree(*result_tuples);
159 (*result_tuples) = NULL;
165 if (log_msg) pfree(log_msg);
166 if (notice_msg) pfree(notice_msg);
167 if (err_msg) pfree(err_msg);
168 if (edges) pfree(edges);
169 if (start_vidsArr) pfree(start_vidsArr);
170 if (end_vidsArr) pfree(end_vidsArr);
177 FuncCallContext *funcctx;
178 TupleDesc tuple_desc;
182 size_t result_count = 0;
185 if (SRF_IS_FIRSTCALL()) {
186 MemoryContext oldcontext;
187 funcctx = SRF_FIRSTCALL_INIT();
188 oldcontext = MemoryContextSwitchTo(funcctx->multi_call_memory_ctx);
191 if (PG_NARGS() == 9) {
197 text_to_cstring(PG_GETARG_TEXT_P(0)),
199 PG_GETARG_ARRAYTYPE_P(1),
200 PG_GETARG_ARRAYTYPE_P(2),
210 }
else if (PG_NARGS() == 7) {
216 text_to_cstring(PG_GETARG_TEXT_P(0)),
217 text_to_cstring(PG_GETARG_TEXT_P(1)),
231 #if PGSQL_VERSION > 95
232 funcctx->max_calls = result_count;
234 funcctx->max_calls = (uint32_t)result_count;
236 funcctx->user_fctx = result_tuples;
237 if (get_call_result_type(fcinfo, NULL, &tuple_desc)
238 != TYPEFUNC_COMPOSITE)
240 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
241 errmsg(
"function returning record called in context "
242 "that cannot accept type record")));
244 funcctx->tuple_desc = tuple_desc;
245 MemoryContextSwitchTo(oldcontext);
248 funcctx = SRF_PERCALL_SETUP();
249 tuple_desc = funcctx->tuple_desc;
252 if (funcctx->call_cntr < funcctx->max_calls) {
271 values = palloc(numb *
sizeof(Datum));
272 nulls = palloc(numb *
sizeof(
bool));
275 for (i = 0; i < numb; ++i) {
280 values[0] = Int32GetDatum(funcctx->call_cntr + 1);
281 values[1] = Int32GetDatum(result_tuples[funcctx->call_cntr].
seq);
282 values[2] = Int64GetDatum(result_tuples[funcctx->call_cntr].
start_id);
283 values[3] = Int64GetDatum(result_tuples[funcctx->call_cntr].
end_id);
284 values[4] = Int64GetDatum(result_tuples[funcctx->call_cntr].
node);
285 values[5] = Int64GetDatum(result_tuples[funcctx->call_cntr].
edge);
286 values[6] = Float8GetDatum(result_tuples[funcctx->call_cntr].
cost);
287 values[7] = Float8GetDatum(result_tuples[funcctx->call_cntr].
agg_cost);
290 tuple = heap_form_tuple(tuple_desc, values, nulls);
291 result = HeapTupleGetDatum(tuple);
292 SRF_RETURN_NEXT(funcctx, result);
294 SRF_RETURN_DONE(funcctx);