Quellcodebibliothek Statistik Leitseite products/Sources/formale Sprachen/C/Postgres/src/test/isolation/   (Postgres Database Version 18.4©)  Datei vom 11.4.2026 mit Größe 196 B image not shown  

Quelle  char.c   Sprache: unbekannt

 
/*-------------------------------------------------------------------------
 *
 * 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=94 H=94 G=93

[Dauer der Verarbeitung: 0.17 Sekunden, vorverarbeitet 2026-08-08]