mirror of
https://github.com/postgres/postgres.git
synced 2025-11-12 05:01:15 +03:00
Implement TIME WITH TIME ZONE type (timetz internal type). Remap length() for character strings to CHAR_LENGTH() for SQL92 and to remove the ambiguity with geometric length() functions. Keep length() for character strings for backward compatibility. Shrink stored views by removing internal column name list from visible rte. Implement min(), max() for time and timetz data types. Implement conversion of TIME to INTERVAL. Implement abs(), mod(), fac() for the int8 data type. Rename some math functions to generic names: round(), sqrt(), cbrt(), pow(), etc. Rename NUMERIC power() function to pow(). Fix int2 factorial to calculate result in int4. Enhance the Oracle compatibility function translate() to work with string arguments (from Edwin Ramirez). Modify pg_proc system table to remove OID holes.
729 lines
10 KiB
C
729 lines
10 KiB
C
/*-------------------------------------------------------------------------
|
|
*
|
|
* int.c
|
|
* Functions for the built-in integer types.
|
|
*
|
|
* Portions Copyright (c) 1996-2000, PostgreSQL, Inc
|
|
* Portions Copyright (c) 1994, Regents of the University of California
|
|
*
|
|
*
|
|
* IDENTIFICATION
|
|
* $Header: /cvsroot/pgsql/src/backend/utils/adt/int.c,v 1.35 2000/03/14 23:06:36 thomas Exp $
|
|
*
|
|
*-------------------------------------------------------------------------
|
|
*/
|
|
/*
|
|
* OLD COMMENTS
|
|
* I/O routines:
|
|
* int2in, int2out, int2vectorin, int2vectorout, int4in, int4out
|
|
* Conversion routines:
|
|
* itoi, int2_text, int4_text
|
|
* Boolean operators:
|
|
* inteq, intne, intlt, intle, intgt, intge
|
|
* Arithmetic operators:
|
|
* intpl, intmi, int4mul, intdiv
|
|
*
|
|
* Arithmetic operators:
|
|
* intmod, int4fac
|
|
*
|
|
* XXX makes massive and possibly unwarranted type promotion assumptions.
|
|
* fix me when we figure out what we want to do about ANSIfication...
|
|
*/
|
|
|
|
#include <ctype.h>
|
|
#include "postgres.h"
|
|
#ifdef HAVE_LIMITS_H
|
|
#include <limits.h>
|
|
#endif
|
|
|
|
#include "utils/builtins.h"
|
|
|
|
#ifndef SHRT_MAX
|
|
#define SHRT_MAX (0x7FFF)
|
|
#endif
|
|
#ifndef SHRT_MIN
|
|
#define SHRT_MIN (-0x8000)
|
|
#endif
|
|
|
|
/*****************************************************************************
|
|
* USER I/O ROUTINES *
|
|
*****************************************************************************/
|
|
|
|
/*
|
|
* int2in - converts "num" to short
|
|
*/
|
|
int32
|
|
int2in(char *num)
|
|
{
|
|
return (int32) pg_atoi(num, sizeof(int16), '\0');
|
|
}
|
|
|
|
/*
|
|
* int2out - converts short to "num"
|
|
*/
|
|
char *
|
|
int2out(int16 sh)
|
|
{
|
|
char *result;
|
|
|
|
result = (char *) palloc(7);/* assumes sign, 5 digits, '\0' */
|
|
itoa((int) sh, result);
|
|
return result;
|
|
}
|
|
|
|
/*
|
|
* int2vectorin - converts "num num ..." to internal form
|
|
*
|
|
* Note:
|
|
* Fills any nonexistent digits with NULLs.
|
|
*/
|
|
int16 *
|
|
int2vectorin(char *intString)
|
|
{
|
|
int16 *result;
|
|
int slot;
|
|
|
|
if (intString == NULL)
|
|
return NULL;
|
|
|
|
result = (int16 *) palloc(sizeof(int16[INDEX_MAX_KEYS]));
|
|
|
|
for (slot=0; *intString && slot < INDEX_MAX_KEYS; slot++)
|
|
{
|
|
if (sscanf(intString, "%hd", &result[slot]) != 1)
|
|
break;
|
|
while (*intString && isspace(*intString))
|
|
intString++;
|
|
while (*intString && !isspace(*intString))
|
|
intString++;
|
|
}
|
|
while (*intString && isspace(*intString))
|
|
intString++;
|
|
if (*intString)
|
|
elog(ERROR,"int2vector value has too many values");
|
|
while (slot < INDEX_MAX_KEYS)
|
|
result[slot++] = 0;
|
|
|
|
return result;
|
|
}
|
|
|
|
/*
|
|
* int2vectorout - converts internal form to "num num ..."
|
|
*/
|
|
char *
|
|
int2vectorout(int16 *int2Array)
|
|
{
|
|
int num, maxnum;
|
|
char *rp;
|
|
char *result;
|
|
|
|
if (int2Array == NULL)
|
|
{
|
|
result = (char *) palloc(2);
|
|
result[0] = '-';
|
|
result[1] = '\0';
|
|
return result;
|
|
}
|
|
|
|
/* find last non-zero value in vector */
|
|
for (maxnum = INDEX_MAX_KEYS-1; maxnum >= 0; maxnum--)
|
|
if (int2Array[maxnum] != 0)
|
|
break;
|
|
|
|
/* assumes sign, 5 digits, ' ' */
|
|
rp = result = (char *) palloc((maxnum+1) * 7 + 1);
|
|
for (num = 0; num <= maxnum; num++)
|
|
{
|
|
if (num != 0)
|
|
*rp++ = ' ';
|
|
ltoa(int2Array[num], rp);
|
|
while (*++rp != '\0')
|
|
;
|
|
}
|
|
*rp = '\0';
|
|
return result;
|
|
}
|
|
|
|
/*
|
|
* We don't have a complete set of int2vector support routines,
|
|
* but we need int2vectoreq for catcache indexing.
|
|
*/
|
|
bool
|
|
int2vectoreq(int16 *arg1, int16 *arg2)
|
|
{
|
|
return (bool) (memcmp(arg1, arg2, INDEX_MAX_KEYS * sizeof(int16)) == 0);
|
|
}
|
|
|
|
|
|
/*
|
|
* int44in - converts "num num ..." to internal form
|
|
*
|
|
* Note:
|
|
* Fills any nonexistent digits with NULLs.
|
|
*/
|
|
int32 *
|
|
int44in(char *input_string)
|
|
{
|
|
int32 *foo = (int32 *) palloc(4 * sizeof(int32));
|
|
int i = 0;
|
|
|
|
i = sscanf(input_string,
|
|
"%d, %d, %d, %d",
|
|
&foo[0],
|
|
&foo[1],
|
|
&foo[2],
|
|
&foo[3]);
|
|
while (i < 4)
|
|
foo[i++] = 0;
|
|
|
|
return foo;
|
|
}
|
|
|
|
/*
|
|
* int44out - converts internal form to "num num ..."
|
|
*/
|
|
char *
|
|
int44out(int32 *an_array)
|
|
{
|
|
int temp = 4;
|
|
char *output_string = NULL;
|
|
int i;
|
|
|
|
if (temp > 0)
|
|
{
|
|
char *walk;
|
|
|
|
output_string = (char *) palloc(16 * temp); /* assume 15 digits +
|
|
* sign */
|
|
walk = output_string;
|
|
for (i = 0; i < temp; i++)
|
|
{
|
|
itoa(an_array[i], walk);
|
|
while (*++walk != '\0')
|
|
;
|
|
*walk++ = ' ';
|
|
}
|
|
*--walk = '\0';
|
|
}
|
|
return output_string;
|
|
}
|
|
|
|
|
|
/*****************************************************************************
|
|
* PUBLIC ROUTINES *
|
|
*****************************************************************************/
|
|
|
|
/*
|
|
* int4in - converts "num" to int4
|
|
*/
|
|
int32
|
|
int4in(char *num)
|
|
{
|
|
return pg_atoi(num, sizeof(int32), '\0');
|
|
}
|
|
|
|
/*
|
|
* int4out - converts int4 to "num"
|
|
*/
|
|
char *
|
|
int4out(int32 l)
|
|
{
|
|
char *result;
|
|
|
|
result = (char *) palloc(12); /* assumes sign, 10 digits, '\0' */
|
|
ltoa(l, result);
|
|
return result;
|
|
}
|
|
|
|
|
|
/*
|
|
* ===================
|
|
* CONVERSION ROUTINES
|
|
* ===================
|
|
*/
|
|
|
|
int32
|
|
i2toi4(int16 arg1)
|
|
{
|
|
return (int32) arg1;
|
|
}
|
|
|
|
int16
|
|
i4toi2(int32 arg1)
|
|
{
|
|
if (arg1 < SHRT_MIN)
|
|
elog(ERROR, "i4toi2: '%d' causes int2 underflow", arg1);
|
|
if (arg1 > SHRT_MAX)
|
|
elog(ERROR, "i4toi2: '%d' causes int2 overflow", arg1);
|
|
|
|
return (int16) arg1;
|
|
}
|
|
|
|
text *
|
|
int2_text(int16 arg1)
|
|
{
|
|
text *result;
|
|
|
|
int len;
|
|
char *str;
|
|
|
|
str = int2out(arg1);
|
|
len = (strlen(str) + VARHDRSZ);
|
|
|
|
result = palloc(len);
|
|
|
|
VARSIZE(result) = len;
|
|
memmove(VARDATA(result), str, (len - VARHDRSZ));
|
|
|
|
pfree(str);
|
|
|
|
return result;
|
|
} /* int2_text() */
|
|
|
|
int16
|
|
text_int2(text *string)
|
|
{
|
|
int16 result;
|
|
|
|
int len;
|
|
char *str;
|
|
|
|
if (!string)
|
|
return 0;
|
|
|
|
len = (VARSIZE(string) - VARHDRSZ);
|
|
|
|
str = palloc(len + 1);
|
|
memmove(str, VARDATA(string), len);
|
|
*(str + len) = '\0';
|
|
|
|
result = int2in(str);
|
|
pfree(str);
|
|
|
|
return result;
|
|
} /* text_int2() */
|
|
|
|
text *
|
|
int4_text(int32 arg1)
|
|
{
|
|
text *result;
|
|
|
|
int len;
|
|
char *str;
|
|
|
|
str = int4out(arg1);
|
|
len = (strlen(str) + VARHDRSZ);
|
|
|
|
result = palloc(len);
|
|
|
|
VARSIZE(result) = len;
|
|
memmove(VARDATA(result), str, (len - VARHDRSZ));
|
|
|
|
pfree(str);
|
|
|
|
return result;
|
|
} /* int4_text() */
|
|
|
|
int32
|
|
text_int4(text *string)
|
|
{
|
|
int32 result;
|
|
|
|
int len;
|
|
char *str;
|
|
|
|
if (!string)
|
|
return 0;
|
|
|
|
len = (VARSIZE(string) - VARHDRSZ);
|
|
|
|
str = palloc(len + 1);
|
|
memmove(str, VARDATA(string), len);
|
|
*(str + len) = '\0';
|
|
|
|
result = int4in(str);
|
|
pfree(str);
|
|
|
|
return result;
|
|
} /* text_int4() */
|
|
|
|
|
|
/*
|
|
* =========================
|
|
* BOOLEAN OPERATOR ROUTINES
|
|
* =========================
|
|
*/
|
|
|
|
/*
|
|
* inteq - returns 1 iff arg1 == arg2
|
|
* intne - returns 1 iff arg1 != arg2
|
|
* intlt - returns 1 iff arg1 < arg2
|
|
* intle - returns 1 iff arg1 <= arg2
|
|
* intgt - returns 1 iff arg1 > arg2
|
|
* intge - returns 1 iff arg1 >= arg2
|
|
*/
|
|
bool
|
|
int4eq(int32 arg1, int32 arg2)
|
|
{
|
|
return arg1 == arg2;
|
|
}
|
|
|
|
bool
|
|
int4ne(int32 arg1, int32 arg2)
|
|
{
|
|
return arg1 != arg2;
|
|
}
|
|
|
|
bool
|
|
int4lt(int32 arg1, int32 arg2)
|
|
{
|
|
return arg1 < arg2;
|
|
}
|
|
|
|
bool
|
|
int4le(int32 arg1, int32 arg2)
|
|
{
|
|
return arg1 <= arg2;
|
|
}
|
|
|
|
bool
|
|
int4gt(int32 arg1, int32 arg2)
|
|
{
|
|
return arg1 > arg2;
|
|
}
|
|
|
|
bool
|
|
int4ge(int32 arg1, int32 arg2)
|
|
{
|
|
return arg1 >= arg2;
|
|
}
|
|
|
|
bool
|
|
int2eq(int16 arg1, int16 arg2)
|
|
{
|
|
return arg1 == arg2;
|
|
}
|
|
|
|
bool
|
|
int2ne(int16 arg1, int16 arg2)
|
|
{
|
|
return arg1 != arg2;
|
|
}
|
|
|
|
bool
|
|
int2lt(int16 arg1, int16 arg2)
|
|
{
|
|
return arg1 < arg2;
|
|
}
|
|
|
|
bool
|
|
int2le(int16 arg1, int16 arg2)
|
|
{
|
|
return arg1 <= arg2;
|
|
}
|
|
|
|
bool
|
|
int2gt(int16 arg1, int16 arg2)
|
|
{
|
|
return arg1 > arg2;
|
|
}
|
|
|
|
bool
|
|
int2ge(int16 arg1, int16 arg2)
|
|
{
|
|
return arg1 >= arg2;
|
|
}
|
|
|
|
bool
|
|
int24eq(int32 arg1, int32 arg2)
|
|
{
|
|
return arg1 == arg2;
|
|
}
|
|
|
|
bool
|
|
int24ne(int32 arg1, int32 arg2)
|
|
{
|
|
return arg1 != arg2;
|
|
}
|
|
|
|
bool
|
|
int24lt(int32 arg1, int32 arg2)
|
|
{
|
|
return arg1 < arg2;
|
|
}
|
|
|
|
bool
|
|
int24le(int32 arg1, int32 arg2)
|
|
{
|
|
return arg1 <= arg2;
|
|
}
|
|
|
|
bool
|
|
int24gt(int32 arg1, int32 arg2)
|
|
{
|
|
return arg1 > arg2;
|
|
}
|
|
|
|
bool
|
|
int24ge(int32 arg1, int32 arg2)
|
|
{
|
|
return arg1 >= arg2;
|
|
}
|
|
|
|
bool
|
|
int42eq(int32 arg1, int32 arg2)
|
|
{
|
|
return arg1 == arg2;
|
|
}
|
|
|
|
bool
|
|
int42ne(int32 arg1, int32 arg2)
|
|
{
|
|
return arg1 != arg2;
|
|
}
|
|
|
|
bool
|
|
int42lt(int32 arg1, int32 arg2)
|
|
{
|
|
return arg1 < arg2;
|
|
}
|
|
|
|
bool
|
|
int42le(int32 arg1, int32 arg2)
|
|
{
|
|
return arg1 <= arg2;
|
|
}
|
|
|
|
bool
|
|
int42gt(int32 arg1, int32 arg2)
|
|
{
|
|
return arg1 > arg2;
|
|
}
|
|
|
|
bool
|
|
int42ge(int32 arg1, int32 arg2)
|
|
{
|
|
return arg1 >= arg2;
|
|
}
|
|
|
|
/*
|
|
* int[24]pl - returns arg1 + arg2
|
|
* int[24]mi - returns arg1 - arg2
|
|
* int[24]mul - returns arg1 * arg2
|
|
* int[24]div - returns arg1 / arg2
|
|
*/
|
|
int32
|
|
int4um(int32 arg)
|
|
{
|
|
return -arg;
|
|
}
|
|
|
|
int32
|
|
int4pl(int32 arg1, int32 arg2)
|
|
{
|
|
return arg1 + arg2;
|
|
}
|
|
|
|
int32
|
|
int4mi(int32 arg1, int32 arg2)
|
|
{
|
|
return arg1 - arg2;
|
|
}
|
|
|
|
int32
|
|
int4mul(int32 arg1, int32 arg2)
|
|
{
|
|
return arg1 * arg2;
|
|
}
|
|
|
|
int32
|
|
int4div(int32 arg1, int32 arg2)
|
|
{
|
|
return arg1 / arg2;
|
|
}
|
|
|
|
int32
|
|
int4inc(int32 arg)
|
|
{
|
|
return arg + (int32) 1;
|
|
}
|
|
|
|
int16
|
|
int2um(int16 arg)
|
|
{
|
|
return -arg;
|
|
}
|
|
|
|
int16
|
|
int2pl(int16 arg1, int16 arg2)
|
|
{
|
|
return arg1 + arg2;
|
|
}
|
|
|
|
int16
|
|
int2mi(int16 arg1, int16 arg2)
|
|
{
|
|
return arg1 - arg2;
|
|
}
|
|
|
|
int16
|
|
int2mul(int16 arg1, int16 arg2)
|
|
{
|
|
return arg1 * arg2;
|
|
}
|
|
|
|
int16
|
|
int2div(int16 arg1, int16 arg2)
|
|
{
|
|
return arg1 / arg2;
|
|
}
|
|
|
|
int16
|
|
int2inc(int16 arg)
|
|
{
|
|
return arg + (int16) 1;
|
|
}
|
|
|
|
int32
|
|
int24pl(int32 arg1, int32 arg2)
|
|
{
|
|
return arg1 + arg2;
|
|
}
|
|
|
|
int32
|
|
int24mi(int32 arg1, int32 arg2)
|
|
{
|
|
return arg1 - arg2;
|
|
}
|
|
|
|
int32
|
|
int24mul(int32 arg1, int32 arg2)
|
|
{
|
|
return arg1 * arg2;
|
|
}
|
|
|
|
int32
|
|
int24div(int32 arg1, int32 arg2)
|
|
{
|
|
return arg1 / arg2;
|
|
}
|
|
|
|
int32
|
|
int42pl(int32 arg1, int32 arg2)
|
|
{
|
|
return arg1 + arg2;
|
|
}
|
|
|
|
int32
|
|
int42mi(int32 arg1, int32 arg2)
|
|
{
|
|
return arg1 - arg2;
|
|
}
|
|
|
|
int32
|
|
int42mul(int32 arg1, int32 arg2)
|
|
{
|
|
return arg1 * arg2;
|
|
}
|
|
|
|
int32
|
|
int42div(int32 arg1, int32 arg2)
|
|
{
|
|
return arg1 / arg2;
|
|
}
|
|
|
|
/*
|
|
* int[24]mod - returns arg1 mod arg2
|
|
*/
|
|
int32
|
|
int4mod(int32 arg1, int32 arg2)
|
|
{
|
|
return arg1 % arg2;
|
|
}
|
|
|
|
int32
|
|
int2mod(int16 arg1, int16 arg2)
|
|
{
|
|
return arg1 % arg2;
|
|
}
|
|
|
|
int32
|
|
int24mod(int32 arg1, int32 arg2)
|
|
{
|
|
return arg1 % arg2;
|
|
}
|
|
|
|
int32
|
|
int42mod(int32 arg1, int32 arg2)
|
|
{
|
|
return arg1 % arg2;
|
|
}
|
|
|
|
/* int[24]fac()
|
|
* Factorial
|
|
*/
|
|
int32
|
|
int4fac(int32 arg1)
|
|
{
|
|
int32 result;
|
|
|
|
if (arg1 < 1)
|
|
result = 0;
|
|
else
|
|
for (result = 1; arg1 > 0; --arg1)
|
|
result *= arg1;
|
|
return result;
|
|
}
|
|
|
|
int32
|
|
int2fac(int16 arg1)
|
|
{
|
|
int32 result;
|
|
|
|
if (arg1 < 1)
|
|
result = 0;
|
|
else
|
|
for (result = 1; arg1 > 0; --arg1)
|
|
result *= arg1;
|
|
return result;
|
|
}
|
|
|
|
/* int[24]abs()
|
|
* Absolute value
|
|
*/
|
|
int32
|
|
int4abs(int32 arg1)
|
|
{
|
|
return ((arg1 < 0)? -arg1: arg1);
|
|
}
|
|
|
|
int16
|
|
int2abs(int16 arg1)
|
|
{
|
|
return ((arg1 < 0)? -arg1: arg1);
|
|
}
|
|
|
|
int16
|
|
int2larger(int16 arg1, int16 arg2)
|
|
{
|
|
return (arg1 > arg2) ? arg1 : arg2;
|
|
}
|
|
|
|
int16
|
|
int2smaller(int16 arg1, int16 arg2)
|
|
{
|
|
return (arg1 < arg2) ? arg1 : arg2;
|
|
}
|
|
|
|
int32
|
|
int4larger(int32 arg1, int32 arg2)
|
|
{
|
|
return (arg1 > arg2) ? arg1 : arg2;
|
|
}
|
|
|
|
int32
|
|
int4smaller(int32 arg1, int32 arg2)
|
|
{
|
|
return (arg1 < arg2) ? arg1 : arg2;
|
|
}
|