Use new overflow-safe integer comparison functions.

Commit 6b80394781 introduced integer comparison functions designed
to be as efficient as possible while avoiding overflow.  This
commit makes use of these functions in many of the in-tree qsort()
comparators to help ensure transitivity.  Many of these comparator
functions should also see a small performance boost.

Author: Mats Kindahl
Reviewed-by: Andres Freund, Fabrízio de Royes Mello
Discussion: https://postgr.es/m/CA%2B14426g2Wa9QuUpmakwPxXFWG_1FaY0AsApkvcTBy-YfS6uaw%40mail.gmail.com
pull/157/head
Nathan Bossart 1 year ago
parent 6b80394781
commit 3b42bdb471
  1. 4
      contrib/hstore/hstore_gist.c
  2. 9
      contrib/intarray/_int_tool.c
  3. 4
      contrib/intarray/_intbig_gist.c
  4. 8
      contrib/pg_stat_statements/pg_stat_statements.c
  5. 8
      contrib/pg_trgm/trgm_op.c
  6. 8
      src/backend/access/nbtree/nbtinsert.c
  7. 10
      src/backend/access/nbtree/nbtpage.c
  8. 8
      src/backend/access/nbtree/nbtsplitloc.c
  9. 5
      src/backend/access/spgist/spgdoinsert.c
  10. 3
      src/backend/access/spgist/spgtextproc.c
  11. 8
      src/backend/backup/basebackup_incremental.c
  12. 7
      src/backend/backup/walsummary.c
  13. 7
      src/backend/catalog/heap.c
  14. 13
      src/backend/nodes/list.c
  15. 7
      src/backend/nodes/tidbitmap.c
  16. 3
      src/backend/parser/parse_agg.c
  17. 7
      src/backend/postmaster/autovacuum.c
  18. 7
      src/backend/replication/logical/reorderbuffer.c
  19. 8
      src/backend/replication/syncrep.c
  20. 7
      src/backend/utils/adt/oid.c
  21. 10
      src/backend/utils/adt/tsgistidx.c
  22. 7
      src/backend/utils/adt/tsquery_gist.c
  23. 5
      src/backend/utils/adt/tsvector.c
  24. 5
      src/backend/utils/adt/tsvector_op.c
  25. 7
      src/backend/utils/adt/xid.c
  26. 3
      src/backend/utils/cache/relcache.c
  27. 5
      src/backend/utils/cache/syscache.c
  28. 8
      src/backend/utils/cache/typcache.c
  29. 10
      src/backend/utils/resowner/resowner.c
  30. 7
      src/bin/pg_dump/pg_dump_sort.c
  31. 12
      src/bin/pg_upgrade/function.c
  32. 8
      src/bin/pg_walsummary/pg_walsummary.c
  33. 3
      src/bin/psql/crosstabview.c
  34. 8
      src/include/access/gin_private.h

@ -7,6 +7,7 @@
#include "access/reloptions.h"
#include "access/stratnum.h"
#include "catalog/pg_type.h"
#include "common/int.h"
#include "hstore.h"
#include "utils/pg_crc.h"
@ -356,7 +357,8 @@ typedef struct
static int
comparecost(const void *a, const void *b)
{
return ((const SPLITCOST *) a)->cost - ((const SPLITCOST *) b)->cost;
return pg_cmp_s32(((const SPLITCOST *) a)->cost,
((const SPLITCOST *) b)->cost);
}

@ -7,6 +7,7 @@
#include "_int.h"
#include "catalog/pg_type.h"
#include "common/int.h"
#include "lib/qunique.h"
/* arguments are assumed sorted & unique-ified */
@ -396,15 +397,11 @@ int_to_intset(int32 elem)
int
compASC(const void *a, const void *b)
{
if (*(const int32 *) a == *(const int32 *) b)
return 0;
return (*(const int32 *) a > *(const int32 *) b) ? 1 : -1;
return pg_cmp_s32(*(const int32 *) a, *(const int32 *) b);
}
int
compDESC(const void *a, const void *b)
{
if (*(const int32 *) a == *(const int32 *) b)
return 0;
return (*(const int32 *) a < *(const int32 *) b) ? 1 : -1;
return pg_cmp_s32(*(const int32 *) b, *(const int32 *) a);
}

