diff --git a/contrib/README b/contrib/README index 6601f02fe67c71073301086780c8eae92f925a79..b66dd8012c6b5b6b8609c58668d30771cf64814a 100644 --- a/contrib/README +++ b/contrib/README @@ -12,7 +12,7 @@ array - datetime - Date & time functions - by Sergio Lenzi <lenzi@bsi.com.br> + by Massimo Dal Zotto <dz@cs.unitn.it> earthdistance - Operator for computing earth distance for two points @@ -66,10 +66,6 @@ pginterface - A crude C/4GL by Bruce Momjian <root@candle.pha.pa.us> -sequence - - Set a new sequence value - by Massimo Dal Zotto <dz@cs.unitn.it> - soundex - Prototype for soundex function @@ -77,7 +73,7 @@ spi - A general trigger function autoinc() and so on. string - - New input/output conversion routines for strings + C-like input/output conversion routines for strings by Massimo Dal Zotto <dz@cs.unitn.it> unixdate - diff --git a/contrib/array/Makefile b/contrib/array/Makefile index dd2ff66091dbaba11ac4c695dbb7f923c792c4e6..9459f9c9bc3042e88d48e0e8e4bf53729c69ae72 100644 --- a/contrib/array/Makefile +++ b/contrib/array/Makefile @@ -15,36 +15,35 @@ INCLUDE_OPT = -I ./ \ -I $(SRCDIR)/include \ -I $(SRCDIR)/port/$(PORTNAME) -CFLAGS += $(INCLUDE_OPT) - -ifeq ($(PORTNAME), linux) - ifdef LINUX_ELF - ifeq ($(CC), gcc) - CFLAGS += -fPIC - endif - endif -endif - -ifeq ($(PORTNAME), i386_solaris) - CFLAGS+= -fPIC -endif +CFLAGS += $(INCLUDE_OPT) $(CFLAGS_SL) MODNAME = array_iterator MODULE = $(MODNAME)$(DLSUFFIX) +MODDIR = $(LIBDIR)/modules + +SQLDIR = $(LIBDIR)/sql + all: module sql module: $(MODULE) sql: $(MODNAME).sql -install: $(MODULE) - cp -p $(MODULE) $(LIBDIR)/modules - cd $(LIBDIR)/modules; strip $(MODULE) +install: $(MODULE) $(MODDIR) $(SQLDIR) + cp -p $(MODULE) $(MODDIR)/ + strip $(MODDIR)/$(MODULE) + cp -p $(MODNAME).sql $(SQLDIR)/ + +$(MODDIR): + mkdir -p $@ + +$(SQLDIR): + mkdir -p $@ %.sql: %.sql.in - sed "s|MODULE_PATHNAME|$(LIBDIR)/modules/$(MODULE)|" < $< > $@ + sed "s|MODULE_PATHNAME|$(MODDIR)/$(MODULE)|" < $< > $@ .SUFFIXES: $(DLSUFFIX) @@ -55,7 +54,7 @@ depend dep: $(CC) -MM $(INCLUDE_OPT) *.c >depend clean: - rm -f $(MODULE) $(MODNAME).sql + rm -f *~ $(MODULE) $(MODNAME).sql ifeq (depend,$(wildcard depend)) include depend diff --git a/contrib/array/array_iterator.c b/contrib/array/array_iterator.c index 9b6d9f8f4cf2df7fd142ba5f05a04ff86b155f83..06028ff4c6db127bd174c394452f0909c8d00a7d 100644 --- a/contrib/array/array_iterator.c +++ b/contrib/array/array_iterator.c @@ -6,7 +6,10 @@ * elements of the array and the value and compute a result as * the logical OR or AND of the iteration results. * - * Copyright (c) 1997, Massimo Dal Zotto <dz@cs.unitn.it> + * Copyright (c) 1998, Massimo Dal Zotto <dz@cs.unitn.it> + * + * This file is distributed under the GNU General Public License + * either version 2, or (at your option) any later version. */ #include <ctype.h> @@ -33,8 +36,7 @@ array_iterator(Oid elemtype, Oid proc, int and, ArrayType *array, Datum value) TypeTupleForm typ_struct; bool typbyval; int typlen; - func_ptr proc_fn; - int pronargs; + FmgrInfo finfo; int nitems, i, result; @@ -70,9 +72,8 @@ array_iterator(Oid elemtype, Oid proc, int and, ArrayType *array, Datum value) typbyval = typ_struct->typbyval; /* Lookup the function entry point */ - proc_fn = (func_ptr) NULL; - fmgr_info(proc, &pronargs); /* (proc, &proc_fn, &pronargs); */ - if ((proc_fn == NULL) || (pronargs != 2)) + fmgr_info(proc, &finfo); + if ((finfo.fn_oid == 0) || (finfo.fn_nargs != 2)) { elog(ERROR, "array_iterator: fmgr_info lookup failed for oid %d", proc); return (0); @@ -88,21 +89,21 @@ array_iterator(Oid elemtype, Oid proc, int and, ArrayType *array, Datum value) switch (typlen) { case 1: - result = (int) (*proc_fn) (*p, value); + result = (int) (*(finfo.fn_addr)) (*p, value); break; case 2: - result = (int) (*proc_fn) (*(int16 *) p, value); + result = (int) (*(finfo.fn_addr)) (*(int16 *) p, value); break; case 3: case 4: - result = (int) (*proc_fn) (*(int32 *) p, value); + result = (int) (*(finfo.fn_addr)) (*(int32 *) p, value); break; } p += typlen; } else { - result = (int) (*proc_fn) (p, value); + result = (int) (*(finfo.fn_addr)) (p, value); if (typlen > 0) p += typlen; else @@ -166,47 +167,6 @@ array_all_textregexeq(ArrayType *array, char *value) array, (Datum) value); } -/* - * Iterator functions for type _char16. Note that the regexp - * operators take the second argument of type text. - */ - -int32 -array_char16eq(ArrayType *array, char *value) -{ - return array_iterator((Oid) 20, /* char16 */ - (Oid) 1275, /* char16eq */ - 0, /* logical or */ - array, (Datum) value); -} - -int32 -array_all_char16eq(ArrayType *array, char *value) -{ - return array_iterator((Oid) 20, /* char16 */ - (Oid) 1275, /* char16eq */ - 1, /* logical and */ - array, (Datum) value); -} - -int32 -array_char16regexeq(ArrayType *array, char *value) -{ - return array_iterator((Oid) 20, /* char16 */ - (Oid) 1288, /* char16regexeq */ - 0, /* logical or */ - array, (Datum) value); -} - -int32 -array_all_char16regexeq(ArrayType *array, char *value) -{ - return array_iterator((Oid) 20, /* char16 */ - (Oid) 1288, /* char16regexeq */ - 1, /* logical and */ - array, (Datum) value); -} - /* * Iterator functions for type _int4 */ @@ -320,3 +280,11 @@ array_all_int4le(ArrayType *array, int4 value) } /* end of file */ + +/* + * Local variables: + * tab-width: 4 + * c-indent-level: 4 + * c-basic-offset: 4 + * End: + */ diff --git a/contrib/array/array_iterator.sql.in b/contrib/array/array_iterator.sql.in index 6489545d97d1e60e6a908fb2be25fe5a8b5a5a71..40deb7e0c607a02c9ecfbd1febe5bf887117c2dc 100644 --- a/contrib/array/array_iterator.sql.in +++ b/contrib/array/array_iterator.sql.in @@ -1,6 +1,13 @@ --- SQL code to define the new array iterator functions and operators +-- array_iterator.sql -- +-- +-- SQL code to define the array iterator functions and operators. +-- +-- Copyright (c) 1998, Massimo Dal Zotto <dz@cs.unitn.it> +-- +-- This file is distributed under the GNU General Public License +-- either version 2, or (at your option) any later version. --- define the array operators *=, **=, *~ and **~ for type _text +-- Define the array functions *=, **=, *~ and **~ for type _text -- create function array_texteq(_text, text) returns bool as 'MODULE_PATHNAME' @@ -38,47 +45,7 @@ create operator **~ ( rightarg=text, procedure=array_all_textregexeq); - --- define the array operators *=, **=, *~ and **~ for type _char16 --- -create function array_char16eq(_char16, char16) returns bool - as 'MODULE_PATHNAME' - language 'c'; - -create function array_all_char16eq(_char16, char16) returns bool - as 'MODULE_PATHNAME' - language 'c'; - -create function array_char16regexeq(_char16, text) returns bool - as 'MODULE_PATHNAME' - language 'c'; - -create function array_all_char16regexeq(_char16, text) returns bool - as 'MODULE_PATHNAME' - language 'c'; - -create operator *= ( - leftarg=_char16, - rightarg=char16, - procedure=array_char16eq); - -create operator **= ( - leftarg=_char16, - rightarg=char16, - procedure=array_all_char16eq); - -create operator *~ ( - leftarg=_char16, - rightarg=text, - procedure=array_char16regexeq); - -create operator **~ ( - leftarg=_char16, - rightarg=text, - procedure=array_all_char16regexeq); - - --- define the array operators *=, **=, *> and **> for type _int4 +-- Define the array functions *=, **=, *> and **> for type _int4 -- create function array_int4eq(_int4, int4) returns bool as 'MODULE_PATHNAME' @@ -128,6 +95,8 @@ create function array_all_int4le(_int4, int4) returns bool as 'MODULE_PATHNAME' language 'c'; +-- Define the operators corresponding to the above functions +-- create operator *= ( leftarg=_int4, rightarg=int4, diff --git a/contrib/datetime/Makefile b/contrib/datetime/Makefile index fdab004eda0bf4cafb119630bf4b27c7635c1c5d..6754bce24f189fae5a140783fac8b89c5e3f0816 100644 --- a/contrib/datetime/Makefile +++ b/contrib/datetime/Makefile @@ -15,36 +15,35 @@ INCLUDE_OPT = -I ./ \ -I $(SRCDIR)/include \ -I $(SRCDIR)/port/$(PORTNAME) -CFLAGS += $(INCLUDE_OPT) - -ifeq ($(PORTNAME), linux) - ifdef LINUX_ELF - ifeq ($(CC), gcc) - CFLAGS += -fPIC - endif - endif -endif - -ifeq ($(PORTNAME), i386_solaris) - CFLAGS+= -fPIC -endif +CFLAGS += $(INCLUDE_OPT) $(CFLAGS_SL) MODNAME = datetime_functions MODULE = $(MODNAME)$(DLSUFFIX) +MODDIR = $(LIBDIR)/modules + +SQLDIR = $(LIBDIR)/sql + all: module sql module: $(MODULE) sql: $(MODNAME).sql -install: $(MODULE) - cp -p $(MODULE) $(LIBDIR)/modules - cd $(LIBDIR)/modules; strip $(MODULE) +install: $(MODULE) $(MODDIR) $(SQLDIR) + cp -p $(MODULE) $(MODDIR)/ + strip $(MODDIR)/$(MODULE) + cp -p $(MODNAME).sql $(SQLDIR)/ + +$(MODDIR): + mkdir -p $@ + +$(SQLDIR): + mkdir -p $@ %.sql: %.sql.in - sed "s|MODULE_PATHNAME|$(LIBDIR)/modules/$(MODULE)|" < $< > $@ + sed "s|MODULE_PATHNAME|$(MODDIR)/$(MODULE)|" < $< > $@ .SUFFIXES: $(DLSUFFIX) @@ -55,7 +54,7 @@ depend dep: $(CC) -MM $(INCLUDE_OPT) *.c >depend clean: - rm -f $(MODULE) $(MODNAME).sql + rm -f *~ $(MODULE) $(MODNAME).sql ifeq (depend,$(wildcard depend)) include depend diff --git a/contrib/datetime/datetime_functions.c b/contrib/datetime/datetime_functions.c index 5138b7fa6f7d81cbfd946a07f116eeefa12dfa05..11c0be64f600418e394af59a03764c2cab09700b 100644 --- a/contrib/datetime/datetime_functions.c +++ b/contrib/datetime/datetime_functions.c @@ -3,10 +3,13 @@ * * This file defines new functions for the time and date data types. * - * Copyright (c) 1996, Massimo Dal Zotto <dz@cs.unitn.it> + * Copyright (c) 1998, Massimo Dal Zotto <dz@cs.unitn.it> + * + * This file is distributed under the GNU General Public License + * either version 2, or (at your option) any later version. */ -#include <stdio.h> /* for sprintf() */ +#include <stdio.h> #include <string.h> #include <limits.h> #ifdef HAVE_FLOAT_H @@ -102,7 +105,6 @@ hhmm_out(TimeADT *time) sprintf(buf, "%02d:%02d:%02d", tm->tm_hour, tm->tm_min, tm->tm_sec); result = palloc(strlen(buf) + 1); - strcpy(result, buf); return (result); @@ -220,3 +222,11 @@ currentdate() } /* end of file */ + +/* + * Local variables: + * tab-width: 4 + * c-indent-level: 4 + * c-basic-offset: 4 + * End: + */ diff --git a/contrib/datetime/datetime_functions.doc b/contrib/datetime/datetime_functions.doc index 1b147e7ac1e2f22e78c7a38af53adbad9cd4fe66..33b41d02181d46cd8f09b499b69118348359aeb7 100644 --- a/contrib/datetime/datetime_functions.doc +++ b/contrib/datetime/datetime_functions.doc @@ -1,16 +1,11 @@ -Date & time functions for use in Postgres version 6.1 & up - -This functions replaces the original ones from the postgresql.org -because the date & time structures has changed. - -There is a Makefile that should be "ajusted" -for directories where postgres home after install. - -In this case: /usr/postgres. - -Hope this can help, - - -Sergio Lenzi (lenzi@bsi.com.br) +I have written some new funtions for time and date data types which can +be used to extract hour,minutes,seconds from time values, and year, +month,day from a date. There is also a time_difference and functions +to convert a time to minutes or seconds. +There are also new input/output functions for the time data type which +allow the insertion of time attributes with value 24:00:00. +This can be useful if your application needs to compute time difference +from two time values representing an elapsed time of 24 hours. +Massimo Dal Zotto <dz@cs.unitn.it> diff --git a/contrib/datetime/datetime_functions.sql.in b/contrib/datetime/datetime_functions.sql.in index 81e40aa9af19636df0aea6fd445c075ca38a00a3..83e9eac9d4c0e8df95367a165d2f10b4fb785b82 100644 --- a/contrib/datetime/datetime_functions.sql.in +++ b/contrib/datetime/datetime_functions.sql.in @@ -1,6 +1,13 @@ +-- datetime_functions.sql -- +-- -- SQL code to define the new date and time functions and operators +-- +-- Copyright (c) 1998, Massimo Dal Zotto <dz@cs.unitn.it> +-- +-- This file is distributed under the GNU General Public License +-- either version 2, or (at your option) any later version. --- Define the new functions +-- Define the new time functions. -- create function hhmm_in(opaque) returns time as 'MODULE_PATHNAME' @@ -58,16 +65,14 @@ create function currentdate() returns date as 'MODULE_PATHNAME' language 'c'; - --- Define a new operator - for time +-- Define new operator - for time. -- create operator - ( leftarg=time, rightarg=time, procedure=time_difference); - --- Define functions to switch from time to hhmm representation +-- Define functions to switch from time to hhmm representation. -- -- select hhmm_mode(); -- select time_mode(); @@ -84,7 +89,6 @@ create function time_mode() returns text select ''time_mode''::text' language 'sql'; - -- Use these to do the updates manually -- -- update pg_type set typinput ='hhmm_in' where typname='time'; diff --git a/contrib/miscutil/Makefile b/contrib/miscutil/Makefile index 33ba1e09370e11c4262aabc516f4a8834fe21aaf..ecb855e560073a1166c75e2564028c3a4b586434 100644 --- a/contrib/miscutil/Makefile +++ b/contrib/miscutil/Makefile @@ -1,7 +1,8 @@ #------------------------------------------------------------------------- # -# Makefile-- -# Makefile for array iterator functions. +# Makefile -- +# +# Makefile for the misc_util module. # #------------------------------------------------------------------------- @@ -15,36 +16,35 @@ INCLUDE_OPT = -I ./ \ -I $(SRCDIR)/include \ -I $(SRCDIR)/port/$(PORTNAME) -CFLAGS += $(INCLUDE_OPT) - -ifeq ($(PORTNAME), linux) - ifdef LINUX_ELF - ifeq ($(CC), gcc) - CFLAGS += -fPIC - endif - endif -endif - -ifeq ($(PORTNAME), i386_solaris) - CFLAGS+= -fPIC -endif +CFLAGS += $(INCLUDE_OPT) $(CFLAGS_SL) MODNAME = misc_utils MODULE = $(MODNAME)$(DLSUFFIX) +MODDIR = $(LIBDIR)/modules + +SQLDIR = $(LIBDIR)/sql + all: module sql module: $(MODULE) sql: $(MODNAME).sql -install: $(MODULE) - cp -p $(MODULE) $(LIBDIR)/modules - cd $(LIBDIR)/modules; strip $(MODULE) +install: $(MODULE) $(MODDIR) $(SQLDIR) + cp -p $(MODULE) $(MODDIR)/ + strip $(MODDIR)/$(MODULE) + cp -p $(MODNAME).sql $(SQLDIR)/ + +$(MODDIR): + mkdir -p $@ + +$(SQLDIR): + mkdir -p $@ %.sql: %.sql.in - sed "s|MODULE_PATHNAME|$(LIBDIR)/modules/$(MODULE)|" < $< > $@ + sed "s|MODULE_PATHNAME|$(MODDIR)/$(MODULE)|" < $< > $@ .SUFFIXES: $(DLSUFFIX) @@ -55,7 +55,7 @@ depend dep: $(CC) -MM $(INCLUDE_OPT) *.c >depend clean: - rm -f $(MODULE) $(MODNAME).sql assert_test.so + rm -f *~ $(MODULE) $(MODNAME).sql ifeq (depend,$(wildcard depend)) include depend diff --git a/contrib/miscutil/assert_test.c b/contrib/miscutil/assert_test.c deleted file mode 100644 index 793f585e5100d4af6e37e2854543f2ba82dc8527..0000000000000000000000000000000000000000 --- a/contrib/miscutil/assert_test.c +++ /dev/null @@ -1,43 +0,0 @@ -/* - * assert_test.c -- - * - * This file tests Postgres assert checking. - * - * Copyright (c) 1996, Massimo Dal Zotto <dz@cs.unitn.it> - */ - -#include "postgres.h" -#include "assert_test.h" - -extern int assertTest(int val); -extern int assertEnable(int val); - -int -assert_enable(int val) -{ - return assertEnable(val); -} - -int -assert_test(int val) -{ - return assertTest(val); -} - -/* - --- Enable/disable Postgres assert checking. --- -create function assert_enable(int4) returns int4 - as '/usr/local/pgsql/lib/assert_test.so' - language 'C'; - --- Test Postgres assert checking. --- -create function assert_test(int4) returns int4 - as '/usr/local/pgsql/lib/assert_test.so' - language 'C'; - -*/ - -/* end of file */ diff --git a/contrib/miscutil/assert_test.h b/contrib/miscutil/assert_test.h deleted file mode 100644 index 73b3938e065449a011d3bb8e85d24d8381669ad0..0000000000000000000000000000000000000000 --- a/contrib/miscutil/assert_test.h +++ /dev/null @@ -1,7 +0,0 @@ -#ifndef ASSERT_TEST_H -#define ASSERT_TEST_H - -int assert_enable(int val); -int assert_test(int val); - -#endif diff --git a/contrib/miscutil/misc_utils.c b/contrib/miscutil/misc_utils.c index b787457e3f9f8c806c951e6d26cd2b9169606f29..ee2f3ec2b28c545b18b653a3ef29ed75769bda0f 100644 --- a/contrib/miscutil/misc_utils.c +++ b/contrib/miscutil/misc_utils.c @@ -1,9 +1,12 @@ /* - * utils.c -- + * misc_utils.c -- * - * This file defines various Postgres utility functions. + * This file defines miscellaneous PostgreSQL utility functions. * - * Copyright (c) 1996, Massimo Dal Zotto <dz@cs.unitn.it> + * Copyright (c) 1998, Massimo Dal Zotto <dz@cs.unitn.it> + * + * This file is distributed under the GNU General Public License + * either version 2, or (at your option) any later version. */ #include <unistd.h> @@ -12,9 +15,15 @@ #include "utils/palloc.h" #include "misc_utils.h" +#include "assert_test.h" extern int ExecutorLimit(int limit); extern void Async_Unlisten(char *relname, int pid); +extern int assertTest(int val); + +#ifdef ASSERT_CHECKING_TEST +extern int assertEnable(int val); +#endif int query_limit(int limit) @@ -47,4 +56,26 @@ min(int x, int y) return ((x < y) ? x : y); } +int +assert_enable(int val) +{ + return assertEnable(val); +} + +#ifdef ASSERT_CHECKING_TEST +int +assert_test(int val) +{ + return assertTest(val); +} +#endif + /* end of file */ + +/* + * Local variables: + * tab-width: 4 + * c-indent-level: 4 + * c-basic-offset: 4 + * End: + */ diff --git a/contrib/miscutil/misc_utils.doc b/contrib/miscutil/misc_utils.doc new file mode 100644 index 0000000000000000000000000000000000000000..d1e3ac29ab8bf92472d91dbffe3ffff44e12879b --- /dev/null +++ b/contrib/miscutil/misc_utils.doc @@ -0,0 +1,39 @@ +Miscellaneous utility functions for PostgreSQL. + +query_limit(n) + + sets a limit on the maximum numbers of query returned from + a backend. It can be used to limit the result size retrieved + by the application for poor input data or to avoid accidental + table product while playying with sql. + +backend_pid() + + return the pid of our corresponding backend. + +unlisten(relname) + + unlisten from a relation or from all relations if the argument + is null, empty or '*'. + It is now obsoleted by the new unlisten command but still useful + if you want unlisten a name computed by the query. + Note that a listen/notify relname can be any ascii string, not + just valid relation names. + +min(x,y) +max(x,y) + + return the min or max bteween two integers. + +assert_enable(bool) + + enable/disable assert checkings in the backend, if it has been + compiled with USE_ASSERT_CHECKING. + +assert_test(bool) + + test the assert enable/disable code, if the backend has been + compiled with ASSERT_CHECKING_TEST. + +-- +Massimo Dal Zotto <dz@cs.unitn.it> diff --git a/contrib/miscutil/misc_utils.h b/contrib/miscutil/misc_utils.h index a87c71b244b570de687cf5c85b5ca80c2d07fc2a..cc7f923443228f5fe76f8f615c93574513c156ab 100644 --- a/contrib/miscutil/misc_utils.h +++ b/contrib/miscutil/misc_utils.h @@ -6,5 +6,17 @@ int backend_pid(void); int unlisten(char *relname); int max(int x, int y); int min(int x, int y); +int assert_enable(int val); +#ifdef ASSERT_CHECKING_TEST +int assert_test(int val); +#endif #endif + +/* + * Local variables: + * tab-width: 4 + * c-indent-level: 4 + * c-basic-offset: 4 + * End: + */ diff --git a/contrib/miscutil/misc_utils.sql.in b/contrib/miscutil/misc_utils.sql.in index 0c90ba52eb9b8ece752f97ac228e001f40eabde0..1185d743e69ed0a26d6ad55299e593b2ef3a7628 100644 --- a/contrib/miscutil/misc_utils.sql.in +++ b/contrib/miscutil/misc_utils.sql.in @@ -1,40 +1,58 @@ --- SQL code to define the new array iterator functions and operators +-- misc_utils.sql -- +-- +-- SQL code to define misc functions. +-- +-- Copyright (c) 1998, Massimo Dal Zotto <dz@cs.unitn.it> +-- +-- This file is distributed under the GNU General Public License +-- either version 2, or (at your option) any later version. --- min(x,y) +-- Set the maximum number of tuples returned by a single query. -- -create function min(int4,int4) returns int4 +create function query_limit(int4) returns int4 as 'MODULE_PATHNAME' language 'C'; --- max(x,y) +-- Return the pid of the backend. -- -create function max(int4,int4) returns int4 +create function backend_pid() returns int4 as 'MODULE_PATHNAME' language 'C'; --- Set the maximum number of tuples returned by a single query +-- Unlisten from a relation. -- -create function query_limit(int4) returns int4 +create function "unlisten"(name) returns int4 as 'MODULE_PATHNAME' language 'C'; --- Return the pid of the backend +-- Unlisten from all relations for this backend. -- -create function backend_pid() returns int4 +create function "unlisten"() returns int4 + as 'select "unlisten"(''*'')' + language 'sql'; + +-- min(x,y) +-- +create function min(int4,int4) returns int4 as 'MODULE_PATHNAME' language 'C'; --- Unlisten from a relation +-- max(x,y) -- -create function unlisten(name) returns int4 +create function max(int4,int4) returns int4 as 'MODULE_PATHNAME' language 'C'; --- Unlisten from all relations for this backend +-- Enable/disable Postgres assert checking. -- -create function unlisten() returns int4 - as 'delete from pg_listener where listenerpid = backend_pid(); - select 0' - language 'sql'; +create function assert_enable(int4) returns int4 + as 'MODULE_PATHNAME' + language 'C'; + +-- Test Postgres assert checking. +-- +-- create function assert_test(int4) returns int4 +-- as 'MODULE_PATHNAME' +-- language 'C'; -- end of file diff --git a/contrib/string/Makefile b/contrib/string/Makefile index 4aba9482772e628f4af82de83d904d66ffb748e0..ea42cfa91b7df08ed1b43091e8af99ac4871846f 100644 --- a/contrib/string/Makefile +++ b/contrib/string/Makefile @@ -1,7 +1,7 @@ #------------------------------------------------------------------------- # -# Makefile-- -# Makefile for new string I/O functions. +# Makefile -- +# Makefile for string I/O module. # #------------------------------------------------------------------------- @@ -15,36 +15,35 @@ INCLUDE_OPT = -I ./ \ -I $(SRCDIR)/include \ -I $(SRCDIR)/port/$(PORTNAME) -CFLAGS += $(INCLUDE_OPT) - -ifeq ($(PORTNAME), linux) - ifdef LINUX_ELF - ifeq ($(CC), gcc) - CFLAGS += -fPIC - endif - endif -endif - -ifeq ($(PORTNAME), i386_solaris) - CFLAGS+= -fPIC -endif +CFLAGS += $(INCLUDE_OPT) $(CFLAGS_SL) MODNAME = string_io MODULE = $(MODNAME)$(DLSUFFIX) +MODDIR = $(LIBDIR)/modules + +SQLDIR = $(LIBDIR)/sql + all: module sql module: $(MODULE) sql: $(MODNAME).sql -install: $(MODULE) - cp -p $(MODULE) $(LIBDIR)/modules - cd $(LIBDIR)/modules; strip $(MODULE) +install: $(MODULE) $(MODDIR) $(SQLDIR) + cp -p $(MODULE) $(MODDIR)/ + strip $(MODDIR)/$(MODULE) + cp -p $(MODNAME).sql $(SQLDIR)/ + +$(MODDIR): + mkdir -p $@ + +$(SQLDIR): + mkdir -p $@ %.sql: %.sql.in - sed "s|MODULE_PATHNAME|$(LIBDIR)/modules/$(MODULE)|" < $< > $@ + sed "s|MODULE_PATHNAME|$(MODDIR)/$(MODULE)|" < $< > $@ .SUFFIXES: $(DLSUFFIX) @@ -55,7 +54,7 @@ depend dep: $(CC) -MM $(INCLUDE_OPT) *.c >depend clean: - rm -f $(MODULE) $(MODNAME).sql + rm -f *~ $(MODULE) $(MODNAME).sql ifeq (depend,$(wildcard depend)) include depend diff --git a/contrib/string/string_io.c b/contrib/string/string_io.c index b163fb75c6c43560683d6184b79cc4646a3ea3c9..03b7169a54a68bf5c0a056f6634b9094a7c6864a 100644 --- a/contrib/string/string_io.c +++ b/contrib/string/string_io.c @@ -1,9 +1,12 @@ /* * string_io.c -- * - * This file defines new input/output conversion routines for strings. + * This file defines C-like input/output conversion routines for strings. * - * Copyright (c) 1996, Massimo Dal Zotto <dz@cs.unitn.it> + * Copyright (c) 1998, Massimo Dal Zotto <dz@cs.unitn.it> + * + * This file is distributed under the GNU General Public License + * either version 2, or (at your option) any later version. */ #include <ctype.h> @@ -33,14 +36,14 @@ * string_output() -- * * This function takes a pointer to a string data and an optional - * data size and returns a printable representation of the data + * data size and returns a printable representation of the string * translating all escape sequences to C-like \nnn or \c escapes. * The function is used by output methods of various string types. * * Arguments: * data - input data (can be NULL) * size - optional size of data. A negative value indicates - * that data is a null terminated string. + * that data is a null terminated string. * * Returns: * a pointer to a new string containing the printable @@ -165,13 +168,13 @@ string_output(char *data, int size) * Arguments: * str - input string possibly with escapes * size - the required size of new data. A value of 0 - * indicates a variable size string, while a - * negative value indicates a variable size string - * of size not greater than this absolute value. + * indicates a variable size string, while a + * negative value indicates a variable size string + * of size not greater than this absolute value. * hdrsize - size of an optional header to be allocated before - * the data. It must then be filled by the caller. + * the data. It must then be filled by the caller. * rtn_size - an optional pointer to an int variable where the - * size of the new string is stored back. + * size of the new string is stored back. * * Returns: * a pointer to the new string or the header. @@ -293,32 +296,8 @@ c_charout(int32 c) return (string_output(str, 1)); } -char * -c_char2out(uint16 s) -{ - return (string_output((char *) &s, 2)); -} - -char * -c_char4out(uint32 s) -{ - return (string_output((char *) &s, 4)); -} - -char * -c_char8out(char *s) -{ - return (string_output(s, 8)); -} - -char * -c_char16out(char *s) -{ - return (string_output(s, 16)); -} - /* - * This can be used for text, bytea, SET and unknown data types + * This can be used for SET, bytea, text and unknown data types */ char * @@ -368,13 +347,19 @@ c_textin(char *str) return (result); } -char * -c_char16in(char *str) +int32 * +c_charin(char *str) { - return (string_input(str, 16, 0, NULL)); + return (string_input(str, 1, 0, NULL)); } - #endif - /* end of file */ + +/* + * Local variables: + * tab-width: 4 + * c-indent-level: 4 + * c-basic-offset: 4 + * End: + */ diff --git a/contrib/string/string_io.doc b/contrib/string/string_io.doc new file mode 100644 index 0000000000000000000000000000000000000000..af4b974785917e1d1406d579188cc94f96d8d9ef --- /dev/null +++ b/contrib/string/string_io.doc @@ -0,0 +1,16 @@ +These output functions can be used as substitution of the standard text +output functions to get the value of text fields printed in the format +used for C strings. This allows the output of queries or the exported +files to be processed more easily using standard unix filter programs +like perl or awk. + +If you use the standard functions instead you could find a single tuple +splitted into many lines and the tabs embedded in the values could be +confused with those used as field delimters. + +My function translates all non-printing characters into corresponding +esacape sequences as defined by the C syntax. All you need to reconstruct +the exact value in your application is a corresponding unescape function +like the string_input defined in the source code. + +Massimo Dal Zotto <dz@cs.unitn.it> diff --git a/contrib/string/string_io.h b/contrib/string/string_io.h index b2af60f62c0444040024a2cb131559adfe84ad60..1ac0f2fb165c817efa0130390a0fa30652234389 100644 --- a/contrib/string/string_io.h +++ b/contrib/string/string_io.h @@ -14,7 +14,14 @@ char *c_varcharout(char *s); #if 0 struct varlena *c_textin(char *str); char *c_char16in(char *str); - #endif #endif + +/* + * Local variables: + * tab-width: 4 + * c-indent-level: 4 + * c-basic-offset: 4 + * End: + */ diff --git a/contrib/string/string_io.sql.in b/contrib/string/string_io.sql.in index ad1a51607cddad5bf13be6ee5ce94ec3ecc761d5..a1fafbc3ae87e0ca9509e019942037d4b358a41d 100644 --- a/contrib/string/string_io.sql.in +++ b/contrib/string/string_io.sql.in @@ -1,32 +1,18 @@ +-- string_io.sql -- +-- -- SQL code to define the new string I/O functions - --- This is not needed because escapes are handled by the parser -- --- create function c_textin(opaque) --- returns text --- as 'MODULE_PATHNAME' --- language 'c'; +-- Copyright (c) 1998, Massimo Dal Zotto <dz@cs.unitn.it> +-- +-- This file is distributed under the GNU General Public License +-- either version 2, or (at your option) any later version. +-- Define the new output functions. +-- create function c_charout(opaque) returns int4 as 'MODULE_PATHNAME' language 'c'; -create function c_char2out(opaque) returns int4 - as 'MODULE_PATHNAME' - language 'c'; - -create function c_char4out(opaque) returns int4 - as 'MODULE_PATHNAME' - language 'c'; - -create function c_char8out(opaque) returns int4 - as 'MODULE_PATHNAME' - language 'c'; - -create function c_char16out(opaque) returns int4 - as 'MODULE_PATHNAME' - language 'c'; - create function c_textout(opaque) returns int4 as 'MODULE_PATHNAME' language 'c'; @@ -35,70 +21,59 @@ create function c_varcharout(opaque) returns int4 as 'MODULE_PATHNAME' language 'c'; +-- This is not needed because escapes are handled by the parser +-- +-- create function c_textin(opaque) +-- returns text +-- as 'MODULE_PATHNAME' +-- language 'c'; --- Define a function which sets the new output routines for char types +-- Define a function which sets the new output routines for char types. -- -- select c_mode(); -- create function c_mode() returns text - as 'update pg_type set typoutput=''c_charout'' where typname=''char''; - update pg_type set typoutput=''c_char2out'' where typname=''char2''; - update pg_type set typoutput=''c_char4out'' where typname=''char4''; - update pg_type set typoutput=''c_char8out'' where typname=''char8''; - update pg_type set typoutput=''c_char16out'' where typname=''char16''; - update pg_type set typoutput=''c_textout'' where typname=''text''; + as 'update pg_type set typoutput=''c_textout'' where typname=''SET''; + update pg_type set typoutput=''c_varcharout'' where typname=''bpchar''; update pg_type set typoutput=''c_textout'' where typname=''bytea''; + update pg_type set typoutput=''c_charout'' where typname=''char''; + update pg_type set typoutput=''c_textout'' where typname=''text''; update pg_type set typoutput=''c_textout'' where typname=''unknown''; - update pg_type set typoutput=''c_textout'' where typname=''SET''; update pg_type set typoutput=''c_varcharout'' where typname=''varchar''; - update pg_type set typoutput=''c_varcharout'' where typname=''bpchar''; select ''c_mode''::text' language 'sql'; --- Define a function which restores the original routines for char types +-- Define a function which restores the standard routines for char types. -- -- select pg_mode(); -- create function pg_mode() returns text - as 'update pg_type set typoutput=''charout'' where typname=''char''; - update pg_type set typoutput=''char2out'' where typname=''char2''; - update pg_type set typoutput=''char4out'' where typname=''char4''; - update pg_type set typoutput=''char8out'' where typname=''char8''; - update pg_type set typoutput=''char16out'' where typname=''char16''; - update pg_type set typoutput=''textout'' where typname=''text''; + as 'update pg_type set typoutput=''textout'' where typname=''SET''; + update pg_type set typoutput=''varcharout'' where typname=''bpchar''; update pg_type set typoutput=''textout'' where typname=''bytea''; + update pg_type set typoutput=''charout'' where typname=''char''; + update pg_type set typoutput=''textout'' where typname=''text''; update pg_type set typoutput=''textout'' where typname=''unknown''; - update pg_type set typoutput=''textout'' where typname=''SET''; update pg_type set typoutput=''varcharout'' where typname=''varchar''; - update pg_type set typoutput=''varcharout'' where typname=''bpchar''; select ''pg_mode''::text' language 'sql'; - --- Use these if you want do the updates manually +-- Use these to do the changes manually. -- +-- update pg_type set typoutput='textout' where typname='SET'; +-- update pg_type set typoutput='varcharout' where typname='bpchar'; +-- update pg_type set typoutput='textout' where typname='bytea'; -- update pg_type set typoutput='charout' where typname='char'; --- update pg_type set typoutput='char2out' where typname='char2'; --- update pg_type set typoutput='char4out' where typname='char4'; --- update pg_type set typoutput='char8out' where typname='char8'; --- update pg_type set typoutput='char16out' where typname='char16'; -- update pg_type set typoutput='textout' where typname='text'; --- update pg_type set typoutput='textout' where typname='bytea'; -- update pg_type set typoutput='textout' where typname='unknown'; --- update pg_type set typoutput='textout' where typname='SET'; -- update pg_type set typoutput='varcharout' where typname='varchar'; --- update pg_type set typoutput='varcharout' where typname='bpchar'; -- +-- update pg_type set typoutput='c_textout' where typname='SET'; +-- update pg_type set typoutput='c_varcharout' where typname='bpchar'; +-- update pg_type set typoutput='c_textout' where typname='bytea'; -- update pg_type set typoutput='c_charout' where typname='char'; --- update pg_type set typoutput='c_char2out' where typname='char2'; --- update pg_type set typoutput='c_char4out' where typname='char4'; --- update pg_type set typoutput='c_char8out' where typname='char8'; --- update pg_type set typoutput='c_char16out' where typname='char16'; -- update pg_type set typoutput='c_textout' where typname='text'; --- update pg_type set typoutput='c_textout' where typname='bytea'; -- update pg_type set typoutput='c_textout' where typname='unknown'; --- update pg_type set typoutput='c_textout' where typname='SET'; -- update pg_type set typoutput='c_varcharout' where typname='varchar'; --- update pg_type set typoutput='c_varcharout' where typname='bpchar'; -- end of file diff --git a/contrib/userlock/Makefile b/contrib/userlock/Makefile index 2b6785945384284a96bf638be35100db19d6b335..ab43f6e388cc40ae0276d7ed0914e4856400cdf7 100644 --- a/contrib/userlock/Makefile +++ b/contrib/userlock/Makefile @@ -1,7 +1,7 @@ #------------------------------------------------------------------------- # -# Makefile-- -# Makefile for new string I/O functions. +# Makefile -- +# Makefile for the user_locks module. # #------------------------------------------------------------------------- @@ -15,36 +15,35 @@ INCLUDE_OPT = -I ./ \ -I $(SRCDIR)/include \ -I $(SRCDIR)/port/$(PORTNAME) -CFLAGS += $(INCLUDE_OPT) - -ifeq ($(PORTNAME), linux) - ifdef LINUX_ELF - ifeq ($(CC), gcc) - CFLAGS += -fPIC - endif - endif -endif - -ifeq ($(PORTNAME), i386_solaris) - CFLAGS+= -fPIC -endif +CFLAGS += $(INCLUDE_OPT) $(CFLAGS_SL) MODNAME = user_locks MODULE = $(MODNAME)$(DLSUFFIX) +MODDIR = $(LIBDIR)/modules + +SQLDIR = $(LIBDIR)/sql + all: module sql module: $(MODULE) sql: $(MODNAME).sql -install: $(MODULE) - cp -p $(MODULE) $(LIBDIR)/modules - cd $(LIBDIR)/modules; strip $(MODULE) +install: $(MODULE) $(MODDIR) $(SQLDIR) + cp -p $(MODULE) $(MODDIR)/ + strip $(MODDIR)/$(MODULE) + cp -p $(MODNAME).sql $(SQLDIR)/ + +$(MODDIR): + mkdir -p $@ + +$(SQLDIR): + mkdir -p $@ %.sql: %.sql.in - sed "s|MODULE_PATHNAME|$(LIBDIR)/modules/$(MODULE)|" < $< > $@ + sed "s|MODULE_PATHNAME|$(MODDIR)/$(MODULE)|" < $< > $@ .SUFFIXES: $(DLSUFFIX) @@ -55,7 +54,7 @@ depend dep: $(CC) -MM $(INCLUDE_OPT) *.c >depend clean: - rm -f $(MODULE) $(MODNAME).sql + rm -f *~ $(MODULE) $(MODNAME).sql ifeq (depend,$(wildcard depend)) include depend diff --git a/contrib/userlock/user_locks.c b/contrib/userlock/user_locks.c index fe8abcac0cf430a4673a665675d17f13de0a8c76..745f28d5bc966baa524a6f031882d042ef6f4675 100644 --- a/contrib/userlock/user_locks.c +++ b/contrib/userlock/user_locks.c @@ -4,7 +4,10 @@ * This loadable module, together with my user-lock.patch applied to the * backend, provides support for user-level long-term cooperative locks. * - * Copyright (c) 1996, Massimo Dal Zotto <dz@cs.unitn.it> + * Copyright (c) 1998, Massimo Dal Zotto <dz@cs.unitn.it> + * + * This file is distributed under the GNU General Public License + * either version 2, or (at your option) any later version. */ #include <stdio.h> @@ -14,46 +17,40 @@ #include "postgres.h" #include "miscadmin.h" #include "storage/lock.h" -#include "storage/lmgr.h" #include "storage/proc.h" -#include "storage/block.h" #include "storage/multilev.h" #include "utils/elog.h" #include "user_locks.h" -#define USER_LOCKS_TABLE_ID 0 - -extern Oid MyDatabaseId; - int -user_lock(unsigned int id1, unsigned int id2, LOCKT lockt) +user_lock(unsigned int id1, unsigned int id2, LOCKMODE lockmode) { LOCKTAG tag; memset(&tag, 0, sizeof(LOCKTAG)); + tag.dbId = MyDatabaseId; tag.relId = 0; - tag.dbId = MyDatabaseId; tag.tupleId.ip_blkid.bi_hi = id2 >> 16; tag.tupleId.ip_blkid.bi_lo = id2 & 0xffff; tag.tupleId.ip_posid = (unsigned short) (id1 & 0xffff); - return LockAcquire(USER_LOCKS_TABLE_ID, &tag, lockt); + return LockAcquire(USER_LOCKMETHOD, &tag, lockmode); } int -user_unlock(unsigned int id1, unsigned int id2, LOCKT lockt) +user_unlock(unsigned int id1, unsigned int id2, LOCKMODE lockmode) { LOCKTAG tag; memset(&tag, 0, sizeof(LOCKTAG)); + tag.dbId = MyDatabaseId; tag.relId = 0; - tag.dbId = MyDatabaseId; tag.tupleId.ip_blkid.bi_hi = id2 >> 16; tag.tupleId.ip_blkid.bi_lo = id2 & 0xffff; tag.tupleId.ip_posid = (unsigned short) (id1 & 0xffff); - return LockRelease(USER_LOCKS_TABLE_ID, &tag, lockt); + return LockRelease(USER_LOCKMETHOD, &tag, lockmode); } int @@ -87,7 +84,7 @@ user_unlock_all() PROC *proc; SHMEM_OFFSET location; - ShmemPIDLookup(getpid(), &location); + ShmemPIDLookup(MyProcPid, &location); if (location == INVALID_OFFSET) { elog(NOTICE, "UserUnlockAll: unable to get proc ptr"); @@ -95,7 +92,15 @@ user_unlock_all() } proc = (PROC *) MAKE_PTR(location); - return LockReleaseAll(USER_LOCKS_TABLE_ID, &proc->lockQueue); + return LockReleaseAll(USER_LOCKMETHOD, &proc->lockQueue); } /* end of file */ + +/* + * Local variables: + * tab-width: 4 + * c-indent-level: 4 + * c-basic-offset: 4 + * End: + */ diff --git a/contrib/userlock/user_locks.doc b/contrib/userlock/user_locks.doc index 15ffe48f13b48ba9aadb7ebfd37af6db5cc8685b..87c474bd1cf02a216000d53227bde575175fcf7e 100644 --- a/contrib/userlock/user_locks.doc +++ b/contrib/userlock/user_locks.doc @@ -2,29 +2,49 @@ User locks, by Massimo Dal Zotto <dz@cs.unitn.it> This loadable module, together with my user-lock.patch applied to the backend, provides support for user-level long-term cooperative locks. +For example one can write: -For example one can write (this example is written in TclX): - - set rec [sql "select ...,user_write_lock_oid(oid) from table where id=$id"] - if {[keylget rec user_write_lock_oid] == 1} { - # the write lock has been acquired with the record, start - # a long editing session, then update the database and - # release the lock. - sql "update table set ... where id=$id" - sql "select user_write_unlock_oid([keylget rec oid])" - } else { - # the record has been read but the write lock couldn't be acquired, - # so it should not be modified by the application. - messageBox "This record is in use by another user, retry later" - } + select some_fields, user_write_lock_oid(oid) from table where id='key'; + +Now if the returned user_write_lock_oid field is 1 you have acquired an +user lock on the oid of the selected tuple and can now do some long operation +on it, like let the data being edited by the user. +If it is 0 it means that the lock has been already acquired by some other +process and you should not use that item until the other has finished. +Note that in this case the query returns 0 immediately without waiting on +the lock. This is good if the lock is held for long time. +After you have finished your work on that item you can do: + + update table set some_fields where id='key'; + select user_write_unlock_oid(oid) from table where id='key'; + +You can also ignore the failure and go ahead but this could produce conflicts +or inconsistent data in your application. User locks require a cooperative +behavior between users. User locks don't interfere with the normal locks +used by postgres for transaction processing. This could also be done by setting a flag in the record itself but in -this case you have the overhead of the updates to the record and there -may be some locks not released if the backend or the application crashes -before resetting the flag. +this case you have the overhead of the updates to the records and there +could be some locks not released if the backend or the application crashes +before resetting the lock flag. It could also be done with a begin/end block but in this case the entire table would be locked by postgres and it is not acceptable to do this for a long period because other transactions would block completely. -Note that this type of locks are handled cooperatively by the application -and do not interfere with the normal locks used by postgres. So an user -could still modify an user-locked record if he wanted to ignore the lock. + +The generic user locks use two values, group and id, to identify a lock, +which correspond to ip_posid and ip_blkid of an ItemPointerData. +Group is a 16 bit value while id is a 32 bit integer which can also +contain an oid. The oid user lock function, which take an oid as argument, +use a group equal to 0. + +The meaning of group and id is defined by the application. The user +lock code just takes two numbers and tells you if the corresponding +entity has been succesfully locked. What this mean is up to you. + +My succestion is that you use the group to identify an area of your +application and the id to identify an object in this area. +Or you can just lock the oid of the tuples which are by definition unique. + +Note also that a process can acquire more than one lock on the same entity +and it must release the lock the corresponding number of times. This can +be done calling the unlock funtion until it returns 0. diff --git a/contrib/userlock/user_locks.h b/contrib/userlock/user_locks.h index 7f315564031e7e465a3e2b6fd3d6d31f491ef20b..0a8f55cbdd8001746a72df5d0c443b42eb42f686 100644 --- a/contrib/userlock/user_locks.h +++ b/contrib/userlock/user_locks.h @@ -1,8 +1,8 @@ #ifndef USER_LOCKS_H #define USER_LOCKS_H -int user_lock(unsigned int id1, unsigned int id2, LOCKT lockt); -int user_unlock(unsigned int id1, unsigned int id2, LOCKT lockt); +int user_lock(unsigned int id1, unsigned int id2, LOCKMODE lockmode); +int user_unlock(unsigned int id1, unsigned int id2, LOCKMODE lockmode); int user_write_lock(unsigned int id1, unsigned int id2); int user_write_unlock(unsigned int id1, unsigned int id2); int user_write_lock_oid(Oid oid); @@ -10,3 +10,11 @@ int user_write_unlock_oid(Oid oid); int user_unlock_all(void); #endif + +/* + * Local variables: + * tab-width: 4 + * c-indent-level: 4 + * c-basic-offset: 4 + * End: + */ diff --git a/contrib/userlock/user_locks.sql.in b/contrib/userlock/user_locks.sql.in index da8d105de9c9856624afb7c902a64a468c4478c4..f5ae6a6e95faaf2ca247037ce67bf4b440fea008 100644 --- a/contrib/userlock/user_locks.sql.in +++ b/contrib/userlock/user_locks.sql.in @@ -1,12 +1,19 @@ --- SQL code to define the user locks functions +-- user_locks.sql -- +-- +-- SQL code to define the user locks functions. +-- +-- Copyright (c) 1998, Massimo Dal Zotto <dz@cs.unitn.it> +-- +-- This file is distributed under the GNU General Public License +-- either version 2, or (at your option) any later version. --- select user_lock(group,id,type); +-- select user_lock(group,id,mode); -- create function user_lock(int4,int4,int4) returns int4 as 'MODULE_PATHNAME' language 'c'; --- select user_unlock(group,id,type); +-- select user_unlock(group,id,mode); -- create function user_unlock(int4,int4,int4) returns int4 as 'MODULE_PATHNAME'