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

Generated by: LCOV version 1.14