• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

estebanzimanyi / MobilityDB / 10010939513

19 Jul 2024 04:04PM UTC coverage: 95.138% (-0.003%) from 95.141%
10010939513

push

github

estebanzimanyi
Finding memory leaks

2 of 2 new or added lines in 1 file covered. (100.0%)

1 existing line in 1 file now uncovered.

31878 of 33507 relevant lines covered (95.14%)

762816.14 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

94.94
/mobilitydb/src/general/span_aggfuncs.c
1
/*****************************************************************************
2
 *
3
 * This MobilityDB code is provided under The PostgreSQL License.
4
 * Copyright (c) 2016-2024, Université libre de Bruxelles and MobilityDB
5
 * contributors
6
 *
7
 * MobilityDB includes portions of PostGIS version 3 source code released
8
 * under the GNU General Public License (GPLv2 or later).
9
 * Copyright (c) 2001-2024, PostGIS contributors
10
 *
11
 * Permission to use, copy, modify, and distribute this software and its
12
 * documentation for any purpose, without fee, and without a written
13
 * agreement is hereby granted, provided that the above copyright notice and
14
 * this paragraph and the following two paragraphs appear in all copies.
15
 *
16
 * IN NO EVENT SHALL UNIVERSITE LIBRE DE BRUXELLES BE LIABLE TO ANY PARTY FOR
17
 * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, INCLUDING
18
 * LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION,
19
 * EVEN IF UNIVERSITE LIBRE DE BRUXELLES HAS BEEN ADVISED OF THE POSSIBILITY
20
 * OF SUCH DAMAGE.
21
 *
22
 * UNIVERSITE LIBRE DE BRUXELLES SPECIFICALLY DISCLAIMS ANY WARRANTIES,
23
 * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
24
 * AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS ON
25
 * AN "AS IS" BASIS, AND UNIVERSITE LIBRE DE BRUXELLES HAS NO OBLIGATIONS TO
26
 * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
27
 *
28
 *****************************************************************************/
29

30
/**
31
 * @file
32
 * @brief Aggregate function for span types
33
 */
34

35
/* C */
36
#include <assert.h>
37
/* PostgreSQL */
38
#include <postgres.h>
39
#include <fmgr.h>
40
#include <utils/array.h>
41
/* MEOS */
42
#include <meos.h>
43
#include <meos_internal.h>
44
#include "general/set.h"
45
#include "general/span.h"
46
#include "general/temporal.h"
47
/* MobilityDB */
48
#include "pg_general/meos_catalog.h"
49

50
/*****************************************************************************/
51

52
PGDLLEXPORT Datum Span_extent_transfn(PG_FUNCTION_ARGS);
53
PG_FUNCTION_INFO_V1(Span_extent_transfn);
15✔
54
/**
55
 * @ingroup mobilitydb_setspan_agg
56
 * @brief Transition function for extent aggregation of spans
57
 * @sqlfn extent()
58
 */
59
Datum
60
Span_extent_transfn(PG_FUNCTION_ARGS)
20,746✔
61
{
62
  Span *s1 = PG_ARGISNULL(0) ? NULL : PG_GETARG_SPAN_P(0);
20,746✔
63
  Span *s2 = PG_ARGISNULL(1) ? NULL : PG_GETARG_SPAN_P(1);
20,746✔
64
  Span *result = span_extent_transfn(s1, s2);
20,746✔
65
  if (! result)
20,746✔
66
    PG_RETURN_NULL();
249✔
67
  PG_RETURN_SPAN_P(result);
20,497✔
68
}
69

70
PGDLLEXPORT Datum Span_extent_combinefn(PG_FUNCTION_ARGS);
71
PG_FUNCTION_INFO_V1(Span_extent_combinefn);
8✔
72
/**
73
 * @ingroup mobilitydb_setspan_agg
74
 * @brief Combine function for extent aggregation of spans
75
 * @sqlfn extent()
76
 */
