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-05-28 09:16:21 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              : /*
     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