LCOV - code coverage report
Current view: top level - contrib/ltree - _ltree_op.c (source / functions) Hit Total Coverage
Test: PostgreSQL 11devel Lines: 134 156 85.9 %
Date: 2017-11-22 12:18:04 Functions: 26 31 83.9 %
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 69 118 58.5 %

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

Generated by: LCOV version 1.13