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'