@ -9,6 +9,7 @@
#include "access/gist.h"
#include "access/reloptions.h"
#include "access/stratnum.h"
#include "common/int.h"
#include "port/pg_bitutils.h"
#define GETENTRY(vec,pos) ((GISTTYPE *) DatumGetPointer((vec)->vector[(pos)].key))
@ -312,7 +313,8 @@ typedef struct
static int
comparecost(const void *a, const void *b)
{
return ((const SPLITCOST *) a)->cost - ((const SPLITCOST *) b)->cost;
return pg_cmp_s32(((const SPLITCOST *) a)->cost,
((const SPLITCOST *) b)->cost);
}

@ -50,6 +50,7 @@
#include "access/parallel.h"
#include "catalog/pg_authid.h"
#include "common/hashfn.h"
#include "common/int.h"
#include "executor/instrument.h"
#include "funcapi.h"
#include "jit/jit.h"
@ -3007,10 +3008,5 @@ comp_location(const void *a, const void *b)
int l = ((const LocationLen *) a)->location;
int r = ((const LocationLen *) b)->location;
if (l < r)
return -1;
else if (l > r)
return +1;
else
return 0;
return pg_cmp_s32(l, r);
}

@ -6,6 +6,7 @@
#include <ctype.h>
#include "catalog/pg_type.h"
#include "common/int.h"
#include "lib/qunique.h"
#include "miscadmin.h"
#include "trgm.h"
@ -433,12 +434,7 @@ comp_ptrgm(const void *v1, const void *v2)
if (cmp != 0)
return cmp;
if (p1->index < p2->index)
return -1;
else if (p1->index == p2->index)
return 0;
else
return 1;
return pg_cmp_s32(p1->index, p2->index);
}
/*

@ -19,6 +19,7 @@
#include "access/nbtxlog.h"
#include "access/transam.h"
#include "access/xloginsert.h"
#include "common/int.h"
#include "common/pg_prng.h"
#include "lib/qunique.h"
#include "miscadmin.h"
@ -3013,10 +3014,5 @@ _bt_blk_cmp(const void *arg1, const void *arg2)
BlockNumber b1 = *((BlockNumber *) arg1);
BlockNumber b2 = *((BlockNumber *) arg2);
if (b1 < b2)
return -1;
else if (b1 > b2)
return 1;
return 0;
return pg_cmp_u32(b1, b2);
}

@ -28,6 +28,7 @@
#include "access/transam.h"
#include "access/xlog.h"
#include "access/xloginsert.h"
#include "common/int.h"
#include "miscadmin.h"
#include "storage/indexfsm.h"
#include "storage/lmgr.h"
@ -1466,14 +1467,9 @@ _bt_delitems_cmp(const void *a, const void *b)
TM_IndexDelete *indexdelete1 = (TM_IndexDelete *) a;
TM_IndexDelete *indexdelete2 = (TM_IndexDelete *) b;
if (indexdelete1->id > indexdelete2->id)
return 1;
if (indexdelete1->id < indexdelete2->id)
return -1;
Assert(indexdelete1->id != indexdelete2->id);
Assert(false);
return 0;
return pg_cmp_s16(indexdelete1->id, indexdelete2->id);
}
/*

@ -15,6 +15,7 @@
#include "postgres.h"
#include "access/nbtree.h"
#include "common/int.h"
#include "storage/lmgr.h"
typedef enum
@ -596,12 +597,7 @@ _bt_splitcmp(const void *arg1, const void *arg2)
SplitPoint *split1 = (SplitPoint *) arg1;
SplitPoint *split2 = (SplitPoint *) arg2;
if (split1->curdelta > split2->curdelta)
return 1;
if (split1->curdelta < split2->curdelta)
return -1;
return 0;
return pg_cmp_s16(split1->curdelta, split2->curdelta);
}
/*

@ -19,6 +19,7 @@
#include "access/spgist_private.h"
#include "access/spgxlog.h"
#include "access/xloginsert.h"
#include "common/int.h"
#include "common/pg_prng.h"
#include "miscadmin.h"
#include "storage/bufmgr.h"
@ -110,9 +111,7 @@ addNode(SpGistState *state, SpGistInnerTuple tuple, Datum label, int offset)
static int
cmpOffsetNumbers(const void *a, const void *b)
{
if (*(const OffsetNumber *) a == *(const OffsetNumber *) b)
return 0;
return (*(const OffsetNumber *) a > *(const OffsetNumber *) b) ? 1 : -1;
return pg_cmp_u16(*(const OffsetNumber *) a, *(const OffsetNumber *) b);
}
/*

@ -40,6 +40,7 @@
#include "postgres.h"
#include "access/spgist.h"
#include "common/int.h"
#include "catalog/pg_type.h"
#include "mb/pg_wchar.h"
#include "utils/builtins.h"
@ -325,7 +326,7 @@ cmpNodePtr(const void *a, const void *b)
const spgNodePtr *aa = (const spgNodePtr *) a;
const spgNodePtr *bb = (const spgNodePtr *) b;
return aa->c - bb->c;
return pg_cmp_s16(aa->c, bb->c);
}
Datum

@ -27,6 +27,7 @@
#include "common/blkreftable.h"
#include "common/parse_manifest.h"
#include "common/hashfn.h"
#include "common/int.h"
#include "postmaster/walsummarizer.h"
#define BLOCKS_PER_READ 512
@ -994,10 +995,5 @@ compare_block_numbers(const void *a, const void *b)
BlockNumber aa = *(BlockNumber *) a;
BlockNumber bb = *(BlockNumber *) b;
if (aa > bb)
return 1;
else if (aa == bb)
return 0;
else
return -1;
return pg_cmp_u32(aa, bb);
}

@ -17,6 +17,7 @@
#include "access/xlog_internal.h"
#include "backup/walsummary.h"
#include "common/int.h"
#include "utils/wait_event.h"
static bool IsWalSummaryFilename(char *filename);
@ -355,9 +356,5 @@ ListComparatorForWalSummaryFiles(const ListCell *a, const ListCell *b)
WalSummaryFile *ws1 = lfirst(a);
WalSummaryFile *ws2 = lfirst(b);
if (ws1->start_lsn < ws2->start_lsn)
return -1;
if (ws1->start_lsn > ws2->start_lsn)
return 1;
return 0;
return pg_cmp_u64(ws1->start_lsn, ws2->start_lsn);
}

@ -56,6 +56,7 @@
#include "catalog/storage.h"
#include "commands/tablecmds.h"
#include "commands/typecmds.h"
#include "common/int.h"
#include "miscadmin.h"
#include "nodes/nodeFuncs.h"
#include "optimizer/optimizer.h"
@ -2762,11 +2763,7 @@ list_cookedconstr_attnum_cmp(const ListCell *p1, const ListCell *p2)
AttrNumber v1 = ((CookedConstraint *) lfirst(p1))->attnum;
AttrNumber v2 = ((CookedConstraint *) lfirst(p2))->attnum;
if (v1 < v2)
return -1;
if (v1 > v2)
return 1;
return 0;
return pg_cmp_s16(v1, v2);
}
/*

@ -17,6 +17,7 @@
*/
#include "postgres.h"
#include "common/int.h"
#include "nodes/pg_list.h"
#include "port/pg_bitutils.h"
#include "utils/memdebug.h"
@ -1692,11 +1693,7 @@ list_int_cmp(const ListCell *p1, const ListCell *p2)
int v1 = lfirst_int(p1);
int v2 = lfirst_int(p2);
if (v1 < v2)
return -1;
if (v1 > v2)
return 1;
return 0;
return pg_cmp_s32(v1, v2);
}
/*
@ -1708,9 +1705,5 @@ list_oid_cmp(const ListCell *p1, const ListCell *p2)
Oid v1 = lfirst_oid(p1);
Oid v2 = lfirst_oid(p2);
if (v1 < v2)
return -1;
if (v1 > v2)
return 1;
return 0;
return pg_cmp_u32(v1, v2);
}

@ -42,6 +42,7 @@
#include "access/htup_details.h"
#include "common/hashfn.h"
#include "common/int.h"
#include "nodes/bitmapset.h"
#include "nodes/tidbitmap.h"
#include "storage/lwlock.h"
@ -1425,11 +1426,7 @@ tbm_comparator(const void *left, const void *right)
BlockNumber l = (*((PagetableEntry *const *) left))->blockno;
BlockNumber r = (*((PagetableEntry *const *) right))->blockno;
if (l < r)
return -1;
else if (l > r)
return 1;
return 0;
return pg_cmp_u32(l, r);
}
/*

@ -18,6 +18,7 @@
#include "catalog/pg_aggregate.h"
#include "catalog/pg_constraint.h"
#include "catalog/pg_type.h"
#include "common/int.h"
#include "nodes/makefuncs.h"
#include "nodes/nodeFuncs.h"
#include "optimizer/optimizer.h"
@ -1760,7 +1761,7 @@ cmp_list_len_asc(const ListCell *a, const ListCell *b)
int la = list_length((const List *) lfirst(a));
int lb = list_length((const List *) lfirst(b));
return (la > lb) ? 1 : (la == lb) ? 0 : -1;
return pg_cmp_s32(la, lb);
}
/* list_sort comparator to sort sub-lists by length and contents */