77
Datum
78
Span_extent_combinefn(PG_FUNCTION_ARGS)
31✔
79
{
80
  Span *s1 = PG_ARGISNULL(0) ? NULL : PG_GETARG_SPAN_P(0);
31✔
81
  Span *s2 = PG_ARGISNULL(1) ? NULL : PG_GETARG_SPAN_P(1);
31✔
82
  if (! s2 && ! s1)
31✔
83
    PG_RETURN_NULL();
×
84
  if (s1 && ! s2)
31✔
85
    PG_RETURN_SPAN_P(s1);
20✔
86
  if (s2 && ! s1)
11✔
87
    PG_RETURN_SPAN_P(s2);
11✔
88
  /* Non-strict union */
UNCOV
89
  PG_RETURN_SPAN_P(super_union_span_span(s1, s2));
×
90
}
91

92
/*****************************************************************************/
93

94
PGDLLEXPORT Datum Spanbase_extent_transfn(PG_FUNCTION_ARGS);
95
PG_FUNCTION_INFO_V1(Spanbase_extent_transfn);
9✔
96
/**
97
 * @ingroup mobilitydb_setspan_agg
98
 * @brief Transition function for extent aggregation of span base values
99
 * @sqlfn extent()
100
 */
101
Datum
102
Spanbase_extent_transfn(PG_FUNCTION_ARGS)
140✔
103
{
104
  if (PG_ARGISNULL(0) && PG_ARGISNULL(1))
140✔
105
    PG_RETURN_NULL();
40✔
106
  Span *s = PG_ARGISNULL(0) ? NULL : PG_GETARG_SPAN_P(0);
100✔
107
  if (PG_ARGISNULL(1))
100✔
108
    PG_RETURN_SPAN_P(s);
1✔
109
  Datum value = PG_GETARG_DATUM(1);
99✔
110
  meosType basetype = oid_type(get_fn_expr_argtype(fcinfo->flinfo, 1));
99✔
111
  PG_RETURN_SPAN_P(spanbase_extent_transfn(s, value, basetype));
99✔
112
}
113

114
PGDLLEXPORT Datum Set_extent_transfn(PG_FUNCTION_ARGS);
115
PG_FUNCTION_INFO_V1(Set_extent_transfn);
9✔
116
/**
117
 * @ingroup mobilitydb_setspan_agg
118
 * @brief Transition function for extent aggregation of sets
119
 * @sqlfn extent()
120
 */
121
Datum
122
Set_extent_transfn(PG_FUNCTION_ARGS)
146✔
123
{
124
  Span *span = PG_ARGISNULL(0) ? NULL : PG_GETARG_SPAN_P(0);
146✔
125
  Set *set = PG_ARGISNULL(1) ? NULL : PG_GETARG_SET_P(1);
146✔
126
  span = set_extent_transfn(span, set);
146✔
127
  PG_FREE_IF_COPY(set, 1);
146✔
128
  if (! span)
146✔
129
    PG_RETURN_NULL();
44✔
130
  PG_RETURN_SPAN_P(span);
102✔
131
}
132

133
PGDLLEXPORT Datum Spanset_extent_transfn(PG_FUNCTION_ARGS);
134
PG_FUNCTION_INFO_V1(Spanset_extent_transfn);
9✔
135
/**
136
 * @ingroup mobilitydb_setspan_agg
137
 * @brief Transition function for extent aggregation of span sets
138
 * @sqlfn extent()
139
 */
140
Datum
141
Spanset_extent_transfn(PG_FUNCTION_ARGS)
146✔
142
{
143
  Span *s = PG_ARGISNULL(0) ? NULL : PG_GETARG_SPAN_P(0);
146✔
144
  SpanSet *ss = PG_ARGISNULL(1) ? NULL : PG_GETARG_SPANSET_P(1);
146✔
145
  s = spanset_extent_transfn(s, ss);
146✔
146
  PG_FREE_IF_COPY(ss, 1);
146✔
147
  if (! s)
146✔
148
    PG_RETURN_NULL();
44✔
149
  PG_RETURN_SPAN_P(s);
102✔
150
}
151

152
/*****************************************************************************/
153

154
/*
155
 * The transition and combine functions for span_union are, respectively,
156
 * PostgreSQL's array_agg_transfn and array_agg_combinefn. Similarly, the
157
 * combine function for spanset_union is PostgreSQL's array_agg_combinefn.
158
 * The idea is that all the component spans are simply appened to an array
159
 * without any processing and thus are not sorted. The final function then
160
 * extract the spans, sort them, and performs the normalization.
161
 * Reusing PostgreSQL array function enables us to leverage parallel aggregates
162
 * (introduced in PostgreSQL version 16) and other built-in optimizations.
163
 */
