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