252 bool moredata =
true;
253 uint32_t TUPLIMIT = 1000;
257 uint32_t total_tuples = 0;
260 .cost = -1, .reverse_cost = -1};
265 uint32_t total_restrict_tuples = 0;
268 int64_t v_max_id = 0;
269 int64_t v_min_id = INT_MAX;
279 PGR_DBG(
"start turn_restrict_shortest_path\n");
281 SPIcode = SPI_connect();
282 if (SPIcode != SPI_OK_CONNECT) {
283 elog(ERROR,
"turn_restrict_shortest_path: "
284 "couldn't open a connection to SPI");
288 SPIplan = SPI_prepare(sql, 0, NULL);
289 if (SPIplan == NULL) {
290 elog(ERROR,
"turn_restrict_shortest_path: "
291 "couldn't create query plan via SPI");
295 if ((SPIportal = SPI_cursor_open(NULL, SPIplan, NULL, NULL,
true)) == NULL) {
296 elog(ERROR,
"turn_restrict_shortest_path: "
297 "SPI_cursor_open('%s') returns NULL", sql);
301 while (moredata ==
true) {
303 SPI_cursor_fetch(SPIportal,
true, TUPLIMIT);
305 if (SPI_tuptable == NULL) {
306 elog(ERROR,
"SPI_tuptable is NULL");
307 return finish(SPIcode, -1);
312 has_reverse_cost) == -1)
313 return finish(SPIcode, ret);
316 ntuples = SPI_processed;
318 total_tuples += ntuples;
322 edges = palloc(total_tuples *
sizeof(
edge_t));
324 edges = repalloc(edges, total_tuples *
sizeof(
edge_t));
327 elog(ERROR,
"Out of memory");
328 return finish(SPIcode, ret);
332 SPITupleTable *tuptable = SPI_tuptable;
333 TupleDesc tupdesc = SPI_tuptable->tupdesc;
335 for (t = 0; t < ntuples; t++) {
336 HeapTuple tuple = tuptable->vals[t];
338 &edges[total_tuples - ntuples + t]);
340 SPI_freetuptable(tuptable);
345 SPI_cursor_close(SPIportal);
349 for (z = 0; z < total_tuples; z++) {
350 if (edges[z].source < v_min_id)
351 v_min_id = edges[z].
source;
353 if (edges[z].source > v_max_id)
354 v_max_id = edges[z].
source;
356 if (edges[z].target < v_min_id)
357 v_min_id = edges[z].
target;
359 if (edges[z].target > v_max_id)
360 v_max_id = edges[z].
target;
366 for (z = 0; z < total_tuples; z++) {
369 if (edges[z].source == start_id || edges[z].target == start_id)
371 if (edges[z].source == end_id || edges[z].target == end_id)
374 if (edges[z].
id == start_id)
376 if (edges[z].
id == end_id)
380 edges[z].
source -= v_min_id;
381 edges[z].
target -= v_min_id;
384 PGR_DBG(
"Min vertex id: %ld , Max vid: %ld", v_min_id, v_max_id);
385 PGR_DBG(
"Total %i edge tuples", total_tuples);
388 elog(ERROR,
"Start id was not found.");
393 elog(ERROR,
"Target id was not found.");
398 start_id -= v_min_id;
402 PGR_DBG(
"Fetching restriction tuples\n");
404 if (restrict_sql == NULL) {
405 PGR_DBG(
"Sql for restrictions is null.");
407 SPIplan = SPI_prepare(restrict_sql, 0, NULL);
408 if (SPIplan == NULL) {
409 elog(ERROR,
"turn_restrict_shortest_path: "
410 "couldn't create query plan via SPI");
414 if ((SPIportal = SPI_cursor_open(NULL, SPIplan, NULL, NULL,
true)) \
416 elog(ERROR,
"turn_restrict_shortest_path:"
417 " SPI_cursor_open('%s') returns NULL", restrict_sql);
422 while (moredata ==
true) {
423 SPI_cursor_fetch(SPIportal,
true, TUPLIMIT);
428 PGR_DBG(
"fetch_restrict_columns failed!");
429 return finish(SPIcode, ret);
434 #pragma GCC diagnostic push
435 #pragma GCC diagnostic ignored "-Wconversion"
436 ntuples = SPI_processed;
437 #pragma GCC diagnostic pop
439 total_restrict_tuples += ntuples;
443 restricts = palloc(total_restrict_tuples *
sizeof(
restrict_t));
445 restricts = repalloc(restricts,
448 if (restricts == NULL) {
449 elog(ERROR,
"Out of memory");
450 return finish(SPIcode, ret);
454 SPITupleTable *tuptable = SPI_tuptable;
455 TupleDesc tupdesc = SPI_tuptable->tupdesc;
457 for (t = 0; t < ntuples; t++) {
458 HeapTuple tuple = tuptable->vals[t];
460 &restricts[total_restrict_tuples - ntuples + t]);
462 SPI_freetuptable(tuptable);
467 SPI_cursor_close(SPIportal);
470 PGR_DBG(
"Total %i restriction tuples", total_restrict_tuples);
472 PGR_DBG(
"Calling trsp_edge_wrapper\n");
474 restricts, total_restrict_tuples,
475 start_id, start_pos, end_id, end_pos,
476 directed, has_reverse_cost,
477 path, path_count, &err_msg);
479 PGR_DBG(
"Message received from inside:");
486 for (z = 0; z < *path_count; z++) {
487 if (z || (*path)[z].vertex_id != -1)
488 (*path)[z].vertex_id += v_min_id;
493 PGR_DBG(
"*path_count = %ld\n", *path_count);
496 ereport(ERROR, (errcode(ERRCODE_E_R_E_CONTAINING_SQL_NOT_PERMITTED),
497 errmsg(
"Error computing path: %s", err_msg)));
500 return finish(SPIcode, ret);