31 #include <utils/date.h>
56 char* multipliers_sql,
61 bool stop_on_all_served,
62 int64_t execution_date,
67 size_t *result_count) {
75 PGR_DBG(
"execution_date: %ld ", execution_date);
80 (errcode(ERRCODE_INTERNAL_ERROR),
81 errmsg(
"Illegal value in parameter: factor"),
82 errhint(
"Value found: %f <= 0", factor)));
88 (errcode(ERRCODE_INTERNAL_ERROR),
89 errmsg(
"Illegal value in parameter: max_cycles"),
90 errhint(
"Value found: %d <= 0", max_cycles)));
96 size_t total_pd_orders = 0;
98 get_shipments(pd_orders_sql, &pd_orders_arr, &total_pd_orders);
103 if (total_pd_orders == 0) {
105 (*result_tuples) = NULL;
108 if (pd_orders_arr) {pfree(pd_orders_arr); pd_orders_arr = NULL;}
115 size_t total_vehicles = 0;
116 if (use_timestamps) {
117 get_vehicles(vehicles_sql, &vehicles_arr, &total_vehicles,
true);
122 if (total_vehicles == 0) {
124 (*result_tuples) = NULL;
127 if (pd_orders_arr) {pfree(pd_orders_arr); pd_orders_arr = NULL;}
128 if (vehicles_arr) {pfree(vehicles_arr); vehicles_arr = NULL;}
131 (errcode(ERRCODE_INTERNAL_ERROR),
132 errmsg(
"No vehicles found")));
139 size_t total_multipliers_arr = 0;
140 if (use_timestamps) {
141 PGR_DBG(
"get_timeMultipliers");
144 PGR_DBG(
"get_timeMultipliers_raw");
148 if (total_multipliers_arr == 0) {
150 (errcode(ERRCODE_INTERNAL_ERROR),
151 errmsg(
"No matrix found")));
153 (*result_tuples) = NULL;
156 if (pd_orders_arr) {pfree(pd_orders_arr); pd_orders_arr = NULL;}
157 if (vehicles_arr) {pfree(vehicles_arr); vehicles_arr = NULL;}
158 if (multipliers_arr) {pfree(multipliers_arr); multipliers_arr = NULL;}
165 size_t total_cells = 0;
166 if (use_timestamps) {
172 if (total_cells == 0) {
174 (*result_tuples) = NULL;
177 if (pd_orders_arr) {pfree(pd_orders_arr); pd_orders_arr = NULL;}
178 if (vehicles_arr) {pfree(vehicles_arr); vehicles_arr = NULL;}
179 if (multipliers_arr) {pfree(multipliers_arr); multipliers_arr = NULL;}
180 if (matrix_cells_arr) {pfree(matrix_cells_arr); matrix_cells_arr = NULL;}
183 (errcode(ERRCODE_INTERNAL_ERROR),
184 errmsg(
"No matrix found")));
189 PGR_DBG(
"Total %ld orders in query:", total_pd_orders);
190 PGR_DBG(
"Total %ld vehicles in query:", total_vehicles);
191 PGR_DBG(
"Total %ld matrix cells in query:", total_cells);
192 PGR_DBG(
"Total %ld time dependant multipliers:", total_multipliers_arr);
194 clock_t start_t = clock();
195 char *log_msg = NULL;
196 char *notice_msg = NULL;
197 char *err_msg = NULL;
200 pd_orders_arr, total_pd_orders,
201 vehicles_arr, total_vehicles,
202 matrix_cells_arr, total_cells,
203 multipliers_arr, total_multipliers_arr,
219 time_msg(
"pgr_pickDeliver", start_t, clock());
221 if (err_msg && (*result_tuples)) {
222 pfree(*result_tuples);
224 (*result_tuples) = NULL;
229 if (log_msg) {pfree(log_msg); log_msg = NULL;}
230 if (notice_msg) {pfree(notice_msg); notice_msg = NULL;}
231 if (err_msg) {pfree(err_msg); err_msg = NULL;}
232 if (pd_orders_arr) {pfree(pd_orders_arr); pd_orders_arr = NULL;}
233 if (vehicles_arr) {pfree(vehicles_arr); vehicles_arr = NULL;}
234 if (multipliers_arr) {pfree(multipliers_arr); multipliers_arr = NULL;}
235 if (matrix_cells_arr) {pfree(matrix_cells_arr); matrix_cells_arr = NULL;}
247 FuncCallContext *funcctx;
248 TupleDesc tuple_desc;
252 size_t result_count = 0;
255 if (SRF_IS_FIRSTCALL()) {
256 MemoryContext oldcontext;
257 funcctx = SRF_FIRSTCALL_INIT();
258 oldcontext = MemoryContextSwitchTo(funcctx->multi_call_memory_ctx);
261 text_to_cstring(PG_GETARG_TEXT_P(0)),
262 text_to_cstring(PG_GETARG_TEXT_P(1)),
263 text_to_cstring(PG_GETARG_TEXT_P(2)),
264 text_to_cstring(PG_GETARG_TEXT_P(3)),
270 PG_GETARG_TIMEADT(8),
278 funcctx->max_calls = result_count;
279 funcctx->user_fctx = result_tuples;
280 if (get_call_result_type(fcinfo, NULL, &tuple_desc)
281 != TYPEFUNC_COMPOSITE) {
283 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
284 errmsg(
"function returning record called in context "
285 "that cannot accept type record")));
288 funcctx->tuple_desc = tuple_desc;
289 MemoryContextSwitchTo(oldcontext);
292 funcctx = SRF_PERCALL_SETUP();
293 tuple_desc = funcctx->tuple_desc;
296 if (funcctx->call_cntr < funcctx->max_calls) {
301 size_t call_cntr = funcctx->call_cntr;
304 values = palloc(numb *
sizeof(Datum));
305 nulls = palloc(numb *
sizeof(
bool));
308 for (i = 0; i < numb; ++i) {
313 values[0] = Int32GetDatum(funcctx->call_cntr + 1);
314 values[1] = Int32GetDatum(result_tuples[call_cntr].vehicle_seq);
315 values[2] = Int64GetDatum(result_tuples[call_cntr].vehicle_id);
316 values[3] = Int32GetDatum(result_tuples[call_cntr].stop_seq);
317 values[4] = Int32GetDatum(result_tuples[call_cntr].stop_type + 1);
318 values[5] = Int64GetDatum(result_tuples[call_cntr].stop_id);
319 values[6] = Int64GetDatum(result_tuples[call_cntr].order_id);
320 values[7] = Int64GetDatum(result_tuples[call_cntr].cargo);
321 values[8] = Int64GetDatum(result_tuples[call_cntr].travelTime);
322 values[9] = Int64GetDatum(result_tuples[call_cntr].arrivalTime);
323 values[10] = Int64GetDatum(result_tuples[call_cntr].waitDuration);
324 values[11] = Int64GetDatum(result_tuples[call_cntr].operationTime);
325 values[12] = Int64GetDatum(result_tuples[call_cntr].serviceDuration);
326 values[13] = Int64GetDatum(result_tuples[call_cntr].departureTime);
327 values[14] = Int32GetDatum(result_tuples[call_cntr].cvTot);
328 values[15] = Int32GetDatum(result_tuples[call_cntr].twvTot);
332 tuple = heap_form_tuple(tuple_desc, values, nulls);
333 result = HeapTupleGetDatum(tuple);
335 pfree(values); values = NULL;
336 pfree(nulls); nulls = NULL;
338 SRF_RETURN_NEXT(funcctx, result);
340 if (result_tuples) {pfree(result_tuples); result_tuples = NULL;}
341 funcctx->user_fctx = NULL;
342 SRF_RETURN_DONE(funcctx);
353 FuncCallContext *funcctx;
354 TupleDesc tuple_desc;
358 size_t result_count = 0;
361 if (SRF_IS_FIRSTCALL()) {
362 MemoryContext oldcontext;
363 funcctx = SRF_FIRSTCALL_INIT();
364 oldcontext = MemoryContextSwitchTo(funcctx->multi_call_memory_ctx);
367 text_to_cstring(PG_GETARG_TEXT_P(0)),
368 text_to_cstring(PG_GETARG_TEXT_P(1)),
369 text_to_cstring(PG_GETARG_TEXT_P(2)),
370 text_to_cstring(PG_GETARG_TEXT_P(3)),
384 funcctx->max_calls = result_count;
385 funcctx->user_fctx = result_tuples;
386 if (get_call_result_type(fcinfo, NULL, &tuple_desc)
387 != TYPEFUNC_COMPOSITE) {
389 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
390 errmsg(
"function returning record called in context "
391 "that cannot accept type record")));
394 funcctx->tuple_desc = tuple_desc;
395 MemoryContextSwitchTo(oldcontext);
398 funcctx = SRF_PERCALL_SETUP();
399 tuple_desc = funcctx->tuple_desc;
402 if (funcctx->call_cntr < funcctx->max_calls) {
407 size_t call_cntr = funcctx->call_cntr;
410 values = palloc(numb *
sizeof(Datum));
411 nulls = palloc(numb *
sizeof(
bool));
414 for (i = 0; i < numb; ++i) {
419 values[0] = Int32GetDatum(funcctx->call_cntr + 1);
420 values[1] = Int32GetDatum(result_tuples[call_cntr].vehicle_seq);
421 values[2] = Int64GetDatum(result_tuples[call_cntr].vehicle_id);
422 values[3] = Int32GetDatum(result_tuples[call_cntr].stop_seq);
423 values[4] = Int32GetDatum(result_tuples[call_cntr].stop_type + 1);
424 values[5] = Int64GetDatum(result_tuples[call_cntr].stop_id);
425 values[6] = Int64GetDatum(result_tuples[call_cntr].order_id);
426 values[7] = Int64GetDatum(result_tuples[call_cntr].cargo);
427 values[8] = Int64GetDatum(result_tuples[call_cntr].travelTime);
428 values[9] = Int64GetDatum(result_tuples[call_cntr].arrivalTime);
429 values[10] = Int64GetDatum(result_tuples[call_cntr].waitDuration);
430 values[11] = Int64GetDatum(result_tuples[call_cntr].operationTime);
431 values[12] = Int64GetDatum(result_tuples[call_cntr].serviceDuration);
432 values[13] = Int64GetDatum(result_tuples[call_cntr].departureTime);
433 values[14] = Int32GetDatum(result_tuples[call_cntr].cvTot);
434 values[15] = Int32GetDatum(result_tuples[call_cntr].twvTot);
438 tuple = heap_form_tuple(tuple_desc, values, nulls);
439 result = HeapTupleGetDatum(tuple);
441 pfree(values); values = NULL;
442 pfree(nulls); nulls = NULL;
444 SRF_RETURN_NEXT(funcctx, result);
446 if (result_tuples) {pfree(result_tuples); result_tuples = NULL;}
447 funcctx->user_fctx = NULL;
448 SRF_RETURN_DONE(funcctx);