31 #include "executor/spi.h"
33 #include "utils/array.h"
34 #include "catalog/pg_type.h"
35 #if PGSQL_VERSION > 92
36 #include "access/htup_details.h"
42 #include "./../../common/src/debug_macro.h"
43 #include "./../../common/src/time_msg.h"
44 #include "./../../common/src/pgr_types.h"
45 #include "./../../common/src/postgres_connection.h"
46 #include "./../../common/src/edges_input.h"
47 #include "./../../common/src/arrays_input.h"
48 #include "./../../common/src/points_input.h"
49 #include "./get_new_queries.h"
50 #include "./many_to_one_withPoints_driver.h"
52 PG_FUNCTION_INFO_V1(many_to_one_withPoints);
58 many_to_one_withPoints(PG_FUNCTION_ARGS);
68 int64_t *start_pidsArr,
69 size_t size_start_pidsArr,
76 size_t *result_count) {
78 driving_side[0] = tolower(driving_side[0]);
83 size_t total_points = 0;
84 pgr_get_points(points_sql, &points, &total_points);
87 char *edges_of_points_query = NULL;
88 char *edges_no_points_query = NULL;
90 edges_sql, points_sql,
91 &edges_of_points_query,
92 &edges_no_points_query);
96 size_t total_edges_of_points = 0;
97 pgr_get_data_5_columns(edges_of_points_query, &edges_of_points, &total_edges_of_points);
101 size_t total_edges = 0;
102 pgr_get_data_5_columns(edges_no_points_query, &edges, &total_edges);
104 free(edges_of_points_query);
105 free(edges_no_points_query);
107 if ( (total_edges + total_edges_of_points) == 0) {
109 (*result_tuples) = NULL;
114 char *err_msg = NULL;
115 clock_t start_t = clock();
116 int errcode = do_pgr_many_to_one_withPoints(
118 points, total_points,
119 edges_of_points, total_edges_of_points,
120 start_pidsArr, size_start_pidsArr,
129 time_msg(
" processing withPoints many to one", start_t, clock());
130 PGR_DBG(
"Returning %ld tuples\n", *result_count);
131 PGR_DBG(
"Returned message = %s\n", err_msg);
132 if (!err_msg) free(err_msg);
140 pgr_send_error(errcode);
152 many_to_one_withPoints(PG_FUNCTION_ARGS) {
153 FuncCallContext *funcctx;
156 TupleDesc tuple_desc;
162 size_t result_count = 0;
166 if (SRF_IS_FIRSTCALL()) {
167 MemoryContext oldcontext;
168 funcctx = SRF_FIRSTCALL_INIT();
169 oldcontext = MemoryContextSwitchTo(funcctx->multi_call_memory_ctx);
185 int64_t* start_pidsArr;
186 size_t size_start_pidsArr;
187 start_pidsArr = (int64_t*)
188 pgr_get_bigIntArray(&size_start_pidsArr, PG_GETARG_ARRAYTYPE_P(2));
191 pgr_text2char(PG_GETARG_TEXT_P(0)),
192 pgr_text2char(PG_GETARG_TEXT_P(1)),
193 start_pidsArr, size_start_pidsArr,
196 pgr_text2char(PG_GETARG_TEXT_P(5)),
202 if (start_pidsArr) free(start_pidsArr);
206 funcctx->max_calls = (uint32_t)result_count;
207 funcctx->user_fctx = result_tuples;
208 if (get_call_result_type(fcinfo, NULL, &tuple_desc) != TYPEFUNC_COMPOSITE)
210 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
211 errmsg(
"function returning record called in context "
212 "that cannot accept type record")));
214 funcctx->tuple_desc = tuple_desc;
215 MemoryContextSwitchTo(oldcontext);
218 funcctx = SRF_PERCALL_SETUP();
219 call_cntr = funcctx->call_cntr;
220 max_calls = funcctx->max_calls;
221 tuple_desc = funcctx->tuple_desc;
224 if (call_cntr < max_calls) {
240 values = palloc(7 *
sizeof(Datum));
241 nulls = palloc(7 *
sizeof(
char));
244 for(i = 0; i < 7; ++i) {
250 values[0] = Int32GetDatum(call_cntr + 1);
251 values[1] = Int32GetDatum(result_tuples[call_cntr].seq);
252 values[2] = Int64GetDatum(result_tuples[call_cntr].start_id);
253 values[3] = Int64GetDatum(result_tuples[call_cntr].node);
254 values[4] = Int64GetDatum(result_tuples[call_cntr].
edge);
255 values[5] = Float8GetDatum(result_tuples[call_cntr].cost);
256 values[6] = Float8GetDatum(result_tuples[call_cntr].agg_cost);
259 tuple = heap_formtuple(tuple_desc, values, nulls);
260 result = HeapTupleGetDatum(tuple);
261 SRF_RETURN_NEXT(funcctx, result);
264 if (result_tuples) free(result_tuples);
266 SRF_RETURN_DONE(funcctx);