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

Generated by: LCOV version 1.14