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