diff options
author | Tom Lane <tgl@sss.pgh.pa.us> | 2000-06-05 07:29:25 +0000 |
---|---|---|
committer | Tom Lane <tgl@sss.pgh.pa.us> | 2000-06-05 07:29:25 +0000 |
commit | 48165ec2262b73c5b81a6caabab66d883d013a83 (patch) | |
tree | 08e878a2a1e7f76981406ac2b34729a510aecac6 /src/backend/utils | |
parent | c61db5ba2decf2e620f6ce3699d4b702957ed72a (diff) | |
download | postgresql-48165ec2262b73c5b81a6caabab66d883d013a83.tar.gz postgresql-48165ec2262b73c5b81a6caabab66d883d013a83.zip |
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.
Diffstat (limited to 'src/backend/utils')
-rw-r--r-- | src/backend/utils/adt/acl.c | 21 | ||||
-rw-r--r-- | src/backend/utils/adt/bool.c | 157 | ||||
-rw-r--r-- | src/backend/utils/adt/cash.c | 76 | ||||
-rw-r--r-- | src/backend/utils/adt/char.c | 218 | ||||
-rw-r--r-- | src/backend/utils/adt/float.c | 79 | ||||
-rw-r--r-- | src/backend/utils/adt/formatting.c | 10 | ||||
-rw-r--r-- | src/backend/utils/adt/geo_selfuncs.c | 86 | ||||
-rw-r--r-- | src/backend/utils/adt/int.c | 761 | ||||
-rw-r--r-- | src/backend/utils/adt/misc.c | 73 | ||||
-rw-r--r-- | src/backend/utils/adt/numeric.c | 34 | ||||
-rw-r--r-- | src/backend/utils/adt/oid.c | 193 | ||||
-rw-r--r-- | src/backend/utils/adt/regproc.c | 64 | ||||
-rw-r--r-- | src/backend/utils/adt/selfuncs.c | 441 | ||||
-rw-r--r-- | src/backend/utils/adt/varchar.c | 44 | ||||
-rw-r--r-- | src/backend/utils/cache/catcache.c | 48 | ||||
-rw-r--r-- | src/backend/utils/fmgr/fmgr.c | 170 |
16 files changed, 1287 insertions, 1188 deletions
diff --git a/src/backend/utils/adt/acl.c b/src/backend/utils/adt/acl.c index 6c27fbe03fa..0a6c664e7dc 100644 --- a/src/backend/utils/adt/acl.c +++ b/src/backend/utils/adt/acl.c @@ -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); } diff --git a/src/backend/utils/adt/bool.c b/src/backend/utils/adt/bool.c index c5657babcf8..bdf695aa522 100644 --- a/src/backend/utils/adt/bool.c +++ b/src/backend/utils/adt/bool.c @@ -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) +{ + bool arg1 = PG_GETARG_BOOL(0); + bool arg2 = PG_GETARG_BOOL(1); + + PG_RETURN_BOOL(arg1 <= arg2); +} + +Datum +boolge(PG_FUNCTION_ARGS) +{ + bool arg1 = PG_GETARG_BOOL(0); + bool arg2 = PG_GETARG_BOOL(1); + + PG_RETURN_BOOL(arg1 >= arg2); +} + +/* + * 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. + */ + +Datum +istrue(PG_FUNCTION_ARGS) { - return arg1 <= arg2; + bool b; + + if (PG_ARGISNULL(0)) + PG_RETURN_BOOL(false); + + b = PG_GETARG_BOOL(0); + + PG_RETURN_BOOL(b); } -bool -boolge(bool arg1, bool arg2) +Datum +isfalse(PG_FUNCTION_ARGS) { - return arg1 >= arg2; + bool b; + + if (PG_ARGISNULL(0)) + PG_RETURN_BOOL(false); + + b = PG_GETARG_BOOL(0); + + PG_RETURN_BOOL(! b); } -bool -istrue(bool arg1) +Datum +isnottrue(PG_FUNCTION_ARGS) { - return arg1 == TRUE; -} /* istrue() */ + bool b; -bool -isfalse(bool arg1) + if (PG_ARGISNULL(0)) + PG_RETURN_BOOL(true); + + b = PG_GETARG_BOOL(0); + + PG_RETURN_BOOL(! b); +} + +Datum +isnotfalse(PG_FUNCTION_ARGS) { - return arg1 != TRUE; -} /* isfalse() */ + bool b; + + if (PG_ARGISNULL(0)) + PG_RETURN_BOOL(true); + + b = PG_GETARG_BOOL(0); + + PG_RETURN_BOOL(b); +} diff --git a/src/backend/utils/adt/cash.c b/src/backend/utils/adt/cash.c index 9a06bc38954..9bfc46bda6c 100644 --- a/src/backend/utils/adt/cash.c +++ b/src/backend/utils/adt/cash.c @@ -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. diff --git a/src/backend/utils/adt/char.c b/src/backend/utils/adt/char.c index 6675e4cb996..04e40406f8b 100644 --- a/src/backend/utils/adt/char.c +++ b/src/backend/utils/adt/char.c @@ -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); } +/***************************************************************************** + * PUBLIC ROUTINES * + *****************************************************************************/ + /* - * cidin - converts "..." to internal representation. + * NOTE: comparisons are done as though char is unsigned (uint8). + * Arithmetic is done as though char is signed (int8). * - * NOTE: we must not use 'charin' because cid might be a non - * printable character... + * You wanted consistency? */ -int32 -cidin(char *s) -{ - CommandId c; - if (s == NULL) - c = 0; - else - c = atoi(s); +Datum +chareq(PG_FUNCTION_ARGS) +{ + char arg1 = PG_GETARG_CHAR(0); + char arg2 = PG_GETARG_CHAR(1); - return (int32) c; + PG_RETURN_BOOL(arg1 == arg2); } -/* - * cidout - converts a cid to "..." - * - * NOTE: we must no use 'charout' because cid might be a non - * printable character... - */ -char * -cidout(int32 c) +Datum +charne(PG_FUNCTION_ARGS) { - char *result; - CommandId c2; + char arg1 = PG_GETARG_CHAR(0); + char arg2 = PG_GETARG_CHAR(1); - result = palloc(12); - c2 = (CommandId) c; - sprintf(result, "%u", (unsigned) (c2)); - return result; + PG_RETURN_BOOL(arg1 != arg2); } - -/***************************************************************************** - * PUBLIC ROUTINES * - *****************************************************************************/ - -bool -chareq(int8 arg1, int8 arg2) +Datum +charlt(PG_FUNCTION_ARGS) { - return arg1 == arg2; + char arg1 = PG_GETARG_CHAR(0); + char arg2 = PG_GETARG_CHAR(1); + + PG_RETURN_BOOL((uint8) arg1 < (uint8) arg2); } -bool -charne(int8 arg1, int8 arg2) +Datum +charle(PG_FUNCTION_ARGS) { - return arg1 != arg2; + char arg1 = PG_GETARG_CHAR(0); + char arg2 = PG_GETARG_CHAR(1); + + PG_RETURN_BOOL((uint8) arg1 <= (uint8) arg2); } -bool -charlt(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 -charle(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); } -bool -chargt(int8 arg1, int8 arg2) +Datum +charpl(PG_FUNCTION_ARGS) { - return (uint8) arg1 > (uint8) arg2; + char arg1 = PG_GETARG_CHAR(0); + char arg2 = PG_GETARG_CHAR(1); + + PG_RETURN_CHAR((int8) arg1 + (int8) arg2); } -bool -charge(int8 arg1, int8 arg2) +Datum +charmi(PG_FUNCTION_ARGS) { - return (uint8) arg1 >= (uint8) arg2; + char arg1 = PG_GETARG_CHAR(0); + char arg2 = PG_GETARG_CHAR(1); + + PG_RETURN_CHAR((int8) arg1 - (int8) arg2); } -int8 -charpl(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 -charmi(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); } -int8 -charmul(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 -chardiv(int8 arg1, int8 arg2) +Datum +char_text(PG_FUNCTION_ARGS) { - return arg1 / arg2; + char arg1 = PG_GETARG_CHAR(0); + text *result = palloc(VARHDRSZ + 1); + + VARSIZE(result) = VARHDRSZ + 1; + *(VARDATA(result)) = arg1; + + PG_RETURN_TEXT_P(result); } -bool -cideq(int8 arg1, int8 arg2) + +/***************************************************************************** + * USER I/O ROUTINES * + *****************************************************************************/ + +/* + * cidin - converts CommandId to internal representation. + */ +Datum +cidin(PG_FUNCTION_ARGS) { - return arg1 == arg2; + char *s = PG_GETARG_CSTRING(0); + CommandId c; + + c = atoi(s); + + /* XXX assume that CommandId is 32 bits... */ + PG_RETURN_INT32((int32) c); } -int8 -text_char(text *arg1) +/* + * cidout - converts a cid to external representation. + */ +Datum +cidout(PG_FUNCTION_ARGS) { - return ((int8) *(VARDATA(arg1))); + /* 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); } -text * -char_text(int8 arg1) -{ - text *result; +/***************************************************************************** + * PUBLIC ROUTINES * + *****************************************************************************/ - result = palloc(VARHDRSZ + 1); - VARSIZE(result) = VARHDRSZ + 1; - *(VARDATA(result)) = arg1; +Datum +cideq(PG_FUNCTION_ARGS) +{ + /* XXX assume that CommandId is 32 bits... */ + CommandId arg1 = PG_GETARG_INT32(0); + CommandId arg2 = PG_GETARG_INT32(1); - return result; + PG_RETURN_BOOL(arg1 == arg2); } diff --git a/src/backend/utils/adt/float.c b/src/backend/utils/adt/float.c index 354ee0110b7..b7b654cc320 100644 --- a/src/backend/utils/adt/float.c +++ b/src/backend/utils/adt/float.c @@ -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; - - result = (float32) palloc(sizeof(float32data)); + int16 num = PG_GETARG_INT16(0); + float4 result; - *result = num; - return result; + result = num; + PG_RETURN_FLOAT4(result); } diff --git a/src/backend/utils/adt/formatting.c b/src/backend/utils/adt/formatting.c index 8d204a15957..674bbefea54 100644 --- a/src/backend/utils/adt/formatting.c +++ b/src/backend/utils/adt/formatting.c @@ -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 == '-') diff --git a/src/backend/utils/adt/geo_selfuncs.c b/src/backend/utils/adt/geo_selfuncs.c index 5b77e1c3301..e5f239612eb 100644 --- a/src/backend/utils/adt/geo_selfuncs.c +++ b/src/backend/utils/adt/geo_selfuncs.c @@ -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); } diff --git a/src/backend/utils/adt/int.c b/src/backend/utils/adt/int.c index 242e9c54011..6e236a01c74 100644 --- a/src/backend/utils/adt/int.c +++ b/src/backend/utils/adt/int.c @@ -1,14 +1,14 @@ /*------------------------------------------------------------------------- * * int.c - * Functions for the built-in integer types. + * Functions for the built-in integer types (except int8). * * Portions Copyright (c) 1996-2000, PostgreSQL, Inc * Portions Copyright (c) 1994, Regents of the University of California * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/utils/adt/int.c,v 1.36 2000/04/12 17:15:50 momjian Exp $ + * $Header: /cvsroot/pgsql/src/backend/utils/adt/int.c,v 1.37 2000/06/05 07:28:52 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -25,13 +25,12 @@ * * Arithmetic operators: * intmod, int4fac - * - * XXX makes massive and possibly unwarranted type promotion assumptions. - * fix me when we figure out what we want to do about ANSIfication... */ #include <ctype.h> + #include "postgres.h" + #ifdef HAVE_LIMITS_H #include <limits.h> #endif @@ -52,42 +51,39 @@ /* * int2in - converts "num" to short */ -int32 -int2in(char *num) +Datum +int2in(PG_FUNCTION_ARGS) { - return (int32) pg_atoi(num, sizeof(int16), '\0'); + char *num = PG_GETARG_CSTRING(0); + + PG_RETURN_INT16(pg_atoi(num, sizeof(int16), '\0')); } /* * int2out - converts short to "num" */ -char * -int2out(int16 sh) +Datum +int2out(PG_FUNCTION_ARGS) { - char *result; + int16 arg1 = PG_GETARG_INT16(0); + char *result = (char *) palloc(7); /* sign, 5 digits, '\0' */ - result = (char *) palloc(7);/* assumes sign, 5 digits, '\0' */ - itoa((int) sh, result); - return result; + itoa((int) arg1, result); + PG_RETURN_CSTRING(result); } /* * int2vectorin - converts "num num ..." to internal form * - * Note: - * Fills any nonexistent digits with NULLs. + * Note: Fills any missing slots with zeroes. */ -int16 * -int2vectorin(char *intString) +Datum +int2vectorin(PG_FUNCTION_ARGS) { - int16 *result; + char *intString = PG_GETARG_CSTRING(0); + int16 *result = (int16 *) palloc(sizeof(int16[INDEX_MAX_KEYS])); int slot; - if (intString == NULL) - return NULL; - - result = (int16 *) palloc(sizeof(int16[INDEX_MAX_KEYS])); - for (slot = 0; *intString && slot < INDEX_MAX_KEYS; slot++) { if (sscanf(intString, "%hd", &result[slot]) != 1) @@ -104,28 +100,21 @@ int2vectorin(char *intString) while (slot < INDEX_MAX_KEYS) result[slot++] = 0; - return result; + PG_RETURN_POINTER(result); } /* * int2vectorout - converts internal form to "num num ..." */ -char * -int2vectorout(int16 *int2Array) +Datum +int2vectorout(PG_FUNCTION_ARGS) { + int16 *int2Array = (int16 *) PG_GETARG_POINTER(0); int num, maxnum; char *rp; char *result; - if (int2Array == NULL) - { - result = (char *) palloc(2); - result[0] = '-'; - result[1] = '\0'; - return result; - } - /* find last non-zero value in vector */ for (maxnum = INDEX_MAX_KEYS - 1; maxnum >= 0; maxnum--) if (int2Array[maxnum] != 0) @@ -142,71 +131,72 @@ int2vectorout(int16 *int2Array) ; } *rp = '\0'; - return result; + PG_RETURN_CSTRING(result); } /* * We don't have a complete set of int2vector support routines, * but we need int2vectoreq for catcache indexing. */ -bool -int2vectoreq(int16 *arg1, int16 *arg2) +Datum +int2vectoreq(PG_FUNCTION_ARGS) { - return (bool) (memcmp(arg1, arg2, INDEX_MAX_KEYS * sizeof(int16)) == 0); + int16 *arg1 = (int16 *) PG_GETARG_POINTER(0); + int16 *arg2 = (int16 *) PG_GETARG_POINTER(1); + + PG_RETURN_BOOL(memcmp(arg1, arg2, INDEX_MAX_KEYS * sizeof(int16)) == 0); } +/* + * Type int44 has no real-world use, but the regression tests use it. + * It's a four-element vector of int4's. + */ /* * int44in - converts "num num ..." to internal form * - * Note: - * Fills any nonexistent digits with NULLs. + * Note: Fills any missing positions with zeroes. */ -int32 * -int44in(char *input_string) +Datum +int44in(PG_FUNCTION_ARGS) { - int32 *foo = (int32 *) palloc(4 * sizeof(int32)); - int i = 0; + char *input_string = PG_GETARG_CSTRING(0); + int32 *result = (int32 *) palloc(4 * sizeof(int32)); + int i; i = sscanf(input_string, "%d, %d, %d, %d", - &foo[0], - &foo[1], - &foo[2], - &foo[3]); + &result[0], + &result[1], + &result[2], + &result[3]); while (i < 4) - foo[i++] = 0; + result[i++] = 0; - return foo; + PG_RETURN_POINTER(result); } /* * int44out - converts internal form to "num num ..." */ -char * -int44out(int32 *an_array) +Datum +int44out(PG_FUNCTION_ARGS) { - int temp = 4; - char *output_string = NULL; + int32 *an_array = (int32 *) PG_GETARG_POINTER(0); + char *result = (char *) palloc(16 * 4); /* Allow 14 digits + sign */ int i; + char *walk; - if (temp > 0) + walk = result; + for (i = 0; i < 4; i++) { - char *walk; - - output_string = (char *) palloc(16 * temp); /* assume 15 digits + - * sign */ - walk = output_string; - for (i = 0; i < temp; i++) - { - itoa(an_array[i], walk); - while (*++walk != '\0') - ; - *walk++ = ' '; - } - *--walk = '\0'; + itoa(an_array[i], walk); + while (*++walk != '\0') + ; + *walk++ = ' '; } - return output_string; + *--walk = '\0'; + PG_RETURN_CSTRING(result); } @@ -217,23 +207,25 @@ int44out(int32 *an_array) /* * int4in - converts "num" to int4 */ -int32 -int4in(char *num) +Datum +int4in(PG_FUNCTION_ARGS) { - return pg_atoi(num, sizeof(int32), '\0'); + char *num = PG_GETARG_CSTRING(0); + + PG_RETURN_INT32(pg_atoi(num, sizeof(int32), '\0')); } /* * int4out - converts int4 to "num" */ -char * -int4out(int32 l) +Datum +int4out(PG_FUNCTION_ARGS) { - char *result; + int32 arg1 = PG_GETARG_INT32(0); + char *result = (char *) palloc(12); /* sign, 10 digits, '\0' */ - result = (char *) palloc(12); /* assumes sign, 10 digits, '\0' */ - ltoa(l, result); - return result; + ltoa(arg1, result); + PG_RETURN_CSTRING(result); } @@ -243,116 +235,94 @@ int4out(int32 l) * =================== */ -int32 -i2toi4(int16 arg1) +Datum +i2toi4(PG_FUNCTION_ARGS) { - return (int32) arg1; + int16 arg1 = PG_GETARG_INT16(0); + + PG_RETURN_INT32((int32) arg1); } -int16 -i4toi2(int32 arg1) +Datum +i4toi2(PG_FUNCTION_ARGS) { + int32 arg1 = PG_GETARG_INT32(0); + if (arg1 < SHRT_MIN) elog(ERROR, "i4toi2: '%d' causes int2 underflow", arg1); if (arg1 > SHRT_MAX) elog(ERROR, "i4toi2: '%d' causes int2 overflow", arg1); - return (int16) arg1; + PG_RETURN_INT16((int16) arg1); } -text * -int2_text(int16 arg1) +Datum +int2_text(PG_FUNCTION_ARGS) { - text *result; - - int len; - char *str; - - str = int2out(arg1); - len = (strlen(str) + VARHDRSZ); - - result = palloc(len); + int16 arg1 = PG_GETARG_INT16(0); + text *result = (text *) palloc(7+VARHDRSZ); /* sign,5 digits, '\0' */ - VARSIZE(result) = len; - memmove(VARDATA(result), str, (len - VARHDRSZ)); - - pfree(str); - - return result; -} /* int2_text() */ + itoa((int) arg1, VARDATA(result)); + VARSIZE(result) = strlen(VARDATA(result)) + VARHDRSZ; + PG_RETURN_TEXT_P(result); +} -int16 -text_int2(text *string) +Datum +text_int2(PG_FUNCTION_ARGS) { - int16 result; - + text *string = PG_GETARG_TEXT_P(0); + Datum result; int len; char *str; - if (!string) - return 0; - - len = (VARSIZE(string) - VARHDRSZ); + len = VARSIZE(string) - VARHDRSZ; str = palloc(len + 1); - memmove(str, VARDATA(string), len); + memcpy(str, VARDATA(string), len); *(str + len) = '\0'; - result = int2in(str); + result = DirectFunctionCall1(int2in, CStringGetDatum(str)); pfree(str); return result; -} /* text_int2() */ +} -text * -int4_text(int32 arg1) +Datum +int4_text(PG_FUNCTION_ARGS) { - text *result; - - int len; - char *str; - - str = int4out(arg1); - len = (strlen(str) + VARHDRSZ); - - result = palloc(len); - - VARSIZE(result) = len; - memmove(VARDATA(result), str, (len - VARHDRSZ)); + int32 arg1 = PG_GETARG_INT32(0); + text *result = (text *) palloc(12+VARHDRSZ); /* sign,10 digits,'\0' */ - pfree(str); - - return result; -} /* int4_text() */ + ltoa(arg1, VARDATA(result)); + VARSIZE(result) = strlen(VARDATA(result)) + VARHDRSZ; + PG_RETURN_TEXT_P(result); +} -int32 -text_int4(text *string) +Datum +text_int4(PG_FUNCTION_ARGS) { - int32 result; - + text *string = PG_GETARG_TEXT_P(0); + Datum result; int len; char *str; - if (!string) - return 0; - - len = (VARSIZE(string) - VARHDRSZ); + len = VARSIZE(string) - VARHDRSZ; str = palloc(len + 1); - memmove(str, VARDATA(string), len); + memcpy(str, VARDATA(string), len); *(str + len) = '\0'; - result = int4in(str); + result = DirectFunctionCall1(int4in, CStringGetDatum(str)); pfree(str); return result; -} /* text_int4() */ +} /* - * ========================= - * BOOLEAN OPERATOR ROUTINES - * ========================= + * ============================ + * COMPARISON OPERATOR ROUTINES + * ============================ */ /* @@ -363,148 +333,221 @@ text_int4(text *string) * intgt - returns 1 iff arg1 > arg2 * intge - returns 1 iff arg1 >= arg2 */ -bool -int4eq(int32 arg1, int32 arg2) + +Datum +int4eq(PG_FUNCTION_ARGS) { - return arg1 == arg2; + int32 arg1 = PG_GETARG_INT32(0); + int32 arg2 = PG_GETARG_INT32(1); + + PG_RETURN_BOOL(arg1 == arg2); } -bool -int4ne(int32 arg1, int32 arg2) +Datum +int4ne(PG_FUNCTION_ARGS) { - return arg1 != arg2; + int32 arg1 = PG_GETARG_INT32(0); + int32 arg2 = PG_GETARG_INT32(1); + + PG_RETURN_BOOL(arg1 != arg2); } -bool -int4lt(int32 arg1, int32 arg2) +Datum +int4lt(PG_FUNCTION_ARGS) { - return arg1 < arg2; + int32 arg1 = PG_GETARG_INT32(0); + int32 arg2 = PG_GETARG_INT32(1); + + PG_RETURN_BOOL(arg1 < arg2); } -bool -int4le(int32 arg1, int32 arg2) +Datum +int4le(PG_FUNCTION_ARGS) { - return arg1 <= arg2; + int32 arg1 = PG_GETARG_INT32(0); + int32 arg2 = PG_GETARG_INT32(1); + + PG_RETURN_BOOL(arg1 <= arg2); } -bool -int4gt(int32 arg1, int32 arg2) +Datum +int4gt(PG_FUNCTION_ARGS) { - return arg1 > arg2; + int32 arg1 = PG_GETARG_INT32(0); + int32 arg2 = PG_GETARG_INT32(1); + + PG_RETURN_BOOL(arg1 > arg2); } -bool -int4ge(int32 arg1, int32 arg2) +Datum +int4ge(PG_FUNCTION_ARGS) { - return arg1 >= arg2; + int32 arg1 = PG_GETARG_INT32(0); + int32 arg2 = PG_GETARG_INT32(1); + + PG_RETURN_BOOL(arg1 >= arg2); } -bool -int2eq(int16 arg1, int16 arg2) +Datum +int2eq(PG_FUNCTION_ARGS) { - return arg1 == arg2; + int16 arg1 = PG_GETARG_INT16(0); + int16 arg2 = PG_GETARG_INT16(1); + + PG_RETURN_BOOL(arg1 == arg2); } -bool -int2ne(int16 arg1, int16 arg2) +Datum +int2ne(PG_FUNCTION_ARGS) { - return arg1 != arg2; + int16 arg1 = PG_GETARG_INT16(0); + int16 arg2 = PG_GETARG_INT16(1); + + PG_RETURN_BOOL(arg1 != arg2); } -bool -int2lt(int16 arg1, int16 arg2) +Datum +int2lt(PG_FUNCTION_ARGS) { - return arg1 < arg2; + int16 arg1 = PG_GETARG_INT16(0); + int16 arg2 = PG_GETARG_INT16(1); + + PG_RETURN_BOOL(arg1 < arg2); } -bool -int2le(int16 arg1, int16 arg2) +Datum +int2le(PG_FUNCTION_ARGS) { - return arg1 <= arg2; + int16 arg1 = PG_GETARG_INT16(0); + int16 arg2 = PG_GETARG_INT16(1); + + PG_RETURN_BOOL(arg1 <= arg2); } -bool -int2gt(int16 arg1, int16 arg2) +Datum +int2gt(PG_FUNCTION_ARGS) { - return arg1 > arg2; + int16 arg1 = PG_GETARG_INT16(0); + int16 arg2 = PG_GETARG_INT16(1); + + PG_RETURN_BOOL(arg1 > arg2); } -bool -int2ge(int16 arg1, int16 arg2) +Datum +int2ge(PG_FUNCTION_ARGS) { - return arg1 >= arg2; + int16 arg1 = PG_GETARG_INT16(0); + int16 arg2 = PG_GETARG_INT16(1); + + PG_RETURN_BOOL(arg1 >= arg2); } -bool -int24eq(int32 arg1, int32 arg2) +Datum +int24eq(PG_FUNCTION_ARGS) { - return arg1 == arg2; + int16 arg1 = PG_GETARG_INT16(0); + int32 arg2 = PG_GETARG_INT32(1); + + PG_RETURN_BOOL(arg1 == arg2); } -bool -int24ne(int32 arg1, int32 arg2) +Datum +int24ne(PG_FUNCTION_ARGS) { - return arg1 != arg2; + int16 arg1 = PG_GETARG_INT16(0); + int32 arg2 = PG_GETARG_INT32(1); + + PG_RETURN_BOOL(arg1 != arg2); } -bool -int24lt(int32 arg1, int32 arg2) +Datum +int24lt(PG_FUNCTION_ARGS) { - return arg1 < arg2; + int16 arg1 = PG_GETARG_INT16(0); + int32 arg2 = PG_GETARG_INT32(1); + + PG_RETURN_BOOL(arg1 < arg2); } -bool -int24le(int32 arg1, int32 arg2) +Datum +int24le(PG_FUNCTION_ARGS) { - return arg1 <= arg2; + int16 arg1 = PG_GETARG_INT16(0); + int32 arg2 = PG_GETARG_INT32(1); + + PG_RETURN_BOOL(arg1 <= arg2); } -bool -int24gt(int32 arg1, int32 arg2) +Datum +int24gt(PG_FUNCTION_ARGS) { - return arg1 > arg2; + int16 arg1 = PG_GETARG_INT16(0); + int32 arg2 = PG_GETARG_INT32(1); + + PG_RETURN_BOOL(arg1 > arg2); } -bool -int24ge(int32 arg1, int32 arg2) +Datum +int24ge(PG_FUNCTION_ARGS) { - return arg1 >= arg2; + int16 arg1 = PG_GETARG_INT16(0); + int32 arg2 = PG_GETARG_INT32(1); + + PG_RETURN_BOOL(arg1 >= arg2); } -bool -int42eq(int32 arg1, int32 arg2) +Datum +int42eq(PG_FUNCTION_ARGS) { - return arg1 == arg2; + int32 arg1 = PG_GETARG_INT32(0); + int16 arg2 = PG_GETARG_INT16(1); + + PG_RETURN_BOOL(arg1 == arg2); } -bool -int42ne(int32 arg1, int32 arg2) +Datum +int42ne(PG_FUNCTION_ARGS) { - return arg1 != arg2; + int32 arg1 = PG_GETARG_INT32(0); + int16 arg2 = PG_GETARG_INT16(1); + + PG_RETURN_BOOL(arg1 != arg2); } -bool -int42lt(int32 arg1, int32 arg2) +Datum +int42lt(PG_FUNCTION_ARGS) { - return arg1 < arg2; + int32 arg1 = PG_GETARG_INT32(0); + int16 arg2 = PG_GETARG_INT16(1); + + PG_RETURN_BOOL(arg1 < arg2); } -bool -int42le(int32 arg1, int32 arg2) +Datum +int42le(PG_FUNCTION_ARGS) { - return arg1 <= arg2; + int32 arg1 = PG_GETARG_INT32(0); + int16 arg2 = PG_GETARG_INT16(1); + + PG_RETURN_BOOL(arg1 <= arg2); } -bool -int42gt(int32 arg1, int32 arg2) +Datum +int42gt(PG_FUNCTION_ARGS) { - return arg1 > arg2; + int32 arg1 = PG_GETARG_INT32(0); + int16 arg2 = PG_GETARG_INT16(1); + + PG_RETURN_BOOL(arg1 > arg2); } -bool -int42ge(int32 arg1, int32 arg2) +Datum +int42ge(PG_FUNCTION_ARGS) { - return arg1 >= arg2; + int32 arg1 = PG_GETARG_INT32(0); + int16 arg2 = PG_GETARG_INT16(1); + + PG_RETURN_BOOL(arg1 >= arg2); } /* @@ -513,159 +556,226 @@ int42ge(int32 arg1, int32 arg2) * int[24]mul - returns arg1 * arg2 * int[24]div - returns arg1 / arg2 */ -int32 -int4um(int32 arg) + +Datum +int4um(PG_FUNCTION_ARGS) { - return -arg; + int32 arg = PG_GETARG_INT32(0); + + PG_RETURN_INT32(-arg); } -int32 -int4pl(int32 arg1, int32 arg2) +Datum +int4pl(PG_FUNCTION_ARGS) { - return arg1 + arg2; + int32 arg1 = PG_GETARG_INT32(0); + int32 arg2 = PG_GETARG_INT32(1); + + PG_RETURN_INT32(arg1 + arg2); } -int32 -int4mi(int32 arg1, int32 arg2) +Datum +int4mi(PG_FUNCTION_ARGS) { - return arg1 - arg2; + int32 arg1 = PG_GETARG_INT32(0); + int32 arg2 = PG_GETARG_INT32(1); + + PG_RETURN_INT32(arg1 - arg2); } -int32 -int4mul(int32 arg1, int32 arg2) +Datum +int4mul(PG_FUNCTION_ARGS) { - return arg1 * arg2; + int32 arg1 = PG_GETARG_INT32(0); + int32 arg2 = PG_GETARG_INT32(1); + + PG_RETURN_INT32(arg1 * arg2); } -int32 -int4div(int32 arg1, int32 arg2) +Datum +int4div(PG_FUNCTION_ARGS) { - return arg1 / arg2; + int32 arg1 = PG_GETARG_INT32(0); + int32 arg2 = PG_GETARG_INT32(1); + + PG_RETURN_INT32(arg1 / arg2); } -int32 -int4inc(int32 arg) +Datum +int4inc(PG_FUNCTION_ARGS) { - return arg + (int32) 1; + int32 arg = PG_GETARG_INT32(0); + + PG_RETURN_INT32(arg + 1); } -int16 -int2um(int16 arg) +Datum +int2um(PG_FUNCTION_ARGS) { - return -arg; + int16 arg = PG_GETARG_INT16(0); + + PG_RETURN_INT16(-arg); } -int16 -int2pl(int16 arg1, int16 arg2) +Datum +int2pl(PG_FUNCTION_ARGS) { - return arg1 + arg2; + int16 arg1 = PG_GETARG_INT16(0); + int16 arg2 = PG_GETARG_INT16(1); + + PG_RETURN_INT16(arg1 + arg2); } -int16 -int2mi(int16 arg1, int16 arg2) +Datum +int2mi(PG_FUNCTION_ARGS) { - return arg1 - arg2; + int16 arg1 = PG_GETARG_INT16(0); + int16 arg2 = PG_GETARG_INT16(1); + + PG_RETURN_INT16(arg1 - arg2); } -int16 -int2mul(int16 arg1, int16 arg2) +Datum +int2mul(PG_FUNCTION_ARGS) { - return arg1 * arg2; + int16 arg1 = PG_GETARG_INT16(0); + int16 arg2 = PG_GETARG_INT16(1); + + PG_RETURN_INT16(arg1 * arg2); } -int16 -int2div(int16 arg1, int16 arg2) +Datum +int2div(PG_FUNCTION_ARGS) { - return arg1 / arg2; + int16 arg1 = PG_GETARG_INT16(0); + int16 arg2 = PG_GETARG_INT16(1); + + PG_RETURN_INT16(arg1 / arg2); } -int16 -int2inc(int16 arg) +Datum +int2inc(PG_FUNCTION_ARGS) { - return arg + (int16) 1; + int16 arg = PG_GETARG_INT16(0); + + PG_RETURN_INT16(arg + 1); } -int32 -int24pl(int32 arg1, int32 arg2) +Datum +int24pl(PG_FUNCTION_ARGS) { - return arg1 + arg2; + int16 arg1 = PG_GETARG_INT16(0); + int32 arg2 = PG_GETARG_INT32(1); + + PG_RETURN_INT32(arg1 + arg2); } -int32 -int24mi(int32 arg1, int32 arg2) +Datum +int24mi(PG_FUNCTION_ARGS) { - return arg1 - arg2; + int16 arg1 = PG_GETARG_INT16(0); + int32 arg2 = PG_GETARG_INT32(1); + + PG_RETURN_INT32(arg1 - arg2); } -int32 -int24mul(int32 arg1, int32 arg2) +Datum +int24mul(PG_FUNCTION_ARGS) { - return arg1 * arg2; + int16 arg1 = PG_GETARG_INT16(0); + int32 arg2 = PG_GETARG_INT32(1); + + PG_RETURN_INT32(arg1 * arg2); } -int32 -int24div(int32 arg1, int32 arg2) +Datum +int24div(PG_FUNCTION_ARGS) { - return arg1 / arg2; + int16 arg1 = PG_GETARG_INT16(0); + int32 arg2 = PG_GETARG_INT32(1); + + PG_RETURN_INT32(arg1 / arg2); } -int32 -int42pl(int32 arg1, int32 arg2) +Datum +int42pl(PG_FUNCTION_ARGS) { - return arg1 + arg2; + int32 arg1 = PG_GETARG_INT32(0); + int16 arg2 = PG_GETARG_INT16(1); + + PG_RETURN_INT32(arg1 + arg2); } -int32 -int42mi(int32 arg1, int32 arg2) +Datum +int42mi(PG_FUNCTION_ARGS) { - return arg1 - arg2; + int32 arg1 = PG_GETARG_INT32(0); + int16 arg2 = PG_GETARG_INT16(1); + + PG_RETURN_INT32(arg1 - arg2); } -int32 -int42mul(int32 arg1, int32 arg2) +Datum +int42mul(PG_FUNCTION_ARGS) { - return arg1 * arg2; + int32 arg1 = PG_GETARG_INT32(0); + int16 arg2 = PG_GETARG_INT16(1); + + PG_RETURN_INT32(arg1 * arg2); } -int32 -int42div(int32 arg1, int32 arg2) +Datum +int42div(PG_FUNCTION_ARGS) { - return arg1 / arg2; + int32 arg1 = PG_GETARG_INT32(0); + int16 arg2 = PG_GETARG_INT16(1); + + PG_RETURN_INT32(arg1 / arg2); } -/* - * int[24]mod - returns arg1 mod arg2 - */ -int32 -int4mod(int32 arg1, int32 arg2) +Datum +int4mod(PG_FUNCTION_ARGS) { - return arg1 % arg2; + int32 arg1 = PG_GETARG_INT32(0); + int32 arg2 = PG_GETARG_INT32(1); + + PG_RETURN_INT32(arg1 % arg2); } -int32 -int2mod(int16 arg1, int16 arg2) +Datum +int2mod(PG_FUNCTION_ARGS) { - return arg1 % arg2; + int16 arg1 = PG_GETARG_INT16(0); + int16 arg2 = PG_GETARG_INT16(1); + + PG_RETURN_INT16(arg1 % arg2); } -int32 -int24mod(int32 arg1, int32 arg2) +Datum +int24mod(PG_FUNCTION_ARGS) { - return arg1 % arg2; + int16 arg1 = PG_GETARG_INT16(0); + int32 arg2 = PG_GETARG_INT32(1); + + PG_RETURN_INT32(arg1 % arg2); } -int32 -int42mod(int32 arg1, int32 arg2) +Datum +int42mod(PG_FUNCTION_ARGS) { - return arg1 % arg2; + int32 arg1 = PG_GETARG_INT32(0); + int16 arg2 = PG_GETARG_INT16(1); + + PG_RETURN_INT32(arg1 % arg2); } /* int[24]fac() * Factorial */ -int32 -int4fac(int32 arg1) +Datum +int4fac(PG_FUNCTION_ARGS) { + int32 arg1 = PG_GETARG_INT32(0); int32 result; if (arg1 < 1) @@ -673,12 +783,13 @@ int4fac(int32 arg1) else for (result = 1; arg1 > 0; --arg1) result *= arg1; - return result; + PG_RETURN_INT32(result); } -int32 -int2fac(int16 arg1) +Datum +int2fac(PG_FUNCTION_ARGS) { + int16 arg1 = PG_GETARG_INT16(0); int32 result; if (arg1 < 1) @@ -686,44 +797,60 @@ int2fac(int16 arg1) else for (result = 1; arg1 > 0; --arg1) result *= arg1; - return result; + PG_RETURN_INT32(result); } /* int[24]abs() * Absolute value */ -int32 -int4abs(int32 arg1) +Datum +int4abs(PG_FUNCTION_ARGS) { - return ((arg1 < 0) ? -arg1 : arg1); + int32 arg1 = PG_GETARG_INT32(0); + + PG_RETURN_INT32((arg1 < 0) ? -arg1 : arg1); } -int16 -int2abs(int16 arg1) +Datum +int2abs(PG_FUNCTION_ARGS) { - return ((arg1 < 0) ? -arg1 : arg1); + int16 arg1 = PG_GETARG_INT16(0); + + PG_RETURN_INT16((arg1 < 0) ? -arg1 : arg1); } -int16 -int2larger(int16 arg1, int16 arg2) +Datum +int2larger(PG_FUNCTION_ARGS) { - return (arg1 > arg2) ? arg1 : arg2; + int16 arg1 = PG_GETARG_INT16(0); + int16 arg2 = PG_GETARG_INT16(1); + + PG_RETURN_INT16((arg1 > arg2) ? arg1 : arg2); } -int16 -int2smaller(int16 arg1, int16 arg2) +Datum +int2smaller(PG_FUNCTION_ARGS) { - return (arg1 < arg2) ? arg1 : arg2; + int16 arg1 = PG_GETARG_INT16(0); + int16 arg2 = PG_GETARG_INT16(1); + + PG_RETURN_INT16((arg1 < arg2) ? arg1 : arg2); } -int32 -int4larger(int32 arg1, int32 arg2) +Datum +int4larger(PG_FUNCTION_ARGS) { - return (arg1 > arg2) ? arg1 : arg2; + int32 arg1 = PG_GETARG_INT32(0); + int32 arg2 = PG_GETARG_INT32(1); + + PG_RETURN_INT32((arg1 > arg2) ? arg1 : arg2); } -int32 -int4smaller(int32 arg1, int32 arg2) +Datum +int4smaller(PG_FUNCTION_ARGS) { - return (arg1 < arg2) ? arg1 : arg2; + int32 arg1 = PG_GETARG_INT32(0); + int32 arg2 = PG_GETARG_INT32(1); + + PG_RETURN_INT32((arg1 < arg2) ? arg1 : arg2); } diff --git a/src/backend/utils/adt/misc.c b/src/backend/utils/adt/misc.c index 00af6350de5..7e3b8b167b9 100644 --- a/src/backend/utils/adt/misc.c +++ b/src/backend/utils/adt/misc.c @@ -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); } diff --git a/src/backend/utils/adt/numeric.c b/src/backend/utils/adt/numeric.c index 36e333e1217..500cb151ac7 100644 --- a/src/backend/utils/adt/numeric.c +++ b/src/backend/utils/adt/numeric.c @@ -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; diff --git a/src/backend/utils/adt/oid.c b/src/backend/utils/adt/oid.c index 96640af91e5..2f1651378cf 100644 --- a/src/backend/utils/adt/oid.c +++ b/src/backend/utils/adt/oid.c @@ -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); +} diff --git a/src/backend/utils/adt/regproc.c b/src/backend/utils/adt/regproc.c index 6db76ac8c5a..c5fbeadff6a 100644 --- a/src/backend/utils/adt/regproc.c +++ b/src/backend/utils/adt/regproc.c @@ -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) */ diff --git a/src/backend/utils/adt/selfuncs.c b/src/backend/utils/adt/selfuncs.c index 611f57f9acb..fb1a77cfbd7 100644 --- a/src/backend/utils/adt/selfuncs.c +++ b/src/backend/utils/adt/selfuncs.c @@ -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); } diff --git a/src/backend/utils/adt/varchar.c b/src/backend/utils/adt/varchar.c index f98de78878d..781d6591b3b 100644 --- a/src/backend/utils/adt/varchar.c +++ b/src/backend/utils/adt/varchar.c @@ -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() diff --git a/src/backend/utils/cache/catcache.c b/src/backend/utils/cache/catcache.c index e5fb546ca70..428110aa360 100644 --- a/src/backend/utils/cache/catcache.c +++ b/src/backend/utils/cache/catcache.c @@ -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); diff --git a/src/backend/utils/fmgr/fmgr.c b/src/backend/utils/fmgr/fmgr.c index 713d714bb7e..489d8c260fd 100644 --- a/src/backend/utils/fmgr/fmgr.c +++ b/src/backend/utils/fmgr/fmgr.c @@ -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 * |