Quellcodebibliothek Statistik Leitseite products/Sources/formale Sprachen/C/MariaDB/mysql-test/suite/compat/oracle/t/   (MariaDB Server Version 8.1-8.4©)  Datei vom 1.9.2026 mit Größe 1 kB image not shown  

Quelle  int8.c  Sprache: unbekannt

 
/*-------------------------------------------------------------------------
 *
 * int8.c
 *   Internal 64-bit integer operations
 *
 * Portions Copyright (c) 1996-2025, PostgreSQL Global Development Group
 * Portions Copyright (c) 1994, Regents of the University of California
 *
 * IDENTIFICATION
 *   src/backend/utils/adt/int8.c
 *
 *-------------------------------------------------------------------------
 */

#include "postgres.h"

#include <ctype.h>
#include <limits.h>
#include <math.h>

#include "common/int.h"
#include "funcapi.h"
#include "libpq/pqformat.h"
#include "nodes/nodeFuncs.h"
#include "nodes/supportnodes.h"
#include "optimizer/optimizer.h"
#include "utils/builtins.h"


typedef struct
{
 int64  current;
 int64  finish;
 int64  step;
} generate_series_fctx;


/***********************************************************************
 **
 **  Routines for 64-bit integers.
 **
 ***********************************************************************/


/*----------------------------------------------------------
 * Formatting and conversion routines.
 *---------------------------------------------------------*/


/* int8in()
 */

Datum
int8in(PG_FUNCTION_ARGS)
{
 char    *num = PG_GETARG_CSTRING(0);

 PG_RETURN_INT64(pg_strtoint64_safe(num, fcinfo->context));
}


/* int8out()
 */

Datum
int8out(PG_FUNCTION_ARGS)
{
 int64  val = PG_GETARG_INT64(0);
 char  buf[MAXINT8LEN + 1];
 char    *result;
 int   len;

 len = pg_lltoa(val, buf) + 1;

 /*
  * Since the length is already known, we do a manual palloc() and memcpy()
  * to avoid the strlen() call that would otherwise be done in pstrdup().
 */

 result = palloc(len);
 memcpy(result, buf, len);
 PG_RETURN_CSTRING(result);
}

/*
 *  int8recv   - converts external binary format to int8
 */

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

 PG_RETURN_INT64(pq_getmsgint64(buf));
}

/*
 *  int8send   - converts int8 to binary format
 */