@ -78,6 +78,7 @@
#include "catalog/pg_database.h"
#include "commands/dbcommands.h"
#include "commands/vacuum.h"
#include "common/int.h"
#include "lib/ilist.h"
#include "libpq/pqsignal.h"
#include "miscadmin.h"
@ -1120,10 +1121,8 @@ rebuild_database_list(Oid newdb)
static int
db_comparator(const void *a, const void *b)
{
if (((const avl_dbase *) a)->adl_score == ((const avl_dbase *) b)->adl_score)
return 0;
else
return (((const avl_dbase *) a)->adl_score < ((const avl_dbase *) b)->adl_score) ? 1 : -1;
return pg_cmp_s32(((const avl_dbase *) a)->adl_score,
((const avl_dbase *) b)->adl_score);
}
/*

@ -91,6 +91,7 @@
#include "access/xact.h"
#include "access/xlog_internal.h"
#include "catalog/catalog.h"
#include "common/int.h"
#include "lib/binaryheap.h"
#include "miscadmin.h"
#include "pgstat.h"
@ -5119,11 +5120,7 @@ file_sort_by_lsn(const ListCell *a_p, const ListCell *b_p)
RewriteMappingFile *a = (RewriteMappingFile *) lfirst(a_p);
RewriteMappingFile *b = (RewriteMappingFile *) lfirst(b_p);
if (a->lsn < b->lsn)
return -1;
else if (a->lsn > b->lsn)
return 1;
return 0;
return pg_cmp_u64(a->lsn, b->lsn);
}
/*

@ -75,6 +75,7 @@
#include <unistd.h>
#include "access/xact.h"
#include "common/int.h"
#include "miscadmin.h"
#include "pgstat.h"
#include "replication/syncrep.h"
@ -698,12 +699,7 @@ cmp_lsn(const void *a, const void *b)
XLogRecPtr lsn1 = *((const XLogRecPtr *) a);
XLogRecPtr lsn2 = *((const XLogRecPtr *) b);
if (lsn1 > lsn2)
return -1;
else if (lsn1 == lsn2)
return 0;
else
return 1;
return pg_cmp_u64(lsn2, lsn1);
}
/*

@ -18,6 +18,7 @@
#include <limits.h>
#include "catalog/pg_type.h"
#include "common/int.h"
#include "libpq/pqformat.h"
#include "nodes/miscnodes.h"
#include "nodes/value.h"
@ -259,11 +260,7 @@ oid_cmp(const void *p1, const void *p2)
Oid v1 = *((const Oid *) p1);
Oid v2 = *((const Oid *) p2);
if (v1 < v2)
return -1;
if (v1 > v2)
return 1;
return 0;
return pg_cmp_u32(v1, v2);
}

@ -17,6 +17,7 @@
#include "access/gist.h"
#include "access/heaptoast.h"
#include "access/reloptions.h"
#include "common/int.h"
#include "lib/qunique.h"
#include "port/pg_bitutils.h"
#include "tsearch/ts_utils.h"
@ -136,9 +137,7 @@ compareint(const void *va, const void *vb)
int32 a = *((const int32 *) va);
int32 b = *((const int32 *) vb);
if (a == b)
return 0;
return (a > b) ? 1 : -1;
return pg_cmp_s32(a, b);
}
static void
@ -598,10 +597,7 @@ comparecost(const void *va, const void *vb)
const SPLITCOST *a = (const SPLITCOST *) va;
const SPLITCOST *b = (const SPLITCOST *) vb;
if (a->cost == b->cost)
return 0;
else
return (a->cost > b->cost) ? 1 : -1;
return pg_cmp_s32(a->cost, b->cost);
}

@ -16,6 +16,7 @@
#include "access/gist.h"
#include "access/stratnum.h"
#include "common/int.h"
#include "tsearch/ts_utils.h"
#include "utils/builtins.h"
@ -156,10 +157,8 @@ typedef struct
static int
comparecost(const void *a, const void *b)
{
if (((const SPLITCOST *) a)->cost == ((const SPLITCOST *) b)->cost)
return 0;
else
return (((const SPLITCOST *) a)->cost > ((const SPLITCOST *) b)->cost) ? 1 : -1;
return pg_cmp_s32(((const SPLITCOST *) a)->cost,
((const SPLITCOST *) b)->cost);
}
#define WISH_F(a,b,c) (double)( -(double)(((a)-(b))*((a)-(b))*((a)-(b)))*(c) )

@ -14,6 +14,7 @@
#include "postgres.h"
#include "common/int.h"
#include "libpq/pqformat.h"
#include "nodes/miscnodes.h"
#include "tsearch/ts_locale.h"
@ -37,9 +38,7 @@ compareWordEntryPos(const void *a, const void *b)
int apos = WEP_GETPOS(*(const WordEntryPos *) a);
int bpos = WEP_GETPOS(*(const WordEntryPos *) b);
if (apos == bpos)
return 0;
return (apos > bpos) ? 1 : -1;
return pg_cmp_s32(apos, bpos);
}
/*

@ -19,6 +19,7 @@
#include "catalog/namespace.h"
#include "catalog/pg_type.h"
#include "commands/trigger.h"
#include "common/int.h"
#include "executor/spi.h"
#include "funcapi.h"
#include "lib/qunique.h"
@ -435,9 +436,7 @@ compare_int(const void *va, const void *vb)
int a = *((const int *) va);
int b = *((const int *) vb);
if (a == b)
return 0;
return (a > b) ? 1 : -1;
return pg_cmp_s32(a, b);
}
static int

@ -19,6 +19,7 @@
#include "access/multixact.h"
#include "access/transam.h"
#include "access/xact.h"
#include "common/int.h"
#include "libpq/pqformat.h"
#include "utils/builtins.h"
#include "utils/xid8.h"
@ -140,11 +141,7 @@ xidComparator(const void *arg1, const void *arg2)
TransactionId xid1 = *(const TransactionId *) arg1;
TransactionId xid2 = *(const TransactionId *) arg2;
if (xid1 > xid2)
return 1;
if (xid1 < xid2)
return -1;
return 0;
return pg_cmp_u32(xid1, xid2);
}
/*

@ -69,6 +69,7 @@
#include "commands/policy.h"
#include "commands/publicationcmds.h"
#include "commands/trigger.h"
#include "common/int.h"
#include "miscadmin.h"
#include "nodes/makefuncs.h"
#include "nodes/nodeFuncs.h"
@ -4520,7 +4521,7 @@ AttrDefaultCmp(const void *a, const void *b)
const AttrDefault *ada = (const AttrDefault *) a;
const AttrDefault *adb = (const AttrDefault *) b;
return ada->adnum - adb->adnum;
return pg_cmp_s16(ada->adnum, adb->adnum);
}
/*

@ -29,6 +29,7 @@
#include "catalog/pg_shdepend_d.h"
#include "catalog/pg_shdescription_d.h"
#include "catalog/pg_shseclabel_d.h"
#include "common/int.h"
#include "lib/qunique.h"
#include "utils/catcache.h"
#include "utils/lsyscache.h"
@ -676,7 +677,5 @@ oid_compare(const void *a, const void *b)
Oid oa = *((const Oid *) a);
Oid ob = *((const Oid *) b);
if (oa == ob)
return 0;
return (oa > ob) ? 1 : -1;
return pg_cmp_u32(oa, ob);
}

@ -57,6 +57,7 @@
#include "catalog/pg_range.h"
#include "catalog/pg_type.h"
#include "commands/defrem.h"
#include "common/int.h"
#include "executor/executor.h"
#include "lib/dshash.h"
#include "optimizer/optimizer.h"
@ -2722,12 +2723,7 @@ enum_oid_cmp(const void *left, const void *right)
const EnumItem *l = (const EnumItem *) left;
const EnumItem *r = (const EnumItem *) right;
if (l->enum_oid < r->enum_oid)
return -1;
else if (l->enum_oid > r->enum_oid)
return 1;
else
return 0;
return pg_cmp_u32(l->enum_oid, r->enum_oid);
}
/*

@ -46,6 +46,7 @@
#include "postgres.h"
#include "common/hashfn.h"
#include "common/int.h"
#include "storage/ipc.h"
#include "storage/predicate.h"
#include "storage/proc.h"
@ -264,14 +265,7 @@ resource_priority_cmp(const void *a, const void *b)
/* Note: reverse order */
if (ra->kind->release_phase == rb->kind->release_phase)
{
if (ra->kind->release_priority == rb->kind->release_priority)
return 0;
else if (ra->kind->release_priority > rb->kind->release_priority)
return -1;
else
return 1;
}
return pg_cmp_u32(rb->kind->release_priority, ra->kind->release_priority);
else if (ra->kind->release_phase > rb->kind->release_phase)
return -1;
else

