diff -urN postgresql-7.0.3/contrib/money.orig postgresql-7.0.3/contrib/money diff -urN postgresql-7.0.3/contrib/money.orig/Makefile postgresql-7.0.3/contrib/money/Makefile --- postgresql-7.0.3/contrib/money.orig/Makefile Wed Dec 31 18:00:00 1969 +++ postgresql-7.0.3/contrib/money/Makefile Wed Jun 13 14:48:27 2001 @@ -0,0 +1,51 @@ +#------------------------------------------------------------------------- +# +# Makefile-- +# Makefile for Postgres 'money' type conversion extensions +# +# David D. Kilzer +# +# Stolen from contrib/int8/Makefile in PostgreSQL v7.0.3 +# written by Thomas G. Lockhart +# +# This file is licensed under the same terms as PostgresSQL itself. +# +#------------------------------------------------------------------------- + +ifndef PGDIR +PGDIR= ../.. +endif + +SRCDIR= $(PGDIR)/src + +include $(SRCDIR)/Makefile.global + +# Comment out this re-declaration of LIBDIR +# if you are installing as the postgres superuser +# into a specific database or into template1. +TARGETLIBDIR= /usr/lib/postgresql +LIBDIR= $(PGDIR)/debian/postgresql-contrib/$(TARGETLIBDIR) + +CFLAGS+= -I$(PGDIR)/src/include -I$(LIBPQDIR) $(CFLAGS_SL) + +TARGETS= money.sql money$(DLSUFFIX) + +all: $(TARGETS) + +money$(DLSUFFIX): money.o + $(CC) -shared -o money$(DLSUFFIX) money.o $(CLIBS) -lc + +install: $(LIBDIR)/modules + $(MAKE) all + cp -p money$(DLSUFFIX) $(LIBDIR)/modules + +%.sql: %.sql.in + rm -f $@; \ + O=$(TARGETLIBDIR)/modules; \ + sed -e "s:_OBJWD_:$$O:g" < $< > $@ + +clean: + rm -f $(TARGETS) money.o + +$(LIBDIR)/modules: + install -d $(LIBDIR)/modules diff -urN postgresql-7.0.3/contrib/money.orig/money.c postgresql-7.0.3/contrib/money/money.c --- postgresql-7.0.3/contrib/money.orig/money.c Wed Dec 31 18:00:00 1969 +++ postgresql-7.0.3/contrib/money/money.c Thu Jun 14 09:14:07 2001 @@ -0,0 +1,267 @@ +/* + * money.c + * Written by David D. Kilzer + * + * Based on cash_out() in src/backend/utils/adt/cash.c written by + * D'Arcy J.M. Cain + * and contrib/int8/int8.c written by + * Thomas G. Lockhart + * from PostgreSQL v7.0.3 + * + * Conversion functions to convert 'money' type to int[248] and + * float[48] without using string manipulation via plpgsql (ick). + * + * Note that the money type appears to have a range of -(2^31-1)/100 to + * (2^31-1)/100 assuming 2 decimal places. Any numbers larger or + * smaller than this produce weird results. Technically -(2^31)/100 + * should be the lower limit, but it looks like this: + * + * db=> select -21474836.48::money; + * ?column? + * ----------------- + * -$./,,),,(-*.,( + * (1 row) + * + * All of the moneytoint[248]() functions will truncate the value, or in + * other words, drop the decimal. No rounding occurs. Also note that + * moneytofloat4() may lose some significant digits. Only + * moneytofloat8() will preserve the entire value of the money data type + * every time. + * + * If you need to convert money to a numeric(N,D) type, for example, use + * float8 as an intermediary. Yeah, it's not quite as efficient as a + * direct conversion, but it works. + * + * db=> select '$1,000,000.01'::money::float8::numeric(16,2); + * ?column? + * ------------ + * 1000000.01 + * (1 row) + * + * This file is licensed under the same terms as PostgresSQL itself. + */ + + +#include "money.h" + + +/* moneytoint2() + * Function to convert 'money' to 'int2'. + */ +int16 +moneytoint2(Cash *money) +{ + Cash value; + int64 result; + int points = 2; + int64 power = 1; + +#ifdef USE_LOCALE + struct lconv *lconvert = localeconv(); +#endif + + if (!PointerIsValid(money)) + elog(ERROR, "moneytoint2: Invalid pointer to money"); + + value = *money; + +#ifdef USE_LOCALE + /* frac_digits in the C locale seems to return CHAR_MAX */ + /* best guess is 2 in this case I think */ + points = ((lconvert->frac_digits != (char)CHAR_MAX) ? lconvert->frac_digits : 2); /* int_frac_digits? */ +#endif + + while (points > 0) + { + power *= 10; + points--; + } + + /* Store results in int64 variable*/ + result = ((int64) value) / power; + + /* Do boundary checking */ + if (result < SHRT_MIN || result > SHRT_MAX) + { + errno = ERANGE; + elog(ERROR, "moneytoint2: Error converting \"" INT64_FORMAT "\": %m", result); + } + + return ((int16) result); +} /* moneytoint2() */ + + +/* moneytoint4() + * Function to convert 'money' to 'int4'. + */ +int32 +moneytoint4(Cash *money) +{ + Cash value; + int64 result; + int points = 2; + int64 power = 1; + +#ifdef USE_LOCALE + struct lconv *lconvert = localeconv(); +#endif + + if (!PointerIsValid(money)) + elog(ERROR, "moneytoint4: Invalid pointer to money"); + + value = *money; + +#ifdef USE_LOCALE + /* frac_digits in the C locale seems to return CHAR_MAX */ + /* best guess is 2 in this case I think */ + points = ((lconvert->frac_digits != (char)CHAR_MAX) ? lconvert->frac_digits : 2); /* int_frac_digits? */ +#endif + + while (points > 0) + { + power *= 10; + points--; + } + + /* Store results in int64 variable*/ + result = ((int64) value) / power; + + /* Do boundary checking */ + if (result < INT_MIN || result > INT_MAX) + { + errno = ERANGE; + elog(ERROR, "moneytoint4: Error converting \"" INT64_FORMAT "\": %m", result); + } + + return ((int32) result); +} /* moneytoint4() */ + + +/* moneytoint8() + * Function to convert 'money' to 'int8'. + */ +int64 * +moneytoint8(Cash *money) +{ + Cash value; + int64 *result; + int points = 2; + int64 power = 1; + +#ifdef USE_LOCALE + struct lconv *lconvert = localeconv(); +#endif + + if (!PointerIsValid(money)) + elog(ERROR, "moneytoint8: Invalid pointer to money"); + + if (!PointerIsValid(result = palloc(sizeof(int64)))) + elog(ERROR, "moneytoint8: Memory allocation failed"); + + value = *money; + +#ifdef USE_LOCALE + /* frac_digits in the C locale seems to return CHAR_MAX */ + /* best guess is 2 in this case I think */ + points = ((lconvert->frac_digits != (char)CHAR_MAX) ? lconvert->frac_digits : 2); /* int_frac_digits? */ +#endif + + while (points > 0) + { + power *= 10; + points--; + } + + /* No boundary checking required */ + + /* Store results in int64 variable*/ + *result = ((int64) value) / power; + + return result; +} /* moneytoint8() */ + + +/* moneytofloat4() + * Function to convert 'money' to 'float4'. + */ +float32 +moneytofloat4(Cash *money) +{ + Cash value; + float32 result; + int points = 2; + float32data power = 1.0; + +#ifdef USE_LOCALE + struct lconv *lconvert = localeconv(); +#endif + + if (!PointerIsValid(money)) + elog(ERROR, "moneytofloat4: Invalid pointer to money"); + + if (!PointerIsValid(result = palloc(sizeof(float32data)))) + elog(ERROR, "moneytofloat4: Memory allocation failed"); + + value = *money; + +#ifdef USE_LOCALE + /* frac_digits in the C locale seems to return CHAR_MAX */ + /* best guess is 2 in this case I think */ + points = ((lconvert->frac_digits != (char)CHAR_MAX) ? lconvert->frac_digits : 2); /* int_frac_digits? */ +#endif + + while (points > 0) + { + power *= 10.0; + points--; + } + + /* Compute the floating point value */ + *result = (((float32data) value) / power); + + return result; +} /* moneytofloat4() */ + + +/* moneytofloat8() + * Function to convert 'money' to 'float8'. + */ +float64 +moneytofloat8(Cash *money) +{ + Cash value; + float64 result; + int points = 2; + float64data power = 1.0; + +#ifdef USE_LOCALE + struct lconv *lconvert = localeconv(); +#endif + + if (!PointerIsValid(money)) + elog(ERROR, "moneytofloat8: Invalid pointer to money"); + + if (!PointerIsValid(result = palloc(sizeof(float64data)))) + elog(ERROR, "moneytofloat8: Memory allocation failed"); + + value = *money; + +#ifdef USE_LOCALE + /* frac_digits in the C locale seems to return CHAR_MAX */ + /* best guess is 2 in this case I think */ + points = ((lconvert->frac_digits != (char)CHAR_MAX) ? lconvert->frac_digits : 2); /* int_frac_digits? */ +#endif + + while (points > 0) + { + power *= 10.0; + points--; + } + + /* Compute the floating point value */ + *result = (((float64data) value) / power); + + return result; +} /* moneytofloat8() */ + + diff -urN postgresql-7.0.3/contrib/money.orig/money.h postgresql-7.0.3/contrib/money/money.h --- postgresql-7.0.3/contrib/money.orig/money.h Wed Dec 31 18:00:00 1969 +++ postgresql-7.0.3/contrib/money/money.h Wed Jun 13 22:15:25 2001 @@ -0,0 +1,56 @@ +/* + * money.h + * Written by David D. Kilzer + * + * Conversion functions to convert 'money' type to int[248] and + * float[48] without using string manipulation via plpgsql (ick). + * + * This file is licensed under the same terms as PostgresSQL itself. + */ + +#ifndef CONTRIB_MONEY_H +#define CONTRIB_MONEY_H 1 + +#include +#include + +#include "postgres.h" +#ifdef HAVE_LIMITS_H +#include +#endif +#ifdef USE_LOCALE +#include +#endif +#include "utils/builtins.h" +#include "utils/cash.h" + +/* stolen from src/backend/utils/adt/numutils.c in PostgreSQL v7.0.3 */ +#ifndef INT_MAX +#define INT_MAX (0x7FFFFFFFL) +#endif +#ifndef INT_MIN +#define INT_MIN (-INT_MAX-1) +#endif +#ifndef SHRT_MAX +#define SHRT_MAX (0x7FFF) +#endif +#ifndef SHRT_MIN +#define SHRT_MIN (-SHRT_MAX-1) +#endif +#ifndef SCHAR_MAX +#define SCHAR_MAX (0x7F) +#endif +#ifndef SCHAR_MIN +#define SCHAR_MIN (-SCHAR_MAX-1) +#endif + +/* function prototypes */ +int16 moneytoint2(Cash *money); +int32 moneytoint4(Cash *money); +int64 *moneytoint8(Cash *money); + +float32 moneytofloat4(Cash *money); +float64 moneytofloat8(Cash *money); + +#endif /* CONTRIB_MONEY_H */ + diff -urN postgresql-7.0.3/contrib/money.orig/money.sql.in postgresql-7.0.3/contrib/money/money.sql.in --- postgresql-7.0.3/contrib/money.orig/money.sql.in Wed Dec 31 18:00:00 1969 +++ postgresql-7.0.3/contrib/money/money.sql.in Wed Jun 13 14:48:48 2001 @@ -0,0 +1,85 @@ +--------------------------------------------------------------------------- +-- +-- money.sql- +-- This file defines operators for money conversion functions. +-- +-- Stolen from contrib/int8/int8.source in PostgreSQL v7.0.3 +-- written by Thomas G. Lockhart +-- +-- This file is licensed under the same terms as PostgresSQL itself. +-- +--------------------------------------------------------------------------- + +LOAD '_OBJWD_/money.so'; + + +-- +-- Conversion functions +-- + +DROP FUNCTION moneytoint2(money); +DROP FUNCTION moneytoint4(money); +DROP FUNCTION moneytoint8(money); +DROP FUNCTION moneytofloat4(money); +DROP FUNCTION moneytofloat8(money); + +CREATE FUNCTION moneytoint2(money) + RETURNS int2 + AS '_OBJWD_/money.so' + LANGUAGE 'c'; + +CREATE FUNCTION moneytoint4(money) + RETURNS int4 + AS '_OBJWD_/money.so' + LANGUAGE 'c'; + +CREATE FUNCTION moneytoint8(money) + RETURNS int8 + AS '_OBJWD_/money.so' + LANGUAGE 'c'; + +CREATE FUNCTION moneytofloat4(money) + RETURNS float4 + AS '_OBJWD_/money.so' + LANGUAGE 'c'; + +CREATE FUNCTION moneytofloat8(money) + RETURNS float8 + AS '_OBJWD_/money.so' + LANGUAGE 'c'; + +-- +-- Generic conversion routines +-- + +DROP FUNCTION int2(money); +DROP FUNCTION int4(money); +DROP FUNCTION int8(money); +DROP FUNCTION float4(money); +DROP FUNCTION float8(money); + +CREATE FUNCTION int2(money) + RETURNS int2 + AS 'select moneytoint2($1)' + LANGUAGE 'sql'; + +CREATE FUNCTION int4(money) + RETURNS int4 + AS 'select moneytoint4($1)' + LANGUAGE 'sql'; + +CREATE FUNCTION int8(money) + RETURNS int8 + AS 'select moneytoint8($1)' + LANGUAGE 'sql'; + +CREATE FUNCTION float4(money) + RETURNS float4 + AS 'select moneytofloat4($1)' + LANGUAGE 'sql'; + +CREATE FUNCTION float8(money) + RETURNS float8 + AS 'select moneytofloat8($1)' + LANGUAGE 'sql'; +