LCOV - differential code coverage report
Current view: top level - contrib/ltree - _ltree_op.c (source / functions) Coverage Total Hit LBC UIC UBC GIC CBC EUB ECB
Current: Differential Code Coverage HEAD vs 15 Lines: 85.9 % 156 134 6 12 4 65 69 18 59
Current Date: 2023-04-08 15:15:32 Functions: 83.9 % 31 26 5 26 5 26
Baseline: 15
Baseline Date: 2023-04-08 15:09:40
Legend: Lines: hit not hit

           TLA  Line data    Source code
       1                 : /*
       2                 :  * contrib/ltree/_ltree_op.c
       3                 :  *
       4                 :  *
       5                 :  * op function for ltree[]
       6                 :  * Teodor Sigaev <teodor@stack.net>
       7                 :  */
       8                 : #include "postgres.h"
       9                 : 
      10                 : #include <ctype.h>
      11                 : 
      12                 : #include "ltree.h"
      13                 : #include "utils/array.h"
      14                 : 
      15 GIC           3 : PG_FUNCTION_INFO_V1(_ltree_isparent);
      16 CBC           2 : PG_FUNCTION_INFO_V1(_ltree_r_isparent);
      17               3 : PG_FUNCTION_INFO_V1(_ltree_risparent);
      18               2 : PG_FUNCTION_INFO_V1(_ltree_r_risparent);
      19               3 : PG_FUNCTION_INFO_V1(_ltq_regex);
      20               2 : PG_FUNCTION_INFO_V1(_ltq_rregex);
      21               3 : PG_FUNCTION_INFO_V1(_lt_q_regex);
      22               2 : PG_FUNCTION_INFO_V1(_lt_q_rregex);
      23               3 : PG_FUNCTION_INFO_V1(_ltxtq_exec);
      24               2 : PG_FUNCTION_INFO_V1(_ltxtq_rexec);
      25 ECB             : 
      26 GIC           3 : PG_FUNCTION_INFO_V1(_ltree_extract_isparent);
      27 CBC           3 : PG_FUNCTION_INFO_V1(_ltree_extract_risparent);
      28               3 : PG_FUNCTION_INFO_V1(_ltq_extract_regex);
      29               3 : PG_FUNCTION_INFO_V1(_ltxtq_extract_exec);
      30 ECB             : 
      31 GIC           3 : PG_FUNCTION_INFO_V1(_lca);
      32 ECB             : 
      33                 : typedef Datum (*PGCALL2) (PG_FUNCTION_ARGS);
      34                 : 
      35                 : #define NEXTVAL(x) ( (ltree*)( (char*)(x) + INTALIGN( VARSIZE(x) ) ) )
      36                 : 
      37                 : static bool
      38 GIC       20323 : array_iterator(ArrayType *la, PGCALL2 callback, void *param, ltree **found)
      39 ECB             : {
      40 GIC       20323 :     int         num = ArrayGetNItems(ARR_NDIM(la), ARR_DIMS(la));
      41 CBC       20323 :     ltree      *item = (ltree *) ARR_DATA_PTR(la);
      42 ECB             : 
      43 GIC       20323 :     if (ARR_NDIM(la) > 1)
      44 LBC           0 :         ereport(ERROR,
      45 EUB             :                 (errcode(ERRCODE_ARRAY_SUBSCRIPT_ERROR),
      46                 :                  errmsg("array must be one-dimensional")));
      47 GIC       20323 :     if (array_contains_nulls(la))
      48 LBC           0 :         ereport(ERROR,
      49 EUB             :                 (errcode(ERRCODE_NULL_VALUE_NOT_ALLOWED),
      50                 :                  errmsg("array must not contain nulls")));
      51                 : 
      52 GIC       20323 :     if (found)
      53 CBC           6 :         *found = NULL;
      54           91782 :     while (num > 0)
      55 ECB             :     {
      56 GIC       72507 :         if (DatumGetBool(DirectFunctionCall2(callback,
      57 ECB             :                                              PointerGetDatum(item), PointerGetDatum(param))))
      58                 :         {
      59                 : 
      60 GIC        1048 :             if (found)
      61 CBC           4 :                 *found = item;
      62            1048 :             return true;
      63 ECB             :         }
      64 GIC       71459 :         num--;
      65 CBC       71459 :         item = NEXTVAL(item);
      66 ECB             :     }
      67                 : 
      68 GIC       19275 :     return false;
      69 ECB             : }
      70                 : 
      71                 : Datum
      72 GIC        3012 : _ltree_isparent(PG_FUNCTION_ARGS)
      73 ECB             : {
      74 GIC        3012 :     ArrayType  *la = PG_GETARG_ARRAYTYPE_P(0);
      75 CBC        3012 :     ltree      *query = PG_GETARG_LTREE_P(1);
      76            3012 :     bool        res = array_iterator(la, ltree_isparent, (void *) query, NULL);
      77 ECB             : 
      78 GIC        3012 :     PG_FREE_IF_COPY(la, 0);
      79 CBC        3012 :     PG_FREE_IF_COPY(query, 1);
      80            3012 :     PG_RETURN_BOOL(res);
      81 ECB             : }
      82                 : 
      83                 : Datum
      84 UIC           0 : _ltree_r_isparent(PG_FUNCTION_ARGS)
      85 EUB             : {
      86 UIC           0 :     PG_RETURN_DATUM(DirectFunctionCall2(_ltree_isparent,
      87 EUB             :                                         PG_GETARG_DATUM(1),
      88                 :                                         PG_GETARG_DATUM(0)
      89                 :                                         ));
      90                 : }
      91                 : 
      92                 : Datum
      93 GIC        2310 : _ltree_risparent(PG_FUNCTION_ARGS)
      94 ECB             : {
      95 GIC        2310 :     ArrayType  *la = PG_GETARG_ARRAYTYPE_P(0);
      96 CBC        2310 :     ltree      *query = PG_GETARG_LTREE_P(1);
      97            2310 :     bool        res = array_iterator(la, ltree_risparent, (void *) query, NULL);
      98 ECB             : 
      99 GIC        2310 :     PG_FREE_IF_COPY(la, 0);
     100 CBC        2310 :     PG_FREE_IF_COPY(query, 1);
     101            2310 :     PG_RETURN_BOOL(res);
     102 ECB             : }
     103                 : 
     104                 : Datum
     105 UIC           0 : _ltree_r_risparent(PG_FUNCTION_ARGS)
     106 EUB             : {
     107 UIC           0 :     PG_RETURN_DATUM(DirectFunctionCall2(_ltree_risparent,
     108 EUB             :                                         PG_GETARG_DATUM(1),
     109                 :                                         PG_GETARG_DATUM(0)
     110                 :                                         ));
     111                 : }
     112                 : 
     113                 : Datum
     114 GIC        9575 : _ltq_regex(PG_FUNCTION_ARGS)
     115 ECB             : {
     116 GIC        9575 :     ArrayType  *la = PG_GETARG_ARRAYTYPE_P(0);
     117 CBC        9575 :     lquery     *query = PG_GETARG_LQUERY_P(1);
     118            9575 :     bool        res = array_iterator(la, ltq_regex, (void *) query, NULL);
     119 ECB             : 
     120 GIC        9575 :     PG_FREE_IF_COPY(la, 0);
     121 CBC        9575 :     PG_FREE_IF_COPY(query, 1);
     122            9575 :     PG_RETURN_BOOL(res);
     123 ECB             : }
     124                 : 
     125                 : Datum
     126 UIC           0 : _ltq_rregex(PG_FUNCTION_ARGS)
     127 EUB             : {
     128 UIC           0 :     PG_RETURN_DATUM(DirectFunctionCall2(_ltq_regex,
     129 EUB             :                                         PG_GETARG_DATUM(1),
     130                 :                                         PG_GETARG_DATUM(0)
     131                 :                                         ));
     132                 : }
     133                 : 
     134                 : Datum
     135 GIC        1868 : _lt_q_regex(PG_FUNCTION_ARGS)
     136 ECB             : {
     137 GIC        1868 :     ArrayType  *_tree = PG_GETARG_ARRAYTYPE_P(0);
     138 CBC        1868 :     ArrayType  *_query = PG_GETARG_ARRAYTYPE_P(1);
     139            1868 :     lquery     *query = (lquery *) ARR_DATA_PTR(_query);
     140            1868 :     bool        res = false;
     141            1868 :     int         num = ArrayGetNItems(ARR_NDIM(_query), ARR_DIMS(_query));
     142 ECB             : 
     143 GIC        1868 :     if (ARR_NDIM(_query) > 1)
     144 LBC           0 :         ereport(ERROR,
     145 EUB             :                 (errcode(ERRCODE_ARRAY_SUBSCRIPT_ERROR),
     146                 :                  errmsg("array must be one-dimensional")));
     147 GIC        1868 :     if (array_contains_nulls(_query))
     148 LBC           0 :         ereport(ERROR,
     149 EUB             :                 (errcode(ERRCODE_NULL_VALUE_NOT_ALLOWED),
     150                 :                  errmsg("array must not contain nulls")));
     151                 : 
     152 GIC        5524 :     while (num > 0)
     153 ECB             :     {
     154 GIC        3702 :         if (array_iterator(_tree, ltq_regex, (void *) query, NULL))
     155 ECB             :         {
     156 GIC          46 :             res = true;
     157 CBC          46 :             break;
     158 ECB             :         }
     159 GIC        3656 :         num--;
     160 CBC        3656 :         query = (lquery *) NEXTVAL(query);
     161 ECB             :     }
     162                 : 
     163 GIC        1868 :     PG_FREE_IF_COPY(_tree, 0);
     164 CBC        1868 :     PG_FREE_IF_COPY(_query, 1);
     165            1868 :     PG_RETURN_BOOL(res);
     166 ECB             : }
     167                 : 
     168                 : Datum
     169 UIC           0 : _lt_q_rregex(PG_FUNCTION_ARGS)
     170 EUB             : {
     171 UIC           0 :     PG_RETURN_DATUM(DirectFunctionCall2(_lt_q_regex,
     172 EUB             :                                         PG_GETARG_DATUM(1),
     173                 :                                         PG_GETARG_DATUM(0)
     174                 :                                         ));
     175                 : }
     176                 : 
     177                 : 
     178                 : Datum
     179 GIC        1718 : _ltxtq_exec(PG_FUNCTION_ARGS)
     180 ECB             : {
     181 GIC        1718 :     ArrayType  *la = PG_GETARG_ARRAYTYPE_P(0);
     182 CBC        1718 :     ltxtquery  *query = PG_GETARG_LTXTQUERY_P(1);
     183            1718 :     bool        res = array_iterator(la, ltxtq_exec, (void *) query, NULL);
     184 ECB             : 
     185 GIC        1718 :     PG_FREE_IF_COPY(la, 0);
     186 CBC        1718 :     PG_FREE_IF_COPY(query, 1);
     187            1718 :     PG_RETURN_BOOL(res);
     188 ECB             : }
     189                 : 
     190                 : Datum
     191 UIC           0 : _ltxtq_rexec(PG_FUNCTION_ARGS)
     192 EUB             : {
     193 UIC           0 :     PG_RETURN_DATUM(DirectFunctionCall2(_ltxtq_exec,
     194 EUB             :                                         PG_GETARG_DATUM(1),
     195                 :                                         PG_GETARG_DATUM(0)
     196                 :                                         ));
     197                 : }
     198                 : 
     199                 : 
     200                 : Datum
     201 GIC           2 : _ltree_extract_isparent(PG_FUNCTION_ARGS)
     202 ECB             : {
     203 GIC           2 :     ArrayType  *la = PG_GETARG_ARRAYTYPE_P(0);
     204 CBC           2 :     ltree      *query = PG_GETARG_LTREE_P(1);
     205 ECB             :     ltree      *found,
     206                 :                *item;
     207                 : 
     208 GIC           2 :     if (!array_iterator(la, ltree_isparent, (void *) query, &found))
     209 ECB             :     {
     210 GIC           1 :         PG_FREE_IF_COPY(la, 0);
     211 CBC           1 :         PG_FREE_IF_COPY(query, 1);
     212               1 :         PG_RETURN_NULL();
     213 ECB             :     }
     214                 : 
     215 GIC           1 :     item = (ltree *) palloc0(VARSIZE(found));
     216 CBC           1 :     memcpy(item, found, VARSIZE(found));
     217 ECB             : 
     218 GIC           1 :     PG_FREE_IF_COPY(la, 0);
     219 CBC           1 :     PG_FREE_IF_COPY(query, 1);
     220               1 :     PG_RETURN_POINTER(item);
     221 ECB             : }
     222                 : 
     223                 : Datum
     224 GIC           2 : _ltree_extract_risparent(PG_FUNCTION_ARGS)
     225 ECB             : {
     226 GIC           2 :     ArrayType  *la = PG_GETARG_ARRAYTYPE_P(0);
     227 CBC           2 :     ltree      *query = PG_GETARG_LTREE_P(1);
     228 ECB             :     ltree      *found,
     229                 :                *item;
     230                 : 
     231 GIC           2 :     if (!array_iterator(la, ltree_risparent, (void *) query, &found))
     232 ECB             :     {
     233 GIC           1 :         PG_FREE_IF_COPY(la, 0);
     234 CBC           1 :         PG_FREE_IF_COPY(query, 1);
     235               1 :         PG_RETURN_NULL();
     236 ECB             :     }
     237                 : 
     238 GIC           1 :     item = (ltree *) palloc0(VARSIZE(found));
     239 CBC           1 :     memcpy(item, found, VARSIZE(found));
     240 ECB             : 
     241 GIC           1 :     PG_FREE_IF_COPY(la, 0);
     242 CBC           1 :     PG_FREE_IF_COPY(query, 1);
     243               1 :     PG_RETURN_POINTER(item);
     244 ECB             : }
     245                 : 
     246                 : Datum
     247 GIC           1 : _ltq_extract_regex(PG_FUNCTION_ARGS)
     248 ECB             : {
     249 GIC           1 :     ArrayType  *la = PG_GETARG_ARRAYTYPE_P(0);
     250 CBC           1 :     lquery     *query = PG_GETARG_LQUERY_P(1);
     251 ECB             :     ltree      *found,
     252                 :                *item;
     253                 : 
     254 GIC           1 :     if (!array_iterator(la, ltq_regex, (void *) query, &found))
     255 ECB             :     {
     256 UIC           0 :         PG_FREE_IF_COPY(la, 0);
     257 UBC           0 :         PG_FREE_IF_COPY(query, 1);
     258               0 :         PG_RETURN_NULL();
     259 EUB             :     }
     260                 : 
     261 GIC           1 :     item = (ltree *) palloc0(VARSIZE(found));
     262 CBC           1 :     memcpy(item, found, VARSIZE(found));
     263 ECB             : 
     264 GIC           1 :     PG_FREE_IF_COPY(la, 0);
     265 CBC           1 :     PG_FREE_IF_COPY(query, 1);
     266               1 :     PG_RETURN_POINTER(item);
     267 ECB             : }
     268                 : 
     269                 : Datum
     270 GIC           1 : _ltxtq_extract_exec(PG_FUNCTION_ARGS)
     271 ECB             : {
     272 GIC           1 :     ArrayType  *la = PG_GETARG_ARRAYTYPE_P(0);
     273 CBC           1 :     ltxtquery  *query = PG_GETARG_LTXTQUERY_P(1);
     274 ECB             :     ltree      *found,
     275                 :                *item;
     276                 : 
     277 GIC           1 :     if (!array_iterator(la, ltxtq_exec, (void *) query, &found))
     278 ECB             :     {
     279 UIC           0 :         PG_FREE_IF_COPY(la, 0);
     280 UBC           0 :         PG_FREE_IF_COPY(query, 1);
     281               0 :         PG_RETURN_NULL();
     282 EUB             :     }
     283                 : 
     284 GIC           1 :     item = (ltree *) palloc0(VARSIZE(found));
     285 CBC           1 :     memcpy(item, found, VARSIZE(found));
     286 ECB             : 
     287 GIC           1 :     PG_FREE_IF_COPY(la, 0);
     288 CBC           1 :     PG_FREE_IF_COPY(query, 1);
     289               1 :     PG_RETURN_POINTER(item);
     290 ECB             : }
     291                 : 
     292                 : Datum
     293 GIC           8 : _lca(PG_FUNCTION_ARGS)
     294 ECB             : {
     295 GIC           8 :     ArrayType  *la = PG_GETARG_ARRAYTYPE_P(0);
     296 CBC           8 :     int         num = ArrayGetNItems(ARR_NDIM(la), ARR_DIMS(la));
     297               8 :     ltree      *item = (ltree *) ARR_DATA_PTR(la);
     298 ECB             :     ltree     **a,
     299                 :                *res;
     300                 : 
     301 GIC           8 :     if (ARR_NDIM(la) > 1)
     302 LBC           0 :         ereport(ERROR,
     303 EUB             :                 (errcode(ERRCODE_ARRAY_SUBSCRIPT_ERROR),
     304                 :                  errmsg("array must be one-dimensional")));
     305 GIC           8 :     if (array_contains_nulls(la))
     306 LBC           0 :         ereport(ERROR,
     307 EUB             :                 (errcode(ERRCODE_NULL_VALUE_NOT_ALLOWED),
     308                 :                  errmsg("array must not contain nulls")));
     309                 : 
     310 GIC           8 :     a = (ltree **) palloc(sizeof(ltree *) * num);
     311 CBC          20 :     while (num > 0)
     312 ECB             :     {
     313 GIC          12 :         num--;
     314 CBC          12 :         a[num] = item;
     315              12 :         item = NEXTVAL(item);
     316 ECB             :     }
     317 GIC           8 :     res = lca_inner(a, ArrayGetNItems(ARR_NDIM(la), ARR_DIMS(la)));
     318 CBC           8 :     pfree(a);
     319 ECB             : 
     320 GIC           8 :     PG_FREE_IF_COPY(la, 0);
     321 ECB             : 
     322 GIC           8 :     if (res)
     323 CBC           6 :         PG_RETURN_POINTER(res);
     324 ECB             :     else
     325 GIC           2 :         PG_RETURN_NULL();
     326 ECB             : }
        

Generated by: LCOV version v1.16-55-g56c0a2a