164

165
PGDLLEXPORT Datum Spanset_union_transfn(PG_FUNCTION_ARGS);
166
PG_FUNCTION_INFO_V1(Spanset_union_transfn);
6✔
167
/**
168
 * @ingroup mobilitydb_setspan_agg
169
 * @brief Transition function for union aggregation of span sets
170
 * @note We simply gather the input values into an array so that the final
171
 * function can sort and combine them
172
 * @sqlfn union()
173
 */
174
Datum
175
Spanset_union_transfn(PG_FUNCTION_ARGS)
108✔
176
{
177
  MemoryContext aggContext;
178
  if (! AggCheckCallContext(fcinfo, &aggContext))
108✔
179
    elog(ERROR, "Spanset_union_transfn called in non-aggregate context");
×
180

181
  Oid spansetoid = get_fn_expr_argtype(fcinfo->flinfo, 1);
108✔
182
  meosType spansettype = oid_type(spansetoid);
108✔
183
  assert(spanset_type(spansettype));
184
  meosType spantype = spansettype_spantype(spansettype);
108✔
185
  Oid spanoid = type_oid(spantype);
108✔
186

187
  ArrayBuildState *state;
188
  if (PG_ARGISNULL(0))
108✔
189
    state = initArrayResult(spanoid, aggContext, false);
5✔
190
  else
191
    state = (ArrayBuildState *) PG_GETARG_POINTER(0);
103✔
192

193
  /* Skip NULLs */
194
  if (! PG_ARGISNULL(1))
108✔
195
  {
196
    SpanSet *ss = PG_GETARG_SPANSET_P(1);
103✔
197
    for (int i = 0; i < ss->count; i++)
586✔
198
      accumArrayResult(state, SpanPGetDatum(SPANSET_SP_N(ss, i)), false,
483✔
199
        spanoid, aggContext);
200
  }
201
  PG_RETURN_POINTER(state);
108✔
202
}
203

204
PGDLLEXPORT Datum Span_union_finalfn(PG_FUNCTION_ARGS);
205
PG_FUNCTION_INFO_V1(Span_union_finalfn);
6✔
206
/**
207
 * @ingroup mobilitydb_setspan_agg
208
 * @brief Final function for union aggregation of spans.
209
 * @note Shared for both spans and span sets
210
 * @sqlfn union()
211
 */
212
Datum
213
Span_union_finalfn(PG_FUNCTION_ARGS)
11✔
214
{
215
  /* cannot be called directly because of internal-type argument */
216
  Assert(AggCheckCallContext(fcinfo, NULL));
217
  // MemoryContext aggContext;
218
  // if (! AggCheckCallContext(fcinfo, &aggContext))
219
    // elog(ERROR, "Span_union_finalfn called in non-aggregate context");
220

221
  ArrayBuildState *state = PG_ARGISNULL(0) ? NULL :
11✔
222
    (ArrayBuildState *) PG_GETARG_POINTER(0);
11✔
223
  if (state == NULL)
11✔
224
    /* This shouldn't be possible, but just in case.... */
225
    PG_RETURN_NULL();
×
226

227
  /* Also return NULL if we had zero inputs, like other aggregates */
228
  int32 count = state->nelems;
11✔
229
  if (count == 0)
11✔
230
    PG_RETURN_NULL();
1✔
231

232
  Span *spans = palloc0(sizeof(Span) * count);
10✔
233
  int k = 0;
234
  for (int i = 0; i < count; i++)
10,601✔
235
  {
236
    if (! state->dnulls[i])
10,591✔
237
      spans[k++] = *(DatumGetSpanP(state->dvalues[i]));
10,186✔
238
  }
239

240
  /* Also return NULL if we had only null inputs */
241
  if (k == 0)
10✔
242
    PG_RETURN_NULL();
1✔
243

244
  PG_RETURN_SPANSET_P(spanset_make_free(spans, k, NORMALIZE, ORDER));
9✔
245
}
246

247
/*****************************************************************************/
248

STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc