LCOV - code coverage report
Current view: top level - src/backend/access/nbtree - nbtcompare.c (source / functions) Hit Total Coverage
Test: PostgreSQL Lines: 118 151 78.1 %
Date: 2017-09-29 13:40:31 Functions: 20 24 83.3 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /*-------------------------------------------------------------------------
       2             :  *
       3             :  * nbtcompare.c
       4             :  *    Comparison functions for btree access method.
       5             :  *
       6             :  * Portions Copyright (c) 1996-2017, PostgreSQL Global Development Group
       7             :  * Portions Copyright (c) 1994, Regents of the University of California
       8             :  *
       9             :  *
      10             :  * IDENTIFICATION
      11             :  *    src/backend/access/nbtree/nbtcompare.c
      12             :  *
      13             :  * NOTES
      14             :  *
      15             :  *  These functions are stored in pg_amproc.  For each operator class
      16             :  *  defined on btrees, they compute
      17             :  *
      18             :  *              compare(a, b):
      19             :  *                      < 0 if a < b,
      20             :  *                      = 0 if a == b,
      21             :  *                      > 0 if a > b.
      22             :  *
      23             :  *  The result is always an int32 regardless of the input datatype.
      24             :  *
      25             :  *  Although any negative int32 (except INT_MIN) is acceptable for reporting
      26             :  *  "<", and any positive int32 is acceptable for reporting ">", routines
      27             :  *  that work on 32-bit or wider datatypes can't just return "a - b".
      28             :  *  That could overflow and give the wrong answer.  Also, one must not
      29             :  *  return INT_MIN to report "<", since some callers will negate the result.
      30             :  *
      31             :  *  NOTE: it is critical that the comparison function impose a total order
      32             :  *  on all non-NULL values of the data type, and that the datatype's
      33             :  *  boolean comparison operators (= < >= etc) yield results consistent
      34             :  *  with the comparison routine.  Otherwise bad behavior may ensue.
      35             :  *  (For example, the comparison operators must NOT punt when faced with
      36             :  *  NAN or other funny values; you must devise some collation sequence for
      37             :  *  all such values.)  If the datatype is not trivial, this is most
      38             :  *  reliably done by having the boolean operators invoke the same
      39             :  *  three-way comparison code that the btree function does.  Therefore,
      40             :  *  this file contains only btree support for "trivial" datatypes ---
      41             :  *  all others are in the /utils/adt/ files that implement their datatypes.
      42             :  *
      43             :  *  NOTE: these routines must not leak memory, since memory allocated
      44             :  *  during an index access won't be recovered till end of query.  This
      45             :  *  primarily affects comparison routines for toastable datatypes;
      46             :  *  they have to be careful to free any detoasted copy of an input datum.
      47             :  *-------------------------------------------------------------------------
      48             :  */
      49             : #include "postgres.h"
      50             : 
      51             : #include "utils/builtins.h"
      52             : #include "utils/sortsupport.h"
      53             : 
      54             : 
      55             : Datum
      56      638823 : btboolcmp(PG_FUNCTION_ARGS)
      57             : {
      58      638823 :     bool        a = PG_GETARG_BOOL(0);
      59      638823 :     bool        b = PG_GETARG_BOOL(1);
      60             : 
      61      638823 :     PG_RETURN_INT32((int32) a - (int32) b);
      62             : }
      63             : 
      64             : Datum
      65      207563 : btint2cmp(PG_FUNCTION_ARGS)
      66             : {
      67      207563 :     int16       a = PG_GETARG_INT16(0);
      68      207563 :     int16       b = PG_GETARG_INT16(1);
      69             : 
      70      207563 :     PG_RETURN_INT32((int32) a - (int32) b);
      71             : }
      72             : 
      73             : static int
      74      277484 : btint2fastcmp(Datum x, Datum y, SortSupport ssup)
      75             : {
      76      277484 :     int16       a = DatumGetInt16(x);
      77      277484 :     int16       b = DatumGetInt16(y);
      78             : 
      79      277484 :     return (int) a - (int) b;
      80             : }
      81             : 
      82             : Datum
      83          50 : btint2sortsupport(PG_FUNCTION_ARGS)
      84             : {
      85          50 :     SortSupport ssup = (SortSupport) PG_GETARG_POINTER(0);
      86             : 
      87          50 :     ssup->comparator = btint2fastcmp;
      88          50 :     PG_RETURN_VOID();
      89             : }
      90             : 
      91             : Datum
      92     4785401 : btint4cmp(PG_FUNCTION_ARGS)
      93             : {
      94     4785401 :     int32       a = PG_GETARG_INT32(0);
      95     4785401 :     int32       b = PG_GETARG_INT32(1);
      96             : 
      97     4785401 :     if (a > b)
      98     2218216 :         PG_RETURN_INT32(1);
      99     2567185 :     else if (a == b)
     100      595732 :         PG_RETURN_INT32(0);
     101             :     else
     102     1971453 :         PG_RETURN_INT32(-1);
     103             : }
     104             : 
     105             : static int
     106    19218425 : btint4fastcmp(Datum x, Datum y, SortSupport ssup)
     107             : {
     108    19218425 :     int32       a = DatumGetInt32(x);
     109    19218425 :     int32       b = DatumGetInt32(y);
     110             : 
     111    19218425 :     if (a > b)
     112     5024687 :         return 1;
     113    14193738 :     else if (a == b)
     114     8970009 :         return 0;
     115             :     else
     116     5223729 :         return -1;
     117             : }
     118             : 
     119             : Datum
     120        4227 : btint4sortsupport(PG_FUNCTION_ARGS)
     121             : {
     122        4227 :     SortSupport ssup = (SortSupport) PG_GETARG_POINTER(0);
     123             : 
     124        4227 :     ssup->comparator = btint4fastcmp;
     125        4227 :     PG_RETURN_VOID();
     126             : }
     127             : 
     128             : Datum
     129         127 : btint8cmp(PG_FUNCTION_ARGS)
     130             : {
     131         127 :     int64       a = PG_GETARG_INT64(0);
     132         127 :     int64       b = PG_GETARG_INT64(1);
     133             : 
     134         127 :     if (a > b)
     135          30 :         PG_RETURN_INT32(1);
     136          97 :     else if (a == b)
     137          50 :         PG_RETURN_INT32(0);
     138             :     else
     139          47 :         PG_RETURN_INT32(-1);
     140             : }
     141             : 
     142             : static int
     143        1332 : btint8fastcmp(Datum x, Datum y, SortSupport ssup)
     144             : {
     145        1332 :     int64       a = DatumGetInt64(x);
     146        1332 :     int64       b = DatumGetInt64(y);
     147             : 
     148        1332 :     if (a > b)
     149         317 :         return 1;
     150        1015 :     else if (a == b)
     151         626 :         return 0;
     152             :     else
     153         389 :         return -1;
     154             : }
     155             : 
     156             : Datum
     157         111 : btint8sortsupport(PG_FUNCTION_ARGS)
     158             : {
     159         111 :     SortSupport ssup = (SortSupport) PG_GETARG_POINTER(0);
     160             : 
     161         111 :     ssup->comparator = btint8fastcmp;
     162         111 :     PG_RETURN_VOID();
     163             : }
     164             : 
     165             : Datum
     166         281 : btint48cmp(PG_FUNCTION_ARGS)
     167             : {
     168         281 :     int32       a = PG_GETARG_INT32(0);
     169         281 :     int64       b = PG_GETARG_INT64(1);
     170             : 
     171         281 :     if (a > b)
     172         105 :         PG_RETURN_INT32(1);
     173         176 :     else if (a == b)
     174          14 :         PG_RETURN_INT32(0);
     175             :     else
     176         162 :         PG_RETURN_INT32(-1);
     177             : }
     178             : 
     179             : Datum
     180           0 : btint84cmp(PG_FUNCTION_ARGS)
     181             : {
     182           0 :     int64       a = PG_GETARG_INT64(0);
     183           0 :     int32       b = PG_GETARG_INT32(1);
     184             : 
     185           0 :     if (a > b)
     186           0 :         PG_RETURN_INT32(1);
     187           0 :     else if (a == b)
     188           0 :         PG_RETURN_INT32(0);
     189             :     else
     190           0 :         PG_RETURN_INT32(-1);
     191             : }
     192             : 
     193             : Datum
     194        2040 : btint24cmp(PG_FUNCTION_ARGS)
     195             : {
     196        2040 :     int16       a = PG_GETARG_INT16(0);
     197        2040 :     int32       b = PG_GETARG_INT32(1);
     198             : 
     199        2040 :     if (a > b)
     200        1334 :         PG_RETURN_INT32(1);
     201         706 :     else if (a == b)
     202           0 :         PG_RETURN_INT32(0);
     203             :     else
     204         706 :         PG_RETURN_INT32(-1);
     205             : }
     206             : 
     207             : Datum
     208           0 : btint42cmp(PG_FUNCTION_ARGS)
     209             : {
     210           0 :     int32       a = PG_GETARG_INT32(0);
     211           0 :     int16       b = PG_GETARG_INT16(1);
     212             : 
     213           0 :     if (a > b)
     214           0 :         PG_RETURN_INT32(1);
     215           0 :     else if (a == b)
     216           0 :         PG_RETURN_INT32(0);
     217             :     else
     218           0 :         PG_RETURN_INT32(-1);
     219             : }
     220             : 
     221             : Datum
     222           0 : btint28cmp(PG_FUNCTION_ARGS)
     223             : {
     224           0 :     int16       a = PG_GETARG_INT16(0);
     225           0 :     int64       b = PG_GETARG_INT64(1);
     226             : 
     227           0 :     if (a > b)
     228           0 :         PG_RETURN_INT32(1);
     229           0 :     else if (a == b)
     230           0 :         PG_RETURN_INT32(0);
     231             :     else
     232           0 :         PG_RETURN_INT32(-1);
     233             : }
     234             : 
     235             : Datum
     236           0 : btint82cmp(PG_FUNCTION_ARGS)
     237             : {
     238           0 :     int64       a = PG_GETARG_INT64(0);
     239           0 :     int16       b = PG_GETARG_INT16(1);
     240             : 
     241           0 :     if (a > b)
     242           0 :         PG_RETURN_INT32(1);
     243           0 :     else if (a == b)
     244           0 :         PG_RETURN_INT32(0);
     245             :     else
     246           0 :         PG_RETURN_INT32(-1);
     247             : }
     248             : 
     249             : Datum
     250     6778687 : btoidcmp(PG_FUNCTION_ARGS)
     251             : {
     252     6778687 :     Oid         a = PG_GETARG_OID(0);
     253     6778687 :     Oid         b = PG_GETARG_OID(1);
     254             : 
     255     6778687 :     if (a > b)
     256     1671914 :         PG_RETURN_INT32(1);
     257     5106773 :     else if (a == b)
     258     2224976 :         PG_RETURN_INT32(0);
     259             :     else
     260     2881797 :         PG_RETURN_INT32(-1);
     261             : }
     262             : 
     263             : static int
     264     1863635 : btoidfastcmp(Datum x, Datum y, SortSupport ssup)
     265             : {
     266     1863635 :     Oid         a = DatumGetObjectId(x);
     267     1863635 :     Oid         b = DatumGetObjectId(y);
     268             : 
     269     1863635 :     if (a > b)
     270      396559 :         return 1;
     271     1467076 :     else if (a == b)
     272     1108336 :         return 0;
     273             :     else
     274      358740 :         return -1;
     275             : }
     276             : 
     277             : Datum
     278        2177 : btoidsortsupport(PG_FUNCTION_ARGS)
     279             : {
     280        2177 :     SortSupport ssup = (SortSupport) PG_GETARG_POINTER(0);
     281             : 
     282        2177 :     ssup->comparator = btoidfastcmp;
     283        2177 :     PG_RETURN_VOID();
     284             : }
     285             : 
     286             : Datum
     287       46581 : btoidvectorcmp(PG_FUNCTION_ARGS)
     288             : {
     289       46581 :     oidvector  *a = (oidvector *) PG_GETARG_POINTER(0);
     290       46581 :     oidvector  *b = (oidvector *) PG_GETARG_POINTER(1);
     291             :     int         i;
     292             : 
     293             :     /* We arbitrarily choose to sort first by vector length */
     294       46581 :     if (a->dim1 != b->dim1)
     295        7813 :         PG_RETURN_INT32(a->dim1 - b->dim1);
     296             : 
     297       72370 :     for (i = 0; i < a->dim1; i++)
     298             :     {
     299       53643 :         if (a->values[i] != b->values[i])
     300             :         {
     301       20041 :             if (a->values[i] > b->values[i])
     302       10842 :                 PG_RETURN_INT32(1);
     303             :             else
     304        9199 :                 PG_RETURN_INT32(-1);
     305             :         }
     306             :     }
     307       18727 :     PG_RETURN_INT32(0);
     308             : }
     309             : 
     310             : Datum
     311      664708 : btcharcmp(PG_FUNCTION_ARGS)
     312             : {
     313      664708 :     char        a = PG_GETARG_CHAR(0);
     314      664708 :     char        b = PG_GETARG_CHAR(1);
     315             : 
     316             :     /* Be careful to compare chars as unsigned */
     317      664708 :     PG_RETURN_INT32((int32) ((uint8) a) - (int32) ((uint8) b));
     318             : }
     319             : 
     320             : Datum
     321      665472 : btnamecmp(PG_FUNCTION_ARGS)
     322             : {
     323      665472 :     Name        a = PG_GETARG_NAME(0);
     324      665472 :     Name        b = PG_GETARG_NAME(1);
     325             : 
     326      665472 :     PG_RETURN_INT32(strncmp(NameStr(*a), NameStr(*b), NAMEDATALEN));
     327             : }
     328             : 
     329             : static int
     330     1771272 : btnamefastcmp(Datum x, Datum y, SortSupport ssup)
     331             : {
     332     1771272 :     Name        a = DatumGetName(x);
     333     1771272 :     Name        b = DatumGetName(y);
     334             : 
     335     1771272 :     return strncmp(NameStr(*a), NameStr(*b), NAMEDATALEN);
     336             : }
     337             : 
     338             : Datum
     339        1413 : btnamesortsupport(PG_FUNCTION_ARGS)
     340             : {
     341        1413 :     SortSupport ssup = (SortSupport) PG_GETARG_POINTER(0);
     342             : 
     343        1413 :     ssup->comparator = btnamefastcmp;
     344        1413 :     PG_RETURN_VOID();
     345             : }

Generated by: LCOV version 1.11