Quellcodebibliothek Statistik Leitseite products/Sources/formale Sprachen/C/Postgres/src/backend/utils/adt/   (Postgres Database Version 18.4©)  Datei vom 11.4.2026 mit Größe 5 kB image not shown  

Quelle  char.c   Sprache: C

 

/*-------------------------------------------------------------------------
 *
 * char.c
 *   Functions for the built-in type "char" (not to be confused with
 *   bpchar, which is the SQL CHAR(n) type).
 *
 * Portions Copyright (c) 1996-2025, PostgreSQL Global Development Group
 * Portions Copyright (c) 1994, Regents of the University of California
 *
 *
 * IDENTIFICATION
 *   src/backend/utils/adt/char.c
 *
 *-------------------------------------------------------------------------
 */

#include "postgres.h"

#include <limits.h>

#include "libpq/pqformat.h"
#include "utils/fmgrprotos.h"
#include "varatt.h"

#define ISOCTAL(c)   (((c) >= '0') && ((c) <= '7'))
#define TOOCTAL(c)   ((c) + '0')
#define FROMOCTAL(c) ((unsigned char) (c) - '0')


/*****************************************************************************
 *  USER I/O ROUTINES               *
 *****************************************************************************/


/*
 *  charin   - converts "x" to 'x'
 *
 * This accepts the formats charout produces.  If we have multibyte input
 * that is not in the form '\ooo', then we take its first byte as the value
 * and silently discard the rest; this is a backwards-compatibility provision.
 */

Datum
charin(PG_FUNCTION_ARGS)
{
 char    *ch = PG_GETARG_CSTRING(0);

 if (strlen(ch) == 4 && ch[0] == '\\' &&
  ISOCTAL(ch[1]) && ISOCTAL(ch[2]) && ISOCTAL(ch[3]))
  PG_RETURN_CHAR((FROMOCTAL(ch[1]) << 6) +
        (FROMOCTAL(ch[2]) << 3) +
        FROMOCTAL(ch[3]));
 /* This will do the right thing for a zero-length input string */
 PG_RETURN_CHAR(ch[0]);
}

/*
 *  charout   - converts 'x' to "x"
 *
 * The possible output formats are:
 * 1. 0x00 is represented as an empty string.
 * 2. 0x01..0x7F are represented as a single ASCII byte.
 * 3. 0x80..0xFF are represented as \ooo (backslash and 3 octal digits).
 * Case 3 is meant to match the traditional "escape" format of bytea.
 */

Datum
charout(PG_FUNCTION_ARGS)
{
 char  ch = PG_GETARG_CHAR(0);
 char    *result = (char *) palloc(5);

 if (IS_HIGHBIT_SET(ch))
 {
  result[0] = '\\';
  result[1] = TOOCTAL(((unsigned char) ch) >> 6);
  result[2] = TOOCTAL((((unsigned char) ch) >> 3) & 07);
  result[3] = TOOCTAL(((unsigned char) ch) & 07);
  result[4] = '\0';
 }
 else
 {
  /* This produces acceptable results for 0x00 as well */
  result[0] = ch;
  result[1] = '\0';
 }
 PG_RETURN_CSTRING(result);
}

/*
 *  charrecv   - converts external binary format to char
 *
 * The external representation is one byte, with no character set
 * conversion.  This is somewhat dubious, perhaps, but in many
 * cases people use char for a 1-byte binary type.
 */

Datum
charrecv(PG_FUNCTION_ARGS)
{
 StringInfo buf = (StringInfo) PG_GETARG_POINTER(0);

 PG_RETURN_CHAR(pq_getmsgbyte(buf));
}

/*
 *  charsend   - converts char to binary format
 */

Datum
charsend(PG_FUNCTION_ARGS)
{
 char  arg1 = PG_GETARG_CHAR(0);
 StringInfoData buf;

 pq_begintypsend(&buf);
 pq_sendbyte(&buf, arg1);
 PG_RETURN_BYTEA_P(pq_endtypsend(&buf));
}

/*****************************************************************************
 *  PUBLIC ROUTINES               *
 *****************************************************************************/


/*
 * NOTE: comparisons are done as though char is unsigned (uint8).
 * Conversions to and from integer are done as though char is signed (int8).
 *
 * You wanted consistency?
 */


Datum
chareq(PG_FUNCTION_ARGS)
{
 char  arg1 = PG_GETARG_CHAR(0);
 char  arg2 = PG_GETARG_CHAR(1);

 PG_RETURN_BOOL(arg1 == arg2);
}

