Age Owner Branch data TLA Line data Source code
1 : : /*-------------------------------------------------------------------------
2 : : *
3 : : * nbtcompare.c
4 : : * Comparison functions for btree access method.
5 : : *
6 : : * Portions Copyright (c) 1996-2026, 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 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.
29 : : *
30 : : * NOTE: it is critical that the comparison function impose a total order
31 : : * on all non-NULL values of the data type, and that the datatype's
32 : : * boolean comparison operators (= < >= etc) yield results consistent
33 : : * with the comparison routine. Otherwise bad behavior may ensue.
34 : : * (For example, the comparison operators must NOT punt when faced with
35 : : * NAN or other funny values; you must devise some collation sequence for
36 : : * all such values.) If the datatype is not trivial, this is most
37 : : * reliably done by having the boolean operators invoke the same
38 : : * three-way comparison code that the btree function does. Therefore,
39 : : * this file contains only btree support for "trivial" datatypes ---
40 : : * all others are in the /utils/adt/ files that implement their datatypes.
41 : : *
42 : : * NOTE: these routines must not leak memory, since memory allocated
43 : : * during an index access won't be recovered till end of query. This
44 : : * primarily affects comparison routines for toastable datatypes;
45 : : * they have to be careful to free any detoasted copy of an input datum.
46 : : *
47 : : * NOTE: we used to forbid comparison functions from returning INT_MIN,
48 : : * but that proves to be too error-prone because some platforms' versions
49 : : * of memcmp() etc can return INT_MIN. As a means of stress-testing
50 : : * callers, this file can be compiled with STRESS_SORT_INT_MIN defined
51 : : * to cause many of these functions to return INT_MIN or INT_MAX instead of
52 : : * their customary -1/+1. For production, though, that's not a good idea
53 : : * since users or third-party code might expect the traditional results.
54 : : *-------------------------------------------------------------------------
55 : : */
56 : : #include "postgres.h"
57 : :
58 : : #include <limits.h>
59 : :
60 : : #include "common/int.h"
61 : : #include "utils/builtins.h"
62 : : #include "utils/fmgrprotos.h"
63 : : #include "utils/skipsupport.h"
64 : : #include "utils/sortsupport.h"
65 : :
66 : : #ifdef STRESS_SORT_INT_MIN
67 : : #define A_LESS_THAN_B INT_MIN
68 : : #define A_GREATER_THAN_B INT_MAX
69 : : #else
70 : : #define A_LESS_THAN_B (-1)
71 : : #define A_GREATER_THAN_B 1
72 : : #endif
73 : :
74 : :
75 : : Datum
9649 tgl@sss.pgh.pa.us 76 :CBC 51741292 : btboolcmp(PG_FUNCTION_ARGS)
77 : : {
78 : 51741292 : bool a = PG_GETARG_BOOL(0);
79 : 51741292 : bool b = PG_GETARG_BOOL(1);
80 : :
81 : 51741292 : PG_RETURN_INT32((int32) a - (int32) b);
82 : : }
83 : :
84 : : static Datum
580 pg@bowt.ie 85 :UBC 0 : bool_decrement(Relation rel, Datum existing, bool *underflow)
86 : : {
87 : 0 : bool bexisting = DatumGetBool(existing);
88 : :
89 [ # # ]: 0 : if (bexisting == false)
90 : : {
91 : : /* return value is undefined */
92 : 0 : *underflow = true;
93 : 0 : return (Datum) 0;
94 : : }
95 : :
96 : 0 : *underflow = false;
97 : 0 : return BoolGetDatum(bexisting - 1);
98 : : }
99 : :
100 : : static Datum
101 : 0 : bool_increment(Relation rel, Datum existing, bool *overflow)
102 : : {
103 : 0 : bool bexisting = DatumGetBool(existing);
104 : :
105 [ # # ]: 0 : if (bexisting == true)
106 : : {
107 : : /* return value is undefined */
108 : 0 : *overflow = true;
109 : 0 : return (Datum) 0;
110 : : }
111 : :
112 : 0 : *overflow = false;
113 : 0 : return BoolGetDatum(bexisting + 1);
114 : : }
115 : :
116 : : Datum
117 : 0 : btboolskipsupport(PG_FUNCTION_ARGS)
118 : : {
119 : 0 : SkipSupport sksup = (SkipSupport) PG_GETARG_POINTER(0);
120 : :
121 : 0 : sksup->decrement = bool_decrement;
122 : 0 : sksup->increment = bool_increment;
123 : 0 : sksup->low_elem = BoolGetDatum(false);
124 : 0 : sksup->high_elem = BoolGetDatum(true);
125 : :
126 : 0 : PG_RETURN_VOID();
127 : : }
128 : :
129 : : Datum
9649 tgl@sss.pgh.pa.us 130 :CBC 7714867 : btint2cmp(PG_FUNCTION_ARGS)
131 : : {
132 : 7714867 : int16 a = PG_GETARG_INT16(0);
133 : 7714867 : int16 b = PG_GETARG_INT16(1);
134 : :
135 : 7714867 : PG_RETURN_INT32((int32) a - (int32) b);
136 : : }
137 : :
138 : : Datum
5447 139 : 6731 : btint2sortsupport(PG_FUNCTION_ARGS)
140 : : {
5261 bruce@momjian.us 141 : 6731 : SortSupport ssup = (SortSupport) PG_GETARG_POINTER(0);
142 : :
126 john.naylor@postgres 143 :GNC 6731 : ssup->comparator = ssup_datum_int32_cmp;
5447 tgl@sss.pgh.pa.us 144 :CBC 6731 : PG_RETURN_VOID();
145 : : }
146 : :
147 : : static Datum
580 pg@bowt.ie 148 :UBC 0 : int2_decrement(Relation rel, Datum existing, bool *underflow)
149 : : {
150 : 0 : int16 iexisting = DatumGetInt16(existing);
151 : :
152 [ # # ]: 0 : if (iexisting == PG_INT16_MIN)
153 : : {
154 : : /* return value is undefined */
155 : 0 : *underflow = true;
156 : 0 : return (Datum) 0;
157 : : }
158 : :
159 : 0 : *underflow = false;
160 : 0 : return Int16GetDatum(iexisting - 1);
161 : : }
162 : :
163 : : static Datum
580 pg@bowt.ie 164 :CBC 2 : int2_increment(Relation rel, Datum existing, bool *overflow)
165 : : {
166 : 2 : int16 iexisting = DatumGetInt16(existing);
167 : :
168 [ - + ]: 2 : if (iexisting == PG_INT16_MAX)
169 : : {
170 : : /* return value is undefined */
580 pg@bowt.ie 171 :UBC 0 : *overflow = true;
172 : 0 : return (Datum) 0;
173 : : }
174 : :
580 pg@bowt.ie 175 :CBC 2 : *overflow = false;
176 : 2 : return Int16GetDatum(iexisting + 1);
177 : : }
178 : :
179 : : Datum
180 : 149 : btint2skipsupport(PG_FUNCTION_ARGS)
181 : : {
182 : 149 : SkipSupport sksup = (SkipSupport) PG_GETARG_POINTER(0);
183 : :
184 : 149 : sksup->decrement = int2_decrement;
185 : 149 : sksup->increment = int2_increment;
186 : 149 : sksup->low_elem = Int16GetDatum(PG_INT16_MIN);
187 : 149 : sksup->high_elem = Int16GetDatum(PG_INT16_MAX);
188 : :
189 : 149 : PG_RETURN_VOID();
190 : : }
191 : :
192 : : Datum
9649 tgl@sss.pgh.pa.us 193 : 85000651 : btint4cmp(PG_FUNCTION_ARGS)
194 : : {
195 : 85000651 : int32 a = PG_GETARG_INT32(0);
196 : 85000651 : int32 b = PG_GETARG_INT32(1);
197 : :
0 heikki.linnakangas@i 198 :GNC 85000651 : PG_RETURN_INT32(pg_cmp_s32(a, b));
199 : : }
200 : :
201 : : Datum
5447 tgl@sss.pgh.pa.us 202 :CBC 114837 : btint4sortsupport(PG_FUNCTION_ARGS)
203 : : {
5261 bruce@momjian.us 204 : 114837 : SortSupport ssup = (SortSupport) PG_GETARG_POINTER(0);
205 : :
1678 john.naylor@postgres 206 : 114837 : ssup->comparator = ssup_datum_int32_cmp;
5447 tgl@sss.pgh.pa.us 207 : 114837 : PG_RETURN_VOID();
208 : : }
209 : :
210 : : static Datum
580 pg@bowt.ie 211 : 2696 : int4_decrement(Relation rel, Datum existing, bool *underflow)
212 : : {
213 : 2696 : int32 iexisting = DatumGetInt32(existing);
214 : :
215 [ - + ]: 2696 : if (iexisting == PG_INT32_MIN)
216 : : {
217 : : /* return value is undefined */
580 pg@bowt.ie 218 :UBC 0 : *underflow = true;
219 : 0 : return (Datum) 0;
220 : : }
221 : :
580 pg@bowt.ie 222 :CBC 2696 : *underflow = false;
223 : 2696 : return Int32GetDatum(iexisting - 1);
224 : : }
225 : :
226 : : static Datum
227 : 2608 : int4_increment(Relation rel, Datum existing, bool *overflow)
228 : : {
229 : 2608 : int32 iexisting = DatumGetInt32(existing);
230 : :
231 [ + + ]: 2608 : if (iexisting == PG_INT32_MAX)
232 : : {
233 : : /* return value is undefined */
234 : 20 : *overflow = true;
235 : 20 : return (Datum) 0;
236 : : }
237 : :
238 : 2588 : *overflow = false;
239 : 2588 : return Int32GetDatum(iexisting + 1);
240 : : }
241 : :
242 : : Datum
243 : 210 : btint4skipsupport(PG_FUNCTION_ARGS)
244 : : {
245 : 210 : SkipSupport sksup = (SkipSupport) PG_GETARG_POINTER(0);
246 : :
247 : 210 : sksup->decrement = int4_decrement;
248 : 210 : sksup->increment = int4_increment;
249 : 210 : sksup->low_elem = Int32GetDatum(PG_INT32_MIN);
250 : 210 : sksup->high_elem = Int32GetDatum(PG_INT32_MAX);
251 : :
252 : 210 : PG_RETURN_VOID();
253 : : }
254 : :
255 : : Datum
9649 tgl@sss.pgh.pa.us 256 : 14814387 : btint8cmp(PG_FUNCTION_ARGS)
257 : : {
258 : 14814387 : int64 a = PG_GETARG_INT64(0);
259 : 14814387 : int64 b = PG_GETARG_INT64(1);
260 : :
0 heikki.linnakangas@i 261 :GNC 14814387 : PG_RETURN_INT32(pg_cmp_s64(a, b));
262 : : }
263 : :
264 : : Datum
5447 tgl@sss.pgh.pa.us 265 :CBC 2369 : btint8sortsupport(PG_FUNCTION_ARGS)
266 : : {
5261 bruce@momjian.us 267 : 2369 : SortSupport ssup = (SortSupport) PG_GETARG_POINTER(0);
268 : :
87 john.naylor@postgres 269 :GNC 2369 : ssup->comparator = ssup_datum_int64_cmp;
5447 tgl@sss.pgh.pa.us 270 :CBC 2369 : PG_RETURN_VOID();
271 : : }
272 : :
273 : : static Datum
580 pg@bowt.ie 274 :UBC 0 : int8_decrement(Relation rel, Datum existing, bool *underflow)
275 : : {
276 : 0 : int64 iexisting = DatumGetInt64(existing);
277 : :
278 [ # # ]: 0 : if (iexisting == PG_INT64_MIN)
279 : : {
280 : : /* return value is undefined */
281 : 0 : *underflow = true;
282 : 0 : return (Datum) 0;
283 : : }
284 : :
285 : 0 : *underflow = false;
286 : 0 : return Int64GetDatum(iexisting - 1);
287 : : }
288 : :
289 : : static Datum
290 : 0 : int8_increment(Relation rel, Datum existing, bool *overflow)
291 : : {
292 : 0 : int64 iexisting = DatumGetInt64(existing);
293 : :
294 [ # # ]: 0 : if (iexisting == PG_INT64_MAX)
295 : : {
296 : : /* return value is undefined */
297 : 0 : *overflow = true;
298 : 0 : return (Datum) 0;
299 : : }
300 : :
301 : 0 : *overflow = false;
302 : 0 : return Int64GetDatum(iexisting + 1);
303 : : }
304 : :
305 : : Datum
306 : 0 : btint8skipsupport(PG_FUNCTION_ARGS)
307 : : {
308 : 0 : SkipSupport sksup = (SkipSupport) PG_GETARG_POINTER(0);
309 : :
310 : 0 : sksup->decrement = int8_decrement;
311 : 0 : sksup->increment = int8_increment;
312 : 0 : sksup->low_elem = Int64GetDatum(PG_INT64_MIN);
313 : 0 : sksup->high_elem = Int64GetDatum(PG_INT64_MAX);
314 : :
315 : 0 : PG_RETURN_VOID();
316 : : }
317 : :
318 : : Datum
8394 tgl@sss.pgh.pa.us 319 :CBC 13500 : btint48cmp(PG_FUNCTION_ARGS)
320 : : {
321 : 13500 : int32 a = PG_GETARG_INT32(0);
322 : 13500 : int64 b = PG_GETARG_INT64(1);
323 : :
324 [ + + ]: 13500 : if (a > b)
2953 325 : 5338 : PG_RETURN_INT32(A_GREATER_THAN_B);
8394 326 [ + + ]: 8162 : else if (a == b)
327 : 1680 : PG_RETURN_INT32(0);
328 : : else
2953 329 : 6482 : PG_RETURN_INT32(A_LESS_THAN_B);
330 : : }
331 : :
332 : : Datum
8394 333 : 216 : btint84cmp(PG_FUNCTION_ARGS)
334 : : {
335 : 216 : int64 a = PG_GETARG_INT64(0);
336 : 216 : int32 b = PG_GETARG_INT32(1);
337 : :
338 [ + + ]: 216 : if (a > b)
2953 339 : 79 : PG_RETURN_INT32(A_GREATER_THAN_B);
8394 340 [ + + ]: 137 : else if (a == b)
341 : 45 : PG_RETURN_INT32(0);
342 : : else
2953 343 : 92 : PG_RETURN_INT32(A_LESS_THAN_B);
344 : : }
345 : :
346 : : Datum
8394 347 : 31184 : btint24cmp(PG_FUNCTION_ARGS)
348 : : {
349 : 31184 : int16 a = PG_GETARG_INT16(0);
350 : 31184 : int32 b = PG_GETARG_INT32(1);
351 : :
352 [ + + ]: 31184 : if (a > b)
2953 353 : 17638 : PG_RETURN_INT32(A_GREATER_THAN_B);
8394 354 [ + + ]: 13546 : else if (a == b)
355 : 4087 : PG_RETURN_INT32(0);
356 : : else
2953 357 : 9459 : PG_RETURN_INT32(A_LESS_THAN_B);
358 : : }
359 : :
360 : : Datum
8394 361 : 954 : btint42cmp(PG_FUNCTION_ARGS)
362 : : {
363 : 954 : int32 a = PG_GETARG_INT32(0);
364 : 954 : int16 b = PG_GETARG_INT16(1);
365 : :
366 [ + + ]: 954 : if (a > b)
2953 367 : 219 : PG_RETURN_INT32(A_GREATER_THAN_B);
8394 368 [ + + ]: 735 : else if (a == b)
369 : 171 : PG_RETURN_INT32(0);
370 : : else
2953 371 : 564 : PG_RETURN_INT32(A_LESS_THAN_B);
372 : : }
373 : :
374 : : Datum
8394 375 : 47 : btint28cmp(PG_FUNCTION_ARGS)
376 : : {
377 : 47 : int16 a = PG_GETARG_INT16(0);
378 : 47 : int64 b = PG_GETARG_INT64(1);
379 : :
380 [ + + ]: 47 : if (a > b)
2953 381 : 6 : PG_RETURN_INT32(A_GREATER_THAN_B);
8394 382 [ + + ]: 41 : else if (a == b)
383 : 5 : PG_RETURN_INT32(0);
384 : : else
2953 385 : 36 : PG_RETURN_INT32(A_LESS_THAN_B);
386 : : }
387 : :
388 : : Datum
8394 389 : 17 : btint82cmp(PG_FUNCTION_ARGS)
390 : : {
391 : 17 : int64 a = PG_GETARG_INT64(0);
392 : 17 : int16 b = PG_GETARG_INT16(1);
393 : :
394 [ + + ]: 17 : if (a > b)
2953 395 : 6 : PG_RETURN_INT32(A_GREATER_THAN_B);
8394 396 [ + + ]: 11 : else if (a == b)
397 : 5 : PG_RETURN_INT32(0);
398 : : else
2953 399 : 6 : PG_RETURN_INT32(A_LESS_THAN_B);
400 : : }
401 : :
402 : : Datum
9649 403 : 134285978 : btoidcmp(PG_FUNCTION_ARGS)
404 : : {
405 : 134285978 : Oid a = PG_GETARG_OID(0);
406 : 134285978 : Oid b = PG_GETARG_OID(1);
407 : :
10651 bruce@momjian.us 408 [ + + ]: 134285978 : if (a > b)
2953 tgl@sss.pgh.pa.us 409 : 35394301 : PG_RETURN_INT32(A_GREATER_THAN_B);
10651 bruce@momjian.us 410 [ + + ]: 98891677 : else if (a == b)
9649 tgl@sss.pgh.pa.us 411 : 32580140 : PG_RETURN_INT32(0);
412 : : else
2953 413 : 66311537 : PG_RETURN_INT32(A_LESS_THAN_B);
414 : : }
415 : :
416 : : Datum
5447 417 : 73988 : btoidsortsupport(PG_FUNCTION_ARGS)
418 : : {
5261 bruce@momjian.us 419 : 73988 : SortSupport ssup = (SortSupport) PG_GETARG_POINTER(0);
420 : :
87 john.naylor@postgres 421 :GNC 73988 : ssup->comparator = ssup_datum_uint32_cmp;
5447 tgl@sss.pgh.pa.us 422 :CBC 73988 : PG_RETURN_VOID();
423 : : }
424 : :
425 : : static Datum
580 pg@bowt.ie 426 :UBC 0 : oid_decrement(Relation rel, Datum existing, bool *underflow)
427 : : {
428 : 0 : Oid oexisting = DatumGetObjectId(existing);
429 : :
430 [ # # ]: 0 : if (oexisting == InvalidOid)
431 : : {
432 : : /* return value is undefined */
433 : 0 : *underflow = true;
434 : 0 : return (Datum) 0;
435 : : }
436 : :
437 : 0 : *underflow = false;
438 : 0 : return ObjectIdGetDatum(oexisting - 1);
439 : : }
440 : :
441 : : static Datum
580 pg@bowt.ie 442 :CBC 1231 : oid_increment(Relation rel, Datum existing, bool *overflow)
443 : : {
444 : 1231 : Oid oexisting = DatumGetObjectId(existing);
445 : :
446 [ - + ]: 1231 : if (oexisting == OID_MAX)
447 : : {
448 : : /* return value is undefined */
580 pg@bowt.ie 449 :UBC 0 : *overflow = true;
450 : 0 : return (Datum) 0;
451 : : }
452 : :
580 pg@bowt.ie 453 :CBC 1231 : *overflow = false;
454 : 1231 : return ObjectIdGetDatum(oexisting + 1);
455 : : }
456 : :
457 : : Datum
458 : 1341 : btoidskipsupport(PG_FUNCTION_ARGS)
459 : : {
460 : 1341 : SkipSupport sksup = (SkipSupport) PG_GETARG_POINTER(0);
461 : :
462 : 1341 : sksup->decrement = oid_decrement;
463 : 1341 : sksup->increment = oid_increment;
464 : 1341 : sksup->low_elem = ObjectIdGetDatum(InvalidOid);
465 : 1341 : sksup->high_elem = ObjectIdGetDatum(OID_MAX);
466 : :
467 : 1341 : PG_RETURN_VOID();
468 : : }
469 : :
470 : : Datum
302 michael@paquier.xyz 471 : 14073 : btoid8cmp(PG_FUNCTION_ARGS)
472 : : {
473 : 14073 : Oid8 a = PG_GETARG_OID8(0);
474 : 14073 : Oid8 b = PG_GETARG_OID8(1);
475 : :
476 [ + + ]: 14073 : if (a > b)
477 : 57 : PG_RETURN_INT32(A_GREATER_THAN_B);
478 [ + + ]: 14016 : else if (a == b)
479 : 11648 : PG_RETURN_INT32(0);
480 : : else
481 : 2368 : PG_RETURN_INT32(A_LESS_THAN_B);
482 : : }
483 : :
484 : : Datum
485 : 84 : btoid8sortsupport(PG_FUNCTION_ARGS)
486 : : {
487 : 84 : SortSupport ssup = (SortSupport) PG_GETARG_POINTER(0);
488 : :
87 john.naylor@postgres 489 :GNC 84 : ssup->comparator = ssup_datum_uint64_cmp;
302 michael@paquier.xyz 490 :CBC 84 : PG_RETURN_VOID();
491 : : }
492 : :
493 : : static Datum
302 michael@paquier.xyz 494 :UBC 0 : oid8_decrement(Relation rel, Datum existing, bool *underflow)
495 : : {
496 : 0 : Oid8 oexisting = DatumGetObjectId8(existing);
497 : :
498 [ # # ]: 0 : if (oexisting == InvalidOid8)
499 : : {
500 : : /* return value is undefined */
501 : 0 : *underflow = true;
502 : 0 : return (Datum) 0;
503 : : }
504 : :
505 : 0 : *underflow = false;
506 : 0 : return ObjectId8GetDatum(oexisting - 1);
507 : : }
508 : :
509 : : static Datum
302 michael@paquier.xyz 510 :GBC 8 : oid8_increment(Relation rel, Datum existing, bool *overflow)
511 : : {
512 : 8 : Oid8 oexisting = DatumGetObjectId8(existing);
513 : :
514 [ - + ]: 8 : if (oexisting == OID8_MAX)
515 : : {
516 : : /* return value is undefined */
302 michael@paquier.xyz 517 :UBC 0 : *overflow = true;
518 : 0 : return (Datum) 0;
519 : : }
520 : :
302 michael@paquier.xyz 521 :GBC 8 : *overflow = false;
522 : 8 : return ObjectId8GetDatum(oexisting + 1);
523 : : }
524 : :
525 : : Datum
526 : 4 : btoid8skipsupport(PG_FUNCTION_ARGS)
527 : : {
528 : 4 : SkipSupport sksup = (SkipSupport) PG_GETARG_POINTER(0);
529 : :
530 : 4 : sksup->decrement = oid8_decrement;
531 : 4 : sksup->increment = oid8_increment;
532 : 4 : sksup->low_elem = ObjectId8GetDatum(InvalidOid8);
533 : 4 : sksup->high_elem = ObjectId8GetDatum(OID8_MAX);
534 : :
535 : 4 : PG_RETURN_VOID();
536 : : }
537 : :
538 : : Datum
9649 tgl@sss.pgh.pa.us 539 :CBC 4965129 : btoidvectorcmp(PG_FUNCTION_ARGS)
540 : : {
7891 541 : 4965129 : oidvector *a = (oidvector *) PG_GETARG_POINTER(0);
542 : 4965129 : oidvector *b = (oidvector *) PG_GETARG_POINTER(1);
543 : : int i;
544 : :
269 545 : 4965129 : check_valid_oidvector(a);
546 : 4965129 : check_valid_oidvector(b);
547 : :
548 : : /* We arbitrarily choose to sort first by vector length */
7891 549 [ + + ]: 4965129 : if (a->dim1 != b->dim1)
550 : 863288 : PG_RETURN_INT32(a->dim1 - b->dim1);
551 : :
552 [ + + ]: 7138990 : for (i = 0; i < a->dim1; i++)
553 : : {
554 [ + + ]: 5391724 : if (a->values[i] != b->values[i])
555 : : {
556 [ + + ]: 2354575 : if (a->values[i] > b->values[i])
2953 557 : 1164135 : PG_RETURN_INT32(A_GREATER_THAN_B);
558 : : else
559 : 1190440 : PG_RETURN_INT32(A_LESS_THAN_B);
560 : : }
561 : : }
9649 562 : 1747266 : PG_RETURN_INT32(0);
563 : : }
564 : :
565 : : Datum
566 : 47311853 : btcharcmp(PG_FUNCTION_ARGS)
567 : : {
568 : 47311853 : char a = PG_GETARG_CHAR(0);
569 : 47311853 : char b = PG_GETARG_CHAR(1);
570 : :
571 : : /* Be careful to compare chars as unsigned */
572 : 47311853 : PG_RETURN_INT32((int32) ((uint8) a) - (int32) ((uint8) b));
573 : : }
574 : :
575 : : static Datum
580 pg@bowt.ie 576 :UBC 0 : char_decrement(Relation rel, Datum existing, bool *underflow)
577 : : {
457 peter@eisentraut.org 578 : 0 : uint8 cexisting = DatumGetUInt8(existing);
579 : :
580 pg@bowt.ie 580 [ # # ]: 0 : if (cexisting == 0)
581 : : {
582 : : /* return value is undefined */
583 : 0 : *underflow = true;
584 : 0 : return (Datum) 0;
585 : : }
586 : :
587 : 0 : *underflow = false;
588 : 0 : return CharGetDatum((uint8) cexisting - 1);
589 : : }
590 : :
591 : : static Datum
592 : 0 : char_increment(Relation rel, Datum existing, bool *overflow)
593 : : {
457 peter@eisentraut.org 594 : 0 : uint8 cexisting = DatumGetUInt8(existing);
595 : :
580 pg@bowt.ie 596 [ # # ]: 0 : if (cexisting == UCHAR_MAX)
597 : : {
598 : : /* return value is undefined */
599 : 0 : *overflow = true;
600 : 0 : return (Datum) 0;
601 : : }
602 : :
603 : 0 : *overflow = false;
604 : 0 : return CharGetDatum((uint8) cexisting + 1);
605 : : }
606 : :
607 : : Datum
608 : 0 : btcharskipsupport(PG_FUNCTION_ARGS)
609 : : {
610 : 0 : SkipSupport sksup = (SkipSupport) PG_GETARG_POINTER(0);
611 : :
612 : 0 : sksup->decrement = char_decrement;
613 : 0 : sksup->increment = char_increment;
614 : :
615 : : /* btcharcmp compares chars as unsigned */
616 : 0 : sksup->low_elem = UInt8GetDatum(0);
617 : 0 : sksup->high_elem = UInt8GetDatum(UCHAR_MAX);
618 : :
619 : 0 : PG_RETURN_VOID();
620 : : }
|