Branch data 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 "utils/builtins.h"
61 : : #include "utils/fmgrprotos.h"
62 : : #include "utils/skipsupport.h"
63 : : #include "utils/sortsupport.h"
64 : :
65 : : #ifdef STRESS_SORT_INT_MIN
66 : : #define A_LESS_THAN_B INT_MIN
67 : : #define A_GREATER_THAN_B INT_MAX
68 : : #else
69 : : #define A_LESS_THAN_B (-1)
70 : : #define A_GREATER_THAN_B 1
71 : : #endif
72 : :
73 : :
74 : : Datum
75 : 39491994 : btboolcmp(PG_FUNCTION_ARGS)
76 : : {
77 : 39491994 : bool a = PG_GETARG_BOOL(0);
78 : 39491994 : bool b = PG_GETARG_BOOL(1);
79 : :
80 : 39491994 : PG_RETURN_INT32((int32) a - (int32) b);
81 : : }
82 : :
83 : : static Datum
84 : 0 : bool_decrement(Relation rel, Datum existing, bool *underflow)
85 : : {
86 : 0 : bool bexisting = DatumGetBool(existing);
87 : :
88 [ # # ]: 0 : if (bexisting == false)
89 : : {
90 : : /* return value is undefined */
91 : 0 : *underflow = true;
92 : 0 : return (Datum) 0;
93 : : }
94 : :
95 : 0 : *underflow = false;
96 : 0 : return BoolGetDatum(bexisting - 1);
97 : : }
98 : :
99 : : static Datum
100 : 0 : bool_increment(Relation rel, Datum existing, bool *overflow)
101 : : {
102 : 0 : bool bexisting = DatumGetBool(existing);
103 : :
104 [ # # ]: 0 : if (bexisting == true)
105 : : {
106 : : /* return value is undefined */
107 : 0 : *overflow = true;
108 : 0 : return (Datum) 0;
109 : : }
110 : :
111 : 0 : *overflow = false;
112 : 0 : return BoolGetDatum(bexisting + 1);
113 : : }
114 : :
115 : : Datum
116 : 0 : btboolskipsupport(PG_FUNCTION_ARGS)
117 : : {
118 : 0 : SkipSupport sksup = (SkipSupport) PG_GETARG_POINTER(0);
119 : :
120 : 0 : sksup->decrement = bool_decrement;
121 : 0 : sksup->increment = bool_increment;
122 : 0 : sksup->low_elem = BoolGetDatum(false);
123 : 0 : sksup->high_elem = BoolGetDatum(true);
124 : :
125 : 0 : PG_RETURN_VOID();
126 : : }
127 : :
128 : : Datum
129 : 8981193 : btint2cmp(PG_FUNCTION_ARGS)
130 : : {
131 : 8981193 : int16 a = PG_GETARG_INT16(0);
132 : 8981193 : int16 b = PG_GETARG_INT16(1);
133 : :
134 : 8981193 : PG_RETURN_INT32((int32) a - (int32) b);
135 : : }
136 : :
137 : : Datum
138 : 6488 : btint2sortsupport(PG_FUNCTION_ARGS)
139 : : {
140 : 6488 : SortSupport ssup = (SortSupport) PG_GETARG_POINTER(0);
141 : :
142 : 6488 : ssup->comparator = ssup_datum_int32_cmp;
143 : 6488 : PG_RETURN_VOID();
144 : : }
145 : :
146 : : static Datum
147 : 0 : int2_decrement(Relation rel, Datum existing, bool *underflow)
148 : : {
149 : 0 : int16 iexisting = DatumGetInt16(existing);
150 : :
151 [ # # ]: 0 : if (iexisting == PG_INT16_MIN)
152 : : {
153 : : /* return value is undefined */
154 : 0 : *underflow = true;
155 : 0 : return (Datum) 0;
156 : : }
157 : :
158 : 0 : *underflow = false;
159 : 0 : return Int16GetDatum(iexisting - 1);
160 : : }
161 : :
162 : : static Datum
163 : 2 : int2_increment(Relation rel, Datum existing, bool *overflow)
164 : : {
165 : 2 : int16 iexisting = DatumGetInt16(existing);
166 : :
167 [ - + ]: 2 : if (iexisting == PG_INT16_MAX)
168 : : {
169 : : /* return value is undefined */
170 : 0 : *overflow = true;
171 : 0 : return (Datum) 0;
172 : : }
173 : :
174 : 2 : *overflow = false;
175 : 2 : return Int16GetDatum(iexisting + 1);
176 : : }
177 : :
178 : : Datum
179 : 133 : btint2skipsupport(PG_FUNCTION_ARGS)
180 : : {
181 : 133 : SkipSupport sksup = (SkipSupport) PG_GETARG_POINTER(0);
182 : :
183 : 133 : sksup->decrement = int2_decrement;
184 : 133 : sksup->increment = int2_increment;
185 : 133 : sksup->low_elem = Int16GetDatum(PG_INT16_MIN);
186 : 133 : sksup->high_elem = Int16GetDatum(PG_INT16_MAX);
187 : :
188 : 133 : PG_RETURN_VOID();
189 : : }
190 : :
191 : : Datum
192 : 74343242 : btint4cmp(PG_FUNCTION_ARGS)
193 : : {
194 : 74343242 : int32 a = PG_GETARG_INT32(0);
195 : 74343242 : int32 b = PG_GETARG_INT32(1);
196 : :
197 [ + + ]: 74343242 : if (a > b)
198 : 26024995 : PG_RETURN_INT32(A_GREATER_THAN_B);
199 [ + + ]: 48318247 : else if (a == b)
200 : 14367911 : PG_RETURN_INT32(0);
201 : : else
202 : 33950336 : PG_RETURN_INT32(A_LESS_THAN_B);
203 : : }
204 : :
205 : : Datum
206 : 116879 : btint4sortsupport(PG_FUNCTION_ARGS)
207 : : {
208 : 116879 : SortSupport ssup = (SortSupport) PG_GETARG_POINTER(0);
209 : :
210 : 116879 : ssup->comparator = ssup_datum_int32_cmp;
211 : 116879 : PG_RETURN_VOID();
212 : : }
213 : :
214 : : static Datum
215 : 2644 : int4_decrement(Relation rel, Datum existing, bool *underflow)
216 : : {
217 : 2644 : int32 iexisting = DatumGetInt32(existing);
218 : :
219 [ - + ]: 2644 : if (iexisting == PG_INT32_MIN)
220 : : {
221 : : /* return value is undefined */
222 : 0 : *underflow = true;
223 : 0 : return (Datum) 0;
224 : : }
225 : :
226 : 2644 : *underflow = false;
227 : 2644 : return Int32GetDatum(iexisting - 1);
228 : : }
229 : :
230 : : static Datum
231 : 2608 : int4_increment(Relation rel, Datum existing, bool *overflow)
232 : : {
233 : 2608 : int32 iexisting = DatumGetInt32(existing);
234 : :
235 [ + + ]: 2608 : if (iexisting == PG_INT32_MAX)
236 : : {
237 : : /* return value is undefined */
238 : 20 : *overflow = true;
239 : 20 : return (Datum) 0;
240 : : }
241 : :
242 : 2588 : *overflow = false;
243 : 2588 : return Int32GetDatum(iexisting + 1);
244 : : }
245 : :
246 : : Datum
247 : 202 : btint4skipsupport(PG_FUNCTION_ARGS)
248 : : {
249 : 202 : SkipSupport sksup = (SkipSupport) PG_GETARG_POINTER(0);
250 : :
251 : 202 : sksup->decrement = int4_decrement;
252 : 202 : sksup->increment = int4_increment;
253 : 202 : sksup->low_elem = Int32GetDatum(PG_INT32_MIN);
254 : 202 : sksup->high_elem = Int32GetDatum(PG_INT32_MAX);
255 : :
256 : 202 : PG_RETURN_VOID();
257 : : }
258 : :
259 : : Datum
260 : 8355269 : btint8cmp(PG_FUNCTION_ARGS)
261 : : {
262 : 8355269 : int64 a = PG_GETARG_INT64(0);
263 : 8355269 : int64 b = PG_GETARG_INT64(1);
264 : :
265 [ + + ]: 8355269 : if (a > b)
266 : 4870301 : PG_RETURN_INT32(A_GREATER_THAN_B);
267 [ + + ]: 3484968 : else if (a == b)
268 : 424246 : PG_RETURN_INT32(0);
269 : : else
270 : 3060722 : PG_RETURN_INT32(A_LESS_THAN_B);
271 : : }
272 : :
273 : : Datum
274 : 2291 : btint8sortsupport(PG_FUNCTION_ARGS)
275 : : {
276 : 2291 : SortSupport ssup = (SortSupport) PG_GETARG_POINTER(0);
277 : :
278 : 2291 : ssup->comparator = ssup_datum_signed_cmp;
279 : 2291 : PG_RETURN_VOID();
280 : : }
281 : :
282 : : static Datum
283 : 0 : int8_decrement(Relation rel, Datum existing, bool *underflow)
284 : : {
285 : 0 : int64 iexisting = DatumGetInt64(existing);
286 : :
287 [ # # ]: 0 : if (iexisting == PG_INT64_MIN)
288 : : {
289 : : /* return value is undefined */
290 : 0 : *underflow = true;
291 : 0 : return (Datum) 0;
292 : : }
293 : :
294 : 0 : *underflow = false;
295 : 0 : return Int64GetDatum(iexisting - 1);
296 : : }
297 : :
298 : : static Datum
299 : 0 : int8_increment(Relation rel, Datum existing, bool *overflow)
300 : : {
301 : 0 : int64 iexisting = DatumGetInt64(existing);
302 : :
303 [ # # ]: 0 : if (iexisting == PG_INT64_MAX)
304 : : {
305 : : /* return value is undefined */
306 : 0 : *overflow = true;
307 : 0 : return (Datum) 0;
308 : : }
309 : :
310 : 0 : *overflow = false;
311 : 0 : return Int64GetDatum(iexisting + 1);
312 : : }
313 : :
314 : : Datum
315 : 0 : btint8skipsupport(PG_FUNCTION_ARGS)
316 : : {
317 : 0 : SkipSupport sksup = (SkipSupport) PG_GETARG_POINTER(0);
318 : :
319 : 0 : sksup->decrement = int8_decrement;
320 : 0 : sksup->increment = int8_increment;
321 : 0 : sksup->low_elem = Int64GetDatum(PG_INT64_MIN);
322 : 0 : sksup->high_elem = Int64GetDatum(PG_INT64_MAX);
323 : :
324 : 0 : PG_RETURN_VOID();
325 : : }
326 : :
327 : : Datum
328 : 4468 : btint48cmp(PG_FUNCTION_ARGS)
329 : : {
330 : 4468 : int32 a = PG_GETARG_INT32(0);
331 : 4468 : int64 b = PG_GETARG_INT64(1);
332 : :
333 [ + + ]: 4468 : if (a > b)
334 : 2078 : PG_RETURN_INT32(A_GREATER_THAN_B);
335 [ + + ]: 2390 : else if (a == b)
336 : 1656 : PG_RETURN_INT32(0);
337 : : else
338 : 734 : PG_RETURN_INT32(A_LESS_THAN_B);
339 : : }
340 : :
341 : : Datum
342 : 162 : btint84cmp(PG_FUNCTION_ARGS)
343 : : {
344 : 162 : int64 a = PG_GETARG_INT64(0);
345 : 162 : int32 b = PG_GETARG_INT32(1);
346 : :
347 [ + + ]: 162 : if (a > b)
348 : 58 : PG_RETURN_INT32(A_GREATER_THAN_B);
349 [ + + ]: 104 : else if (a == b)
350 : 42 : PG_RETURN_INT32(0);
351 : : else
352 : 62 : PG_RETURN_INT32(A_LESS_THAN_B);
353 : : }
354 : :
355 : : Datum
356 : 33509 : btint24cmp(PG_FUNCTION_ARGS)
357 : : {
358 : 33509 : int16 a = PG_GETARG_INT16(0);
359 : 33509 : int32 b = PG_GETARG_INT32(1);
360 : :
361 [ + + ]: 33509 : if (a > b)
362 : 18258 : PG_RETURN_INT32(A_GREATER_THAN_B);
363 [ + + ]: 15251 : else if (a == b)
364 : 4711 : PG_RETURN_INT32(0);
365 : : else
366 : 10540 : PG_RETURN_INT32(A_LESS_THAN_B);
367 : : }
368 : :
369 : : Datum
370 : 992 : btint42cmp(PG_FUNCTION_ARGS)
371 : : {
372 : 992 : int32 a = PG_GETARG_INT32(0);
373 : 992 : int16 b = PG_GETARG_INT16(1);
374 : :
375 [ + + ]: 992 : if (a > b)
376 : 81 : PG_RETURN_INT32(A_GREATER_THAN_B);
377 [ + + ]: 911 : else if (a == b)
378 : 213 : PG_RETURN_INT32(0);
379 : : else
380 : 698 : PG_RETURN_INT32(A_LESS_THAN_B);
381 : : }
382 : :
383 : : Datum
384 : 47 : btint28cmp(PG_FUNCTION_ARGS)
385 : : {
386 : 47 : int16 a = PG_GETARG_INT16(0);
387 : 47 : int64 b = PG_GETARG_INT64(1);
388 : :
389 [ + + ]: 47 : if (a > b)
390 : 6 : PG_RETURN_INT32(A_GREATER_THAN_B);
391 [ + + ]: 41 : else if (a == b)
392 : 5 : PG_RETURN_INT32(0);
393 : : else
394 : 36 : PG_RETURN_INT32(A_LESS_THAN_B);
395 : : }
396 : :
397 : : Datum
398 : 17 : btint82cmp(PG_FUNCTION_ARGS)
399 : : {
400 : 17 : int64 a = PG_GETARG_INT64(0);
401 : 17 : int16 b = PG_GETARG_INT16(1);
402 : :
403 [ + + ]: 17 : if (a > b)
404 : 6 : PG_RETURN_INT32(A_GREATER_THAN_B);
405 [ + + ]: 11 : else if (a == b)
406 : 5 : PG_RETURN_INT32(0);
407 : : else
408 : 6 : PG_RETURN_INT32(A_LESS_THAN_B);
409 : : }
410 : :
411 : : Datum
412 : 149830749 : btoidcmp(PG_FUNCTION_ARGS)
413 : : {
414 : 149830749 : Oid a = PG_GETARG_OID(0);
415 : 149830749 : Oid b = PG_GETARG_OID(1);
416 : :
417 [ + + ]: 149830749 : if (a > b)
418 : 40419608 : PG_RETURN_INT32(A_GREATER_THAN_B);
419 [ + + ]: 109411141 : else if (a == b)
420 : 35272805 : PG_RETURN_INT32(0);
421 : : else
422 : 74138336 : PG_RETURN_INT32(A_LESS_THAN_B);
423 : : }
424 : :
425 : : Datum
426 : 73708 : btoidsortsupport(PG_FUNCTION_ARGS)
427 : : {
428 : 73708 : SortSupport ssup = (SortSupport) PG_GETARG_POINTER(0);
429 : :
430 : 73708 : ssup->comparator = ssup_datum_unsigned_cmp;
431 : 73708 : PG_RETURN_VOID();
432 : : }
433 : :
434 : : static Datum
435 : 0 : oid_decrement(Relation rel, Datum existing, bool *underflow)
436 : : {
437 : 0 : Oid oexisting = DatumGetObjectId(existing);
438 : :
439 [ # # ]: 0 : if (oexisting == InvalidOid)
440 : : {
441 : : /* return value is undefined */
442 : 0 : *underflow = true;
443 : 0 : return (Datum) 0;
444 : : }
445 : :
446 : 0 : *underflow = false;
447 : 0 : return ObjectIdGetDatum(oexisting - 1);
448 : : }
449 : :
450 : : static Datum
451 : 1230 : oid_increment(Relation rel, Datum existing, bool *overflow)
452 : : {
453 : 1230 : Oid oexisting = DatumGetObjectId(existing);
454 : :
455 [ - + ]: 1230 : if (oexisting == OID_MAX)
456 : : {
457 : : /* return value is undefined */
458 : 0 : *overflow = true;
459 : 0 : return (Datum) 0;
460 : : }
461 : :
462 : 1230 : *overflow = false;
463 : 1230 : return ObjectIdGetDatum(oexisting + 1);
464 : : }
465 : :
466 : : Datum
467 : 1258 : btoidskipsupport(PG_FUNCTION_ARGS)
468 : : {
469 : 1258 : SkipSupport sksup = (SkipSupport) PG_GETARG_POINTER(0);
470 : :
471 : 1258 : sksup->decrement = oid_decrement;
472 : 1258 : sksup->increment = oid_increment;
473 : 1258 : sksup->low_elem = ObjectIdGetDatum(InvalidOid);
474 : 1258 : sksup->high_elem = ObjectIdGetDatum(OID_MAX);
475 : :
476 : 1258 : PG_RETURN_VOID();
477 : : }
478 : :
479 : : Datum
480 : 15 : btoid8cmp(PG_FUNCTION_ARGS)
481 : : {
482 : 15 : Oid8 a = PG_GETARG_OID8(0);
483 : 15 : Oid8 b = PG_GETARG_OID8(1);
484 : :
485 [ + + ]: 15 : if (a > b)
486 : 5 : PG_RETURN_INT32(A_GREATER_THAN_B);
487 [ + + ]: 10 : else if (a == b)
488 : 5 : PG_RETURN_INT32(0);
489 : : else
490 : 5 : PG_RETURN_INT32(A_LESS_THAN_B);
491 : : }
492 : :
493 : : Datum
494 : 8 : btoid8sortsupport(PG_FUNCTION_ARGS)
495 : : {
496 : 8 : SortSupport ssup = (SortSupport) PG_GETARG_POINTER(0);
497 : :
498 : 8 : ssup->comparator = ssup_datum_unsigned_cmp;
499 : 8 : PG_RETURN_VOID();
500 : : }
501 : :
502 : : static Datum
503 : 0 : oid8_decrement(Relation rel, Datum existing, bool *underflow)
504 : : {
505 : 0 : Oid8 oexisting = DatumGetObjectId8(existing);
506 : :
507 [ # # ]: 0 : if (oexisting == InvalidOid8)
508 : : {
509 : : /* return value is undefined */
510 : 0 : *underflow = true;
511 : 0 : return (Datum) 0;
512 : : }
513 : :
514 : 0 : *underflow = false;
515 : 0 : return ObjectId8GetDatum(oexisting - 1);
516 : : }
517 : :
518 : : static Datum
519 : 0 : oid8_increment(Relation rel, Datum existing, bool *overflow)
520 : : {
521 : 0 : Oid8 oexisting = DatumGetObjectId8(existing);
522 : :
523 [ # # ]: 0 : if (oexisting == OID8_MAX)
524 : : {
525 : : /* return value is undefined */
526 : 0 : *overflow = true;
527 : 0 : return (Datum) 0;
528 : : }
529 : :
530 : 0 : *overflow = false;
531 : 0 : return ObjectId8GetDatum(oexisting + 1);
532 : : }
533 : :
534 : : Datum
535 : 0 : btoid8skipsupport(PG_FUNCTION_ARGS)
536 : : {
537 : 0 : SkipSupport sksup = (SkipSupport) PG_GETARG_POINTER(0);
538 : :
539 : 0 : sksup->decrement = oid8_decrement;
540 : 0 : sksup->increment = oid8_increment;
541 : 0 : sksup->low_elem = ObjectId8GetDatum(InvalidOid8);
542 : 0 : sksup->high_elem = ObjectId8GetDatum(OID8_MAX);
543 : :
544 : 0 : PG_RETURN_VOID();
545 : : }
546 : :
547 : : Datum
548 : 4543698 : btoidvectorcmp(PG_FUNCTION_ARGS)
549 : : {
550 : 4543698 : oidvector *a = (oidvector *) PG_GETARG_POINTER(0);
551 : 4543698 : oidvector *b = (oidvector *) PG_GETARG_POINTER(1);
552 : : int i;
553 : :
554 : 4543698 : check_valid_oidvector(a);
555 : 4543698 : check_valid_oidvector(b);
556 : :
557 : : /* We arbitrarily choose to sort first by vector length */
558 [ + + ]: 4543698 : if (a->dim1 != b->dim1)
559 : 718912 : PG_RETURN_INT32(a->dim1 - b->dim1);
560 : :
561 [ + + ]: 6562513 : for (i = 0; i < a->dim1; i++)
562 : : {
563 [ + + ]: 4970042 : if (a->values[i] != b->values[i])
564 : : {
565 [ + + ]: 2232315 : if (a->values[i] > b->values[i])
566 : 1050647 : PG_RETURN_INT32(A_GREATER_THAN_B);
567 : : else
568 : 1181668 : PG_RETURN_INT32(A_LESS_THAN_B);
569 : : }
570 : : }
571 : 1592471 : PG_RETURN_INT32(0);
572 : : }
573 : :
574 : : Datum
575 : 38548807 : btcharcmp(PG_FUNCTION_ARGS)
576 : : {
577 : 38548807 : char a = PG_GETARG_CHAR(0);
578 : 38548807 : char b = PG_GETARG_CHAR(1);
579 : :
580 : : /* Be careful to compare chars as unsigned */
581 : 38548807 : PG_RETURN_INT32((int32) ((uint8) a) - (int32) ((uint8) b));
582 : : }
583 : :
584 : : static Datum
585 : 0 : char_decrement(Relation rel, Datum existing, bool *underflow)
586 : : {
587 : 0 : uint8 cexisting = DatumGetUInt8(existing);
588 : :
589 [ # # ]: 0 : if (cexisting == 0)
590 : : {
591 : : /* return value is undefined */
592 : 0 : *underflow = true;
593 : 0 : return (Datum) 0;
594 : : }
595 : :
596 : 0 : *underflow = false;
597 : 0 : return CharGetDatum((uint8) cexisting - 1);
598 : : }
599 : :
600 : : static Datum
601 : 0 : char_increment(Relation rel, Datum existing, bool *overflow)
602 : : {
603 : 0 : uint8 cexisting = DatumGetUInt8(existing);
604 : :
605 [ # # ]: 0 : if (cexisting == UCHAR_MAX)
606 : : {
607 : : /* return value is undefined */
608 : 0 : *overflow = true;
609 : 0 : return (Datum) 0;
610 : : }
611 : :
612 : 0 : *overflow = false;
613 : 0 : return CharGetDatum((uint8) cexisting + 1);
614 : : }
615 : :
616 : : Datum
617 : 0 : btcharskipsupport(PG_FUNCTION_ARGS)
618 : : {
619 : 0 : SkipSupport sksup = (SkipSupport) PG_GETARG_POINTER(0);
620 : :
621 : 0 : sksup->decrement = char_decrement;
622 : 0 : sksup->increment = char_increment;
623 : :
624 : : /* btcharcmp compares chars as unsigned */
625 : 0 : sksup->low_elem = UInt8GetDatum(0);
626 : 0 : sksup->high_elem = UInt8GetDatum(UCHAR_MAX);
627 : :
628 : 0 : PG_RETURN_VOID();
629 : : }
|