Datum
charne(PG_FUNCTION_ARGS)
{
 char  arg1 = PG_GETARG_CHAR(0);
 char  arg2 = PG_GETARG_CHAR(1);

 PG_RETURN_BOOL(arg1 != arg2);
}

Datum
charlt(PG_FUNCTION_ARGS)
{
 char  arg1 = PG_GETARG_CHAR(0);
 char  arg2 = PG_GETARG_CHAR(1);

 PG_RETURN_BOOL((uint8) arg1 < (uint8) arg2);
}

Datum
charle(PG_FUNCTION_ARGS)
{
 char  arg1 = PG_GETARG_CHAR(0);
 char  arg2 = PG_GETARG_CHAR(1);

 PG_RETURN_BOOL((uint8) arg1 <= (uint8) arg2);
}

Datum
chargt(PG_FUNCTION_ARGS)
{
 char  arg1 = PG_GETARG_CHAR(0);
 char  arg2 = PG_GETARG_CHAR(1);

 PG_RETURN_BOOL((uint8) arg1 > (uint8) arg2);
}

Datum
charge(PG_FUNCTION_ARGS)
{
 char  arg1 = PG_GETARG_CHAR(0);
 char  arg2 = PG_GETARG_CHAR(1);

 PG_RETURN_BOOL((uint8) arg1 >= (uint8) arg2);
}


Datum
chartoi4(PG_FUNCTION_ARGS)
{
 char  arg1 = PG_GETARG_CHAR(0);

 PG_RETURN_INT32((int32) ((int8) arg1));
}

Datum
i4tochar(PG_FUNCTION_ARGS)
{
 int32  arg1 = PG_GETARG_INT32(0);

 if (arg1 < SCHAR_MIN || arg1 > SCHAR_MAX)
  ereport(ERROR,
    (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
     errmsg("\"char\" out of range")));

 PG_RETURN_CHAR((int8) arg1);
}


Datum
text_char(PG_FUNCTION_ARGS)
{
 text    *arg1 = PG_GETARG_TEXT_PP(0);
 char    *ch = VARDATA_ANY(arg1);
 char  result;

 /*
  * Conversion rules are the same as in charin(), but here we need to
  * handle the empty-string case honestly.
 */

 if (VARSIZE_ANY_EXHDR(arg1) == 4 && ch[0] == '\\' &&
  ISOCTAL(ch[1]) && ISOCTAL(ch[2]) && ISOCTAL(ch[3]))
  result = (FROMOCTAL(ch[1]) << 6) +
   (FROMOCTAL(ch[2]) << 3) +
   FROMOCTAL(ch[3]);
 else if (VARSIZE_ANY_EXHDR(arg1) > 0)
  result = ch[0];
 else
  result = '\0';

 PG_RETURN_CHAR(result);
}

Datum
char_text(PG_FUNCTION_ARGS)
{
 char  arg1 = PG_GETARG_CHAR(0);
 text    *result = palloc(VARHDRSZ + 4);

 /*
  * Conversion rules are the same as in charout(), but here we need to be
  * honest about converting 0x00 to an empty string.
 */

 if (IS_HIGHBIT_SET(arg1))
 {
  SET_VARSIZE(result, VARHDRSZ + 4);
  (VARDATA(result))[0] = '\\';
  (VARDATA(result))[1] = TOOCTAL(((unsigned char) arg1) >> 6);
  (VARDATA(result))[2] = TOOCTAL((((unsigned char) arg1) >> 3) & 07);
  (VARDATA(result))[3] = TOOCTAL(((unsigned char) arg1) & 07);
 }
 else if (arg1 != '\0')
 {
  SET_VARSIZE(result, VARHDRSZ + 1);
  *(VARDATA(result)) = arg1;
 }
 else
  SET_VARSIZE(result, VARHDRSZ);

 PG_RETURN_TEXT_P(result);
}

Messung V0.5 in Prozent
C=95 H=95 G=94

¤ Dauer der Verarbeitung: 0.13 Sekunden  (vorverarbeitet am  2026-10-11) ¤

*© Formatika GbR, Deutschland






Wurzel

Suchen

PVS Prover

Isabelle Prover

NIST Cobol Testsuite

Cephes Mathematical Library

Vienna Development Method

Haftungshinweis

Die Informationen auf dieser Webseite wurden nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit, noch Qualität der bereit gestellten Informationen zugesichert.

Bemerkung:

Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.