33 #include "utils/array.h"
34 #include "catalog/pg_type.h"
35 #include "utils/lsyscache.h"
38 #define INT8ARRAYOID 1016
62 size_t *result_count) {
66 if (num_cycles < 1)
return;
70 size_t size_forbidden_vertices = 0;
71 int64_t* forbidden_vertices =
73 &size_forbidden_vertices,
75 PGR_DBG(
"size_forbidden_vertices %ld", size_forbidden_vertices);
77 size_t size_contraction_order = 0;
78 int64_t* contraction_order =
80 &size_contraction_order,
82 PGR_DBG(
"size_contraction_order %ld ", size_contraction_order);
85 size_t total_edges = 0;
88 if (total_edges == 0) {
89 if (forbidden_vertices) pfree(forbidden_vertices);
90 if (contraction_order) pfree(contraction_order);
96 clock_t start_t = clock();
98 char* notice_msg = NULL;
102 forbidden_vertices, size_forbidden_vertices,
103 contraction_order, size_contraction_order,
106 result_tuples, result_count,
111 time_msg(
"processing pgr_contraction()", start_t, clock());
114 if (err_msg && (*result_tuples)) {
115 pfree(*result_tuples);
116 (*result_tuples) = NULL;
122 if (log_msg) pfree(log_msg);
123 if (notice_msg) pfree(notice_msg);
124 if (err_msg) pfree(err_msg);
125 if (edges) pfree(edges);
126 if (forbidden_vertices) pfree(forbidden_vertices);
127 if (contraction_order) pfree(contraction_order);
133 FuncCallContext *funcctx;
134 TupleDesc tuple_desc;
138 size_t result_count = 0;
141 if (SRF_IS_FIRSTCALL()) {
142 MemoryContext oldcontext;
143 funcctx = SRF_FIRSTCALL_INIT();
144 oldcontext = MemoryContextSwitchTo(funcctx->multi_call_memory_ctx);
156 text_to_cstring(PG_GETARG_TEXT_P(0)),
157 PG_GETARG_ARRAYTYPE_P(1),
159 PG_GETARG_ARRAYTYPE_P(3),
166 #if PGSQL_VERSION > 95
167 funcctx->max_calls = result_count;
169 funcctx->max_calls = (uint32_t)result_count;
171 funcctx->user_fctx = result_tuples;
172 if (get_call_result_type(fcinfo, NULL, &tuple_desc)
173 != TYPEFUNC_COMPOSITE)
175 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
176 errmsg(
"function returning record called in context "
177 "that cannot accept type record")));
178 funcctx->tuple_desc = tuple_desc;
179 MemoryContextSwitchTo(oldcontext);
182 funcctx = SRF_PERCALL_SETUP();
183 tuple_desc = funcctx->tuple_desc;
186 if (funcctx->call_cntr < funcctx->max_calls) {
192 size_t call_cntr = funcctx->call_cntr;
196 values =(Datum *)palloc(numb *
sizeof(Datum));
197 nulls = palloc(numb *
sizeof(
bool));
199 for (i = 0; i < numb; ++i) {
203 size_t contracted_vertices_size =
204 (size_t)result_tuples[call_cntr].contracted_vertices_size;
206 Datum* contracted_vertices_array;
207 contracted_vertices_array = (Datum*) palloc(
sizeof(Datum) *
208 (size_t)contracted_vertices_size);
210 for (i = 0; i < contracted_vertices_size; ++i) {
211 PGR_DBG(
"Storing contracted vertex %ld",
212 result_tuples[call_cntr].contracted_vertices[i]);
213 contracted_vertices_array[i] =
214 Int64GetDatum(result_tuples[call_cntr].contracted_vertices[i]);
219 get_typlenbyvalalign(INT8OID, &typlen, &typbyval, &typalign);
220 ArrayType* arrayType;
230 arrayType = construct_array(
231 contracted_vertices_array,
232 (
int)contracted_vertices_size,
233 INT8OID, typlen, typbyval, typalign);
244 TupleDescInitEntry(tuple_desc, (AttrNumber) 3,
"contracted_vertices",
247 values[0] = CStringGetTextDatum(result_tuples[call_cntr].type);
248 values[1] = Int64GetDatum(result_tuples[call_cntr].
id);
249 values[2] = PointerGetDatum(arrayType);
250 values[3] = Int64GetDatum(result_tuples[call_cntr].source);
251 values[4] = Int64GetDatum(result_tuples[call_cntr].target);
252 values[5] = Float8GetDatum(result_tuples[call_cntr].cost);
255 tuple = heap_form_tuple(tuple_desc, values, nulls);
256 result = HeapTupleGetDatum(tuple);
264 SRF_RETURN_NEXT(funcctx, result);
266 SRF_RETURN_DONE(funcctx);