1 : /*-------------------------------------------------------------------------
2 : *
3 : * nbtcompare.c
4 : * Comparison functions for btree access method.
5 : *
6 : * Portions Copyright (c) 1996-2008, PostgreSQL Global Development Group
7 : * Portions Copyright (c) 1994, Regents of the University of California
8 : *
9 : *
10 : * IDENTIFICATION
11 : * $PostgreSQL: pgsql/src/backend/access/nbtree/nbtcompare.c,v 1.54 2007/01/09 02:14:10 tgl Exp $
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 :
53 :
54 : Datum
55 : btboolcmp(PG_FUNCTION_ARGS)
56 135790 : {
57 135790 : bool a = PG_GETARG_BOOL(0);
58 135790 : bool b = PG_GETARG_BOOL(1);
59 :
60 135790 : PG_RETURN_INT32((int32) a - (int32) b);
61 : }
62 :
63 : Datum
64 : btint2cmp(PG_FUNCTION_ARGS)
65 155568 : {
66 155568 : int16 a = PG_GETARG_INT16(0);
67 155568 : int16 b = PG_GETARG_INT16(1);
68 :
69 155568 : PG_RETURN_INT32((int32) a - (int32) b);
70 : }
71 :
72 : Datum
73 : btint4cmp(PG_FUNCTION_ARGS)
74 2384271 : {
75 2384271 : int32 a = PG_GETARG_INT32(0);
76 2384271 : int32 b = PG_GETARG_INT32(1);
77 :
78 2384271 : if (a > b)
79 698453 : PG_RETURN_INT32(1);
80 1685818 : else if (a == b)
81 613370 : PG_RETURN_INT32(0);
82 : else
83 1072448 : PG_RETURN_INT32(-1);
84 : }
85 :
86 : Datum
87 : btint8cmp(PG_FUNCTION_ARGS)
88 450 : {
89 450 : int64 a = PG_GETARG_INT64(0);
90 450 : int64 b = PG_GETARG_INT64(1);
91 :
92 450 : if (a > b)
93 172 : PG_RETURN_INT32(1);
94 278 : else if (a == b)
95 174 : PG_RETURN_INT32(0);
96 : else
97 104 : PG_RETURN_INT32(-1);
98 : }
99 :
100 : Datum
101 : btint48cmp(PG_FUNCTION_ARGS)
102 5 : {
103 5 : int32 a = PG_GETARG_INT32(0);
104 5 : int64 b = PG_GETARG_INT64(1);
105 :
106 5 : if (a > b)
107 0 : PG_RETURN_INT32(1);
108 5 : else if (a == b)
109 2 : PG_RETURN_INT32(0);
110 : else
111 3 : PG_RETURN_INT32(-1);
112 : }
113 :
114 : Datum
115 : btint84cmp(PG_FUNCTION_ARGS)
116 0 : {
117 0 : int64 a = PG_GETARG_INT64(0);
118 0 : int32 b = PG_GETARG_INT32(1);
119 :
120 0 : if (a > b)
121 0 : PG_RETURN_INT32(1);
122 0 : else if (a == b)
123 0 : PG_RETURN_INT32(0);
124 : else
125 0 : PG_RETURN_INT32(-1);
126 : }
127 :
128 : Datum
129 : btint24cmp(PG_FUNCTION_ARGS)
130 959 : {
131 959 : int16 a = PG_GETARG_INT16(0);
132 959 : int32 b = PG_GETARG_INT32(1);
133 :
134 959 : if (a > b)
135 593 : PG_RETURN_INT32(1);
136 366 : else if (a == b)
137 48 : PG_RETURN_INT32(0);
138 : else
139 318 : PG_RETURN_INT32(-1);
140 : }
141 :
142 : Datum
143 : btint42cmp(PG_FUNCTION_ARGS)
144 0 : {
145 0 : int32 a = PG_GETARG_INT32(0);
146 0 : int16 b = PG_GETARG_INT16(1);
147 :
148 0 : if (a > b)
149 0 : PG_RETURN_INT32(1);
150 0 : else if (a == b)
151 0 : PG_RETURN_INT32(0);
152 : else
153 0 : PG_RETURN_INT32(-1);
154 : }
155 :
156 : Datum
157 : btint28cmp(PG_FUNCTION_ARGS)
158 0 : {
159 0 : int16 a = PG_GETARG_INT16(0);
160 0 : int64 b = PG_GETARG_INT64(1);
161 :
162 0 : if (a > b)
163 0 : PG_RETURN_INT32(1);
164 0 : else if (a == b)
165 0 : PG_RETURN_INT32(0);
166 : else
167 0 : PG_RETURN_INT32(-1);
168 : }
169 :
170 : Datum
171 : btint82cmp(PG_FUNCTION_ARGS)
172 0 : {
173 0 : int64 a = PG_GETARG_INT64(0);
174 0 : int16 b = PG_GETARG_INT16(1);
175 :
176 0 : if (a > b)
177 0 : PG_RETURN_INT32(1);
178 0 : else if (a == b)
179 0 : PG_RETURN_INT32(0);
180 : else
181 0 : PG_RETURN_INT32(-1);
182 : }
183 :
184 : Datum
185 : btoidcmp(PG_FUNCTION_ARGS)
186 2922812 : {
187 2922812 : Oid a = PG_GETARG_OID(0);
188 2922812 : Oid b = PG_GETARG_OID(1);
189 :
190 2922812 : if (a > b)
191 776486 : PG_RETURN_INT32(1);
192 2146326 : else if (a == b)
193 1031166 : PG_RETURN_INT32(0);
194 : else
195 1115160 : PG_RETURN_INT32(-1);
196 : }
197 :
198 : Datum
199 : btoidvectorcmp(PG_FUNCTION_ARGS)
200 30459 : {
201 30459 : oidvector *a = (oidvector *) PG_GETARG_POINTER(0);
202 30459 : oidvector *b = (oidvector *) PG_GETARG_POINTER(1);
203 : int i;
204 :
205 : /* We arbitrarily choose to sort first by vector length */
206 30459 : if (a->dim1 != b->dim1)
207 3877 : PG_RETURN_INT32(a->dim1 - b->dim1);
208 :
209 47297 : for (i = 0; i < a->dim1; i++)
210 : {
211 36808 : if (a->values[i] != b->values[i])
212 : {
213 16093 : if (a->values[i] > b->values[i])
214 7854 : PG_RETURN_INT32(1);
215 : else
216 8239 : PG_RETURN_INT32(-1);
217 : }
218 : }
219 10489 : PG_RETURN_INT32(0);
220 : }
221 :
222 : Datum
223 : btcharcmp(PG_FUNCTION_ARGS)
224 138252 : {
225 138252 : char a = PG_GETARG_CHAR(0);
226 138252 : char b = PG_GETARG_CHAR(1);
227 :
228 : /* Be careful to compare chars as unsigned */
229 138252 : PG_RETURN_INT32((int32) ((uint8) a) - (int32) ((uint8) b));
230 : }
231 :
232 : Datum
233 : btnamecmp(PG_FUNCTION_ARGS)
234 719319 : {
235 719319 : Name a = PG_GETARG_NAME(0);
236 719319 : Name b = PG_GETARG_NAME(1);
237 :
238 719319 : PG_RETURN_INT32(strncmp(NameStr(*a), NameStr(*b), NAMEDATALEN));
239 : }
240 :
241 : Datum
242 : btname_pattern_cmp(PG_FUNCTION_ARGS)
243 0 : {
244 0 : Name a = PG_GETARG_NAME(0);
245 0 : Name b = PG_GETARG_NAME(1);
246 :
247 0 : PG_RETURN_INT32(memcmp(NameStr(*a), NameStr(*b), NAMEDATALEN));
248 : }
|