@ -16,6 +16,7 @@
#include "postgres_fe.h"
#include "catalog/pg_class_d.h"
#include "common/int.h"
#include "lib/binaryheap.h"
#include "pg_backup_archiver.h"
#include "pg_backup_utils.h"
@ -1504,9 +1505,5 @@ int_cmp(void *a, void *b, void *arg)
int ai = (int) (intptr_t) a;
int bi = (int) (intptr_t) b;
if (ai < bi)
return -1;
if (ai > bi)
return 1;
return 0;
return pg_cmp_s32(ai, bi);
}

@ -11,6 +11,7 @@
#include "access/transam.h"
#include "catalog/pg_language_d.h"
#include "common/int.h"
#include "pg_upgrade.h"
/*
@ -29,17 +30,16 @@ library_name_compare(const void *p1, const void *p2)
{
const char *str1 = ((const LibraryInfo *) p1)->name;
const char *str2 = ((const LibraryInfo *) p2)->name;
int slen1 = strlen(str1);
int slen2 = strlen(str2);
size_t slen1 = strlen(str1);
size_t slen2 = strlen(str2);
int cmp = strcmp(str1, str2);
if (slen1 != slen2)
return slen1 - slen2;
return pg_cmp_size(slen1, slen2);
if (cmp != 0)
return cmp;
else
return ((const LibraryInfo *) p1)->dbnum -
((const LibraryInfo *) p2)->dbnum;
return pg_cmp_s32(((const LibraryInfo *) p1)->dbnum,
((const LibraryInfo *) p2)->dbnum);
}

@ -16,6 +16,7 @@
#include <limits.h>
#include "common/blkreftable.h"
#include "common/int.h"
#include "common/logging.h"
#include "fe_utils/option_utils.h"
#include "lib/stringinfo.h"
@ -219,12 +220,7 @@ compare_block_numbers(const void *a, const void *b)
BlockNumber aa = *(BlockNumber *) a;
BlockNumber bb = *(BlockNumber *) b;
if (aa > bb)
return 1;
else if (aa == bb)
return 0;
else
return -1;
return pg_cmp_u32(aa, bb);
}
/*

@ -8,6 +8,7 @@
#include "postgres_fe.h"
#include "common.h"
#include "common/int.h"
#include "common/logging.h"
#include "crosstabview.h"
#include "pqexpbuffer.h"
@ -709,5 +710,5 @@ pivotFieldCompare(const void *a, const void *b)
static int
rankCompare(const void *a, const void *b)
{
return *((const int *) a) - *((const int *) b);
return pg_cmp_s32(*(const int *) a, *(const int *) b);
}

@ -14,6 +14,7 @@
#include "access/gin.h"
#include "access/ginblock.h"
#include "access/itup.h"
#include "common/int.h"
#include "catalog/pg_am_d.h"
#include "fmgr.h"
#include "lib/rbtree.h"
@ -489,12 +490,7 @@ ginCompareItemPointers(ItemPointer a, ItemPointer b)
uint64 ia = (uint64) GinItemPointerGetBlockNumber(a) << 32 | GinItemPointerGetOffsetNumber(a);
uint64 ib = (uint64) GinItemPointerGetBlockNumber(b) << 32 | GinItemPointerGetOffsetNumber(b);
if (ia == ib)
return 0;
else if (ia > ib)
return 1;
else
return -1;
return pg_cmp_u64(ia, ib);
}
extern int ginTraverseLock(Buffer buffer, bool searchMode);

Loading…
Cancel
Save