LCOV - code coverage report
Current view: top level - contrib/intarray - _int_op.c (source / functions) Coverage Total Hit
Test: PostgreSQL 19devel Lines: 85.8 % 240 206
Test Date: 2026-03-03 13:15:30 Functions: 95.1 % 41 39
Legend: Lines:     hit not hit

            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              : /*  _int_overlap -- does a overlap b?
     100              :  */
     101              : Datum
     102         7563 : _int_overlap(PG_FUNCTION_ARGS)
     103              : {
     104         7563 :     ArrayType  *a = PG_GETARG_ARRAYTYPE_P_COPY(0);
     105         7563 :     ArrayType  *b = PG_GETARG_ARRAYTYPE_P_COPY(1);
     106              :     bool        result;
     107              : 
     108         7563 :     CHECKARRVALID(a);
     109         7563 :     CHECKARRVALID(b);
     110         7563 :     if (ARRISEMPTY(a) || ARRISEMPTY(b))
     111            9 :         PG_RETURN_BOOL(false);
     112              : 
     113         7554 :     SORT(a);
     114         7554 :     SORT(b);
     115              : 
     116         7554 :     result = inner_int_overlap(a, b);
     117              : 
     118         7554 :     pfree(a);
     119         7554 :     pfree(b);
     120              : 
     121         7554 :     PG_RETURN_BOOL(result);
     122              : }
     123              : 
     124              : Datum
     125            1 : _int_union(PG_FUNCTION_ARGS)
     126              : {
     127            1 :     ArrayType  *a = PG_GETARG_ARRAYTYPE_P_COPY(0);
     128            1 :     ArrayType  *b = PG_GETARG_ARRAYTYPE_P_COPY(1);
     129              :     ArrayType  *result;
     130              : 
     131            1 :     CHECKARRVALID(a);
     132            1 :     CHECKARRVALID(b);
     133              : 
     134            1 :     SORT(a);
     135            1 :     SORT(b);
     136              : 
     137            1 :     result = inner_int_union(a, b);
     138              : 
     139            1 :     pfree(a);
     140            1 :     pfree(b);
     141              : 
     142            1 :     PG_RETURN_POINTER(result);
     143              : }
     144              : 
     145              : Datum
     146            6 : _int_inter(PG_FUNCTION_ARGS)
     147              : {
     148            6 :     ArrayType  *a = PG_GETARG_ARRAYTYPE_P_COPY(0);
     149            6 :     ArrayType  *b = PG_GETARG_ARRAYTYPE_P_COPY(1);
     150              :     ArrayType  *result;
     151              : 
     152            6 :     CHECKARRVALID(a);
     153            6 :     CHECKARRVALID(b);
     154              : 
     155            6 :     SORT(a);
     156            6 :     SORT(b);
     157              : 
     158            6 :     result = inner_int_inter(a, b);
     159              : 
     160            6 :     pfree(a);
     161            6 :     pfree(b);
     162              : 
     163            6 :     PG_RETURN_POINTER(result);
     164              : }
     165              : 
     166              : 
     167            2 : PG_FUNCTION_INFO_V1(intset);
     168            2 : PG_FUNCTION_INFO_V1(icount);
     169            4 : PG_FUNCTION_INFO_V1(sort);
     170            2 : PG_FUNCTION_INFO_V1(sort_asc);
     171            2 : PG_FUNCTION_INFO_V1(sort_desc);
     172            2 : PG_FUNCTION_INFO_V1(uniq);
     173            2 : PG_FUNCTION_INFO_V1(idx);
     174            3 : PG_FUNCTION_INFO_V1(subarray);
     175            2 : PG_FUNCTION_INFO_V1(intarray_push_elem);
     176            2 : PG_FUNCTION_INFO_V1(intarray_push_array);
     177            2 : PG_FUNCTION_INFO_V1(intarray_del_elem);
     178            2 : PG_FUNCTION_INFO_V1(intset_union_elem);
     179            2 : PG_FUNCTION_INFO_V1(intset_subtract);
     180              : 
     181              : Datum
     182            1 : intset(PG_FUNCTION_ARGS)
     183              : {
     184            1 :     PG_RETURN_POINTER(int_to_intset(PG_GETARG_INT32(0)));
     185              : }
     186              : 
     187              : Datum
     188            2 : icount(PG_FUNCTION_ARGS)
     189              : {
     190            2 :     ArrayType  *a = PG_GETARG_ARRAYTYPE_P(0);
     191            2 :     int32       count = ARRNELEMS(a);
     192              : 
     193            2 :     PG_FREE_IF_COPY(a, 0);
     194            2 :     PG_RETURN_INT32(count);
     195              : }
     196              : 
     197              : Datum
     198            3 : sort(PG_FUNCTION_ARGS)
     199              : {
     200            3 :     ArrayType  *a = PG_GETARG_ARRAYTYPE_P_COPY(0);
     201            3 :     text       *dirstr = (fcinfo->nargs == 2) ? PG_GETARG_TEXT_PP(1) : NULL;
     202            3 :     int32       dc = (dirstr) ? VARSIZE_ANY_EXHDR(dirstr) : 0;
     203            3 :     char       *d = (dirstr) ? VARDATA_ANY(dirstr) : NULL;
     204            3 :     int         dir = -1;
     205              : 
     206            3 :     CHECKARRVALID(a);
     207            3 :     if (ARRNELEMS(a) < 2)
     208            0 :         PG_RETURN_POINTER(a);
     209              : 
     210            3 :     if (dirstr == NULL || (dc == 3
     211            1 :                            && (d[0] == 'A' || d[0] == 'a')
     212            1 :                            && (d[1] == 'S' || d[1] == 's')
     213            1 :                            && (d[2] == 'C' || d[2] == 'c')))
     214            2 :         dir = 1;
     215            1 :     else if (dc == 4
     216            1 :              && (d[0] == 'D' || d[0] == 'd')
     217            1 :              && (d[1] == 'E' || d[1] == 'e')
     218            1 :              && (d[2] == 'S' || d[2] == 's')
     219            1 :              && (d[3] == 'C' || d[3] == 'c'))
     220            1 :         dir = 0;
     221            3 :     if (dir == -1)
     222            0 :         ereport(ERROR,
     223              :                 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
     224              :                  errmsg("second parameter must be \"ASC\" or \"DESC\"")));
     225            3 :     QSORT(a, dir);
     226            3 :     PG_RETURN_POINTER(a);
     227              : }
     228              : 
     229              : Datum
     230            2 : sort_asc(PG_FUNCTION_ARGS)
     231              : {
     232            2 :     ArrayType  *a = PG_GETARG_ARRAYTYPE_P_COPY(0);
     233              : 
     234            2 :     CHECKARRVALID(a);
     235            2 :     QSORT(a, 1);
     236            2 :     PG_RETURN_POINTER(a);
     237              : }
     238              : 
     239              : Datum
     240            1 : sort_desc(PG_FUNCTION_ARGS)
     241              : {
     242            1 :     ArrayType  *a = PG_GETARG_ARRAYTYPE_P_COPY(0);
     243              : 
     244            1 :     CHECKARRVALID(a);
     245            1 :     QSORT(a, 0);
     246            1 :     PG_RETURN_POINTER(a);
     247              : }
     248              : 
     249              : Datum
     250            2 : uniq(PG_FUNCTION_ARGS)
     251              : {
     252            2 :     ArrayType  *a = PG_GETARG_ARRAYTYPE_P_COPY(0);
     253              : 
     254            2 :     CHECKARRVALID(a);
     255            2 :     if (ARRNELEMS(a) < 2)
     256            0 :         PG_RETURN_POINTER(a);
     257            2 :     a = _int_unique(a);
     258            2 :     PG_RETURN_POINTER(a);
     259              : }
     260              : 
     261              : Datum
     262            1 : idx(PG_FUNCTION_ARGS)
     263              : {
     264            1 :     ArrayType  *a = PG_GETARG_ARRAYTYPE_P(0);
     265              :     int32       result;
     266              : 
     267            1 :     CHECKARRVALID(a);
     268            1 :     result = ARRNELEMS(a);
     269            1 :     if (result)
     270            1 :         result = intarray_match_first(a, PG_GETARG_INT32(1));
     271            1 :     PG_FREE_IF_COPY(a, 0);
     272            1 :     PG_RETURN_INT32(result);
     273              : }
     274              : 
     275              : Datum
     276            3 : subarray(PG_FUNCTION_ARGS)
     277              : {
     278            3 :     ArrayType  *a = PG_GETARG_ARRAYTYPE_P(0);
     279            3 :     int32       start = PG_GETARG_INT32(1);
     280            3 :     int32       len = (fcinfo->nargs == 3) ? PG_GETARG_INT32(2) : 0;
     281            3 :     int32       end = 0;
     282              :     int32       c;
     283              :     ArrayType  *result;
     284              : 
     285            3 :     start = (start > 0) ? start - 1 : start;
     286              : 
     287            3 :     CHECKARRVALID(a);
     288            3 :     if (ARRISEMPTY(a))
     289              :     {
     290            0 :         PG_FREE_IF_COPY(a, 0);
     291            0 :         PG_RETURN_POINTER(new_intArrayType(0));
     292              :     }
     293              : 
     294            3 :     c = ARRNELEMS(a);
     295              : 
     296            3 :     if (start < 0)
     297            1 :         start = c + start;
     298              : 
     299            3 :     if (len < 0)
     300            1 :         end = c + len;
     301            2 :     else if (len == 0)
     302            0 :         end = c;
     303              :     else
     304            2 :         end = start + len;
     305              : 
     306            3 :     if (end > c)
     307            0 :         end = c;
     308              : 
     309            3 :     if (start < 0)
     310            0 :         start = 0;
     311              : 
     312            3 :     if (start >= end || end <= 0)
     313              :     {
     314            0 :         PG_FREE_IF_COPY(a, 0);
     315            0 :         PG_RETURN_POINTER(new_intArrayType(0));
     316              :     }
     317              : 
     318            3 :     result = new_intArrayType(end - start);
     319            3 :     if (end - start > 0)
     320            3 :         memcpy(ARRPTR(result), ARRPTR(a) + start, (end - start) * sizeof(int32));
     321            3 :     PG_FREE_IF_COPY(a, 0);
     322            3 :     PG_RETURN_POINTER(result);
     323              : }
     324              : 
     325              : Datum
     326            2 : intarray_push_elem(PG_FUNCTION_ARGS)
     327              : {
     328            2 :     ArrayType  *a = PG_GETARG_ARRAYTYPE_P(0);
     329              :     ArrayType  *result;
     330              : 
     331            2 :     result = intarray_add_elem(a, PG_GETARG_INT32(1));
     332            2 :     PG_FREE_IF_COPY(a, 0);
     333            2 :     PG_RETURN_POINTER(result);
     334              : }
     335              : 
     336              : Datum
     337            1 : intarray_push_array(PG_FUNCTION_ARGS)
     338              : {
     339            1 :     ArrayType  *a = PG_GETARG_ARRAYTYPE_P(0);
     340            1 :     ArrayType  *b = PG_GETARG_ARRAYTYPE_P(1);
     341              :     ArrayType  *result;
     342              : 
     343            1 :     result = intarray_concat_arrays(a, b);
     344            1 :     PG_FREE_IF_COPY(a, 0);
     345            1 :     PG_FREE_IF_COPY(b, 1);
     346            1 :     PG_RETURN_POINTER(result);
     347              : }
     348              : 
     349              : Datum
     350            1 : intarray_del_elem(PG_FUNCTION_ARGS)
     351              : {
     352            1 :     ArrayType  *a = PG_GETARG_ARRAYTYPE_P_COPY(0);
     353            1 :     int32       elem = PG_GETARG_INT32(1);
     354              :     int32       c;
     355              :     int32      *aa;
     356            1 :     int32       n = 0,
     357              :                 i;
     358              : 
     359            1 :     CHECKARRVALID(a);
     360            1 :     if (!ARRISEMPTY(a))
     361              :     {
     362            1 :         c = ARRNELEMS(a);
     363            1 :         aa = ARRPTR(a);
     364            4 :         for (i = 0; i < c; i++)
     365              :         {
     366            3 :             if (aa[i] != elem)
     367              :             {
     368            2 :                 if (i > n)
     369            1 :                     aa[n++] = aa[i];
     370              :                 else
     371            1 :                     n++;
     372              :             }
     373              :         }
     374            1 :         a = resize_intArrayType(a, n);
     375              :     }
     376            1 :     PG_RETURN_POINTER(a);
     377              : }
     378              : 
     379              : Datum
     380            2 : intset_union_elem(PG_FUNCTION_ARGS)
     381              : {
     382            2 :     ArrayType  *a = PG_GETARG_ARRAYTYPE_P(0);
     383              :     ArrayType  *result;
     384              : 
     385            2 :     result = intarray_add_elem(a, PG_GETARG_INT32(1));
     386            2 :     PG_FREE_IF_COPY(a, 0);
     387            2 :     QSORT(result, 1);
     388            2 :     PG_RETURN_POINTER(_int_unique(result));
     389              : }
     390              : 
     391              : Datum
     392            1 : intset_subtract(PG_FUNCTION_ARGS)
     393              : {
     394            1 :     ArrayType  *a = PG_GETARG_ARRAYTYPE_P_COPY(0);
     395            1 :     ArrayType  *b = PG_GETARG_ARRAYTYPE_P_COPY(1);
     396              :     ArrayType  *result;
     397              :     int32       ca;
     398              :     int32       cb;
     399              :     int32      *aa,
     400              :                *bb,
     401              :                *r;
     402            1 :     int32       n = 0,
     403            1 :                 i = 0,
     404            1 :                 k = 0;
     405              : 
     406            1 :     CHECKARRVALID(a);
     407            1 :     CHECKARRVALID(b);
     408              : 
     409            1 :     QSORT(a, 1);
     410            1 :     a = _int_unique(a);
     411            1 :     ca = ARRNELEMS(a);
     412            1 :     QSORT(b, 1);
     413            1 :     b = _int_unique(b);
     414            1 :     cb = ARRNELEMS(b);
     415            1 :     result = new_intArrayType(ca);
     416            1 :     aa = ARRPTR(a);
     417            1 :     bb = ARRPTR(b);
     418            1 :     r = ARRPTR(result);
     419            4 :     while (i < ca)
     420              :     {
     421            3 :         if (k == cb || aa[i] < bb[k])
     422            2 :             r[n++] = aa[i++];
     423            1 :         else if (aa[i] == bb[k])
     424              :         {
     425            1 :             i++;
     426            1 :             k++;
     427              :         }
     428              :         else
     429            0 :             k++;
     430              :     }
     431            1 :     result = resize_intArrayType(result, n);
     432            1 :     pfree(a);
     433            1 :     pfree(b);
     434            1 :     PG_RETURN_POINTER(result);
     435              : }
        

Generated by: LCOV version 2.0-1