]> granicus.if.org Git - postgresql/blob - src/backend/utils/adt/char.c
969f8946666683fd817275d83d3be40fcd704196
[postgresql] / src / backend / utils / adt / char.c
1 /*-------------------------------------------------------------------------
2  *
3  * char.c
4  *        Functions for the built-in type "char" (not to be confused with
5  *        bpchar, which is the SQL CHAR(n) type).
6  *
7  * Portions Copyright (c) 1996-2002, PostgreSQL Global Development Group
8  * Portions Copyright (c) 1994, Regents of the University of California
9  *
10  *
11  * IDENTIFICATION
12  *        $Header: /cvsroot/pgsql/src/backend/utils/adt/char.c,v 1.35 2003/05/12 23:08:50 tgl Exp $
13  *
14  *-------------------------------------------------------------------------
15  */
16 #include "postgres.h"
17
18 #include "libpq/pqformat.h"
19 #include "utils/builtins.h"
20
21 /*****************************************************************************
22  *       USER I/O ROUTINES                                                                                                               *
23  *****************************************************************************/
24
25 /*
26  *              charin                  - converts "x" to 'x'
27  *
28  * Note that an empty input string will implicitly be converted to \0.
29  */
30 Datum
31 charin(PG_FUNCTION_ARGS)
32 {
33         char       *ch = PG_GETARG_CSTRING(0);
34
35         PG_RETURN_CHAR(ch[0]);
36 }
37
38 /*
39  *              charout                 - converts 'x' to "x"
40  *
41  * Note that if the char value is \0, the resulting string will appear
42  * to be empty (null-terminated after zero characters).  So this is the
43  * inverse of the charin() function for such data.
44  */
45 Datum
46 charout(PG_FUNCTION_ARGS)
47 {
48         char            ch = PG_GETARG_CHAR(0);
49         char       *result = (char *) palloc(2);
50
51         result[0] = ch;
52         result[1] = '\0';
53         PG_RETURN_CSTRING(result);
54 }
55
56 /*
57  *              charrecv                        - converts external binary format to char
58  *
59  * The external representation is one byte, with no character set
60  * conversion.  This is somewhat dubious, perhaps, but in many
61  * cases people use char for a 1-byte binary type.
62  */
63 Datum
64 charrecv(PG_FUNCTION_ARGS)
65 {
66         StringInfo      buf = (StringInfo) PG_GETARG_POINTER(0);
67
68         PG_RETURN_CHAR(pq_getmsgbyte(buf));
69 }
70
71 /*
72  *              charsend                        - converts char to binary format
73  */
74 Datum
75 charsend(PG_FUNCTION_ARGS)
76 {
77         char            arg1 = PG_GETARG_CHAR(0);
78         StringInfoData buf;
79
80         pq_begintypsend(&buf);
81         pq_sendbyte(&buf, arg1);
82         PG_RETURN_BYTEA_P(pq_endtypsend(&buf));
83 }
84
85 /*****************************************************************************
86  *       PUBLIC ROUTINES                                                                                                                 *
87  *****************************************************************************/
88
89 /*
90  * NOTE: comparisons are done as though char is unsigned (uint8).
91  * Arithmetic is done as though char is signed (int8).
92  *
93  * You wanted consistency?
94  */
95
96 Datum
97 chareq(PG_FUNCTION_ARGS)
98 {
99         char            arg1 = PG_GETARG_CHAR(0);
100         char            arg2 = PG_GETARG_CHAR(1);
101
102         PG_RETURN_BOOL(arg1 == arg2);
103 }
104
105 Datum
106 charne(PG_FUNCTION_ARGS)
107 {
108         char            arg1 = PG_GETARG_CHAR(0);
109         char            arg2 = PG_GETARG_CHAR(1);
110
111         PG_RETURN_BOOL(arg1 != arg2);
112 }
113
114 Datum
115 charlt(PG_FUNCTION_ARGS)
116 {
117         char            arg1 = PG_GETARG_CHAR(0);
118         char            arg2 = PG_GETARG_CHAR(1);
119
120         PG_RETURN_BOOL((uint8) arg1 < (uint8) arg2);
121 }
122
123 Datum
124 charle(PG_FUNCTION_ARGS)
125 {
126         char            arg1 = PG_GETARG_CHAR(0);
127         char            arg2 = PG_GETARG_CHAR(1);
128
129         PG_RETURN_BOOL((uint8) arg1 <= (uint8) arg2);
130 }
131
132 Datum
133 chargt(PG_FUNCTION_ARGS)
134 {
135         char            arg1 = PG_GETARG_CHAR(0);
136         char            arg2 = PG_GETARG_CHAR(1);
137
138         PG_RETURN_BOOL((uint8) arg1 > (uint8) arg2);
139 }
140
141 Datum
142 charge(PG_FUNCTION_ARGS)
143 {
144         char            arg1 = PG_GETARG_CHAR(0);
145         char            arg2 = PG_GETARG_CHAR(1);
146
147         PG_RETURN_BOOL((uint8) arg1 >= (uint8) arg2);
148 }
149
150 Datum
151 charpl(PG_FUNCTION_ARGS)
152 {
153         char            arg1 = PG_GETARG_CHAR(0);
154         char            arg2 = PG_GETARG_CHAR(1);
155
156         PG_RETURN_CHAR((int8) arg1 + (int8) arg2);
157 }
158
159 Datum
160 charmi(PG_FUNCTION_ARGS)
161 {
162         char            arg1 = PG_GETARG_CHAR(0);
163         char            arg2 = PG_GETARG_CHAR(1);
164
165         PG_RETURN_CHAR((int8) arg1 - (int8) arg2);
166 }
167
168 Datum
169 charmul(PG_FUNCTION_ARGS)
170 {
171         char            arg1 = PG_GETARG_CHAR(0);
172         char            arg2 = PG_GETARG_CHAR(1);
173
174         PG_RETURN_CHAR((int8) arg1 * (int8) arg2);
175 }
176
177 Datum
178 chardiv(PG_FUNCTION_ARGS)
179 {
180         char            arg1 = PG_GETARG_CHAR(0);
181         char            arg2 = PG_GETARG_CHAR(1);
182
183         if (arg2 == 0)
184                 elog(ERROR, "division by zero");
185
186         PG_RETURN_CHAR((int8) arg1 / (int8) arg2);
187 }
188
189
190 Datum
191 text_char(PG_FUNCTION_ARGS)
192 {
193         text       *arg1 = PG_GETARG_TEXT_P(0);
194         char            result;
195
196         /*
197          * An empty input string is converted to \0 (for consistency with
198          * charin). If the input is longer than one character, the excess data
199          * is silently discarded.
200          */
201         if (VARSIZE(arg1) > VARHDRSZ)
202                 result = *(VARDATA(arg1));
203         else
204                 result = '\0';
205
206         PG_RETURN_CHAR(result);
207 }
208
209 Datum
210 char_text(PG_FUNCTION_ARGS)
211 {
212         char            arg1 = PG_GETARG_CHAR(0);
213         text       *result = palloc(VARHDRSZ + 1);
214
215         /*
216          * Convert \0 to an empty string, for consistency with charout (and
217          * because the text stuff doesn't like embedded nulls all that well).
218          */
219         if (arg1 != '\0')
220         {
221                 VARATT_SIZEP(result) = VARHDRSZ + 1;
222                 *(VARDATA(result)) = arg1;
223         }
224         else
225                 VARATT_SIZEP(result) = VARHDRSZ;
226
227         PG_RETURN_TEXT_P(result);
228 }