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
|
|
|
|
*
|
2017-01-03 19:48:53 +01:00
|
|
|
* Portions Copyright (c) 1996-2017, PostgreSQL Global Development Group
|
2000-05-28 19:56:29 +02:00
|
|
|
* Portions Copyright (c) 1994, Regents of the University of California
|
|
|
|
*
|
|
|
|
* IDENTIFICATION
|
2010-09-20 22:08:53 +02:00
|
|
|
* src/backend/utils/adt/int8.c
|
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"
|
1998-07-08 15:57:05 +02:00
|
|
|
#include "utils/int8.h"
|
2010-11-20 04:13:11 +01:00
|
|
|
#include "utils/builtins.h"
|
1998-07-08 15:57:05 +02:00
|
|
|
|
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
|
|
|
/*
|
2014-05-06 18:12:18 +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
|
|
|
*/
|
2004-10-04 16:42:48 +02:00
|
|
|
if (strncmp(ptr, "9223372036854775808", 19) == 0)
|
2001-11-24 20:57:06 +01:00
|
|
|
{
|
2015-04-02 17:43:35 +02:00
|
|
|
tmp = PG_INT64_MIN;
|
2004-10-04 16:42:48 +02:00
|
|
|
ptr += 19;
|
|
|
|
goto gotdigits;
|
2001-11-24 20:57:06 +01:00
|
|
|
}
|
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),
|
2017-09-11 17:20:47 +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
|
|
|
|
Phase 2 of pgindent updates.
Change pg_bsd_indent to follow upstream rules for placement of comments
to the right of code, and remove pgindent hack that caused comments
following #endif to not obey the general rule.
Commit e3860ffa4dd0dad0dd9eea4be9cc1412373a8c89 wasn't actually using
the published version of pg_bsd_indent, but a hacked-up version that
tried to minimize the amount of movement of comments to the right of
code. The situation of interest is where such a comment has to be
moved to the right of its default placement at column 33 because there's
code there. BSD indent has always moved right in units of tab stops
in such cases --- but in the previous incarnation, indent was working
in 8-space tab stops, while now it knows we use 4-space tabs. So the
net result is that in about half the cases, such comments are placed
one tab stop left of before. This is better all around: it leaves
more room on the line for comment text, and it means that in such
cases the comment uniformly starts at the next 4-space tab stop after
the code, rather than sometimes one and sometimes two tabs after.
Also, ensure that comments following #endif are indented the same
as comments following other preprocessor commands such as #else.
That inconsistency turns out to have been self-inflicted damage
from a poorly-thought-through post-indent "fixup" in pgindent.
This patch is much less interesting than the first round of indent
changes, but also bulkier, so I thought it best to separate the effects.
Discussion: https://postgr.es/m/E1dAmxK-0006EE-1r@gemulon.postgresql.org
Discussion: https://postgr.es/m/30527.1495162840@sss.pgh.pa.us
2017-06-21 21:18:54 +02: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),
|
2017-01-18 20:08:20 +01:00
|
|
|
errmsg("value \"%s\" is out of range for type %s",
|
|
|
|
str, "bigint")));
|
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),
|
2017-09-11 17:20:47 +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 buf[MAXINT8LEN + 1];
|
2010-11-20 04:13:11 +01:00
|
|
|
char *result;
|
1998-07-08 15:57:05 +02:00
|
|
|
|
2010-11-20 04:13:11 +01:00
|
|
|
pg_lltoa(val, buf);
|
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
|
|
|
/*
|
2014-05-06 18:12:18 +02:00
|
|
|
* Overflow check. If the inputs are of different signs then their sum
|
2005-10-15 04:49:52 +02:00
|
|
|
* 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
|
|
|
/*
|
2014-05-06 18:12:18 +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
|
2005-10-15 04:49:52 +02:00
|
|
|
* 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
|
|
|
/*
|
2014-05-06 18:12:18 +02:00
|
|
|
* Overflow check. We basically check to see if result / arg2 gives arg1
|
2005-10-15 04:49:52 +02:00
|
|
|
* 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
|
2010-01-07 05:53:35 +01:00
|
|
|
* range; if so, no overflow is possible.
|
2004-10-04 16:42:48 +02:00
|
|
|
*/
|
2007-08-30 07:27:29 +02:00
|
|
|
if (arg1 != (int64) ((int32) arg1) || arg2 != (int64) ((int32) arg2))
|
|
|
|
{
|
|
|
|
if (arg2 != 0 &&
|
2012-11-19 18:24:25 +01:00
|
|
|
((arg2 == -1 && arg1 < 0 && result < 0) ||
|
|
|
|
result / arg2 != arg1))
|
2007-08-30 07:27:29 +02:00
|
|
|
ereport(ERROR,
|
|
|
|
(errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
|
|
|
|
errmsg("bigint out of range")));
|
|
|
|
}
|
2004-10-04 16:42:48 +02:00
|
|
|
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)
|
2011-03-12 00:18:55 +01:00
|
|
|
{
|
2003-07-27 06:53:12 +02:00
|
|
|
ereport(ERROR,
|
|
|
|
(errcode(ERRCODE_DIVISION_BY_ZERO),
|
|
|
|
errmsg("division by zero")));
|
2011-03-12 00:18:55 +01:00
|
|
|
/* ensure compiler realizes we mustn't reach the division (gcc bug) */
|
|
|
|
PG_RETURN_NULL();
|
|
|
|
}
|
2003-03-11 22:01:33 +01:00
|
|
|
|
2004-10-04 16:42:48 +02:00
|
|
|
/*
|
2012-11-19 18:24:25 +01:00
|
|
|
* 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.
|
2004-10-04 16:42:48 +02:00
|
|
|
*/
|
2012-11-19 18:24:25 +01:00
|
|
|
if (arg2 == -1)
|
|
|
|
{
|
|
|
|
result = -arg1;
|
|
|
|
/* overflow check (needed for INT64_MIN) */
|
|
|
|
if (arg1 != 0 && SAMESIGN(result, arg1))
|
|
|
|
ereport(ERROR,
|
|
|
|
(errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
|
|
|
|
errmsg("bigint out of range")));
|
|
|
|
PG_RETURN_INT64(result);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* No overflow is possible */
|
|
|
|
|
|
|
|
result = arg1 / arg2;
|
|
|
|
|
2004-10-04 16:42:48 +02:00
|
|
|
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)
|
2011-03-12 00:18:55 +01:00
|
|
|
{
|
2003-07-27 06:53:12 +02:00
|
|
|
ereport(ERROR,
|
|
|
|
(errcode(ERRCODE_DIVISION_BY_ZERO),
|
|
|
|
errmsg("division by zero")));
|
2011-03-12 00:18:55 +01:00
|
|
|
/* ensure compiler realizes we mustn't reach the division (gcc bug) */
|
|
|
|
PG_RETURN_NULL();
|
|
|
|
}
|
|
|
|
|
2012-11-14 23:30:00 +01:00
|
|
|
/*
|
|
|
|
* 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);
|
|
|
|
|
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)
|
|
|
|
{
|
2008-04-21 02:26:47 +02:00
|
|
|
/*
|
|
|
|
* When int8 is pass-by-reference, we provide this special case to avoid
|
2010-02-08 21:39:52 +01:00
|
|
|
* palloc overhead for COUNT(): when called as an aggregate, we know that
|
2010-02-26 03:01:40 +01:00
|
|
|
* 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.)
|
2008-04-21 02:26:47 +02:00
|
|
|
*/
|
|
|
|
#ifndef USE_FLOAT8_BYVAL /* controls int8 too */
|
2010-02-08 21:39:52 +01:00
|
|
|
if (AggCheckCallContext(fcinfo, NULL))
|
2005-03-12 21:25:06 +01:00
|
|
|
{
|
|
|
|
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
|
2008-04-21 02:26:47 +02:00
|
|
|
#endif
|
2005-03-12 21:25:06 +01:00
|
|
|
{
|
2010-02-08 21:39:52 +01:00
|
|
|
/* Not called as an aggregate, so just do it the dumb way */
|
2005-03-12 21:25:06 +01:00
|
|
|
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
|
|
|
}
|
|
|
|
|
2014-04-13 02:33:09 +02:00
|
|
|
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);
|
|
|
|
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")));
|
|
|
|
|
|
|
|
*arg = result;
|
|
|
|
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;
|
|
|
|
|
|
|
|
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);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2006-07-28 20:33:04 +02:00
|
|
|
/*
|
2014-04-13 02:33:09 +02:00
|
|
|
* These functions are exactly like int8inc/int8dec but are used for
|
2014-05-06 18:12:18 +02:00
|
|
|
* aggregates that count only non-null values. Since the functions are
|
2014-04-13 02:33:09 +02:00
|
|
|
* 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.
|
2006-07-28 20:33:04 +02:00
|
|
|
*/
|
|
|
|
|
|
|
|
Datum
|
|
|
|
int8inc_any(PG_FUNCTION_ARGS)
|
|
|
|
{
|
|
|
|
return int8inc(fcinfo);
|
|
|
|
}
|
|
|
|
|
|
|
|
Datum
|
|
|
|
int8inc_float8_float8(PG_FUNCTION_ARGS)
|
|
|
|
{
|
|
|
|
return int8inc(fcinfo);
|
|
|
|
}
|
2014-04-13 02:33:09 +02:00
|
|
|
|
|
|
|
Datum
|
|
|
|
int8dec_any(PG_FUNCTION_ARGS)
|
|
|
|
{
|
|
|
|
return int8dec(fcinfo);
|
|
|
|
}
|
2006-07-28 20:33:04 +02:00
|
|
|
|
|
|
|
|
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
|
|
|
/*
|
2014-05-06 18:12:18 +02:00
|
|
|
* Overflow check. If the inputs are of different signs then their sum
|
2005-10-15 04:49:52 +02:00
|
|
|
* 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
|
|
|
/*
|
2014-05-06 18:12:18 +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
|
2005-10-15 04:49:52 +02:00
|
|
|
* 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
|
|
|
/*
|
2014-05-06 18:12:18 +02:00
|
|
|
* Overflow check. We basically check to see if result / arg1 gives arg2
|
2005-10-15 04:49:52 +02:00
|
|
|
* 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)
|
2011-03-12 00:18:55 +01:00
|
|
|
{
|
2003-07-27 06:53:12 +02:00
|
|
|
ereport(ERROR,
|
|
|
|
(errcode(ERRCODE_DIVISION_BY_ZERO),
|
|
|
|
errmsg("division by zero")));
|
2011-03-12 00:18:55 +01:00
|
|
|
/* ensure compiler realizes we mustn't reach the division (gcc bug) */
|
|
|
|
PG_RETURN_NULL();
|
|
|
|
}
|
2003-03-11 22:01:33 +01:00
|
|
|
|
2004-10-04 16:42:48 +02:00
|
|
|
/*
|
2012-11-19 18:24:25 +01:00
|
|
|
* 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.
|
2004-10-04 16:42:48 +02:00
|
|
|
*/
|
2012-11-19 18:24:25 +01:00
|
|
|
if (arg2 == -1)
|
|
|
|
{
|
|
|
|
result = -arg1;
|
|
|
|
/* overflow check (needed for INT64_MIN) */
|
|
|
|
if (arg1 != 0 && SAMESIGN(result, arg1))
|
|
|
|
ereport(ERROR,
|
|
|
|
(errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
|
|
|
|
errmsg("bigint out of range")));
|
|
|
|
PG_RETURN_INT64(result);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* No overflow is possible */
|
|
|
|
|
|
|
|
result = arg1 / arg2;
|
|
|
|
|
2004-10-04 16:42:48 +02:00
|
|
|
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
|
|
|
/*
|
2014-05-06 18:12:18 +02:00
|
|
|
* Overflow check. If the inputs are of different signs then their sum
|
2005-10-15 04:49:52 +02:00
|
|
|
* 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
|
|
|
/*
|
2014-05-06 18:12:18 +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
|
2005-10-15 04:49:52 +02:00
|
|
|
* 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
|
|
|
/*
|
2014-05-06 18:12:18 +02:00
|
|
|
* Overflow check. We basically check to see if result / arg2 gives arg1
|
2005-10-15 04:49:52 +02:00
|
|
|
* 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)
|
2009-09-03 20:48:14 +02:00
|
|
|
{
|
2003-07-27 06:53:12 +02:00
|
|
|
ereport(ERROR,
|
|
|
|
(errcode(ERRCODE_DIVISION_BY_ZERO),
|
|
|
|
errmsg("division by zero")));
|
2009-09-03 20:48:14 +02:00
|
|
|
/* ensure compiler realizes we mustn't reach the division (gcc bug) */
|
|
|
|
PG_RETURN_NULL();
|
|
|
|
}
|
|
|
|
|
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
|
|
|
|
2008-06-17 21:10:56 +02:00
|
|
|
Datum
|
|
|
|
int82pl(PG_FUNCTION_ARGS)
|
|
|
|
{
|
|
|
|
int64 arg1 = PG_GETARG_INT64(0);
|
|
|
|
int16 arg2 = PG_GETARG_INT16(1);
|
|
|
|
int64 result;
|
|
|
|
|
|
|
|
result = arg1 + arg2;
|
|
|
|
|
|
|
|
/*
|
2014-05-06 18:12:18 +02:00
|
|
|
* Overflow check. If the inputs are of different signs then their sum
|
2008-06-17 21:10:56 +02:00
|
|
|
* cannot overflow. If the inputs are of the same sign, their sum had
|
|
|
|
* better be that sign too.
|
|
|
|
*/
|
|
|
|
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);
|
|
|
|
}
|
|
|
|
|
|
|
|
Datum
|
|
|
|
int82mi(PG_FUNCTION_ARGS)
|
|
|
|
{
|
|
|
|
int64 arg1 = PG_GETARG_INT64(0);
|
|
|
|
int16 arg2 = PG_GETARG_INT16(1);
|
|
|
|
int64 result;
|
|
|
|
|
|
|
|
result = arg1 - arg2;
|
|
|
|
|
|
|
|
/*
|
2014-05-06 18:12:18 +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
|
2008-06-17 21:10:56 +02:00
|
|
|
* result should be of the same sign as the first input.
|
|
|
|
*/
|
|
|
|
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);
|
|
|
|
}
|
|
|
|
|
|
|
|
Datum
|
|
|
|
int82mul(PG_FUNCTION_ARGS)
|
|
|
|
{
|
|
|
|
int64 arg1 = PG_GETARG_INT64(0);
|
|
|
|
int16 arg2 = PG_GETARG_INT16(1);
|
|
|
|
int64 result;
|
|
|
|
|
|
|
|
result = arg1 * arg2;
|
|
|
|
|
|
|
|
/*
|
2014-05-06 18:12:18 +02:00
|
|
|
* Overflow check. We basically check to see if result / arg1 gives arg2
|
2008-06-17 21:10:56 +02:00
|
|
|
* again. There is one case where this fails: arg1 = 0 (which cannot
|
|
|
|
* overflow).
|
|
|
|
*
|
|
|
|
* Since the division is likely much more expensive than the actual
|
|
|
|
* 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.
|
|
|
|
*/
|
|
|
|
if (arg1 != (int64) ((int32) arg1) &&
|
|
|
|
result / arg1 != arg2)
|
|
|
|
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 (arg2 == 0)
|
2011-03-12 00:18:55 +01:00
|
|
|
{
|
2008-06-17 21:10:56 +02:00
|
|
|
ereport(ERROR,
|
|
|
|
(errcode(ERRCODE_DIVISION_BY_ZERO),
|
|
|
|
errmsg("division by zero")));
|
2011-03-12 00:18:55 +01:00
|
|
|
/* ensure compiler realizes we mustn't reach the division (gcc bug) */
|
|
|
|
PG_RETURN_NULL();
|
|
|
|
}
|
2008-06-17 21:10:56 +02:00
|
|
|
|
|
|
|
/*
|
2012-11-19 18:24:25 +01:00
|
|
|
* 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.
|
2008-06-17 21:10:56 +02:00
|
|
|
*/
|
2012-11-19 18:24:25 +01:00
|
|
|
if (arg2 == -1)
|
|
|
|
{
|
|
|
|
result = -arg1;
|
|
|
|
/* overflow check (needed for INT64_MIN) */
|
|
|
|
if (arg1 != 0 && SAMESIGN(result, arg1))
|
|
|
|
ereport(ERROR,
|
|
|
|
(errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
|
|
|
|
errmsg("bigint out of range")));
|
|
|
|
PG_RETURN_INT64(result);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* No overflow is possible */
|
|
|
|
|
|
|
|
result = arg1 / arg2;
|
|
|
|
|
2008-06-17 21:10:56 +02:00
|
|
|
PG_RETURN_INT64(result);
|
|
|
|
}
|
|
|
|
|
|
|
|
Datum
|
|
|
|
int28pl(PG_FUNCTION_ARGS)
|
|
|
|
{
|
|
|
|
int16 arg1 = PG_GETARG_INT16(0);
|
|
|
|
int64 arg2 = PG_GETARG_INT64(1);
|
|
|
|
int64 result;
|
|
|
|
|
|
|
|
result = arg1 + arg2;
|
|
|
|
|
|
|
|
/*
|
2014-05-06 18:12:18 +02:00
|
|
|
* Overflow check. If the inputs are of different signs then their sum
|
2008-06-17 21:10:56 +02:00
|
|
|
* cannot overflow. If the inputs are of the same sign, their sum had
|
|
|
|
* better be that sign too.
|
|
|
|
*/
|
|
|
|
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);
|
|
|
|
}
|
|
|
|
|
|
|
|
Datum
|
|
|
|
int28mi(PG_FUNCTION_ARGS)
|
|
|
|
{
|
|
|
|
int16 arg1 = PG_GETARG_INT16(0);
|
|
|
|
int64 arg2 = PG_GETARG_INT64(1);
|
|
|
|
int64 result;
|
|
|
|
|
|
|
|
result = arg1 - arg2;
|
|
|
|
|
|
|
|
/*
|
2014-05-06 18:12:18 +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
|
2008-06-17 21:10:56 +02:00
|
|
|
* result should be of the same sign as the first input.
|
|
|
|
*/
|
|
|
|
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);
|
|
|
|
}
|
|
|
|
|
|
|
|
Datum
|
|
|
|
int28mul(PG_FUNCTION_ARGS)
|
|
|
|
{
|
|
|
|
int16 arg1 = PG_GETARG_INT16(0);
|
|
|
|
int64 arg2 = PG_GETARG_INT64(1);
|
|
|
|
int64 result;
|
|
|
|
|
|
|
|
result = arg1 * arg2;
|
|
|
|
|
|
|
|
/*
|
2014-05-06 18:12:18 +02:00
|
|
|
* Overflow check. We basically check to see if result / arg2 gives arg1
|
2008-06-17 21:10:56 +02:00
|
|
|
* again. There is one case where this fails: arg2 = 0 (which cannot
|
|
|
|
* overflow).
|
|
|
|
*
|
|
|
|
* Since the division is likely much more expensive than the actual
|
|
|
|
* 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.
|
|
|
|
*/
|
|
|
|
if (arg2 != (int64) ((int32) arg2) &&
|
|
|
|
result / arg2 != arg1)
|
|
|
|
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 (arg2 == 0)
|
2009-09-03 20:48:14 +02:00
|
|
|
{
|
2008-06-17 21:10:56 +02:00
|
|
|
ereport(ERROR,
|
|
|
|
(errcode(ERRCODE_DIVISION_BY_ZERO),
|
|
|
|
errmsg("division by zero")));
|
2009-09-03 20:48:14 +02:00
|
|
|
/* ensure compiler realizes we mustn't reach the division (gcc bug) */
|
|
|
|
PG_RETURN_NULL();
|
|
|
|
}
|
|
|
|
|
2008-06-17 21:10:56 +02:00
|
|
|
/* No overflow is possible */
|
|
|
|
PG_RETURN_INT64((int64) arg1 / arg2);
|
|
|
|
}
|
|
|
|
|
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
|
|
|
}
|
|
|
|
|
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;
|
|
|
|
|
2011-06-17 20:28:45 +02:00
|
|
|
/* if next-value computation overflows, this is the final result */
|
|
|
|
if (SAMESIGN(result, fctx->step) && !SAMESIGN(result, fctx->current))
|
|
|
|
fctx->step = 0;
|
|
|
|
|
2004-02-03 09:29:57 +01:00
|
|
|
/* 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);
|
|
|
|
}
|