mirror of
https://github.com/postgres/postgres.git
synced 2025-11-12 05:01:15 +03:00
Latest round of fmgr updates. All functions with bool,char, or int2
inputs have been converted to newstyle. This should go a long way towards fixing our portability problems with platforms where char and short parameters are passed differently from int-width parameters. Still more to do for the Alpha port however.
This commit is contained in:
@@ -8,7 +8,7 @@
|
||||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $Header: /cvsroot/pgsql/src/backend/access/hash/hashfunc.c,v 1.25 2000/04/12 17:14:44 momjian Exp $
|
||||
* $Header: /cvsroot/pgsql/src/backend/access/hash/hashfunc.c,v 1.26 2000/06/05 07:28:35 tgl Exp $
|
||||
*
|
||||
* NOTES
|
||||
* These functions are stored in pg_amproc. For each operator class
|
||||
@@ -21,134 +21,132 @@
|
||||
|
||||
#include "access/hash.h"
|
||||
|
||||
uint32
|
||||
hashint2(int16 key)
|
||||
Datum
|
||||
hashint2(PG_FUNCTION_ARGS)
|
||||
{
|
||||
return (uint32) ~key;
|
||||
PG_RETURN_UINT32((uint32) ~ PG_GETARG_INT16(0));
|
||||
}
|
||||
|
||||
uint32
|
||||
hashint4(uint32 key)
|
||||
Datum
|
||||
hashint4(PG_FUNCTION_ARGS)
|
||||
{
|
||||
return ~key;
|
||||
PG_RETURN_UINT32(~ PG_GETARG_UINT32(0));
|
||||
}
|
||||
|
||||
uint32
|
||||
hashint8(int64 *key)
|
||||
Datum
|
||||
hashint8(PG_FUNCTION_ARGS)
|
||||
{
|
||||
return ~((uint32) *key);
|
||||
/* we just use the low 32 bits... */
|
||||
PG_RETURN_UINT32(~((uint32) PG_GETARG_INT64(0)));
|
||||
}
|
||||
|
||||
/* Hash function from Chris Torek. */
|
||||
uint32
|
||||
hashfloat4(float32 keyp)
|
||||
Datum
|
||||
hashfloat4(PG_FUNCTION_ARGS)
|
||||
{
|
||||
int len;
|
||||
float4 key = PG_GETARG_FLOAT4(0);
|
||||
char *kp = (char *) &key;
|
||||
int len = sizeof(key);
|
||||
int loop;
|
||||
uint32 h;
|
||||
char *kp = (char *) keyp;
|
||||
|
||||
len = sizeof(float32data);
|
||||
|
||||
#define HASH4a h = (h << 5) - h + *kp++;
|
||||
#define HASH4b h = (h << 5) + h + *kp++;
|
||||
#define HASH4 HASH4b
|
||||
|
||||
|
||||
h = 0;
|
||||
if (len > 0)
|
||||
{
|
||||
loop = (len + 8 - 1) >> 3;
|
||||
/*
|
||||
* This is a tad silly, given that we expect len = 4, but a smart
|
||||
* compiler should be able to eliminate the redundant code...
|
||||
*/
|
||||
loop = (len + 8 - 1) >> 3;
|
||||
|
||||
switch (len & (8 - 1))
|
||||
{
|
||||
case 0:
|
||||
do
|
||||
{ /* All fall throughs */
|
||||
HASH4;
|
||||
case 7:
|
||||
HASH4;
|
||||
case 6:
|
||||
HASH4;
|
||||
case 5:
|
||||
HASH4;
|
||||
case 4:
|
||||
HASH4;
|
||||
case 3:
|
||||
HASH4;
|
||||
case 2:
|
||||
HASH4;
|
||||
case 1:
|
||||
HASH4;
|
||||
} while (--loop);
|
||||
}
|
||||
switch (len & (8 - 1))
|
||||
{
|
||||
case 0:
|
||||
do
|
||||
{ /* All fall throughs */
|
||||
HASH4;
|
||||
case 7:
|
||||
HASH4;
|
||||
case 6:
|
||||
HASH4;
|
||||
case 5:
|
||||
HASH4;
|
||||
case 4:
|
||||
HASH4;
|
||||
case 3:
|
||||
HASH4;
|
||||
case 2:
|
||||
HASH4;
|
||||
case 1:
|
||||
HASH4;
|
||||
} while (--loop);
|
||||
}
|
||||
return h;
|
||||
PG_RETURN_UINT32(h);
|
||||
}
|
||||
|
||||
|
||||
uint32
|
||||
hashfloat8(float64 keyp)
|
||||
Datum
|
||||
hashfloat8(PG_FUNCTION_ARGS)
|
||||
{
|
||||
int len;
|
||||
float8 key = PG_GETARG_FLOAT8(0);
|
||||
char *kp = (char *) &key;
|
||||
int len = sizeof(key);
|
||||
int loop;
|
||||
uint32 h;
|
||||
char *kp = (char *) keyp;
|
||||
|
||||
len = sizeof(float64data);
|
||||
|
||||
#define HASH4a h = (h << 5) - h + *kp++;
|
||||
#define HASH4b h = (h << 5) + h + *kp++;
|
||||
#define HASH4 HASH4b
|
||||
|
||||
|
||||
h = 0;
|
||||
if (len > 0)
|
||||
/*
|
||||
* This is a tad silly, given that we expect len = 8, but a smart
|
||||
* compiler should be able to eliminate the redundant code...
|
||||
*/
|
||||
loop = (len + 8 - 1) >> 3;
|
||||
|
||||
switch (len & (8 - 1))
|
||||
{
|
||||
loop = (len + 8 - 1) >> 3;
|
||||
|
||||
switch (len & (8 - 1))
|
||||
{
|
||||
case 0:
|
||||
do
|
||||
{ /* All fall throughs */
|
||||
HASH4;
|
||||
case 7:
|
||||
HASH4;
|
||||
case 6:
|
||||
HASH4;
|
||||
case 5:
|
||||
HASH4;
|
||||
case 4:
|
||||
HASH4;
|
||||
case 3:
|
||||
HASH4;
|
||||
case 2:
|
||||
HASH4;
|
||||
case 1:
|
||||
HASH4;
|
||||
} while (--loop);
|
||||
}
|
||||
case 0:
|
||||
do
|
||||
{ /* All fall throughs */
|
||||
HASH4;
|
||||
case 7:
|
||||
HASH4;
|
||||
case 6:
|
||||
HASH4;
|
||||
case 5:
|
||||
HASH4;
|
||||
case 4:
|
||||
HASH4;
|
||||
case 3:
|
||||
HASH4;
|
||||
case 2:
|
||||
HASH4;
|
||||
case 1:
|
||||
HASH4;
|
||||
} while (--loop);
|
||||
}
|
||||
return h;
|
||||
PG_RETURN_UINT32(h);
|
||||
}
|
||||
|
||||
|
||||
uint32
|
||||
hashoid(Oid key)
|
||||
Datum
|
||||
hashoid(PG_FUNCTION_ARGS)
|
||||
{
|
||||
return (uint32) ~key;
|
||||
PG_RETURN_UINT32(~(uint32) PG_GETARG_OID(0));
|
||||
}
|
||||
|
||||
uint32
|
||||
hashoidvector(Oid *key)
|
||||
Datum
|
||||
hashoidvector(PG_FUNCTION_ARGS)
|
||||
{
|
||||
Oid *key = (Oid *) PG_GETARG_POINTER(0);
|
||||
int i;
|
||||
uint32 result = 0;
|
||||
|
||||
for (i = INDEX_MAX_KEYS; --i >= 0;)
|
||||
result = (result << 1) ^ (~(uint32) key[i]);
|
||||
return result;
|
||||
PG_RETURN_UINT32(result);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -156,55 +154,50 @@ hashoidvector(Oid *key)
|
||||
* hash function, because it has no pg_proc entry. We only need it
|
||||
* for catcache indexing.
|
||||
*/
|
||||
uint32
|
||||
hashint2vector(int16 *key)
|
||||
Datum
|
||||
hashint2vector(PG_FUNCTION_ARGS)
|
||||
{
|
||||
int16 *key = (int16 *) PG_GETARG_POINTER(0);
|
||||
int i;
|
||||
uint32 result = 0;
|
||||
|
||||
for (i = INDEX_MAX_KEYS; --i >= 0;)
|
||||
result = (result << 1) ^ (~(uint32) key[i]);
|
||||
return result;
|
||||
PG_RETURN_UINT32(result);
|
||||
}
|
||||
|
||||
|
||||
#define PRIME1 37
|
||||
#define PRIME2 1048583
|
||||
|
||||
uint32
|
||||
hashchar(char key)
|
||||
Datum
|
||||
hashchar(PG_FUNCTION_ARGS)
|
||||
{
|
||||
uint32 h;
|
||||
|
||||
/* Convert char to integer */
|
||||
h = (key - ' ');
|
||||
h = (PG_GETARG_CHAR(0) - ' ');
|
||||
h %= PRIME2;
|
||||
|
||||
return h;
|
||||
PG_RETURN_UINT32(h);
|
||||
}
|
||||
|
||||
|
||||
uint32
|
||||
hashname(NameData *n)
|
||||
Datum
|
||||
hashname(PG_FUNCTION_ARGS)
|
||||
{
|
||||
char *key = NameStr(* PG_GETARG_NAME(0));
|
||||
int len = NAMEDATALEN;
|
||||
uint32 h;
|
||||
int len;
|
||||
char *key;
|
||||
|
||||
key = NameStr(*n);
|
||||
|
||||
h = 0;
|
||||
len = NAMEDATALEN;
|
||||
/* Convert string to integer */
|
||||
while (len--)
|
||||
h = h * PRIME1 ^ (*key++ - ' ');
|
||||
h %= PRIME2;
|
||||
|
||||
return h;
|
||||
PG_RETURN_UINT32(h);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* (Comment from the original db3 hashing code: )
|
||||
*
|
||||
@@ -216,19 +209,17 @@ hashname(NameData *n)
|
||||
*
|
||||
* "OZ's original sdbm hash"
|
||||
*/
|
||||
uint32
|
||||
hashtext(struct varlena * key)
|
||||
Datum
|
||||
hashtext(PG_FUNCTION_ARGS)
|
||||
{
|
||||
text *key = PG_GETARG_TEXT_P(0);
|
||||
int keylen;
|
||||
char *keydata;
|
||||
uint32 n;
|
||||
int loop;
|
||||
|
||||
keydata = VARDATA(key);
|
||||
keylen = VARSIZE(key);
|
||||
|
||||
/* keylen includes the four bytes in which string keylength is stored */
|
||||
keylen -= sizeof(VARSIZE(key));
|
||||
keylen = VARSIZE(key) - VARHDRSZ;
|
||||
|
||||
#define HASHC n = *keydata++ + 65599 * n
|
||||
|
||||
@@ -260,5 +251,5 @@ hashtext(struct varlena * key)
|
||||
} while (--loop);
|
||||
}
|
||||
}
|
||||
return n;
|
||||
PG_RETURN_UINT32(n);
|
||||
}
|
||||
|
||||
@@ -8,141 +8,203 @@
|
||||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $Header: /cvsroot/pgsql/src/backend/access/nbtree/nbtcompare.c,v 1.34 2000/04/12 17:14:49 momjian Exp $
|
||||
* $Header: /cvsroot/pgsql/src/backend/access/nbtree/nbtcompare.c,v 1.35 2000/06/05 07:28:36 tgl Exp $
|
||||
*
|
||||
* NOTES
|
||||
* These functions are stored in pg_amproc. For each operator class
|
||||
* defined on btrees, they compute
|
||||
* NOTES
|
||||
*
|
||||
* These functions are stored in pg_amproc. For each operator class
|
||||
* defined on btrees, they compute
|
||||
*
|
||||
* compare(a, b):
|
||||
* < 0 if a < b,
|
||||
* = 0 if a == b,
|
||||
* > 0 if a > b.
|
||||
*
|
||||
* The result is always an int32 regardless of the input datatype.
|
||||
*
|
||||
* NOTE: although any negative int32 is acceptable for reporting "<",
|
||||
* and any positive int32 is acceptable for reporting ">", routines
|
||||
* that work on 32-bit or wider datatypes can't just return "a - b".
|
||||
* That could overflow and give the wrong answer.
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
|
||||
#include "postgres.h"
|
||||
|
||||
#include "utils/builtins.h"
|
||||
|
||||
int32
|
||||
btint2cmp(int16 a, int16 b)
|
||||
Datum
|
||||
btboolcmp(PG_FUNCTION_ARGS)
|
||||
{
|
||||
return (int32) (a - b);
|
||||
bool a = PG_GETARG_BOOL(0);
|
||||
bool b = PG_GETARG_BOOL(1);
|
||||
|
||||
PG_RETURN_INT32((int32) a - (int32) b);
|
||||
}
|
||||
|
||||
int32
|
||||
btint4cmp(int32 a, int32 b)
|
||||
Datum
|
||||
btint2cmp(PG_FUNCTION_ARGS)
|
||||
{
|
||||
int16 a = PG_GETARG_INT16(0);
|
||||
int16 b = PG_GETARG_INT16(1);
|
||||
|
||||
PG_RETURN_INT32((int32) a - (int32) b);
|
||||
}
|
||||
|
||||
Datum
|
||||
btint4cmp(PG_FUNCTION_ARGS)
|
||||
{
|
||||
int32 a = PG_GETARG_INT32(0);
|
||||
int32 b = PG_GETARG_INT32(1);
|
||||
|
||||
if (a > b)
|
||||
return 1;
|
||||
PG_RETURN_INT32(1);
|
||||
else if (a == b)
|
||||
return 0;
|
||||
PG_RETURN_INT32(0);
|
||||
else
|
||||
return -1;
|
||||
PG_RETURN_INT32(-1);
|
||||
}
|
||||
|
||||
int32
|
||||
btint8cmp(int64 *a, int64 *b)
|
||||
Datum
|
||||
btint8cmp(PG_FUNCTION_ARGS)
|
||||
{
|
||||
if (*a > *b)
|
||||
return 1;
|
||||
else if (*a == *b)
|
||||
return 0;
|
||||
else
|
||||
return -1;
|
||||
}
|
||||
int64 a = PG_GETARG_INT64(0);
|
||||
int64 b = PG_GETARG_INT64(1);
|
||||
|
||||
int32
|
||||
btint24cmp(int16 a, int32 b)
|
||||
{
|
||||
return ((int32) a) - b;
|
||||
}
|
||||
|
||||
int32
|
||||
btint42cmp(int32 a, int16 b)
|
||||
{
|
||||
return a - ((int32) b);
|
||||
}
|
||||
|
||||
int32
|
||||
btfloat4cmp(float32 a, float32 b)
|
||||
{
|
||||
if (*a > *b)
|
||||
return 1;
|
||||
else if (*a == *b)
|
||||
return 0;
|
||||
else
|
||||
return -1;
|
||||
}
|
||||
|
||||
int32
|
||||
btfloat8cmp(float64 a, float64 b)
|
||||
{
|
||||
if (*a > *b)
|
||||
return 1;
|
||||
else if (*a == *b)
|
||||
return 0;
|
||||
else
|
||||
return -1;
|
||||
}
|
||||
|
||||
int32
|
||||
btoidcmp(Oid a, Oid b)
|
||||
{
|
||||
if (a > b)
|
||||
return 1;
|
||||
PG_RETURN_INT32(1);
|
||||
else if (a == b)
|
||||
return 0;
|
||||
PG_RETURN_INT32(0);
|
||||
else
|
||||
return -1;
|
||||
PG_RETURN_INT32(-1);
|
||||
}
|
||||
|
||||
int32
|
||||
btoidvectorcmp(Oid *a, Oid *b)
|
||||
Datum
|
||||
btint24cmp(PG_FUNCTION_ARGS)
|
||||
{
|
||||
int16 a = PG_GETARG_INT16(0);
|
||||
int32 b = PG_GETARG_INT32(1);
|
||||
|
||||
if (a > b)
|
||||
PG_RETURN_INT32(1);
|
||||
else if (a == b)
|
||||
PG_RETURN_INT32(0);
|
||||
else
|
||||
PG_RETURN_INT32(-1);
|
||||
}
|
||||
|
||||
Datum
|
||||
btint42cmp(PG_FUNCTION_ARGS)
|
||||
{
|
||||
int32 a = PG_GETARG_INT32(0);
|
||||
int16 b = PG_GETARG_INT16(1);
|
||||
|
||||
if (a > b)
|
||||
PG_RETURN_INT32(1);
|
||||
else if (a == b)
|
||||
PG_RETURN_INT32(0);
|
||||
else
|
||||
PG_RETURN_INT32(-1);
|
||||
}
|
||||
|
||||
Datum
|
||||
btfloat4cmp(PG_FUNCTION_ARGS)
|
||||
{
|
||||
float4 a = PG_GETARG_FLOAT4(0);
|
||||
float4 b = PG_GETARG_FLOAT4(1);
|
||||
|
||||
if (a > b)
|
||||
PG_RETURN_INT32(1);
|
||||
else if (a == b)
|
||||
PG_RETURN_INT32(0);
|
||||
else
|
||||
PG_RETURN_INT32(-1);
|
||||
}
|
||||
|
||||
Datum
|
||||
btfloat8cmp(PG_FUNCTION_ARGS)
|
||||
{
|
||||
float8 a = PG_GETARG_FLOAT8(0);
|
||||
float8 b = PG_GETARG_FLOAT8(1);
|
||||
|
||||
if (a > b)
|
||||
PG_RETURN_INT32(1);
|
||||
else if (a == b)
|
||||
PG_RETURN_INT32(0);
|
||||
else
|
||||
PG_RETURN_INT32(-1);
|
||||
}
|
||||
|
||||
Datum
|
||||
btoidcmp(PG_FUNCTION_ARGS)
|
||||
{
|
||||
Oid a = PG_GETARG_OID(0);
|
||||
Oid b = PG_GETARG_OID(1);
|
||||
|
||||
if (a > b)
|
||||
PG_RETURN_INT32(1);
|
||||
else if (a == b)
|
||||
PG_RETURN_INT32(0);
|
||||
else
|
||||
PG_RETURN_INT32(-1);
|
||||
}
|
||||
|
||||
Datum
|
||||
btoidvectorcmp(PG_FUNCTION_ARGS)
|
||||
{
|
||||
Oid *a = (Oid *) PG_GETARG_POINTER(0);
|
||||
Oid *b = (Oid *) PG_GETARG_POINTER(1);
|
||||
int i;
|
||||
|
||||
for (i = 0; i < INDEX_MAX_KEYS; i++)
|
||||
/* we use this because we need the int4gt, etc */
|
||||
if (!int4eq(a[i], b[i]))
|
||||
{
|
||||
if (a[i] != b[i])
|
||||
{
|
||||
if (int4gt(a[i], b[i]))
|
||||
return 1;
|
||||
if (a[i] > b[i])
|
||||
PG_RETURN_INT32(1);
|
||||
else
|
||||
return -1;
|
||||
PG_RETURN_INT32(-1);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
PG_RETURN_INT32(0);
|
||||
}
|
||||
|
||||
|
||||
int32
|
||||
btabstimecmp(AbsoluteTime a, AbsoluteTime b)
|
||||
{
|
||||
if (AbsoluteTimeIsBefore(a, b))
|
||||
return -1;
|
||||
PG_RETURN_INT32(-1);
|
||||
else if (AbsoluteTimeIsBefore(b, a))
|
||||
return 1;
|
||||
PG_RETURN_INT32(1);
|
||||
else
|
||||
return 0;
|
||||
PG_RETURN_INT32(0);
|
||||
}
|
||||
|
||||
int32
|
||||
btcharcmp(char a, char b)
|
||||
Datum
|
||||
btcharcmp(PG_FUNCTION_ARGS)
|
||||
{
|
||||
return (int32) ((uint8) a - (uint8) b);
|
||||
char a = PG_GETARG_CHAR(0);
|
||||
char b = PG_GETARG_CHAR(1);
|
||||
|
||||
/* Be careful to compare chars as unsigned */
|
||||
PG_RETURN_INT32((int32) ((uint8) a) - (int32) ((uint8) b));
|
||||
}
|
||||
|
||||
int32
|
||||
btnamecmp(NameData *a, NameData *b)
|
||||
Datum
|
||||
btnamecmp(PG_FUNCTION_ARGS)
|
||||
{
|
||||
return strncmp(NameStr(*a), NameStr(*b), NAMEDATALEN);
|
||||
Name a = PG_GETARG_NAME(0);
|
||||
Name b = PG_GETARG_NAME(1);
|
||||
|
||||
PG_RETURN_INT32(strncmp(NameStr(*a), NameStr(*b), NAMEDATALEN));
|
||||
}
|
||||
|
||||
int32
|
||||
bttextcmp(struct varlena * a, struct varlena * b)
|
||||
Datum
|
||||
bttextcmp(PG_FUNCTION_ARGS)
|
||||
{
|
||||
text *a = PG_GETARG_TEXT_P(0);
|
||||
text *b = PG_GETARG_TEXT_P(1);
|
||||
int res;
|
||||
unsigned char *ap,
|
||||
*bp;
|
||||
@@ -187,7 +249,7 @@ bttextcmp(struct varlena * a, struct varlena * b)
|
||||
{
|
||||
do
|
||||
{
|
||||
res = (int) (*ap++ - *bp++);
|
||||
res = (int) *ap++ - (int) *bp++;
|
||||
len--;
|
||||
} while (res == 0 && len != 0);
|
||||
}
|
||||
@@ -195,7 +257,7 @@ bttextcmp(struct varlena * a, struct varlena * b)
|
||||
#endif
|
||||
|
||||
if (res != 0 || VARSIZE(a) == VARSIZE(b))
|
||||
return res;
|
||||
PG_RETURN_INT32(res);
|
||||
|
||||
/*
|
||||
* The two strings are the same in the first len bytes, and they are
|
||||
@@ -203,13 +265,7 @@ bttextcmp(struct varlena * a, struct varlena * b)
|
||||
*/
|
||||
|
||||
if (VARSIZE(a) < VARSIZE(b))
|
||||
return -1;
|
||||
PG_RETURN_INT32(-1);
|
||||
else
|
||||
return 1;
|
||||
}
|
||||
|
||||
int32
|
||||
btboolcmp(bool a, bool b)
|
||||
{
|
||||
return (int32) ((uint8) a - (uint8) b);
|
||||
PG_RETURN_INT32(1);
|
||||
}
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
/*-------------------------------------------------------------------------
|
||||
*
|
||||
* xid.c
|
||||
* POSTGRES transaction identifier code.
|
||||
* POSTGRES transaction identifier type.
|
||||
*
|
||||
* Portions Copyright (c) 1996-2000, PostgreSQL, Inc
|
||||
* Portions Copyright (c) 1994, Regents of the University of California
|
||||
*
|
||||
* $Id: xid.c,v 1.27 2000/01/26 05:56:04 momjian Exp $
|
||||
* $Id: xid.c,v 1.28 2000/06/05 07:28:38 tgl Exp $
|
||||
*
|
||||
* OLD COMMENTS
|
||||
* XXX WARNING
|
||||
@@ -19,33 +19,42 @@
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
|
||||
#include "postgres.h"
|
||||
|
||||
#include "access/xact.h"
|
||||
|
||||
/*
|
||||
* TransactionId is typedef'd as uint32, so...
|
||||
*/
|
||||
#define PG_GETARG_TRANSACTIONID(n) PG_GETARG_UINT32(n)
|
||||
#define PG_RETURN_TRANSACTIONID(x) PG_RETURN_UINT32(x)
|
||||
|
||||
|
||||
extern TransactionId NullTransactionId;
|
||||
extern TransactionId DisabledTransactionId;
|
||||
extern TransactionId AmiTransactionId;
|
||||
extern TransactionId FirstTransactionId;
|
||||
|
||||
/* XXX name for catalogs */
|
||||
TransactionId
|
||||
xidin(char *representation)
|
||||
Datum
|
||||
xidin(PG_FUNCTION_ARGS)
|
||||
{
|
||||
return atol(representation);
|
||||
char *representation = PG_GETARG_CSTRING(0);
|
||||
|
||||
PG_RETURN_TRANSACTIONID((TransactionId) atol(representation));
|
||||
}
|
||||
|
||||
/* XXX name for catalogs */
|
||||
char *
|
||||
xidout(TransactionId transactionId)
|
||||
Datum
|
||||
xidout(PG_FUNCTION_ARGS)
|
||||
{
|
||||
TransactionId transactionId = PG_GETARG_TRANSACTIONID(0);
|
||||
/* maximum 32 bit unsigned integer representation takes 10 chars */
|
||||
char *representation = palloc(11);
|
||||
|
||||
snprintf(representation, 11, "%u", transactionId);
|
||||
|
||||
return representation;
|
||||
snprintf(representation, 11, "%lu", (unsigned long) transactionId);
|
||||
|
||||
PG_RETURN_CSTRING(representation);
|
||||
}
|
||||
|
||||
/* ----------------------------------------------------------------
|
||||
@@ -57,14 +66,15 @@ xidout(TransactionId transactionId)
|
||||
* xideq - returns 1, iff xid1 == xid2
|
||||
* 0 else;
|
||||
*/
|
||||
bool
|
||||
xideq(TransactionId xid1, TransactionId xid2)
|
||||
Datum
|
||||
xideq(PG_FUNCTION_ARGS)
|
||||
{
|
||||
return (bool) (xid1 == xid2);
|
||||
TransactionId xid1 = PG_GETARG_TRANSACTIONID(0);
|
||||
TransactionId xid2 = PG_GETARG_TRANSACTIONID(1);
|
||||
|
||||
PG_RETURN_BOOL(xid1 == xid2);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* ----------------------------------------------------------------
|
||||
* TransactionIdAdd
|
||||
* ----------------------------------------------------------------
|
||||
@@ -73,5 +83,4 @@ void
|
||||
TransactionIdAdd(TransactionId *xid, int value)
|
||||
{
|
||||
*xid += value;
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
* Portions Copyright (c) 1994, Regents of the University of California
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $Header: /cvsroot/pgsql/src/backend/bootstrap/bootstrap.c,v 1.84 2000/05/31 00:28:14 petere Exp $
|
||||
* $Header: /cvsroot/pgsql/src/backend/bootstrap/bootstrap.c,v 1.85 2000/06/05 07:28:40 tgl Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@@ -38,7 +38,7 @@
|
||||
#include "utils/lsyscache.h"
|
||||
#include "utils/portal.h"
|
||||
|
||||
#define ALLOC(t, c) (t *)calloc((unsigned)(c), sizeof(t))
|
||||
#define ALLOC(t, c) ((t *) calloc((unsigned)(c), sizeof(t)))
|
||||
|
||||
extern void BaseInit(void);
|
||||
extern void StartupXLOG(void);
|
||||
@@ -112,7 +112,7 @@ static struct typinfo Procid[] = {
|
||||
{"int4", INT4OID, 0, 4, F_INT4IN, F_INT4OUT},
|
||||
{"regproc", REGPROCOID, 0, 4, F_REGPROCIN, F_REGPROCOUT},
|
||||
{"text", TEXTOID, 0, -1, F_TEXTIN, F_TEXTOUT},
|
||||
{"oid", OIDOID, 0, 4, F_INT4IN, F_INT4OUT},
|
||||
{"oid", OIDOID, 0, 4, F_OIDIN, F_OIDOUT},
|
||||
{"tid", TIDOID, 0, 6, F_TIDIN, F_TIDOUT},
|
||||
{"xid", XIDOID, 0, 4, F_XIDIN, F_XIDOUT},
|
||||
{"cid", CIDOID, 0, 4, F_CIDIN, F_CIDOUT},
|
||||
|
||||
@@ -772,7 +772,7 @@ CommentOperator(char *opername, List *arguments, char *comment)
|
||||
/*** Get the procedure associated with the operator ***/
|
||||
|
||||
data = (Form_pg_operator) GETSTRUCT(optuple);
|
||||
oid = regproctooid(data->oprcode);
|
||||
oid = RegprocToOid(data->oprcode);
|
||||
if (oid == InvalidOid)
|
||||
elog(ERROR, "operator '%s' does not have an underlying function", opername);
|
||||
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $Header: /cvsroot/pgsql/src/backend/commands/copy.c,v 1.110 2000/06/02 15:57:18 momjian Exp $
|
||||
* $Header: /cvsroot/pgsql/src/backend/commands/copy.c,v 1.111 2000/06/05 07:28:42 tgl Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@@ -473,7 +473,9 @@ CopyTo(Relation rel, bool binary, bool oids, FILE *fp, char *delim, char *null_p
|
||||
|
||||
if (oids && !binary)
|
||||
{
|
||||
CopySendString(oidout(tuple->t_data->t_oid), fp);
|
||||
CopySendString(DatumGetCString(DirectFunctionCall1(oidout,
|
||||
ObjectIdGetDatum(tuple->t_data->t_oid))),
|
||||
fp);
|
||||
CopySendChar(delim[0], fp);
|
||||
}
|
||||
|
||||
@@ -782,7 +784,8 @@ CopyFrom(Relation rel, bool binary, bool oids, FILE *fp, char *delim, char *null
|
||||
done = 1;
|
||||
else
|
||||
{
|
||||
loaded_oid = oidin(string);
|
||||
loaded_oid = DatumGetObjectId(DirectFunctionCall1(oidin,
|
||||
CStringGetDatum(string)));
|
||||
if (loaded_oid == InvalidOid)
|
||||
elog(ERROR, "COPY TEXT: Invalid Oid");
|
||||
}
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $Header: /cvsroot/pgsql/src/backend/parser/parse_expr.c,v 1.79 2000/05/30 00:49:50 momjian Exp $
|
||||
* $Header: /cvsroot/pgsql/src/backend/parser/parse_expr.c,v 1.80 2000/06/05 07:28:43 tgl Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@@ -892,7 +892,8 @@ parser_typecast_constant(Value *expr, TypeName *typename)
|
||||
{
|
||||
case T_Integer:
|
||||
string_palloced = true;
|
||||
const_string = int4out(expr->val.ival);
|
||||
const_string = DatumGetCString(DirectFunctionCall1(int4out,
|
||||
Int32GetDatum(expr->val.ival)));
|
||||
break;
|
||||
case T_Float:
|
||||
case T_String:
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $Header: /cvsroot/pgsql/src/backend/storage/large_object/inv_api.c,v 1.68 2000/05/28 17:56:03 tgl Exp $
|
||||
* $Header: /cvsroot/pgsql/src/backend/storage/large_object/inv_api.c,v 1.69 2000/06/05 07:28:45 tgl Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@@ -174,7 +174,8 @@ inv_create(int flags)
|
||||
if (!RelationIsValid(indr))
|
||||
{
|
||||
elog(ERROR, "cannot create index for large obj on %s under inversion",
|
||||
smgrout(DEFAULT_SMGR));
|
||||
DatumGetCString(DirectFunctionCall1(smgrout,
|
||||
Int16GetDatum(DEFAULT_SMGR))));
|
||||
}
|
||||
|
||||
retval = (LargeObjectDesc *) palloc(sizeof(LargeObjectDesc));
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $Header: /cvsroot/pgsql/src/backend/storage/smgr/smgr.c,v 1.35 2000/04/12 17:15:42 momjian Exp $
|
||||
* $Header: /cvsroot/pgsql/src/backend/storage/smgr/smgr.c,v 1.36 2000/06/05 07:28:47 tgl Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@@ -105,7 +105,9 @@ smgrinit()
|
||||
if (smgrsw[i].smgr_init)
|
||||
{
|
||||
if ((*(smgrsw[i].smgr_init)) () == SM_FAIL)
|
||||
elog(FATAL, "initialization failed on %s", smgrout(i));
|
||||
elog(FATAL, "initialization failed on %s",
|
||||
DatumGetCString(DirectFunctionCall1(smgrout,
|
||||
Int16GetDatum(i))));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -125,7 +127,9 @@ smgrshutdown(int dummy)
|
||||
if (smgrsw[i].smgr_shutdown)
|
||||
{
|
||||
if ((*(smgrsw[i].smgr_shutdown)) () == SM_FAIL)
|
||||
elog(FATAL, "shutdown failed on %s", smgrout(i));
|
||||
elog(FATAL, "shutdown failed on %s",
|
||||
DatumGetCString(DirectFunctionCall1(smgrout,
|
||||
Int16GetDatum(i))));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -445,7 +449,9 @@ smgrcommit()
|
||||
if (smgrsw[i].smgr_commit)
|
||||
{
|
||||
if ((*(smgrsw[i].smgr_commit)) () == SM_FAIL)
|
||||
elog(FATAL, "transaction commit failed on %s", smgrout(i));
|
||||
elog(FATAL, "transaction commit failed on %s",
|
||||
DatumGetCString(DirectFunctionCall1(smgrout,
|
||||
Int16GetDatum(i))));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -462,7 +468,9 @@ smgrabort()
|
||||
if (smgrsw[i].smgr_abort)
|
||||
{
|
||||
if ((*(smgrsw[i].smgr_abort)) () == SM_FAIL)
|
||||
elog(FATAL, "transaction abort failed on %s", smgrout(i));
|
||||
elog(FATAL, "transaction abort failed on %s",
|
||||
DatumGetCString(DirectFunctionCall1(smgrout,
|
||||
Int16GetDatum(i))));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $Header: /cvsroot/pgsql/src/backend/storage/smgr/smgrtype.c,v 1.16 2000/01/26 05:57:05 momjian Exp $
|
||||
* $Header: /cvsroot/pgsql/src/backend/storage/smgr/smgrtype.c,v 1.17 2000/06/05 07:28:47 tgl Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@@ -37,45 +37,48 @@ static smgrid StorageManager[] = {
|
||||
|
||||
static int NStorageManagers = lengthof(StorageManager);
|
||||
|
||||
int2
|
||||
smgrin(char *s)
|
||||
Datum
|
||||
smgrin(PG_FUNCTION_ARGS)
|
||||
{
|
||||
int i;
|
||||
char *s = PG_GETARG_CSTRING(0);
|
||||
int16 i;
|
||||
|
||||
for (i = 0; i < NStorageManagers; i++)
|
||||
{
|
||||
if (strcmp(s, StorageManager[i].smgr_name) == 0)
|
||||
return (int2) i;
|
||||
PG_RETURN_INT16(i);
|
||||
}
|
||||
elog(ERROR, "smgrin: illegal storage manager name %s", s);
|
||||
return 0;
|
||||
elog(ERROR, "smgrin: unknown storage manager name '%s'", s);
|
||||
PG_RETURN_INT16(0);
|
||||
}
|
||||
|
||||
char *
|
||||
smgrout(int2 i)
|
||||
Datum
|
||||
smgrout(PG_FUNCTION_ARGS)
|
||||
{
|
||||
int16 i = PG_GETARG_INT16(0);
|
||||
char *s;
|
||||
|
||||
if (i >= NStorageManagers || i < 0)
|
||||
elog(ERROR, "Illegal storage manager id %d", i);
|
||||
|
||||
s = (char *) palloc(strlen(StorageManager[i].smgr_name) + 1);
|
||||
strcpy(s, StorageManager[i].smgr_name);
|
||||
return s;
|
||||
s = pstrdup(StorageManager[i].smgr_name);
|
||||
PG_RETURN_CSTRING(s);
|
||||
}
|
||||
|
||||
bool
|
||||
smgreq(int2 a, int2 b)
|
||||
Datum
|
||||
smgreq(PG_FUNCTION_ARGS)
|
||||
{
|
||||
if (a == b)
|
||||
return true;
|
||||
return false;
|
||||
int16 a = PG_GETARG_INT16(0);
|
||||
int16 b = PG_GETARG_INT16(1);
|
||||
|
||||
PG_RETURN_BOOL(a == b);
|
||||
}
|
||||
|
||||
bool
|
||||
smgrne(int2 a, int2 b)
|
||||
Datum
|
||||
smgrne(PG_FUNCTION_ARGS)
|
||||
{
|
||||
if (a == b)
|
||||
return false;
|
||||
return true;
|
||||
int16 a = PG_GETARG_INT16(0);
|
||||
int16 b = PG_GETARG_INT16(1);
|
||||
|
||||
PG_RETURN_BOOL(a != b);
|
||||
}
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $Header: /cvsroot/pgsql/src/backend/tcop/fastpath.c,v 1.40 2000/05/30 07:09:23 tgl Exp $
|
||||
* $Header: /cvsroot/pgsql/src/backend/tcop/fastpath.c,v 1.41 2000/06/05 07:28:49 tgl Exp $
|
||||
*
|
||||
* NOTES
|
||||
* This cruft is the server side of PQfn.
|
||||
@@ -164,7 +164,7 @@ valid_fp_info(Oid func_id, struct fp_info * fip)
|
||||
Assert(fip != (struct fp_info *) NULL);
|
||||
|
||||
return (OidIsValid(fip->funcid) &&
|
||||
oideq(func_id, fip->funcid) &&
|
||||
func_id == fip->funcid &&
|
||||
TransactionIdIsCurrentTransactionId(fip->xid) &&
|
||||
CommandIdIsCurrentCommandId(fip->cid));
|
||||
}
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $Header: /cvsroot/pgsql/src/backend/utils/adt/acl.c,v 1.45 2000/04/12 17:15:47 momjian Exp $
|
||||
* $Header: /cvsroot/pgsql/src/backend/utils/adt/acl.c,v 1.46 2000/06/05 07:28:51 tgl Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@@ -21,6 +21,7 @@
|
||||
#include "catalog/pg_type.h"
|
||||
#include "lib/stringinfo.h"
|
||||
#include "utils/acl.h"
|
||||
#include "utils/builtins.h"
|
||||
#include "utils/memutils.h"
|
||||
#include "utils/syscache.h"
|
||||
|
||||
@@ -268,7 +269,6 @@ aclitemout(AclItem *aip)
|
||||
static AclItem default_aclitem = {ACL_ID_WORLD,
|
||||
ACL_IDTYPE_WORLD,
|
||||
ACL_WORLD_DEFAULT};
|
||||
extern char *int2out();
|
||||
char *tmpname;
|
||||
|
||||
if (!aip)
|
||||
@@ -287,20 +287,11 @@ aclitemout(AclItem *aip)
|
||||
0, 0, 0);
|
||||
if (!HeapTupleIsValid(htup))
|
||||
{
|
||||
char *tmp = int2out(aip->ai_id);
|
||||
|
||||
#ifdef NOT_USED
|
||||
|
||||
When this elog(NOTICE) goes to the libpq client,
|
||||
it crashes the
|
||||
client because the NOTICE protocol is coming right in the middle
|
||||
of a request for a field value.We skip the NOTICE for now.
|
||||
|
||||
elog(NOTICE, "aclitemout: usesysid %d not found",
|
||||
aip->ai_id);
|
||||
|
||||
#endif
|
||||
/* Generate numeric UID if we don't find an entry */
|
||||
char *tmp;
|
||||
|
||||
tmp = DatumGetCString(DirectFunctionCall1(int4out,
|
||||
Int32GetDatum((int32) aip->ai_id)));
|
||||
strcat(p, tmp);
|
||||
pfree(tmp);
|
||||
}
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $Header: /cvsroot/pgsql/src/backend/utils/adt/bool.c,v 1.22 2000/02/10 19:51:39 momjian Exp $
|
||||
* $Header: /cvsroot/pgsql/src/backend/utils/adt/bool.c,v 1.23 2000/06/05 07:28:51 tgl Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@@ -29,43 +29,45 @@
|
||||
*
|
||||
* In the switch statement, check the most-used possibilities first.
|
||||
*/
|
||||
bool
|
||||
boolin(char *b)
|
||||
Datum
|
||||
boolin(PG_FUNCTION_ARGS)
|
||||
{
|
||||
char *b = PG_GETARG_CSTRING(0);
|
||||
|
||||
switch (*b)
|
||||
{
|
||||
case 't':
|
||||
case 'T':
|
||||
if (strncasecmp(b, "true", strlen(b)) == 0)
|
||||
return TRUE;
|
||||
PG_RETURN_BOOL(true);
|
||||
break;
|
||||
|
||||
case 'f':
|
||||
case 'F':
|
||||
if (strncasecmp(b, "false", strlen(b)) == 0)
|
||||
return FALSE;
|
||||
PG_RETURN_BOOL(false);
|
||||
break;
|
||||
|
||||
case 'y':
|
||||
case 'Y':
|
||||
if (strncasecmp(b, "yes", strlen(b)) == 0)
|
||||
return TRUE;
|
||||
PG_RETURN_BOOL(true);
|
||||
break;
|
||||
|
||||
case '1':
|
||||
if (strncasecmp(b, "1", strlen(b)) == 0)
|
||||
return TRUE;
|
||||
PG_RETURN_BOOL(true);
|
||||
break;
|
||||
|
||||
case 'n':
|
||||
case 'N':
|
||||
if (strncasecmp(b, "no", strlen(b)) == 0)
|
||||
return FALSE;
|
||||
PG_RETURN_BOOL(false);
|
||||
break;
|
||||
|
||||
case '0':
|
||||
if (strncasecmp(b, "0", strlen(b)) == 0)
|
||||
return FALSE;
|
||||
PG_RETURN_BOOL(false);
|
||||
break;
|
||||
|
||||
default:
|
||||
@@ -73,72 +75,143 @@ boolin(char *b)
|
||||
}
|
||||
|
||||
elog(ERROR, "Bad boolean external representation '%s'", b);
|
||||
|
||||
/* not reached */
|
||||
return FALSE;
|
||||
} /* boolin() */
|
||||
PG_RETURN_BOOL(false);
|
||||
}
|
||||
|
||||
/*
|
||||
* boolout - converts 1 or 0 to "t" or "f"
|
||||
*/
|
||||
char *
|
||||
boolout(bool b)
|
||||
Datum
|
||||
boolout(PG_FUNCTION_ARGS)
|
||||
{
|
||||
bool b = PG_GETARG_BOOL(0);
|
||||
char *result = (char *) palloc(2);
|
||||
|
||||
*result = (b) ? 't' : 'f';
|
||||
result[0] = (b) ? 't' : 'f';
|
||||
result[1] = '\0';
|
||||
return result;
|
||||
} /* boolout() */
|
||||
PG_RETURN_CSTRING(result);
|
||||
}
|
||||
|
||||
|
||||
/*****************************************************************************
|
||||
* PUBLIC ROUTINES *
|
||||
*****************************************************************************/
|
||||
|
||||
bool
|
||||
booleq(bool arg1, bool arg2)
|
||||
Datum
|
||||
booleq(PG_FUNCTION_ARGS)
|
||||
{
|
||||
return arg1 == arg2;
|
||||
bool arg1 = PG_GETARG_BOOL(0);
|
||||
bool arg2 = PG_GETARG_BOOL(1);
|
||||
|
||||
PG_RETURN_BOOL(arg1 == arg2);
|
||||
}
|
||||
|
||||
bool
|
||||
boolne(bool arg1, bool arg2)
|
||||
Datum
|
||||
boolne(PG_FUNCTION_ARGS)
|
||||
{
|
||||
return arg1 != arg2;
|
||||
bool arg1 = PG_GETARG_BOOL(0);
|
||||
bool arg2 = PG_GETARG_BOOL(1);
|
||||
|
||||
PG_RETURN_BOOL(arg1 != arg2);
|
||||
}
|
||||
|
||||
bool
|
||||
boollt(bool arg1, bool arg2)
|
||||
Datum
|
||||
boollt(PG_FUNCTION_ARGS)
|
||||
{
|
||||
return arg1 < arg2;
|
||||
bool arg1 = PG_GETARG_BOOL(0);
|
||||
bool arg2 = PG_GETARG_BOOL(1);
|
||||
|
||||
PG_RETURN_BOOL(arg1 < arg2);
|
||||
}
|
||||
|
||||
bool
|
||||
boolgt(bool arg1, bool arg2)
|
||||
Datum
|
||||
boolgt(PG_FUNCTION_ARGS)
|
||||
{
|
||||
return arg1 > arg2;
|
||||
bool arg1 = PG_GETARG_BOOL(0);
|
||||
bool arg2 = PG_GETARG_BOOL(1);
|
||||
|
||||
PG_RETURN_BOOL(arg1 > arg2);
|
||||
}
|
||||
|
||||
bool
|
||||
boolle(bool arg1, bool arg2)
|
||||
Datum
|
||||
boolle(PG_FUNCTION_ARGS)
|
||||
{
|
||||
return arg1 <= arg2;
|
||||
bool arg1 = PG_GETARG_BOOL(0);
|
||||
bool arg2 = PG_GETARG_BOOL(1);
|
||||
|
||||
PG_RETURN_BOOL(arg1 <= arg2);
|
||||
}
|
||||
|
||||
bool
|
||||
boolge(bool arg1, bool arg2)
|
||||
Datum
|
||||
boolge(PG_FUNCTION_ARGS)
|
||||
{
|
||||
return arg1 >= arg2;
|
||||
bool arg1 = PG_GETARG_BOOL(0);
|
||||
bool arg2 = PG_GETARG_BOOL(1);
|
||||
|
||||
PG_RETURN_BOOL(arg1 >= arg2);
|
||||
}
|
||||
|
||||
bool
|
||||
istrue(bool arg1)
|
||||
{
|
||||
return arg1 == TRUE;
|
||||
} /* istrue() */
|
||||
/*
|
||||
* Per SQL92, istrue() and isfalse() should return false, not NULL,
|
||||
* when presented a NULL input (since NULL is our implementation of
|
||||
* UNKNOWN). Conversely isnottrue() and isnotfalse() should return true.
|
||||
* Therefore, these routines are all declared not-strict in pg_proc
|
||||
* and must do their own checking for null inputs.
|
||||
*
|
||||
* Note we don't need isunknown() and isnotunknown() functions, since
|
||||
* nullvalue() and nonnullvalue() will serve.
|
||||
*/
|
||||
|
||||
bool
|
||||
isfalse(bool arg1)
|
||||
Datum
|
||||
istrue(PG_FUNCTION_ARGS)
|
||||
{
|
||||
return arg1 != TRUE;
|
||||
} /* isfalse() */
|
||||
bool b;
|
||||
|
||||
if (PG_ARGISNULL(0))
|
||||
PG_RETURN_BOOL(false);
|
||||
|
||||
b = PG_GETARG_BOOL(0);
|
||||
|
||||
PG_RETURN_BOOL(b);
|
||||
}
|
||||
|
||||
Datum
|
||||
isfalse(PG_FUNCTION_ARGS)
|
||||
{
|
||||
bool b;
|
||||
|
||||
if (PG_ARGISNULL(0))
|
||||
PG_RETURN_BOOL(false);
|
||||
|
||||
b = PG_GETARG_BOOL(0);
|
||||
|
||||
PG_RETURN_BOOL(! b);
|
||||
}
|
||||
|
||||
Datum
|
||||
isnottrue(PG_FUNCTION_ARGS)
|
||||
{
|
||||
bool b;
|
||||
|
||||
if (PG_ARGISNULL(0))
|
||||
PG_RETURN_BOOL(true);
|
||||
|
||||
b = PG_GETARG_BOOL(0);
|
||||
|
||||
PG_RETURN_BOOL(! b);
|
||||
}
|
||||
|
||||
Datum
|
||||
isnotfalse(PG_FUNCTION_ARGS)
|
||||
{
|
||||
bool b;
|
||||
|
||||
if (PG_ARGISNULL(0))
|
||||
PG_RETURN_BOOL(true);
|
||||
|
||||
b = PG_GETARG_BOOL(0);
|
||||
|
||||
PG_RETURN_BOOL(b);
|
||||
}
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
* workings can be found in the book "Software Solutions in C" by
|
||||
* Dale Schumacher, Academic Press, ISBN: 0-12-632360-7.
|
||||
*
|
||||
* $Header: /cvsroot/pgsql/src/backend/utils/adt/cash.c,v 1.36 2000/05/16 20:48:49 momjian Exp $
|
||||
* $Header: /cvsroot/pgsql/src/backend/utils/adt/cash.c,v 1.37 2000/06/05 07:28:51 tgl Exp $
|
||||
*/
|
||||
|
||||
#include <limits.h>
|
||||
@@ -35,6 +35,24 @@ static struct lconv *lconvert = NULL;
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
* Cash is a pass-by-ref SQL type, so we must pass and return pointers.
|
||||
* These macros and support routine hide the pass-by-refness.
|
||||
*/
|
||||
#define PG_GETARG_CASH(n) (* ((Cash *) DatumGetPointer(fcinfo->arg[n])))
|
||||
#define PG_RETURN_CASH(x) return CashGetDatum(x)
|
||||
|
||||
static Datum
|
||||
CashGetDatum(Cash value)
|
||||
{
|
||||
Cash *result = (Cash *) palloc(sizeof(Cash));
|
||||
|
||||
*result = value;
|
||||
return PointerGetDatum(result);
|
||||
}
|
||||
|
||||
|
||||
/* cash_in()
|
||||
* Convert a string to a cash data type.
|
||||
* Format is [$]###[,]###[.##]
|
||||
@@ -573,32 +591,30 @@ cash_div_int4(Cash *c, int4 i)
|
||||
/* cash_mul_int2()
|
||||
* Multiply cash by int2.
|
||||
*/
|
||||
Cash *
|
||||
cash_mul_int2(Cash *c, int2 s)
|
||||
Datum
|
||||
cash_mul_int2(PG_FUNCTION_ARGS)
|
||||
{
|
||||
Cash *result;
|
||||
|
||||
if (!PointerIsValid(c))
|
||||
return NULL;
|
||||
|
||||
if (!PointerIsValid(result = palloc(sizeof(Cash))))
|
||||
elog(ERROR, "Memory allocation failed, can't multiply cash");
|
||||
|
||||
*result = ((s) * (*c));
|
||||
|
||||
return result;
|
||||
} /* cash_mul_int2() */
|
||||
Cash c = PG_GETARG_CASH(0);
|
||||
int16 s = PG_GETARG_INT16(1);
|
||||
Cash result;
|
||||
|
||||
result = c * s;
|
||||
PG_RETURN_CASH(result);
|
||||
}
|
||||
|
||||
/* int2_mul_cash()
|
||||
* Multiply int2 by cash.
|
||||
*/
|
||||
Cash *
|
||||
int2_mul_cash(int2 s, Cash *c)
|
||||
Datum
|
||||
int2_mul_cash(PG_FUNCTION_ARGS)
|
||||
{
|
||||
return cash_mul_int2(c, s);
|
||||
} /* int2_mul_cash() */
|
||||
int16 s = PG_GETARG_INT16(0);
|
||||
Cash c = PG_GETARG_CASH(1);
|
||||
Cash result;
|
||||
|
||||
result = s * c;
|
||||
PG_RETURN_CASH(result);
|
||||
}
|
||||
|
||||
/* cash_div_int2()
|
||||
* Divide cash by int2.
|
||||
@@ -606,25 +622,19 @@ int2_mul_cash(int2 s, Cash *c)
|
||||
* XXX Don't know if rounding or truncating is correct behavior.
|
||||
* Round for now. - tgl 97/04/15
|
||||
*/
|
||||
Cash *
|
||||
cash_div_int2(Cash *c, int2 s)
|
||||
Datum
|
||||
cash_div_int2(PG_FUNCTION_ARGS)
|
||||
{
|
||||
Cash *result;
|
||||
|
||||
if (!PointerIsValid(c))
|
||||
return NULL;
|
||||
|
||||
if (!PointerIsValid(result = palloc(sizeof(Cash))))
|
||||
elog(ERROR, "Memory allocation failed, can't divide cash");
|
||||
Cash c = PG_GETARG_CASH(0);
|
||||
int16 s = PG_GETARG_INT16(1);
|
||||
Cash result;
|
||||
|
||||
if (s == 0)
|
||||
elog(ERROR, "cash_div: divide by 0 error");
|
||||
|
||||
*result = rint(*c / s);
|
||||
|
||||
return result;
|
||||
} /* cash_div_int2() */
|
||||
|
||||
result = rint(c / s);
|
||||
PG_RETURN_CASH(result);
|
||||
}
|
||||
|
||||
/* cashlarger()
|
||||
* Return larger of two cash values.
|
||||
|
||||
@@ -2,18 +2,19 @@
|
||||
*
|
||||
* char.c
|
||||
* Functions for the built-in type "char".
|
||||
* Functions for the built-in type "cid".
|
||||
* Functions for the built-in type "cid" (what's that doing here?)
|
||||
*
|
||||
* 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/char.c,v 1.27 2000/01/26 05:57:13 momjian Exp $
|
||||
* $Header: /cvsroot/pgsql/src/backend/utils/adt/char.c,v 1.28 2000/06/05 07:28:51 tgl Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
#include "postgres.h"
|
||||
|
||||
#include "utils/builtins.h"
|
||||
|
||||
/*****************************************************************************
|
||||
@@ -23,149 +24,194 @@
|
||||
/*
|
||||
* charin - converts "x" to 'x'
|
||||
*/
|
||||
int32
|
||||
charin(char *ch)
|
||||
Datum
|
||||
charin(PG_FUNCTION_ARGS)
|
||||
{
|
||||
if (ch == NULL)
|
||||
return (int32) '\0';
|
||||
return (int32) *ch;
|
||||
char *ch = PG_GETARG_CSTRING(0);
|
||||
|
||||
PG_RETURN_CHAR(ch[0]);
|
||||
}
|
||||
|
||||
/*
|
||||
* charout - converts 'x' to "x"
|
||||
*/
|
||||
char *
|
||||
charout(int32 ch)
|
||||
Datum
|
||||
charout(PG_FUNCTION_ARGS)
|
||||
{
|
||||
char ch = PG_GETARG_CHAR(0);
|
||||
char *result = (char *) palloc(2);
|
||||
|
||||
result[0] = (char) ch;
|
||||
result[0] = ch;
|
||||
result[1] = '\0';
|
||||
return result;
|
||||
PG_RETURN_CSTRING(result);
|
||||
}
|
||||
|
||||
/*
|
||||
* cidin - converts "..." to internal representation.
|
||||
*
|
||||
* NOTE: we must not use 'charin' because cid might be a non
|
||||
* printable character...
|
||||
*/
|
||||
int32
|
||||
cidin(char *s)
|
||||
{
|
||||
CommandId c;
|
||||
|
||||
if (s == NULL)
|
||||
c = 0;
|
||||
else
|
||||
c = atoi(s);
|
||||
|
||||
return (int32) c;
|
||||
}
|
||||
|
||||
/*
|
||||
* cidout - converts a cid to "..."
|
||||
*
|
||||
* NOTE: we must no use 'charout' because cid might be a non
|
||||
* printable character...
|
||||
*/
|
||||
char *
|
||||
cidout(int32 c)
|
||||
{
|
||||
char *result;
|
||||
CommandId c2;
|
||||
|
||||
result = palloc(12);
|
||||
c2 = (CommandId) c;
|
||||
sprintf(result, "%u", (unsigned) (c2));
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
/*****************************************************************************
|
||||
* PUBLIC ROUTINES *
|
||||
*****************************************************************************/
|
||||
|
||||
bool
|
||||
chareq(int8 arg1, int8 arg2)
|
||||
/*
|
||||
* NOTE: comparisons are done as though char is unsigned (uint8).
|
||||
* Arithmetic is done as though char is signed (int8).
|
||||
*
|
||||
* You wanted consistency?
|
||||
*/
|
||||
|
||||
Datum
|
||||
chareq(PG_FUNCTION_ARGS)
|
||||
{
|
||||
return arg1 == arg2;
|
||||
char arg1 = PG_GETARG_CHAR(0);
|
||||
char arg2 = PG_GETARG_CHAR(1);
|
||||
|
||||
PG_RETURN_BOOL(arg1 == arg2);
|
||||
}
|
||||
|
||||
bool
|
||||
charne(int8 arg1, int8 arg2)
|
||||
Datum
|
||||
charne(PG_FUNCTION_ARGS)
|
||||
{
|
||||
return arg1 != arg2;
|
||||
char arg1 = PG_GETARG_CHAR(0);
|
||||
char arg2 = PG_GETARG_CHAR(1);
|
||||
|
||||
PG_RETURN_BOOL(arg1 != arg2);
|
||||
}
|
||||
|
||||
bool
|
||||
charlt(int8 arg1, int8 arg2)
|
||||
Datum
|
||||
charlt(PG_FUNCTION_ARGS)
|
||||
{
|
||||
return (uint8) arg1 < (uint8) arg2;
|
||||
char arg1 = PG_GETARG_CHAR(0);
|
||||
char arg2 = PG_GETARG_CHAR(1);
|
||||
|
||||
PG_RETURN_BOOL((uint8) arg1 < (uint8) arg2);
|
||||
}
|
||||
|
||||
bool
|
||||
charle(int8 arg1, int8 arg2)
|
||||
Datum
|
||||
charle(PG_FUNCTION_ARGS)
|
||||
{
|
||||
return (uint8) arg1 <= (uint8) arg2;
|
||||
char arg1 = PG_GETARG_CHAR(0);
|
||||
char arg2 = PG_GETARG_CHAR(1);
|
||||
|
||||
PG_RETURN_BOOL((uint8) arg1 <= (uint8) arg2);
|
||||
}
|
||||
|
||||
bool
|
||||
chargt(int8 arg1, int8 arg2)
|
||||
Datum
|
||||
chargt(PG_FUNCTION_ARGS)
|
||||
{
|
||||
return (uint8) arg1 > (uint8) arg2;
|
||||
char arg1 = PG_GETARG_CHAR(0);
|
||||
char arg2 = PG_GETARG_CHAR(1);
|
||||
|
||||
PG_RETURN_BOOL((uint8) arg1 > (uint8) arg2);
|
||||
}
|
||||
|
||||
bool
|
||||
charge(int8 arg1, int8 arg2)
|
||||
Datum
|
||||
charge(PG_FUNCTION_ARGS)
|
||||
{
|
||||
return (uint8) arg1 >= (uint8) arg2;
|
||||
char arg1 = PG_GETARG_CHAR(0);
|
||||
char arg2 = PG_GETARG_CHAR(1);
|
||||
|
||||
PG_RETURN_BOOL((uint8) arg1 >= (uint8) arg2);
|
||||
}
|
||||
|
||||
int8
|
||||
charpl(int8 arg1, int8 arg2)
|
||||
Datum
|
||||
charpl(PG_FUNCTION_ARGS)
|
||||
{
|
||||
return arg1 + arg2;
|
||||
char arg1 = PG_GETARG_CHAR(0);
|
||||
char arg2 = PG_GETARG_CHAR(1);
|
||||
|
||||
PG_RETURN_CHAR((int8) arg1 + (int8) arg2);
|
||||
}
|
||||
|
||||
int8
|
||||
charmi(int8 arg1, int8 arg2)
|
||||
Datum
|
||||
charmi(PG_FUNCTION_ARGS)
|
||||
{
|
||||
return arg1 - arg2;
|
||||
char arg1 = PG_GETARG_CHAR(0);
|
||||
char arg2 = PG_GETARG_CHAR(1);
|
||||
|
||||
PG_RETURN_CHAR((int8) arg1 - (int8) arg2);
|
||||
}
|
||||
|
||||
int8
|
||||
charmul(int8 arg1, int8 arg2)
|
||||
Datum
|
||||
charmul(PG_FUNCTION_ARGS)
|
||||
{
|
||||
return arg1 * arg2;
|
||||
char arg1 = PG_GETARG_CHAR(0);
|
||||
char arg2 = PG_GETARG_CHAR(1);
|
||||
|
||||
PG_RETURN_CHAR((int8) arg1 * (int8) arg2);
|
||||
}
|
||||
|
||||
int8
|
||||
chardiv(int8 arg1, int8 arg2)
|
||||
Datum
|
||||
chardiv(PG_FUNCTION_ARGS)
|
||||
{
|
||||
return arg1 / arg2;
|
||||
char arg1 = PG_GETARG_CHAR(0);
|
||||
char arg2 = PG_GETARG_CHAR(1);
|
||||
|
||||
PG_RETURN_CHAR((int8) arg1 / (int8) arg2);
|
||||
}
|
||||
|
||||
bool
|
||||
cideq(int8 arg1, int8 arg2)
|
||||
Datum
|
||||
text_char(PG_FUNCTION_ARGS)
|
||||
{
|
||||
return arg1 == arg2;
|
||||
text *arg1 = PG_GETARG_TEXT_P(0);
|
||||
|
||||
/* XXX what if arg1 has length zero? */
|
||||
PG_RETURN_CHAR(*(VARDATA(arg1)));
|
||||
}
|
||||
|
||||
int8
|
||||
text_char(text *arg1)
|
||||
Datum
|
||||
char_text(PG_FUNCTION_ARGS)
|
||||
{
|
||||
return ((int8) *(VARDATA(arg1)));
|
||||
}
|
||||
char arg1 = PG_GETARG_CHAR(0);
|
||||
text *result = palloc(VARHDRSZ + 1);
|
||||
|
||||
text *
|
||||
char_text(int8 arg1)
|
||||
{
|
||||
text *result;
|
||||
|
||||
result = palloc(VARHDRSZ + 1);
|
||||
VARSIZE(result) = VARHDRSZ + 1;
|
||||
*(VARDATA(result)) = arg1;
|
||||
|
||||
return result;
|
||||
PG_RETURN_TEXT_P(result);
|
||||
}
|
||||
|
||||
|
||||
/*****************************************************************************
|
||||
* USER I/O ROUTINES *
|
||||
*****************************************************************************/
|
||||
|
||||
/*
|
||||
* cidin - converts CommandId to internal representation.
|
||||
*/
|
||||
Datum
|
||||
cidin(PG_FUNCTION_ARGS)
|
||||
{
|
||||
char *s = PG_GETARG_CSTRING(0);
|
||||
CommandId c;
|
||||
|
||||
c = atoi(s);
|
||||
|
||||
/* XXX assume that CommandId is 32 bits... */
|
||||
PG_RETURN_INT32((int32) c);
|
||||
}
|
||||
|
||||
/*
|
||||
* cidout - converts a cid to external representation.
|
||||
*/
|
||||
Datum
|
||||
cidout(PG_FUNCTION_ARGS)
|
||||
{
|
||||
/* XXX assume that CommandId is 32 bits... */
|
||||
CommandId c = PG_GETARG_INT32(0);
|
||||
char *result = (char *) palloc(16);
|
||||
|
||||
sprintf(result, "%u", (unsigned int) c);
|
||||
PG_RETURN_CSTRING(result);
|
||||
}
|
||||
|
||||
/*****************************************************************************
|
||||
* PUBLIC ROUTINES *
|
||||
*****************************************************************************/
|
||||
|
||||
Datum
|
||||
cideq(PG_FUNCTION_ARGS)
|
||||
{
|
||||
/* XXX assume that CommandId is 32 bits... */
|
||||
CommandId arg1 = PG_GETARG_INT32(0);
|
||||
CommandId arg2 = PG_GETARG_INT32(1);
|
||||
|
||||
PG_RETURN_BOOL(arg1 == arg2);
|
||||
}
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $Header: /cvsroot/pgsql/src/backend/utils/adt/float.c,v 1.57 2000/04/12 17:15:49 momjian Exp $
|
||||
* $Header: /cvsroot/pgsql/src/backend/utils/adt/float.c,v 1.58 2000/06/05 07:28:51 tgl Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@@ -122,25 +122,6 @@ extern double rint(double x);
|
||||
#define FLOAT8_MAX DBL_MAX
|
||||
#define FLOAT8_MIN DBL_MIN
|
||||
|
||||
/*
|
||||
* if FLOAT8_MIN and FLOAT8_MAX are the limits of the range a
|
||||
* double can store, then how are we ever going to wind up
|
||||
* with something stored in a double that is outside those
|
||||
* limits? (and similarly for FLOAT4_{MIN,MAX}/float.)
|
||||
* doesn't make sense to me, and it causes a
|
||||
* floating point exception on linuxalpha, so UNSAFE_FLOATS
|
||||
* it is.
|
||||
* (maybe someone wanted to allow for values other than DBL_MIN/
|
||||
* DBL_MAX for FLOAT8_MIN/FLOAT8_MAX?)
|
||||
* --djm 12/12/96
|
||||
* according to Richard Henderson this is a known bug in gcc on
|
||||
* the Alpha. might as well leave the workaround in
|
||||
* until the distributions are updated.
|
||||
* --djm 12/16/96
|
||||
*/
|
||||
#if ( defined(linux) && defined(__alpha__) ) && !defined(UNSAFE_FLOATS)
|
||||
#define UNSAFE_FLOATS
|
||||
#endif
|
||||
|
||||
/*
|
||||
check to see if a float4 val is outside of
|
||||
@@ -844,19 +825,17 @@ dtoi4(float64 num)
|
||||
/*
|
||||
* dtoi2 - converts a float8 number to an int2 number
|
||||
*/
|
||||
int16
|
||||
dtoi2(float64 num)
|
||||
Datum
|
||||
dtoi2(PG_FUNCTION_ARGS)
|
||||
{
|
||||
float8 num = PG_GETARG_FLOAT8(0);
|
||||
int16 result;
|
||||
|
||||
if (!num)
|
||||
return 0; /* fmgr will return NULL anyway */
|
||||
|
||||
if ((*num < SHRT_MIN) || (*num > SHRT_MAX))
|
||||
if ((num < SHRT_MIN) || (num > SHRT_MAX))
|
||||
elog(ERROR, "dtoi2: integer out of range");
|
||||
|
||||
result = rint(*num);
|
||||
return result;
|
||||
result = (int16) rint(num);
|
||||
PG_RETURN_INT16(result);
|
||||
}
|
||||
|
||||
|
||||
@@ -878,15 +857,14 @@ i4tod(int32 num)
|
||||
/*
|
||||
* i2tod - converts an int2 number to a float8 number
|
||||
*/
|
||||
float64
|
||||
i2tod(int16 num)
|
||||
Datum
|
||||
i2tod(PG_FUNCTION_ARGS)
|
||||
{
|
||||
float64 result;
|
||||
int16 num = PG_GETARG_INT16(0);
|
||||
float8 result;
|
||||
|
||||
result = (float64) palloc(sizeof(float64data));
|
||||
|
||||
*result = num;
|
||||
return result;
|
||||
result = num;
|
||||
PG_RETURN_FLOAT8(result);
|
||||
}
|
||||
|
||||
|
||||
@@ -910,21 +888,19 @@ ftoi4(float32 num)
|
||||
|
||||
|
||||
/*
|
||||
* ftoi2 - converts a float8 number to an int2 number
|
||||
* ftoi2 - converts a float4 number to an int2 number
|
||||
*/
|
||||
int16
|
||||
ftoi2(float32 num)
|
||||
Datum
|
||||
ftoi2(PG_FUNCTION_ARGS)
|
||||
{
|
||||
float4 num = PG_GETARG_FLOAT4(0);
|
||||
int16 result;
|
||||
|
||||
if (!num)
|
||||
return 0; /* fmgr will return NULL anyway */
|
||||
|
||||
if ((*num < SHRT_MIN) || (*num > SHRT_MAX))
|
||||
if ((num < SHRT_MIN) || (num > SHRT_MAX))
|
||||
elog(ERROR, "ftoi2: integer out of range");
|
||||
|
||||
result = rint(*num);
|
||||
return result;
|
||||
result = (int16) rint(num);
|
||||
PG_RETURN_INT16(result);
|
||||
}
|
||||
|
||||
|
||||
@@ -944,17 +920,16 @@ i4tof(int32 num)
|
||||
|
||||
|
||||
/*
|
||||
* i2tof - converts an int2 number to a float8 number
|
||||
* i2tof - converts an int2 number to a float4 number
|
||||
*/
|
||||
float32
|
||||
i2tof(int16 num)
|
||||
Datum
|
||||
i2tof(PG_FUNCTION_ARGS)
|
||||
{
|
||||
float32 result;
|
||||
int16 num = PG_GETARG_INT16(0);
|
||||
float4 result;
|
||||
|
||||
result = (float32) palloc(sizeof(float32data));
|
||||
|
||||
*result = num;
|
||||
return result;
|
||||
result = num;
|
||||
PG_RETURN_FLOAT4(result);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/* -----------------------------------------------------------------------
|
||||
* formatting.c
|
||||
*
|
||||
* $Header: /cvsroot/pgsql/src/backend/utils/adt/formatting.c,v 1.8 2000/04/12 17:15:49 momjian Exp $
|
||||
* $Header: /cvsroot/pgsql/src/backend/utils/adt/formatting.c,v 1.9 2000/06/05 07:28:51 tgl Exp $
|
||||
*
|
||||
*
|
||||
* Portions Copyright (c) 1999-2000, PostgreSQL, Inc
|
||||
@@ -4048,11 +4048,15 @@ int4_to_char(int32 value, text *fmt)
|
||||
{
|
||||
if (IS_MULTI(&Num))
|
||||
{
|
||||
orgnum = int4out(int4mul(value, (int32) pow((double) 10, (double) Num.multi)));
|
||||
orgnum = DatumGetCString(DirectFunctionCall1(int4out,
|
||||
Int32GetDatum(value * ((int32) pow((double) 10, (double) Num.multi)))));
|
||||
Num.pre += Num.multi;
|
||||
}
|
||||
else
|
||||
orgnum = int4out(value);
|
||||
{
|
||||
orgnum = DatumGetCString(DirectFunctionCall1(int4out,
|
||||
Int32GetDatum(value)));
|
||||
}
|
||||
len = strlen(orgnum);
|
||||
|
||||
if (*orgnum == '-')
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $Header: /cvsroot/pgsql/src/backend/utils/adt/geo_selfuncs.c,v 1.15 2000/05/13 06:04:46 tgl Exp $
|
||||
* $Header: /cvsroot/pgsql/src/backend/utils/adt/geo_selfuncs.c,v 1.16 2000/06/05 07:28:52 tgl Exp $
|
||||
*
|
||||
* XXX These are totally bogus. Perhaps someone will make them do
|
||||
* something reasonable, someday.
|
||||
@@ -44,32 +44,16 @@
|
||||
* Selectivity for operators that depend on area, such as "overlap".
|
||||
*/
|
||||
|
||||
float64
|
||||
areasel(Oid opid,
|
||||
Oid relid,
|
||||
AttrNumber attno,
|
||||
Datum value,
|
||||
int32 flag)
|
||||
Datum
|
||||
areasel(PG_FUNCTION_ARGS)
|
||||
{
|
||||
float64 result;
|
||||
|
||||
result = (float64) palloc(sizeof(float64data));
|
||||
*result = 0.02;
|
||||
return result;
|
||||
PG_RETURN_FLOAT8(0.02);
|
||||
}
|
||||
|
||||
float64
|
||||
areajoinsel(Oid opid,
|
||||
Oid relid1,
|
||||
AttrNumber attno1,
|
||||
Oid relid2,
|
||||
AttrNumber attno2)
|
||||
Datum
|
||||
areajoinsel(PG_FUNCTION_ARGS)
|
||||
{
|
||||
float64 result;
|
||||
|
||||
result = (float64) palloc(sizeof(float64data));
|
||||
*result = 0.02;
|
||||
return result;
|
||||
PG_RETURN_FLOAT8(0.02);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -79,32 +63,16 @@ areajoinsel(Oid opid,
|
||||
* a given box?
|
||||
*/
|
||||
|
||||
float64
|
||||
positionsel(Oid opid,
|
||||
Oid relid,
|
||||
AttrNumber attno,
|
||||
Datum value,
|
||||
int32 flag)
|
||||
Datum
|
||||
positionsel(PG_FUNCTION_ARGS)
|
||||
{
|
||||
float64 result;
|
||||
|
||||
result = (float64) palloc(sizeof(float64data));
|
||||
*result = 0.1;
|
||||
return result;
|
||||
PG_RETURN_FLOAT8(0.1);
|
||||
}
|
||||
|
||||
float64
|
||||
positionjoinsel(Oid opid,
|
||||
Oid relid1,
|
||||
AttrNumber attno1,
|
||||
Oid relid2,
|
||||
AttrNumber attno2)
|
||||
Datum
|
||||
positionjoinsel(PG_FUNCTION_ARGS)
|
||||
{
|
||||
float64 result;
|
||||
|
||||
result = (float64) palloc(sizeof(float64data));
|
||||
*result = 0.1;
|
||||
return result;
|
||||
PG_RETURN_FLOAT8(0.1);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -114,30 +82,14 @@ positionjoinsel(Oid opid,
|
||||
* estimate than areasel does.
|
||||
*/
|
||||
|
||||
float64
|
||||
contsel(Oid opid,
|
||||
Oid relid,
|
||||
AttrNumber attno,
|
||||
Datum value,
|
||||
int32 flag)
|
||||
Datum
|
||||
contsel(PG_FUNCTION_ARGS)
|
||||
{
|
||||
float64 result;
|
||||
|
||||
result = (float64) palloc(sizeof(float64data));
|
||||
*result = 0.01;
|
||||
return result;
|
||||
PG_RETURN_FLOAT8(0.01);
|
||||
}
|
||||
|
||||
float64
|
||||
contjoinsel(Oid opid,
|
||||
Oid relid1,
|
||||
AttrNumber attno1,
|
||||
Oid relid2,
|
||||
AttrNumber attno2)
|
||||
Datum
|
||||
contjoinsel(PG_FUNCTION_ARGS)
|
||||
{
|
||||
float64 result;
|
||||
|
||||
result = (float64) palloc(sizeof(float64data));
|
||||
*result = 0.01;
|
||||
return result;
|
||||
PG_RETURN_FLOAT8(0.01);
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -8,44 +8,39 @@
|
||||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $Header: /cvsroot/pgsql/src/backend/utils/adt/misc.c,v 1.18 2000/01/26 05:57:14 momjian Exp $
|
||||
* $Header: /cvsroot/pgsql/src/backend/utils/adt/misc.c,v 1.19 2000/06/05 07:28:52 tgl Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
#include <sys/types.h>
|
||||
#include <sys/file.h>
|
||||
#include <time.h>
|
||||
|
||||
#include "postgres.h"
|
||||
|
||||
#include "utils/builtins.h"
|
||||
|
||||
/*-------------------------------------------------------------------------
|
||||
|
||||
/*
|
||||
* Check if data is Null
|
||||
*/
|
||||
bool
|
||||
nullvalue(Datum value, bool *isNull)
|
||||
Datum
|
||||
nullvalue(PG_FUNCTION_ARGS)
|
||||
{
|
||||
if (*isNull)
|
||||
{
|
||||
*isNull = false;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
|
||||
if (PG_ARGISNULL(0))
|
||||
PG_RETURN_BOOL(true);
|
||||
PG_RETURN_BOOL(false);
|
||||
}
|
||||
|
||||
/*----------------------------------------------------------------------*
|
||||
* check if data is not Null *
|
||||
*--------------------------------------------------------------------- */
|
||||
bool
|
||||
nonnullvalue(Datum value, bool *isNull)
|
||||
/*
|
||||
* Check if data is not Null
|
||||
*/
|
||||
Datum
|
||||
nonnullvalue(PG_FUNCTION_ARGS)
|
||||
{
|
||||
if (*isNull)
|
||||
{
|
||||
*isNull = false;
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
|
||||
if (PG_ARGISNULL(0))
|
||||
PG_RETURN_BOOL(false);
|
||||
PG_RETURN_BOOL(true);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -63,13 +58,18 @@ nonnullvalue(Datum value, bool *isNull)
|
||||
|
||||
static bool random_initialized = false;
|
||||
|
||||
bool
|
||||
oidrand(Oid o, int32 X)
|
||||
Datum
|
||||
oidrand(PG_FUNCTION_ARGS)
|
||||
{
|
||||
/* XXX seems like we ought to be using the oid for something? */
|
||||
#ifdef NOT_USED
|
||||
Oid o = PG_GETARG_OID(0);
|
||||
#endif
|
||||
int32 X = PG_GETARG_INT32(1);
|
||||
bool result;
|
||||
|
||||
if (X == 0)
|
||||
return true;
|
||||
PG_RETURN_BOOL(true);
|
||||
|
||||
/*
|
||||
* We do this because the cancel key is actually a random, so we don't
|
||||
@@ -83,26 +83,29 @@ oidrand(Oid o, int32 X)
|
||||
}
|
||||
|
||||
result = (random() % X == 0);
|
||||
return result;
|
||||
PG_RETURN_BOOL(result);
|
||||
}
|
||||
|
||||
/*
|
||||
oidsrand(int32 X) -
|
||||
seeds the random number generator
|
||||
always return true
|
||||
always returns true
|
||||
*/
|
||||
bool
|
||||
oidsrand(int32 X)
|
||||
Datum
|
||||
oidsrand(PG_FUNCTION_ARGS)
|
||||
{
|
||||
int32 X = PG_GETARG_INT32(0);
|
||||
|
||||
srand(X);
|
||||
random_initialized = true;
|
||||
return true;
|
||||
PG_RETURN_BOOL(true);
|
||||
}
|
||||
|
||||
|
||||
|
||||
int32
|
||||
userfntest(int i)
|
||||
Datum
|
||||
userfntest(PG_FUNCTION_ARGS)
|
||||
{
|
||||
return i;
|
||||
int32 i = PG_GETARG_INT32(0);
|
||||
|
||||
PG_RETURN_INT32(i);
|
||||
}
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
*
|
||||
* 1998 Jan Wieck
|
||||
*
|
||||
* $Header: /cvsroot/pgsql/src/backend/utils/adt/numeric.c,v 1.27 2000/04/12 17:15:50 momjian Exp $
|
||||
* $Header: /cvsroot/pgsql/src/backend/utils/adt/numeric.c,v 1.28 2000/06/05 07:28:52 tgl Exp $
|
||||
*
|
||||
* ----------
|
||||
*/
|
||||
@@ -33,6 +33,9 @@
|
||||
* Local definitions
|
||||
* ----------
|
||||
*/
|
||||
#define PG_GETARG_NUMERIC(n) ((Numeric) DatumGetPointer(fcinfo->arg[n]))
|
||||
#define PG_RETURN_NUMERIC(x) return PointerGetDatum(x)
|
||||
|
||||
#ifndef MIN
|
||||
#define MIN(a,b) (((a)<(b)) ? (a) : (b))
|
||||
#endif
|
||||
@@ -1714,7 +1717,8 @@ int4_numeric(int32 val)
|
||||
|
||||
init_var(&result);
|
||||
|
||||
tmp = int4out(val);
|
||||
tmp = DatumGetCString(DirectFunctionCall1(int4out,
|
||||
Int32GetDatum(val)));
|
||||
set_var_from_str(tmp, &result);
|
||||
res = make_result(&result);
|
||||
|
||||
@@ -1730,7 +1734,7 @@ numeric_int4(Numeric num)
|
||||
{
|
||||
NumericVar x;
|
||||
char *str;
|
||||
int32 result;
|
||||
Datum result;
|
||||
|
||||
if (num == NULL)
|
||||
return 0;
|
||||
@@ -1749,7 +1753,7 @@ numeric_int4(Numeric num)
|
||||
|
||||
free_var(&x);
|
||||
|
||||
result = int4in(str);
|
||||
result = DirectFunctionCall1(int4in, CStringGetDatum(str));
|
||||
pfree(str);
|
||||
|
||||
return result;
|
||||
@@ -1807,35 +1811,35 @@ numeric_int8(Numeric num)
|
||||
}
|
||||
|
||||
|
||||
Numeric
|
||||
int2_numeric(int16 val)
|
||||
Datum
|
||||
int2_numeric(PG_FUNCTION_ARGS)
|
||||
{
|
||||
int16 val = PG_GETARG_INT16(0);
|
||||
Numeric res;
|
||||
NumericVar result;
|
||||
char *tmp;
|
||||
|
||||
init_var(&result);
|
||||
|
||||
tmp = int2out(val);
|
||||
tmp = DatumGetCString(DirectFunctionCall1(int2out,
|
||||
Int16GetDatum(val)));
|
||||
set_var_from_str(tmp, &result);
|
||||
res = make_result(&result);
|
||||
|
||||
free_var(&result);
|
||||
pfree(tmp);
|
||||
|
||||
return res;
|
||||
PG_RETURN_NUMERIC(res);
|
||||
}
|
||||
|
||||
|
||||
int16
|
||||
numeric_int2(Numeric num)
|
||||
Datum
|
||||
numeric_int2(PG_FUNCTION_ARGS)
|
||||
{
|
||||
Numeric num = PG_GETARG_NUMERIC(0);
|
||||
NumericVar x;
|
||||
char *str;
|
||||
int16 result;
|
||||
|
||||
if (num == NULL)
|
||||
return 0;
|
||||
Datum result;
|
||||
|
||||
if (NUMERIC_IS_NAN(num))
|
||||
elog(ERROR, "Cannot convert NaN to int2");
|
||||
@@ -1851,7 +1855,7 @@ numeric_int2(Numeric num)
|
||||
|
||||
free_var(&x);
|
||||
|
||||
result = int2in(str);
|
||||
result = DirectFunctionCall1(int2in, CStringGetDatum(str));
|
||||
pfree(str);
|
||||
|
||||
return result;
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $Header: /cvsroot/pgsql/src/backend/utils/adt/oid.c,v 1.34 2000/04/12 17:15:51 momjian Exp $
|
||||
* $Header: /cvsroot/pgsql/src/backend/utils/adt/oid.c,v 1.35 2000/06/05 07:28:52 tgl Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@@ -26,17 +26,15 @@
|
||||
* oidvectorin - converts "num num ..." to internal form
|
||||
*
|
||||
* Note:
|
||||
* Fills any nonexistent digits with NULL oids.
|
||||
* Fills any unsupplied positions with InvalidOid.
|
||||
*/
|
||||
Oid *
|
||||
oidvectorin(char *oidString)
|
||||
Datum
|
||||
oidvectorin(PG_FUNCTION_ARGS)
|
||||
{
|
||||
char *oidString = PG_GETARG_CSTRING(0);
|
||||
Oid *result;
|
||||
int slot;
|
||||
|
||||
if (oidString == NULL)
|
||||
return NULL;
|
||||
|
||||
result = (Oid *) palloc(sizeof(Oid[INDEX_MAX_KEYS]));
|
||||
|
||||
for (slot = 0; *oidString && slot < INDEX_MAX_KEYS; slot++)
|
||||
@@ -53,30 +51,23 @@ oidvectorin(char *oidString)
|
||||
if (*oidString)
|
||||
elog(ERROR, "oidvector value has too many values");
|
||||
while (slot < INDEX_MAX_KEYS)
|
||||
result[slot++] = 0;
|
||||
result[slot++] = InvalidOid;
|
||||
|
||||
return result;
|
||||
PG_RETURN_POINTER(result);
|
||||
}
|
||||
|
||||
/*
|
||||
* oidvectorout - converts internal form to "num num ..."
|
||||
*/
|
||||
char *
|
||||
oidvectorout(Oid *oidArray)
|
||||
Datum
|
||||
oidvectorout(PG_FUNCTION_ARGS)
|
||||
{
|
||||
Oid *oidArray = (Oid *) PG_GETARG_POINTER(0);
|
||||
int num,
|
||||
maxnum;
|
||||
char *rp;
|
||||
char *result;
|
||||
|
||||
if (oidArray == 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 (oidArray[maxnum] != 0)
|
||||
@@ -93,147 +84,177 @@ oidvectorout(Oid *oidArray)
|
||||
;
|
||||
}
|
||||
*rp = '\0';
|
||||
return result;
|
||||
PG_RETURN_CSTRING(result);
|
||||
}
|
||||
|
||||
Oid
|
||||
oidin(char *s)
|
||||
Datum
|
||||
oidin(PG_FUNCTION_ARGS)
|
||||
{
|
||||
return int4in(s);
|
||||
char *s = PG_GETARG_CSTRING(0);
|
||||
|
||||
/* XXX should use an unsigned-int conversion here */
|
||||
return DirectFunctionCall1(int4in, CStringGetDatum(s));
|
||||
}
|
||||
|
||||
char *
|
||||
oidout(Oid o)
|
||||
Datum
|
||||
oidout(PG_FUNCTION_ARGS)
|
||||
{
|
||||
return int4out(o);
|
||||
Oid o = PG_GETARG_OID(0);
|
||||
|
||||
/* XXX should use an unsigned-int conversion here */
|
||||
return DirectFunctionCall1(int4out, ObjectIdGetDatum(o));
|
||||
}
|
||||
|
||||
/*****************************************************************************
|
||||
* PUBLIC ROUTINES *
|
||||
*****************************************************************************/
|
||||
|
||||
/*
|
||||
* If you change this function, change heap_keytest()
|
||||
* because we have hardcoded this in there as an optimization
|
||||
*/
|
||||
bool
|
||||
oideq(Oid arg1, Oid arg2)
|
||||
Datum
|
||||
oideq(PG_FUNCTION_ARGS)
|
||||
{
|
||||
return arg1 == arg2;
|
||||
Oid arg1 = PG_GETARG_OID(0);
|
||||
Oid arg2 = PG_GETARG_OID(1);
|
||||
|
||||
PG_RETURN_BOOL(arg1 == arg2);
|
||||
}
|
||||
|
||||
bool
|
||||
oidne(Oid arg1, Oid arg2)
|
||||
Datum
|
||||
oidne(PG_FUNCTION_ARGS)
|
||||
{
|
||||
return arg1 != arg2;
|
||||
Oid arg1 = PG_GETARG_OID(0);
|
||||
Oid arg2 = PG_GETARG_OID(1);
|
||||
|
||||
PG_RETURN_BOOL(arg1 != arg2);
|
||||
}
|
||||
|
||||
bool
|
||||
oidvectoreq(Oid *arg1, Oid *arg2)
|
||||
Datum
|
||||
oidvectoreq(PG_FUNCTION_ARGS)
|
||||
{
|
||||
return (bool) (memcmp(arg1, arg2, INDEX_MAX_KEYS * sizeof(Oid)) == 0);
|
||||
Oid *arg1 = (Oid *) PG_GETARG_POINTER(0);
|
||||
Oid *arg2 = (Oid *) PG_GETARG_POINTER(1);
|
||||
|
||||
PG_RETURN_BOOL(memcmp(arg1, arg2, INDEX_MAX_KEYS * sizeof(Oid)) == 0);
|
||||
}
|
||||
|
||||
bool
|
||||
oidvectorne(Oid *arg1, Oid *arg2)
|
||||
Datum
|
||||
oidvectorne(PG_FUNCTION_ARGS)
|
||||
{
|
||||
return (bool) (memcmp(arg1, arg2, INDEX_MAX_KEYS * sizeof(Oid)) != 0);
|
||||
Oid *arg1 = (Oid *) PG_GETARG_POINTER(0);
|
||||
Oid *arg2 = (Oid *) PG_GETARG_POINTER(1);
|
||||
|
||||
PG_RETURN_BOOL(memcmp(arg1, arg2, INDEX_MAX_KEYS * sizeof(Oid)) != 0);
|
||||
}
|
||||
|
||||
bool
|
||||
oidvectorlt(Oid *arg1, Oid *arg2)
|
||||
Datum
|
||||
oidvectorlt(PG_FUNCTION_ARGS)
|
||||
{
|
||||
Oid *arg1 = (Oid *) PG_GETARG_POINTER(0);
|
||||
Oid *arg2 = (Oid *) PG_GETARG_POINTER(1);
|
||||
int i;
|
||||
|
||||
for (i = 0; i < INDEX_MAX_KEYS; i++)
|
||||
if (!int4eq(arg1[i], arg2[i]))
|
||||
return int4lt(arg1[i], arg2[i]);
|
||||
return false;
|
||||
if (arg1[i] != arg2[i])
|
||||
PG_RETURN_BOOL(arg1[i] < arg2[i]);
|
||||
PG_RETURN_BOOL(false);
|
||||
}
|
||||
|
||||
bool
|
||||
oidvectorle(Oid *arg1, Oid *arg2)
|
||||
Datum
|
||||
oidvectorle(PG_FUNCTION_ARGS)
|
||||
{
|
||||
Oid *arg1 = (Oid *) PG_GETARG_POINTER(0);
|
||||
Oid *arg2 = (Oid *) PG_GETARG_POINTER(1);
|
||||
int i;
|
||||
|
||||
for (i = 0; i < INDEX_MAX_KEYS; i++)
|
||||
if (!int4eq(arg1[i], arg2[i]))
|
||||
return int4le(arg1[i], arg2[i]);
|
||||
return true;
|
||||
if (arg1[i] != arg2[i])
|
||||
PG_RETURN_BOOL(arg1[i] <= arg2[i]);
|
||||
PG_RETURN_BOOL(true);
|
||||
}
|
||||
|
||||
bool
|
||||
oidvectorge(Oid *arg1, Oid *arg2)
|
||||
Datum
|
||||
oidvectorge(PG_FUNCTION_ARGS)
|
||||
{
|
||||
Oid *arg1 = (Oid *) PG_GETARG_POINTER(0);
|
||||
Oid *arg2 = (Oid *) PG_GETARG_POINTER(1);
|
||||
int i;
|
||||
|
||||
for (i = 0; i < INDEX_MAX_KEYS; i++)
|
||||
if (!int4eq(arg1[i], arg2[i]))
|
||||
return int4ge(arg1[i], arg2[i]);
|
||||
return true;
|
||||
if (arg1[i] != arg2[i])
|
||||
PG_RETURN_BOOL(arg1[i] >= arg2[i]);
|
||||
PG_RETURN_BOOL(true);
|
||||
}
|
||||
|
||||
bool
|
||||
oidvectorgt(Oid *arg1, Oid *arg2)
|
||||
Datum
|
||||
oidvectorgt(PG_FUNCTION_ARGS)
|
||||
{
|
||||
Oid *arg1 = (Oid *) PG_GETARG_POINTER(0);
|
||||
Oid *arg2 = (Oid *) PG_GETARG_POINTER(1);
|
||||
int i;
|
||||
|
||||
for (i = 0; i < INDEX_MAX_KEYS; i++)
|
||||
if (!int4eq(arg1[i], arg2[i]))
|
||||
return int4gt(arg1[i], arg2[i]);
|
||||
return false;
|
||||
if (arg1[i] != arg2[i])
|
||||
PG_RETURN_BOOL(arg1[i] > arg2[i]);
|
||||
PG_RETURN_BOOL(false);
|
||||
}
|
||||
|
||||
bool
|
||||
oideqint4(Oid arg1, int32 arg2)
|
||||
Datum
|
||||
oideqint4(PG_FUNCTION_ARGS)
|
||||
{
|
||||
/* oid is unsigned, but int4 is signed */
|
||||
return arg2 >= 0 && arg1 == arg2;
|
||||
Oid arg1 = PG_GETARG_OID(0);
|
||||
int32 arg2 = PG_GETARG_INT32(1);
|
||||
|
||||
/* oid is unsigned, but int4 is signed */
|
||||
PG_RETURN_BOOL(arg2 >= 0 && arg1 == arg2);
|
||||
}
|
||||
|
||||
bool
|
||||
int4eqoid(int32 arg1, Oid arg2)
|
||||
Datum
|
||||
int4eqoid(PG_FUNCTION_ARGS)
|
||||
{
|
||||
/* oid is unsigned, but int4 is signed */
|
||||
return arg1 >= 0 && arg1 == arg2;
|
||||
int32 arg1 = PG_GETARG_INT32(0);
|
||||
Oid arg2 = PG_GETARG_OID(1);
|
||||
|
||||
/* oid is unsigned, but int4 is signed */
|
||||
PG_RETURN_BOOL(arg1 >= 0 && arg1 == arg2);
|
||||
}
|
||||
|
||||
text *
|
||||
oid_text(Oid oid)
|
||||
Datum
|
||||
oid_text(PG_FUNCTION_ARGS)
|
||||
{
|
||||
Oid oid = PG_GETARG_OID(0);
|
||||
text *result;
|
||||
|
||||
int len;
|
||||
char *str;
|
||||
|
||||
str = oidout(oid);
|
||||
len = (strlen(str) + VARHDRSZ);
|
||||
str = DatumGetCString(DirectFunctionCall1(oidout,
|
||||
ObjectIdGetDatum(oid)));
|
||||
len = strlen(str) + VARHDRSZ;
|
||||
|
||||
result = palloc(len);
|
||||
result = (text *) palloc(len);
|
||||
|
||||
VARSIZE(result) = len;
|
||||
memmove(VARDATA(result), str, (len - VARHDRSZ));
|
||||
memcpy(VARDATA(result), str, (len - VARHDRSZ));
|
||||
pfree(str);
|
||||
|
||||
return result;
|
||||
} /* oid_text() */
|
||||
PG_RETURN_TEXT_P(result);
|
||||
}
|
||||
|
||||
Oid
|
||||
text_oid(text *string)
|
||||
Datum
|
||||
text_oid(PG_FUNCTION_ARGS)
|
||||
{
|
||||
text *string = PG_GETARG_TEXT_P(0);
|
||||
Oid result;
|
||||
|
||||
int len;
|
||||
char *str;
|
||||
|
||||
len = (VARSIZE(string) - VARHDRSZ);
|
||||
|
||||
str = palloc(len + 1);
|
||||
memmove(str, VARDATA(string), len);
|
||||
memcpy(str, VARDATA(string), len);
|
||||
*(str + len) = '\0';
|
||||
|
||||
result = oidin(str);
|
||||
result = DatumGetObjectId(DirectFunctionCall1(oidin,
|
||||
CStringGetDatum(str)));
|
||||
pfree(str);
|
||||
|
||||
return result;
|
||||
} /* oid_text() */
|
||||
PG_RETURN_OID(result);
|
||||
}
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $Header: /cvsroot/pgsql/src/backend/utils/adt/regproc.c,v 1.55 2000/05/28 17:56:05 tgl Exp $
|
||||
* $Header: /cvsroot/pgsql/src/backend/utils/adt/regproc.c,v 1.56 2000/06/05 07:28:52 tgl Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@@ -34,17 +34,16 @@
|
||||
*
|
||||
* proid of '-' signifies unknown, for consistency with regprocout
|
||||
*/
|
||||
int32
|
||||
regprocin(char *pro_name_or_oid)
|
||||
Datum
|
||||
regprocin(PG_FUNCTION_ARGS)
|
||||
{
|
||||
HeapTuple proctup = NULL;
|
||||
char *pro_name_or_oid = PG_GETARG_CSTRING(0);
|
||||
HeapTuple proctup;
|
||||
HeapTupleData tuple;
|
||||
RegProcedure result = InvalidOid;
|
||||
|
||||
if (pro_name_or_oid == NULL)
|
||||
return InvalidOid;
|
||||
if (pro_name_or_oid[0] == '-' && pro_name_or_oid[1] == '\0')
|
||||
return InvalidOid;
|
||||
PG_RETURN_OID(InvalidOid);
|
||||
|
||||
if (!IsIgnoringSystemIndexes())
|
||||
{
|
||||
@@ -57,7 +56,8 @@ regprocin(char *pro_name_or_oid)
|
||||
pro_name_or_oid[0] <= '9')
|
||||
{
|
||||
proctup = SearchSysCacheTuple(PROCOID,
|
||||
ObjectIdGetDatum(oidin(pro_name_or_oid)),
|
||||
DirectFunctionCall1(oidin,
|
||||
CStringGetDatum(pro_name_or_oid)),
|
||||
0, 0, 0);
|
||||
if (HeapTupleIsValid(proctup))
|
||||
result = (RegProcedure) proctup->t_data->t_oid;
|
||||
@@ -78,7 +78,7 @@ regprocin(char *pro_name_or_oid)
|
||||
(bits16) 0x0,
|
||||
(AttrNumber) 1,
|
||||
(RegProcedure) F_NAMEEQ,
|
||||
PointerGetDatum(pro_name_or_oid));
|
||||
CStringGetDatum(pro_name_or_oid));
|
||||
|
||||
hdesc = heap_openr(ProcedureRelationName, AccessShareLock);
|
||||
idesc = index_openr(ProcedureNameIndex);
|
||||
@@ -125,7 +125,7 @@ regprocin(char *pro_name_or_oid)
|
||||
(bits16) 0,
|
||||
(AttrNumber) 1,
|
||||
(RegProcedure) F_NAMEEQ,
|
||||
(Datum) pro_name_or_oid);
|
||||
CStringGetDatum(pro_name_or_oid));
|
||||
|
||||
procscan = heap_beginscan(proc, 0, SnapshotNow, 1, &key);
|
||||
if (!HeapScanIsValid(procscan))
|
||||
@@ -133,7 +133,7 @@ regprocin(char *pro_name_or_oid)
|
||||
heap_close(proc, AccessShareLock);
|
||||
elog(ERROR, "regprocin: could not begin scan of %s",
|
||||
ProcedureRelationName);
|
||||
return 0;
|
||||
PG_RETURN_OID(InvalidOid);
|
||||
}
|
||||
proctup = heap_getnext(procscan, 0);
|
||||
if (HeapTupleIsValid(proctup))
|
||||
@@ -143,24 +143,25 @@ regprocin(char *pro_name_or_oid)
|
||||
RelationGetDescr(proc),
|
||||
&isnull);
|
||||
if (isnull)
|
||||
elog(FATAL, "regprocin: null procedure %s", pro_name_or_oid);
|
||||
elog(ERROR, "regprocin: null procedure %s", pro_name_or_oid);
|
||||
}
|
||||
else
|
||||
result = (RegProcedure) 0;
|
||||
elog(ERROR, "No procedure with name %s", pro_name_or_oid);
|
||||
|
||||
heap_endscan(procscan);
|
||||
heap_close(proc, AccessShareLock);
|
||||
}
|
||||
|
||||
return (int32) result;
|
||||
PG_RETURN_OID(result);
|
||||
}
|
||||
|
||||
/*
|
||||
* regprocout - converts proid to "pro_name"
|
||||
*/
|
||||
char *
|
||||
regprocout(RegProcedure proid)
|
||||
Datum
|
||||
regprocout(PG_FUNCTION_ARGS)
|
||||
{
|
||||
RegProcedure proid = PG_GETARG_OID(0);
|
||||
HeapTuple proctup;
|
||||
char *result;
|
||||
|
||||
@@ -170,7 +171,7 @@ regprocout(RegProcedure proid)
|
||||
{
|
||||
result[0] = '-';
|
||||
result[1] = '\0';
|
||||
return result;
|
||||
PG_RETURN_CSTRING(result);
|
||||
}
|
||||
|
||||
if (!IsBootstrapProcessingMode())
|
||||
@@ -203,7 +204,7 @@ regprocout(RegProcedure proid)
|
||||
(bits16) 0,
|
||||
(AttrNumber) ObjectIdAttributeNumber,
|
||||
(RegProcedure) F_INT4EQ,
|
||||
(Datum) proid);
|
||||
ObjectIdGetDatum(proid));
|
||||
|
||||
procscan = heap_beginscan(proc, 0, SnapshotNow, 1, &key);
|
||||
if (!HeapScanIsValid(procscan))
|
||||
@@ -211,7 +212,6 @@ regprocout(RegProcedure proid)
|
||||
heap_close(proc, AccessShareLock);
|
||||
elog(ERROR, "regprocout: could not begin scan of %s",
|
||||
ProcedureRelationName);
|
||||
return 0;
|
||||
}
|
||||
proctup = heap_getnext(procscan, 0);
|
||||
if (HeapTupleIsValid(proctup))
|
||||
@@ -224,7 +224,7 @@ regprocout(RegProcedure proid)
|
||||
if (!isnull)
|
||||
StrNCpy(result, s, NAMEDATALEN);
|
||||
else
|
||||
elog(FATAL, "regprocout: null procedure %u", proid);
|
||||
elog(ERROR, "regprocout: null procedure %u", proid);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -235,7 +235,7 @@ regprocout(RegProcedure proid)
|
||||
heap_close(proc, AccessShareLock);
|
||||
}
|
||||
|
||||
return result;
|
||||
PG_RETURN_CSTRING(result);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -245,21 +245,15 @@ regprocout(RegProcedure proid)
|
||||
* OIDs are significant in the input vector, so that trailing InvalidOid
|
||||
* argument types can be recognized.
|
||||
*/
|
||||
text *
|
||||
oidvectortypes(Oid *oidArray)
|
||||
Datum
|
||||
oidvectortypes(PG_FUNCTION_ARGS)
|
||||
{
|
||||
Oid *oidArray = (Oid *) PG_GETARG_POINTER(0);
|
||||
HeapTuple typetup;
|
||||
text *result;
|
||||
int numargs,
|
||||
num;
|
||||
|
||||
if (oidArray == NULL)
|
||||
{
|
||||
result = (text *) palloc(VARHDRSZ);
|
||||
VARSIZE(result) = 0;
|
||||
return result;
|
||||
}
|
||||
|
||||
/* Try to guess how many args there are :-( */
|
||||
numargs = 0;
|
||||
for (num = 0; num < FUNC_MAX_ARGS; num++)
|
||||
@@ -289,7 +283,7 @@ oidvectortypes(Oid *oidArray)
|
||||
strcat(VARDATA(result), "- ");
|
||||
}
|
||||
VARSIZE(result) = strlen(VARDATA(result)) + VARHDRSZ;
|
||||
return result;
|
||||
PG_RETURN_TEXT_P(result);
|
||||
}
|
||||
|
||||
|
||||
@@ -302,10 +296,12 @@ oidvectortypes(Oid *oidArray)
|
||||
* Define RegprocToOid() as a macro in builtins.h.
|
||||
* Referenced in pg_proc.h. - tgl 97/04/26
|
||||
*/
|
||||
Oid
|
||||
regproctooid(RegProcedure rp)
|
||||
Datum
|
||||
regproctooid(PG_FUNCTION_ARGS)
|
||||
{
|
||||
return (Oid) rp;
|
||||
RegProcedure rp = PG_GETARG_OID(0);
|
||||
|
||||
PG_RETURN_OID((Oid) rp);
|
||||
}
|
||||
|
||||
/* (see int.c for comparison/operation routines) */
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $Header: /cvsroot/pgsql/src/backend/utils/adt/selfuncs.c,v 1.68 2000/05/30 04:24:51 tgl Exp $
|
||||
* $Header: /cvsroot/pgsql/src/backend/utils/adt/selfuncs.c,v 1.69 2000/06/05 07:28:52 tgl Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@@ -44,9 +44,6 @@
|
||||
/* N is not a valid var/constant or relation id */
|
||||
#define NONVALUE(N) ((N) == 0)
|
||||
|
||||
/* are we looking at a functional index selectivity request? */
|
||||
#define FunctionalSelectivity(nIndKeys,attNum) ((attNum)==InvalidAttrNumber)
|
||||
|
||||
/* default selectivity estimate for equalities such as "A = b" */
|
||||
#define DEFAULT_EQ_SEL 0.01
|
||||
|
||||
@@ -106,18 +103,18 @@ static Datum string_to_datum(const char *str, Oid datatype);
|
||||
* of the given constant "value" may be different from the type of the
|
||||
* attribute.
|
||||
*/
|
||||
float64
|
||||
eqsel(Oid opid,
|
||||
Oid relid,
|
||||
AttrNumber attno,
|
||||
Datum value,
|
||||
int32 flag)
|
||||
Datum
|
||||
eqsel(PG_FUNCTION_ARGS)
|
||||
{
|
||||
float64 result;
|
||||
Oid opid = PG_GETARG_OID(0);
|
||||
Oid relid = PG_GETARG_OID(1);
|
||||
AttrNumber attno = PG_GETARG_INT16(2);
|
||||
Datum value = PG_GETARG_DATUM(3);
|
||||
int32 flag = PG_GETARG_INT32(4);
|
||||
float8 result;
|
||||
|
||||
result = (float64) palloc(sizeof(float64data));
|
||||
if (NONVALUE(attno) || NONVALUE(relid))
|
||||
*result = DEFAULT_EQ_SEL;
|
||||
result = DEFAULT_EQ_SEL;
|
||||
else
|
||||
{
|
||||
Oid typid;
|
||||
@@ -239,9 +236,9 @@ eqsel(Oid opid,
|
||||
selec = get_attdisbursion(relid, attno, 0.01);
|
||||
}
|
||||
|
||||
*result = (float64data) selec;
|
||||
result = (float8) selec;
|
||||
}
|
||||
return result;
|
||||
PG_RETURN_FLOAT8(result);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -251,18 +248,14 @@ eqsel(Oid opid,
|
||||
* but have comparable selectivity behavior. See above comments
|
||||
* for eqsel().
|
||||
*/
|
||||
float64
|
||||
neqsel(Oid opid,
|
||||
Oid relid,
|
||||
AttrNumber attno,
|
||||
Datum value,
|
||||
int32 flag)
|
||||
Datum
|
||||
neqsel(PG_FUNCTION_ARGS)
|
||||
{
|
||||
float64 result;
|
||||
float8 result;
|
||||
|
||||
result = eqsel(opid, relid, attno, value, flag);
|
||||
*result = 1.0 - *result;
|
||||
return result;
|
||||
result = DatumGetFloat8(eqsel(fcinfo));
|
||||
result = 1.0 - result;
|
||||
PG_RETURN_FLOAT8(result);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -272,18 +265,18 @@ neqsel(Oid opid,
|
||||
* convert_to_scalar(). If it is applied to some other datatype,
|
||||
* it will return a default estimate.
|
||||
*/
|
||||
float64
|
||||
scalarltsel(Oid opid,
|
||||
Oid relid,
|
||||
AttrNumber attno,
|
||||
Datum value,
|
||||
int32 flag)
|
||||
Datum
|
||||
scalarltsel(PG_FUNCTION_ARGS)
|
||||
{
|
||||
float64 result;
|
||||
Oid opid = PG_GETARG_OID(0);
|
||||
Oid relid = PG_GETARG_OID(1);
|
||||
AttrNumber attno = PG_GETARG_INT16(2);
|
||||
Datum value = PG_GETARG_DATUM(3);
|
||||
int32 flag = PG_GETARG_INT32(4);
|
||||
float8 result;
|
||||
|
||||
result = (float64) palloc(sizeof(float64data));
|
||||
if (!(flag & SEL_CONSTANT) || NONVALUE(attno) || NONVALUE(relid))
|
||||
*result = DEFAULT_INEQ_SEL;
|
||||
result = DEFAULT_INEQ_SEL;
|
||||
else
|
||||
{
|
||||
HeapTuple oprtuple;
|
||||
@@ -322,8 +315,7 @@ scalarltsel(Oid opid,
|
||||
&loval, &hival))
|
||||
{
|
||||
/* no stats available, so default result */
|
||||
*result = DEFAULT_INEQ_SEL;
|
||||
return result;
|
||||
PG_RETURN_FLOAT8(DEFAULT_INEQ_SEL);
|
||||
}
|
||||
|
||||
/* Convert the values to a uniform comparison scale. */
|
||||
@@ -344,8 +336,7 @@ scalarltsel(Oid opid,
|
||||
pfree(DatumGetPointer(hival));
|
||||
pfree(DatumGetPointer(loval));
|
||||
}
|
||||
*result = DEFAULT_INEQ_SEL;
|
||||
return result;
|
||||
PG_RETURN_FLOAT8(DEFAULT_INEQ_SEL);
|
||||
}
|
||||
|
||||
/* release temp storage if needed */
|
||||
@@ -364,7 +355,7 @@ scalarltsel(Oid opid,
|
||||
* point the constant is on. But it seems better to assume
|
||||
* that the stats are wrong and return a default...
|
||||
*/
|
||||
*result = DEFAULT_INEQ_SEL;
|
||||
result = DEFAULT_INEQ_SEL;
|
||||
}
|
||||
else if (val < low || val > high)
|
||||
{
|
||||
@@ -375,9 +366,9 @@ scalarltsel(Oid opid,
|
||||
* chance the stats are out of date.
|
||||
*/
|
||||
if (flag & SEL_RIGHT)
|
||||
*result = (val < low) ? 0.001 : 0.999;
|
||||
result = (val < low) ? 0.001 : 0.999;
|
||||
else
|
||||
*result = (val < low) ? 0.999 : 0.001;
|
||||
result = (val < low) ? 0.999 : 0.001;
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -386,10 +377,10 @@ scalarltsel(Oid opid,
|
||||
numerator = val - low;
|
||||
else
|
||||
numerator = high - val;
|
||||
*result = numerator / denominator;
|
||||
result = numerator / denominator;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
PG_RETURN_FLOAT8(result);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -397,42 +388,37 @@ scalarltsel(Oid opid,
|
||||
*
|
||||
* See above comments for scalarltsel.
|
||||
*/
|
||||
float64
|
||||
scalargtsel(Oid opid,
|
||||
Oid relid,
|
||||
AttrNumber attno,
|
||||
Datum value,
|
||||
int32 flag)
|
||||
Datum
|
||||
scalargtsel(PG_FUNCTION_ARGS)
|
||||
{
|
||||
float64 result;
|
||||
float8 result;
|
||||
|
||||
/*
|
||||
* Compute selectivity of "<", then invert --- but only if we were
|
||||
* able to produce a non-default estimate.
|
||||
*/
|
||||
result = scalarltsel(opid, relid, attno, value, flag);
|
||||
if (*result != DEFAULT_INEQ_SEL)
|
||||
*result = 1.0 - *result;
|
||||
return result;
|
||||
result = DatumGetFloat8(scalarltsel(fcinfo));
|
||||
if (result != DEFAULT_INEQ_SEL)
|
||||
result = 1.0 - result;
|
||||
PG_RETURN_FLOAT8(result);
|
||||
}
|
||||
|
||||
/*
|
||||
* patternsel - Generic code for pattern-match selectivity.
|
||||
*/
|
||||
static float64
|
||||
patternsel(Oid opid,
|
||||
Pattern_Type ptype,
|
||||
Oid relid,
|
||||
AttrNumber attno,
|
||||
Datum value,
|
||||
int32 flag)
|
||||
static Datum
|
||||
patternsel(PG_FUNCTION_ARGS, Pattern_Type ptype)
|
||||
{
|
||||
float64 result;
|
||||
Oid opid = PG_GETARG_OID(0);
|
||||
Oid relid = PG_GETARG_OID(1);
|
||||
AttrNumber attno = PG_GETARG_INT16(2);
|
||||
Datum value = PG_GETARG_DATUM(3);
|
||||
int32 flag = PG_GETARG_INT32(4);
|
||||
float8 result;
|
||||
|
||||
result = (float64) palloc(sizeof(float64data));
|
||||
/* Must have a constant for the pattern, or cannot learn anything */
|
||||
if ((flag & (SEL_CONSTANT | SEL_RIGHT)) != (SEL_CONSTANT | SEL_RIGHT))
|
||||
*result = DEFAULT_MATCH_SEL;
|
||||
result = DEFAULT_MATCH_SEL;
|
||||
else
|
||||
{
|
||||
HeapTuple oprtuple;
|
||||
@@ -469,7 +455,12 @@ patternsel(Oid opid,
|
||||
if (eqopr == InvalidOid)
|
||||
elog(ERROR, "patternsel: no = operator for type %u", ltype);
|
||||
eqcon = string_to_datum(prefix, ltype);
|
||||
result = eqsel(eqopr, relid, attno, eqcon, SEL_CONSTANT|SEL_RIGHT);
|
||||
result = DatumGetFloat8(DirectFunctionCall5(eqsel,
|
||||
ObjectIdGetDatum(eqopr),
|
||||
ObjectIdGetDatum(relid),
|
||||
Int16GetDatum(attno),
|
||||
eqcon,
|
||||
Int32GetDatum(SEL_CONSTANT|SEL_RIGHT)));
|
||||
pfree(DatumGetPointer(eqcon));
|
||||
}
|
||||
else
|
||||
@@ -494,125 +485,103 @@ patternsel(Oid opid,
|
||||
selec = 0.0;
|
||||
else if (selec > 1.0)
|
||||
selec = 1.0;
|
||||
*result = (float64data) selec;
|
||||
result = (float8) selec;
|
||||
}
|
||||
if (prefix)
|
||||
pfree(prefix);
|
||||
pfree(patt);
|
||||
}
|
||||
return result;
|
||||
PG_RETURN_FLOAT8(result);
|
||||
}
|
||||
|
||||
/*
|
||||
* regexeqsel - Selectivity of regular-expression pattern match.
|
||||
*/
|
||||
float64
|
||||
regexeqsel(Oid opid,
|
||||
Oid relid,
|
||||
AttrNumber attno,
|
||||
Datum value,
|
||||
int32 flag)
|
||||
Datum
|
||||
regexeqsel(PG_FUNCTION_ARGS)
|
||||
{
|
||||
return patternsel(opid, Pattern_Type_Regex, relid, attno, value, flag);
|
||||
return patternsel(fcinfo, Pattern_Type_Regex);
|
||||
}
|
||||
|
||||
/*
|
||||
* icregexeqsel - Selectivity of case-insensitive regex match.
|
||||
*/
|
||||
float64
|
||||
icregexeqsel(Oid opid,
|
||||
Oid relid,
|
||||
AttrNumber attno,
|
||||
Datum value,
|
||||
int32 flag)
|
||||
Datum
|
||||
icregexeqsel(PG_FUNCTION_ARGS)
|
||||
{
|
||||
return patternsel(opid, Pattern_Type_Regex_IC, relid, attno, value, flag);
|
||||
return patternsel(fcinfo, Pattern_Type_Regex_IC);
|
||||
}
|
||||
|
||||
/*
|
||||
* likesel - Selectivity of LIKE pattern match.
|
||||
*/
|
||||
float64
|
||||
likesel(Oid opid,
|
||||
Oid relid,
|
||||
AttrNumber attno,
|
||||
Datum value,
|
||||
int32 flag)
|
||||
Datum
|
||||
likesel(PG_FUNCTION_ARGS)
|
||||
{
|
||||
return patternsel(opid, Pattern_Type_Like, relid, attno, value, flag);
|
||||
return patternsel(fcinfo, Pattern_Type_Like);
|
||||
}
|
||||
|
||||
/*
|
||||
* regexnesel - Selectivity of regular-expression pattern non-match.
|
||||
*/
|
||||
float64
|
||||
regexnesel(Oid opid,
|
||||
Oid relid,
|
||||
AttrNumber attno,
|
||||
Datum value,
|
||||
int32 flag)
|
||||
Datum
|
||||
regexnesel(PG_FUNCTION_ARGS)
|
||||
{
|
||||
float64 result;
|
||||
float8 result;
|
||||
|
||||
result = patternsel(opid, Pattern_Type_Regex, relid, attno, value, flag);
|
||||
*result = 1.0 - *result;
|
||||
return result;
|
||||
result = DatumGetFloat8(patternsel(fcinfo, Pattern_Type_Regex));
|
||||
result = 1.0 - result;
|
||||
PG_RETURN_FLOAT8(result);
|
||||
}
|
||||
|
||||
/*
|
||||
* icregexnesel - Selectivity of case-insensitive regex non-match.
|
||||
*/
|
||||
float64
|
||||
icregexnesel(Oid opid,
|
||||
Oid relid,
|
||||
AttrNumber attno,
|
||||
Datum value,
|
||||
int32 flag)
|
||||
Datum
|
||||
icregexnesel(PG_FUNCTION_ARGS)
|
||||
{
|
||||
float64 result;
|
||||
float8 result;
|
||||
|
||||
result = patternsel(opid, Pattern_Type_Regex_IC, relid, attno, value, flag);
|
||||
*result = 1.0 - *result;
|
||||
return result;
|
||||
result = DatumGetFloat8(patternsel(fcinfo, Pattern_Type_Regex_IC));
|
||||
result = 1.0 - result;
|
||||
PG_RETURN_FLOAT8(result);
|
||||
}
|
||||
|
||||
/*
|
||||
* nlikesel - Selectivity of LIKE pattern non-match.
|
||||
*/
|
||||
float64
|
||||
nlikesel(Oid opid,
|
||||
Oid relid,
|
||||
AttrNumber attno,
|
||||
Datum value,
|
||||
int32 flag)
|
||||
Datum
|
||||
nlikesel(PG_FUNCTION_ARGS)
|
||||
{
|
||||
float64 result;
|
||||
float8 result;
|
||||
|
||||
result = patternsel(opid, Pattern_Type_Like, relid, attno, value, flag);
|
||||
*result = 1.0 - *result;
|
||||
return result;
|
||||
result = DatumGetFloat8(patternsel(fcinfo, Pattern_Type_Like));
|
||||
result = 1.0 - result;
|
||||
PG_RETURN_FLOAT8(result);
|
||||
}
|
||||
|
||||
/*
|
||||
* eqjoinsel - Join selectivity of "="
|
||||
*/
|
||||
float64
|
||||
eqjoinsel(Oid opid,
|
||||
Oid relid1,
|
||||
AttrNumber attno1,
|
||||
Oid relid2,
|
||||
AttrNumber attno2)
|
||||
Datum
|
||||
eqjoinsel(PG_FUNCTION_ARGS)
|
||||
{
|
||||
float64 result;
|
||||
float64data num1,
|
||||
#ifdef NOT_USED
|
||||
Oid opid = PG_GETARG_OID(0);
|
||||
#endif
|
||||
Oid relid1 = PG_GETARG_OID(1);
|
||||
AttrNumber attno1 = PG_GETARG_INT16(2);
|
||||
Oid relid2 = PG_GETARG_OID(3);
|
||||
AttrNumber attno2 = PG_GETARG_INT16(4);
|
||||
float8 result;
|
||||
float8 num1,
|
||||
num2,
|
||||
min;
|
||||
bool unknown1 = NONVALUE(relid1) || NONVALUE(attno1);
|
||||
bool unknown2 = NONVALUE(relid2) || NONVALUE(attno2);
|
||||
|
||||
result = (float64) palloc(sizeof(float64data));
|
||||
if (unknown1 && unknown2)
|
||||
*result = DEFAULT_EQ_SEL;
|
||||
result = DEFAULT_EQ_SEL;
|
||||
else
|
||||
{
|
||||
num1 = unknown1 ? 1.0 : get_attdisbursion(relid1, attno1, 0.01);
|
||||
@@ -637,162 +606,106 @@ eqjoinsel(Oid opid,
|
||||
* about applying the operator to the most common values?
|
||||
*/
|
||||
min = (num1 < num2) ? num1 : num2;
|
||||
*result = min;
|
||||
result = min;
|
||||
}
|
||||
return result;
|
||||
PG_RETURN_FLOAT8(result);
|
||||
}
|
||||
|
||||
/*
|
||||
* neqjoinsel - Join selectivity of "!="
|
||||
*/
|
||||
float64
|
||||
neqjoinsel(Oid opid,
|
||||
Oid relid1,
|
||||
AttrNumber attno1,
|
||||
Oid relid2,
|
||||
AttrNumber attno2)
|
||||
Datum
|
||||
neqjoinsel(PG_FUNCTION_ARGS)
|
||||
{
|
||||
float64 result;
|
||||
float8 result;
|
||||
|
||||
result = eqjoinsel(opid, relid1, attno1, relid2, attno2);
|
||||
*result = 1.0 - *result;
|
||||
return result;
|
||||
result = DatumGetFloat8(eqjoinsel(fcinfo));
|
||||
result = 1.0 - result;
|
||||
PG_RETURN_FLOAT8(result);
|
||||
}
|
||||
|
||||
/*
|
||||
* scalarltjoinsel - Join selectivity of "<" and "<=" for scalars
|
||||
*/
|
||||
float64
|
||||
scalarltjoinsel(Oid opid,
|
||||
Oid relid1,
|
||||
AttrNumber attno1,
|
||||
Oid relid2,
|
||||
AttrNumber attno2)
|
||||
Datum
|
||||
scalarltjoinsel(PG_FUNCTION_ARGS)
|
||||
{
|
||||
float64 result;
|
||||
|
||||
result = (float64) palloc(sizeof(float64data));
|
||||
*result = DEFAULT_INEQ_SEL;
|
||||
return result;
|
||||
PG_RETURN_FLOAT8(DEFAULT_INEQ_SEL);
|
||||
}
|
||||
|
||||
/*
|
||||
* scalargtjoinsel - Join selectivity of ">" and ">=" for scalars
|
||||
*/
|
||||
float64
|
||||
scalargtjoinsel(Oid opid,
|
||||
Oid relid1,
|
||||
AttrNumber attno1,
|
||||
Oid relid2,
|
||||
AttrNumber attno2)
|
||||
Datum
|
||||
scalargtjoinsel(PG_FUNCTION_ARGS)
|
||||
{
|
||||
float64 result;
|
||||
|
||||
result = (float64) palloc(sizeof(float64data));
|
||||
*result = DEFAULT_INEQ_SEL;
|
||||
return result;
|
||||
PG_RETURN_FLOAT8(DEFAULT_INEQ_SEL);
|
||||
}
|
||||
|
||||
/*
|
||||
* regexeqjoinsel - Join selectivity of regular-expression pattern match.
|
||||
*/
|
||||
float64
|
||||
regexeqjoinsel(Oid opid,
|
||||
Oid relid1,
|
||||
AttrNumber attno1,
|
||||
Oid relid2,
|
||||
AttrNumber attno2)
|
||||
Datum
|
||||
regexeqjoinsel(PG_FUNCTION_ARGS)
|
||||
{
|
||||
float64 result;
|
||||
|
||||
result = (float64) palloc(sizeof(float64data));
|
||||
*result = DEFAULT_MATCH_SEL;
|
||||
return result;
|
||||
PG_RETURN_FLOAT8(DEFAULT_MATCH_SEL);
|
||||
}
|
||||
|
||||
/*
|
||||
* icregexeqjoinsel - Join selectivity of case-insensitive regex match.
|
||||
*/
|
||||
float64
|
||||
icregexeqjoinsel(Oid opid,
|
||||
Oid relid1,
|
||||
AttrNumber attno1,
|
||||
Oid relid2,
|
||||
AttrNumber attno2)
|
||||
Datum
|
||||
icregexeqjoinsel(PG_FUNCTION_ARGS)
|
||||
{
|
||||
float64 result;
|
||||
|
||||
result = (float64) palloc(sizeof(float64data));
|
||||
*result = DEFAULT_MATCH_SEL;
|
||||
return result;
|
||||
PG_RETURN_FLOAT8(DEFAULT_MATCH_SEL);
|
||||
}
|
||||
|
||||
/*
|
||||
* likejoinsel - Join selectivity of LIKE pattern match.
|
||||
*/
|
||||
float64
|
||||
likejoinsel(Oid opid,
|
||||
Oid relid1,
|
||||
AttrNumber attno1,
|
||||
Oid relid2,
|
||||
AttrNumber attno2)
|
||||
Datum
|
||||
likejoinsel(PG_FUNCTION_ARGS)
|
||||
{
|
||||
float64 result;
|
||||
|
||||
result = (float64) palloc(sizeof(float64data));
|
||||
*result = DEFAULT_MATCH_SEL;
|
||||
return result;
|
||||
PG_RETURN_FLOAT8(DEFAULT_MATCH_SEL);
|
||||
}
|
||||
|
||||
/*
|
||||
* regexnejoinsel - Join selectivity of regex non-match.
|
||||
*/
|
||||
float64
|
||||
regexnejoinsel(Oid opid,
|
||||
Oid relid1,
|
||||
AttrNumber attno1,
|
||||
Oid relid2,
|
||||
AttrNumber attno2)
|
||||
Datum
|
||||
regexnejoinsel(PG_FUNCTION_ARGS)
|
||||
{
|
||||
float64 result;
|
||||
float8 result;
|
||||
|
||||
result = regexeqjoinsel(opid, relid1, attno1, relid2, attno2);
|
||||
*result = 1.0 - *result;
|
||||
return result;
|
||||
result = DatumGetFloat8(regexeqjoinsel(fcinfo));
|
||||
result = 1.0 - result;
|
||||
PG_RETURN_FLOAT8(result);
|
||||
}
|
||||
|
||||
/*
|
||||
* icregexnejoinsel - Join selectivity of case-insensitive regex non-match.
|
||||
*/
|
||||
float64
|
||||
icregexnejoinsel(Oid opid,
|
||||
Oid relid1,
|
||||
AttrNumber attno1,
|
||||
Oid relid2,
|
||||
AttrNumber attno2)
|
||||
Datum
|
||||
icregexnejoinsel(PG_FUNCTION_ARGS)
|
||||
{
|
||||
float64 result;
|
||||
float8 result;
|
||||
|
||||
result = icregexeqjoinsel(opid, relid1, attno1, relid2, attno2);
|
||||
*result = 1.0 - *result;
|
||||
return result;
|
||||
result = DatumGetFloat8(icregexeqjoinsel(fcinfo));
|
||||
result = 1.0 - result;
|
||||
PG_RETURN_FLOAT8(result);
|
||||
}
|
||||
|
||||
/*
|
||||
* nlikejoinsel - Join selectivity of LIKE pattern non-match.
|
||||
*/
|
||||
float64
|
||||
nlikejoinsel(Oid opid,
|
||||
Oid relid1,
|
||||
AttrNumber attno1,
|
||||
Oid relid2,
|
||||
AttrNumber attno2)
|
||||
Datum
|
||||
nlikejoinsel(PG_FUNCTION_ARGS)
|
||||
{
|
||||
float64 result;
|
||||
float8 result;
|
||||
|
||||
result = likejoinsel(opid, relid1, attno1, relid2, attno2);
|
||||
*result = 1.0 - *result;
|
||||
return result;
|
||||
result = DatumGetFloat8(likejoinsel(fcinfo));
|
||||
result = 1.0 - result;
|
||||
PG_RETURN_FLOAT8(result);
|
||||
}
|
||||
|
||||
|
||||
@@ -1563,8 +1476,12 @@ prefix_selectivity(char *prefix,
|
||||
datatype);
|
||||
prefixcon = string_to_datum(prefix, datatype);
|
||||
/* Assume scalargtsel is appropriate for all supported types */
|
||||
prefixsel = * scalargtsel(cmpopr, relid, attno,
|
||||
prefixcon, SEL_CONSTANT|SEL_RIGHT);
|
||||
prefixsel = DatumGetFloat8(DirectFunctionCall5(scalargtsel,
|
||||
ObjectIdGetDatum(cmpopr),
|
||||
ObjectIdGetDatum(relid),
|
||||
Int16GetDatum(attno),
|
||||
prefixcon,
|
||||
Int32GetDatum(SEL_CONSTANT|SEL_RIGHT)));
|
||||
pfree(DatumGetPointer(prefixcon));
|
||||
|
||||
/*
|
||||
@@ -1582,8 +1499,12 @@ prefix_selectivity(char *prefix,
|
||||
datatype);
|
||||
prefixcon = string_to_datum(greaterstr, datatype);
|
||||
/* Assume scalarltsel is appropriate for all supported types */
|
||||
topsel = * scalarltsel(cmpopr, relid, attno,
|
||||
prefixcon, SEL_CONSTANT|SEL_RIGHT);
|
||||
topsel = DatumGetFloat8(DirectFunctionCall5(scalarltsel,
|
||||
ObjectIdGetDatum(cmpopr),
|
||||
ObjectIdGetDatum(relid),
|
||||
Int16GetDatum(attno),
|
||||
prefixcon,
|
||||
Int32GetDatum(SEL_CONSTANT|SEL_RIGHT)));
|
||||
pfree(DatumGetPointer(prefixcon));
|
||||
pfree(greaterstr);
|
||||
|
||||
@@ -1966,13 +1887,16 @@ string_to_datum(const char *str, Oid datatype)
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
static void
|
||||
genericcostestimate(Query *root, RelOptInfo *rel,
|
||||
IndexOptInfo *index, List *indexQuals,
|
||||
Cost *indexStartupCost,
|
||||
Cost *indexTotalCost,
|
||||
Selectivity *indexSelectivity)
|
||||
static Datum
|
||||
genericcostestimate(PG_FUNCTION_ARGS)
|
||||
{
|
||||
Query *root = (Query *) PG_GETARG_POINTER(0);
|
||||
RelOptInfo *rel = (RelOptInfo *) PG_GETARG_POINTER(1);
|
||||
IndexOptInfo *index = (IndexOptInfo *) PG_GETARG_POINTER(2);
|
||||
List *indexQuals = (List *) PG_GETARG_POINTER(3);
|
||||
Cost *indexStartupCost = (Cost *) PG_GETARG_POINTER(4);
|
||||
Cost *indexTotalCost = (Cost *) PG_GETARG_POINTER(5);
|
||||
Selectivity *indexSelectivity = (Selectivity *) PG_GETARG_POINTER(6);
|
||||
double numIndexTuples;
|
||||
double numIndexPages;
|
||||
|
||||
@@ -2007,52 +1931,35 @@ genericcostestimate(Query *root, RelOptInfo *rel,
|
||||
*indexStartupCost = 0;
|
||||
*indexTotalCost = numIndexPages +
|
||||
(cpu_index_tuple_cost + cost_qual_eval(indexQuals)) * numIndexTuples;
|
||||
|
||||
/* No real return value ... */
|
||||
PG_RETURN_POINTER(NULL);
|
||||
}
|
||||
|
||||
/*
|
||||
* For first cut, just use generic function for all index types.
|
||||
*/
|
||||
|
||||
void
|
||||
btcostestimate(Query *root, RelOptInfo *rel,
|
||||
IndexOptInfo *index, List *indexQuals,
|
||||
Cost *indexStartupCost,
|
||||
Cost *indexTotalCost,
|
||||
Selectivity *indexSelectivity)
|
||||
Datum
|
||||
btcostestimate(PG_FUNCTION_ARGS)
|
||||
{
|
||||
genericcostestimate(root, rel, index, indexQuals,
|
||||
indexStartupCost, indexTotalCost, indexSelectivity);
|
||||
return genericcostestimate(fcinfo);
|
||||
}
|
||||
|
||||
void
|
||||
rtcostestimate(Query *root, RelOptInfo *rel,
|
||||
IndexOptInfo *index, List *indexQuals,
|
||||
Cost *indexStartupCost,
|
||||
Cost *indexTotalCost,
|
||||
Selectivity *indexSelectivity)
|
||||
Datum
|
||||
rtcostestimate(PG_FUNCTION_ARGS)
|
||||
{
|
||||
genericcostestimate(root, rel, index, indexQuals,
|
||||
indexStartupCost, indexTotalCost, indexSelectivity);
|
||||
return genericcostestimate(fcinfo);
|
||||
}
|
||||
|
||||
void
|
||||
hashcostestimate(Query *root, RelOptInfo *rel,
|
||||
IndexOptInfo *index, List *indexQuals,
|
||||
Cost *indexStartupCost,
|
||||
Cost *indexTotalCost,
|
||||
Selectivity *indexSelectivity)
|
||||
Datum
|
||||
hashcostestimate(PG_FUNCTION_ARGS)
|
||||
{
|
||||
genericcostestimate(root, rel, index, indexQuals,
|
||||
indexStartupCost, indexTotalCost, indexSelectivity);
|
||||
return genericcostestimate(fcinfo);
|
||||
}
|
||||
|
||||
void
|
||||
gistcostestimate(Query *root, RelOptInfo *rel,
|
||||
IndexOptInfo *index, List *indexQuals,
|
||||
Cost *indexStartupCost,
|
||||
Cost *indexTotalCost,
|
||||
Selectivity *indexSelectivity)
|
||||
Datum
|
||||
gistcostestimate(PG_FUNCTION_ARGS)
|
||||
{
|
||||
genericcostestimate(root, rel, index, indexQuals,
|
||||
indexStartupCost, indexTotalCost, indexSelectivity);
|
||||
return genericcostestimate(fcinfo);
|
||||
}
|
||||
|
||||
@@ -1,19 +1,20 @@
|
||||
/*-------------------------------------------------------------------------
|
||||
*
|
||||
* varchar.c
|
||||
* Functions for the built-in type char() and varchar().
|
||||
* Functions for the built-in types char(n) and varchar(n).
|
||||
*
|
||||
* 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/varchar.c,v 1.62 2000/05/30 00:49:53 momjian Exp $
|
||||
* $Header: /cvsroot/pgsql/src/backend/utils/adt/varchar.c,v 1.63 2000/06/05 07:28:52 tgl Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
#include "postgres.h"
|
||||
|
||||
#include "catalog/pg_type.h"
|
||||
#include "utils/builtins.h"
|
||||
#include "utils/fmgroids.h"
|
||||
@@ -22,9 +23,10 @@
|
||||
#include "mb/pg_wchar.h"
|
||||
#endif
|
||||
|
||||
#ifdef CYR_RECODE
|
||||
char *convertstr(char *, int, int);
|
||||
|
||||
#ifdef CYR_RECODE
|
||||
/* XXX no points for style --- this is actually in utils/init/miscinit.c */
|
||||
extern char *convertstr(char *, int, int);
|
||||
#endif
|
||||
|
||||
|
||||
@@ -34,7 +36,7 @@ char *convertstr(char *, int, int);
|
||||
* VARCHAR is for storing string whose length is at most the length specified
|
||||
* at CREATE TABLE time.
|
||||
*
|
||||
* It's hard to implement these types because we cannot figure out what
|
||||
* It's hard to implement these types because we cannot figure out
|
||||
* the length of the type from the type itself. I change (hopefully all) the
|
||||
* fmgr calls that invoke input functions of a data type to supply the
|
||||
* length also. (eg. in INSERTs, we have the tupleDescriptor which contains
|
||||
@@ -44,8 +46,9 @@ char *convertstr(char *, int, int);
|
||||
* must be null-terminated.
|
||||
*
|
||||
* We actually implement this as a varlena so that we don't have to pass in
|
||||
* the length for the comparison functions. (The difference between "text"
|
||||
* is that we truncate and possibly blank-pad the string at insertion time.)
|
||||
* the length for the comparison functions. (The difference between these
|
||||
* types and "text" is that we truncate and possibly blank-pad the string
|
||||
* at insertion time.)
|
||||
*
|
||||
* - ay 6/95
|
||||
*/
|
||||
@@ -231,28 +234,33 @@ _bpchar(ArrayType *v, int32 len)
|
||||
|
||||
/* bpchar_char()
|
||||
* Convert bpchar(1) to char.
|
||||
*
|
||||
* If input is multiple chars, only the first is returned.
|
||||
*/
|
||||
int32
|
||||
bpchar_char(char *s)
|
||||
Datum
|
||||
bpchar_char(PG_FUNCTION_ARGS)
|
||||
{
|
||||
return (int32) *VARDATA(s);
|
||||
} /* bpchar_char() */
|
||||
struct varlena *s = PG_GETARG_BPCHAR_P(0);
|
||||
|
||||
PG_RETURN_CHAR(*VARDATA(s));
|
||||
}
|
||||
|
||||
/* char_bpchar()
|
||||
* Convert char to bpchar(1).
|
||||
*/
|
||||
char *
|
||||
char_bpchar(int32 c)
|
||||
Datum
|
||||
char_bpchar(PG_FUNCTION_ARGS)
|
||||
{
|
||||
char *result;
|
||||
char c = PG_GETARG_CHAR(0);
|
||||
struct varlena *result;
|
||||
|
||||
result = palloc(VARHDRSZ + 1);
|
||||
result = (struct varlena *) palloc(VARHDRSZ + 1);
|
||||
|
||||
VARSIZE(result) = VARHDRSZ + 1;
|
||||
*(VARDATA(result)) = (char) c;
|
||||
*(VARDATA(result)) = c;
|
||||
|
||||
return result;
|
||||
} /* char_bpchar() */
|
||||
PG_RETURN_BPCHAR_P(result);
|
||||
}
|
||||
|
||||
|
||||
/* bpchar_name()
|
||||
|
||||
48
src/backend/utils/cache/catcache.c
vendored
48
src/backend/utils/cache/catcache.c
vendored
@@ -8,7 +8,7 @@
|
||||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $Header: /cvsroot/pgsql/src/backend/utils/cache/catcache.c,v 1.64 2000/05/28 17:56:06 tgl Exp $
|
||||
* $Header: /cvsroot/pgsql/src/backend/utils/cache/catcache.c,v 1.65 2000/06/05 07:28:53 tgl Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@@ -35,7 +35,7 @@ static Index CatalogCacheComputeTupleHashIndex(struct catcache * cacheInOutP,
|
||||
HeapTuple tuple);
|
||||
static void CatalogCacheInitializeCache(struct catcache * cache,
|
||||
Relation relation);
|
||||
static uint32 cc_hashname(NameData *n);
|
||||
static Datum cc_hashname(PG_FUNCTION_ARGS);
|
||||
|
||||
/* ----------------
|
||||
* variables, macros and other stuff
|
||||
@@ -87,38 +87,38 @@ static const Oid eqproc[] = {
|
||||
* ----------------------------------------------------------------
|
||||
*/
|
||||
|
||||
static CCHashFunc
|
||||
static PGFunction
|
||||
GetCCHashFunc(Oid keytype)
|
||||
{
|
||||
switch (keytype)
|
||||
{
|
||||
case BOOLOID:
|
||||
case CHAROID:
|
||||
return (CCHashFunc) hashchar;
|
||||
case BOOLOID:
|
||||
case CHAROID:
|
||||
return hashchar;
|
||||
case NAMEOID:
|
||||
return (CCHashFunc) cc_hashname;
|
||||
return cc_hashname;
|
||||
case INT2OID:
|
||||
return (CCHashFunc) hashint2;
|
||||
return hashint2;
|
||||
case INT2VECTOROID:
|
||||
return (CCHashFunc) hashint2vector;
|
||||
return hashint2vector;
|
||||
case INT4OID:
|
||||
return (CCHashFunc) hashint4;
|
||||
return hashint4;
|
||||
case TEXTOID:
|
||||
return (CCHashFunc) hashtext;
|
||||
return hashtext;
|
||||
case REGPROCOID:
|
||||
case OIDOID:
|
||||
return (CCHashFunc) hashoid;
|
||||
return hashoid;
|
||||
case OIDVECTOROID:
|
||||
return (CCHashFunc) hashoidvector;
|
||||
return hashoidvector;
|
||||
default:
|
||||
elog(FATAL, "GetCCHashFunc: type %u unsupported as catcache key",
|
||||
keytype);
|
||||
return NULL;
|
||||
return (PGFunction) NULL;
|
||||
}
|
||||
}
|
||||
|
||||
static uint32
|
||||
cc_hashname(NameData *n)
|
||||
static Datum
|
||||
cc_hashname(PG_FUNCTION_ARGS)
|
||||
{
|
||||
|
||||
/*
|
||||
@@ -129,9 +129,9 @@ cc_hashname(NameData *n)
|
||||
*/
|
||||
NameData my_n;
|
||||
|
||||
namestrcpy(&my_n, NameStr(*n));
|
||||
namestrcpy(&my_n, NameStr(* PG_GETARG_NAME(0)));
|
||||
|
||||
return hashname(&my_n);
|
||||
return DirectFunctionCall1(hashname, NameGetDatum(&my_n));
|
||||
}
|
||||
|
||||
|
||||
@@ -320,19 +320,23 @@ CatalogCacheComputeHashIndex(struct catcache * cacheInP)
|
||||
{
|
||||
case 4:
|
||||
hashIndex ^=
|
||||
(*cacheInP->cc_hashfunc[3]) (cacheInP->cc_skey[3].sk_argument) << 9;
|
||||
DatumGetUInt32(DirectFunctionCall1(cacheInP->cc_hashfunc[3],
|
||||
cacheInP->cc_skey[3].sk_argument)) << 9;
|
||||
/* FALLTHROUGH */
|
||||
case 3:
|
||||
hashIndex ^=
|
||||
(*cacheInP->cc_hashfunc[2]) (cacheInP->cc_skey[2].sk_argument) << 6;
|
||||
DatumGetUInt32(DirectFunctionCall1(cacheInP->cc_hashfunc[2],
|
||||
cacheInP->cc_skey[2].sk_argument)) << 6;
|
||||
/* FALLTHROUGH */
|
||||
case 2:
|
||||
hashIndex ^=
|
||||
(*cacheInP->cc_hashfunc[1]) (cacheInP->cc_skey[1].sk_argument) << 3;
|
||||
DatumGetUInt32(DirectFunctionCall1(cacheInP->cc_hashfunc[1],
|
||||
cacheInP->cc_skey[1].sk_argument)) << 3;
|
||||
/* FALLTHROUGH */
|
||||
case 1:
|
||||
hashIndex ^=
|
||||
(*cacheInP->cc_hashfunc[0]) (cacheInP->cc_skey[0].sk_argument);
|
||||
DatumGetUInt32(DirectFunctionCall1(cacheInP->cc_hashfunc[0],
|
||||
cacheInP->cc_skey[0].sk_argument));
|
||||
break;
|
||||
default:
|
||||
elog(FATAL, "CCComputeHashIndex: %d cc_nkeys", cacheInP->cc_nkeys);
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $Header: /cvsroot/pgsql/src/backend/utils/fmgr/fmgr.c,v 1.42 2000/05/30 04:24:53 tgl Exp $
|
||||
* $Header: /cvsroot/pgsql/src/backend/utils/fmgr/fmgr.c,v 1.43 2000/06/05 07:28:55 tgl Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@@ -21,6 +21,27 @@
|
||||
#include "utils/fmgrtab.h"
|
||||
#include "utils/syscache.h"
|
||||
|
||||
/*
|
||||
* Declaration for old-style function pointer type. This is now used only
|
||||
* in fmgr_oldstyle() and is no longer exported.
|
||||
*
|
||||
* The m68k SVR4 ABI defines that pointers are returned in %a0 instead of
|
||||
* %d0. So if a function pointer is declared to return a pointer, the
|
||||
* compiler may look only into %a0, but if the called function was declared
|
||||
* to return an integer type, it puts its value only into %d0. So the
|
||||
* caller doesn't pink up the correct return value. The solution is to
|
||||
* declare the function pointer to return int, so the compiler picks up the
|
||||
* return value from %d0. (Functions returning pointers put their value
|
||||
* *additionally* into %d0 for compatibility.) The price is that there are
|
||||
* some warnings about int->pointer conversions...
|
||||
*/
|
||||
#if defined(__mc68000__) && defined(__ELF__)
|
||||
typedef int32 ((*func_ptr) ());
|
||||
#else
|
||||
typedef char *((*func_ptr) ());
|
||||
#endif
|
||||
|
||||
|
||||
static Datum fmgr_oldstyle(PG_FUNCTION_ARGS);
|
||||
static Datum fmgr_untrusted(PG_FUNCTION_ARGS);
|
||||
static Datum fmgr_sql(PG_FUNCTION_ARGS);
|
||||
@@ -377,7 +398,7 @@ fmgr_oldstyle(PG_FUNCTION_ARGS)
|
||||
default:
|
||||
/*
|
||||
* Increasing FUNC_MAX_ARGS doesn't automatically add cases
|
||||
* to the above code, so give the actual value in this error
|
||||
* to the above code, so mention the actual value in this error
|
||||
* not FUNC_MAX_ARGS. You could add cases to the above if you
|
||||
* needed to support old-style functions with many arguments,
|
||||
* but making 'em be new-style is probably a better idea.
|
||||
@@ -420,100 +441,6 @@ fmgr_sql(PG_FUNCTION_ARGS)
|
||||
return 0; /* keep compiler happy */
|
||||
}
|
||||
|
||||
#if 0
|
||||
|
||||
/*
|
||||
* Interface routine for functions using fmgr_faddr
|
||||
*/
|
||||
FmgrInfo *fmgr_pl_finfo; /* should GO AWAY */
|
||||
|
||||
char *
|
||||
fmgr_faddr_link(char *arg0, ...)
|
||||
{
|
||||
FunctionCallInfoData fcinfo;
|
||||
int n_arguments;
|
||||
Datum result;
|
||||
|
||||
MemSet(&fcinfo, 0, sizeof(fcinfo));
|
||||
/* We rely on fmgr_faddr macro to have set back-link to FmgrInfo (ugh) */
|
||||
fcinfo.flinfo = fmgr_pl_finfo;
|
||||
fcinfo.nargs = fcinfo.flinfo->fn_nargs;
|
||||
n_arguments = fcinfo.nargs;
|
||||
|
||||
if (n_arguments > 0)
|
||||
{
|
||||
fcinfo.arg[0] = (Datum) arg0;
|
||||
if (n_arguments > 1)
|
||||
{
|
||||
va_list pvar;
|
||||
int i;
|
||||
|
||||
if (n_arguments > FUNC_MAX_ARGS)
|
||||
elog(ERROR, "fmgr_faddr_link: function %u: too many arguments (%d > %d)",
|
||||
fcinfo.flinfo->fn_oid, n_arguments, FUNC_MAX_ARGS);
|
||||
va_start(pvar, arg0);
|
||||
for (i = 1; i < n_arguments; i++)
|
||||
fcinfo.arg[i] = (Datum) va_arg(pvar, char *);
|
||||
va_end(pvar);
|
||||
}
|
||||
}
|
||||
|
||||
result = FunctionCallInvoke(&fcinfo);
|
||||
|
||||
/* Check for null result, since caller is clearly not expecting one */
|
||||
if (fcinfo.isnull)
|
||||
elog(ERROR, "fmgr_faddr_link: function %u returned NULL",
|
||||
fcinfo.flinfo->fn_oid);
|
||||
|
||||
return (char *) result;
|
||||
}
|
||||
|
||||
/*
|
||||
* fmgr - return the value of a function call
|
||||
*
|
||||
* This is essentially fmgr_info plus call the function.
|
||||
*/
|
||||
char *
|
||||
fmgr(Oid procedureId,...)
|
||||
{
|
||||
FmgrInfo flinfo;
|
||||
FunctionCallInfoData fcinfo;
|
||||
int n_arguments;
|
||||
Datum result;
|
||||
|
||||
fmgr_info(procedureId, &flinfo);
|
||||
|
||||
MemSet(&fcinfo, 0, sizeof(fcinfo));
|
||||
fcinfo.flinfo = &flinfo;
|
||||
fcinfo.nargs = flinfo.fn_nargs;
|
||||
n_arguments = fcinfo.nargs;
|
||||
|
||||
if (n_arguments > 0)
|
||||
{
|
||||
va_list pvar;
|
||||
int i;
|
||||
|
||||
if (n_arguments > FUNC_MAX_ARGS)
|
||||
elog(ERROR, "fmgr: function %u: too many arguments (%d > %d)",
|
||||
flinfo.fn_oid, n_arguments, FUNC_MAX_ARGS);
|
||||
va_start(pvar, procedureId);
|
||||
for (i = 0; i < n_arguments; i++)
|
||||
fcinfo.arg[i] = (Datum) va_arg(pvar, char *);
|
||||
va_end(pvar);
|
||||
}
|
||||
|
||||
result = FunctionCallInvoke(&fcinfo);
|
||||
|
||||
/* Check for null result, since caller is clearly not expecting one */
|
||||
if (fcinfo.isnull)
|
||||
elog(ERROR, "fmgr: function %u returned NULL",
|
||||
flinfo.fn_oid);
|
||||
|
||||
return (char *) result;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
/*-------------------------------------------------------------------------
|
||||
* Support routines for callers of fmgr-compatible functions
|
||||
@@ -1267,6 +1194,57 @@ OidFunctionCall9(Oid functionId, Datum arg1, Datum arg2,
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* !!! OLD INTERFACE !!!
|
||||
*
|
||||
* fmgr() is the only remaining vestige of the old-style caller support
|
||||
* functions. It's no longer used anywhere in the Postgres distribution,
|
||||
* but we should leave it around for a release or two to ease the transition
|
||||
* for user-supplied C functions. OidFunctionCallN() replaces it for new
|
||||
* code.
|
||||
*
|
||||
* DEPRECATED, DO NOT USE IN NEW CODE
|
||||
*/
|
||||
char *
|
||||
fmgr(Oid procedureId,...)
|
||||
{
|
||||
FmgrInfo flinfo;
|
||||
FunctionCallInfoData fcinfo;
|
||||
int n_arguments;
|
||||
Datum result;
|
||||
|
||||
fmgr_info(procedureId, &flinfo);
|
||||
|
||||
MemSet(&fcinfo, 0, sizeof(fcinfo));
|
||||
fcinfo.flinfo = &flinfo;
|
||||
fcinfo.nargs = flinfo.fn_nargs;
|
||||
n_arguments = fcinfo.nargs;
|
||||
|
||||
if (n_arguments > 0)
|
||||
{
|
||||
va_list pvar;
|
||||
int i;
|
||||
|
||||
if (n_arguments > FUNC_MAX_ARGS)
|
||||
elog(ERROR, "fmgr: function %u: too many arguments (%d > %d)",
|
||||
flinfo.fn_oid, n_arguments, FUNC_MAX_ARGS);
|
||||
va_start(pvar, procedureId);
|
||||
for (i = 0; i < n_arguments; i++)
|
||||
fcinfo.arg[i] = (Datum) va_arg(pvar, char *);
|
||||
va_end(pvar);
|
||||
}
|
||||
|
||||
result = FunctionCallInvoke(&fcinfo);
|
||||
|
||||
/* Check for null result, since caller is clearly not expecting one */
|
||||
if (fcinfo.isnull)
|
||||
elog(ERROR, "fmgr: function %u returned NULL",
|
||||
flinfo.fn_oid);
|
||||
|
||||
return (char *) result;
|
||||
}
|
||||
|
||||
|
||||
/*-------------------------------------------------------------------------
|
||||
* Support routines for standard pass-by-reference datatypes
|
||||
*
|
||||
|
||||
Reference in New Issue
Block a user