Header And Logo

PostgreSQL
| The world's most advanced open source database.

char.c

Go to the documentation of this file.
00001 /*-------------------------------------------------------------------------
00002  *
00003  * char.c
00004  *    Functions for the built-in type "char" (not to be confused with
00005  *    bpchar, which is the SQL CHAR(n) type).
00006  *
00007  * Portions Copyright (c) 1996-2013, PostgreSQL Global Development Group
00008  * Portions Copyright (c) 1994, Regents of the University of California
00009  *
00010  *
00011  * IDENTIFICATION
00012  *    src/backend/utils/adt/char.c
00013  *
00014  *-------------------------------------------------------------------------
00015  */
00016 #include "postgres.h"
00017 
00018 #include <limits.h>
00019 
00020 #include "libpq/pqformat.h"
00021 #include "utils/builtins.h"
00022 
00023 /*****************************************************************************
00024  *   USER I/O ROUTINES                                                       *
00025  *****************************************************************************/
00026 
00027 /*
00028  *      charin          - converts "x" to 'x'
00029  *
00030  * Note that an empty input string will implicitly be converted to \0.
00031  */
00032 Datum
00033 charin(PG_FUNCTION_ARGS)
00034 {
00035     char       *ch = PG_GETARG_CSTRING(0);
00036 
00037     PG_RETURN_CHAR(ch[0]);
00038 }
00039 
00040 /*
00041  *      charout         - converts 'x' to "x"
00042  *
00043  * Note that if the char value is \0, the resulting string will appear
00044  * to be empty (null-terminated after zero characters).  So this is the
00045  * inverse of the charin() function for such data.
00046  */
00047 Datum
00048 charout(PG_FUNCTION_ARGS)
00049 {
00050     char        ch = PG_GETARG_CHAR(0);
00051     char       *result = (char *) palloc(2);
00052 
00053     result[0] = ch;
00054     result[1] = '\0';
00055     PG_RETURN_CSTRING(result);
00056 }
00057 
00058 /*
00059  *      charrecv            - converts external binary format to char
00060  *
00061  * The external representation is one byte, with no character set
00062  * conversion.  This is somewhat dubious, perhaps, but in many
00063  * cases people use char for a 1-byte binary type.
00064  */
00065 Datum
00066 charrecv(PG_FUNCTION_ARGS)
00067 {
00068     StringInfo  buf = (StringInfo) PG_GETARG_POINTER(0);
00069 
00070     PG_RETURN_CHAR(pq_getmsgbyte(buf));
00071 }
00072 
00073 /*
00074  *      charsend            - converts char to binary format
00075  */
00076 Datum
00077 charsend(PG_FUNCTION_ARGS)
00078 {
00079     char        arg1 = PG_GETARG_CHAR(0);
00080     StringInfoData buf;
00081 
00082     pq_begintypsend(&buf);
00083     pq_sendbyte(&buf, arg1);
00084     PG_RETURN_BYTEA_P(pq_endtypsend(&buf));
00085 }
00086 
00087 /*****************************************************************************
00088  *   PUBLIC ROUTINES                                                         *
00089  *****************************************************************************/
00090 
00091 /*
00092  * NOTE: comparisons are done as though char is unsigned (uint8).
00093  * Conversions to and from integer are done as though char is signed (int8).
00094  *
00095  * You wanted consistency?
00096  */
00097 
00098 Datum
00099 chareq(PG_FUNCTION_ARGS)
00100 {
00101     char        arg1 = PG_GETARG_CHAR(0);
00102     char        arg2 = PG_GETARG_CHAR(1);
00103 
00104     PG_RETURN_BOOL(arg1 == arg2);
00105 }
00106 
00107 Datum
00108 charne(PG_FUNCTION_ARGS)
00109 {
00110     char        arg1 = PG_GETARG_CHAR(0);
00111     char        arg2 = PG_GETARG_CHAR(1);
00112 
00113     PG_RETURN_BOOL(arg1 != arg2);
00114 }
00115 
00116 Datum
00117 charlt(PG_FUNCTION_ARGS)
00118 {
00119     char        arg1 = PG_GETARG_CHAR(0);
00120     char        arg2 = PG_GETARG_CHAR(1);
00121 
00122     PG_RETURN_BOOL((uint8) arg1 < (uint8) arg2);
00123 }
00124 
00125 Datum
00126 charle(PG_FUNCTION_ARGS)
00127 {
00128     char        arg1 = PG_GETARG_CHAR(0);
00129     char        arg2 = PG_GETARG_CHAR(1);
00130 
00131     PG_RETURN_BOOL((uint8) arg1 <= (uint8) arg2);
00132 }
00133 
00134 Datum
00135 chargt(PG_FUNCTION_ARGS)
00136 {
00137     char        arg1 = PG_GETARG_CHAR(0);
00138     char        arg2 = PG_GETARG_CHAR(1);
00139 
00140     PG_RETURN_BOOL((uint8) arg1 > (uint8) arg2);
00141 }
00142 
00143 Datum
00144 charge(PG_FUNCTION_ARGS)
00145 {
00146     char        arg1 = PG_GETARG_CHAR(0);
00147     char        arg2 = PG_GETARG_CHAR(1);
00148 
00149     PG_RETURN_BOOL((uint8) arg1 >= (uint8) arg2);
00150 }
00151 
00152 
00153 Datum
00154 chartoi4(PG_FUNCTION_ARGS)
00155 {
00156     char        arg1 = PG_GETARG_CHAR(0);
00157 
00158     PG_RETURN_INT32((int32) ((int8) arg1));
00159 }
00160 
00161 Datum
00162 i4tochar(PG_FUNCTION_ARGS)
00163 {
00164     int32       arg1 = PG_GETARG_INT32(0);
00165 
00166     if (arg1 < SCHAR_MIN || arg1 > SCHAR_MAX)
00167         ereport(ERROR,
00168                 (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
00169                  errmsg("\"char\" out of range")));
00170 
00171     PG_RETURN_CHAR((int8) arg1);
00172 }
00173 
00174 
00175 Datum
00176 text_char(PG_FUNCTION_ARGS)
00177 {
00178     text       *arg1 = PG_GETARG_TEXT_P(0);
00179     char        result;
00180 
00181     /*
00182      * An empty input string is converted to \0 (for consistency with charin).
00183      * If the input is longer than one character, the excess data is silently
00184      * discarded.
00185      */
00186     if (VARSIZE(arg1) > VARHDRSZ)
00187         result = *(VARDATA(arg1));
00188     else
00189         result = '\0';
00190 
00191     PG_RETURN_CHAR(result);
00192 }
00193 
00194 Datum
00195 char_text(PG_FUNCTION_ARGS)
00196 {
00197     char        arg1 = PG_GETARG_CHAR(0);
00198     text       *result = palloc(VARHDRSZ + 1);
00199 
00200     /*
00201      * Convert \0 to an empty string, for consistency with charout (and
00202      * because the text stuff doesn't like embedded nulls all that well).
00203      */
00204     if (arg1 != '\0')
00205     {
00206         SET_VARSIZE(result, VARHDRSZ + 1);
00207         *(VARDATA(result)) = arg1;
00208     }
00209     else
00210         SET_VARSIZE(result, VARHDRSZ);
00211 
00212     PG_RETURN_TEXT_P(result);
00213 }