LCOV - code coverage report
Current view: top level - contrib/intarray - _int_op.c (source / functions) Coverage Total Hit
Test: PostgreSQL 20devel Lines: 85.8 % 240 206
Test Date: 2026-07-08 05:15:38 Functions: 95.1 % 41 39
Legend: Lines:     hit not hit
Branches: + taken - not taken # not executed
Branches: 37.1 % 278 103

             Branch data     Line data    Source code
       1                 :             : /*
       2                 :             :  * contrib/intarray/_int_op.c
       3                 :             :  */
       4                 :             : #include "postgres.h"
       5                 :             : 
       6                 :             : #include "_int.h"
       7                 :             : 
       8                 :           1 : PG_MODULE_MAGIC_EXT(
       9                 :             :                     .name = "intarray",
      10                 :             :                     .version = PG_VERSION
      11                 :             : );
      12                 :             : 
      13                 :           1 : PG_FUNCTION_INFO_V1(_int_different);
      14                 :           1 : PG_FUNCTION_INFO_V1(_int_same);
      15                 :           2 : PG_FUNCTION_INFO_V1(_int_contains);
      16                 :           2 : PG_FUNCTION_INFO_V1(_int_contained);
      17                 :           2 : PG_FUNCTION_INFO_V1(_int_overlap);
      18                 :           2 : PG_FUNCTION_INFO_V1(_int_union);
      19                 :           2 : PG_FUNCTION_INFO_V1(_int_inter);
      20                 :             : 
      21                 :             : Datum
      22                 :       41160 : _int_contained(PG_FUNCTION_ARGS)
      23                 :             : {
      24                 :             :     /* just reverse the operands and call _int_contains */
      25                 :       41160 :     return DirectFunctionCall2(_int_contains,
      26                 :             :                                PG_GETARG_DATUM(1),
      27                 :             :                                PG_GETARG_DATUM(0));
      28                 :             : }
      29                 :             : 
      30                 :             : Datum
      31                 :       68284 : _int_contains(PG_FUNCTION_ARGS)
      32                 :             : {
      33                 :             :     /* Force copy so we can modify the arrays in-place */
      34                 :       68284 :     ArrayType  *a = PG_GETARG_ARRAYTYPE_P_COPY(0);
      35                 :       68284 :     ArrayType  *b = PG_GETARG_ARRAYTYPE_P_COPY(1);
      36                 :             :     bool        res;
      37                 :             : 
      38   [ -  +  -  -  :       68284 :     CHECKARRVALID(a);
                   -  - ]
      39   [ -  +  -  -  :       68284 :     CHECKARRVALID(b);
                   -  - ]
      40         [ -  + ]:       68284 :     PREPAREARR(a);
      41         [ -  + ]:       68284 :     PREPAREARR(b);
      42                 :       68284 :     res = inner_int_contains(a, b);
      43                 :       68284 :     pfree(a);
      44                 :       68284 :     pfree(b);
      45                 :       68284 :     PG_RETURN_BOOL(res);
      46                 :             : }
      47                 :             : 
      48                 :             : Datum
      49                 :           0 : _int_different(PG_FUNCTION_ARGS)
      50                 :             : {
      51                 :           0 :     PG_RETURN_BOOL(!DatumGetBool(DirectFunctionCall2(_int_same,
      52                 :             :                                                      PointerGetDatum(PG_GETARG_POINTER(0)),
      53                 :             :                                                      PointerGetDatum(PG_GETARG_POINTER(1)))));
      54                 :             : }
      55                 :             : 
      56                 :             : Datum
      57                 :           0 : _int_same(PG_FUNCTION_ARGS)
      58                 :             : {
      59                 :           0 :     ArrayType  *a = PG_GETARG_ARRAYTYPE_P_COPY(0);
      60                 :           0 :     ArrayType  *b = PG_GETARG_ARRAYTYPE_P_COPY(1);
      61                 :             :     int         na,
      62                 :             :                 nb;
      63                 :             :     int         n;
      64                 :             :     int        *da,
      65                 :             :                *db;
      66                 :             :     bool        result;
      67                 :             : 
      68   [ #  #  #  #  :           0 :     CHECKARRVALID(a);
                   #  # ]
      69   [ #  #  #  #  :           0 :     CHECKARRVALID(b);
                   #  # ]
      70                 :           0 :     na = ARRNELEMS(a);
      71                 :           0 :     nb = ARRNELEMS(b);
      72         [ #  # ]:           0 :     da = ARRPTR(a);
      73         [ #  # ]:           0 :     db = ARRPTR(b);
      74                 :             : 
      75                 :           0 :     result = false;
      76                 :             : 
      77         [ #  # ]:           0 :     if (na == nb)
      78                 :             :     {
      79         [ #  # ]:           0 :         SORT(a);
      80         [ #  # ]:           0 :         SORT(b);
      81                 :           0 :         result = true;
      82                 :             : 
      83         [ #  # ]:           0 :         for (n = 0; n < na; n++)
      84                 :             :         {
      85         [ #  # ]:           0 :             if (da[n] != db[n])
      86                 :             :             {
      87                 :           0 :                 result = false;
      88                 :           0 :                 break;
      89                 :             :             }
      90                 :             :         }
      91                 :             :     }
      92                 :             : 
      93                 :           0 :     pfree(a);
      94                 :           0 :     pfree(b);
      95                 :             : 
      96                 :           0 :     PG_RETURN_BOOL(result);
      97                 :             : }
      98                 :             : 
      99                 :             : /*
     100                 :             :  * _int_overlap -- does a overlap b?
     101                 :             :  */
     102                 :             : Datum
     103                 :        7563 : _int_overlap(PG_FUNCTION_ARGS)
     104                 :             : {
     105                 :        7563 :     ArrayType  *a = PG_GETARG_ARRAYTYPE_P_COPY(0);
     106                 :        7563 :     ArrayType  *b = PG_GETARG_ARRAYTYPE_P_COPY(1);
     107                 :             :     bool        result;
     108                 :             : 
     109   [ -  +  -  -  :        7563 :     CHECKARRVALID(a);
                   -  - ]
     110   [ -  +  -  -  :        7563 :     CHECKARRVALID(b);
                   -  - ]
     111   [ +  +  -  + ]:        7563 :     if (ARRISEMPTY(a) || ARRISEMPTY(b))
     112                 :           9 :         PG_RETURN_BOOL(false);
     113                 :             : 
     114         [ -  + ]:        7554 :     SORT(a);
     115         [ -  + ]:        7554 :     SORT(b);
     116                 :             : 
     117                 :        7554 :     result = inner_int_overlap(a, b);
     118                 :             : 
     119                 :        7554 :     pfree(a);
     120                 :        7554 :     pfree(b);
     121                 :             : 
     122                 :        7554 :     PG_RETURN_BOOL(result);
     123                 :             : }
     124                 :             : 
     125                 :             : Datum
     126                 :           1 : _int_union(PG_FUNCTION_ARGS)
     127                 :             : {
     128                 :           1 :     ArrayType  *a = PG_GETARG_ARRAYTYPE_P_COPY(0);
     129                 :           1 :     ArrayType  *b = PG_GETARG_ARRAYTYPE_P_COPY(1);
     130                 :             :     ArrayType  *result;
     131                 :             : 
     132   [ -  +  -  -  :           1 :     CHECKARRVALID(a);
                   -  - ]
     133   [ -  +  -  -  :           1 :     CHECKARRVALID(b);
                   -  - ]
     134                 :             : 
     135         [ -  + ]:           1 :     SORT(a);
     136         [ -  + ]:           1 :     SORT(b);
     137                 :             : 
     138                 :           1 :     result = inner_int_union(a, b);
     139                 :             : 
     140                 :           1 :     pfree(a);
     141                 :           1 :     pfree(b);
     142                 :             : 
     143                 :           1 :     PG_RETURN_POINTER(result);
     144                 :             : }
     145                 :             : 
     146                 :             : Datum
     147                 :           6 : _int_inter(PG_FUNCTION_ARGS)
     148                 :             : {
     149                 :           6 :     ArrayType  *a = PG_GETARG_ARRAYTYPE_P_COPY(0);
     150                 :           6 :     ArrayType  *b = PG_GETARG_ARRAYTYPE_P_COPY(1);
     151                 :             :     ArrayType  *result;
     152                 :             : 
     153   [ -  +  -  -  :           6 :     CHECKARRVALID(a);
                   -  - ]
     154   [ -  +  -  -  :           6 :     CHECKARRVALID(b);
                   -  - ]
     155                 :             : 
     156         [ -  + ]:           6 :     SORT(a);
     157         [ -  + ]:           6 :     SORT(b);
     158                 :             : 
     159                 :           6 :     result = inner_int_inter(a, b);
     160                 :             : 
     161                 :           6 :     pfree(a);
     162                 :           6 :     pfree(b);
     163                 :             : 
     164                 :           6 :     PG_RETURN_POINTER(result);
     165                 :             : }
     166                 :             : 
     167                 :             : 
     168                 :           2 : PG_FUNCTION_INFO_V1(intset);
     169                 :           2 : PG_FUNCTION_INFO_V1(icount);
     170                 :           4 : PG_FUNCTION_INFO_V1(sort);
     171                 :           2 : PG_FUNCTION_INFO_V1(sort_asc);
     172                 :           2 : PG_FUNCTION_INFO_V1(sort_desc);
     173                 :           2 : PG_FUNCTION_INFO_V1(uniq);
     174                 :           2 : PG_FUNCTION_INFO_V1(idx);
     175                 :           3 : PG_FUNCTION_INFO_V1(subarray);
     176                 :           2 : PG_FUNCTION_INFO_V1(intarray_push_elem);
     177                 :           2 : PG_FUNCTION_INFO_V1(intarray_push_array);
     178                 :           2 : PG_FUNCTION_INFO_V1(intarray_del_elem);
     179                 :           2 : PG_FUNCTION_INFO_V1(intset_union_elem);
     180                 :           2 : PG_FUNCTION_INFO_V1(intset_subtract);
     181                 :             : 
     182                 :             : Datum
     183                 :           1 : intset(PG_FUNCTION_ARGS)
     184                 :             : {
     185                 :           1 :     PG_RETURN_POINTER(int_to_intset(PG_GETARG_INT32(0)));
     186                 :             : }
     187                 :             : 
     188                 :             : Datum
     189                 :           2 : icount(PG_FUNCTION_ARGS)
     190                 :             : {
     191                 :           2 :     ArrayType  *a = PG_GETARG_ARRAYTYPE_P(0);
     192                 :           2 :     int32       count = ARRNELEMS(a);
     193                 :             : 
     194         [ -  + ]:           2 :     PG_FREE_IF_COPY(a, 0);
     195                 :           2 :     PG_RETURN_INT32(count);
     196                 :             : }
     197                 :             : 
     198                 :             : Datum
     199                 :           3 : sort(PG_FUNCTION_ARGS)
     200                 :             : {
     201                 :           3 :     ArrayType  *a = PG_GETARG_ARRAYTYPE_P_COPY(0);
     202         [ +  + ]:           3 :     text       *dirstr = (fcinfo->nargs == 2) ? PG_GETARG_TEXT_PP(1) : NULL;
     203         [ +  + ]:           3 :     int32       dc = (dirstr) ? VARSIZE_ANY_EXHDR(dirstr) : 0;
     204         [ +  + ]:           3 :     char       *d = (dirstr) ? VARDATA_ANY(dirstr) : NULL;
     205                 :           3 :     int         dir = -1;
     206                 :             : 
     207   [ -  +  -  -  :           3 :     CHECKARRVALID(a);
                   -  - ]
     208         [ -  + ]:           3 :     if (ARRNELEMS(a) < 2)
     209                 :           0 :         PG_RETURN_POINTER(a);
     210                 :             : 
     211   [ +  +  +  + ]:           3 :     if (dirstr == NULL || (dc == 3
     212   [ +  -  +  - ]:           1 :                            && (d[0] == 'A' || d[0] == 'a')
     213   [ +  -  +  - ]:           1 :                            && (d[1] == 'S' || d[1] == 's')
     214   [ +  -  +  - ]:           1 :                            && (d[2] == 'C' || d[2] == 'c')))
     215                 :           2 :         dir = 1;
     216         [ +  - ]:           1 :     else if (dc == 4
     217   [ +  -  +  - ]:           1 :              && (d[0] == 'D' || d[0] == 'd')
     218   [ +  -  +  - ]:           1 :              && (d[1] == 'E' || d[1] == 'e')
     219   [ +  -  +  - ]:           1 :              && (d[2] == 'S' || d[2] == 's')
     220   [ +  -  +  - ]:           1 :              && (d[3] == 'C' || d[3] == 'c'))
     221                 :           1 :         dir = 0;
     222         [ -  + ]:           3 :     if (dir == -1)
     223         [ #  # ]:           0 :         ereport(ERROR,
     224                 :             :                 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
     225                 :             :                  errmsg("second parameter must be \"ASC\" or \"DESC\"")));
     226         [ -  + ]:           3 :     QSORT(a, dir);
     227                 :           3 :     PG_RETURN_POINTER(a);
     228                 :             : }
     229                 :             : 
     230                 :             : Datum
     231                 :           2 : sort_asc(PG_FUNCTION_ARGS)
     232                 :             : {
     233                 :           2 :     ArrayType  *a = PG_GETARG_ARRAYTYPE_P_COPY(0);
     234                 :             : 
     235   [ -  +  -  -  :           2 :     CHECKARRVALID(a);
                   -  - ]
     236         [ -  + ]:           2 :     QSORT(a, 1);
     237                 :           2 :     PG_RETURN_POINTER(a);
     238                 :             : }
     239                 :             : 
     240                 :             : Datum
     241                 :           1 : sort_desc(PG_FUNCTION_ARGS)
     242                 :             : {
     243                 :           1 :     ArrayType  *a = PG_GETARG_ARRAYTYPE_P_COPY(0);
     244                 :             : 
     245   [ -  +  -  -  :           1 :     CHECKARRVALID(a);
                   -  - ]
     246         [ -  + ]:           1 :     QSORT(a, 0);
     247                 :           1 :     PG_RETURN_POINTER(a);
     248                 :             : }
     249                 :             : 
     250                 :             : Datum
     251                 :           2 : uniq(PG_FUNCTION_ARGS)
     252                 :             : {
     253                 :           2 :     ArrayType  *a = PG_GETARG_ARRAYTYPE_P_COPY(0);
     254                 :             : 
     255   [ -  +  -  -  :           2 :     CHECKARRVALID(a);
                   -  - ]
     256         [ -  + ]:           2 :     if (ARRNELEMS(a) < 2)
     257                 :           0 :         PG_RETURN_POINTER(a);
     258                 :           2 :     a = _int_unique(a);
     259                 :           2 :     PG_RETURN_POINTER(a);
     260                 :             : }
     261                 :             : 
     262                 :             : Datum
     263                 :           1 : idx(PG_FUNCTION_ARGS)
     264                 :             : {
     265                 :           1 :     ArrayType  *a = PG_GETARG_ARRAYTYPE_P(0);
     266                 :             :     int32       result;
     267                 :             : 
     268   [ -  +  -  -  :           1 :     CHECKARRVALID(a);
                   -  - ]
     269                 :           1 :     result = ARRNELEMS(a);
     270         [ +  - ]:           1 :     if (result)
     271                 :           1 :         result = intarray_match_first(a, PG_GETARG_INT32(1));
     272         [ -  + ]:           1 :     PG_FREE_IF_COPY(a, 0);
     273                 :           1 :     PG_RETURN_INT32(result);
     274                 :             : }
     275                 :             : 
     276                 :             : Datum
     277                 :           3 : subarray(PG_FUNCTION_ARGS)
     278                 :             : {
     279                 :           3 :     ArrayType  *a = PG_GETARG_ARRAYTYPE_P(0);
     280                 :           3 :     int32       start = PG_GETARG_INT32(1);
     281         [ +  - ]:           3 :     int32       len = (fcinfo->nargs == 3) ? PG_GETARG_INT32(2) : 0;
     282                 :           3 :     int32       end = 0;
     283                 :             :     int32       c;
     284                 :             :     ArrayType  *result;
     285                 :             : 
     286         [ +  + ]:           3 :     start = (start > 0) ? start - 1 : start;
     287                 :             : 
     288   [ -  +  -  -  :           3 :     CHECKARRVALID(a);
                   -  - ]
     289         [ -  + ]:           3 :     if (ARRISEMPTY(a))
     290                 :             :     {
     291         [ #  # ]:           0 :         PG_FREE_IF_COPY(a, 0);
     292                 :           0 :         PG_RETURN_POINTER(new_intArrayType(0));
     293                 :             :     }
     294                 :             : 
     295                 :           3 :     c = ARRNELEMS(a);
     296                 :             : 
     297         [ +  + ]:           3 :     if (start < 0)
     298                 :           1 :         start = c + start;
     299                 :             : 
     300         [ +  + ]:           3 :     if (len < 0)
     301                 :           1 :         end = c + len;
     302         [ -  + ]:           2 :     else if (len == 0)
     303                 :           0 :         end = c;
     304                 :             :     else
     305                 :           2 :         end = start + len;
     306                 :             : 
     307         [ -  + ]:           3 :     if (end > c)
     308                 :           0 :         end = c;
     309                 :             : 
     310         [ -  + ]:           3 :     if (start < 0)
     311                 :           0 :         start = 0;
     312                 :             : 
     313   [ +  -  -  + ]:           3 :     if (start >= end || end <= 0)
     314                 :             :     {
     315         [ #  # ]:           0 :         PG_FREE_IF_COPY(a, 0);
     316                 :           0 :         PG_RETURN_POINTER(new_intArrayType(0));
     317                 :             :     }
     318                 :             : 
     319                 :           3 :     result = new_intArrayType(end - start);
     320         [ +  - ]:           3 :     if (end - start > 0)
     321   [ -  +  -  + ]:           3 :         memcpy(ARRPTR(result), ARRPTR(a) + start, (end - start) * sizeof(int32));
     322         [ -  + ]:           3 :     PG_FREE_IF_COPY(a, 0);
     323                 :           3 :     PG_RETURN_POINTER(result);
     324                 :             : }
     325                 :             : 
     326                 :             : Datum
     327                 :           2 : intarray_push_elem(PG_FUNCTION_ARGS)
     328                 :             : {
     329                 :           2 :     ArrayType  *a = PG_GETARG_ARRAYTYPE_P(0);
     330                 :             :     ArrayType  *result;
     331                 :             : 
     332                 :           2 :     result = intarray_add_elem(a, PG_GETARG_INT32(1));
     333         [ -  + ]:           2 :     PG_FREE_IF_COPY(a, 0);
     334                 :           2 :     PG_RETURN_POINTER(result);
     335                 :             : }
     336                 :             : 
     337                 :             : Datum
     338                 :           1 : intarray_push_array(PG_FUNCTION_ARGS)
     339                 :             : {
     340                 :           1 :     ArrayType  *a = PG_GETARG_ARRAYTYPE_P(0);
     341                 :           1 :     ArrayType  *b = PG_GETARG_ARRAYTYPE_P(1);
     342                 :             :     ArrayType  *result;
     343                 :             : 
     344                 :           1 :     result = intarray_concat_arrays(a, b);
     345         [ -  + ]:           1 :     PG_FREE_IF_COPY(a, 0);
     346         [ -  + ]:           1 :     PG_FREE_IF_COPY(b, 1);
     347                 :           1 :     PG_RETURN_POINTER(result);
     348                 :             : }
     349                 :             : 
     350                 :             : Datum
     351                 :           1 : intarray_del_elem(PG_FUNCTION_ARGS)
     352                 :             : {
     353                 :           1 :     ArrayType  *a = PG_GETARG_ARRAYTYPE_P_COPY(0);
     354                 :           1 :     int32       elem = PG_GETARG_INT32(1);
     355                 :             :     int32       c;
     356                 :             :     int32      *aa;
     357                 :           1 :     int32       n = 0,
     358                 :             :                 i;
     359                 :             : 
     360   [ -  +  -  -  :           1 :     CHECKARRVALID(a);
                   -  - ]
     361         [ +  - ]:           1 :     if (!ARRISEMPTY(a))
     362                 :             :     {
     363                 :           1 :         c = ARRNELEMS(a);
     364         [ -  + ]:           1 :         aa = ARRPTR(a);
     365         [ +  + ]:           4 :         for (i = 0; i < c; i++)
     366                 :             :         {
     367         [ +  + ]:           3 :             if (aa[i] != elem)
     368                 :             :             {
     369         [ +  + ]:           2 :                 if (i > n)
     370                 :           1 :                     aa[n++] = aa[i];
     371                 :             :                 else
     372                 :           1 :                     n++;
     373                 :             :             }
     374                 :             :         }
     375                 :           1 :         a = resize_intArrayType(a, n);
     376                 :             :     }
     377                 :           1 :     PG_RETURN_POINTER(a);
     378                 :             : }
     379                 :             : 
     380                 :             : Datum
     381                 :           2 : intset_union_elem(PG_FUNCTION_ARGS)
     382                 :             : {
     383                 :           2 :     ArrayType  *a = PG_GETARG_ARRAYTYPE_P(0);
     384                 :             :     ArrayType  *result;
     385                 :             : 
     386                 :           2 :     result = intarray_add_elem(a, PG_GETARG_INT32(1));
     387         [ -  + ]:           2 :     PG_FREE_IF_COPY(a, 0);
     388         [ -  + ]:           2 :     QSORT(result, 1);
     389                 :           2 :     PG_RETURN_POINTER(_int_unique(result));
     390                 :             : }
     391                 :             : 
     392                 :             : Datum
     393                 :           1 : intset_subtract(PG_FUNCTION_ARGS)
     394                 :             : {
     395                 :           1 :     ArrayType  *a = PG_GETARG_ARRAYTYPE_P_COPY(0);
     396                 :           1 :     ArrayType  *b = PG_GETARG_ARRAYTYPE_P_COPY(1);
     397                 :             :     ArrayType  *result;
     398                 :             :     int32       ca;
     399                 :             :     int32       cb;
     400                 :             :     int32      *aa,
     401                 :             :                *bb,
     402                 :             :                *r;
     403                 :           1 :     int32       n = 0,
     404                 :           1 :                 i = 0,
     405                 :           1 :                 k = 0;
     406                 :             : 
     407   [ -  +  -  -  :           1 :     CHECKARRVALID(a);
                   -  - ]
     408   [ -  +  -  -  :           1 :     CHECKARRVALID(b);
                   -  - ]
     409                 :             : 
     410         [ -  + ]:           1 :     QSORT(a, 1);
     411                 :           1 :     a = _int_unique(a);
     412                 :           1 :     ca = ARRNELEMS(a);
     413         [ -  + ]:           1 :     QSORT(b, 1);
     414                 :           1 :     b = _int_unique(b);
     415                 :           1 :     cb = ARRNELEMS(b);
     416                 :           1 :     result = new_intArrayType(ca);
     417         [ -  + ]:           1 :     aa = ARRPTR(a);
     418         [ -  + ]:           1 :     bb = ARRPTR(b);
     419         [ -  + ]:           1 :     r = ARRPTR(result);
     420         [ +  + ]:           4 :     while (i < ca)
     421                 :             :     {
     422   [ +  -  +  + ]:           3 :         if (k == cb || aa[i] < bb[k])
     423                 :           2 :             r[n++] = aa[i++];
     424         [ +  - ]:           1 :         else if (aa[i] == bb[k])
     425                 :             :         {
     426                 :           1 :             i++;
     427                 :           1 :             k++;
     428                 :             :         }
     429                 :             :         else
     430                 :           0 :             k++;
     431                 :             :     }
     432                 :           1 :     result = resize_intArrayType(result, n);
     433                 :           1 :     pfree(a);
     434                 :           1 :     pfree(b);
     435                 :           1 :     PG_RETURN_POINTER(result);
     436                 :             : }
        

Generated by: LCOV version 2.0-1