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

Generated by: LCOV version 1.13