1998-07-08 15:57:05 +02:00
|
|
|
/*-------------------------------------------------------------------------
|
|
|
|
*
|
1999-02-14 00:22:53 +01:00
|
|
|
* int8.c
|
1998-07-08 15:57:05 +02:00
|
|
|
* Internal 64-bit integer operations
|
|
|
|
*
|
2007-01-05 23:20:05 +01:00
|
|
|
* Portions Copyright (c) 1996-2007, PostgreSQL Global Development Group
|
2000-05-28 19:56:29 +02:00
|
|
|
* Portions Copyright (c) 1994, Regents of the University of California
|
|
|
|
*
|
|
|
|
* IDENTIFICATION
|
Wording cleanup for error messages. Also change can't -> cannot.
Standard English uses "may", "can", and "might" in different ways:
may - permission, "You may borrow my rake."
can - ability, "I can lift that log."
might - possibility, "It might rain today."
Unfortunately, in conversational English, their use is often mixed, as
in, "You may use this variable to do X", when in fact, "can" is a better
choice. Similarly, "It may crash" is better stated, "It might crash".
2007-02-01 20:10:30 +01:00
|
|
|
* $PostgreSQL: pgsql/src/backend/utils/adt/int8.c,v 1.64 2007/02/01 19:10:28 momjian Exp $
|
2000-05-28 19:56:29 +02:00
|
|
|
*
|
1998-07-08 15:57:05 +02:00
|
|
|
*-------------------------------------------------------------------------
|
|
|
|
*/
|
2000-07-13 00:59:15 +02:00
|
|
|
#include "postgres.h"
|
|
|
|
|
1998-07-08 15:57:05 +02:00
|
|
|
#include <ctype.h>
|
2004-02-03 09:29:57 +01:00
|
|
|
#include <limits.h>
|
1998-07-08 15:57:05 +02:00
|
|
|
#include <math.h>
|
1999-08-21 05:06:58 +02:00
|
|
|
|
2004-02-03 09:29:57 +01:00
|
|
|
#include "funcapi.h"
|
2003-05-09 17:44:42 +02:00
|
|
|
#include "libpq/pqformat.h"
|
2005-03-12 21:25:06 +01:00
|
|
|
#include "nodes/nodes.h"
|
1998-07-08 15:57:05 +02:00
|
|
|
#include "utils/int8.h"
|
|
|
|
|
2001-11-24 20:57:06 +01:00
|
|
|
|
1998-07-08 15:57:05 +02:00
|
|
|
#define MAXINT8LEN 25
|
|
|
|
|
2004-10-04 16:42:48 +02:00
|
|
|
#define SAMESIGN(a,b) (((a) < 0) == ((b) < 0))
|
|
|
|
|
2004-02-03 09:29:57 +01:00
|
|
|
typedef struct
|
|
|
|
{
|
|
|
|
int64 current;
|
|
|
|
int64 finish;
|
|
|
|
int64 step;
|
2004-08-29 07:07:03 +02:00
|
|
|
} generate_series_fctx;
|
1998-07-08 15:57:05 +02:00
|
|
|
|
2004-10-04 16:42:48 +02:00
|
|
|
|
1998-07-08 15:57:05 +02:00
|
|
|
/***********************************************************************
|
|
|
|
**
|
|
|
|
** Routines for 64-bit integers.
|
|
|
|
**
|
|
|
|
***********************************************************************/
|
|
|
|
|
|
|
|
/*----------------------------------------------------------
|
|
|
|
* Formatting and conversion routines.
|
|
|
|
*---------------------------------------------------------*/
|
|
|
|
|
Extend pg_cast castimplicit column to a three-way value; this allows us
to be flexible about assignment casts without introducing ambiguity in
operator/function resolution. Introduce a well-defined promotion hierarchy
for numeric datatypes (int2->int4->int8->numeric->float4->float8).
Change make_const to initially label numeric literals as int4, int8, or
numeric (never float8 anymore).
Explicitly mark Func and RelabelType nodes to indicate whether they came
from a function call, explicit cast, or implicit cast; use this to do
reverse-listing more accurately and without so many heuristics.
Explicit casts to char, varchar, bit, varbit will truncate or pad without
raising an error (the pre-7.2 behavior), while assigning to a column without
any explicit cast will still raise an error for wrong-length data like 7.3.
This more nearly follows the SQL spec than 7.2 behavior (we should be
reporting a 'completion condition' in the explicit-cast cases, but we have
no mechanism for that, so just do silent truncation).
Fix some problems with enforcement of typmod for array elements;
it didn't work at all in 'UPDATE ... SET array[n] = foo', for example.
Provide a generalized array_length_coerce() function to replace the
specialized per-array-type functions that used to be needed (and were
missing for NUMERIC as well as all the datetime types).
Add missing conversions int8<->float4, text<->numeric, oid<->int8.
initdb forced.
2002-09-18 23:35:25 +02:00
|
|
|
/*
|
|
|
|
* scanint8 --- try to parse a string into an int8.
|
|
|
|
*
|
2003-07-27 06:53:12 +02:00
|
|
|
* If errorOK is false, ereport a useful error message if the string is bad.
|
Extend pg_cast castimplicit column to a three-way value; this allows us
to be flexible about assignment casts without introducing ambiguity in
operator/function resolution. Introduce a well-defined promotion hierarchy
for numeric datatypes (int2->int4->int8->numeric->float4->float8).
Change make_const to initially label numeric literals as int4, int8, or
numeric (never float8 anymore).
Explicitly mark Func and RelabelType nodes to indicate whether they came
from a function call, explicit cast, or implicit cast; use this to do
reverse-listing more accurately and without so many heuristics.
Explicit casts to char, varchar, bit, varbit will truncate or pad without
raising an error (the pre-7.2 behavior), while assigning to a column without
any explicit cast will still raise an error for wrong-length data like 7.3.
This more nearly follows the SQL spec than 7.2 behavior (we should be
reporting a 'completion condition' in the explicit-cast cases, but we have
no mechanism for that, so just do silent truncation).
Fix some problems with enforcement of typmod for array elements;
it didn't work at all in 'UPDATE ... SET array[n] = foo', for example.
Provide a generalized array_length_coerce() function to replace the
specialized per-array-type functions that used to be needed (and were
missing for NUMERIC as well as all the datetime types).
Add missing conversions int8<->float4, text<->numeric, oid<->int8.
initdb forced.
2002-09-18 23:35:25 +02:00
|
|
|
* If errorOK is true, just return "false" for bad input.
|
1998-07-08 15:57:05 +02:00
|
|
|
*/
|
Extend pg_cast castimplicit column to a three-way value; this allows us
to be flexible about assignment casts without introducing ambiguity in
operator/function resolution. Introduce a well-defined promotion hierarchy
for numeric datatypes (int2->int4->int8->numeric->float4->float8).
Change make_const to initially label numeric literals as int4, int8, or
numeric (never float8 anymore).
Explicitly mark Func and RelabelType nodes to indicate whether they came
from a function call, explicit cast, or implicit cast; use this to do
reverse-listing more accurately and without so many heuristics.
Explicit casts to char, varchar, bit, varbit will truncate or pad without
raising an error (the pre-7.2 behavior), while assigning to a column without
any explicit cast will still raise an error for wrong-length data like 7.3.
This more nearly follows the SQL spec than 7.2 behavior (we should be
reporting a 'completion condition' in the explicit-cast cases, but we have
no mechanism for that, so just do silent truncation).
Fix some problems with enforcement of typmod for array elements;
it didn't work at all in 'UPDATE ... SET array[n] = foo', for example.
Provide a generalized array_length_coerce() function to replace the
specialized per-array-type functions that used to be needed (and were
missing for NUMERIC as well as all the datetime types).
Add missing conversions int8<->float4, text<->numeric, oid<->int8.
initdb forced.
2002-09-18 23:35:25 +02:00
|
|
|
bool
|
|
|
|
scanint8(const char *str, bool errorOK, int64 *result)
|
1998-07-08 15:57:05 +02:00
|
|
|
{
|
Extend pg_cast castimplicit column to a three-way value; this allows us
to be flexible about assignment casts without introducing ambiguity in
operator/function resolution. Introduce a well-defined promotion hierarchy
for numeric datatypes (int2->int4->int8->numeric->float4->float8).
Change make_const to initially label numeric literals as int4, int8, or
numeric (never float8 anymore).
Explicitly mark Func and RelabelType nodes to indicate whether they came
from a function call, explicit cast, or implicit cast; use this to do
reverse-listing more accurately and without so many heuristics.
Explicit casts to char, varchar, bit, varbit will truncate or pad without
raising an error (the pre-7.2 behavior), while assigning to a column without
any explicit cast will still raise an error for wrong-length data like 7.3.
This more nearly follows the SQL spec than 7.2 behavior (we should be
reporting a 'completion condition' in the explicit-cast cases, but we have
no mechanism for that, so just do silent truncation).
Fix some problems with enforcement of typmod for array elements;
it didn't work at all in 'UPDATE ... SET array[n] = foo', for example.
Provide a generalized array_length_coerce() function to replace the
specialized per-array-type functions that used to be needed (and were
missing for NUMERIC as well as all the datetime types).
Add missing conversions int8<->float4, text<->numeric, oid<->int8.
initdb forced.
2002-09-18 23:35:25 +02:00
|
|
|
const char *ptr = str;
|
1999-02-03 01:18:53 +01:00
|
|
|
int64 tmp = 0;
|
|
|
|
int sign = 1;
|
1998-07-08 15:57:05 +02:00
|
|
|
|
1999-05-25 18:15:34 +02:00
|
|
|
/*
|
2005-10-15 04:49:52 +02:00
|
|
|
* Do our own scan, rather than relying on sscanf which might be broken
|
|
|
|
* for long long.
|
1999-02-03 01:18:53 +01:00
|
|
|
*/
|
Extend pg_cast castimplicit column to a three-way value; this allows us
to be flexible about assignment casts without introducing ambiguity in
operator/function resolution. Introduce a well-defined promotion hierarchy
for numeric datatypes (int2->int4->int8->numeric->float4->float8).
Change make_const to initially label numeric literals as int4, int8, or
numeric (never float8 anymore).
Explicitly mark Func and RelabelType nodes to indicate whether they came
from a function call, explicit cast, or implicit cast; use this to do
reverse-listing more accurately and without so many heuristics.
Explicit casts to char, varchar, bit, varbit will truncate or pad without
raising an error (the pre-7.2 behavior), while assigning to a column without
any explicit cast will still raise an error for wrong-length data like 7.3.
This more nearly follows the SQL spec than 7.2 behavior (we should be
reporting a 'completion condition' in the explicit-cast cases, but we have
no mechanism for that, so just do silent truncation).
Fix some problems with enforcement of typmod for array elements;
it didn't work at all in 'UPDATE ... SET array[n] = foo', for example.
Provide a generalized array_length_coerce() function to replace the
specialized per-array-type functions that used to be needed (and were
missing for NUMERIC as well as all the datetime types).
Add missing conversions int8<->float4, text<->numeric, oid<->int8.
initdb forced.
2002-09-18 23:35:25 +02:00
|
|
|
|
|
|
|
/* skip leading spaces */
|
|
|
|
while (*ptr && isspace((unsigned char) *ptr))
|
1999-02-03 01:18:53 +01:00
|
|
|
ptr++;
|
Extend pg_cast castimplicit column to a three-way value; this allows us
to be flexible about assignment casts without introducing ambiguity in
operator/function resolution. Introduce a well-defined promotion hierarchy
for numeric datatypes (int2->int4->int8->numeric->float4->float8).
Change make_const to initially label numeric literals as int4, int8, or
numeric (never float8 anymore).
Explicitly mark Func and RelabelType nodes to indicate whether they came
from a function call, explicit cast, or implicit cast; use this to do
reverse-listing more accurately and without so many heuristics.
Explicit casts to char, varchar, bit, varbit will truncate or pad without
raising an error (the pre-7.2 behavior), while assigning to a column without
any explicit cast will still raise an error for wrong-length data like 7.3.
This more nearly follows the SQL spec than 7.2 behavior (we should be
reporting a 'completion condition' in the explicit-cast cases, but we have
no mechanism for that, so just do silent truncation).
Fix some problems with enforcement of typmod for array elements;
it didn't work at all in 'UPDATE ... SET array[n] = foo', for example.
Provide a generalized array_length_coerce() function to replace the
specialized per-array-type functions that used to be needed (and were
missing for NUMERIC as well as all the datetime types).
Add missing conversions int8<->float4, text<->numeric, oid<->int8.
initdb forced.
2002-09-18 23:35:25 +02:00
|
|
|
|
2001-11-24 20:57:06 +01:00
|
|
|
/* handle sign */
|
|
|
|
if (*ptr == '-')
|
|
|
|
{
|
|
|
|
ptr++;
|
2002-09-04 22:31:48 +02:00
|
|
|
|
2001-11-24 20:57:06 +01:00
|
|
|
/*
|
2002-09-04 22:31:48 +02:00
|
|
|
* Do an explicit check for INT64_MIN. Ugly though this is, it's
|
2005-10-15 04:49:52 +02:00
|
|
|
* cleaner than trying to get the loop below to handle it portably.
|
2001-11-24 20:57:06 +01:00
|
|
|
*/
|
|
|
|
#ifndef INT64_IS_BUSTED
|
2004-10-04 16:42:48 +02:00
|
|
|
if (strncmp(ptr, "9223372036854775808", 19) == 0)
|
2001-11-24 20:57:06 +01:00
|
|
|
{
|
2004-10-04 16:42:48 +02:00
|
|
|
tmp = -INT64CONST(0x7fffffffffffffff) - 1;
|
|
|
|
ptr += 19;
|
|
|
|
goto gotdigits;
|
2001-11-24 20:57:06 +01:00
|
|
|
}
|
|
|
|
#endif
|
2004-10-04 16:42:48 +02:00
|
|
|
|
|
|
|
sign = -1;
|
2001-11-24 20:57:06 +01:00
|
|
|
}
|
1999-02-03 01:18:53 +01:00
|
|
|
else if (*ptr == '+')
|
|
|
|
ptr++;
|
Extend pg_cast castimplicit column to a three-way value; this allows us
to be flexible about assignment casts without introducing ambiguity in
operator/function resolution. Introduce a well-defined promotion hierarchy
for numeric datatypes (int2->int4->int8->numeric->float4->float8).
Change make_const to initially label numeric literals as int4, int8, or
numeric (never float8 anymore).
Explicitly mark Func and RelabelType nodes to indicate whether they came
from a function call, explicit cast, or implicit cast; use this to do
reverse-listing more accurately and without so many heuristics.
Explicit casts to char, varchar, bit, varbit will truncate or pad without
raising an error (the pre-7.2 behavior), while assigning to a column without
any explicit cast will still raise an error for wrong-length data like 7.3.
This more nearly follows the SQL spec than 7.2 behavior (we should be
reporting a 'completion condition' in the explicit-cast cases, but we have
no mechanism for that, so just do silent truncation).
Fix some problems with enforcement of typmod for array elements;
it didn't work at all in 'UPDATE ... SET array[n] = foo', for example.
Provide a generalized array_length_coerce() function to replace the
specialized per-array-type functions that used to be needed (and were
missing for NUMERIC as well as all the datetime types).
Add missing conversions int8<->float4, text<->numeric, oid<->int8.
initdb forced.
2002-09-18 23:35:25 +02:00
|
|
|
|
|
|
|
/* require at least one digit */
|
|
|
|
if (!isdigit((unsigned char) *ptr))
|
|
|
|
{
|
|
|
|
if (errorOK)
|
|
|
|
return false;
|
|
|
|
else
|
2003-07-27 06:53:12 +02:00
|
|
|
ereport(ERROR,
|
|
|
|
(errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
|
2004-10-04 16:42:48 +02:00
|
|
|
errmsg("invalid input syntax for integer: \"%s\"",
|
|
|
|
str)));
|
Extend pg_cast castimplicit column to a three-way value; this allows us
to be flexible about assignment casts without introducing ambiguity in
operator/function resolution. Introduce a well-defined promotion hierarchy
for numeric datatypes (int2->int4->int8->numeric->float4->float8).
Change make_const to initially label numeric literals as int4, int8, or
numeric (never float8 anymore).
Explicitly mark Func and RelabelType nodes to indicate whether they came
from a function call, explicit cast, or implicit cast; use this to do
reverse-listing more accurately and without so many heuristics.
Explicit casts to char, varchar, bit, varbit will truncate or pad without
raising an error (the pre-7.2 behavior), while assigning to a column without
any explicit cast will still raise an error for wrong-length data like 7.3.
This more nearly follows the SQL spec than 7.2 behavior (we should be
reporting a 'completion condition' in the explicit-cast cases, but we have
no mechanism for that, so just do silent truncation).
Fix some problems with enforcement of typmod for array elements;
it didn't work at all in 'UPDATE ... SET array[n] = foo', for example.
Provide a generalized array_length_coerce() function to replace the
specialized per-array-type functions that used to be needed (and were
missing for NUMERIC as well as all the datetime types).
Add missing conversions int8<->float4, text<->numeric, oid<->int8.
initdb forced.
2002-09-18 23:35:25 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
/* process digits */
|
|
|
|
while (*ptr && isdigit((unsigned char) *ptr))
|
2000-02-24 02:54:40 +01:00
|
|
|
{
|
2000-04-12 19:17:23 +02:00
|
|
|
int64 newtmp = tmp * 10 + (*ptr++ - '0');
|
2000-02-24 02:54:40 +01:00
|
|
|
|
|
|
|
if ((newtmp / 10) != tmp) /* overflow? */
|
Extend pg_cast castimplicit column to a three-way value; this allows us
to be flexible about assignment casts without introducing ambiguity in
operator/function resolution. Introduce a well-defined promotion hierarchy
for numeric datatypes (int2->int4->int8->numeric->float4->float8).
Change make_const to initially label numeric literals as int4, int8, or
numeric (never float8 anymore).
Explicitly mark Func and RelabelType nodes to indicate whether they came
from a function call, explicit cast, or implicit cast; use this to do
reverse-listing more accurately and without so many heuristics.
Explicit casts to char, varchar, bit, varbit will truncate or pad without
raising an error (the pre-7.2 behavior), while assigning to a column without
any explicit cast will still raise an error for wrong-length data like 7.3.
This more nearly follows the SQL spec than 7.2 behavior (we should be
reporting a 'completion condition' in the explicit-cast cases, but we have
no mechanism for that, so just do silent truncation).
Fix some problems with enforcement of typmod for array elements;
it didn't work at all in 'UPDATE ... SET array[n] = foo', for example.
Provide a generalized array_length_coerce() function to replace the
specialized per-array-type functions that used to be needed (and were
missing for NUMERIC as well as all the datetime types).
Add missing conversions int8<->float4, text<->numeric, oid<->int8.
initdb forced.
2002-09-18 23:35:25 +02:00
|
|
|
{
|
|
|
|
if (errorOK)
|
|
|
|
return false;
|
|
|
|
else
|
2003-07-27 06:53:12 +02:00
|
|
|
ereport(ERROR,
|
|
|
|
(errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
|
2005-10-15 04:49:52 +02:00
|
|
|
errmsg("value \"%s\" is out of range for type bigint",
|
|
|
|
str)));
|
Extend pg_cast castimplicit column to a three-way value; this allows us
to be flexible about assignment casts without introducing ambiguity in
operator/function resolution. Introduce a well-defined promotion hierarchy
for numeric datatypes (int2->int4->int8->numeric->float4->float8).
Change make_const to initially label numeric literals as int4, int8, or
numeric (never float8 anymore).
Explicitly mark Func and RelabelType nodes to indicate whether they came
from a function call, explicit cast, or implicit cast; use this to do
reverse-listing more accurately and without so many heuristics.
Explicit casts to char, varchar, bit, varbit will truncate or pad without
raising an error (the pre-7.2 behavior), while assigning to a column without
any explicit cast will still raise an error for wrong-length data like 7.3.
This more nearly follows the SQL spec than 7.2 behavior (we should be
reporting a 'completion condition' in the explicit-cast cases, but we have
no mechanism for that, so just do silent truncation).
Fix some problems with enforcement of typmod for array elements;
it didn't work at all in 'UPDATE ... SET array[n] = foo', for example.
Provide a generalized array_length_coerce() function to replace the
specialized per-array-type functions that used to be needed (and were
missing for NUMERIC as well as all the datetime types).
Add missing conversions int8<->float4, text<->numeric, oid<->int8.
initdb forced.
2002-09-18 23:35:25 +02:00
|
|
|
}
|
2000-02-24 02:54:40 +01:00
|
|
|
tmp = newtmp;
|
|
|
|
}
|
1998-07-08 15:57:05 +02:00
|
|
|
|
2004-10-04 16:42:48 +02:00
|
|
|
gotdigits:
|
|
|
|
|
2004-03-11 03:11:14 +01:00
|
|
|
/* allow trailing whitespace, but not other trailing chars */
|
2004-04-02 00:51:31 +02:00
|
|
|
while (*ptr != '\0' && isspace((unsigned char) *ptr))
|
2004-03-11 03:11:14 +01:00
|
|
|
ptr++;
|
|
|
|
|
|
|
|
if (*ptr != '\0')
|
Extend pg_cast castimplicit column to a three-way value; this allows us
to be flexible about assignment casts without introducing ambiguity in
operator/function resolution. Introduce a well-defined promotion hierarchy
for numeric datatypes (int2->int4->int8->numeric->float4->float8).
Change make_const to initially label numeric literals as int4, int8, or
numeric (never float8 anymore).
Explicitly mark Func and RelabelType nodes to indicate whether they came
from a function call, explicit cast, or implicit cast; use this to do
reverse-listing more accurately and without so many heuristics.
Explicit casts to char, varchar, bit, varbit will truncate or pad without
raising an error (the pre-7.2 behavior), while assigning to a column without
any explicit cast will still raise an error for wrong-length data like 7.3.
This more nearly follows the SQL spec than 7.2 behavior (we should be
reporting a 'completion condition' in the explicit-cast cases, but we have
no mechanism for that, so just do silent truncation).
Fix some problems with enforcement of typmod for array elements;
it didn't work at all in 'UPDATE ... SET array[n] = foo', for example.
Provide a generalized array_length_coerce() function to replace the
specialized per-array-type functions that used to be needed (and were
missing for NUMERIC as well as all the datetime types).
Add missing conversions int8<->float4, text<->numeric, oid<->int8.
initdb forced.
2002-09-18 23:35:25 +02:00
|
|
|
{
|
|
|
|
if (errorOK)
|
|
|
|
return false;
|
|
|
|
else
|
2003-07-27 06:53:12 +02:00
|
|
|
ereport(ERROR,
|
|
|
|
(errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
|
2004-10-04 16:42:48 +02:00
|
|
|
errmsg("invalid input syntax for integer: \"%s\"",
|
|
|
|
str)));
|
Extend pg_cast castimplicit column to a three-way value; this allows us
to be flexible about assignment casts without introducing ambiguity in
operator/function resolution. Introduce a well-defined promotion hierarchy
for numeric datatypes (int2->int4->int8->numeric->float4->float8).
Change make_const to initially label numeric literals as int4, int8, or
numeric (never float8 anymore).
Explicitly mark Func and RelabelType nodes to indicate whether they came
from a function call, explicit cast, or implicit cast; use this to do
reverse-listing more accurately and without so many heuristics.
Explicit casts to char, varchar, bit, varbit will truncate or pad without
raising an error (the pre-7.2 behavior), while assigning to a column without
any explicit cast will still raise an error for wrong-length data like 7.3.
This more nearly follows the SQL spec than 7.2 behavior (we should be
reporting a 'completion condition' in the explicit-cast cases, but we have
no mechanism for that, so just do silent truncation).
Fix some problems with enforcement of typmod for array elements;
it didn't work at all in 'UPDATE ... SET array[n] = foo', for example.
Provide a generalized array_length_coerce() function to replace the
specialized per-array-type functions that used to be needed (and were
missing for NUMERIC as well as all the datetime types).
Add missing conversions int8<->float4, text<->numeric, oid<->int8.
initdb forced.
2002-09-18 23:35:25 +02:00
|
|
|
}
|
1998-07-08 15:57:05 +02:00
|
|
|
|
Extend pg_cast castimplicit column to a three-way value; this allows us
to be flexible about assignment casts without introducing ambiguity in
operator/function resolution. Introduce a well-defined promotion hierarchy
for numeric datatypes (int2->int4->int8->numeric->float4->float8).
Change make_const to initially label numeric literals as int4, int8, or
numeric (never float8 anymore).
Explicitly mark Func and RelabelType nodes to indicate whether they came
from a function call, explicit cast, or implicit cast; use this to do
reverse-listing more accurately and without so many heuristics.
Explicit casts to char, varchar, bit, varbit will truncate or pad without
raising an error (the pre-7.2 behavior), while assigning to a column without
any explicit cast will still raise an error for wrong-length data like 7.3.
This more nearly follows the SQL spec than 7.2 behavior (we should be
reporting a 'completion condition' in the explicit-cast cases, but we have
no mechanism for that, so just do silent truncation).
Fix some problems with enforcement of typmod for array elements;
it didn't work at all in 'UPDATE ... SET array[n] = foo', for example.
Provide a generalized array_length_coerce() function to replace the
specialized per-array-type functions that used to be needed (and were
missing for NUMERIC as well as all the datetime types).
Add missing conversions int8<->float4, text<->numeric, oid<->int8.
initdb forced.
2002-09-18 23:35:25 +02:00
|
|
|
*result = (sign < 0) ? -tmp : tmp;
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* int8in()
|
|
|
|
*/
|
|
|
|
Datum
|
|
|
|
int8in(PG_FUNCTION_ARGS)
|
|
|
|
{
|
|
|
|
char *str = PG_GETARG_CSTRING(0);
|
|
|
|
int64 result;
|
|
|
|
|
|
|
|
(void) scanint8(str, false, &result);
|
2000-06-13 09:35:40 +02:00
|
|
|
PG_RETURN_INT64(result);
|
|
|
|
}
|
1998-07-08 15:57:05 +02:00
|
|
|
|
|
|
|
|
|
|
|
/* int8out()
|
|
|
|
*/
|
2000-06-13 09:35:40 +02:00
|
|
|
Datum
|
|
|
|
int8out(PG_FUNCTION_ARGS)
|
1998-07-08 15:57:05 +02:00
|
|
|
{
|
2000-06-13 09:35:40 +02:00
|
|
|
int64 val = PG_GETARG_INT64(0);
|
1998-07-08 15:57:05 +02:00
|
|
|
char *result;
|
|
|
|
int len;
|
|
|
|
char buf[MAXINT8LEN + 1];
|
|
|
|
|
2000-06-13 09:35:40 +02:00
|
|
|
if ((len = snprintf(buf, MAXINT8LEN, INT64_FORMAT, val)) < 0)
|
2003-07-27 06:53:12 +02:00
|
|
|
elog(ERROR, "could not format int8");
|
1998-07-08 15:57:05 +02:00
|
|
|
|
2000-06-13 09:35:40 +02:00
|
|
|
result = pstrdup(buf);
|
|
|
|
PG_RETURN_CSTRING(result);
|
|
|
|
}
|
1998-07-08 15:57:05 +02:00
|
|
|
|
2003-05-09 17:44:42 +02:00
|
|
|
/*
|
|
|
|
* 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));
|
|
|
|
}
|
|
|
|
|
1998-07-08 15:57:05 +02:00
|
|
|
|
|
|
|
/*----------------------------------------------------------
|
2000-07-28 07:07:49 +02:00
|
|
|
* Relational operators for int8s, including cross-data-type comparisons.
|
1998-07-08 15:57:05 +02:00
|
|
|
*---------------------------------------------------------*/
|
|
|
|
|
|
|
|
/* int8relop()
|
|
|
|
* Is val1 relop val2?
|
|
|
|
*/
|
2000-06-13 09:35:40 +02:00
|
|
|
Datum
|
|
|
|
int8eq(PG_FUNCTION_ARGS)
|
1998-07-08 15:57:05 +02:00
|
|
|
{
|
2000-06-13 09:35:40 +02:00
|
|
|
int64 val1 = PG_GETARG_INT64(0);
|
|
|
|
int64 val2 = PG_GETARG_INT64(1);
|
1999-08-21 05:06:58 +02:00
|
|
|
|
2000-06-13 09:35:40 +02:00
|
|
|
PG_RETURN_BOOL(val1 == val2);
|
|
|
|
}
|
1998-07-08 15:57:05 +02:00
|
|
|
|
2000-06-13 09:35:40 +02:00
|
|
|
Datum
|
|
|
|
int8ne(PG_FUNCTION_ARGS)
|
1998-07-08 15:57:05 +02:00
|
|
|
{
|
2000-06-13 09:35:40 +02:00
|
|
|
int64 val1 = PG_GETARG_INT64(0);
|
|
|
|
int64 val2 = PG_GETARG_INT64(1);
|
1999-08-21 05:06:58 +02:00
|
|
|
|
2000-06-13 09:35:40 +02:00
|
|
|
PG_RETURN_BOOL(val1 != val2);
|
|
|
|
}
|
1998-07-08 15:57:05 +02:00
|
|
|
|
2000-06-13 09:35:40 +02:00
|
|
|
Datum
|
|
|
|
int8lt(PG_FUNCTION_ARGS)
|
1998-07-08 15:57:05 +02:00
|
|
|
{
|
2000-06-13 09:35:40 +02:00
|
|
|
int64 val1 = PG_GETARG_INT64(0);
|
|
|
|
int64 val2 = PG_GETARG_INT64(1);
|
1999-08-21 05:06:58 +02:00
|
|
|
|
2000-06-13 09:35:40 +02:00
|
|
|
PG_RETURN_BOOL(val1 < val2);
|
|
|
|
}
|
1998-07-08 15:57:05 +02:00
|
|
|
|
2000-06-13 09:35:40 +02:00
|
|
|
Datum
|
|
|
|
int8gt(PG_FUNCTION_ARGS)
|
1998-07-08 15:57:05 +02:00
|
|
|
{
|
2000-06-13 09:35:40 +02:00
|
|
|
int64 val1 = PG_GETARG_INT64(0);
|
|
|
|
int64 val2 = PG_GETARG_INT64(1);
|
1999-08-21 05:06:58 +02:00
|
|
|
|
2000-06-13 09:35:40 +02:00
|
|
|
PG_RETURN_BOOL(val1 > val2);
|
|
|
|
}
|
1998-07-08 15:57:05 +02:00
|
|
|
|
2000-06-13 09:35:40 +02:00
|
|
|
Datum
|
|
|
|
int8le(PG_FUNCTION_ARGS)
|
1998-07-08 15:57:05 +02:00
|
|
|
{
|
2000-06-13 09:35:40 +02:00
|
|
|
int64 val1 = PG_GETARG_INT64(0);
|
|
|
|
int64 val2 = PG_GETARG_INT64(1);
|
1999-08-21 05:06:58 +02:00
|
|
|
|
2000-06-13 09:35:40 +02:00
|
|
|
PG_RETURN_BOOL(val1 <= val2);
|
|
|
|
}
|
1998-07-08 15:57:05 +02:00
|
|
|
|
2000-06-13 09:35:40 +02:00
|
|
|
Datum
|
|
|
|
int8ge(PG_FUNCTION_ARGS)
|
1998-07-08 15:57:05 +02:00
|
|
|
{
|
2000-06-13 09:35:40 +02:00
|
|
|
int64 val1 = PG_GETARG_INT64(0);
|
|
|
|
int64 val2 = PG_GETARG_INT64(1);
|
1998-07-08 15:57:05 +02:00
|
|
|
|
2000-06-13 09:35:40 +02:00
|
|
|
PG_RETURN_BOOL(val1 >= val2);
|
|
|
|
}
|
1998-07-08 15:57:05 +02:00
|
|
|
|
|
|
|
/* int84relop()
|
|
|
|
* Is 64-bit val1 relop 32-bit val2?
|
|
|
|
*/
|
2000-06-13 09:35:40 +02:00
|
|
|
Datum
|
|
|
|
int84eq(PG_FUNCTION_ARGS)
|
1998-07-08 15:57:05 +02:00
|
|
|
{
|
2000-06-13 09:35:40 +02:00
|
|
|
int64 val1 = PG_GETARG_INT64(0);
|
|
|
|
int32 val2 = PG_GETARG_INT32(1);
|
1999-08-21 05:06:58 +02:00
|
|
|
|
2000-06-13 09:35:40 +02:00
|
|
|
PG_RETURN_BOOL(val1 == val2);
|
|
|
|
}
|
1998-07-08 15:57:05 +02:00
|
|
|
|
2000-06-13 09:35:40 +02:00
|
|
|
Datum
|
|
|
|
int84ne(PG_FUNCTION_ARGS)
|
1998-07-08 15:57:05 +02:00
|
|
|
{
|
2000-06-13 09:35:40 +02:00
|
|
|
int64 val1 = PG_GETARG_INT64(0);
|
|
|
|
int32 val2 = PG_GETARG_INT32(1);
|
1999-08-21 05:06:58 +02:00
|
|
|
|
2000-06-13 09:35:40 +02:00
|
|
|
PG_RETURN_BOOL(val1 != val2);
|
|
|
|
}
|
1998-07-08 15:57:05 +02:00
|
|
|
|
2000-06-13 09:35:40 +02:00
|
|
|
Datum
|
|
|
|
int84lt(PG_FUNCTION_ARGS)
|
1998-07-08 15:57:05 +02:00
|
|
|
{
|
2000-06-13 09:35:40 +02:00
|
|
|
int64 val1 = PG_GETARG_INT64(0);
|
|
|
|
int32 val2 = PG_GETARG_INT32(1);
|
1999-08-21 05:06:58 +02:00
|
|
|
|
2000-06-13 09:35:40 +02:00
|
|
|
PG_RETURN_BOOL(val1 < val2);
|
|
|
|
}
|
1998-07-08 15:57:05 +02:00
|
|
|
|
2000-06-13 09:35:40 +02:00
|
|
|
Datum
|
|
|
|
int84gt(PG_FUNCTION_ARGS)
|
1998-07-08 15:57:05 +02:00
|
|
|
{
|
2000-06-13 09:35:40 +02:00
|
|
|
int64 val1 = PG_GETARG_INT64(0);
|
|
|
|
int32 val2 = PG_GETARG_INT32(1);
|
1999-08-21 05:06:58 +02:00
|
|
|
|
2000-06-13 09:35:40 +02:00
|
|
|
PG_RETURN_BOOL(val1 > val2);
|
|
|
|
}
|
1998-07-08 15:57:05 +02:00
|
|
|
|
2000-06-13 09:35:40 +02:00
|
|
|
Datum
|
|
|
|
int84le(PG_FUNCTION_ARGS)
|
1998-07-08 15:57:05 +02:00
|
|
|
{
|
2000-06-13 09:35:40 +02:00
|
|
|
int64 val1 = PG_GETARG_INT64(0);
|
|
|
|
int32 val2 = PG_GETARG_INT32(1);
|
1999-08-21 05:06:58 +02:00
|
|
|
|
2000-06-13 09:35:40 +02:00
|
|
|
PG_RETURN_BOOL(val1 <= val2);
|
|
|
|
}
|
1998-07-08 15:57:05 +02:00
|
|
|
|
2000-06-13 09:35:40 +02:00
|
|
|
Datum
|
|
|
|
int84ge(PG_FUNCTION_ARGS)
|
1998-07-08 15:57:05 +02:00
|
|
|
{
|
2000-06-13 09:35:40 +02:00
|
|
|
int64 val1 = PG_GETARG_INT64(0);
|
|
|
|
int32 val2 = PG_GETARG_INT32(1);
|
1998-07-08 15:57:05 +02:00
|
|
|
|
2000-06-13 09:35:40 +02:00
|
|
|
PG_RETURN_BOOL(val1 >= val2);
|
|
|
|
}
|
1998-07-08 15:57:05 +02:00
|
|
|
|
|
|
|
/* int48relop()
|
|
|
|
* Is 32-bit val1 relop 64-bit val2?
|
|
|
|
*/
|
2000-06-13 09:35:40 +02:00
|
|
|
Datum
|
|
|
|
int48eq(PG_FUNCTION_ARGS)
|
1998-07-08 15:57:05 +02:00
|
|
|
{
|
2000-06-13 09:35:40 +02:00
|
|
|
int32 val1 = PG_GETARG_INT32(0);
|
|
|
|
int64 val2 = PG_GETARG_INT64(1);
|
1999-08-21 05:06:58 +02:00
|
|
|
|
2000-06-13 09:35:40 +02:00
|
|
|
PG_RETURN_BOOL(val1 == val2);
|
|
|
|
}
|
1998-07-08 15:57:05 +02:00
|
|
|
|
2000-06-13 09:35:40 +02:00
|
|
|
Datum
|
|
|
|
int48ne(PG_FUNCTION_ARGS)
|
1998-07-08 15:57:05 +02:00
|
|
|
{
|
2000-06-13 09:35:40 +02:00
|
|
|
int32 val1 = PG_GETARG_INT32(0);
|
|
|
|
int64 val2 = PG_GETARG_INT64(1);
|
1999-08-21 05:06:58 +02:00
|
|
|
|
2000-06-13 09:35:40 +02:00
|
|
|
PG_RETURN_BOOL(val1 != val2);
|
|
|
|
}
|
1998-07-08 15:57:05 +02:00
|
|
|
|
2000-06-13 09:35:40 +02:00
|
|
|
Datum
|
|
|
|
int48lt(PG_FUNCTION_ARGS)
|
1998-07-08 15:57:05 +02:00
|
|
|
{
|
2000-06-13 09:35:40 +02:00
|
|
|
int32 val1 = PG_GETARG_INT32(0);
|
|
|
|
int64 val2 = PG_GETARG_INT64(1);
|
1999-08-21 05:06:58 +02:00
|
|
|
|
2000-06-13 09:35:40 +02:00
|
|
|
PG_RETURN_BOOL(val1 < val2);
|
|
|
|
}
|
1998-07-08 15:57:05 +02:00
|
|
|
|
2000-06-13 09:35:40 +02:00
|
|
|
Datum
|
|
|
|
int48gt(PG_FUNCTION_ARGS)
|
1998-07-08 15:57:05 +02:00
|
|
|
{
|
2000-06-13 09:35:40 +02:00
|
|
|
int32 val1 = PG_GETARG_INT32(0);
|
|
|
|
int64 val2 = PG_GETARG_INT64(1);
|
1999-08-21 05:06:58 +02:00
|
|
|
|
2000-06-13 09:35:40 +02:00
|
|
|
PG_RETURN_BOOL(val1 > val2);
|
|
|
|
}
|
1998-07-08 15:57:05 +02:00
|
|
|
|
2000-06-13 09:35:40 +02:00
|
|
|
Datum
|
|
|
|
int48le(PG_FUNCTION_ARGS)
|
1998-07-08 15:57:05 +02:00
|
|
|
{
|
2000-06-13 09:35:40 +02:00
|
|
|
int32 val1 = PG_GETARG_INT32(0);
|
|
|
|
int64 val2 = PG_GETARG_INT64(1);
|
1999-08-21 05:06:58 +02:00
|
|
|
|
2000-06-13 09:35:40 +02:00
|
|
|
PG_RETURN_BOOL(val1 <= val2);
|
|
|
|
}
|
1998-07-08 15:57:05 +02:00
|
|
|
|
2000-06-13 09:35:40 +02:00
|
|
|
Datum
|
|
|
|
int48ge(PG_FUNCTION_ARGS)
|
1998-07-08 15:57:05 +02:00
|
|
|
{
|
2000-06-13 09:35:40 +02:00
|
|
|
int32 val1 = PG_GETARG_INT32(0);
|
|
|
|
int64 val2 = PG_GETARG_INT64(1);
|
2000-07-28 07:07:49 +02:00
|
|
|
|
|
|
|
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);
|
1999-08-21 05:06:58 +02:00
|
|
|
|
2000-06-13 09:35:40 +02:00
|
|
|
PG_RETURN_BOOL(val1 >= val2);
|
|
|
|
}
|
1998-07-08 15:57:05 +02:00
|
|
|
|
|
|
|
|
|
|
|
/*----------------------------------------------------------
|
|
|
|
* Arithmetic operators on 64-bit integers.
|
|
|
|
*---------------------------------------------------------*/
|
|
|
|
|
2000-06-13 09:35:40 +02:00
|
|
|
Datum
|
|
|
|
int8um(PG_FUNCTION_ARGS)
|
1998-07-08 15:57:05 +02:00
|
|
|
{
|
2004-10-04 16:42:48 +02:00
|
|
|
int64 arg = PG_GETARG_INT64(0);
|
|
|
|
int64 result;
|
1998-07-08 15:57:05 +02:00
|
|
|
|
2004-10-04 16:42:48 +02:00
|
|
|
result = -arg;
|
|
|
|
/* overflow check (needed for INT64_MIN) */
|
|
|
|
if (arg != 0 && SAMESIGN(result, arg))
|
|
|
|
ereport(ERROR,
|
|
|
|
(errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
|
|
|
|
errmsg("bigint out of range")));
|
|
|
|
PG_RETURN_INT64(result);
|
2000-06-13 09:35:40 +02:00
|
|
|
}
|
1998-07-08 15:57:05 +02:00
|
|
|
|
2001-06-07 02:09:32 +02:00
|
|
|
Datum
|
|
|
|
int8up(PG_FUNCTION_ARGS)
|
|
|
|
{
|
2004-10-04 16:42:48 +02:00
|
|
|
int64 arg = PG_GETARG_INT64(0);
|
2001-06-07 02:09:32 +02:00
|
|
|
|
2004-10-04 16:42:48 +02:00
|
|
|
PG_RETURN_INT64(arg);
|
2001-06-07 02:09:32 +02:00
|
|
|
}
|
|
|
|
|
2000-06-13 09:35:40 +02:00
|
|
|
Datum
|
|
|
|
int8pl(PG_FUNCTION_ARGS)
|
1998-07-08 15:57:05 +02:00
|
|
|
{
|
2004-10-04 16:42:48 +02:00
|
|
|
int64 arg1 = PG_GETARG_INT64(0);
|
|
|
|
int64 arg2 = PG_GETARG_INT64(1);
|
|
|
|
int64 result;
|
1998-07-08 15:57:05 +02:00
|
|
|
|
2004-10-04 16:42:48 +02:00
|
|
|
result = arg1 + arg2;
|
2005-10-15 04:49:52 +02:00
|
|
|
|
2004-10-04 16:42:48 +02:00
|
|
|
/*
|
2005-10-15 04:49:52 +02:00
|
|
|
* Overflow check. If the inputs are of different signs then their sum
|
|
|
|
* cannot overflow. If the inputs are of the same sign, their sum had
|
|
|
|
* better be that sign too.
|
2004-10-04 16:42:48 +02:00
|
|
|
*/
|
|
|
|
if (SAMESIGN(arg1, arg2) && !SAMESIGN(result, arg1))
|
|
|
|
ereport(ERROR,
|
|
|
|
(errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
|
|
|
|
errmsg("bigint out of range")));
|
|
|
|
PG_RETURN_INT64(result);
|
2000-06-13 09:35:40 +02:00
|
|
|
}
|
1998-07-08 15:57:05 +02:00
|
|
|
|
2000-06-13 09:35:40 +02:00
|
|
|
Datum
|
|
|
|
int8mi(PG_FUNCTION_ARGS)
|
1998-07-08 15:57:05 +02:00
|
|
|
{
|
2004-10-04 16:42:48 +02:00
|
|
|
int64 arg1 = PG_GETARG_INT64(0);
|
|
|
|
int64 arg2 = PG_GETARG_INT64(1);
|
|
|
|
int64 result;
|
1998-07-08 15:57:05 +02:00
|
|
|
|
2004-10-04 16:42:48 +02:00
|
|
|
result = arg1 - arg2;
|
2005-10-15 04:49:52 +02:00
|
|
|
|
2004-10-04 16:42:48 +02:00
|
|
|
/*
|
2005-10-15 04:49:52 +02:00
|
|
|
* Overflow check. If the inputs are of the same sign then their
|
|
|
|
* difference cannot overflow. If they are of different signs then the
|
|
|
|
* result should be of the same sign as the first input.
|
2004-10-04 16:42:48 +02:00
|
|
|
*/
|
|
|
|
if (!SAMESIGN(arg1, arg2) && !SAMESIGN(result, arg1))
|
|
|
|
ereport(ERROR,
|
|
|
|
(errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
|
|
|
|
errmsg("bigint out of range")));
|
|
|
|
PG_RETURN_INT64(result);
|
2000-06-13 09:35:40 +02:00
|
|
|
}
|
1998-07-08 15:57:05 +02:00
|
|
|
|
2000-06-13 09:35:40 +02:00
|
|
|
Datum
|
|
|
|
int8mul(PG_FUNCTION_ARGS)
|
1998-07-08 15:57:05 +02:00
|
|
|
{
|
2004-10-04 16:42:48 +02:00
|
|
|
int64 arg1 = PG_GETARG_INT64(0);
|
|
|
|
int64 arg2 = PG_GETARG_INT64(1);
|
|
|
|
int64 result;
|
1998-07-08 15:57:05 +02:00
|
|
|
|
2004-10-04 16:42:48 +02:00
|
|
|
result = arg1 * arg2;
|
2005-10-15 04:49:52 +02:00
|
|
|
|
2004-10-04 16:42:48 +02:00
|
|
|
/*
|
2005-10-15 04:49:52 +02:00
|
|
|
* Overflow check. We basically check to see if result / arg2 gives arg1
|
|
|
|
* again. There are two cases where this fails: arg2 = 0 (which cannot
|
|
|
|
* overflow) and arg1 = INT64_MIN, arg2 = -1 (where the division itself
|
|
|
|
* will overflow and thus incorrectly match).
|
2004-10-04 16:42:48 +02:00
|
|
|
*
|
|
|
|
* Since the division is likely much more expensive than the actual
|
2005-10-15 04:49:52 +02:00
|
|
|
* multiplication, we'd like to skip it where possible. The best bang for
|
|
|
|
* the buck seems to be to check whether both inputs are in the int32
|
|
|
|
* range; if so, no overflow is possible.
|
2004-10-04 16:42:48 +02:00
|
|
|
*/
|
|
|
|
if (!(arg1 == (int64) ((int32) arg1) &&
|
|
|
|
arg2 == (int64) ((int32) arg2)) &&
|
|
|
|
arg2 != 0 &&
|
2005-10-15 04:49:52 +02:00
|
|
|
(result / arg2 != arg1 || (arg2 == -1 && arg1 < 0 && result < 0)))
|
2004-10-04 16:42:48 +02:00
|
|
|
ereport(ERROR,
|
|
|
|
(errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
|
|
|
|
errmsg("bigint out of range")));
|
|
|
|
PG_RETURN_INT64(result);
|
2000-06-13 09:35:40 +02:00
|
|
|
}
|
1998-07-08 15:57:05 +02:00
|
|
|
|
2000-06-13 09:35:40 +02:00
|
|
|
Datum
|
|
|
|
int8div(PG_FUNCTION_ARGS)
|
1998-07-08 15:57:05 +02:00
|
|
|
{
|
2004-10-04 16:42:48 +02:00
|
|
|
int64 arg1 = PG_GETARG_INT64(0);
|
|
|
|
int64 arg2 = PG_GETARG_INT64(1);
|
|
|
|
int64 result;
|
1998-07-08 15:57:05 +02:00
|
|
|
|
2004-10-04 16:42:48 +02:00
|
|
|
if (arg2 == 0)
|
2003-07-27 06:53:12 +02:00
|
|
|
ereport(ERROR,
|
|
|
|
(errcode(ERRCODE_DIVISION_BY_ZERO),
|
|
|
|
errmsg("division by zero")));
|
2003-03-11 22:01:33 +01:00
|
|
|
|
2004-10-04 16:42:48 +02:00
|
|
|
result = arg1 / arg2;
|
2005-10-15 04:49:52 +02:00
|
|
|
|
2004-10-04 16:42:48 +02:00
|
|
|
/*
|
2005-10-15 04:49:52 +02:00
|
|
|
* Overflow check. The only possible overflow case is for arg1 =
|
|
|
|
* INT64_MIN, arg2 = -1, where the correct result is -INT64_MIN, which
|
|
|
|
* can't be represented on a two's-complement machine.
|
2004-10-04 16:42:48 +02:00
|
|
|
*/
|
|
|
|
if (arg2 == -1 && arg1 < 0 && result < 0)
|
|
|
|
ereport(ERROR,
|
|
|
|
(errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
|
|
|
|
errmsg("bigint out of range")));
|
|
|
|
PG_RETURN_INT64(result);
|
2000-06-13 09:35:40 +02:00
|
|
|
}
|
1998-07-08 15:57:05 +02:00
|
|
|
|
2000-03-15 00:06:59 +01:00
|
|
|
/* int8abs()
|
|
|
|
* Absolute value
|
|
|
|
*/
|
2000-06-13 09:35:40 +02:00
|
|
|
Datum
|
|
|
|
int8abs(PG_FUNCTION_ARGS)
|
2000-03-15 00:06:59 +01:00
|
|
|
{
|
2000-06-13 09:35:40 +02:00
|
|
|
int64 arg1 = PG_GETARG_INT64(0);
|
2004-10-04 16:42:48 +02:00
|
|
|
int64 result;
|
2000-03-15 00:06:59 +01:00
|
|
|
|
2004-10-04 16:42:48 +02:00
|
|
|
result = (arg1 < 0) ? -arg1 : arg1;
|
|
|
|
/* overflow check (needed for INT64_MIN) */
|
|
|
|
if (result < 0)
|
|
|
|
ereport(ERROR,
|
|
|
|
(errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
|
|
|
|
errmsg("bigint out of range")));
|
|
|
|
PG_RETURN_INT64(result);
|
2000-03-15 00:06:59 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
/* int8mod()
|
|
|
|
* Modulo operation.
|
|
|
|
*/
|
2000-06-13 09:35:40 +02:00
|
|
|
Datum
|
|
|
|
int8mod(PG_FUNCTION_ARGS)
|
2000-03-15 00:06:59 +01:00
|
|
|
{
|
2004-10-04 16:42:48 +02:00
|
|
|
int64 arg1 = PG_GETARG_INT64(0);
|
|
|
|
int64 arg2 = PG_GETARG_INT64(1);
|
2000-03-15 00:06:59 +01:00
|
|
|
|
2004-10-04 16:42:48 +02:00
|
|
|
if (arg2 == 0)
|
2003-07-27 06:53:12 +02:00
|
|
|
ereport(ERROR,
|
|
|
|
(errcode(ERRCODE_DIVISION_BY_ZERO),
|
|
|
|
errmsg("division by zero")));
|
2004-10-04 16:42:48 +02:00
|
|
|
/* No overflow is possible */
|
2003-03-11 22:01:33 +01:00
|
|
|
|
2004-10-04 16:42:48 +02:00
|
|
|
PG_RETURN_INT64(arg1 % arg2);
|
2000-06-13 09:35:40 +02:00
|
|
|
}
|
2000-03-15 00:06:59 +01:00
|
|
|
|
|
|
|
|
2001-08-15 00:21:59 +02:00
|
|
|
Datum
|
|
|
|
int8inc(PG_FUNCTION_ARGS)
|
|
|
|
{
|
2005-03-12 21:25:06 +01:00
|
|
|
if (fcinfo->context && IsA(fcinfo->context, AggState))
|
|
|
|
{
|
|
|
|
/*
|
2005-10-15 04:49:52 +02:00
|
|
|
* Special case to avoid palloc overhead for COUNT(): when called from
|
|
|
|
* nodeAgg, we know that the argument is modifiable local storage, so
|
|
|
|
* just update it in-place.
|
2005-03-12 21:25:06 +01:00
|
|
|
*
|
|
|
|
* Note: this assumes int8 is a pass-by-ref type; if we ever support
|
|
|
|
* pass-by-val int8, this should be ifdef'd out when int8 is
|
|
|
|
* pass-by-val.
|
|
|
|
*/
|
|
|
|
int64 *arg = (int64 *) PG_GETARG_POINTER(0);
|
|
|
|
int64 result;
|
2001-08-15 00:21:59 +02:00
|
|
|
|
2005-03-12 21:25:06 +01:00
|
|
|
result = *arg + 1;
|
|
|
|
/* Overflow check */
|
|
|
|
if (result < 0 && *arg > 0)
|
|
|
|
ereport(ERROR,
|
|
|
|
(errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
|
|
|
|
errmsg("bigint out of range")));
|
2004-10-04 16:42:48 +02:00
|
|
|
|
2005-03-12 21:25:06 +01:00
|
|
|
*arg = result;
|
|
|
|
PG_RETURN_POINTER(arg);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
/* Not called by nodeAgg, so just do it the dumb way */
|
|
|
|
int64 arg = PG_GETARG_INT64(0);
|
|
|
|
int64 result;
|
|
|
|
|
|
|
|
result = arg + 1;
|
|
|
|
/* Overflow check */
|
|
|
|
if (result < 0 && arg > 0)
|
|
|
|
ereport(ERROR,
|
|
|
|
(errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
|
|
|
|
errmsg("bigint out of range")));
|
|
|
|
|
|
|
|
PG_RETURN_INT64(result);
|
|
|
|
}
|
2001-08-15 00:21:59 +02:00
|
|
|
}
|
|
|
|
|
2006-07-28 20:33:04 +02:00
|
|
|
/*
|
|
|
|
* These functions are exactly like int8inc but are used for aggregates that
|
2006-10-04 02:30:14 +02:00
|
|
|
* count only non-null values. Since the functions are declared strict,
|
2006-07-28 20:33:04 +02:00
|
|
|
* 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, 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);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2000-06-13 09:35:40 +02:00
|
|
|
Datum
|
|
|
|
int8larger(PG_FUNCTION_ARGS)
|
1998-07-08 15:57:05 +02:00
|
|
|
{
|
2004-10-04 16:42:48 +02:00
|
|
|
int64 arg1 = PG_GETARG_INT64(0);
|
|
|
|
int64 arg2 = PG_GETARG_INT64(1);
|
2000-06-13 09:35:40 +02:00
|
|
|
int64 result;
|
1998-07-08 15:57:05 +02:00
|
|
|
|
2004-10-04 16:42:48 +02:00
|
|
|
result = ((arg1 > arg2) ? arg1 : arg2);
|
1998-07-08 15:57:05 +02:00
|
|
|
|
2000-06-13 09:35:40 +02:00
|
|
|
PG_RETURN_INT64(result);
|
|
|
|
}
|
1998-07-08 15:57:05 +02:00
|
|
|
|
2000-06-13 09:35:40 +02:00
|
|
|
Datum
|
|
|
|
int8smaller(PG_FUNCTION_ARGS)
|
1998-07-08 15:57:05 +02:00
|
|
|
{
|
2004-10-04 16:42:48 +02:00
|
|
|
int64 arg1 = PG_GETARG_INT64(0);
|
|
|
|
int64 arg2 = PG_GETARG_INT64(1);
|
2000-06-13 09:35:40 +02:00
|
|
|
int64 result;
|
1998-09-01 06:40:42 +02:00
|
|
|
|
2004-10-04 16:42:48 +02:00
|
|
|
result = ((arg1 < arg2) ? arg1 : arg2);
|
1998-07-08 15:57:05 +02:00
|
|
|
|
2000-06-13 09:35:40 +02:00
|
|
|
PG_RETURN_INT64(result);
|
|
|
|
}
|
1998-07-08 15:57:05 +02:00
|
|
|
|
2000-06-13 09:35:40 +02:00
|
|
|
Datum
|
|
|
|
int84pl(PG_FUNCTION_ARGS)
|
1998-07-08 15:57:05 +02:00
|
|
|
{
|
2004-10-04 16:42:48 +02:00
|
|
|
int64 arg1 = PG_GETARG_INT64(0);
|
|
|
|
int32 arg2 = PG_GETARG_INT32(1);
|
|
|
|
int64 result;
|
1998-07-08 15:57:05 +02:00
|
|
|
|
2004-10-04 16:42:48 +02:00
|
|
|
result = arg1 + arg2;
|
2005-10-15 04:49:52 +02:00
|
|
|
|
2004-10-04 16:42:48 +02:00
|
|
|
/*
|
2005-10-15 04:49:52 +02:00
|
|
|
* Overflow check. If the inputs are of different signs then their sum
|
|
|
|
* cannot overflow. If the inputs are of the same sign, their sum had
|
|
|
|
* better be that sign too.
|
2004-10-04 16:42:48 +02:00
|
|
|
*/
|
|
|
|
if (SAMESIGN(arg1, arg2) && !SAMESIGN(result, arg1))
|
|
|
|
ereport(ERROR,
|
|
|
|
(errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
|
|
|
|
errmsg("bigint out of range")));
|
|
|
|
PG_RETURN_INT64(result);
|
2000-06-13 09:35:40 +02:00
|
|
|
}
|
1998-07-08 15:57:05 +02:00
|
|
|
|
2000-06-13 09:35:40 +02:00
|
|
|
Datum
|
|
|
|
int84mi(PG_FUNCTION_ARGS)
|
1998-07-08 15:57:05 +02:00
|
|
|
{
|
2004-10-04 16:42:48 +02:00
|
|
|
int64 arg1 = PG_GETARG_INT64(0);
|
|
|
|
int32 arg2 = PG_GETARG_INT32(1);
|
|
|
|
int64 result;
|
1998-07-08 15:57:05 +02:00
|
|
|
|
2004-10-04 16:42:48 +02:00
|
|
|
result = arg1 - arg2;
|
2005-10-15 04:49:52 +02:00
|
|
|
|
2004-10-04 16:42:48 +02:00
|
|
|
/*
|
2005-10-15 04:49:52 +02:00
|
|
|
* Overflow check. If the inputs are of the same sign then their
|
|
|
|
* difference cannot overflow. If they are of different signs then the
|
|
|
|
* result should be of the same sign as the first input.
|
2004-10-04 16:42:48 +02:00
|
|
|
*/
|
|
|
|
if (!SAMESIGN(arg1, arg2) && !SAMESIGN(result, arg1))
|
|
|
|
ereport(ERROR,
|
|
|
|
(errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
|
|
|
|
errmsg("bigint out of range")));
|
|
|
|
PG_RETURN_INT64(result);
|
2000-06-13 09:35:40 +02:00
|
|
|
}
|
1998-07-08 15:57:05 +02:00
|
|
|
|
2000-06-13 09:35:40 +02:00
|
|
|
Datum
|
|
|
|
int84mul(PG_FUNCTION_ARGS)
|
1998-07-08 15:57:05 +02:00
|
|
|
{
|
2004-10-04 16:42:48 +02:00
|
|
|
int64 arg1 = PG_GETARG_INT64(0);
|
|
|
|
int32 arg2 = PG_GETARG_INT32(1);
|
|
|
|
int64 result;
|
1998-07-08 15:57:05 +02:00
|
|
|
|
2004-10-04 16:42:48 +02:00
|
|
|
result = arg1 * arg2;
|
2005-10-15 04:49:52 +02:00
|
|
|
|
2004-10-04 16:42:48 +02:00
|
|
|
/*
|
2005-10-15 04:49:52 +02:00
|
|
|
* Overflow check. We basically check to see if result / arg1 gives arg2
|
|
|
|
* again. There is one case where this fails: arg1 = 0 (which cannot
|
|
|
|
* overflow).
|
2004-10-04 16:42:48 +02:00
|
|
|
*
|
|
|
|
* Since the division is likely much more expensive than the actual
|
2005-10-15 04:49:52 +02:00
|
|
|
* multiplication, we'd like to skip it where possible. The best bang for
|
|
|
|
* the buck seems to be to check whether both inputs are in the int32
|
|
|
|
* range; if so, no overflow is possible.
|
2004-10-04 16:42:48 +02:00
|
|
|
*/
|
|
|
|
if (arg1 != (int64) ((int32) arg1) &&
|
2005-10-15 04:49:52 +02:00
|
|
|
result / arg1 != arg2)
|
2004-10-04 16:42:48 +02:00
|
|
|
ereport(ERROR,
|
|
|
|
(errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
|
|
|
|
errmsg("bigint out of range")));
|
|
|
|
PG_RETURN_INT64(result);
|
2000-06-13 09:35:40 +02:00
|
|
|
}
|
1998-07-08 15:57:05 +02:00
|
|
|
|
2000-06-13 09:35:40 +02:00
|
|
|
Datum
|
|
|
|
int84div(PG_FUNCTION_ARGS)
|
1998-07-08 15:57:05 +02:00
|
|
|
{
|
2004-10-04 16:42:48 +02:00
|
|
|
int64 arg1 = PG_GETARG_INT64(0);
|
|
|
|
int32 arg2 = PG_GETARG_INT32(1);
|
|
|
|
int64 result;
|
1998-07-08 15:57:05 +02:00
|
|
|
|
2004-10-04 16:42:48 +02:00
|
|
|
if (arg2 == 0)
|
2003-07-27 06:53:12 +02:00
|
|
|
ereport(ERROR,
|
|
|
|
(errcode(ERRCODE_DIVISION_BY_ZERO),
|
|
|
|
errmsg("division by zero")));
|
2003-03-11 22:01:33 +01:00
|
|
|
|
2004-10-04 16:42:48 +02:00
|
|
|
result = arg1 / arg2;
|
2005-10-15 04:49:52 +02:00
|
|
|
|
2004-10-04 16:42:48 +02:00
|
|
|
/*
|
2005-10-15 04:49:52 +02:00
|
|
|
* Overflow check. The only possible overflow case is for arg1 =
|
|
|
|
* INT64_MIN, arg2 = -1, where the correct result is -INT64_MIN, which
|
|
|
|
* can't be represented on a two's-complement machine.
|
2004-10-04 16:42:48 +02:00
|
|
|
*/
|
|
|
|
if (arg2 == -1 && arg1 < 0 && result < 0)
|
|
|
|
ereport(ERROR,
|
|
|
|
(errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
|
|
|
|
errmsg("bigint out of range")));
|
|
|
|
PG_RETURN_INT64(result);
|
2000-06-13 09:35:40 +02:00
|
|
|
}
|
1998-07-08 15:57:05 +02:00
|
|
|
|
2000-06-13 09:35:40 +02:00
|
|
|
Datum
|
|
|
|
int48pl(PG_FUNCTION_ARGS)
|
1998-07-08 15:57:05 +02:00
|
|
|
{
|
2004-10-04 16:42:48 +02:00
|
|
|
int32 arg1 = PG_GETARG_INT32(0);
|
|
|
|
int64 arg2 = PG_GETARG_INT64(1);
|
|
|
|
int64 result;
|
1998-07-08 15:57:05 +02:00
|
|
|
|
2004-10-04 16:42:48 +02:00
|
|
|
result = arg1 + arg2;
|
2005-10-15 04:49:52 +02:00
|
|
|
|
2004-10-04 16:42:48 +02:00
|
|
|
/*
|
2005-10-15 04:49:52 +02:00
|
|
|
* Overflow check. If the inputs are of different signs then their sum
|
|
|
|
* cannot overflow. If the inputs are of the same sign, their sum had
|
|
|
|
* better be that sign too.
|
2004-10-04 16:42:48 +02:00
|
|
|
*/
|
|
|
|
if (SAMESIGN(arg1, arg2) && !SAMESIGN(result, arg1))
|
|
|
|
ereport(ERROR,
|
|
|
|
(errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
|
|
|
|
errmsg("bigint out of range")));
|
|
|
|
PG_RETURN_INT64(result);
|
2000-06-13 09:35:40 +02:00
|
|
|
}
|
1998-07-08 15:57:05 +02:00
|
|
|
|
2000-06-13 09:35:40 +02:00
|
|
|
Datum
|
|
|
|
int48mi(PG_FUNCTION_ARGS)
|
1998-07-08 15:57:05 +02:00
|
|
|
{
|
2004-10-04 16:42:48 +02:00
|
|
|
int32 arg1 = PG_GETARG_INT32(0);
|
|
|
|
int64 arg2 = PG_GETARG_INT64(1);
|
|
|
|
int64 result;
|
1998-07-08 15:57:05 +02:00
|
|
|
|
2004-10-04 16:42:48 +02:00
|
|
|
result = arg1 - arg2;
|
2005-10-15 04:49:52 +02:00
|
|
|
|
2004-10-04 16:42:48 +02:00
|
|
|
/*
|
2005-10-15 04:49:52 +02:00
|
|
|
* Overflow check. If the inputs are of the same sign then their
|
|
|
|
* difference cannot overflow. If they are of different signs then the
|
|
|
|
* result should be of the same sign as the first input.
|
2004-10-04 16:42:48 +02:00
|
|
|
*/
|
|
|
|
if (!SAMESIGN(arg1, arg2) && !SAMESIGN(result, arg1))
|
|
|
|
ereport(ERROR,
|
|
|
|
(errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
|
|
|
|
errmsg("bigint out of range")));
|
|
|
|
PG_RETURN_INT64(result);
|
2000-06-13 09:35:40 +02:00
|
|
|
}
|
1998-07-08 15:57:05 +02:00
|
|
|
|
2000-06-13 09:35:40 +02:00
|
|
|
Datum
|
|
|
|
int48mul(PG_FUNCTION_ARGS)
|
1998-07-08 15:57:05 +02:00
|
|
|
{
|
2004-10-04 16:42:48 +02:00
|
|
|
int32 arg1 = PG_GETARG_INT32(0);
|
|
|
|
int64 arg2 = PG_GETARG_INT64(1);
|
|
|
|
int64 result;
|
1998-07-08 15:57:05 +02:00
|
|
|
|
2004-10-04 16:42:48 +02:00
|
|
|
result = arg1 * arg2;
|
2005-10-15 04:49:52 +02:00
|
|
|
|
2004-10-04 16:42:48 +02:00
|
|
|
/*
|
2005-10-15 04:49:52 +02:00
|
|
|
* Overflow check. We basically check to see if result / arg2 gives arg1
|
|
|
|
* again. There is one case where this fails: arg2 = 0 (which cannot
|
|
|
|
* overflow).
|
2004-10-04 16:42:48 +02:00
|
|
|
*
|
|
|
|
* Since the division is likely much more expensive than the actual
|
2005-10-15 04:49:52 +02:00
|
|
|
* multiplication, we'd like to skip it where possible. The best bang for
|
|
|
|
* the buck seems to be to check whether both inputs are in the int32
|
|
|
|
* range; if so, no overflow is possible.
|
2004-10-04 16:42:48 +02:00
|
|
|
*/
|
|
|
|
if (arg2 != (int64) ((int32) arg2) &&
|
2005-10-15 04:49:52 +02:00
|
|
|
result / arg2 != arg1)
|
2004-10-04 16:42:48 +02:00
|
|
|
ereport(ERROR,
|
|
|
|
(errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
|
|
|
|
errmsg("bigint out of range")));
|
|
|
|
PG_RETURN_INT64(result);
|
2000-06-13 09:35:40 +02:00
|
|
|
}
|
1998-07-08 15:57:05 +02:00
|
|
|
|
2000-06-13 09:35:40 +02:00
|
|
|
Datum
|
|
|
|
int48div(PG_FUNCTION_ARGS)
|
1998-07-08 15:57:05 +02:00
|
|
|
{
|
2004-10-04 16:42:48 +02:00
|
|
|
int32 arg1 = PG_GETARG_INT32(0);
|
|
|
|
int64 arg2 = PG_GETARG_INT64(1);
|
1998-07-08 15:57:05 +02:00
|
|
|
|
2004-10-04 16:42:48 +02:00
|
|
|
if (arg2 == 0)
|
2003-07-27 06:53:12 +02:00
|
|
|
ereport(ERROR,
|
|
|
|
(errcode(ERRCODE_DIVISION_BY_ZERO),
|
|
|
|
errmsg("division by zero")));
|
2004-10-04 16:42:48 +02:00
|
|
|
/* No overflow is possible */
|
|
|
|
PG_RETURN_INT64((int64) arg1 / arg2);
|
2000-06-13 09:35:40 +02:00
|
|
|
}
|
1998-07-08 15:57:05 +02:00
|
|
|
|
2000-10-24 22:16:48 +02:00
|
|
|
/* 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);
|
|
|
|
}
|
1998-07-08 15:57:05 +02:00
|
|
|
|
|
|
|
/*----------------------------------------------------------
|
|
|
|
* Conversion operators.
|
|
|
|
*---------------------------------------------------------*/
|
|
|
|
|
2000-06-13 09:35:40 +02:00
|
|
|
Datum
|
|
|
|
int48(PG_FUNCTION_ARGS)
|
1998-07-08 15:57:05 +02:00
|
|
|
{
|
2004-10-04 16:42:48 +02:00
|
|
|
int32 arg = PG_GETARG_INT32(0);
|
1998-07-08 15:57:05 +02:00
|
|
|
|
2004-10-04 16:42:48 +02:00
|
|
|
PG_RETURN_INT64((int64) arg);
|
2000-06-13 09:35:40 +02:00
|
|
|
}
|
1998-07-08 15:57:05 +02:00
|
|
|
|
2000-06-13 09:35:40 +02:00
|
|
|
Datum
|
|
|
|
int84(PG_FUNCTION_ARGS)
|
1998-07-08 15:57:05 +02:00
|
|
|
{
|
2004-10-04 16:42:48 +02:00
|
|
|
int64 arg = PG_GETARG_INT64(0);
|
1998-07-08 15:57:05 +02:00
|
|
|
int32 result;
|
|
|
|
|
2004-10-04 16:42:48 +02:00
|
|
|
result = (int32) arg;
|
1998-07-08 15:57:05 +02:00
|
|
|
|
2001-09-07 03:33:44 +02:00
|
|
|
/* Test for overflow by reverse-conversion. */
|
2004-10-04 16:42:48 +02:00
|
|
|
if ((int64) result != arg)
|
2003-07-27 06:53:12 +02:00
|
|
|
ereport(ERROR,
|
|
|
|
(errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
|
|
|
|
errmsg("integer out of range")));
|
2001-09-07 03:33:44 +02:00
|
|
|
|
2000-06-13 09:35:40 +02:00
|
|
|
PG_RETURN_INT32(result);
|
|
|
|
}
|
1998-07-08 15:57:05 +02:00
|
|
|
|
2001-10-25 16:10:07 +02:00
|
|
|
Datum
|
|
|
|
int28(PG_FUNCTION_ARGS)
|
|
|
|
{
|
2004-10-04 16:42:48 +02:00
|
|
|
int16 arg = PG_GETARG_INT16(0);
|
2001-10-25 16:10:07 +02:00
|
|
|
|
2004-10-04 16:42:48 +02:00
|
|
|
PG_RETURN_INT64((int64) arg);
|
2001-10-25 16:10:07 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
Datum
|
|
|
|
int82(PG_FUNCTION_ARGS)
|
|
|
|
{
|
2004-10-04 16:42:48 +02:00
|
|
|
int64 arg = PG_GETARG_INT64(0);
|
2001-10-25 16:10:07 +02:00
|
|
|
int16 result;
|
|
|
|
|
2004-10-04 16:42:48 +02:00
|
|
|
result = (int16) arg;
|
2001-10-25 16:10:07 +02:00
|
|
|
|
|
|
|
/* Test for overflow by reverse-conversion. */
|
2004-10-04 16:42:48 +02:00
|
|
|
if ((int64) result != arg)
|
2003-07-27 06:53:12 +02:00
|
|
|
ereport(ERROR,
|
|
|
|
(errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
|
2004-10-04 16:42:48 +02:00
|
|
|
errmsg("smallint out of range")));
|
2001-10-25 16:10:07 +02:00
|
|
|
|
|
|
|
PG_RETURN_INT16(result);
|
|
|
|
}
|
|
|
|
|
2000-06-13 09:35:40 +02:00
|
|
|
Datum
|
|
|
|
i8tod(PG_FUNCTION_ARGS)
|
1998-07-08 15:57:05 +02:00
|
|
|
{
|
2004-10-04 16:42:48 +02:00
|
|
|
int64 arg = PG_GETARG_INT64(0);
|
2000-06-13 09:35:40 +02:00
|
|
|
float8 result;
|
1999-08-21 05:06:58 +02:00
|
|
|
|
2004-10-04 16:42:48 +02:00
|
|
|
result = arg;
|
1998-07-08 15:57:05 +02:00
|
|
|
|
2000-06-13 09:35:40 +02:00
|
|
|
PG_RETURN_FLOAT8(result);
|
|
|
|
}
|
1998-07-08 15:57:05 +02:00
|
|
|
|
|
|
|
/* dtoi8()
|
Extend pg_cast castimplicit column to a three-way value; this allows us
to be flexible about assignment casts without introducing ambiguity in
operator/function resolution. Introduce a well-defined promotion hierarchy
for numeric datatypes (int2->int4->int8->numeric->float4->float8).
Change make_const to initially label numeric literals as int4, int8, or
numeric (never float8 anymore).
Explicitly mark Func and RelabelType nodes to indicate whether they came
from a function call, explicit cast, or implicit cast; use this to do
reverse-listing more accurately and without so many heuristics.
Explicit casts to char, varchar, bit, varbit will truncate or pad without
raising an error (the pre-7.2 behavior), while assigning to a column without
any explicit cast will still raise an error for wrong-length data like 7.3.
This more nearly follows the SQL spec than 7.2 behavior (we should be
reporting a 'completion condition' in the explicit-cast cases, but we have
no mechanism for that, so just do silent truncation).
Fix some problems with enforcement of typmod for array elements;
it didn't work at all in 'UPDATE ... SET array[n] = foo', for example.
Provide a generalized array_length_coerce() function to replace the
specialized per-array-type functions that used to be needed (and were
missing for NUMERIC as well as all the datetime types).
Add missing conversions int8<->float4, text<->numeric, oid<->int8.
initdb forced.
2002-09-18 23:35:25 +02:00
|
|
|
* Convert float8 to 8-byte integer.
|
1998-07-08 15:57:05 +02:00
|
|
|
*/
|
2000-06-13 09:35:40 +02:00
|
|
|
Datum
|
|
|
|
dtoi8(PG_FUNCTION_ARGS)
|
1998-07-08 15:57:05 +02:00
|
|
|
{
|
2004-10-04 16:42:48 +02:00
|
|
|
float8 arg = PG_GETARG_FLOAT8(0);
|
2000-06-13 09:35:40 +02:00
|
|
|
int64 result;
|
1998-07-08 15:57:05 +02:00
|
|
|
|
2004-10-04 16:42:48 +02:00
|
|
|
/* Round arg to nearest integer (but it's still in float form) */
|
|
|
|
arg = rint(arg);
|
2001-03-22 05:01:46 +01:00
|
|
|
|
2001-01-26 23:50:26 +01:00
|
|
|
/*
|
2005-10-15 04:49:52 +02:00
|
|
|
* Does it fit in an int64? Avoid assuming that we have handy constants
|
|
|
|
* defined for the range boundaries, instead test for overflow by
|
|
|
|
* reverse-conversion.
|
2001-01-26 23:50:26 +01:00
|
|
|
*/
|
2004-10-04 16:42:48 +02:00
|
|
|
result = (int64) arg;
|
1998-07-08 15:57:05 +02:00
|
|
|
|
2004-10-04 16:42:48 +02:00
|
|
|
if ((float8) result != arg)
|
2003-07-27 06:53:12 +02:00
|
|
|
ereport(ERROR,
|
|
|
|
(errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
|
2004-10-04 16:42:48 +02:00
|
|
|
errmsg("bigint out of range")));
|
2001-01-26 23:50:26 +01:00
|
|
|
|
2000-06-13 09:35:40 +02:00
|
|
|
PG_RETURN_INT64(result);
|
|
|
|
}
|
1999-02-13 05:22:34 +01:00
|
|
|
|
Extend pg_cast castimplicit column to a three-way value; this allows us
to be flexible about assignment casts without introducing ambiguity in
operator/function resolution. Introduce a well-defined promotion hierarchy
for numeric datatypes (int2->int4->int8->numeric->float4->float8).
Change make_const to initially label numeric literals as int4, int8, or
numeric (never float8 anymore).
Explicitly mark Func and RelabelType nodes to indicate whether they came
from a function call, explicit cast, or implicit cast; use this to do
reverse-listing more accurately and without so many heuristics.
Explicit casts to char, varchar, bit, varbit will truncate or pad without
raising an error (the pre-7.2 behavior), while assigning to a column without
any explicit cast will still raise an error for wrong-length data like 7.3.
This more nearly follows the SQL spec than 7.2 behavior (we should be
reporting a 'completion condition' in the explicit-cast cases, but we have
no mechanism for that, so just do silent truncation).
Fix some problems with enforcement of typmod for array elements;
it didn't work at all in 'UPDATE ... SET array[n] = foo', for example.
Provide a generalized array_length_coerce() function to replace the
specialized per-array-type functions that used to be needed (and were
missing for NUMERIC as well as all the datetime types).
Add missing conversions int8<->float4, text<->numeric, oid<->int8.
initdb forced.
2002-09-18 23:35:25 +02:00
|
|
|
Datum
|
|
|
|
i8tof(PG_FUNCTION_ARGS)
|
|
|
|
{
|
2004-10-04 16:42:48 +02:00
|
|
|
int64 arg = PG_GETARG_INT64(0);
|
Extend pg_cast castimplicit column to a three-way value; this allows us
to be flexible about assignment casts without introducing ambiguity in
operator/function resolution. Introduce a well-defined promotion hierarchy
for numeric datatypes (int2->int4->int8->numeric->float4->float8).
Change make_const to initially label numeric literals as int4, int8, or
numeric (never float8 anymore).
Explicitly mark Func and RelabelType nodes to indicate whether they came
from a function call, explicit cast, or implicit cast; use this to do
reverse-listing more accurately and without so many heuristics.
Explicit casts to char, varchar, bit, varbit will truncate or pad without
raising an error (the pre-7.2 behavior), while assigning to a column without
any explicit cast will still raise an error for wrong-length data like 7.3.
This more nearly follows the SQL spec than 7.2 behavior (we should be
reporting a 'completion condition' in the explicit-cast cases, but we have
no mechanism for that, so just do silent truncation).
Fix some problems with enforcement of typmod for array elements;
it didn't work at all in 'UPDATE ... SET array[n] = foo', for example.
Provide a generalized array_length_coerce() function to replace the
specialized per-array-type functions that used to be needed (and were
missing for NUMERIC as well as all the datetime types).
Add missing conversions int8<->float4, text<->numeric, oid<->int8.
initdb forced.
2002-09-18 23:35:25 +02:00
|
|
|
float4 result;
|
|
|
|
|
2004-10-04 16:42:48 +02:00
|
|
|
result = arg;
|
Extend pg_cast castimplicit column to a three-way value; this allows us
to be flexible about assignment casts without introducing ambiguity in
operator/function resolution. Introduce a well-defined promotion hierarchy
for numeric datatypes (int2->int4->int8->numeric->float4->float8).
Change make_const to initially label numeric literals as int4, int8, or
numeric (never float8 anymore).
Explicitly mark Func and RelabelType nodes to indicate whether they came
from a function call, explicit cast, or implicit cast; use this to do
reverse-listing more accurately and without so many heuristics.
Explicit casts to char, varchar, bit, varbit will truncate or pad without
raising an error (the pre-7.2 behavior), while assigning to a column without
any explicit cast will still raise an error for wrong-length data like 7.3.
This more nearly follows the SQL spec than 7.2 behavior (we should be
reporting a 'completion condition' in the explicit-cast cases, but we have
no mechanism for that, so just do silent truncation).
Fix some problems with enforcement of typmod for array elements;
it didn't work at all in 'UPDATE ... SET array[n] = foo', for example.
Provide a generalized array_length_coerce() function to replace the
specialized per-array-type functions that used to be needed (and were
missing for NUMERIC as well as all the datetime types).
Add missing conversions int8<->float4, text<->numeric, oid<->int8.
initdb forced.
2002-09-18 23:35:25 +02:00
|
|
|
|
|
|
|
PG_RETURN_FLOAT4(result);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* ftoi8()
|
|
|
|
* Convert float4 to 8-byte integer.
|
1999-02-13 05:22:34 +01:00
|
|
|
*/
|
Extend pg_cast castimplicit column to a three-way value; this allows us
to be flexible about assignment casts without introducing ambiguity in
operator/function resolution. Introduce a well-defined promotion hierarchy
for numeric datatypes (int2->int4->int8->numeric->float4->float8).
Change make_const to initially label numeric literals as int4, int8, or
numeric (never float8 anymore).
Explicitly mark Func and RelabelType nodes to indicate whether they came
from a function call, explicit cast, or implicit cast; use this to do
reverse-listing more accurately and without so many heuristics.
Explicit casts to char, varchar, bit, varbit will truncate or pad without
raising an error (the pre-7.2 behavior), while assigning to a column without
any explicit cast will still raise an error for wrong-length data like 7.3.
This more nearly follows the SQL spec than 7.2 behavior (we should be
reporting a 'completion condition' in the explicit-cast cases, but we have
no mechanism for that, so just do silent truncation).
Fix some problems with enforcement of typmod for array elements;
it didn't work at all in 'UPDATE ... SET array[n] = foo', for example.
Provide a generalized array_length_coerce() function to replace the
specialized per-array-type functions that used to be needed (and were
missing for NUMERIC as well as all the datetime types).
Add missing conversions int8<->float4, text<->numeric, oid<->int8.
initdb forced.
2002-09-18 23:35:25 +02:00
|
|
|
Datum
|
|
|
|
ftoi8(PG_FUNCTION_ARGS)
|
|
|
|
{
|
2004-10-04 16:42:48 +02:00
|
|
|
float4 arg = PG_GETARG_FLOAT4(0);
|
Extend pg_cast castimplicit column to a three-way value; this allows us
to be flexible about assignment casts without introducing ambiguity in
operator/function resolution. Introduce a well-defined promotion hierarchy
for numeric datatypes (int2->int4->int8->numeric->float4->float8).
Change make_const to initially label numeric literals as int4, int8, or
numeric (never float8 anymore).
Explicitly mark Func and RelabelType nodes to indicate whether they came
from a function call, explicit cast, or implicit cast; use this to do
reverse-listing more accurately and without so many heuristics.
Explicit casts to char, varchar, bit, varbit will truncate or pad without
raising an error (the pre-7.2 behavior), while assigning to a column without
any explicit cast will still raise an error for wrong-length data like 7.3.
This more nearly follows the SQL spec than 7.2 behavior (we should be
reporting a 'completion condition' in the explicit-cast cases, but we have
no mechanism for that, so just do silent truncation).
Fix some problems with enforcement of typmod for array elements;
it didn't work at all in 'UPDATE ... SET array[n] = foo', for example.
Provide a generalized array_length_coerce() function to replace the
specialized per-array-type functions that used to be needed (and were
missing for NUMERIC as well as all the datetime types).
Add missing conversions int8<->float4, text<->numeric, oid<->int8.
initdb forced.
2002-09-18 23:35:25 +02:00
|
|
|
int64 result;
|
2004-10-04 16:42:48 +02:00
|
|
|
float8 darg;
|
Extend pg_cast castimplicit column to a three-way value; this allows us
to be flexible about assignment casts without introducing ambiguity in
operator/function resolution. Introduce a well-defined promotion hierarchy
for numeric datatypes (int2->int4->int8->numeric->float4->float8).
Change make_const to initially label numeric literals as int4, int8, or
numeric (never float8 anymore).
Explicitly mark Func and RelabelType nodes to indicate whether they came
from a function call, explicit cast, or implicit cast; use this to do
reverse-listing more accurately and without so many heuristics.
Explicit casts to char, varchar, bit, varbit will truncate or pad without
raising an error (the pre-7.2 behavior), while assigning to a column without
any explicit cast will still raise an error for wrong-length data like 7.3.
This more nearly follows the SQL spec than 7.2 behavior (we should be
reporting a 'completion condition' in the explicit-cast cases, but we have
no mechanism for that, so just do silent truncation).
Fix some problems with enforcement of typmod for array elements;
it didn't work at all in 'UPDATE ... SET array[n] = foo', for example.
Provide a generalized array_length_coerce() function to replace the
specialized per-array-type functions that used to be needed (and were
missing for NUMERIC as well as all the datetime types).
Add missing conversions int8<->float4, text<->numeric, oid<->int8.
initdb forced.
2002-09-18 23:35:25 +02:00
|
|
|
|
2004-10-04 16:42:48 +02:00
|
|
|
/* Round arg to nearest integer (but it's still in float form) */
|
|
|
|
darg = rint(arg);
|
Extend pg_cast castimplicit column to a three-way value; this allows us
to be flexible about assignment casts without introducing ambiguity in
operator/function resolution. Introduce a well-defined promotion hierarchy
for numeric datatypes (int2->int4->int8->numeric->float4->float8).
Change make_const to initially label numeric literals as int4, int8, or
numeric (never float8 anymore).
Explicitly mark Func and RelabelType nodes to indicate whether they came
from a function call, explicit cast, or implicit cast; use this to do
reverse-listing more accurately and without so many heuristics.
Explicit casts to char, varchar, bit, varbit will truncate or pad without
raising an error (the pre-7.2 behavior), while assigning to a column without
any explicit cast will still raise an error for wrong-length data like 7.3.
This more nearly follows the SQL spec than 7.2 behavior (we should be
reporting a 'completion condition' in the explicit-cast cases, but we have
no mechanism for that, so just do silent truncation).
Fix some problems with enforcement of typmod for array elements;
it didn't work at all in 'UPDATE ... SET array[n] = foo', for example.
Provide a generalized array_length_coerce() function to replace the
specialized per-array-type functions that used to be needed (and were
missing for NUMERIC as well as all the datetime types).
Add missing conversions int8<->float4, text<->numeric, oid<->int8.
initdb forced.
2002-09-18 23:35:25 +02:00
|
|
|
|
|
|
|
/*
|
2005-10-15 04:49:52 +02:00
|
|
|
* Does it fit in an int64? Avoid assuming that we have handy constants
|
|
|
|
* defined for the range boundaries, instead test for overflow by
|
|
|
|
* reverse-conversion.
|
Extend pg_cast castimplicit column to a three-way value; this allows us
to be flexible about assignment casts without introducing ambiguity in
operator/function resolution. Introduce a well-defined promotion hierarchy
for numeric datatypes (int2->int4->int8->numeric->float4->float8).
Change make_const to initially label numeric literals as int4, int8, or
numeric (never float8 anymore).
Explicitly mark Func and RelabelType nodes to indicate whether they came
from a function call, explicit cast, or implicit cast; use this to do
reverse-listing more accurately and without so many heuristics.
Explicit casts to char, varchar, bit, varbit will truncate or pad without
raising an error (the pre-7.2 behavior), while assigning to a column without
any explicit cast will still raise an error for wrong-length data like 7.3.
This more nearly follows the SQL spec than 7.2 behavior (we should be
reporting a 'completion condition' in the explicit-cast cases, but we have
no mechanism for that, so just do silent truncation).
Fix some problems with enforcement of typmod for array elements;
it didn't work at all in 'UPDATE ... SET array[n] = foo', for example.
Provide a generalized array_length_coerce() function to replace the
specialized per-array-type functions that used to be needed (and were
missing for NUMERIC as well as all the datetime types).
Add missing conversions int8<->float4, text<->numeric, oid<->int8.
initdb forced.
2002-09-18 23:35:25 +02:00
|
|
|
*/
|
2004-10-04 16:42:48 +02:00
|
|
|
result = (int64) darg;
|
Extend pg_cast castimplicit column to a three-way value; this allows us
to be flexible about assignment casts without introducing ambiguity in
operator/function resolution. Introduce a well-defined promotion hierarchy
for numeric datatypes (int2->int4->int8->numeric->float4->float8).
Change make_const to initially label numeric literals as int4, int8, or
numeric (never float8 anymore).
Explicitly mark Func and RelabelType nodes to indicate whether they came
from a function call, explicit cast, or implicit cast; use this to do
reverse-listing more accurately and without so many heuristics.
Explicit casts to char, varchar, bit, varbit will truncate or pad without
raising an error (the pre-7.2 behavior), while assigning to a column without
any explicit cast will still raise an error for wrong-length data like 7.3.
This more nearly follows the SQL spec than 7.2 behavior (we should be
reporting a 'completion condition' in the explicit-cast cases, but we have
no mechanism for that, so just do silent truncation).
Fix some problems with enforcement of typmod for array elements;
it didn't work at all in 'UPDATE ... SET array[n] = foo', for example.
Provide a generalized array_length_coerce() function to replace the
specialized per-array-type functions that used to be needed (and were
missing for NUMERIC as well as all the datetime types).
Add missing conversions int8<->float4, text<->numeric, oid<->int8.
initdb forced.
2002-09-18 23:35:25 +02:00
|
|
|
|
2004-10-04 16:42:48 +02:00
|
|
|
if ((float8) result != darg)
|
2003-07-27 06:53:12 +02:00
|
|
|
ereport(ERROR,
|
|
|
|
(errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
|
2004-10-04 16:42:48 +02:00
|
|
|
errmsg("bigint out of range")));
|
Extend pg_cast castimplicit column to a three-way value; this allows us
to be flexible about assignment casts without introducing ambiguity in
operator/function resolution. Introduce a well-defined promotion hierarchy
for numeric datatypes (int2->int4->int8->numeric->float4->float8).
Change make_const to initially label numeric literals as int4, int8, or
numeric (never float8 anymore).
Explicitly mark Func and RelabelType nodes to indicate whether they came
from a function call, explicit cast, or implicit cast; use this to do
reverse-listing more accurately and without so many heuristics.
Explicit casts to char, varchar, bit, varbit will truncate or pad without
raising an error (the pre-7.2 behavior), while assigning to a column without
any explicit cast will still raise an error for wrong-length data like 7.3.
This more nearly follows the SQL spec than 7.2 behavior (we should be
reporting a 'completion condition' in the explicit-cast cases, but we have
no mechanism for that, so just do silent truncation).
Fix some problems with enforcement of typmod for array elements;
it didn't work at all in 'UPDATE ... SET array[n] = foo', for example.
Provide a generalized array_length_coerce() function to replace the
specialized per-array-type functions that used to be needed (and were
missing for NUMERIC as well as all the datetime types).
Add missing conversions int8<->float4, text<->numeric, oid<->int8.
initdb forced.
2002-09-18 23:35:25 +02:00
|
|
|
|
|
|
|
PG_RETURN_INT64(result);
|
|
|
|
}
|
|
|
|
|
|
|
|
Datum
|
|
|
|
i8tooid(PG_FUNCTION_ARGS)
|
|
|
|
{
|
2004-10-04 16:42:48 +02:00
|
|
|
int64 arg = PG_GETARG_INT64(0);
|
Extend pg_cast castimplicit column to a three-way value; this allows us
to be flexible about assignment casts without introducing ambiguity in
operator/function resolution. Introduce a well-defined promotion hierarchy
for numeric datatypes (int2->int4->int8->numeric->float4->float8).
Change make_const to initially label numeric literals as int4, int8, or
numeric (never float8 anymore).
Explicitly mark Func and RelabelType nodes to indicate whether they came
from a function call, explicit cast, or implicit cast; use this to do
reverse-listing more accurately and without so many heuristics.
Explicit casts to char, varchar, bit, varbit will truncate or pad without
raising an error (the pre-7.2 behavior), while assigning to a column without
any explicit cast will still raise an error for wrong-length data like 7.3.
This more nearly follows the SQL spec than 7.2 behavior (we should be
reporting a 'completion condition' in the explicit-cast cases, but we have
no mechanism for that, so just do silent truncation).
Fix some problems with enforcement of typmod for array elements;
it didn't work at all in 'UPDATE ... SET array[n] = foo', for example.
Provide a generalized array_length_coerce() function to replace the
specialized per-array-type functions that used to be needed (and were
missing for NUMERIC as well as all the datetime types).
Add missing conversions int8<->float4, text<->numeric, oid<->int8.
initdb forced.
2002-09-18 23:35:25 +02:00
|
|
|
Oid result;
|
|
|
|
|
2004-10-04 16:42:48 +02:00
|
|
|
result = (Oid) arg;
|
Extend pg_cast castimplicit column to a three-way value; this allows us
to be flexible about assignment casts without introducing ambiguity in
operator/function resolution. Introduce a well-defined promotion hierarchy
for numeric datatypes (int2->int4->int8->numeric->float4->float8).
Change make_const to initially label numeric literals as int4, int8, or
numeric (never float8 anymore).
Explicitly mark Func and RelabelType nodes to indicate whether they came
from a function call, explicit cast, or implicit cast; use this to do
reverse-listing more accurately and without so many heuristics.
Explicit casts to char, varchar, bit, varbit will truncate or pad without
raising an error (the pre-7.2 behavior), while assigning to a column without
any explicit cast will still raise an error for wrong-length data like 7.3.
This more nearly follows the SQL spec than 7.2 behavior (we should be
reporting a 'completion condition' in the explicit-cast cases, but we have
no mechanism for that, so just do silent truncation).
Fix some problems with enforcement of typmod for array elements;
it didn't work at all in 'UPDATE ... SET array[n] = foo', for example.
Provide a generalized array_length_coerce() function to replace the
specialized per-array-type functions that used to be needed (and were
missing for NUMERIC as well as all the datetime types).
Add missing conversions int8<->float4, text<->numeric, oid<->int8.
initdb forced.
2002-09-18 23:35:25 +02:00
|
|
|
|
|
|
|
/* Test for overflow by reverse-conversion. */
|
2004-10-04 16:42:48 +02:00
|
|
|
if ((int64) result != arg)
|
2003-07-27 06:53:12 +02:00
|
|
|
ereport(ERROR,
|
|
|
|
(errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
|
|
|
|
errmsg("OID out of range")));
|
Extend pg_cast castimplicit column to a three-way value; this allows us
to be flexible about assignment casts without introducing ambiguity in
operator/function resolution. Introduce a well-defined promotion hierarchy
for numeric datatypes (int2->int4->int8->numeric->float4->float8).
Change make_const to initially label numeric literals as int4, int8, or
numeric (never float8 anymore).
Explicitly mark Func and RelabelType nodes to indicate whether they came
from a function call, explicit cast, or implicit cast; use this to do
reverse-listing more accurately and without so many heuristics.
Explicit casts to char, varchar, bit, varbit will truncate or pad without
raising an error (the pre-7.2 behavior), while assigning to a column without
any explicit cast will still raise an error for wrong-length data like 7.3.
This more nearly follows the SQL spec than 7.2 behavior (we should be
reporting a 'completion condition' in the explicit-cast cases, but we have
no mechanism for that, so just do silent truncation).
Fix some problems with enforcement of typmod for array elements;
it didn't work at all in 'UPDATE ... SET array[n] = foo', for example.
Provide a generalized array_length_coerce() function to replace the
specialized per-array-type functions that used to be needed (and were
missing for NUMERIC as well as all the datetime types).
Add missing conversions int8<->float4, text<->numeric, oid<->int8.
initdb forced.
2002-09-18 23:35:25 +02:00
|
|
|
|
|
|
|
PG_RETURN_OID(result);
|
|
|
|
}
|
|
|
|
|
|
|
|
Datum
|
|
|
|
oidtoi8(PG_FUNCTION_ARGS)
|
|
|
|
{
|
2004-10-04 16:42:48 +02:00
|
|
|
Oid arg = PG_GETARG_OID(0);
|
Extend pg_cast castimplicit column to a three-way value; this allows us
to be flexible about assignment casts without introducing ambiguity in
operator/function resolution. Introduce a well-defined promotion hierarchy
for numeric datatypes (int2->int4->int8->numeric->float4->float8).
Change make_const to initially label numeric literals as int4, int8, or
numeric (never float8 anymore).
Explicitly mark Func and RelabelType nodes to indicate whether they came
from a function call, explicit cast, or implicit cast; use this to do
reverse-listing more accurately and without so many heuristics.
Explicit casts to char, varchar, bit, varbit will truncate or pad without
raising an error (the pre-7.2 behavior), while assigning to a column without
any explicit cast will still raise an error for wrong-length data like 7.3.
This more nearly follows the SQL spec than 7.2 behavior (we should be
reporting a 'completion condition' in the explicit-cast cases, but we have
no mechanism for that, so just do silent truncation).
Fix some problems with enforcement of typmod for array elements;
it didn't work at all in 'UPDATE ... SET array[n] = foo', for example.
Provide a generalized array_length_coerce() function to replace the
specialized per-array-type functions that used to be needed (and were
missing for NUMERIC as well as all the datetime types).
Add missing conversions int8<->float4, text<->numeric, oid<->int8.
initdb forced.
2002-09-18 23:35:25 +02:00
|
|
|
|
2004-10-04 16:42:48 +02:00
|
|
|
PG_RETURN_INT64((int64) arg);
|
Extend pg_cast castimplicit column to a three-way value; this allows us
to be flexible about assignment casts without introducing ambiguity in
operator/function resolution. Introduce a well-defined promotion hierarchy
for numeric datatypes (int2->int4->int8->numeric->float4->float8).
Change make_const to initially label numeric literals as int4, int8, or
numeric (never float8 anymore).
Explicitly mark Func and RelabelType nodes to indicate whether they came
from a function call, explicit cast, or implicit cast; use this to do
reverse-listing more accurately and without so many heuristics.
Explicit casts to char, varchar, bit, varbit will truncate or pad without
raising an error (the pre-7.2 behavior), while assigning to a column without
any explicit cast will still raise an error for wrong-length data like 7.3.
This more nearly follows the SQL spec than 7.2 behavior (we should be
reporting a 'completion condition' in the explicit-cast cases, but we have
no mechanism for that, so just do silent truncation).
Fix some problems with enforcement of typmod for array elements;
it didn't work at all in 'UPDATE ... SET array[n] = foo', for example.
Provide a generalized array_length_coerce() function to replace the
specialized per-array-type functions that used to be needed (and were
missing for NUMERIC as well as all the datetime types).
Add missing conversions int8<->float4, text<->numeric, oid<->int8.
initdb forced.
2002-09-18 23:35:25 +02:00
|
|
|
}
|
|
|
|
|
2000-06-13 09:35:40 +02:00
|
|
|
Datum
|
|
|
|
text_int8(PG_FUNCTION_ARGS)
|
1999-02-13 05:22:34 +01:00
|
|
|
{
|
2000-06-13 09:35:40 +02:00
|
|
|
text *str = PG_GETARG_TEXT_P(0);
|
1999-02-13 05:22:34 +01:00
|
|
|
int len;
|
|
|
|
char *s;
|
2000-06-13 09:35:40 +02:00
|
|
|
Datum result;
|
1999-02-13 05:22:34 +01:00
|
|
|
|
|
|
|
len = (VARSIZE(str) - VARHDRSZ);
|
1999-05-25 18:15:34 +02:00
|
|
|
s = palloc(len + 1);
|
2000-06-13 09:35:40 +02:00
|
|
|
memcpy(s, VARDATA(str), len);
|
1999-05-25 18:15:34 +02:00
|
|
|
*(s + len) = '\0';
|
1999-02-13 05:22:34 +01:00
|
|
|
|
2000-06-13 09:35:40 +02:00
|
|
|
result = DirectFunctionCall1(int8in, CStringGetDatum(s));
|
|
|
|
|
|
|
|
pfree(s);
|
|
|
|
|
|
|
|
return result;
|
|
|
|
}
|
1999-02-13 05:22:34 +01:00
|
|
|
|
2000-06-13 09:35:40 +02:00
|
|
|
Datum
|
|
|
|
int8_text(PG_FUNCTION_ARGS)
|
1999-02-13 05:22:34 +01:00
|
|
|
{
|
2004-10-04 16:42:48 +02:00
|
|
|
/* arg is int64, but easier to leave it as Datum */
|
|
|
|
Datum arg = PG_GETARG_DATUM(0);
|
1999-02-13 05:22:34 +01:00
|
|
|
char *s;
|
2000-06-13 09:35:40 +02:00
|
|
|
int len;
|
|
|
|
text *result;
|
1999-02-13 05:22:34 +01:00
|
|
|
|
2004-10-04 16:42:48 +02:00
|
|
|
s = DatumGetCString(DirectFunctionCall1(int8out, arg));
|
1999-02-13 05:22:34 +01:00
|
|
|
len = strlen(s);
|
|
|
|
|
2000-06-13 09:35:40 +02:00
|
|
|
result = (text *) palloc(VARHDRSZ + len);
|
1999-02-13 05:22:34 +01:00
|
|
|
|
2000-07-04 01:10:14 +02:00
|
|
|
VARATT_SIZEP(result) = len + VARHDRSZ;
|
2000-06-13 09:35:40 +02:00
|
|
|
memcpy(VARDATA(result), s, len);
|
1999-02-13 05:22:34 +01:00
|
|
|
|
2000-06-13 09:35:40 +02:00
|
|
|
pfree(s);
|
|
|
|
|
|
|
|
PG_RETURN_TEXT_P(result);
|
|
|
|
}
|
2004-02-03 09:29:57 +01:00
|
|
|
|
|
|
|
/*
|
|
|
|
* 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)
|
|
|
|
{
|
2004-08-29 07:07:03 +02:00
|
|
|
FuncCallContext *funcctx;
|
|
|
|
generate_series_fctx *fctx;
|
|
|
|
int64 result;
|
|
|
|
MemoryContext oldcontext;
|
2004-02-03 09:29:57 +01:00
|
|
|
|
|
|
|
/* stuff done only on the first call of the function */
|
|
|
|
if (SRF_IS_FIRSTCALL())
|
|
|
|
{
|
2004-08-29 07:07:03 +02:00
|
|
|
int64 start = PG_GETARG_INT64(0);
|
|
|
|
int64 finish = PG_GETARG_INT64(1);
|
|
|
|
int64 step = 1;
|
2004-02-03 09:29:57 +01:00
|
|
|
|
|
|
|
/* 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),
|
Wording cleanup for error messages. Also change can't -> cannot.
Standard English uses "may", "can", and "might" in different ways:
may - permission, "You may borrow my rake."
can - ability, "I can lift that log."
might - possibility, "It might rain today."
Unfortunately, in conversational English, their use is often mixed, as
in, "You may use this variable to do X", when in fact, "can" is a better
choice. Similarly, "It may crash" is better stated, "It might crash".
2007-02-01 20:10:30 +01:00
|
|
|
errmsg("step size cannot equal zero")));
|
2004-02-03 09:29:57 +01:00
|
|
|
|
|
|
|
/* create a function context for cross-call persistence */
|
|
|
|
funcctx = SRF_FIRSTCALL_INIT();
|
|
|
|
|
|
|
|
/*
|
2005-10-15 04:49:52 +02:00
|
|
|
* switch to memory context appropriate for multiple function calls
|
2004-02-03 09:29:57 +01:00
|
|
|
*/
|
|
|
|
oldcontext = MemoryContextSwitchTo(funcctx->multi_call_memory_ctx);
|
|
|
|
|
|
|
|
/* allocate memory for user context */
|
|
|
|
fctx = (generate_series_fctx *) palloc(sizeof(generate_series_fctx));
|
|
|
|
|
|
|
|
/*
|
2004-08-29 07:07:03 +02:00
|
|
|
* Use fctx to keep state from call to call. Seed current with the
|
|
|
|
* original start value
|
2004-02-03 09:29:57 +01:00
|
|
|
*/
|
|
|
|
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();
|
|
|
|
|
|
|
|
/*
|
2005-10-15 04:49:52 +02:00
|
|
|
* get the saved state and use current as the result for this iteration
|
2004-02-03 09:29:57 +01:00
|
|
|
*/
|
|
|
|
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 */
|
|
|
|
fctx->current += fctx->step;
|
|
|
|
|
|
|
|
/* 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);
|
|
|
|
}
|