+++ /dev/null
-#-------------------------------------------------------------------------
-#
-# Makefile--
-# Makefile for Postgres 64-bit integer extensions
-#
-# Thomas G. Lockhart <Thomas.Lockhart@jpl.nasa.gov>
-#
-# This is a first attempt at 64-bit arithmetic for Postgres.
-# It takes advantage of "long long int" support in GNU C on 32-bit machines.
-# The modules are built and installed as user-defined types,
-# so destination directories are pointing away from the standard
-# Postgres areas. You will need to modify the paths to fit your machine.
-#
-# On my Linux box, I had to find an extra library for the division function (?).
-# For Alpha boxes, both the DEC and GNU compilers should need "long int" only.
-#
-#-------------------------------------------------------------------------
-
-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.
-#LIBDIR= /home/tgl/lib
-
-CFLAGS+= -I$(PGDIR)/include -I$(PGDIR)/src/include -I$(LIBPQDIR)
-
-# This extra library is for the 64-bit division routine on my Linux box
-# and probably will need to be commented-out for most other platforms.
-#CLIBS+= /usr/lib/gcc-lib/i486-linux/2.7.2/libgcc.a
-
-TARGETS= int8.sql int8$(DLSUFFIX)
-
-all: $(TARGETS)
-
-int8$(DLSUFFIX): int8.o
- $(CC) -shared -o int8$(DLSUFFIX) int8.o $(CLIBS)
-
-install:
- $(MAKE) all
- cp -p int8$(DLSUFFIX) $(LIBDIR)/modules
-
-%.sql: %.source
- if [ -z "$$USER" ]; then USER=$$LOGNAME; fi; \
- if [ -z "$$USER" ]; then USER=`whoami`; fi; \
- if [ -z "$$USER" ]; then echo 'Cannot deduce $$USER.'; exit 1; fi; \
- rm -f $@; \
- C=`pwd`; \
- O=$C; \
- if [ -d ${LIBDIR}/contrib ]; then O=${LIBDIR}/contrib; fi; \
- sed -e "s:_CWD_:$$C:g" \
- -e "s:_OBJWD_:$$O:g" \
- -e "s:_DLSUFFIX_:$(DLSUFFIX):g" \
- -e "s/_USER_/$$USER/g" < $< > $@
-
-clean:
- rm -f $(TARGETS) int8.o
-
+++ /dev/null
- Postgres int8
-
-Thomas G. Lockhart <Thomas.Lockhart@jpl.nasa.gov>
-
-This is a first attempt at 64-bit integer arithmetic for Postgres. The code
-should support any 64-bit architecture and any 32-bit machine using a recent
-GNU C compiler. At the moment, DEC-Alpha and Linux/gcc are explicitly
-supported. The code uses "long long int" support in GNU C on 32-bit machines.
-This type is an extension to ANSI-C, and may not appear on any other compiler.
-
-The modules are built and installed as user-defined types, so destination
- directories are pointing away from the standard Postgres areas.
-
-Other compilers and architectures should be supportable, so please let me know
-what changes were required to run on your machine, and I will fold those into
-this standard distribution.
-
-Good luck!
-
- - Tom
-
-
- Installation
-
-You will need to modify the Makefile paths to fit your machine. Since this
-is packaged as a "user-installable" type, the libraries and source code
-can reside outside of the standard Postgres areas.
-
-If you are compiling on a DEC-Alpha, then the code might compile
-and run without change. (I do a lot of code development on Alphas,
-but do not have a Postgres installation to test).
-
- make
- make install
- psql dbname < int8.sql
-
-If you are running gcc on a 32-bit machine, you will probably need to:
- - remove the extra library reference in the Makefile.
- - if there are unresolved symbols when you try running, then find
- the right library. The one I had chosen might be a clue.
-
-If you are not running gcc on a 32-bit machine, you will need to:
- - redeclare the 64 bit data type.
- - modify the scanf and printf() arguments to use the appropriate
- 64-bit int arguments.
-
-On my Linux box, I had to find an extra library for the division function.
-For Alpha boxes, both the DEC and GNU compilers should need "long int" only.
-I have a reference to "__alpha" in the C source code, but have not tested it
- and am not certain that this is the correct pre-defined symbol for that machine.
-
-itest.sql is a small test file which exercises some of the I/O, functions,
- and boolean operators.
-
-int8:
- =
- <>
- <
- >
- <=
- >=
-
- - unary minus
- + addition
- - subtraction
- * multiplication
- / division
-
- int4() convert to 4-byte integer
- float8() convert to double float
-
-Routines defined are:
-
-int64 *int8in(char *str);
-char *int8out(int64 *val);
-
-bool int8eq(int64 *val1, int64 *val2);
-bool int8ne(int64 *val1, int64 *val2);
-bool int8lt(int64 *val1, int64 *val2);
-bool int8gt(int64 *val1, int64 *val2);
-bool int8le(int64 *val1, int64 *val2);
-bool int8ge(int64 *val1, int64 *val2);
-
-bool int84eq(int64 *val1, int32 val2);
-bool int84ne(int64 *val1, int32 val2);
-bool int84lt(int64 *val1, int32 val2);
-bool int84gt(int64 *val1, int32 val2);
-bool int84le(int64 *val1, int32 val2);
-bool int84ge(int64 *val1, int32 val2);
-
-int64 *int8um(int64 *val);
-int64 *int8pl(int64 *val1, int64 *val2);
-int64 *int8mi(int64 *val1, int64 *val2);
-int64 *int8mul(int64 *val1, int64 *val2);
-int64 *int8div(int64 *val1, int64 *val2);
-
-int64 *int48(int32 val);
-int32 int84(int64 *val);
-
-int64 *dtoi8(float8 *val);
-float8 *i8tod(int64 *val);
+++ /dev/null
-/*-------------------------------------------------------------------------
- *
- * int8.c--
- * Internal 64-bit integer operations
- *
- *-------------------------------------------------------------------------
- */
-#include <stdio.h> /* for sprintf proto, etc. */
-#include <stdlib.h> /* for strtod, etc. */
-#include <string.h>
-#include <ctype.h>
-#include <time.h>
-#include <math.h>
-#include <float.h>
-#include <limits.h>
-
-#include "postgres.h"
-#include "utils/palloc.h"
-
-#define MAXINT8LEN 25
-
-#if defined(__alpha) || defined(__GNUC__)
-#define HAVE_64BIT_INTS 1
-#endif
-
-#ifndef HAVE_64BIT_INTS
-typedef char[8]
-int64;
-
-#elif defined(__alpha)
-typedef long int int64;
-
-#define INT64_FORMAT "%ld"
-
-#elif defined(__GNUC__)
-typedef long long int int64;
-
-#define INT64_FORMAT "%Ld"
-
-#else
-typedef long int int64;
-
-#define INT64_FORMAT "%ld"
-#endif
-
-int64 *int8in(char *str);
-char *int8out(int64 *val);
-
-bool int8eq(int64 *val1, int64 *val2);
-bool int8ne(int64 *val1, int64 *val2);
-bool int8lt(int64 *val1, int64 *val2);
-bool int8gt(int64 *val1, int64 *val2);
-bool int8le(int64 *val1, int64 *val2);
-bool int8ge(int64 *val1, int64 *val2);
-
-bool int84eq(int64 *val1, int32 val2);
-bool int84ne(int64 *val1, int32 val2);
-bool int84lt(int64 *val1, int32 val2);
-bool int84gt(int64 *val1, int32 val2);
-bool int84le(int64 *val1, int32 val2);
-bool int84ge(int64 *val1, int32 val2);
-
-int64 *int8um(int64 *val);
-int64 *int8pl(int64 *val1, int64 *val2);
-int64 *int8mi(int64 *val1, int64 *val2);
-int64 *int8mul(int64 *val1, int64 *val2);
-int64 *int8div(int64 *val1, int64 *val2);
-
-int64 *int48(int32 val);
-int32 int84(int64 *val);
-
-#if FALSE
-int64 *int28 (int16 val);
-int16 int82(int64 *val);
-
-#endif
-
-float64 i8tod(int64 *val);
-int64 *dtoi8(float64 val);
-
-/***********************************************************************
- **
- ** Routines for 64-bit integers.
- **
- ***********************************************************************/
-
-/*----------------------------------------------------------
- * Formatting and conversion routines.
- *---------------------------------------------------------*/
-
-/* int8in()
- */
-int64 *
-int8in(char *str)
-{
- int64 *result = palloc(sizeof(int64));
-
-#if HAVE_64BIT_INTS
- if (!PointerIsValid(str))
- elog(ERROR, "Bad (null) int8 external representation", NULL);
-
- if (sscanf(str, INT64_FORMAT, result) != 1)
- elog(ERROR, "Bad int8 external representation '%s'", str);
-
-#else
- elog(ERROR, "64-bit integers are not supported", NULL);
- result = NULL;
-#endif
-
- return (result);
-} /* int8in() */
-
-
-/* int8out()
- */
-char *
-int8out(int64 *val)
-{
- char *result;
-
- int len;
- char buf[MAXINT8LEN + 1];
-
-#if HAVE_64BIT_INTS
- if (!PointerIsValid(val))
- return (NULL);
-
- if ((len = snprintf(buf, MAXINT8LEN, INT64_FORMAT, *val)) < 0)
- elog(ERROR, "Unable to format int8", NULL);
-
- result = palloc(len + 1);
-
- strcpy(result, buf);
-
-#else
- elog(ERROR, "64-bit integers are not supported", NULL);
- result = NULL;
-#endif
-
- return (result);
-} /* int8out() */
-
-
-/*----------------------------------------------------------
- * Relational operators for int8s.
- *---------------------------------------------------------*/
-
-/* int8relop()
- * Is val1 relop val2?
- */
-bool
-int8eq(int64 *val1, int64 *val2)
-{
- return (*val1 == *val2);
-} /* int8eq() */
-
-bool
-int8ne(int64 *val1, int64 *val2)
-{
- return (*val1 != *val2);
-} /* int8ne() */
-
-bool
-int8lt(int64 *val1, int64 *val2)
-{
- return (*val1 < *val2);
-} /* int8lt() */
-
-bool
-int8gt(int64 *val1, int64 *val2)
-{
- return (*val1 > *val2);
-} /* int8gt() */
-
-bool
-int8le(int64 *val1, int64 *val2)
-{
- return (*val1 <= *val2);
-} /* int8le() */
-
-bool
-int8ge(int64 *val1, int64 *val2)
-{
- return (*val1 >= *val2);
-} /* int8ge() */
-
-
-/* int84relop()
- * Is 64-bit val1 relop 32-bit val2?
- */
-bool
-int84eq(int64 *val1, int32 val2)
-{
- return (*val1 == val2);
-} /* int84eq() */
-
-bool
-int84ne(int64 *val1, int32 val2)
-{
- return (*val1 != val2);
-} /* int84ne() */
-
-bool
-int84lt(int64 *val1, int32 val2)
-{
- return (*val1 < val2);
-} /* int84lt() */
-
-bool
-int84gt(int64 *val1, int32 val2)
-{
- return (*val1 > val2);
-} /* int84gt() */
-
-bool
-int84le(int64 *val1, int32 val2)
-{
- return (*val1 <= val2);
-} /* int84le() */
-
-bool
-int84ge(int64 *val1, int32 val2)
-{
- return (*val1 >= val2);
-} /* int84ge() */
-
-
-/*----------------------------------------------------------
- * Arithmetic operators on 64-bit integers.
- *---------------------------------------------------------*/
-
-int64 *
-int8um(int64 *val)
-{
- int64 *result = palloc(sizeof(int64));
-
- if (!PointerIsValid(val))
- return NULL;
-
- *result = (-*val);
-
- return (result);
-} /* int8um() */
-
-int64 *
-int8pl(int64 *val1, int64 *val2)
-{
- int64 *result = palloc(sizeof(int64));
-
- if ((!PointerIsValid(val1)) || (!PointerIsValid(val2)))
- return NULL;
-
- *result = *val1 + *val2;
-
- return (result);
-} /* int8pl() */
-
-int64 *
-int8mi(int64 *val1, int64 *val2)
-{
- int64 *result = palloc(sizeof(int64));
-
- if ((!PointerIsValid(val1)) || (!PointerIsValid(val2)))
- return NULL;
-
- *result = *val1 - *val2;
-
- return (result);
-} /* int8mi() */
-
-int64 *
-int8mul(int64 *val1, int64 *val2)
-{
- int64 *result = palloc(sizeof(int64));
-
- if ((!PointerIsValid(val1)) || (!PointerIsValid(val2)))
- return NULL;
-
- *result = *val1 * *val2;
-
- return (result);
-} /* int8mul() */
-
-int64 *
-int8div(int64 *val1, int64 *val2)
-{
- int64 *result = palloc(sizeof(int64));
-
- if ((!PointerIsValid(val1)) || (!PointerIsValid(val2)))
- return NULL;
-
- *result = *val1 / *val2;
-
- return (result);
-} /* int8div() */
-
-
-/*----------------------------------------------------------
- * Conversion operators.
- *---------------------------------------------------------*/
-
-int64 *
-int48(int32 val)
-{
- int64 *result = palloc(sizeof(int64));
-
- *result = val;
-
- return (result);
-} /* int48() */
-
-int32
-int84(int64 *val)
-{
- int32 result;
-
- if (!PointerIsValid(val))
- elog(ERROR, "Invalid (null) int64, can't convert int8 to int4", NULL);
-
- if ((*val < INT_MIN) || (*val > INT_MAX))
- elog(ERROR, "int8 conversion to int4 is out of range", NULL);
-
- result = *val;
-
- return (result);
-} /* int84() */
-
-#if FALSE
-int64 *
-int28 (int16 val)
-{
- int64 *result;
-
- if (!PointerIsValid(result = palloc(sizeof(int64))))
- elog(ERROR, "Memory allocation failed, can't convert int8 to int2", NULL);
-
- *result = val;
-
- return (result);
-} /* int28() */
-
-int16
-int82(int64 *val)
-{
- int16 result;
-
- if (!PointerIsValid(val))
- elog(ERROR, "Invalid (null) int8, can't convert to int2", NULL);
-
- result = *val;
-
- return (result);
-} /* int82() */
-
-#endif
-
-float64
-i8tod(int64 *val)
-{
- float64 result = palloc(sizeof(float64data));
-
- *result = *val;
-
- return (result);
-} /* i8tod() */
-
-int64 *
-dtoi8(float64 val)
-{
- int64 *result = palloc(sizeof(int64));
-
- if ((*val < (-pow(2, 64) + 1)) || (*val > (pow(2, 64) - 1)))
- elog(ERROR, "Floating point conversion to int64 is out of range", NULL);
-
- *result = *val;
-
- return (result);
-} /* dtoi8() */
+++ /dev/null
----------------------------------------------------------------------------
---
--- int8.sql-
--- This file defines operators for 64-bit integers.
---
----------------------------------------------------------------------------
-
-LOAD '_OBJWD_/int8.so';
-
-CREATE FUNCTION int8in(opaque)
- RETURNS int8
- AS '_OBJWD_/int8.so'
- LANGUAGE 'c';
-
-CREATE FUNCTION int8out(opaque)
- RETURNS opaque
- AS '_OBJWD_/int8.so'
- LANGUAGE 'c';
-
-CREATE TYPE int8 (
- internallength = 8,
- input = int8in,
- output = int8out
-);
-
-
------------------------------
--- Create operators
------------------------------
-
-CREATE FUNCTION int8um(int8)
- RETURNS int8
- AS '_OBJWD_/int8.so'
- LANGUAGE 'c';
-
-CREATE OPERATOR - (
- rightarg = int8,
- procedure = int8um
-);
-
-CREATE FUNCTION int8pl(int8,int8)
- RETURNS int8
- AS '_OBJWD_/int8.so'
- LANGUAGE 'c';
-
-CREATE OPERATOR + (
- leftarg = int8,
- rightarg = int8,
- procedure = int8pl,
- commutator = +
-);
-
-CREATE FUNCTION int8mi(int8,int8)
- RETURNS int8
- AS '_OBJWD_/int8.so'
- LANGUAGE 'c';
-
-CREATE OPERATOR - (
- leftarg = int8,
- rightarg = int8,
- procedure = int8mi
-);
-
-CREATE FUNCTION int8mul(int8,int8)
- RETURNS int8
- AS '_OBJWD_/int8.so'
- LANGUAGE 'c';
-
-CREATE OPERATOR * (
- leftarg = int8,
- rightarg = int8,
- procedure = int8mul,
- commutator = *
-);
-
-CREATE FUNCTION int8div(int8,int8)
- RETURNS int8
- AS '_OBJWD_/int8.so'
- LANGUAGE 'c';
-
-CREATE OPERATOR / (
- leftarg = int8,
- rightarg = int8,
- procedure = int8div
-);
-
---
--- 64-bit comparison operators
---
-
-CREATE FUNCTION int8eq(int8,int8)
- RETURNS bool
- AS '_OBJWD_/int8.so'
- LANGUAGE 'c';
-
-CREATE OPERATOR = (
- leftarg = int8,
- rightarg = int8,
- procedure = int8eq,
- commutator = =
-);
-
-CREATE FUNCTION int8ne(int8,int8)
- RETURNS bool
- AS '_OBJWD_/int8.so'
- LANGUAGE 'c';
-
-CREATE OPERATOR <> (
- leftarg = int8,
- rightarg = int8,
- procedure = int8ne,
- commutator = <>
-);
-
-CREATE FUNCTION int8lt(int8,int8)
- RETURNS bool
- AS '_OBJWD_/int8.so'
- LANGUAGE 'c';
-
-CREATE OPERATOR < (
- leftarg = int8,
- rightarg = int8,
- procedure = int8lt
-);
-
-CREATE FUNCTION int8gt(int8,int8)
- RETURNS bool
- AS '_OBJWD_/int8.so'
- LANGUAGE 'c';
-
-CREATE OPERATOR > (
- leftarg = int8,
- rightarg = int8,
- procedure = int8gt
-);
-
-CREATE FUNCTION int8le(int8,int8)
- RETURNS bool
- AS '_OBJWD_/int8.so'
- LANGUAGE 'c';
-
-CREATE OPERATOR <= (
- leftarg = int8,
- rightarg = int8,
- procedure = int8le
-);
-
-CREATE FUNCTION int8ge(int8,int8)
- RETURNS bool
- AS '_OBJWD_/int8.so'
- LANGUAGE 'c';
-
-CREATE OPERATOR >= (
- leftarg = int8,
- rightarg = int8,
- procedure = int8ge
-);
-
---
--- 64-bit/32-bit comparison operators
---
-
-CREATE FUNCTION int84eq(int8,int4)
- RETURNS bool
- AS '_OBJWD_/int8.so'
- LANGUAGE 'c';
-
-CREATE OPERATOR = (
- leftarg = int8,
- rightarg = int4,
- procedure = int84eq,
- commutator = =
-);
-
-CREATE FUNCTION int84ne(int8,int4)
- RETURNS bool
- AS '_OBJWD_/int8.so'
- LANGUAGE 'c';
-
-CREATE OPERATOR <> (
- leftarg = int8,
- rightarg = int4,
- procedure = int84ne,
- commutator = <>
-);
-
-CREATE FUNCTION int84lt(int8,int4)
- RETURNS bool
- AS '_OBJWD_/int8.so'
- LANGUAGE 'c';
-
-CREATE OPERATOR < (
- leftarg = int8,
- rightarg = int4,
- procedure = int84lt
-);
-
-CREATE FUNCTION int84gt(int8,int4)
- RETURNS bool
- AS '_OBJWD_/int8.so'
- LANGUAGE 'c';
-
-CREATE OPERATOR > (
- leftarg = int8,
- rightarg = int4,
- procedure = int84gt
-);
-
-CREATE FUNCTION int84le(int8,int4)
- RETURNS bool
- AS '_OBJWD_/int8.so'
- LANGUAGE 'c';
-
-CREATE OPERATOR <= (
- leftarg = int8,
- rightarg = int4,
- procedure = int84le
-);
-
-CREATE FUNCTION int84ge(int8,int4)
- RETURNS bool
- AS '_OBJWD_/int8.so'
- LANGUAGE 'c';
-
-CREATE OPERATOR >= (
- leftarg = int8,
- rightarg = int4,
- procedure = int84ge
-);
-
---
--- Conversion functions
---
-
-CREATE FUNCTION int48(int4)
- RETURNS int8
- AS '_OBJWD_/int8.so'
- LANGUAGE 'c';
-
-CREATE FUNCTION int84(int8)
- RETURNS int4
- AS '_OBJWD_/int8.so'
- LANGUAGE 'c';
-
---CREATE FUNCTION int28(int2)
--- RETURNS int8
--- AS '_OBJWD_/int8.so'
--- LANGUAGE 'c';
---
---CREATE FUNCTION int82(int8)
--- RETURNS int2
--- AS '_OBJWD_/int8.so'
--- LANGUAGE 'c';
-
-CREATE FUNCTION i8tod(int8)
- RETURNS float8
- AS '_OBJWD_/int8.so'
- LANGUAGE 'c';
-
-CREATE FUNCTION dtoi8(float8)
- RETURNS int8
- AS '_OBJWD_/int8.so'
- LANGUAGE 'c';
-
---
--- Generic conversion routines
---
-
-CREATE FUNCTION int8(int4)
- RETURNS int8
- AS 'select int48($1)'
- LANGUAGE 'sql';
-
-CREATE FUNCTION int8(float8)
- RETURNS int8
- AS 'select dtoi8($1)'
- LANGUAGE 'sql';
-
-CREATE FUNCTION float8(int8)
- RETURNS float8
- AS 'select i8tod($1)'
- LANGUAGE 'sql';
-
-CREATE FUNCTION int4(int8)
- RETURNS int4
- AS 'select int84($1)'
- LANGUAGE 'sql';
-
+++ /dev/null
---
--- Test int8 64-bit integers.
---
-drop table qtest;
-create table qtest(q1 int8, q2 int8);
-
-insert into qtest values('123','456');
-insert into qtest values('123','4567890123456789');
-insert into qtest values('4567890123456789','123');
-insert into qtest values('4567890123456789','4567890123456789');
-insert into qtest values('4567890123456789','-4567890123456789');
-
-select * from qtest;
-
-select q1, -q1 as minus from qtest;
-
-select q1, q2, q1 + q2 as plus from qtest;
-select q1, q2, q1 - q2 as minus from qtest;
-select q1, q2, q1 * q2 as multiply from qtest
- where q1 < 1000 or (q2 > 0 and q2 < 1000);
---select q1, q2, q1 * q2 as multiply qtest
--- where q1 < '1000'::int8 or (q2 > '0'::int8 and q2 < '1000'::int8);
-select q1, q2, q1 / q2 as divide from qtest;
-
-select q1, float8(q1) from qtest;
-select q2, float8(q2) from qtest;
-select q1, int8(float8(q1)) from qtest;