Datum
int8send(PG_FUNCTION_ARGS)
{
 int64  arg1 = PG_GETARG_INT64(0);
 StringInfoData buf;

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


/*----------------------------------------------------------
 * Relational operators for int8s, including cross-data-type comparisons.
 *---------------------------------------------------------*/


/* int8relop()
 * Is val1 relop val2?
 */

Datum
int8eq(PG_FUNCTION_ARGS)
{
 int64  val1 = PG_GETARG_INT64(0);
 int64  val2 = PG_GETARG_INT64(1);

 PG_RETURN_BOOL(val1 == val2);
}

Datum
int8ne(PG_FUNCTION_ARGS)
{
 int64  val1 = PG_GETARG_INT64(0);
 int64  val2 = PG_GETARG_INT64(1);

 PG_RETURN_BOOL(val1 != val2);
}

Datum
int8lt(PG_FUNCTION_ARGS)
{
 int64  val1 = PG_GETARG_INT64(0);
 int64  val2 = PG_GETARG_INT64(1);

 PG_RETURN_BOOL(val1 < val2);
}

Datum
int8gt(PG_FUNCTION_ARGS)
{
 int64  val1 = PG_GETARG_INT64(0);
 int64  val2 = PG_GETARG_INT64(1);

 PG_RETURN_BOOL(val1 > val2);
}

Datum
int8le(PG_FUNCTION_ARGS)
{
 int64  val1 = PG_GETARG_INT64(0);
 int64  val2 = PG_GETARG_INT64(1);

 PG_RETURN_BOOL(val1 <= val2);
}

Datum
int8ge(PG_FUNCTION_ARGS)
{
 int64  val1 = PG_GETARG_INT64(0);
 int64  val2 = PG_GETARG_INT64(1);

 PG_RETURN_BOOL(val1 >= val2);
}

/* int84relop()
 * Is 64-bit val1 relop 32-bit val2?
 */

Datum
int84eq(PG_FUNCTION_ARGS)
{
 int64  val1 = PG_GETARG_INT64(0);
 int32  val2 = PG_GETARG_INT32(1);

 PG_RETURN_BOOL(val1 == val2);
}

Datum
int84ne(PG_FUNCTION_ARGS)
{
 int64  val1 = PG_GETARG_INT64(0);
 int32  val2 = PG_GETARG_INT32(1);

 PG_RETURN_BOOL(val1 != val2);
}

Datum
int84lt(PG_FUNCTION_ARGS)
{
 int64  val1 = PG_GETARG_INT64(0);
 int32  val2 = PG_GETARG_INT32(1);

 PG_RETURN_BOOL(val1 < val2);
}

Datum
int84gt(PG_FUNCTION_ARGS)
{
 int64  val1 = PG_GETARG_INT64(0);
 int32  val2 = PG_GETARG_INT32(1);

 PG_RETURN_BOOL(val1 > val2);
}

Datum
int84le(PG_FUNCTION_ARGS)
{
 int64  val1 = PG_GETARG_INT64(0);
 int32  val2 = PG_GETARG_INT32(1);

 PG_RETURN_BOOL(val1 <= val2);
}

Datum
int84ge(PG_FUNCTION_ARGS)
{
 int64  val1 = PG_GETARG_INT64(0);
 int32  val2 = PG_GETARG_INT32(1);

 PG_RETURN_BOOL(val1 >= val2);
}

/* int48relop()
 * Is 32-bit val1 relop 64-bit val2?
 */

Datum
int48eq(PG_FUNCTION_ARGS)
{
 int32  val1 = PG_GETARG_INT32(0);
 int64  val2 = PG_GETARG_INT64(1);

 PG_RETURN_BOOL(val1 == val2);
}

Datum
int48ne(PG_FUNCTION_ARGS)
{
 int32  val1 = PG_GETARG_INT32(0);
 int64  val2 = PG_GETARG_INT64(1);

 PG_RETURN_BOOL(val1 != val2);
}

Datum
int48lt(PG_FUNCTION_ARGS)
{
 int32  val1 = PG_GETARG_INT32(0);
 int64  val2 = PG_GETARG_INT64(1);

 PG_RETURN_BOOL(val1 < val2);
}

Datum
int48gt(PG_FUNCTION_ARGS)
{
 int32  val1 = PG_GETARG_INT32(0);
 int64  val2 = PG_GETARG_INT64(1);

 PG_RETURN_BOOL(val1 > val2);
}

Datum
int48le(PG_FUNCTION_ARGS)
{
 int32  val1 = PG_GETARG_INT32(0);
 int64  val2 = PG_GETARG_INT64(1);

 PG_RETURN_BOOL(val1 <= val2);
}

Datum
int48ge(PG_FUNCTION_ARGS)
{
 int32  val1 = PG_GETARG_INT32(0);
 int64  val2 = PG_GETARG_INT64(1);

 PG_RETURN_BOOL(val1 >= val2);
}

/* int82relop()
 * Is 64-bit val1 relop 16-bit val2?
 */

Datum
int82eq(PG_FUNCTION_ARGS)
{
 int64  val1 = PG_GETARG_INT64(0);
 int16  val2 = PG_GETARG_INT16(1);

 PG_RETURN_BOOL(val1 == val2);
}

Datum
int82ne(PG_FUNCTION_ARGS)
{
 int64  val1 = PG_GETARG_INT64(0);
 int16  val2 = PG_GETARG_INT16(1);

 PG_RETURN_BOOL(val1 != val2);
}

Datum
int82lt(PG_FUNCTION_ARGS)
{
 int64  val1 = PG_GETARG_INT64(0);
 int16  val2 = PG_GETARG_INT16(1);

 PG_RETURN_BOOL(val1 < val2);
}

Datum
int82gt(PG_FUNCTION_ARGS)
{
 int64  val1 = PG_GETARG_INT64(0);
 int16  val2 = PG_GETARG_INT16(1);

 PG_RETURN_BOOL(val1 > val2);
}

Datum
int82le(PG_FUNCTION_ARGS)
{
 int64  val1 = PG_GETARG_INT64(0);
 int16  val2 = PG_GETARG_INT16(1);

 PG_RETURN_BOOL(val1 <= val2);
}

Datum
int82ge(PG_FUNCTION_ARGS)
{
 int64  val1 = PG_GETARG_INT64(0);
 int16  val2 = PG_GETARG_INT16(1);

 PG_RETURN_BOOL(val1 >= val2);
}

/* int28relop()
 * Is 16-bit val1 relop 64-bit val2?
 */

Datum
int28eq(PG_FUNCTION_ARGS)
{
 int16  val1 = PG_GETARG_INT16(0);
 int64  val2 = PG_GETARG_INT64(1);

 PG_RETURN_BOOL(val1 == val2);
}

Datum
int28ne(PG_FUNCTION_ARGS)
{
 int16  val1 = PG_GETARG_INT16(0);
 int64  val2 = PG_GETARG_INT64(1);

 PG_RETURN_BOOL(val1 != val2);
}

Datum
int28lt(PG_FUNCTION_ARGS)
{
 int16  val1 = PG_GETARG_INT16(0);
 int64  val2 = PG_GETARG_INT64(1);

 PG_RETURN_BOOL(val1 < val2);
}

Datum
int28gt(PG_FUNCTION_ARGS)
{
 int16  val1 = PG_GETARG_INT16(0);
 int64  val2 = PG_GETARG_INT64(1);

 PG_RETURN_BOOL(val1 > val2);
}

Datum
int28le(PG_FUNCTION_ARGS)
{
 int16  val1 = PG_GETARG_INT16(0);
 int64  val2 = PG_GETARG_INT64(1);

 PG_RETURN_BOOL(val1 <= val2);
}

Datum
int28ge(PG_FUNCTION_ARGS)
{
 int16  val1 = PG_GETARG_INT16(0);
 int64  val2 = PG_GETARG_INT64(1);

 PG_RETURN_BOOL(val1 >= val2);
}

/*
 * in_range support function for int8.
 *
 * Note: we needn't supply int8_int4 or int8_int2 variants, as implicit
 * coercion of the offset value takes care of those scenarios just as well.
 */

Datum
in_range_int8_int8(PG_FUNCTION_ARGS)
{
 int64  val = PG_GETARG_INT64(0);
 int64  base = PG_GETARG_INT64(1);
 int64  offset = PG_GETARG_INT64(2);
 bool  sub = PG_GETARG_BOOL(3);
 bool  less = PG_GETARG_BOOL(4);
 int64  sum;

 if (offset < 0)
  ereport(ERROR,
    (errcode(ERRCODE_INVALID_PRECEDING_OR_FOLLOWING_SIZE),
     errmsg("invalid preceding or following size in window function")));

 if (sub)
  offset = -offset;  /* cannot overflow */

 if (unlikely(pg_add_s64_overflow(base, offset, &sum)))
 {
  /*
   * If sub is false, the true sum is surely more than val, so correct
   * answer is the same as "less".  If sub is true, the true sum is
   * surely less than val, so the answer is "!less".
 */

  PG_RETURN_BOOL(sub ? !less : less);
 }

 if (less)
  PG_RETURN_BOOL(val <= sum);
 else
  PG_RETURN_BOOL(val >= sum);
}


/*----------------------------------------------------------
 * Arithmetic operators on 64-bit integers.
 *---------------------------------------------------------*/


Datum
int8um(PG_FUNCTION_ARGS)
{
 int64  arg = PG_GETARG_INT64(0);
 int64  result;

 if (unlikely(arg == PG_INT64_MIN))
  ereport(ERROR,
    (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
     errmsg("bigint out of range")));
 result = -arg;
 PG_RETURN_INT64(result);
}

Datum
int8up(PG_FUNCTION_ARGS)
{
 int64  arg = PG_GETARG_INT64(0);

 PG_RETURN_INT64(arg);
}

Datum
int8pl(PG_FUNCTION_ARGS)
{
 int64  arg1 = PG_GETARG_INT64(0);
 int64  arg2 = PG_GETARG_INT64(1);
 int64  result;

 if (unlikely(pg_add_s64_overflow(arg1, arg2, &result)))
  ereport(ERROR,
    (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
     errmsg("bigint out of range")));
 PG_RETURN_INT64(result);
}

Datum
int8mi(PG_FUNCTION_ARGS)
{
 int64  arg1 = PG_GETARG_INT64(0);
 int64  arg2 = PG_GETARG_INT64(1);
 int64  result;

 if (unlikely(pg_sub_s64_overflow(arg1, arg2, &result)))
  ereport(ERROR,
    (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
     errmsg("bigint out of range")));
 PG_RETURN_INT64(result);
}

Datum
int8mul(PG_FUNCTION_ARGS)
{
 int64  arg1 = PG_GETARG_INT64(0);
 int64  arg2 = PG_GETARG_INT64(1);
 int64  result;

 if (unlikely(pg_mul_s64_overflow(arg1, arg2, &result)))
  ereport(ERROR,
    (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
     errmsg("bigint out of range")));
 PG_RETURN_INT64(result);
}

Datum
int8div(PG_FUNCTION_ARGS)
{
 int64  arg1 = PG_GETARG_INT64(0);
 int64  arg2 = PG_GETARG_INT64(1);
 int64  result;

 if (arg2 == 0)
 {
  ereport(ERROR,
    (errcode(ERRCODE_DIVISION_BY_ZERO),
     errmsg("division by zero")));
  /* ensure compiler realizes we mustn't reach the division (gcc bug) */
  PG_RETURN_NULL();
 }

 /*
  * INT64_MIN / -1 is problematic, since the result can't be represented on
  * a two's-complement machine.  Some machines produce INT64_MIN, some
  * produce zero, some throw an exception.  We can dodge the problem by
  * recognizing that division by -1 is the same as negation.
 */

 if (arg2 == -1)
 {
  if (unlikely(arg1 == PG_INT64_MIN))
   ereport(ERROR,
     (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
      errmsg("bigint out of range")));
  result = -arg1;
  PG_RETURN_INT64(result);
 }

 /* No overflow is possible */

 result = arg1 / arg2;

 PG_RETURN_INT64(result);
}

/* int8abs()
 * Absolute value
 */

Datum
int8abs(PG_FUNCTION_ARGS)
{
 int64  arg1 = PG_GETARG_INT64(0);
 int64  result;

 if (unlikely(arg1 == PG_INT64_MIN))
  ereport(ERROR,
    (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
     errmsg("bigint out of range")));
 result = (arg1 < 0) ? -arg1 : arg1;
 PG_RETURN_INT64(result);
}

/* int8mod()
 * Modulo operation.
 */

Datum
int8mod(PG_FUNCTION_ARGS)
{
 int64  arg1 = PG_GETARG_INT64(0);
 int64  arg2 = PG_GETARG_INT64(1);

 if (unlikely(arg2 == 0))
 {
  ereport(ERROR,
    (errcode(ERRCODE_DIVISION_BY_ZERO),
     errmsg("division by zero")));
  /* ensure compiler realizes we mustn't reach the division (gcc bug) */
  PG_RETURN_NULL();
 }

 /*
  * Some machines throw a floating-point exception for INT64_MIN % -1,
  * which is a bit silly since the correct answer is perfectly
  * well-defined, namely zero.
 */

 if (arg2 == -1)
  PG_RETURN_INT64(0);

 /* No overflow is possible */

 PG_RETURN_INT64(arg1 % arg2);
}

/*
 * Greatest Common Divisor
 *
 * Returns the largest positive integer that exactly divides both inputs.
 * Special cases:
 *   - gcd(x, 0) = gcd(0, x) = abs(x)
 *     because 0 is divisible by anything
 *   - gcd(0, 0) = 0
 *     complies with the previous definition and is a common convention
 *
 * Special care must be taken if either input is INT64_MIN ---
 * gcd(0, INT64_MIN), gcd(INT64_MIN, 0) and gcd(INT64_MIN, INT64_MIN) are
 * all equal to abs(INT64_MIN), which cannot be represented as a 64-bit signed
 * integer.
 */

static int64
int8gcd_internal(int64 arg1, int64 arg2)
{
 int64  swap;
 int64  a1,
    a2;

 /*
  * Put the greater absolute value in arg1.
  *
  * This would happen automatically in the loop below, but avoids an
  * expensive modulo operation, and simplifies the special-case handling
  * for INT64_MIN below.
  *
  * We do this in negative space in order to handle INT64_MIN.
 */

 a1 = (arg1 < 0) ? arg1 : -arg1;
 a2 = (arg2 < 0) ? arg2 : -arg2;
 if (a1 > a2)
 {
  swap = arg1;
  arg1 = arg2;
  arg2 = swap;
 }

 /* Special care needs to be taken with INT64_MIN.  See comments above. */
 if (arg1 == PG_INT64_MIN)
 {
  if (arg2 == 0 || arg2 == PG_INT64_MIN)
   ereport(ERROR,
     (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
      errmsg("bigint out of range")));

  /*
   * Some machines throw a floating-point exception for INT64_MIN % -1,
   * which is a bit silly since the correct answer is perfectly
   * well-defined, namely zero.  Guard against this and just return the
   * result, gcd(INT64_MIN, -1) = 1.
 */

  if (arg2 == -1)
   return 1;
 }

 /* Use the Euclidean algorithm to find the GCD */
 while (arg2 != 0)
 {
  swap = arg2;
  arg2 = arg1 % arg2;
  arg1 = swap;
 }

 /*
  * Make sure the result is positive. (We know we don't have INT64_MIN
  * anymore).
 */

 if (arg1 < 0)
  arg1 = -arg1;

 return arg1;
}

Datum
int8gcd(PG_FUNCTION_ARGS)
{
 int64  arg1 = PG_GETARG_INT64(0);
 int64  arg2 = PG_GETARG_INT64(1);
 int64  result;

 result = int8gcd_internal(arg1, arg2);

 PG_RETURN_INT64(result);
}

/*
 * Least Common Multiple
 */

Datum
int8lcm(PG_FUNCTION_ARGS)
{
 int64  arg1 = PG_GETARG_INT64(0);
 int64  arg2 = PG_GETARG_INT64(1);
 int64  gcd;
 int64  result;

 /*
  * Handle lcm(x, 0) = lcm(0, x) = 0 as a special case.  This prevents a
  * division-by-zero error below when x is zero, and an overflow error from
  * the GCD computation when x = INT64_MIN.
 */

 if (arg1 == 0 || arg2 == 0)
  PG_RETURN_INT64(0);

 /* lcm(x, y) = abs(x / gcd(x, y) * y) */
 gcd = int8gcd_internal(arg1, arg2);
 arg1 = arg1 / gcd;

 if (unlikely(pg_mul_s64_overflow(arg1, arg2, &result)))
  ereport(ERROR,
    (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
     errmsg("bigint out of range")));

 /* If the result is INT64_MIN, it cannot be represented. */
 if (unlikely(result == PG_INT64_MIN))
  ereport(ERROR,
    (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
     errmsg("bigint out of range")));

 if (result < 0)
  result = -result;

 PG_RETURN_INT64(result);
}

Datum
int8inc(PG_FUNCTION_ARGS)
{
 /*
  * When int8 is pass-by-reference, we provide this special case to avoid
  * palloc overhead for COUNT(): when called as an aggregate, we know that
  * the argument is modifiable local storage, so just update it in-place.
  * (If int8 is pass-by-value, then of course this is useless as well as
  * incorrect, so just ifdef it out.)
 */

#ifndef USE_FLOAT8_BYVAL  /* controls int8 too */
 if (AggCheckCallContext(fcinfo, NULL))
 {
  int64    *arg = (int64 *) PG_GETARG_POINTER(0);

  if (unlikely(pg_add_s64_overflow(*arg, 1, arg)))
   ereport(ERROR,
     (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
      errmsg("bigint out of range")));

  PG_RETURN_POINTER(arg);
 }
 else
#endif
 {
  /* Not called as an aggregate, so just do it the dumb way */
  int64  arg = PG_GETARG_INT64(0);
  int64  result;

  if (unlikely(pg_add_s64_overflow(arg, 1, &result)))
   ereport(ERROR,
     (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
      errmsg("bigint out of range")));

  PG_RETURN_INT64(result);
 }
}

Datum
int8dec(PG_FUNCTION_ARGS)
{
 /*
  * When int8 is pass-by-reference, we provide this special case to avoid
  * palloc overhead for COUNT(): when called as an aggregate, we know that
  * the argument is modifiable local storage, so just update it in-place.
  * (If int8 is pass-by-value, then of course this is useless as well as
  * incorrect, so just ifdef it out.)
 */

#ifndef USE_FLOAT8_BYVAL  /* controls int8 too */
 if (AggCheckCallContext(fcinfo, NULL))
 {
  int64    *arg = (int64 *) PG_GETARG_POINTER(0);

  if (unlikely(pg_sub_s64_overflow(*arg, 1, arg)))
   ereport(ERROR,
     (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
      errmsg("bigint out of range")));
  PG_RETURN_POINTER(arg);
 }
 else
#endif
 {
  /* Not called as an aggregate, so just do it the dumb way */
  int64  arg = PG_GETARG_INT64(0);
  int64  result;

  if (unlikely(pg_sub_s64_overflow(arg, 1, &result)))
   ereport(ERROR,
     (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
      errmsg("bigint out of range")));

  PG_RETURN_INT64(result);
 }
}


/*
 * These functions are exactly like int8inc/int8dec but are used for
 * aggregates that count only non-null values.  Since the functions are
 * declared strict, the null checks happen before we ever get here, and all we
 * need do is increment the state value.  We could actually make these pg_proc
 * entries point right at int8inc/int8dec, but then the opr_sanity regression
 * test would complain about mismatched entries for a built-in function.
 */


Datum
int8inc_any(PG_FUNCTION_ARGS)
{
 return int8inc(fcinfo);
}

Datum
int8inc_float8_float8(PG_FUNCTION_ARGS)
{
 return int8inc(fcinfo);
}

Datum
int8dec_any(PG_FUNCTION_ARGS)
{
 return int8dec(fcinfo);
}

/*
 * int8inc_support
 *  prosupport function for int8inc() and int8inc_any()
 */

Datum
int8inc_support(PG_FUNCTION_ARGS)
{
 Node    *rawreq = (Node *) PG_GETARG_POINTER(0);

 if (IsA(rawreq, SupportRequestWFuncMonotonic))
 {
  SupportRequestWFuncMonotonic *req = (SupportRequestWFuncMonotonic *) rawreq;
  MonotonicFunction monotonic = MONOTONICFUNC_NONE;
  int   frameOptions = req->window_clause->frameOptions;

  /* No ORDER BY clause then all rows are peers */
  if (req->window_clause->orderClause == NIL)
   monotonic = MONOTONICFUNC_BOTH;
  else
  {
   /*
    * Otherwise take into account the frame options.  When the frame
    * bound is the start of the window then the resulting value can
    * never decrease, therefore is monotonically increasing
 */

   if (frameOptions & FRAMEOPTION_START_UNBOUNDED_PRECEDING)
    monotonic |= MONOTONICFUNC_INCREASING;

   /*
    * Likewise, if the frame bound is the end of the window then the
    * resulting value can never decrease.
 */

   if (frameOptions & FRAMEOPTION_END_UNBOUNDED_FOLLOWING)
    monotonic |= MONOTONICFUNC_DECREASING;
  }

  req->monotonic = monotonic;
  PG_RETURN_POINTER(req);
 }

 PG_RETURN_POINTER(NULL);
}


Datum
int8larger(PG_FUNCTION_ARGS)
{
 int64  arg1 = PG_GETARG_INT64(0);
 int64  arg2 = PG_GETARG_INT64(1);
 int64  result;

 result = ((arg1 > arg2) ? arg1 : arg2);

 PG_RETURN_INT64(result);
}

Datum
int8smaller(PG_FUNCTION_ARGS)
{
 int64  arg1 = PG_GETARG_INT64(0);
 int64  arg2 = PG_GETARG_INT64(1);
 int64  result;

 result = ((arg1 < arg2) ? arg1 : arg2);

 PG_RETURN_INT64(result);
}

Datum
int84pl(PG_FUNCTION_ARGS)
{
 int64  arg1 = PG_GETARG_INT64(0);
 int32  arg2 = PG_GETARG_INT32(1);
 int64  result;

 if (unlikely(pg_add_s64_overflow(arg1, (int64) arg2, &result)))
  ereport(ERROR,
    (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
     errmsg("bigint out of range")));
 PG_RETURN_INT64(result);
}

Datum
int84mi(PG_FUNCTION_ARGS)
{
 int64  arg1 = PG_GETARG_INT64(0);
 int32  arg2 = PG_GETARG_INT32(1);
 int64  result;

 if (unlikely(pg_sub_s64_overflow(arg1, (int64) arg2, &result)))
  ereport(ERROR,
    (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
     errmsg("bigint out of range")));
 PG_RETURN_INT64(result);
}

Datum
int84mul(PG_FUNCTION_ARGS)
{
 int64  arg1 = PG_GETARG_INT64(0);
 int32  arg2 = PG_GETARG_INT32(1);
 int64  result;

 if (unlikely(pg_mul_s64_overflow(arg1, (int64) arg2, &result)))
  ereport(ERROR,
    (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
     errmsg("bigint out of range")));
 PG_RETURN_INT64(result);
}

Datum
int84div(PG_FUNCTION_ARGS)
{
 int64  arg1 = PG_GETARG_INT64(0);
 int32  arg2 = PG_GETARG_INT32(1);
 int64  result;

 if (arg2 == 0)
 {
  ereport(ERROR,
    (errcode(ERRCODE_DIVISION_BY_ZERO),
     errmsg("division by zero")));
  /* ensure compiler realizes we mustn't reach the division (gcc bug) */
  PG_RETURN_NULL();
 }

 /*
  * INT64_MIN / -1 is problematic, since the result can't be represented on
  * a two's-complement machine.  Some machines produce INT64_MIN, some
  * produce zero, some throw an exception.  We can dodge the problem by
  * recognizing that division by -1 is the same as negation.
 */

 if (arg2 == -1)
 {
  if (unlikely(arg1 == PG_INT64_MIN))
   ereport(ERROR,
     (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
      errmsg("bigint out of range")));
  result = -arg1;
  PG_RETURN_INT64(result);
 }

 /* No overflow is possible */

 result = arg1 / arg2;

 PG_RETURN_INT64(result);
}

Datum
int48pl(PG_FUNCTION_ARGS)
{
 int32  arg1 = PG_GETARG_INT32(0);
 int64  arg2 = PG_GETARG_INT64(1);
 int64  result;

 if (unlikely(pg_add_s64_overflow((int64) arg1, arg2, &result)))
  ereport(ERROR,
    (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
     errmsg("bigint out of range")));
 PG_RETURN_INT64(result);
}

Datum
int48mi(PG_FUNCTION_ARGS)
{
 int32  arg1 = PG_GETARG_INT32(0);
 int64  arg2 = PG_GETARG_INT64(1);
 int64  result;

 if (unlikely(pg_sub_s64_overflow((int64) arg1, arg2, &result)))
  ereport(ERROR,
    (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
     errmsg("bigint out of range")));
 PG_RETURN_INT64(result);
}

Datum
int48mul(PG_FUNCTION_ARGS)
{
 int32  arg1 = PG_GETARG_INT32(0);
 int64  arg2 = PG_GETARG_INT64(1);
 int64  result;

 if (unlikely(pg_mul_s64_overflow((int64) arg1, arg2, &result)))
  ereport(ERROR,
    (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
     errmsg("bigint out of range")));
 PG_RETURN_INT64(result);
}

Datum
int48div(PG_FUNCTION_ARGS)
{
 int32  arg1 = PG_GETARG_INT32(0);
 int64  arg2 = PG_GETARG_INT64(1);

 if (unlikely(arg2 == 0))
 {
  ereport(ERROR,
    (errcode(ERRCODE_DIVISION_BY_ZERO),
     errmsg("division by zero")));
  /* ensure compiler realizes we mustn't reach the division (gcc bug) */
  PG_RETURN_NULL();
 }

 /* No overflow is possible */
 PG_RETURN_INT64((int64) arg1 / arg2);
}

Datum
int82pl(PG_FUNCTION_ARGS)
{
 int64  arg1 = PG_GETARG_INT64(0);
 int16  arg2 = PG_GETARG_INT16(1);
 int64  result;

 if (unlikely(pg_add_s64_overflow(arg1, (int64) arg2, &result)))
  ereport(ERROR,
    (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
     errmsg("bigint out of range")));
 PG_RETURN_INT64(result);
}

Datum
int82mi(PG_FUNCTION_ARGS)
{
 int64  arg1 = PG_GETARG_INT64(0);
 int16  arg2 = PG_GETARG_INT16(1);
 int64  result;

 if (unlikely(pg_sub_s64_overflow(arg1, (int64) arg2, &result)))
  ereport(ERROR,
    (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
     errmsg("bigint out of range")));
 PG_RETURN_INT64(result);
}

Datum
int82mul(PG_FUNCTION_ARGS)
{
 int64  arg1 = PG_GETARG_INT64(0);
 int16  arg2 = PG_GETARG_INT16(1);
 int64  result;

 if (unlikely(pg_mul_s64_overflow(arg1, (int64) arg2, &result)))
  ereport(ERROR,
    (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
     errmsg("bigint out of range")));
 PG_RETURN_INT64(result);
}

Datum
int82div(PG_FUNCTION_ARGS)
{
 int64  arg1 = PG_GETARG_INT64(0);
 int16  arg2 = PG_GETARG_INT16(1);
 int64  result;

 if (unlikely(arg2 == 0))
 {
  ereport(ERROR,
    (errcode(ERRCODE_DIVISION_BY_ZERO),
     errmsg("division by zero")));
  /* ensure compiler realizes we mustn't reach the division (gcc bug) */
  PG_RETURN_NULL();
 }

 /*
  * INT64_MIN / -1 is problematic, since the result can't be represented on
  * a two's-complement machine.  Some machines produce INT64_MIN, some
  * produce zero, some throw an exception.  We can dodge the problem by
  * recognizing that division by -1 is the same as negation.
 */

 if (arg2 == -1)
 {
  if (unlikely(arg1 == PG_INT64_MIN))
   ereport(ERROR,
     (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
      errmsg("bigint out of range")));
  result = -arg1;
  PG_RETURN_INT64(result);
 }

 /* No overflow is possible */

 result = arg1 / arg2;

 PG_RETURN_INT64(result);
}

Datum
int28pl(PG_FUNCTION_ARGS)
{
 int16  arg1 = PG_GETARG_INT16(0);
 int64  arg2 = PG_GETARG_INT64(1);
 int64  result;

 if (unlikely(pg_add_s64_overflow((int64) arg1, arg2, &result)))
  ereport(ERROR,
    (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
     errmsg("bigint out of range")));
 PG_RETURN_INT64(result);
}

Datum
int28mi(PG_FUNCTION_ARGS)
{
 int16  arg1 = PG_GETARG_INT16(0);
 int64  arg2 = PG_GETARG_INT64(1);
 int64  result;

 if (unlikely(pg_sub_s64_overflow((int64) arg1, arg2, &result)))
  ereport(ERROR,
    (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
     errmsg("bigint out of range")));
 PG_RETURN_INT64(result);
}

Datum
int28mul(PG_FUNCTION_ARGS)
{
 int16  arg1 = PG_GETARG_INT16(0);
 int64  arg2 = PG_GETARG_INT64(1);
 int64  result;

 if (unlikely(pg_mul_s64_overflow((int64) arg1, arg2, &result)))
  ereport(ERROR,
    (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
     errmsg("bigint out of range")));
 PG_RETURN_INT64(result);
}

Datum
int28div(PG_FUNCTION_ARGS)
{
 int16  arg1 = PG_GETARG_INT16(0);
 int64  arg2 = PG_GETARG_INT64(1);

 if (unlikely(arg2 == 0))
 {
  ereport(ERROR,
    (errcode(ERRCODE_DIVISION_BY_ZERO),
     errmsg("division by zero")));
  /* ensure compiler realizes we mustn't reach the division (gcc bug) */
  PG_RETURN_NULL();
 }

 /* No overflow is possible */
 PG_RETURN_INT64((int64) arg1 / arg2);
}

/* Binary arithmetics
 *
 *  int8and  - returns arg1 & arg2
 *  int8or  - returns arg1 | arg2
 *  int8xor  - returns arg1 # arg2
 *  int8not  - returns ~arg1
 *  int8shl  - returns arg1 << arg2
 *  int8shr  - returns arg1 >> arg2
 */


Datum
int8and(PG_FUNCTION_ARGS)
{
 int64  arg1 = PG_GETARG_INT64(0);
 int64  arg2 = PG_GETARG_INT64(1);

 PG_RETURN_INT64(arg1 & arg2);
}

Datum
int8or(PG_FUNCTION_ARGS)
{
 int64  arg1 = PG_GETARG_INT64(0);
 int64  arg2 = PG_GETARG_INT64(1);

 PG_RETURN_INT64(arg1 | arg2);
}

Datum
int8xor(PG_FUNCTION_ARGS)
{
 int64  arg1 = PG_GETARG_INT64(0);
 int64  arg2 = PG_GETARG_INT64(1);

 PG_RETURN_INT64(arg1 ^ arg2);
}

Datum
int8not(PG_FUNCTION_ARGS)
{
 int64  arg1 = PG_GETARG_INT64(0);

 PG_RETURN_INT64(~arg1);
}

Datum
int8shl(PG_FUNCTION_ARGS)
{
 int64  arg1 = PG_GETARG_INT64(0);
 int32  arg2 = PG_GETARG_INT32(1);

 PG_RETURN_INT64(arg1 << arg2);
}

Datum
int8shr(PG_FUNCTION_ARGS)
{
 int64  arg1 = PG_GETARG_INT64(0);
 int32  arg2 = PG_GETARG_INT32(1);

 PG_RETURN_INT64(arg1 >> arg2);
}

/*----------------------------------------------------------
 * Conversion operators.
 *---------------------------------------------------------*/


Datum
int48(PG_FUNCTION_ARGS)
{
 int32  arg = PG_GETARG_INT32(0);

 PG_RETURN_INT64((int64) arg);
}

Datum
int84(PG_FUNCTION_ARGS)
{
 int64  arg = PG_GETARG_INT64(0);

 if (unlikely(arg < PG_INT32_MIN) || unlikely(arg > PG_INT32_MAX))
  ereport(ERROR,
    (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
     errmsg("integer out of range")));

 PG_RETURN_INT32((int32) arg);
}

Datum
int28(PG_FUNCTION_ARGS)
{
 int16  arg = PG_GETARG_INT16(0);

 PG_RETURN_INT64((int64) arg);
}

Datum
int82(PG_FUNCTION_ARGS)
{
 int64  arg = PG_GETARG_INT64(0);

 if (unlikely(arg < PG_INT16_MIN) || unlikely(arg > PG_INT16_MAX))
  ereport(ERROR,
    (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
     errmsg("smallint out of range")));

 PG_RETURN_INT16((int16) arg);
}

Datum
i8tod(PG_FUNCTION_ARGS)
{
 int64  arg = PG_GETARG_INT64(0);
 float8  result;

 result = arg;

 PG_RETURN_FLOAT8(result);
}

/* dtoi8()
 * Convert float8 to 8-byte integer.
 */

Datum
dtoi8(PG_FUNCTION_ARGS)
{
 float8  num = PG_GETARG_FLOAT8(0);

 /*
  * Get rid of any fractional part in the input.  This is so we don't fail
  * on just-out-of-range values that would round into range.  Note
  * assumption that rint() will pass through a NaN or Inf unchanged.
 */

 num = rint(num);

 /* Range check */
 if (unlikely(isnan(num) || !FLOAT8_FITS_IN_INT64(num)))
  ereport(ERROR,
    (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
     errmsg("bigint out of range")));

 PG_RETURN_INT64((int64) num);
}

Datum
i8tof(PG_FUNCTION_ARGS)
{
 int64  arg = PG_GETARG_INT64(0);
 float4  result;

 result = arg;

 PG_RETURN_FLOAT4(result);
}

/* ftoi8()
 * Convert float4 to 8-byte integer.
 */

Datum
ftoi8(PG_FUNCTION_ARGS)
{
 float4  num = PG_GETARG_FLOAT4(0);

 /*
  * Get rid of any fractional part in the input.  This is so we don't fail
  * on just-out-of-range values that would round into range.  Note
  * assumption that rint() will pass through a NaN or Inf unchanged.
 */

 num = rint(num);

 /* Range check */
 if (unlikely(isnan(num) || !FLOAT4_FITS_IN_INT64(num)))
  ereport(ERROR,
    (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
     errmsg("bigint out of range")));

 PG_RETURN_INT64((int64) num);
}

Datum
i8tooid(PG_FUNCTION_ARGS)
{
 int64  arg = PG_GETARG_INT64(0);

 if (unlikely(arg < 0) || unlikely(arg > PG_UINT32_MAX))
  ereport(ERROR,
    (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
     errmsg("OID out of range")));

 PG_RETURN_OID((Oid) arg);
}

Datum
oidtoi8(PG_FUNCTION_ARGS)
{
 Oid   arg = PG_GETARG_OID(0);

 PG_RETURN_INT64((int64) arg);
}

/*
 * non-persistent numeric series generator
 */

Datum
generate_series_int8(PG_FUNCTION_ARGS)
{
 return generate_series_step_int8(fcinfo);
}

Datum
generate_series_step_int8(PG_FUNCTION_ARGS)
{
 FuncCallContext *funcctx;
 generate_series_fctx *fctx;
 int64  result;
 MemoryContext oldcontext;

 /* stuff done only on the first call of the function */
 if (SRF_IS_FIRSTCALL())
 {
  int64  start = PG_GETARG_INT64(0);
  int64  finish = PG_GETARG_INT64(1);
  int64  step = 1;

  /* see if we were given an explicit step size */
  if (PG_NARGS() == 3)
   step = PG_GETARG_INT64(2);
  if (step == 0)
   ereport(ERROR,
     (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
      errmsg("step size cannot equal zero")));

  /* create a function context for cross-call persistence */
  funcctx = SRF_FIRSTCALL_INIT();

  /*
   * switch to memory context appropriate for multiple function calls
 */

  oldcontext = MemoryContextSwitchTo(funcctx->multi_call_memory_ctx);

  /* allocate memory for user context */
  fctx = (generate_series_fctx *) palloc(sizeof(generate_series_fctx));

  /*
   * Use fctx to keep state from call to call. Seed current with the
   * original start value
 */

  fctx->current = start;
  fctx->finish = finish;
  fctx->step = step;

  funcctx->user_fctx = fctx;
  MemoryContextSwitchTo(oldcontext);
 }

 /* stuff done on every call of the function */
 funcctx = SRF_PERCALL_SETUP();

 /*
  * get the saved state and use current as the result for this iteration
 */

 fctx = funcctx->user_fctx;
 result = fctx->current;

 if ((fctx->step > 0 && fctx->current <= fctx->finish) ||
  (fctx->step < 0 && fctx->current >= fctx->finish))
 {
  /*
   * Increment current in preparation for next iteration. If next-value
   * computation overflows, this is the final result.
 */

  if (pg_add_s64_overflow(fctx->current, fctx->step, &fctx->current))
   fctx->step = 0;

  /* do when there is more left to send */
  SRF_RETURN_NEXT(funcctx, Int64GetDatum(result));
 }
 else
  /* do when there is no more left */
  SRF_RETURN_DONE(funcctx);
}

/*
 * Planner support function for generate_series(int8, int8 [, int8])
 */

Datum
generate_series_int8_support(PG_FUNCTION_ARGS)
{
 Node    *rawreq = (Node *) PG_GETARG_POINTER(0);
 Node    *ret = NULL;

 if (IsA(rawreq, SupportRequestRows))
 {
  /* Try to estimate the number of rows returned */
  SupportRequestRows *req = (SupportRequestRows *) rawreq;

  if (is_funcclause(req->node)) /* be paranoid */
  {
   List    *args = ((FuncExpr *) req->node)->args;
   Node    *arg1,
        *arg2,
        *arg3;

   /* We can use estimated argument values here */
   arg1 = estimate_expression_value(req->root, linitial(args));
   arg2 = estimate_expression_value(req->root, lsecond(args));
   if (list_length(args) >= 3)
    arg3 = estimate_expression_value(req->root, lthird(args));
   else
    arg3 = NULL;

   /*
    * If any argument is constant NULL, we can safely assume that
    * zero rows are returned.  Otherwise, if they're all non-NULL
    * constants, we can calculate the number of rows that will be
    * returned.  Use double arithmetic to avoid overflow hazards.
 */

   if ((IsA(arg1, Const) &&
     ((Const *) arg1)->constisnull) ||
    (IsA(arg2, Const) &&
     ((Const *) arg2)->constisnull) ||
    (arg3 != NULL && IsA(arg3, Const) &&
     ((Const *) arg3)->constisnull))
   {
    req->rows = 0;
    ret = (Node *) req;
   }
   else if (IsA(arg1, Const) &&
      IsA(arg2, Const) &&
      (arg3 == NULL || IsA(arg3, Const)))
   {
    double  start,
       finish,
       step;

    start = DatumGetInt64(((Const *) arg1)->constvalue);
    finish = DatumGetInt64(((Const *) arg2)->constvalue);
    step = arg3 ? DatumGetInt64(((Const *) arg3)->constvalue) : 1;

    /* This equation works for either sign of step */
    if (step != 0)
    {
     req->rows = floor((finish - start + step) / step);
     ret = (Node *) req;
    }
   }
  }
 }

 PG_RETURN_POINTER(ret);
}

Messung V0.5 in Prozent
C=91 H=94 G=92

[Verzeichnis aufwärts0.46unsichere VerbindungÜbersetzung europäischer Sprachen durch Browser2026-09-27]