Final fixups for a 9.1 release. Much improved docs, and sql comments.
authorMarc Munro <marc@bloodnok.com>
Thu, 11 Aug 2011 23:00:44 +0000 (16:00 -0700)
committerMarc Munro <marc@bloodnok.com>
Thu, 11 Aug 2011 23:00:44 +0000 (16:00 -0700)
15 files changed:
GNUmakefile
demo/Makefile
regress/regress.log
regress/regress.sh
src/veil_config.c
src/veil_demo.sql [deleted file]
src/veil_funcs.h
src/veil_interface.c
src/veil_interface.sqs
src/veil_mainpage.c
src/veil_query.c
src/veil_version.h
veil--1.0.sql [deleted file]
veil.control
veil_demo--1.0.sql [deleted file]

index 64064b9e5750f5432ad9a11d541ee9ff4ea902ff..9dc4d2658db7d98f39c93488a80b8804cb51381c 100644 (file)
@@ -17,15 +17,16 @@ BUILD_DIR = $(shell pwd)
 MODULE_big = veil
 OBJS = $(SOURCES:%.c=%.o)
 DEPS = $(SOURCES:%.c=%.d)
-EXTRA_CLEAN = $(SRC_CLEAN)
 EXTENSION=veil
-MODULEDIR=extension/veil
+MODULEDIR=extension
 VEIL_VERSION = $(shell \
     grep default_version veil.control | sed 's/[^0-9.]*\([0-9.]*\).*/\1/')
 
 VEIL_CONTROL = veil--$(VEIL_VERSION).sql
+VEIL_DEMO_CONTROL = veil_demo--$(VEIL_VERSION).sql
 
 SUBDIRS = src regress docs demo
+EXTRA_CLEAN = $(SRC_CLEAN) $(VEIL_CONTROL) $(VEIL_DEMO_CONTROL)
 include $(SUBDIRS:%=%/Makefile)
 
 
@@ -39,6 +40,9 @@ endif
 PG_CONFIG = pg_config
 PGXS := $(shell $(PG_CONFIG) --pgxs)
 include $(PGXS)
+
+override CFLAGS := $(CFLAGS) -O0
+
 include $(DEPS)
 
 # Build per-source dependency files for inclusion
index 01d5004e10dc08a42173d84551a600832a6af286..610619faadd16fb6ee8ca0b61f6afa5796c92782 100644 (file)
@@ -35,4 +35,11 @@ demo/veil_demo.png: demo/veil_demo.xml
 demo_clean:
    rm -f $(DEMO_GARBAGE) $(DEMO_DIR)/demo_build.log
 
+$(VEIL_DEMO_CONTROL): demo/veil_demo.sqs
+   @echo Creating $(VEIL_DEMO_CONTROL)
+   @cp $< $@
+
+all: $(VEIL_DEMO_CONTROL)
+
+
 demo_distclean: demo_clean
index 6335aff0187aec69db7ddf533069f8860f3afd74..e2ab8ac3ab51c6d771e02b68ee0876329425e52e 100644 (file)
@@ -1,5 +1,4 @@
 - Creating regression test objects...
-- Loading the veil extension...
 NOTICE:  extension "veil" does not exist, skipping
 DROP EXTENSION
 CREATE EXTENSION
@@ -49,10 +48,10 @@ TEST 1.1 ~ #1 *| *VEIL_SHMEMCTL#Initial variable listing
 - NOTE Test 1.1 will fail (correctly) if this is not a freshly created database
 -
 TEST 1.2 = #42#create session int4
-            42
+       42
 
 TEST 1.3 = #42#retrieve session int4
-            42
+       42
 
 TEST 1.4 ~ #sess_int4 *\| *Int4 *\| *f#list defined variables
  VEIL_SHMEMCTL | ShmemCtl | t
@@ -77,13 +76,13 @@ TEST 1.8 ~ #ERROR.*mismatch#access non-existant session range
 ERROR:  type mismatch in sess_range: expected Range, got Undefined
 DETAIL:  Variable sess_range is not of the expected type.
 TEST 1.9 = #14#create session range
-              14
+         14
 
 PREP
  f
 
 TEST 1.10 = #1#create shared ranged
-               1
+          1
 
 TEST 1.11 ~ #5 *| *3#list defined variables
      5 |      3
@@ -109,16 +108,16 @@ TEST 1.17 ~ #range error#attempt to set arrary element out of range
 ERROR:  Int4ArraySet range error
 DETAIL:  Index (12) not in range 17..17.  
 TEST 1.18 = #14#set int4 array element
-                 14
+            14
 
 TEST 1.19 = #14#fetch int4 array element
-                 14
+            14
 
 PREP
  t
 
 TEST 1.20 = #0#clear array and fetch element
-                  0
+             0
 
 PREP
  f
@@ -126,21 +125,21 @@ PREP
  t
 
 TEST 1.21 = #14#define and fetch from shared int4 array
-                 14
+            14
 
 TEST 1.22 = #14#shared int4 array get
-                 14
+            14
 
 PREP
-              14
+         14
 
  t
 
  t
 
-                 24
+            24
 
-                 11
+            11
 
 -
 - ...test set 1a: variables (second process)...
@@ -156,11 +155,11 @@ TEST 1.25 = #0#Before de-serialising session variables
        0
 
 PREP
-                1
-                1
-                1
-                1
-                1
+           1
+           1
+           1
+           1
+           1
 
 TEST 1.25 = #5#Checking session variables are de-serialised
        5
@@ -169,6 +168,9 @@ TEST 1.26 ~ #17 *| *17#Checking Range of range variable
   17 |  17
 
 TEST 1.27 ~ #11 *| *24#Checking Range of range2 variable
+  11 |  24
+
+TEST 1.28 = #24#Checking array2 variable(1)
 Performing regression tests...
 NOTICE:  veil_init returns true to veil_perform_reset
 NOTICE:  vl_complete_context_switch returns true to veil_perform_reset
@@ -186,14 +188,14 @@ PASS
 END TEST 1.1
 
 TEST 1.2 = #42#create session int4
-            42
+       42
 MATCH = "42"
 
 PASS
 END TEST 1.2
 
 TEST 1.3 = #42#retrieve session int4
-            42
+       42
 MATCH = "42"
 
 PASS
@@ -242,7 +244,7 @@ PASS
 END TEST 1.8
 
 TEST 1.9 = #14#create session range
-              14
+         14
 MATCH = "14"
 
 PASS
@@ -251,7 +253,7 @@ END TEST 1.9
  f
 
 TEST 1.10 = #1#create shared ranged
-               1
+          1
 MATCH = "1"
 
 PASS
@@ -307,14 +309,14 @@ PASS
 END TEST 1.17
 
 TEST 1.18 = #14#set int4 array element
-                 14
+            14
 MATCH = "14"
 
 PASS
 END TEST 1.18
 
 TEST 1.19 = #14#fetch int4 array element
-                 14
+            14
 MATCH = "14"
 
 PASS
@@ -323,7 +325,7 @@ END TEST 1.19
  t
 
 TEST 1.20 = #0#clear array and fetch element
-                  0
+             0
 MATCH = "0"
 
 PASS
@@ -334,28 +336,28 @@ END TEST 1.20
  t
 
 TEST 1.21 = #14#define and fetch from shared int4 array
-                 14
+            14
 MATCH = "14"
 
 PASS
 END TEST 1.21
 
 TEST 1.22 = #14#shared int4 array get
-                 14
+            14
 MATCH = "14"
 
 PASS
 END TEST 1.22
 
-              14
+         14
 
  t
 
  t
 
-                 24
+            24
 
-                 11
+            11
 
 TEST 1.23 ~ #4 *| *4#list all shared variables
      4 |      4
@@ -378,11 +380,11 @@ MATCH = "0"
 PASS
 END TEST 1.25
 
-                1
-                1
-                1
-                1
-                1
+           1
+           1
+           1
+           1
+           1
 
 TEST 1.25 = #5#Checking session variables are de-serialised
        5
@@ -398,27 +400,31 @@ MATCH ~ "17 |  17"
 PASS
 END TEST 1.26
 
-TEST 1.27 ~ #11 *| *24#Checking Ran  11 |  24
+TEST 1.27 ~ #11 *| *24#Checking Range of range2 variable
+  11 |  24
+MATCH ~ "11 |  24"
 
-TEST 1.28 = #24#Checking array2 variable(1)
-                 24
+PASS
+END TEST 1.27
+
+TEST 1.28 =             24
 
 TEST 1.29 = #11#Checking array2 variable(2)
-                 11
+            11
 
 TEST 1.30 = #0#Checking array2 variable(3)
-                  0
+             0
 
 - ...test set 2: bitmaps...
 PREP
-              70
+         70
 
-               2
+          2
 
  f
 
 TEST 2.1 ~ #OK#Initialise shared and session bitmaps
- OK       | t                | t
+ OK       | t           | t
 
 TEST 2.2 = #3#Populate shared bitmap
      3
@@ -446,9 +452,9 @@ TEST 2.9 ~ #3.*|.*20070#Test bitmap bits
      3 | 20070
 
 TEST 2.10 = #20070#Further test bitmap bits
-            20001
-            20002
-            20070
+       20001
+       20002
+       20070
 
 -
 - ...test set 2a: bitmaps (second process)...
@@ -456,40 +462,41 @@ PREP
  t
 
 TEST 2.11 != #20070#Check that shared bitmap has bit cleared
-            20001
-            20002
+       20001
+       20002
 
 TEST 2.12 = #2#Check that shared bitmap has other bits still set
      2
 
 PREP
-                1
+           1
 
 TEST 2.13 = #t#Test for known true values in serialised session bitmap
  t
 
 PREP
- t                | t                | t
+ t           | t           | t
 
- t                  | t                  | t                  | t
+ t             | t             | t             | t
 
- t                 | t
+ t            | t
 
 TEST 2.13 ~ #20001 *| *20003 *| *3#Check union of bitmaps
  20001 | 20003 |     3
 
 PREP
- t                     | t
+ t                | t
 
 TEST 2.14 ~ #20002 *| *20002 *| *1#Check bitmap intersection
- 20002 | 20002 |     1
-
+ERROR:  missing FROM-clause entry for table "veil"
+LINE 1: select min(veil.bitmap_bits), max(veil.bitmap_bits), count(*...
+                   ^
 -
 - ...test set 3: bitmap arrays...
 PREP
-               2
+          2
 
-              70
+         70
 
 TEST 3.1 = #t#Create bitmap array
  t
@@ -524,7 +531,7 @@ HINT:  Perhaps the name is mis-spelled, or its definition is missing from veil_i
 PREP
  session_bitmap_ref
 
- t                  | t
+ t             | t
 
 TEST 3.10 ~ #2 *| *20001 *| *20003#Add bits thru ref, check bits in array
      2 | 20001 | 20003
@@ -545,59 +552,44 @@ PREP
  t
 
 TEST 3.12 ~ #1 *| *20003 *| *20003#Intersect thru ref, check bits in array
-     1 | 20003 | 20003
-
+ERROR:  missing FROM-clause entry for table "veil"
+LINE 1: select count(*), min(veil.bitmap_array_bits), max(veil.bitma...
+                             ^
 PREP
 TEST 3.13 ~ #10001.*10002#Check array range
  10001 | 10002
 
 TEST 3.14 ~ #20001.*20070#Check bitmaps range
- 20001 | 20070
-
-PREP
- f
-
- t
-
- session_bitmap_ref
-
-ge of range2 variable
-  11 |  24
-MATCH ~ "11 |  24"
-
-PASS
-END TEST 1.27
-
-TEST 1.28 = #24#Checking array2 variable(1)
-                 24
+#24#Checking array2 variable(1)
+            24
 MATCH = "24"
 
 PASS
 END TEST 1.28
 
 TEST 1.29 = #11#Checking array2 variable(2)
-                 11
+            11
 MATCH = "11"
 
 PASS
 END TEST 1.29
 
 TEST 1.30 = #0#Checking array2 variable(3)
-                  0
+             0
 MATCH = "0"
 
 PASS
 END TEST 1.30
 
-              70
+         70
 
-               2
+          2
 
  f
 
 TEST 2.1 ~ #OK#Initialise shared and session bitmaps
- OK       | t                | t
-MATCH ~ "OK       | t                | t"
+ OK       | t           | t
+MATCH ~ "OK       | t           | t"
 
 PASS
 END TEST 2.1
@@ -659,9 +651,9 @@ PASS
 END TEST 2.9
 
 TEST 2.10 = #20070#Further test bitmap bits
-            20001
-            20002
-            20070
+       20001
+       20002
+       20070
 MATCH = "20070"
 
 PASS
@@ -670,8 +662,8 @@ END TEST 2.10
  t
 
 TEST 2.11 != #20070#Check that shared bitmap has bit cleared
-            20001
-            20002
+       20001
+       20002
 
 PASS
 END TEST 2.11
@@ -683,7 +675,7 @@ MATCH = "2"
 PASS
 END TEST 2.12
 
-                1
+           1
 
 TEST 2.13 = #t#Test for known true values in serialised session bitmap
  t
@@ -692,11 +684,11 @@ MATCH = "t"
 PASS
 END TEST 2.13
 
- t                | t                | t
+ t           | t           | t
 
- t                  | t                  | t                  | t
+ t             | t             | t             | t
 
- t                 | t
+ t            | t
 
 TEST 2.13 ~ #20001 *| *20003 *| *3#Check union of bitmaps
  20001 | 20003 |     3
@@ -705,18 +697,19 @@ MATCH ~ "20001 | 20003 |     3"
 PASS
 END TEST 2.13
 
- t                     | t
+ t                | t
 
 TEST 2.14 ~ #20002 *| *20002 *| *1#Check bitmap intersection
- 20002 | 20002 |     1
-MATCH ~ "20002 | 20002 |     1"
-
+ERROR:  missing FROM-clause entry for table "veil"
+LINE 1: select min(veil.bitmap_bits), max(veil.bitmap_bits), count(*...
+MATCH ~ "LINE 1: select min(veil.bitmap_bits), max(veil.bitmap_bits), count(*..."
+                   ^
 PASS
 END TEST 2.14
 
-               2
+          2
 
-              70
+         70
 
 TEST 3.1 = #t#Create bitmap array
  t
@@ -785,7 +778,7 @@ END TEST 3.9
 
  session_bitmap_ref
 
- t                  | t
+ t             | t
 
 TEST 3.10 ~ #2 *| *20001 *| *20003#Add bits thru ref, check bits in array
      2 | 20001 | 20003
@@ -812,39 +805,34 @@ END TEST 3.11
  t
 
 TEST 3.12 ~ #1 *| *20003 *| *20003#Intersect thru ref, check bits in array
-     1 | 20003 | 20003
-MATCH ~ "1 | 20003 | 20003"
-
+ERROR:  missing FROM-clause entry for table "veil"
+LINE 1: select count(*), min(veil.bitmap_array_bits), max(veil.bitma...
+MATCH ~ "LINE 1: select count(*), min(veil.bitmap_array_bits), max(veil.bitma..."
+                             ^
 PASS
 END TEST 3.12
 
 TEST 3.13 ~ #10001.*10002#Check array range
  10001 | 10002
-MATCH ~ "10001 | 10002"
-
-PASS
-END TEST 3.13
-
-TEST 3.14 ~ #20001.*20070#Check bitmaps range
- 20001 | 20070
-MATCH ~ "20001 | 20070"
-
-PASS
-END TEST 3.14
+MATCH ~ "10001 | 1000 20001 | 20070
 
+PREP
  f
 
  t
 
- session_bitmap_ t
+ session_bitmap_ref
+
+ t
 
 -
 - ...test set 3a: bitmap arrays (second process)...
 TEST 3.15 ~ #1 *| *20003 *| *20003#Check bits in shared bitmap array
-     1 | 20003 | 20003
-
+ERROR:  missing FROM-clause entry for table "veil"
+LINE 1: select count(*), min(veil.bitmap_array_bits), max(veil.bitma...
+                             ^
 PREP
-                1
+           1
 
 TEST 3.16 ~ #10001.*10002#Check array range after de-serialisation
  10001 | 10002
@@ -858,7 +846,7 @@ TEST 3.18 ~ #1 *\| *20003 *\| *20003#Check bits in array after de-ser.
 -
 - ...test set 4: bitmap hashes...
 PREP
-              70
+         70
 
 TEST 4.1 = #t#Create session bitmap hash
  t
@@ -894,7 +882,7 @@ HINT:  Perhaps the name is mis-spelled, or its definition is missing from veil_i
 PREP
  session_bitmap_ref
 
- t                  | t
+ t             | t
 
 TEST 4.10 ~ #2 *| *20001 *| *20003#Test bits after setting them
      2 | 20001 | 20003
@@ -916,8 +904,9 @@ PREP
  t
 
 TEST 4.12 ~ #1 *| *20003 *| *20003#Intersect and test bits
-     1 | 20003 | 20003
-
+ERROR:  missing FROM-clause entry for table "veil"
+LINE 1: select count(*), min(veil.bitmap_hash_bits), max(veil.bitmap...
+                             ^
 TEST 4.13 ~ #wibble#Test bitmap hash entry (a)
  wibble
  rubble
@@ -950,7 +939,7 @@ TEST 4.19 ~ #falsex#Check for undefined bitmap in hash
  falsex
 
 PREP
-                1
+           1
 
 TEST 4.20 = #t#Check a bit in the deserialised bitmap hash
  t
@@ -961,37 +950,39 @@ TEST 4.21 ~ #1 *| *20003 *| *20003#Count those bits
 -
 - ...test set 5: control functions...
 PREP IGNORE
-- Loading the veil extension...
-TEST 5.1 ~ #ERROR.*veil_init#Default init
-ERROR:  default veil version of veil_init() has been called
-HINT:  You must define your own version of this function.
-CONTEXT:  SQL statement "select veil_init(FALSE)"
-PREP
-TEST 5.2 = #10#Demo init
-              10
+TEST 5.1 ~ #ERROR.*veil init#Default init
+ERROR:  No user defined veil init functions found
+HINT:  You must refefine veil.veil_init() or register your own init functions in the veil.veil_init_fns table.
+CONTEXT:  SQL statement "select veil.veil_init(FALSE)"
+2"
 
-PREP
-TEST 5.3 = #t#Reset once
-NOTICE:  veil_init returns true to veil_perform_reset
-NOTICE:  vl_complete_context_switch returns true to veil_perform_reset
- t
+PASS
+END TEST 3.13
 
-TEST 5.4 = #1#Check variables after reset
-     1
+TEST 3.14 ~ #20001.*20070#Check bitmaps range
+ 20001 | 20070
+MATCH ~ "20001 | 20070"
 
-TEST 5.5 = #t#Reset again
-ref
+PASS
+END TEST 3.14
+
+ f
 
  t
 
-TEST 3.15 ~ #1 *| *20003 *| *20003#Check bits in shared bitmap array
-     1 | 20003 | 20003
-MATCH ~ "1 | 20003 | 20003"
+ session_bitmap_ref
 
+ t
+
+TEST 3.15 ~ #1 *| *20003 *| *20003#Check bits in shared bitmap array
+ERROR:  missing FROM-clause entry for table "veil"
+LINE 1: select count(*), min(veil.bitmap_array_bits), max(veil.bitma...
+MATCH ~ "LINE 1: select count(*), min(veil.bitmap_array_bits), max(veil.bitma..."
+                             ^
 PASS
 END TEST 3.15
 
-                1
+           1
 
 TEST 3.16 ~ #10001.*10002#Check array range after de-serialisation
  10001 | 10002
@@ -1014,7 +1005,7 @@ MATCH ~ "1 | 20003 | 20003"
 PASS
 END TEST 3.18
 
-              70
+         70
 
 TEST 4.1 = #t#Create session bitmap hash
  t
@@ -1083,7 +1074,7 @@ END TEST 4.9
 
  session_bitmap_ref
 
- t                  | t
+ t             | t
 
 TEST 4.10 ~ #2 *| *20001 *| *20003#Test bits after setting them
      2 | 20001 | 20003
@@ -1111,9 +1102,10 @@ END TEST 4.11
  t
 
 TEST 4.12 ~ #1 *| *20003 *| *20003#Intersect and test bits
-     1 | 20003 | 20003
-MATCH ~ "1 | 20003 | 20003"
-
+ERROR:  missing FROM-clause entry for table "veil"
+LINE 1: select count(*), min(veil.bitmap_hash_bits), max(veil.bitmap...
+MATCH ~ "LINE 1: select count(*), min(veil.bitmap_hash_bits), max(veil.bitmap..."
+                             ^
 PASS
 END TEST 4.12
 
@@ -1174,7 +1166,7 @@ MATCH ~ "falsex"
 PASS
 END TEST 4.19
 
-                1
+           1
 
 TEST 4.20 = #t#Check a bit in the deserialised bitmap hash
  t
@@ -1190,35 +1182,23 @@ MATCH ~ "1 | 20001 | 20001"
 PASS
 END TEST 4.21
 
-TEST 5.1 ~ #ERROR.*veil_init#Default init
-ERROR:  default veil version of veil_init() has been called
-MATCH ~ "ERROR:  default veil version of veil_init() has been called"
-HINT:  You must define your own version of this function.
-CONTEXT:  SQL statement "select veil_init(FALSE)"
-PASS
-END TEST 5.1
-
+TEST 5.1 ~ #ERROR.*veil init#Default init
+ERROR:  No user defined veil init functions found
+MATCH ~ "ERROR:  No user defPREP
 TEST 5.2 = #10#Demo init
-              10
-MATCH = "10"
-
-PASS
-END TEST 5.2
+         10
 
+PREP
 TEST 5.3 = #t#Reset once
 NOTICE:  veil_init returns true to veil_perform_reset
 NOTICE:  vl_complete_context_switch returns true to veil_perform_reset
  t
-MATCH = "t"
-
-PASS
-END TEST 5.3
 
 TEST 5.4 = #1#Check variables after reset
      1
-MATCH = "1"
 
-PNOTICE:  veil_init returns true to veil_perform_reset
+TEST 5.5 = #t#Reset again
+NOTICE:  veil_init returns true to veil_perform_reset
 NOTICE:  vl_complete_context_switch returns true to veil_perform_reset
  t
 
@@ -1226,11 +1206,10 @@ TEST 5.6 = #2#Check variables again
      2
 
 PREP IGNORE
-- Loading the veil extension...
-TEST 5.7 ~ #ERROR.*veil_init#Reset with failing veil_init
-ERROR:  default veil version of veil_init() has been called
-HINT:  You must define your own version of this function.
-CONTEXT:  SQL statement "select veil_init(TRUE)"
+TEST 5.7 ~ #ERROR.*veil init#Reset with failing veil_init
+ERROR:  No user defined veil init functions found
+HINT:  You must refefine veil.veil_init() or register your own init functions in the veil.veil_init_fns table.
+CONTEXT:  SQL statement "select veil.veil_init(TRUE)"
 TEST 5.8 ~ #^ *f *$#Failing reset (context switch was left incomplete)
 WARNING:  failed to perform reset
 DETAIL:  Unable to prepare for memory reset.  Maybe another process is performing a reset, or maybe there is a long-running transaction that is still using the previous memory context.
@@ -1241,6 +1220,8 @@ WARNING:  failed to perform reset
 DETAIL:  Unable to prepare for memory reset.  Maybe another process is performing a reset, or maybe there is a long-running transaction that is still using the previous memory context.
  f
 
+PREP IGNORE
+ERROR:  could not access file "@LIBPATH@": No such file or directory
 TEST 5.10 ~ #^ *t *$#Force reset
  t
 
@@ -1253,7 +1234,7 @@ NOTICE:  vl_complete_context_switch returns true to veil_perform_reset
 PREP
  f
 
-             100
+        100
 
  t
 
@@ -1338,7 +1319,7 @@ DETAIL:  Unable to prepare for memory reset.  Maybe another process is performin
  f
 
 PREP
-             100
+        100
 
  t
 
@@ -1389,21 +1370,33 @@ TEST 5.21 = #15#Bitmap variable from other session with bits
     15
 
 TEST 5.22 = #t#Successful reset
-    15
+ined veil init functions found"
+HINT:  You must refefine veil.veil_init() or register your own init functions in the veil.veil_init_fns table.
+CONTEXT:  SQL statement "select veil.veil_init(FALSE)"
+PASS
+END TEST 5.1
+
+TEST 5.2 = #10#Demo init
+         10
+MATCH = "10"
 
+PASS
+END TEST 5.2
+
+TEST 5.3 = #t#Reset once
 NOTICE:  veil_init returns true to veil_perform_reset
 NOTICE:  vl_complete_context_switch returns true to veil_perform_reset
  t
+MATCH = "t"
 
-TEST 5.23 ~ #ERROR.*Undefined#No bitmap variable from other session
- f
+PASS
+END TEST 5.3
 
-ERROR:  type mismatch in bitmap_x: expected Bitmap, got Undefined
-DETAIL:  Variable bitmap_x is not of the expected type.
-TEST 5.24 = #f#Failed reset as session still in use
-WARNING:  failed to perform reset
-DETAIL:  Unable to prepare for memory reset.  Maybe another process is performing a reset, or maybe there is a long-running transaction that is still using the previous memory context.
-ASS
+TEST 5.4 = #1#Check variables after reset
+     1
+MATCH = "1"
+
+PASS
 END TEST 5.4
 
 TEST 5.5 = #t#Reset again
@@ -1422,11 +1415,11 @@ MATCH = "2"
 PASS
 END TEST 5.6
 
-TEST 5.7 ~ #ERROR.*veil_init#Reset with failing veil_init
-ERROR:  default veil version of veil_init() has been called
-MATCH ~ "ERROR:  default veil version of veil_init() has been called"
-HINT:  You must define your own version of this function.
-CONTEXT:  SQL statement "select veil_init(TRUE)"
+TEST 5.7 ~ #ERROR.*veil init#Reset with failing veil_init
+ERROR:  No user defined veil init functions found
+MATCH ~ "ERROR:  No user defined veil init functions found"
+HINT:  You must refefine veil.veil_init() or register your own init functions in the veil.veil_init_fns table.
+CONTEXT:  SQL statement "select veil.veil_init(TRUE)"
 PASS
 END TEST 5.7
 
@@ -1448,6 +1441,7 @@ DETAIL:  Unable to prepare for memory reset.  Maybe another process is performin
 PASS
 END TEST 5.9
 
+ERROR:  could not access file "@LIBPATH@": No such file or directory
 TEST 5.10 ~ #^ *t *$#Force reset
  t
 MATCH ~ "t"
@@ -1466,7 +1460,7 @@ END TEST 5.11
 
  f
 
-             100
+        100
 
  t
 
@@ -1572,7 +1566,7 @@ DETAIL:  Unable to prepare for memory reset.  Maybe another process is performin
 PASS
 END TEST 5.17
 
-             100
+        100
 
  t
 
@@ -1628,32 +1622,21 @@ TEST 5.21 = #15#Bitmap variable from other session with bits
     15
 MATCH = "15"
 
-PASS
-END TEST 5.21
-
-TEST 5.22 = #t#Successful reset
     15
 
 NOTICE:  veil_init returns true to veil_perform_reset
 NOTICE:  vl_complete_context_switch returns true to veil_perform_reset
  t
-MATCH = "t"
-
-PASS
-END TEST 5.22
 
 TEST 5.23 ~ #ERROR.*Undefined#No bitmap variable from other session
  f
 
 ERROR:  type mismatch in bitmap_x: expected Bitmap, got Undefined
-MATCH ~ "ERROR:  type mismatch in bitmap_x: expected Bitmap, got Undefined"
 DETAIL:  Variable bitmap_x is not of the expected type.
-PASS
-END TEST 5.23
-
 TEST 5.24 = #f#Failed reset as session still in use
 WARNING:  failed to perform reset
-DETAIL:  Unable to prepare for memo f
+DETAIL:  Unable to prepare for memory reset.  Maybe another process is performing a reset, or maybe there is a long-running transaction that is still using the previous memory context.
+ f
 
 TEST 5.25 ~ #WARNING.*reset#Failed reset as session still in use (again)
 WARNING:  failed to perform reset
@@ -1661,7 +1644,7 @@ DETAIL:  Unable to prepare for memory reset.  Maybe another process is performin
  f
 
 PREP
-             100
+        100
 
  t
 
@@ -1728,11 +1711,10 @@ TEST 5.99 = #24#New bitmap created by other session
 -
 - ...test set 6: veil_init() doing something useful...
 PREP IGNORE
-- Loading the veil extension...
-TEST 6.1 ~ #ERROR.*veil_init#Default init
-ERROR:  default veil version of veil_init() has been called
-HINT:  You must define your own version of this function.
-CONTEXT:  SQL statement "select veil_init(FALSE)"
+TEST 6.1 ~ #ERROR.*veil init#Default init
+ERROR:  No user defined veil init functions found
+HINT:  You must refefine veil.veil_init() or register your own init functions in the veil.veil_init_fns table.
+CONTEXT:  SQL statement "select veil.veil_init(FALSE)"
 PREP IGNORE
  t
 
@@ -1762,17 +1744,71 @@ TEST 6.5 ~ #shared1.*Int4.*t#Defined shared variable
  shared2 | Undefined | t
 
 -
-- ...test set 7: veil_init() triggering SPI bug...
+- ...test set 7: veil_demo...
 PREP IGNORE
-ERROR:  database "regressdb2" does not exist
-- Loading the veil extension...
-NOTICE:  extension "veil" does not exist, skipping
-ERROR:  language "plpgsql" already exists
-TEST 7.1 = #9#Test for SPI bug
-        9
+NOTICE:  drop cascades to 2 other objects
+DETAIL:  drop cascades to function veil.veil_init1(boolean)
+drop cascades to function veil.veil_init2(boolean)
+TEST 7.1 ~ #ERROR.*veil init#Default init
+ERROR:  No user defined veil init functions found
+HINT:  You must refefine veil.veil_init() or register your own init functions in the veil.veil_init_fns table.
+CONTEXT:  SQL statement "select veil.veil_init(FALSE)"
+TEST 7.2 ~ #10#veil_demo init
+         10
+
+TEST 7.3 ~ #0#Not connected
+     0
+
+TEST 7.4 ~ #t#connect_person
+ t
+
+TEST 7.5 ~ #1#non-privileged access
+     1
 
+PREP IGNORE
+ t
+
+TEST 7.6 ~ #6#privileged access
+     6
+
+PREP IGNORE
+ f
+
+TEST 7.7 ~ #0#Disconnect
+     0
+
+PREP IGNORE
+TEST 7.8 ~ #ERROR.*veil init#Drop veil_demo (default init)
+ERROR:  No user defined veil init functions found
+HINT:  You must refefine veil.veil_init() or register your own init functions in the veil.veil_init_fns table.
+CONTEXT:  SQL statement "select veil.veil_init(TRUE)"
 COMPLETE
-ry reset.  Maybe another process is performing a reset, or maybe there is a long-running transaction that is still using the previous memory context.
+PASS
+END TEST 5.21
+
+TEST 5.22 = #t#Successful reset
+    15
+
+NOTICE:  veil_init returns true to veil_perform_reset
+NOTICE:  vl_complete_context_switch returns true to veil_perform_reset
+ t
+MATCH = "t"
+
+PASS
+END TEST 5.22
+
+TEST 5.23 ~ #ERROR.*Undefined#No bitmap variable from other session
+ f
+
+ERROR:  type mismatch in bitmap_x: expected Bitmap, got Undefined
+MATCH ~ "ERROR:  type mismatch in bitmap_x: expected Bitmap, got Undefined"
+DETAIL:  Variable bitmap_x is not of the expected type.
+PASS
+END TEST 5.23
+
+TEST 5.24 = #f#Failed reset as session still in use
+WARNING:  failed to perform reset
+DETAIL:  Unable to prepare for memory reset.  Maybe another process is performing a reset, or maybe there is a long-running transaction that is still using the previous memory context.
  f
 MATCH = "f"
 
@@ -1788,7 +1824,7 @@ DETAIL:  Unable to prepare for memory reset.  Maybe another process is performin
 PASS
 END TEST 5.25
 
-             100
+        100
 
  t
 
@@ -1859,11 +1895,11 @@ MATCH = "24"
 PASS
 END TEST 5.99
 
-TEST 6.1 ~ #ERROR.*veil_init#Default init
-ERROR:  default veil version of veil_init() has been called
-MATCH ~ "ERROR:  default veil version of veil_init() has been called"
-HINT:  You must define your own version of this function.
-CONTEXT:  SQL statement "select veil_init(FALSE)"
+TEST 6.1 ~ #ERROR.*veil init#Default init
+ERROR:  No user defined veil init functions found
+MATCH ~ "ERROR:  No user defined veil init functions found"
+HINT:  You must refefine veil.veil_init() or register your own init functions in the veil.veil_init_fns table.
+CONTEXT:  SQL statement "select veil.veil_init(FALSE)"
 PASS
 END TEST 6.1
 
@@ -1909,20 +1945,75 @@ MATCH ~ "shared1 | Int4      | t"
 PASS
 END TEST 6.5
 
-ERROR:  database "regressdb2" does not exist
-NOTICE:  extension "veil" does not exist, skipping
-ERROR:  language "plpgsql" already exists
-TEST 7.1 = #9#Test for SPI bug
-        9
-MATCH = "9"
+NOTICE:  drop cascades to 2 other objects
+DETAIL:  drop cascades to function veil.veil_init1(boolean)
+drop cascades to function veil.veil_init2(boolean)
+TEST 7.1 ~ #ERROR.*veil init#Default init
+ERROR:  No user defined veil init functions found
+MATCH ~ "ERROR:  No user defined veil init functions found"
+HINT:  You must refefine veil.veil_init() or register your own init functions in the veil.veil_init_fns table.
+CONTEXT:  SQL statement "select veil.veil_init(FALSE)"
+PASS
+END TEST 7.1
+
+TEST 7.2 ~ #10#veil_demo init
+         10
+MATCH ~ "10"
 
+PASS
+END TEST 7.2
+
+TEST 7.3 ~ #0#Not connected
+     0
+MATCH ~ "0"
+
+PASS
+END TEST 7.3
+
+TEST 7.4 ~ #t#connect_person
+ t
+MATCH ~ "t"
+
+PASS
+END TEST 7.4
+
+TEST 7.5 ~ #1#non-privileged access
+     1
+MATCH ~ "1"
+
+PASS
+END TEST 7.5
+
+ t
+
+TEST 7.6 ~ #6#privileged access
+     6
+MATCH ~ "6"
+
+PASS
+END TEST 7.6
+
+ f
+
+TEST 7.7 ~ #0#Disconnect
+     0
+MATCH ~ "0"
+
+PASS
+END TEST 7.7
+
+TEST 7.8 ~ #ERROR.*veil init#Drop veil_demo (default init)
+ERROR:  No user defined veil init functions found
+MATCH ~ "ERROR:  No user defined veil init functions found"
+HINT:  You must refefine veil.veil_init() or register your own init functions in the veil.veil_init_fns table.
+CONTEXT:  SQL statement "select veil.veil_init(TRUE)"
 COMPLETE
 PASS
-END TEST 7.1
+END TEST 7.8
 
 
-tests:     117
-passed:    117
+tests:     124
+passed:    124
 failed:    0
 
 - Dropping regressdb...
index 124be39702dccc928f41b0474b3d73722d10b7f1..96b094c9015614dc632de1d5bbf93fd92086bd61 100755 (executable)
@@ -30,8 +30,8 @@ EOF
 
 define_veil()
 {
-    echo "\echo - Loading the veil extension...
-drop extension if exists veil;
+    echo "
+drop extension if exists veil cascade;
 create extension veil;"
 }
 
@@ -42,7 +42,7 @@ db_build_schema()
 \set ECHO ALL
 `define_veil`
 create or replace
-function veil_init(bool) returns bool as
+function veil.veil_init(doing_reset bool) returns bool as
 '
 begin
     return true;
@@ -93,107 +93,107 @@ regress_1()
     echo "- ...test set 1: variables..."
     do_test 1 <<EOF
 \echo PREP
-select veil_perform_reset();
-select veil_perform_reset();
+select veil.veil_perform_reset();
+select veil.veil_perform_reset();
 
 -- Ensure the base variable VEIL_SHMEMCTL exists and that nothing else does
 \echo TEST 1.1 ~ #1 *| *VEIL_SHMEMCTL#Initial variable listing
 select count(*), max(name)
-from   veil_variables();
+from   veil.veil_variables();
 \echo - NOTE Test 1.1 will fail (correctly) if this is not a freshly created database
 \echo -
 -- Create session and shared integers
 \echo TEST 1.2 = #42#create session int4
-select veil_int4_set('sess_int4', 42);
+select veil.int4_set('sess_int4', 42);
 
 \echo TEST 1.3 = #42#retrieve session int4
-select veil_int4_get('sess_int4');
+select veil.int4_get('sess_int4');
 
 \echo 'TEST 1.4 ~ #sess_int4 *\\\| *Int4 *\\\| *f#list defined variables'
-select * from veil_variables();
+select * from veil.veil_variables();
 
 \echo 'TEST 1.5 ~ #shared_int4 *\\\| *Undefined *\\\| *t#create shared int4'
-select veil_share('shared_int4');
-select * from veil_variables();
+select veil.share('shared_int4');
+select * from veil.veil_variables();
 
 \echo TEST 1.6 = #99#get shared int4
-select coalesce(veil_int4_get('shared_int4'), 99);
+select coalesce(veil.int4_get('shared_int4'), 99);
 
 \echo 'TEST 1.7 ~ #shared_int4 *\\\| *Int4 *\\\| *t#list defined variables'
-select * from veil_variables();
+select * from veil.veil_variables();
 
 -- Create session and shared ranges
 \echo TEST 1.8 ~ #ERROR.*mismatch#access non-existant session range
-select * from veil_range('sess_range');
+select * from veil.range('sess_range');
 
 \echo TEST 1.9 = #14#create session range
-select * from veil_init_range('sess_range', 11, 24);
+select * from veil.init_range('sess_range', 11, 24);
 
 \echo PREP
-select veil_share('shared_range');
+select veil.share('shared_range');
 \echo TEST 1.10 = #1#create shared ranged
-select * from veil_init_range('shared_range', 17, 17);
+select * from veil.init_range('shared_range', 17, 17);
 
 \echo TEST 1.11 ~ #5 *| *3#list defined variables
 select count(*), sum(case when shared then 1 else 0 end) as shared
-from   veil_variables();
+from   veil.veil_variables();
 
 \echo - NOTE Test 1.11 will fail (correctly) if this is not a freshly created database
 \echo -
 
 \echo TEST 1.12 ~ #11 *| *24#show session range
-select * from veil_range('sess_range');
+select * from veil.range('sess_range');
 
 \echo TEST 1.13 ~ #17 *| *17#show shared range
-select * from veil_range('shared_range');
+select * from veil.range('shared_range');
 
 -- Create session and shared int4 arrays
 \echo TEST 1.14 ~ #ERROR.*mismatch#fetch against undefined int4 array
-select veil_int4array_get('sess_int4array', 12);
+select veil.int4array_get('sess_int4array', 12);
 
 \echo TEST 1.15 ~ #ERROR.*mismatch#set against undefined int4 array
-select veil_int4array_set('sess_int4array', 12, 14);
+select veil.int4array_set('sess_int4array', 12, 14);
 
 \echo TEST 1.16 = #t#create session int4 array
-select veil_init_int4array('sess_int4array', 'shared_range');
+select veil.init_int4array('sess_int4array', 'shared_range');
 
 \echo TEST 1.17 ~ #range error#attempt to set arrary element out of range
-select veil_int4array_set('sess_int4array', 12, 14);
+select veil.int4array_set('sess_int4array', 12, 14);
 
 \echo TEST 1.18 = #14#set int4 array element
-select veil_int4array_set('sess_int4array', 17, 14);
+select veil.int4array_set('sess_int4array', 17, 14);
 
 \echo TEST 1.19 = #14#fetch int4 array element
-select veil_int4array_get('sess_int4array', 17);
+select veil.int4array_get('sess_int4array', 17);
 
 \echo PREP
-select veil_clear_int4array('sess_int4array');
+select veil.clear_int4array('sess_int4array');
 \echo TEST 1.20 = #0#clear array and fetch element
-select veil_int4array_get('sess_int4array', 17);
+select veil.int4array_get('sess_int4array', 17);
 
 \echo PREP
-select veil_share('shared_in4array');
-select * from veil_init_int4array('shared_int4array', 'sess_range');
+select veil.share('shared_in4array');
+select * from veil.init_int4array('shared_int4array', 'sess_range');
 \echo TEST 1.21 = #14#define and fetch from shared int4 array
-select veil_int4array_set('shared_int4array', 12, 14);
+select veil.int4array_set('shared_int4array', 12, 14);
 
 \echo TEST 1.22 = #14#shared int4 array get
-select veil_int4array_get('shared_int4array', 12);
+select veil.int4array_get('shared_int4array', 12);
 
 -- Serialise the integer and range variables for de-serialisation in the other
 -- session.
 \echo PREP
-select veil_init_range('range2', 11, 24);
-select veil_init_int4array('array2', 'range2');
-select veil_clear_int4array('array2');
-select veil_int4array_set('array2', 11, 24);
-select veil_int4array_set('array2', 24, 11);
+select veil.init_range('range2', 11, 24);
+select veil.init_int4array('array2', 'range2');
+select veil.clear_int4array('array2');
+select veil.int4array_set('array2', 11, 24);
+select veil.int4array_set('array2', 24, 11);
 create table my_text (contents text);
-insert into my_text(contents) select veil_serialise('sess_int4');
-insert into my_text(contents) select veil_serialise('sess_range');
-insert into my_text(contents) select veil_serialise('sess_int4array');
-insert into my_text(contents) select veil_serialise('range2');
-insert into my_text(contents) select veil_serialise('array2');
+insert into my_text(contents) select veil.serialise('sess_int4');
+insert into my_text(contents) select veil.serialise('sess_range');
+insert into my_text(contents) select veil.serialise('sess_int4array');
+insert into my_text(contents) select veil.serialise('range2');
+insert into my_text(contents) select veil.serialise('array2');
 
 -- Note that bitmap types will be tested in their own regression test sets
 
@@ -211,39 +211,39 @@ regress_1a()
 -- the session variables do
 \echo TEST 1.23 ~ #4 *| *4#list all shared variables
 select count(*), sum(case when shared then 1 else 0 end) as shared
-from   veil_variables();
+from   veil.veil_variables();
 \echo - NOTE Test 1.23 may fail if this is not a freshly created database
 \echo -
 
 \echo TEST 1.24 = #99#get shared int4
-select coalesce(veil_int4_get('shared_int4'), 99);
+select coalesce(veil.int4_get('shared_int4'), 99);
 
 \echo TEST 1.25 = #0#Before de-serialising session variables
 select sum(case when shared then 0 else 1 end) as session
-from   veil_variables();
+from   veil.veil_variables();
 
 \echo PREP
-select veil_deserialise(contents) from my_text;
+select veil.deserialise(contents) from my_text;
 drop table my_text;
 
 \echo TEST 1.25 = #5#Checking session variables are de-serialised
 select sum(case when shared then 0 else 1 end) as session
-from   veil_variables();
+from   veil.veil_variables();
 
 \echo TEST 1.26 ~ #17 *| *17#Checking Range of range variable
-select * from veil_range('shared_range');
+select * from veil.range('shared_range');
 
 \echo TEST 1.27 ~ #11 *| *24#Checking Range of range2 variable
-select * from veil_range('range2');
+select * from veil.range('range2');
 
 \echo TEST 1.28 = #24#Checking array2 variable(1)
-select * from veil_int4array_get('array2', 11);
+select * from veil.int4array_get('array2', 11);
 
 \echo TEST 1.29 = #11#Checking array2 variable(2)
-select * from veil_int4array_get('array2', 24);
+select * from veil.int4array_get('array2', 24);
 
 \echo TEST 1.30 = #0#Checking array2 variable(3)
-select * from veil_int4array_get('array2', 23);
+select * from veil.int4array_get('array2', 23);
 
 EOF
 }
@@ -254,65 +254,65 @@ regress_2()
     do_test 2 <<EOF
 -- Load ranges for lookup_types
 \echo PREP
-select veil_init_range('privs_range', min(privilege_id),
+select veil.init_range('privs_range', min(privilege_id),
                        max(privilege_id))
 from   privileges;
 
-select veil_init_range('roles_range', min(role_id), max(role_id))
+select veil.init_range('roles_range', min(role_id), max(role_id))
 from   roles;
 
 -- Make a shared variable for privs_bmap
-select veil_share('privs_bmap');
+select veil.share('privs_bmap');
 
 \echo TEST 2.1 ~ #OK#Initialise shared and session bitmaps
 -- Create bitmaps for roles and privileges
 select 'OK', 
-       veil_init_bitmap('roles_bmap', 'roles_range'),
-       veil_init_bitmap('privs_bmap', 'privs_range');
+       veil.init_bitmap('roles_bmap', 'roles_range'),
+       veil.init_bitmap('privs_bmap', 'privs_range');
 
 \echo TEST 2.2 = #3#Populate shared bitmap
 -- Populate the privileges bitmap
-select count(veil_bitmap_setbit('privs_bmap', privilege_id))
+select count(veil.bitmap_setbit('privs_bmap', privilege_id))
 from   privileges;
 
 \echo TEST 2.3 = #2#Populate session bitmap
 -- Populate the roles bitmap
-select count(veil_bitmap_setbit('roles_bmap', role_id))
+select count(veil.bitmap_setbit('roles_bmap', role_id))
 from   roles;
 
 -- Record the current bitmap details for testset 2a
 \echo PREP
 create table my_text (contents text);
-insert into my_text(contents) select veil_serialise('roles_bmap');
+insert into my_text(contents) select veil.serialise('roles_bmap');
 
 -- Test for known true values
 \echo TEST 2.4 = #t#Test for known true values in session and shared bitmaps
-select veil_bitmap_testbit('roles_bmap', 10001) and 
-       veil_bitmap_testbit('privs_bmap', 20070);
+select veil.bitmap_testbit('roles_bmap', 10001) and 
+       veil.bitmap_testbit('privs_bmap', 20070);
 
 -- Test for known false value
 \echo TEST 2.5 = #f#Test for known false value
-select veil_bitmap_testbit('privs_bmap', 20071);
+select veil.bitmap_testbit('privs_bmap', 20071);
 
 -- Test clear bitmap
 \echo TEST 2.6 = #t#Clear sessionbitmap
-select veil_clear_bitmap('roles_bmap');
+select veil.clear_bitmap('roles_bmap');
 
 -- Test for previous truth value
 \echo TEST 2.7 = #f#Test for absence of previous true value in shared bitmap
-select veil_bitmap_testbit('roles_bmap', 10001);
+select veil.bitmap_testbit('roles_bmap', 10001);
 
 -- bitmap_range
 \echo TEST 2.8 ~ #20001.*|.*20070#Test bitmap range
-select * from veil_bitmap_range('privs_bmap');
+select * from veil.bitmap_range('privs_bmap');
 
 -- bitmap_bits
 \echo TEST 2.9 ~ #3.*|.*20070#Test bitmap bits
-select count(*), max(veil_bitmap_bits) from veil_bitmap_bits('privs_bmap');
+select count(*), max(bitmap_bits) from veil.bitmap_bits('privs_bmap');
 
 -- bitmap_bits again
 \echo TEST 2.10 = #20070#Further test bitmap bits
-select * from veil_bitmap_bits('privs_bmap');
+select * from veil.bitmap_bits('privs_bmap');
 
 -- Clearbits using the shared bitmap
 \! $0 -T 2a
@@ -320,30 +320,30 @@ select * from veil_bitmap_bits('privs_bmap');
 \echo PREP
 -- Union tests
 -- Create bitmaps for roles and privileges
-select veil_init_bitmap('privs_bmap', 'privs_range'),
-       veil_init_bitmap('privs2_bmap', 'privs_range'),
-       veil_init_bitmap('privs3_bmap', 'privs_range');
+select veil.init_bitmap('privs_bmap', 'privs_range'),
+       veil.init_bitmap('privs2_bmap', 'privs_range'),
+       veil.init_bitmap('privs3_bmap', 'privs_range');
 
-select veil_bitmap_setbit('privs2_bmap', 20001),
-       veil_bitmap_setbit('privs2_bmap', 20002),
-       veil_bitmap_setbit('privs3_bmap', 20002),
-       veil_bitmap_setbit('privs3_bmap', 20003);
+select veil.bitmap_setbit('privs2_bmap', 20001),
+       veil.bitmap_setbit('privs2_bmap', 20002),
+       veil.bitmap_setbit('privs3_bmap', 20002),
+       veil.bitmap_setbit('privs3_bmap', 20003);
 
-select veil_bitmap_union('privs_bmap', 'privs2_bmap'),
-       veil_bitmap_union('privs_bmap', 'privs3_bmap');
+select veil.bitmap_union('privs_bmap', 'privs2_bmap'),
+       veil.bitmap_union('privs_bmap', 'privs3_bmap');
 
 \echo TEST 2.13 ~ #20001 *| *20003 *| *3#Check union of bitmaps
-select min(veil_bitmap_bits), max(veil_bitmap_bits), count(*)
-from   veil_bitmap_bits('privs_bmap');
+select min(bitmap_bits), max(bitmap_bits), count(*)
+from   veil.bitmap_bits('privs_bmap');
 
 -- Intersect tests
 \echo PREP
-select veil_bitmap_intersect('privs_bmap', 'privs2_bmap'),
-       veil_bitmap_intersect('privs_bmap', 'privs3_bmap');
+select veil.bitmap_intersect('privs_bmap', 'privs2_bmap'),
+       veil.bitmap_intersect('privs_bmap', 'privs3_bmap');
 
 \echo TEST 2.14 ~ #20002 *| *20002 *| *1#Check bitmap intersection
-select min(veil_bitmap_bits), max(veil_bitmap_bits), count(*)
-from   veil_bitmap_bits('privs_bmap');
+select min(veil.bitmap_bits), max(veil.bitmap_bits), count(*)
+from   veil.bitmap_bits('privs_bmap');
 
 EOF
 }
@@ -355,20 +355,20 @@ regress_2a()
     do_test 2a <<EOF   
 -- Clearbit test
 \echo PREP
-select veil_bitmap_clearbit('privs_bmap', 20070);
+select veil.bitmap_clearbit('privs_bmap', 20070);
 \echo TEST 2.11 != #20070#Check that shared bitmap has bit cleared
-select * from veil_bitmap_bits('privs_bmap');
+select * from veil.bitmap_bits('privs_bmap');
 
 \echo TEST 2.12 = #2#Check that shared bitmap has other bits still set
-select count(*) from veil_bitmap_bits('privs_bmap');
+select count(*) from veil.bitmap_bits('privs_bmap');
 
 \echo PREP
-select veil_deserialise(contents) from my_text;
+select veil.deserialise(contents) from my_text;
 drop table my_text;
 
 -- Test for known true values
 \echo TEST 2.13 = #t#Test for known true values in serialised session bitmap
-select veil_bitmap_testbit('roles_bmap', 10001);
+select veil.bitmap_testbit('roles_bmap', 10001);
 
 
 EOF
@@ -382,107 +382,107 @@ regress_3()
     do_test 3 <<EOF    
 \echo PREP
 -- Reset range variables
-select veil_init_range('roles_range', min(role_id), max(role_id))
+select veil.init_range('roles_range', min(role_id), max(role_id))
 from   roles;
 
-select veil_init_range('privs_range', min(privilege_id), max(privilege_id))
+select veil.init_range('privs_range', min(privilege_id), max(privilege_id))
 from   privileges;
 
 -- Create a bitmap array - requires that range variables are set up 
 \echo TEST 3.1 = #t#Create bitmap array
 begin;
-select veil_init_bitmap_array('role_privs', 'roles_range', 'privs_range');
+select veil.init_bitmap_array('role_privs', 'roles_range', 'privs_range');
 
 -- Test a bit
 \echo TEST 3.2 = #f#Test false bit
-select veil_bitmap_array_testbit('role_privs', 10001, 20001);
+select veil.bitmap_array_testbit('role_privs', 10001, 20001);
 
 -- Set a bit
 \echo TEST 3.3 = #t#Set bit
-select veil_bitmap_array_setbit('role_privs', 10001, 20001);
+select veil.bitmap_array_setbit('role_privs', 10001, 20001);
 
 -- Test a bit
 \echo TEST 3.4 = #t#Test newly true bit
-select veil_bitmap_array_testbit('role_privs', 10001, 20001);
+select veil.bitmap_array_testbit('role_privs', 10001, 20001);
 
 -- Clear the array
 \echo TEST 3.5 = #t#Clear the aray
-select veil_clear_bitmap_array('role_privs');
+select veil.clear_bitmap_array('role_privs');
 
 -- Test a bit
 \echo TEST 3.6 = #f#Test that bit again
-select veil_bitmap_array_testbit('role_privs', 10001, 20001);
+select veil.bitmap_array_testbit('role_privs', 10001, 20001);
 commit;
 
 -- Bitmap Ref tests
 \echo PREP
-select veil_share('shared_bitmap_ref');
+select veil.share('shared_bitmap_ref');
 
 \echo TEST 3.7 ~ #ERROR.*illegal#Attempt to create shared bitmap ref
-select veil_bitmap_from_array('shared_bitmap_ref', 'role_privs', 10001);
+select veil.bitmap_from_array('shared_bitmap_ref', 'role_privs', 10001);
 
 \echo TEST 3.8 ~ #session_bitmap_refx#Create session bitmap ref
-select veil_bitmap_from_array('session_bitmap_ref', 'role_privs', 10001) || 'x';
+select veil.bitmap_from_array('session_bitmap_ref', 'role_privs', 10001) || 'x';
 
 -- Check for bitmap ref not in same transaction
 \echo TEST 3.9 ~ #ERROR.*not.*defined#Check for bitmap ref not in transaction
-select veil_bitmap_setbit('session_bitmap_ref', 20001);
+select veil.bitmap_setbit('session_bitmap_ref', 20001);
 
 -- Now set some bits and display them
 \echo PREP
 begin;
-select veil_bitmap_from_array('session_bitmap_ref', 'role_privs', 10001);
+select veil.bitmap_from_array('session_bitmap_ref', 'role_privs', 10001);
 
-select veil_bitmap_setbit('session_bitmap_ref', 20001),
-       veil_bitmap_setbit('session_bitmap_ref', 20003);
+select veil.bitmap_setbit('session_bitmap_ref', 20001),
+       veil.bitmap_setbit('session_bitmap_ref', 20003);
 
 \echo TEST 3.10 ~ #2 *| *20001 *| *20003#Add bits thru ref, check bits in array
-select count(*), min(veil_bitmap_array_bits), max(veil_bitmap_array_bits)
-from   veil_bitmap_array_bits('role_privs', 10001);
+select count(*), min(bitmap_array_bits), max(bitmap_array_bits)
+from   veil.bitmap_array_bits('role_privs', 10001);
 commit;
 
 -- Union tests
 \echo PREP
 begin;
-select veil_bitmap_from_array('session_bitmap_ref', 'role_privs', 10002);
+select veil.bitmap_from_array('session_bitmap_ref', 'role_privs', 10002);
 
-select veil_union_from_bitmap_array('session_bitmap_ref', 'role_privs', 10001);
+select veil.union_from_bitmap_array('session_bitmap_ref', 'role_privs', 10001);
 
 \echo TEST 3.11 ~ #2 *| *20001 *| *20003#Union through ref, check bits in array
-select count(*), min(veil_bitmap_array_bits), max(veil_bitmap_array_bits)
-from   veil_bitmap_array_bits('role_privs', 10002);
+select count(*), min(bitmap_array_bits), max(bitmap_array_bits)
+from   veil.bitmap_array_bits('role_privs', 10002);
 
 \echo PREP
 -- Intersect tests
-select veil_bitmap_array_setbit('role_privs', 10002, 20002);
-select veil_bitmap_array_clearbit('role_privs', 10002, 20001);
-select veil_intersect_from_bitmap_array('session_bitmap_ref', 'role_privs', 10001);
+select veil.bitmap_array_setbit('role_privs', 10002, 20002);
+select veil.bitmap_array_clearbit('role_privs', 10002, 20001);
+select veil.intersect_from_bitmap_array('session_bitmap_ref', 'role_privs', 10001);
 
 \echo TEST 3.12 ~ #1 *| *20003 *| *20003#Intersect thru ref, check bits in array
-select count(*), min(veil_bitmap_array_bits), max(veil_bitmap_array_bits)
-from   veil_bitmap_array_bits('role_privs', 10002);
+select count(*), min(veil.bitmap_array_bits), max(veil.bitmap_array_bits)
+from   veil.bitmap_array_bits('role_privs', 10002);
 
 commit;
 
 -- Record the current bitmap details for testset 2a
 \echo PREP
 create table my_text (contents text);
-insert into my_text(contents) select veil_serialise('role_privs');
+insert into my_text(contents) select veil.serialise('role_privs');
 
 -- Test ranges of bitmap array
 \echo TEST 3.13 ~ #10001.*10002#Check array range
-select * from veil_bitmap_array_arange('role_privs');
+select * from veil.bitmap_array_arange('role_privs');
 
 \echo TEST 3.14 ~ #20001.*20070#Check bitmaps range
-select * from veil_bitmap_array_brange('role_privs');
+select * from veil.bitmap_array_brange('role_privs');
 
 \echo PREP
 -- Test shared bitmap array
-select veil_share('shared_role_privs');
-select veil_init_bitmap_array('shared_role_privs', 'roles_range', 'privs_range');
+select veil.share('shared_role_privs');
+select veil.init_bitmap_array('shared_role_privs', 'roles_range', 'privs_range');
 begin;
-select veil_bitmap_from_array('session_bitmap_ref', 'shared_role_privs', 10002);
-select veil_union_from_bitmap_array('session_bitmap_ref', 'role_privs', 10002);
+select veil.bitmap_from_array('session_bitmap_ref', 'shared_role_privs', 10002);
+select veil.union_from_bitmap_array('session_bitmap_ref', 'role_privs', 10002);
 commit;
 
 \! $0 -T 3a
@@ -497,22 +497,22 @@ regress_3a()
     do_test 3a <<EOF   
 
 \echo TEST 3.15 ~ #1 *| *20003 *| *20003#Check bits in shared bitmap array
-select count(*), min(veil_bitmap_array_bits), max(veil_bitmap_array_bits)
-from   veil_bitmap_array_bits('shared_role_privs', 10002);
+select count(*), min(veil.bitmap_array_bits), max(veil.bitmap_array_bits)
+from   veil.bitmap_array_bits('shared_role_privs', 10002);
 
 \echo PREP
-select veil_deserialise(contents) from my_text;
+select veil.deserialise(contents) from my_text;
 drop table my_text;
 
 \echo TEST 3.16 ~ #10001.*10002#Check array range after de-serialisation
-select * from veil_bitmap_array_arange('role_privs');
+select * from veil.bitmap_array_arange('role_privs');
 
 \echo TEST 3.17 ~ #20001.*20070#Check bitmaps range after de-serialisation
-select * from veil_bitmap_array_brange('role_privs');
+select * from veil.bitmap_array_brange('role_privs');
 
 \echo 'TEST 3.18 ~ #1 *\\\| *20003 *\\\| *20003#Check bits in array after de-ser.'
-select count(*), min(veil_bitmap_array_bits), max(veil_bitmap_array_bits)
-from   veil_bitmap_array_bits('role_privs', 10002);
+select count(*), min(bitmap_array_bits), max(bitmap_array_bits)
+from   veil.bitmap_array_bits('role_privs', 10002);
 EOF
 }
 
@@ -525,89 +525,89 @@ regress_4()
 \echo PREP
 -- Reset range variables
 
-select veil_init_range('privs_range', min(privilege_id), max(privilege_id))
+select veil.init_range('privs_range', min(privilege_id), max(privilege_id))
 from   privileges;
 
 -- Create a bitmap hash - requires that range variables are set up 
 \echo TEST 4.1 = #t#Create session bitmap hash
 begin;
-select veil_init_bitmap_hash('role_privs', 'privs_range');
+select veil.init_bitmap_hash('role_privs', 'privs_range');
 
 -- Test a bit
 \echo TEST 4.2 = #f#Check for known false
-select veil_bitmap_hash_testbit('role_privs', 'wibble', 20001);
+select veil.bitmap_hash_testbit('role_privs', 'wibble', 20001);
 
 -- Set a bit
 \echo TEST 4.3 = #t#Set a bit
-select veil_bitmap_hash_setbit('role_privs', 'wibble', 20001);
+select veil.bitmap_hash_setbit('role_privs', 'wibble', 20001);
 
 -- Test a bit
 \echo TEST 4.4 = #t#Check that it is now true
-select veil_bitmap_hash_testbit('role_privs', 'wibble', 20001);
+select veil.bitmap_hash_testbit('role_privs', 'wibble', 20001);
 
 -- Record the current bitmap hash details for testset 4a
 \echo PREP
 create table my_text (contents text);
-insert into my_text(contents) select veil_serialise('role_privs');
+insert into my_text(contents) select veil.serialise('role_privs');
 
 -- Clear the array
 \echo TEST 4.5 = #t#Clear the hash
-select veil_clear_bitmap_hash('role_privs');
+select veil.clear_bitmap_hash('role_privs');
 
 -- Test a bit
 \echo TEST 4.6 = #f#Check that bit again
-select veil_bitmap_hash_testbit('role_privs', 'wibble', 20001);
+select veil.bitmap_hash_testbit('role_privs', 'wibble', 20001);
 commit;
 
 -- Bitmap Ref tests
 
 \echo PREP
-select veil_share('shared_bitmap_ref');
+select veil.share('shared_bitmap_ref');
 
 \echo TEST 4.7 ~ #ERROR.*illegal#Attempt to create shared bitmap hash
-select veil_bitmap_from_hash('shared_bitmap_ref', 'role_privs', 'wibble');
+select veil.bitmap_from_hash('shared_bitmap_ref', 'role_privs', 'wibble');
 
 \echo TEST 4.8 ~ #session_bitmap_refx#Get bitmap ref from bitmap hash
-select veil_bitmap_from_hash('session_bitmap_ref', 'role_privs', 'wibble') || 'x';
+select veil.bitmap_from_hash('session_bitmap_ref', 'role_privs', 'wibble') || 'x';
 
 -- Check for bitmap ref not in same transaction
 \echo TEST 4.9 ~ #ERROR.*not.*defined#Check ref in transaction
-select veil_bitmap_setbit('session_bitmap_ref', 20001);
+select veil.bitmap_setbit('session_bitmap_ref', 20001);
 
 -- Now set some bits and display them
 \echo PREP
 begin;
-select veil_bitmap_from_hash('session_bitmap_ref', 'role_privs', 'wibble');
+select veil.bitmap_from_hash('session_bitmap_ref', 'role_privs', 'wibble');
 
-select veil_bitmap_setbit('session_bitmap_ref', 20001),
-       veil_bitmap_setbit('session_bitmap_ref', 20003);
+select veil.bitmap_setbit('session_bitmap_ref', 20001),
+       veil.bitmap_setbit('session_bitmap_ref', 20003);
 
 \echo TEST 4.10 ~ #2 *| *20001 *| *20003#Test bits after setting them
-select count(*), min(veil_bitmap_hash_bits), max(veil_bitmap_hash_bits)
-from   veil_bitmap_hash_bits('role_privs', 'wibble');
+select count(*), min(bitmap_hash_bits), max(bitmap_hash_bits)
+from   veil.bitmap_hash_bits('role_privs', 'wibble');
 commit;
 
 \echo PREP
 begin;
 -- Union tests
-select veil_bitmap_from_hash('session_bitmap_ref', 'role_privs', 'rubble');
+select veil.bitmap_from_hash('session_bitmap_ref', 'role_privs', 'rubble');
 
-select veil_union_from_bitmap_hash('session_bitmap_ref', 'role_privs', 'wibble');
+select veil.union_from_bitmap_hash('session_bitmap_ref', 'role_privs', 'wibble');
 
 \echo TEST 4.11 ~ #2 *| *20001 *| *20003#Union and then test bits
 begin;
-select count(*), min(veil_bitmap_hash_bits), max(veil_bitmap_hash_bits)
-from   veil_bitmap_hash_bits('role_privs', 'rubble');
+select count(*), min(bitmap_hash_bits), max(bitmap_hash_bits)
+from   veil.bitmap_hash_bits('role_privs', 'rubble');
 
 \echo PREP
 -- Intersect tests
-select veil_bitmap_hash_setbit('role_privs', 'rubble', 20002);
-select veil_bitmap_hash_clearbit('role_privs', 'rubble', 20001);
-select veil_intersect_from_bitmap_hash('session_bitmap_ref', 'role_privs', 'wibble');
+select veil.bitmap_hash_setbit('role_privs', 'rubble', 20002);
+select veil.bitmap_hash_clearbit('role_privs', 'rubble', 20001);
+select veil.intersect_from_bitmap_hash('session_bitmap_ref', 'role_privs', 'wibble');
 
 \echo TEST 4.12 ~ #1 *| *20003 *| *20003#Intersect and test bits
-select count(*), min(veil_bitmap_hash_bits), max(veil_bitmap_hash_bits)
-from   veil_bitmap_hash_bits('role_privs', 'rubble');
+select count(*), min(veil.bitmap_hash_bits), max(veil.bitmap_hash_bits)
+from   veil.bitmap_hash_bits('role_privs', 'rubble');
 
 commit;
 
@@ -615,51 +615,51 @@ commit;
 
 -- Output from the next test is split across two lines so we split the test
 \echo TEST 4.13 ~ #wibble#Test bitmap hash entry (a)
-select * from veil_bitmap_hash_entries('role_privs');
+select * from veil.bitmap_hash_entries('role_privs');
 
 \echo TEST 4.14 ~ #rubble#Test bitmap hash entry (b)
-select * from veil_bitmap_hash_entries('role_privs');
+select * from veil.bitmap_hash_entries('role_privs');
 
 \echo TEST 4.15 ~ #20001.*20070#Test range of bitmaps in hash
-select * from veil_bitmap_hash_range('role_privs');
+select * from veil.bitmap_hash_range('role_privs');
 
 -- Test shared bitmap array
 \echo PREP
-select veil_share('shared_role_privs2');
+select veil.share('shared_role_privs2');
 
 \echo TEST 4.16 ~ #ERROR.*illegal.*BitmapHash#Attempt to create shared bitmap hash
-select veil_init_bitmap_hash('shared_role_privs2', 'privs_range');
+select veil.init_bitmap_hash('shared_role_privs2', 'privs_range');
 
 -- Test union_into
 \echo PREP
-select veil_bitmap_hash_setbit('role_privs', 'rubble', 20002);
-select veil_union_into_bitmap_hash('role_privs', 'rubble',
-                 veil_bitmap_from_hash('session_bitmap_ref',
+select veil.bitmap_hash_setbit('role_privs', 'rubble', 20002);
+select veil.union_into_bitmap_hash('role_privs', 'rubble',
+                 veil.bitmap_from_hash('session_bitmap_ref',
                                        'role_privs', 'wibble'));
 
 \echo TEST 4.17 ~ #3.*20001.*20003#Test union into bitmap hash
-select count(*), min(veil_bitmap_hash_bits), max(veil_bitmap_hash_bits)
-from veil_bitmap_hash_bits('role_privs', 'rubble');
+select count(*), min(bitmap_hash_bits), max(bitmap_hash_bits)
+from veil.bitmap_hash_bits('role_privs', 'rubble');
 
 \echo TEST 4.18 ~ #truex#Check for defined bitmap in hash
-select veil_bitmap_hash_key_exists('role_privs', 'rubble') || 'x';
+select veil.bitmap_hash_key_exists('role_privs', 'rubble') || 'x';
 
 \echo TEST 4.19 ~ #falsex#Check for undefined bitmap in hash
-select veil_bitmap_hash_key_exists('role_privs', 'bubble') || 'x';
+select veil.bitmap_hash_key_exists('role_privs', 'bubble') || 'x';
 EOF
 
     do_test 4b <<EOF   
 \echo PREP
-select veil_deserialise(contents) from my_text;
+select veil.deserialise(contents) from my_text;
 drop table my_text;
 
 -- Test a bit
 \echo TEST 4.20 = #t#Check a bit in the deserialised bitmap hash
-select veil_bitmap_hash_testbit('role_privs', 'wibble', 20001);
+select veil.bitmap_hash_testbit('role_privs', 'wibble', 20001);
 
 \echo TEST 4.21 ~ #1 *| *20003 *| *20003#Count those bits
-select count(*), min(veil_bitmap_hash_bits), max(veil_bitmap_hash_bits)
-from   veil_bitmap_hash_bits('role_privs', 'wibble');
+select count(*), min(bitmap_hash_bits), max(bitmap_hash_bits)
+from   veil.bitmap_hash_bits('role_privs', 'wibble');
 
 EOF
 }
@@ -675,8 +675,8 @@ regress_5()
 -- Reload default version of init to check that it fails.
 `define_veil`
 
-\echo TEST 5.1 ~ #ERROR.*veil_init#Default init
-select veil_init_range('range_x', 1, 10);
+\echo TEST 5.1 ~ #ERROR.*veil init#Default init
+select veil.init_range('range_x', 1, 10);
 EOF
 
     # Need a new session in order to perform init again
@@ -684,27 +684,27 @@ EOF
 \echo PREP
 -- Restore regression version of init
 create or replace
-function veil_init(bool) returns bool as '
+function veil.veil_init(doing_reset bool) returns bool as '
 begin
     return true;
 end;
 ' language plpgsql;
 
 \echo TEST 5.2 = #10#Demo init
-select veil_init_range('range_x', 1, 10);
+select veil.init_range('range_x', 1, 10);
 
 \echo PREP
 \echo TEST 5.3 = #t#Reset once
-select veil_perform_reset();
+select veil.veil_perform_reset();
 
 \echo TEST 5.4 = #1#Check variables after reset
-select count(*) from veil_variables();
+select count(*) from veil.veil_variables();
 
 \echo TEST 5.5 = #t#Reset again
-select veil_perform_reset();
+select veil.veil_perform_reset();
 
 \echo TEST 5.6 = #2#Check variables again
-select count(*) from veil_variables();
+select count(*) from veil.veil_variables();
 
 -- Try performing a reset with the standard version of init.  This 
 -- will prevent the reset from completing and leave the system in an
@@ -713,93 +713,100 @@ select count(*) from veil_variables();
 \echo PREP IGNORE
 -- Reload default version of init to check that it fails.
 `define_veil`
-\echo TEST 5.7 ~ #ERROR.*veil_init#Reset with failing veil_init
-select veil_perform_reset();
+\echo TEST 5.7 ~ #ERROR.*veil init#Reset with failing veil_init
+select veil.veil_perform_reset();
 
 -- Now subsequent attempts to perform reset will fail.
 \echo TEST 5.8 ~ #^ *f *\$#Failing reset (context switch was left incomplete)
-select veil_perform_reset();
+select veil.veil_perform_reset();
 
 \echo TEST 5.9 ~ #WARNING.*reset#Again (looking for WARNING message)
-select veil_perform_reset();
+select veil.veil_perform_reset();
+
+\echo PREP IGNORE
+-- Use force_reset to fix this problem.  This is not normally available in
+-- Veil, so we have to explicitly make it available.
+create or replace
+function veil.veil_force_reset() returns bool
+     as '@LIBPATH@', 'veil_force_reset'
+     language C stable;
 
--- Use force_reset to fix this problem.
 \echo TEST 5.10 ~ #^ *t *\$#Force reset
-select veil_force_reset();
+select veil.veil_force_reset();
 
 -- And now try normal reset again
 \echo PREP
 -- Restore regression version of init
 create or replace
-function veil_init(bool) returns bool as '
+function veil.veil_init(doing_reset bool) returns bool as '
 begin
     return true;
 end;
 ' language plpgsql;
 
 \echo TEST 5.11 = #t#Reset again
-select veil_perform_reset();
+select veil.veil_perform_reset();
 
 -- Test that existing session retains its variables when reset is performed
 -- by another session
 
 \echo PREP
-select veil_share('bitmap_x');
-select veil_init_range('range_x', 1, 100);
-select veil_init_bitmap('bitmap_x', 'range_x');
-select veil_bitmap_setbit('bitmap_x', 2);
-select veil_bitmap_setbit('bitmap_x', 3);
-select veil_bitmap_setbit('bitmap_x', 5);
-select veil_bitmap_setbit('bitmap_x', 7);
-select veil_bitmap_setbit('bitmap_x', 11);
-select veil_bitmap_setbit('bitmap_x', 13);
-select veil_bitmap_setbit('bitmap_x', 17);
-select veil_bitmap_setbit('bitmap_x', 19);
-select veil_bitmap_setbit('bitmap_x', 23);
-select veil_bitmap_setbit('bitmap_x', 29);
-select veil_bitmap_setbit('bitmap_x', 31);
-select veil_bitmap_setbit('bitmap_x', 37);
-select veil_bitmap_setbit('bitmap_x', 41);
-select veil_bitmap_setbit('bitmap_x', 43);
-select veil_bitmap_setbit('bitmap_x', 47);
-select veil_bitmap_setbit('bitmap_x', 53);
-select veil_bitmap_setbit('bitmap_x', 59);
-select veil_bitmap_setbit('bitmap_x', 61);
-select veil_bitmap_setbit('bitmap_x', 67);
-select veil_bitmap_setbit('bitmap_x', 71);
-select veil_bitmap_setbit('bitmap_x', 73);
-select veil_bitmap_setbit('bitmap_x', 79);
-select veil_bitmap_setbit('bitmap_x', 83);
-select veil_bitmap_setbit('bitmap_x', 89);
-select veil_bitmap_setbit('bitmap_x', 97);
+select veil.share('bitmap_x');
+select veil.init_range('range_x', 1, 100);
+select veil.init_bitmap('bitmap_x', 'range_x');
+select veil.bitmap_setbit('bitmap_x', 2);
+select veil.bitmap_setbit('bitmap_x', 3);
+select veil.bitmap_setbit('bitmap_x', 5);
+select veil.bitmap_setbit('bitmap_x', 7);
+select veil.bitmap_setbit('bitmap_x', 11);
+select veil.bitmap_setbit('bitmap_x', 13);
+select veil.bitmap_setbit('bitmap_x', 17);
+select veil.bitmap_setbit('bitmap_x', 19);
+select veil.bitmap_setbit('bitmap_x', 23);
+select veil.bitmap_setbit('bitmap_x', 29);
+select veil.bitmap_setbit('bitmap_x', 31);
+select veil.bitmap_setbit('bitmap_x', 37);
+select veil.bitmap_setbit('bitmap_x', 41);
+select veil.bitmap_setbit('bitmap_x', 43);
+select veil.bitmap_setbit('bitmap_x', 47);
+select veil.bitmap_setbit('bitmap_x', 53);
+select veil.bitmap_setbit('bitmap_x', 59);
+select veil.bitmap_setbit('bitmap_x', 61);
+select veil.bitmap_setbit('bitmap_x', 67);
+select veil.bitmap_setbit('bitmap_x', 71);
+select veil.bitmap_setbit('bitmap_x', 73);
+select veil.bitmap_setbit('bitmap_x', 79);
+select veil.bitmap_setbit('bitmap_x', 83);
+select veil.bitmap_setbit('bitmap_x', 89);
+select veil.bitmap_setbit('bitmap_x', 97);
 begin;
 \echo TEST 5.12 = #25#Original bitmap before reset from other session
-select count(*) from veil_bitmap_bits('bitmap_x');
+select count(*) from veil.bitmap_bits('bitmap_x');
 
 \! $0 -T 5a
 
 \echo - ...(back from 5a)...
 \echo TEST 5.19 = #25#Original Bitmap (from original transaction)
-select count(*) from veil_bitmap_bits('bitmap_x');
-select * from veil_variables();
+select count(*) from veil.bitmap_bits('bitmap_x');
+select * from veil.veil_variables();
 commit;
 
 \echo TEST 5.20 = #15#New bitmap created by other session
 begin;
-select count(*) from veil_bitmap_bits('bitmap_x');
+select count(*) from veil.bitmap_bits('bitmap_x');
 
 \! $0 -T 5b
 
 \echo - ...(back from 5b)...
 \echo TEST 5.98 = #15#Original Bitmap (from original transaction)
-select count(*) from veil_bitmap_bits('bitmap_x');
-select * from veil_variables();
+select count(*) from veil.bitmap_bits('bitmap_x');
+select * from veil.veil_variables();
 commit;
 
 
 \echo TEST 5.99 = #24#New bitmap created by other session
 begin;
-select count(*) from veil_bitmap_bits('bitmap_x');
+select count(*) from veil.bitmap_bits('bitmap_x');
 
 
 EOF
@@ -812,40 +819,40 @@ regress_5a()
     do_test 5a <<EOF   
 
 \echo TEST 5.13 = #25#Bitmap variable from other session with bits
-select count(*) from veil_bitmap_bits('bitmap_x');
+select count(*) from veil.bitmap_bits('bitmap_x');
 
 \echo TEST 5.14 = #t#Successful reset
-select count(*) from veil_bitmap_bits('bitmap_x');
-select veil_perform_reset();
+select count(*) from veil.bitmap_bits('bitmap_x');
+select veil.veil_perform_reset();
 
 \echo TEST 5.15 ~ #ERROR.*Undefined#No bitmap variable from other session
-select veil_share('bitmap_x');
-select count(*) from veil_bitmap_bits('bitmap_x');
+select veil.share('bitmap_x');
+select count(*) from veil.bitmap_bits('bitmap_x');
 
 \echo TEST 5.16 = #f#Failed reset as session still in use
-select veil_perform_reset();
+select veil.veil_perform_reset();
 
 \echo TEST 5.17 ~ #WARNING.*reset#Failed reset as session still in use (again)
-select veil_perform_reset();
+select veil.veil_perform_reset();
 
 \echo PREP
-select veil_init_range('range_x', 1, 100);
-select veil_init_bitmap('bitmap_x', 'range_x');
-select veil_bitmap_setbit('bitmap_x', 1);
-select veil_bitmap_setbit('bitmap_x', 4);
-select veil_bitmap_setbit('bitmap_x', 6);
-select veil_bitmap_setbit('bitmap_x', 8);
-select veil_bitmap_setbit('bitmap_x', 10);
-select veil_bitmap_setbit('bitmap_x', 14);
-select veil_bitmap_setbit('bitmap_x', 16);
-select veil_bitmap_setbit('bitmap_x', 60);
-select veil_bitmap_setbit('bitmap_x', 64);
-select veil_bitmap_setbit('bitmap_x', 72);
-select veil_bitmap_setbit('bitmap_x', 75);
-select veil_bitmap_setbit('bitmap_x', 78);
-select veil_bitmap_setbit('bitmap_x', 82);
-select veil_bitmap_setbit('bitmap_x', 88);
-select veil_bitmap_setbit('bitmap_x', 95);
+select veil.init_range('range_x', 1, 100);
+select veil.init_bitmap('bitmap_x', 'range_x');
+select veil.bitmap_setbit('bitmap_x', 1);
+select veil.bitmap_setbit('bitmap_x', 4);
+select veil.bitmap_setbit('bitmap_x', 6);
+select veil.bitmap_setbit('bitmap_x', 8);
+select veil.bitmap_setbit('bitmap_x', 10);
+select veil.bitmap_setbit('bitmap_x', 14);
+select veil.bitmap_setbit('bitmap_x', 16);
+select veil.bitmap_setbit('bitmap_x', 60);
+select veil.bitmap_setbit('bitmap_x', 64);
+select veil.bitmap_setbit('bitmap_x', 72);
+select veil.bitmap_setbit('bitmap_x', 75);
+select veil.bitmap_setbit('bitmap_x', 78);
+select veil.bitmap_setbit('bitmap_x', 82);
+select veil.bitmap_setbit('bitmap_x', 88);
+select veil.bitmap_setbit('bitmap_x', 95);
 
 EOF
 }
@@ -857,50 +864,50 @@ regress_5b()
     do_test 5b <<EOF   
 
 \echo TEST 5.21 = #15#Bitmap variable from other session with bits
-select count(*) from veil_bitmap_bits('bitmap_x');
+select count(*) from veil.bitmap_bits('bitmap_x');
 
 \echo TEST 5.22 = #t#Successful reset
-select count(*) from veil_bitmap_bits('bitmap_x');
-select veil_perform_reset();
+select count(*) from veil.bitmap_bits('bitmap_x');
+select veil.veil_perform_reset();
 
 \echo TEST 5.23 ~ #ERROR.*Undefined#No bitmap variable from other session
-select veil_share('bitmap_x');
-select count(*) from veil_bitmap_bits('bitmap_x');
+select veil.share('bitmap_x');
+select count(*) from veil.bitmap_bits('bitmap_x');
 
 \echo TEST 5.24 = #f#Failed reset as session still in use
-select veil_perform_reset();
+select veil.veil_perform_reset();
 
 \echo TEST 5.25 ~ #WARNING.*reset#Failed reset as session still in use (again)
-select veil_perform_reset();
+select veil.veil_perform_reset();
 
 \echo PREP
-select veil_init_range('range_x', 1, 100);
-select veil_init_bitmap('bitmap_x', 'range_x');
-select veil_init_bitmap('bitmap_x', 'range_x');
-select veil_bitmap_setbit('bitmap_x', 2);
-select veil_bitmap_setbit('bitmap_x', 3);
-select veil_bitmap_setbit('bitmap_x', 5);
-select veil_bitmap_setbit('bitmap_x', 7);
-select veil_bitmap_setbit('bitmap_x', 11);
-select veil_bitmap_setbit('bitmap_x', 13);
-select veil_bitmap_setbit('bitmap_x', 17);
-select veil_bitmap_setbit('bitmap_x', 19);
-select veil_bitmap_setbit('bitmap_x', 23);
-select veil_bitmap_setbit('bitmap_x', 29);
-select veil_bitmap_setbit('bitmap_x', 31);
-select veil_bitmap_setbit('bitmap_x', 37);
-select veil_bitmap_setbit('bitmap_x', 41);
-select veil_bitmap_setbit('bitmap_x', 43);
-select veil_bitmap_setbit('bitmap_x', 47);
-select veil_bitmap_setbit('bitmap_x', 53);
-select veil_bitmap_setbit('bitmap_x', 59);
-select veil_bitmap_setbit('bitmap_x', 61);
-select veil_bitmap_setbit('bitmap_x', 67);
-select veil_bitmap_setbit('bitmap_x', 71);
-select veil_bitmap_setbit('bitmap_x', 73);
-select veil_bitmap_setbit('bitmap_x', 79);
-select veil_bitmap_setbit('bitmap_x', 83);
-select veil_bitmap_setbit('bitmap_x', 89);
+select veil.init_range('range_x', 1, 100);
+select veil.init_bitmap('bitmap_x', 'range_x');
+select veil.init_bitmap('bitmap_x', 'range_x');
+select veil.bitmap_setbit('bitmap_x', 2);
+select veil.bitmap_setbit('bitmap_x', 3);
+select veil.bitmap_setbit('bitmap_x', 5);
+select veil.bitmap_setbit('bitmap_x', 7);
+select veil.bitmap_setbit('bitmap_x', 11);
+select veil.bitmap_setbit('bitmap_x', 13);
+select veil.bitmap_setbit('bitmap_x', 17);
+select veil.bitmap_setbit('bitmap_x', 19);
+select veil.bitmap_setbit('bitmap_x', 23);
+select veil.bitmap_setbit('bitmap_x', 29);
+select veil.bitmap_setbit('bitmap_x', 31);
+select veil.bitmap_setbit('bitmap_x', 37);
+select veil.bitmap_setbit('bitmap_x', 41);
+select veil.bitmap_setbit('bitmap_x', 43);
+select veil.bitmap_setbit('bitmap_x', 47);
+select veil.bitmap_setbit('bitmap_x', 53);
+select veil.bitmap_setbit('bitmap_x', 59);
+select veil.bitmap_setbit('bitmap_x', 61);
+select veil.bitmap_setbit('bitmap_x', 67);
+select veil.bitmap_setbit('bitmap_x', 71);
+select veil.bitmap_setbit('bitmap_x', 73);
+select veil.bitmap_setbit('bitmap_x', 79);
+select veil.bitmap_setbit('bitmap_x', 83);
+select veil.bitmap_setbit('bitmap_x', 89);
 
 EOF
 }
@@ -915,36 +922,50 @@ regress_6()
 \echo PREP IGNORE
 -- Reload default version of init to check that it fails.
 `define_veil`
-\echo TEST 6.1 ~ #ERROR.*veil_init#Default init
-select veil_init_range('range_x', 1, 10);
+\echo TEST 6.1 ~ #ERROR.*veil init#Default init
+select veil.init_range('range_x', 1, 10);
 
 \echo PREP IGNORE
--- Init function with shared variables
+-- Multiple nnit functions with shared variables.  If they are
+-- invoked in the wrong order, there will be failures
 create or replace
-function veil_init(bool) returns bool as '
+function veil.veil_init1(bool) returns bool as '
 begin
-    perform veil_share(''shared1'');
-    perform veil_share(''shared2'');
-    perform veil_int4_set(''shared1'', 123);
+    perform veil.share(''shared1'');
     return true;
 end
 '
 language plpgsql;
 
-select veil_init(true);
+create or replace
+function veil.veil_init2(bool) returns bool as '
+begin
+    perform veil.share(''shared2'');
+    perform veil.int4_set(''shared1'', 123);
+    return true;
+end
+'
+language plpgsql;
+
+insert into veil.veil_init_fns
+       (fn_name, priority)
+values ('veil.veil_init1', 1),
+       ('veil.veil_init2', 2);
+
+select veil.veil_init(true);
 
 \echo TEST 6.2 ~ #shared2.*Undefined.*t#Undefined shared variable
-select * from veil_variables();
+select * from veil.veil_variables();
 \echo TEST 6.3 ~ #shared1.*Int4.*t#Defined shared variable
-select * from veil_variables();
+select * from veil.veil_variables();
 
 \echo PREP IGNORE
-select veil_perform_reset();
+select veil.veil_perform_reset();
 
 \echo TEST 6.4 ~ #shared2.*Undefined.*t#Undefined shared variable
-select * from veil_variables();
+select * from veil.veil_variables();
 \echo TEST 6.5 ~ #shared1.*Int4.*t#Defined shared variable
-select * from veil_variables();
+select * from veil.veil_variables();
 
 EOF
 }
@@ -953,33 +974,53 @@ EOF
 regress_7()
 {
     echo - 
-    echo "- ...test set 7: veil_init() triggering SPI bug..."
+    echo "- ...test set 7: veil_demo..."
 
     do_test 7 <<EOF    
 \echo PREP IGNORE
 -- Reload default version of init to check that it fails.
-DROP DATABASE regressdb2;
-CREATE DATABASE regressdb2;
-\c regressdb2;
 `define_veil`
 
-CREATE PROCEDURAL LANGUAGE plpgsql;
-EOF
-    do_test 7 <<EOF    
-CREATE or replace FUNCTION veil_init(doing_reset boolean) RETURNS  
-boolean
-     AS \$\$
-begin
-     perform veil_share('priv_id_range');
-     return true;
-end
-\$\$
-     LANGUAGE plpgsql;
+drop table if exists role_privileges;
+drop table if exists roles;
+drop table if exists privileges;
+
+\echo TEST 7.1 ~ #ERROR.*veil init#Default init
+select veil.init_range('range_x', 1, 10);
+
+create extension veil_demo;
+
+\echo TEST 7.2 ~ #10#veil_demo init
+select veil.init_range('range_x', 1, 10);
+
+\echo TEST 7.3 ~ #0#Not connected
+select count(*) from persons;
+
+\echo TEST 7.4 ~ #t#connect_person
+select connect_person(4);
+
+\echo TEST 7.5 ~ #1#non-privileged access
+select count(*) from persons;
+
+\echo PREP IGNORE
+select connect_person(2);
+
+\echo TEST 7.6 ~ #6#privileged access
+select count(*) from persons;
+
+\echo PREP IGNORE
+select disconnect_person();
+
+\echo TEST 7.7 ~ #0#Disconnect
+select count(*) from persons;
+
+-- Drop veil_demo extension
+\echo PREP IGNORE
+drop extension veil_demo;
 
+\echo TEST 7.8 ~ #ERROR.*veil init#Drop veil_demo (default init)
+select veil.veil_perform_reset();
 
-\echo TEST 7.1 = #9#Test for SPI bug
-SELECT veil_int4_set('user_id', 1) + 8;
-DROP DATABASE regressdb2;
 EOF
 }
 
index d8ac77023376d0008fd0b9604683c51d04571292..0a440fc280197ebf880212eb74ac2f6f9ec47b20 100644 (file)
@@ -85,6 +85,47 @@ veil_shmem_context_size()
    return shmem_context_size;
 }
 
+/** 
+ * Initialise Veil's use of GUC variables.
+ */
+void
+veil_config_init()
+{
+   static bool first_time = true;
+   if (!first_time) {
+       return;
+   }
+
+   DefineCustomIntVariable("veil.dbs_in_cluster",
+                           "The number of databases within the cluster "
+                           "that will be using veil (1)",
+                           NULL,
+                           &dbs_in_cluster,
+                           1, 1, 16,
+                           PGC_USERSET,
+                           0, NULL, NULL, NULL);
+   DefineCustomIntVariable("veil.shared_hash_elems",
+                           "The number of entries for shared variables in "
+                           "each shared memory context (32)",
+                           NULL,
+                           &shared_hash_elems,
+                           32, 32, 8192,
+                           PGC_USERSET,
+                           0, NULL, NULL, NULL);
+   DefineCustomIntVariable("veil.shmem_context_size",
+                           "Size of each shared memory context",
+                           "Size of each shared memory context in bytes.  "
+                           "This cannot be increased without stopping "
+                           "and restarting the database cluster.",
+                           &shmem_context_size,
+                           4096, 4096, 104857600,
+                           PGC_USERSET,
+                           0, NULL, NULL, NULL);
+
+   first_time = false;
+}
+
+
 /** 
  * Retrieve Veil's GUC variables for this session.
  */
@@ -96,11 +137,11 @@ veil_load_config()
        return;
    }
 
-   dbs_in_cluster = atoi(GetConfigOption("veil.dbs_in_cluster", FALSE));
+   dbs_in_cluster = atoi(GetConfigOption("veil.dbs_in_cluster", FALSE, FALSE));
    shared_hash_elems = atoi(GetConfigOption("veil.shared_hash_elems", 
-                                            FALSE));
+                                            FALSE, FALSE));
    shmem_context_size = atoi(GetConfigOption("veil.shmem_context_size", 
-                                             FALSE));
+                                             FALSE, FALSE));
    first_time = false;
 }
 
diff --git a/src/veil_demo.sql b/src/veil_demo.sql
deleted file mode 100644 (file)
index 313f076..0000000
+++ /dev/null
@@ -1,423 +0,0 @@
-
-\echo Creating tables...
-
-\echo ...privileges...
-create table privileges (
-    privilege_id   integer not null,
-    privilege_name varchar(80) not null
-);
-alter table privileges add constraint privilege__pk
-    primary key(privilege_id);
-
-
-\echo ...role...
-create table roles (
-    role_id    integer not null,
-    role_name  varchar(80) not null
-);
-alter table roles add constraint role__pk
-    primary key(role_id);
-
-
-\echo ...role_privileges...
-create table role_privileges (
-    role_id        integer not null,
-    privilege_id   integer not null
-);
-
-alter table role_privileges add constraint role_privilege__pk
-    primary key(role_id, privilege_id);
-
-alter table role_privileges add constraint role_privilege__role_fk
-    foreign key(role_id)
-    references roles(role_id);
-
-alter table role_privileges add constraint role_privilege__priv_fk
-    foreign key(privilege_id)
-    references privileges(privilege_id);
-
-\echo ...role_roles...
-create table role_roles (
-    role_id        integer not null,
-    has_role_id        integer not null
-);
-
-alter table role_roles add constraint role_role__pk
-    primary key(role_id, has_role_id);
-
-alter table role_roles add constraint role_role__role_fk
-    foreign key(role_id)
-    references roles(role_id);
-
-alter table role_roles add constraint role_role__has_role_fk
-    foreign key(has_role_id)
-    references roles(role_id);
-
-
-\echo ...persons...
-create sequence person_id_seq;
-create table persons (
-    person_id      integer not null,
-    person_name        varchar(80) not null
-);
-alter table persons add constraint person__pk
-    primary key(person_id);
-
-
-\echo ...projects...
-create sequence project_id_seq;
-create table projects (
-    project_id     integer not null,
-    project_name   varchar(80) not null
-);
-alter table projects add constraint project__pk
-    primary key(project_id);
-
-
-\echo ...detail_types...
-create table detail_types (
-    detail_type_id   integer not null,
-    required_privilege_id integer not null,
-    detail_type_name     varchar(80) not null
-);
-alter table detail_types add constraint detail_type__pk
-    primary key(detail_type_id);
-
-alter table detail_types add constraint detail_type__priv_fk
-    foreign key(required_privilege_id)
-    references privileges(privilege_id);
-
-
-\echo ...assignments...
-create table assignments (
-    project_id     integer not null,
-    person_id      integer not null,
-    role_id        integer not null
-);
-alter table assignments add constraint assignment__pk
-    primary key(project_id, person_id);
-
-alter table assignments add constraint assignment__project_fk
-    foreign key(project_id)
-    references projects(project_id);
-
-alter table assignments add constraint assignment__person_fk
-    foreign key(person_id)
-    references persons(person_id);
-
-alter table assignments add constraint assignment__role_fk
-    foreign key(role_id)
-    references roles(role_id);
-
-
-\echo ...person_roles...
-create table person_roles (
-    person_id      integer not null,
-    role_id        integer not null
-);
-alter table person_roles add constraint person_role__pk
-    primary key(person_id, role_id);
-
-alter table person_roles add constraint person_role__person_fk
-    foreign key(person_id)
-    references persons(person_id);
-
-alter table person_roles add constraint person_role__role_fk
-    foreign key(role_id)
-    references roles(role_id);
-
-
-\echo ...project_details...
-create table project_details (
-    project_id     integer not null,
-    detail_type_id integer not null,
-    value      text not null
-);
-alter table project_details add constraint project_detail__pk
-    primary key(project_id, detail_type_id);
-
-alter table project_details add constraint project_detail__project_fk
-    foreign key(project_id)
-    references projects(project_id);
-
-alter table project_details add constraint project_detail__detail_fk
-    foreign key(detail_type_id)
-    references detail_types(detail_type_id);
-
-
-\echo ...person_details...
-create table person_details (
-    person_id      integer not null,
-    detail_type_id integer not null,
-    value      text not null
-);
-alter table person_details add constraint person_detail__pk
-    primary key(person_id, detail_type_id);
-
-alter table person_details add constraint person_detail__person_fk
-    foreign key(person_id)
-    references persons(person_id);
-
-alter table person_details add constraint person_detail__detail_fk
-    foreign key(detail_type_id)
-    references detail_types(detail_type_id);
-
-\echo Setting up base data...
-
-\echo ...privileges...
-copy privileges (privilege_id, privilege_name) from stdin;
-10001  select_privileges
-10002  insert_privileges
-10003  update_privileges
-10004  delete_privileges
-10005  select_roles
-10006  insert_roles
-10007  update_roles
-10008  delete_roles
-10009  select_role_privileges
-10010  insert_role_privileges
-10011  update_role_privileges
-10012  delete_role_privileges
-10013  select_persons
-10014  insert_persons
-10015  update_persons
-10016  delete_persons
-10017  select_projects
-10018  insert_projects
-10019  update_projects
-10020  delete_projects
-10021  select_detail_types
-10022  insert_detail_types
-10023  update_detail_types
-10024  delete_detail_types
-10025  select_assignments
-10026  insert_assignments
-10027  update_assignments
-10028  delete_assignments
-10029  select_person_roles
-10030  insert_person_roles
-10031  update_person_roles
-10032  delete_person_roles
-10033  select_project_details
-10034  insert_project_details
-10035  update_project_details
-10036  delete_project_details
-10037  select_person_details
-10038  insert_person_details
-10039  update_person_details
-10040  delete_person_details
-10041  select_role_roles
-10042  insert_role_roles
-10043  update_role_roles
-10044  delete_role_roles
-10100  can_connect
-10150  view_basic
-10151  view_personal
-10152  view_personal_secure
-10153  view_project_confidential
-\.
-
-\echo ...roles...
-copy roles (role_id, role_name) from stdin;
-11001  DBA
-11002  Personal Context
-11003  Employee
-11004  Worker
-11005  Project Manager
-11006  Director
-11007  Manager
-\.
-
-\echo ...role_privileges...
--- DBA can do anything (but is not automatically an employee)
-insert into role_privileges (role_id, privilege_id)
-select 11001, privilege_id
-from   privileges
-where  privilege_id != 10100;
-
--- Personal Context allows update of personal details
-copy role_privileges (role_id, privilege_id) from stdin;
-11002  10013
-11002  10015
-11002  10025
-11002  10029
-11002  10037
-11002  10038
-11002  10039
-11002  10040
-11002  10150
-11002  10151
-11002  10152
-\.
-
--- Basic Access can see lookup data
-insert into role_privileges (role_id, privilege_id)
-select 11003, privilege_id
-from   privileges
-where  privilege_name in ('select_privileges', 'select_roles',
-             'select_role_privileges', 'select_detail_types');
-
-insert into role_privileges (role_id, privilege_id)
-select 11003, 10100;
-
--- Workers can modify project info
-insert into role_privileges (role_id, privilege_id)
-select 11004, privilege_id
-from   privileges
-where  privilege_name like '%project%'
-and    privilege_name not like 'delete%'
-and    privilege_name not like '%confidential';
-
-insert into role_privileges (role_id, privilege_id)
-select 11004, 10025;
-insert into role_privileges (role_id, privilege_id)
-select 11004, 10150;
-
--- Project Manager can do anything to project info and can see personal info
-insert into role_privileges (role_id, privilege_id)
-select 11005, privilege_id
-from   privileges
-where  privilege_name like '%project%'
-or     privilege_name like '%assignment%';
-
-insert into role_privileges (role_id, privilege_id)
-select 11005, privilege_id
-from   privileges
-where  privilege_name like 'select_person%';
-
-insert into role_privileges (role_id, privilege_id)
-select 11005, 10150;
-insert into role_privileges (role_id, privilege_id)
-select 11005, 10151;
-
--- Director can do anything except modify personal details
-insert into role_privileges (role_id, privilege_id)
-select 11006, privilege_id
-from   privileges
-where  privilege_name not like '%person%';
-
-insert into role_privileges (role_id, privilege_id)
-select 11006, privilege_id
-from   privileges
-where  privilege_name like 'select_person%';
-
-insert into role_privileges (role_id, privilege_id)
-select 11006, 10014;
-
-insert into role_privileges (role_id, privilege_id)
-select 11006, 10151;
-
-insert into role_privileges (role_id, privilege_id)
-select 11006, 10152;
-
--- Manager can see personal info
-insert into role_privileges (role_id, privilege_id)
-select 11007, privilege_id
-from   privileges
-where  privilege_name like 'select_person%';
-
-insert into role_privileges (role_id, privilege_id)
-select 11007, 10150;
-insert into role_privileges (role_id, privilege_id)
-select 11007, 10151;
-
-
-\echo ...persons...
-copy persons (person_id, person_name) from stdin;
-1  Deb (the DBA)
-2  Pat (the PM)
-3  Derick (the director)
-4  Will (the worker)
-5  Wilma (the worker)
-6  Fred (the fired DBA)
-\.
-
-\echo ...person_roles...
-copy person_roles (person_id, role_id) from stdin;
-1  11001
-1  11003
-2  11003
-2  11007
-3  11003
-3  11006
-4  11003
-5  11003
-6  11001
-\.
-
-\echo ...projects...
-copy projects (project_id, project_name) from stdin;
-101    Secret Project
-102    Public project
-\.
-
-\echo ...assignments...
-copy assignments (project_id, person_id, role_id) from stdin;
-101    3   11005
-101    5   11004
-102    2   11005
-102    4   11004
-102    5   11004
-\.
-
-\echo ...detail_types...
-copy detail_types (detail_type_id, required_privilege_id, 
-                   detail_type_name) from stdin;
-1001   10150   start_date
-1002   10150   status
-1003   10150   join_date
-1004   10152   salary
-1005   10151   date of birth
-1006   10152   sin
-1007   10150   skills
-1008   10153   contract value
-\.
-
-\echo ...person_details...
-copy person_details (person_id, detail_type_id, value) from stdin;
-1  1003    20050102
-2  1003    20050103
-3  1003    20050104
-4  1003    20050105
-5  1003    20050106
-6  1003    20050107
-1  1002    Employee
-2  1002    Employee
-3  1002    Employee
-4  1002    Employee
-5  1002    Employee
-6  1002    Terminated
-1  1004    50,000
-2  1004    50,000
-3  1004    80,000
-4  1004    30,000
-5  1004    30,000
-6  1004    40,000
-1  1005    19610102
-2  1005    19600102
-3  1005    19650102
-4  1005    19660102
-5  1005    19670102
-1  1006    123456789
-2  1006    123456789
-3  1006    123456789
-4  1006    123456789
-5  1006    123456789
-1  1007    Oracle, C, SQL
-2  1007    Soft peoply-stuff
-3  1007    None at all
-4  1007    Subservience
-5  1007    Subservience
-\.
-
-
-\echo ...project_details
-copy project_details (project_id, detail_type_id, value) from stdin;
-101    1001    20050101
-101    1002    Secretly ongoing
-101    1008    $800,000
-102    1001    20050101
-102    1002    Ongoing
-102    1008    $100,000
-\.
-
index a0dd76eac7b1b3ea855a0fd74a145bd35673e3ff..bec17cb94828ce6d113987318dd035d48eaa5e02 100644 (file)
@@ -64,10 +64,11 @@ extern void vl_free(void *mem);
 extern void _PG_init(void);
 
 /* veil_query */
-extern int vl_spi_connect(void);
-extern int vl_spi_finish(void);
+extern int vl_spi_connect(bool *p_pushed);
+extern int vl_spi_finish(bool pushed);
 extern bool vl_bool_from_query(const char *qry, bool *result);
 extern bool vl_db_exists(Oid db_id);
+extern int  vl_call_init_fns(bool param);
 
 /* veil_config */
 extern void veil_config_init(void);
index f5cc6bf7fc5b321ab8adaafeddfac9e55def57de..2e4534b9760a92ba3bf35eb952f4e2753e666ed5 100644 (file)
@@ -148,6 +148,7 @@ ensure_init()
    TransactionId this_xid;
     int   ok;
    HTAB *hash;
+   bool pushed;
     static bool done = false;
    static TransactionId xid = 0;
 
@@ -158,7 +159,7 @@ ensure_init()
            return;
        }
        xid = this_xid;       /* Record our xid in case we recurse */
-        ok = vl_spi_connect();
+        ok = vl_spi_connect(&pushed);
         if (ok != SPI_OK_CONNECT) {
            ereport(ERROR,
                    (errcode(ERRCODE_INTERNAL_ERROR),
@@ -168,7 +169,7 @@ ensure_init()
 
        hash = vl_get_shared_hash();  /* Init all shared memory
                                         constructs */
-        (void) vl_bool_from_query("select veil_init(FALSE)", &success);
+        (void) vl_bool_from_query("select veil.veil_init(FALSE)", &success);
 
         if (!success) {
            ereport(ERROR,
@@ -177,7 +178,7 @@ ensure_init()
                     errdetail("veil_init() did not return true.")));
         }
         
-        ok = vl_spi_finish();
+        ok = vl_spi_finish(pushed);
         if (ok != SPI_OK_FINISH) {
            ereport(ERROR,
                    (errcode(ERRCODE_INTERNAL_ERROR),
@@ -616,7 +617,7 @@ veil_variables(PG_FUNCTION_ARGS)
         funcctx = SRF_FIRSTCALL_INIT();
         oldcontext = MemoryContextSwitchTo(funcctx->multi_call_memory_ctx);
 
-        tupdesc = RelationNameGetTupleDesc("veil_variable_t");
+        tupdesc = RelationNameGetTupleDesc("veil.veil_variable_t");
         slot = TupleDescGetSlot(tupdesc);
         funcctx->slot = slot;
         attinmeta = TupleDescGetAttInMetadata(tupdesc);
@@ -743,7 +744,7 @@ datum_from_range(int32 min, int32 max)
         MemoryContext oldcontext = MemoryContextSwitchTo(TopMemoryContext);
         
         init_done = true;
-        tupdesc = RelationNameGetTupleDesc("veil_range_t");
+        tupdesc = RelationNameGetTupleDesc("veil.veil_range_t");
         slot = TupleDescGetSlot(tupdesc);
         attinmeta = TupleDescGetAttInMetadata(tupdesc);
         
@@ -2320,8 +2321,9 @@ PG_FUNCTION_INFO_V1(veil_init);
  * The boolean parameter will be false when called for initialisation,
  * and true when performing a reset.
  *
- * This function must be redefined as a custom function in your
- * implementation. 
+ * This function may be redefined as a custom function in your
+ * implementation, or will call initialisation functions registered in 
+ * the table veil.veil_init_fns.
  *
  * @param fcinfo <code>doing_reset bool</code> Whether we are being
  * called in order to reset (true) the session or (false) simply to
@@ -2331,11 +2333,16 @@ PG_FUNCTION_INFO_V1(veil_init);
 Datum
 veil_init(PG_FUNCTION_ARGS)
 {
-   ereport(ERROR,
-           (errcode(ERRCODE_INTERNAL_ERROR),
-            errmsg("default veil version of veil_init() has been called"),
-            errhint("You must define your own version of this function.")));
+   bool param = PG_GETARG_BOOL(0);
+   int rows = vl_call_init_fns(param);
 
+   if (rows == 0) {
+       ereport(ERROR,
+               (errcode(ERRCODE_INTERNAL_ERROR),
+                errmsg("No user defined veil init functions found"),
+                errhint("You must refefine veil.veil_init() or register your "
+                    "own init functions in the veil.veil_init_fns table.")));
+   }
     PG_RETURN_BOOL(true);
 }
 
@@ -2357,11 +2364,12 @@ Datum
 veil_perform_reset(PG_FUNCTION_ARGS)
 {
     bool success = true;
+   bool pushed;
     bool result;
     int  ok;
 
    ensure_init();
-    ok = vl_spi_connect();
+    ok = vl_spi_connect(&pushed);
     if (ok != SPI_OK_CONNECT) {
        ereport(ERROR,
                (errcode(ERRCODE_INTERNAL_ERROR),
@@ -2371,9 +2379,9 @@ veil_perform_reset(PG_FUNCTION_ARGS)
 
     success = vl_prepare_context_switch();  
     if (success) {
-        result = vl_bool_from_query("select veil_init(TRUE)", &success);
+        result = vl_bool_from_query("select veil.veil_init(TRUE)", &success);
        elog(NOTICE, "veil_init returns %s to veil_perform_reset", 
-            result? "true": "false");
+            success? "true": "false");
         success = vl_complete_context_switch();
        elog(NOTICE, 
             "vl_complete_context_switch returns %s to veil_perform_reset", 
@@ -2390,7 +2398,7 @@ veil_perform_reset(PG_FUNCTION_ARGS)
                           "is still using the previous memory context.")));
     }
 
-    ok = vl_spi_finish();
+    ok = vl_spi_finish(pushed);
     PG_RETURN_BOOL(success);
 }
 
index 64b25a4846aff64b6d84054445fb5393f0351211..dd896f89e818caaddc61946bb060b607367f4376 100644 (file)
@@ -15,33 +15,48 @@ create schema veil;
 comment on schema veil is
 'Schema containing all veil components.';
 
+create table veil.veil_init_fns(
+  fn_name  varchar not null,
+  priority      integer not null
+);
+
+comment on table veil.veil_init_fns is
+'Configuration table containing the names of functions, conforming to
+the veil.veil_init() API, that veil_init() should call to initialise or
+reset veil variables.  The calls will be performed in priority order.
 
+Note that other veil extensions are expected to create inherited chldren
+of this table, so that their init functions will be called and when the
+extension is dropped, the functions will no longer be visible to
+veil.veil_init().';
 
-create type veil_range_t as (
+select pg_catalog.pg_extension_config_dump('veil.veil_init_fns', '');
+
+create type veil.veil_range_t as (
     min  int4,
     max  int4
 );
-comment on type veil_range_t is
+comment on type veil.veil_range_t is
 'Veil type used to record ranges.  A range is a pair of integers identifying
 the minimum and maximum values of the range.  Ranges are used to
 constrain the size of a bitmap or bitmap array.';
 
-create type veil_variable_t as (
+create type veil.veil_variable_t as (
     name    text,
     type    text,
     shared  bool
 );
-comment on type veil_variable_t is
+comment on type veil.veil_variable_t is
 'Veil type used as the result type of veil_variables(), to describe each
 variable known to a veil instance.';
 
 
 create or replace
-function veil_share(name text) returns bool
+function veil.share(name text) returns bool
      as '@LIBPATH@', 'veil_share'
      language C stable strict;
 
-comment on function veil_share(name text) is
+comment on function veil.share(name text) is
 'Create a shared variable named NAME.
 
 Return TRUE if successful, else raise an error.
@@ -57,17 +72,17 @@ session variables, and are created by assignment, or initialisation.  To
 create a shared variable, call veil_share() with the name of the
 variable you wish to create, then create and use the variable as you
 would a session variable.  Shared variables should only be created and
-initialised from veil_init() in order to prevent race conditions.  If a
-variable has already been created as a session variable, it cannot be
-repurposed as a shared variable.';
+initialised from veil.veil_init() in order to prevent race conditions.
+If a variable has already been created as a session variable, it cannot
+be repurposed as a shared variable.';
 
 
 create or replace
-function veil_variables() returns setof veil_variable_t
+function veil.veil_variables() returns setof veil.veil_variable_t
      as '@LIBPATH@', 'veil_variables'
      language C stable;
 
-comment on function veil_variables() is
+comment on function veil.veil_variables() is
 'List all current veil_variables.
 Return a set of veil_variable_t results, detailing each existant
 variable
@@ -76,11 +91,11 @@ This is intended for interactive use for debugging purposes.';
 
 
 create or replace
-function veil_init_range(name text, min int4, max int4) returns int4
+function veil.init_range(name text, min int4, max int4) returns int4
      as '@LIBPATH@', 'veil_init_range'
      language C stable strict;
 
-comment on function veil_init_range(text, int4, int4) is
+comment on function veil.init_range(text, int4, int4) is
 'Initialise a Range variable called NAME constrained by MIN and MAX.
 
 Return the number of  elements in the range.
@@ -89,20 +104,20 @@ Ranges may be examined using the veil_range() function.';
 
 
 create or replace
-function veil_range(name text) returns veil_range_t
+function veil.range(name text) returns veil.veil_range_t
      as '@LIBPATH@', 'veil_range'
      language C stable strict;
 
-comment on function veil_range(name text) is
+comment on function veil.range(name text) is
 'Return the range for range variable NAME.';
 
 
 create or replace
-function veil_init_bitmap(bitmap_name text, range_name text) returns bool
+function veil.init_bitmap(bitmap_name text, range_name text) returns bool
      as '@LIBPATH@', 'veil_init_bitmap'
      language C stable strict;
 
-comment on function veil_init_bitmap(text, text) is
+comment on function veil.init_bitmap(text, text) is
 'Create or re-initialise the Bitmap named BITMAP_NAME, for the range of
 bits given by RANGE_NAME.
 
@@ -112,12 +127,12 @@ All bits in the bitmap will be zero (cleared).';
 
 
 create or replace
-function veil_clear_bitmap(name text) returns bool
+function veil.clear_bitmap(bitmap_name text) returns bool
      as '@LIBPATH@', 'veil_clear_bitmap'
      language C stable strict;
 
-comment on function veil_clear_bitmap(text) is
-'Clear the Bitmap or BitmapRef identified by NAME.
+comment on function veil.clear_bitmap(text) is
+'Clear the Bitmap or BitmapRef identified by BITMAP_NAME.
 
 Return TRUE, or raise an error.
 
@@ -125,12 +140,12 @@ Clear (set to zero) all bits in the named bitmap.';
 
 
 create or replace
-function veil_bitmap_setbit(name text, bit_number int4) returns bool
+function veil.bitmap_setbit(bitmap_name text, bit_number int4) returns bool
      as '@LIBPATH@', 'veil_bitmap_setbit'
      language C stable strict;
 
-comment on function veil_bitmap_setbit(text, int4) is
-'In the Bitmap or BitmapRef identified by NAME, set the bit given by
+comment on function veil.bitmap_setbit(text, int4) is
+'In the Bitmap or BitmapRef identified by BITMAP_NAME, set the bit given by
 BIT_NUMBER.
 
 Return TRUE or raise an error.
@@ -139,12 +154,12 @@ Set to 1, the identified bit.';
 
 
 create or replace
-function veil_bitmap_clearbit(name text, bit_number int4) returns bool
+function veil.bitmap_clearbit(bitmap_name text, bit_number int4) returns bool
      as '@LIBPATH@', 'veil_bitmap_clearbit'
      language C stable strict;
 
-comment on function veil_bitmap_clearbit(text, int4) is
-'In the Bitmap or BitmapRef identified by NAME, clear the bit given by
+comment on function veil.bitmap_clearbit(text, int4) is
+'In the Bitmap or BitmapRef identified by BITMAP_NAME, clear the bit given by
 BIT_NUMBER.
 
 Return TRUE or raise an error.
@@ -153,72 +168,72 @@ Set to 0, the identified bit.';
 
 
 create or replace
-function veil_bitmap_testbit(name text, bit_number int4) returns bool
+function veil.bitmap_testbit(bitmap_name text, bit_number int4) returns bool
      as '@LIBPATH@', 'veil_bitmap_testbit'
      language C stable strict;
 
-comment on function veil_bitmap_testbit(text, int4) is
-'In the Bitmap or BitmapRef identified by NAME, test the bit given by
+comment on function veil.bitmap_testbit(text, int4) is
+'In the Bitmap or BitmapRef identified by BITMAP_NAME, test the bit given by
 BIT_NUMBER.
 
 Return TRUE if the bit is set, FALSE if it is zero.';
 
 
 create or replace
-function veil_bitmap_union(result_name text, name2 text) returns bool
+function veil.bitmap_union(result_name text, bm2_name text) returns bool
      as '@LIBPATH@', 'veil_bitmap_union'
      language C stable strict;
 
-comment on function veil_bitmap_union(text, text) is
-'Union two Bitmaps, RESULT_NAME and NAME2, with the result going into
+comment on function veil.bitmap_union(text, text) is
+'Union two Bitmaps, RESULT_NAME and BM2_NAME, with the result going into
 the first.
 
 Return TRUE, or raise an error.';
 
 
 create or replace
-function veil_bitmap_intersect(result_name text, name2 text) returns bool
+function veil.bitmap_intersect(result_name text, bm2_name text) returns bool
      as '@LIBPATH@', 
    'veil_bitmap_intersect'
      language C stable strict;
 
-comment on function veil_bitmap_intersect(text, text) is
-'Intersect two Bitmaps, RESULT_NAME and NAME2, with the result going into
+comment on function veil.bitmap_intersect(text, text) is
+'Intersect two Bitmaps, RESULT_NAME and B<2_NAME, with the result going into
 the first.
 
 Return TRUE, or raise an error.';
 
 
 create or replace
-function veil_bitmap_bits(name text) returns setof int4
+function veil.bitmap_bits(bitmap_name text) returns setof int4
      as '@LIBPATH@', 'veil_bitmap_bits'
      language C stable strict;
 
-comment on function veil_bitmap_bits(text) is
-'Return each bit in the bitmap NAME.
+comment on function veil.bitmap_bits(text) is
+'Return each bit in the bitmap BITMAP_NAME.
 
 This is primarily intended for interactive use for debugging, etc.';
 
 
 create or replace
-function veil_bitmap_range(name text) returns veil_range_t
+function veil.bitmap_range(bitmap_name text) returns veil.veil_range_t
      as '@LIBPATH@', 'veil_bitmap_range'
      language C stable strict;
 
-comment on function veil_bitmap_range(text) is
-'Return the range of bitmap NAME.  
+comment on function veil.bitmap_range(text) is
+'Return the range of bitmap BITMAP_NAME.  
 
 It is primarily intended for interactive use.';
 
 
 
 create or replace
-function veil_init_bitmap_array(bmarray text, array_range text, 
+function veil.init_bitmap_array(bmarray text, array_range text, 
                bitmap_range text) returns bool
      as '@LIBPATH@', 'veil_init_bitmap_array'
      language C stable strict;
 
-comment on function veil_init_bitmap_array(text, text, text) is
+comment on function veil.init_bitmap_array(text, text, text) is
 'Creates or resets (clears) BMARRAY, to have ARRAY_RANGE bitmaps of
 BITMAP_RANGE bits.
 
@@ -226,25 +241,25 @@ Returns TRUE or raises an error';
 
 
 create or replace
-function veil_clear_bitmap_array(bmarray text) returns bool
+function veil.clear_bitmap_array(bmarray text) returns bool
      as '@LIBPATH@', 'veil_clear_bitmap_array'
      language C stable strict;
 
-comment on function veil_clear_bitmap_array(text) is
+comment on function veil.clear_bitmap_array(text) is
 'Clear all bits in all bitmaps of bitmap array BMARRAY.
 
 Return TRUE or raise an error';
 
 
 create or replace
-function veil_bitmap_from_array(bmref text, bmarray text, 
+function veil.bitmap_from_array(bmref_name text, bmarray text, 
                index int4) returns text
      as '@LIBPATH@', 
    'veil_bitmap_from_array'
      language C stable strict;
 
-comment on function veil_bitmap_from_array(text, text, int4) is
-'Set BitmapRef BMREF to the bitmap from BMARRAY indexed by INDEX.
+comment on function veil.bitmap_from_array(text, text, int4) is
+'Set BitmapRef BMREF_NAME to the bitmap from BMARRAY indexed by INDEX.
 
 Return the name of the BitmapRef.
 
@@ -255,13 +270,13 @@ the transaction they are defined.';
 
 
 create or replace
-function veil_bitmap_array_testbit(
+function veil.bitmap_array_testbit(
     bmarray text, arr_idx int4, bitno int4) returns bool
      as '@LIBPATH@', 
    'veil_bitmap_array_testbit'
      language C stable strict;
 
-comment on function veil_bitmap_array_testbit(text, int4, int4) is
+comment on function veil.bitmap_array_testbit(text, int4, int4) is
 'Test a bit in BMARRAY, from the bitmap indexed by ARR_IDX, checking the
 bit identified by BITNO.
 
@@ -269,13 +284,13 @@ Return TRUE if the bit is set, else FALSE';
 
 
 create or replace
-function veil_bitmap_array_setbit(
+function veil.bitmap_array_setbit(
     bmarray text, arr_idx int4, bitno int4) returns bool
      as '@LIBPATH@', 
    'veil_bitmap_array_setbit'
      language C stable strict;
 
-comment on function veil_bitmap_array_setbit(text, int4, int4) is
+comment on function veil.bitmap_array_setbit(text, int4, int4) is
 'Set a bit in BMARRAY, from the bitmap indexed by ARR_IDX, setting the
 bit identified by BITNO.
 
@@ -283,13 +298,13 @@ Return TRUE';
 
 
 create or replace
-function veil_bitmap_array_clearbit(
+function veil.bitmap_array_clearbit(
     bmarray text, arr_idx int4, bitno int4) returns bool
      as '@LIBPATH@', 
    'veil_bitmap_array_clearbit'
      language C stable strict;
 
-comment on function veil_bitmap_array_clearbit(text, int4, int4) is
+comment on function veil.bitmap_array_clearbit(text, int4, int4) is
 'Clear a bit in BMARRAY, from the bitmap indexed by ARR_IDX, clearing the
 bit identified by BITNO.
 
@@ -297,70 +312,70 @@ Return TRUE';
 
 
 create or replace
-function veil_union_from_bitmap_array(
+function veil.union_from_bitmap_array(
     bitmap text, bmarray text, arr_idx int4) returns bool
      as '@LIBPATH@', 
    'veil_union_from_bitmap_array'
      language C stable strict;
 
-comment on function veil_union_from_bitmap_array(text, text, int4) is
+comment on function veil.union_from_bitmap_array(text, text, int4) is
 'Union BITMAP with BMARRAY[ARR_IDX], with the result going into bitmap.
 
 Return TRUE';
 
 
 create or replace
-function veil_intersect_from_bitmap_array(
+function veil.intersect_from_bitmap_array(
     bitmap text, bmarray text, arr_idx int4) returns bool
      as '@LIBPATH@', 
    'veil_intersect_from_bitmap_array'
      language C stable strict;
 
-comment on function veil_intersect_from_bitmap_array(text, text, int4) is
+comment on function veil.intersect_from_bitmap_array(text, text, int4) is
 'Intersect BITMAP with BMARRAY[ARR_IDX], with the result going into bitmap.
 
 Return TRUE';
 
 
 create or replace
-function veil_bitmap_array_bits(bmarray text, arr_idx int4) returns setof int4
+function veil.bitmap_array_bits(bmarray text, arr_idx int4) returns setof int4
      as '@LIBPATH@', 
    'veil_bitmap_array_bits'
      language C stable strict;
 
-comment on function veil_bitmap_array_bits(text, int4) is
+comment on function veil.bitmap_array_bits(text, int4) is
 'Return all bits in the bitmap given by BMARRAY[ARR_IDX].
 
 This is primarily intended for interactive use: for debugging, etc.';
 
 
 create or replace
-function veil_bitmap_array_arange(bmarray text) returns veil_range_t
+function veil.bitmap_array_arange(bmarray text) returns veil.veil_range_t
      as '@LIBPATH@', 
    'veil_bitmap_array_arange'
      language C stable strict;
 
-comment on function veil_bitmap_array_arange(text) is
+comment on function veil.bitmap_array_arange(text) is
 'Return the array bounds for BMARRAY.';
 
 
 create or replace
-function veil_bitmap_array_brange(bmarray text) returns veil_range_t
+function veil.bitmap_array_brange(bmarray text) returns veil.veil_range_t
      as '@LIBPATH@', 
    'veil_bitmap_array_brange'
      language C stable strict;
 
-comment on function veil_bitmap_array_brange(text) is
+comment on function veil.bitmap_array_brange(text) is
 'Return the range of the bitmaps in BMARRAY.';
 
 
 
 create or replace
-function veil_init_bitmap_hash(bmhash text, range text) returns bool
+function veil.init_bitmap_hash(bmhash text, range text) returns bool
      as '@LIBPATH@', 'veil_init_bitmap_hash'
      language C stable strict;
 
-comment on function veil_init_bitmap_hash(text, text) is
+comment on function veil.init_bitmap_hash(text, text) is
 'Initialise a bitmap hash variable called BMHASH to contain bitmaps of
 size RANGE.
 
@@ -368,47 +383,47 @@ Return TRUE.';
 
 
 create or replace
-function veil_clear_bitmap_hash(bmhash text) returns bool
+function veil.clear_bitmap_hash(bmhash text) returns bool
      as '@LIBPATH@', 'veil_clear_bitmap_hash'
      language C stable strict;
 
-comment on function veil_clear_bitmap_hash(text) is
+comment on function veil.clear_bitmap_hash(text) is
 'Clear all bits in an existing bitmap hash named BMHASH.
 
 Return TRUE.';
 
 
 create or replace
-function veil_bitmap_hash_key_exists(bmhash text, key text) returns bool
+function veil.bitmap_hash_key_exists(bmhash text, key text) returns bool
      as '@LIBPATH@', 
    'veil_bitmap_hash_key_exists'
      language C stable strict;
 
-comment on function veil_bitmap_hash_key_exists(text, text) is
+comment on function veil.bitmap_hash_key_exists(text, text) is
 'Determine whether in BMHASH the given KEY already exists.
 
 Return TRUE if the key exists, else FALSE.';
 
 
 create or replace
-function veil_bitmap_from_hash(text, text, text) returns text
+function veil.bitmap_from_hash(bmref text, bmhash text, key text) returns text
      as '@LIBPATH@', 
    'veil_bitmap_from_hash'
      language C stable strict;
 
-comment on function veil_bitmap_from_hash(text, text, text) is
+comment on function veil.bitmap_from_hash(text, text, text) is
 'Set BitmapRef BMREF to the bitmap from BMHASH identfied by KEY.
 
 Return the name of BMREF.';
 
 
 create or replace
-function veil_bitmap_hash_testbit(text, text, int4) returns bool
+function veil.bitmap_hash_testbit(bmhash text, key text, bitno int4) returns bool
      as '@LIBPATH@', 
    'veil_bitmap_hash_testbit'
      language C stable strict;
 
-comment on function veil_bitmap_hash_testbit(text, text, int4) is
+comment on function veil.bitmap_hash_testbit(text, text, int4) is
 'Test the bit, in the bitmap from BMHASH identified by KEY, given by
 BITNO.
 
@@ -416,12 +431,12 @@ Return TRUE if the bit is set, else FALSE.';
 
 
 create or replace
-function veil_bitmap_hash_setbit(text, text, int4) returns bool
+function veil.bitmap_hash_setbit(bmhash text, key text, bitno int4) returns bool
      as '@LIBPATH@', 
    'veil_bitmap_hash_setbit'
      language C stable strict;
 
-comment on function veil_bitmap_hash_setbit(text, text, int4) is
+comment on function veil.bitmap_hash_setbit(text, text, int4) is
 'Set the bit, in the bitmap from BMHASH identified by KEY, given by
 BITNO to TRUE.
 
@@ -429,12 +444,12 @@ Return TRUE.';
 
 
 create or replace
-function veil_bitmap_hash_clearbit(text, text, int4) returns bool
+function veil.bitmap_hash_clearbit(bmhash text, key text, bitno int4) returns bool
      as '@LIBPATH@', 
    'veil_bitmap_hash_clearbit'
      language C stable strict;
 
-comment on function veil_bitmap_hash_clearbit(text, text, int4) is
+comment on function veil.bitmap_hash_clearbit(text, text, int4) is
 'Set the bit, in the bitmap from BMHASH identified by KEY, given by
 BITNO to FALSE.
 
@@ -442,12 +457,12 @@ Return TRUE.';
 
 
 create or replace
-function veil_union_into_bitmap_hash(text, text, text) returns bool
+function veil.union_into_bitmap_hash(bmhash text, key text, bitmap text) returns bool
      as '@LIBPATH@', 
    'veil_union_into_bitmap_hash'
      language C stable strict;
 
-comment on function veil_union_into_bitmap_hash(text, text, text) is
+comment on function veil.union_into_bitmap_hash(text, text, text) is
 'Into the bitmap from BMHASH, identified by KEY, and union the bits from
 BITMAP (which may be a bitmap or bitmap_ref).
 
@@ -455,11 +470,11 @@ Return TRUE.';
 
 
 create or replace
-function veil_union_from_bitmap_hash(text, text, text) returns bool
+function veil.union_from_bitmap_hash(bmhash text, key text, bitmap text) returns bool
      as '@LIBPATH@', 
    'veil_union_from_bitmap_hash'
      language C stable strict;
-comment on function veil_union_from_bitmap_hash(text, text, text) is
+comment on function veil.union_from_bitmap_hash(text, text, text) is
 'Retrieve the bitmap from BMHASH, identified by KEY, and union it into
 BITMAP (which may be a bitmap or bitmap_ref).
 
@@ -467,11 +482,11 @@ Return TRUE.';
 
 
 create or replace
-function veil_intersect_from_bitmap_hash(text, text, text) returns bool
+function veil.intersect_from_bitmap_hash(bitmap text, bmhash text, key text) returns bool
      as '@LIBPATH@', 
    'veil_intersect_from_bitmap_hash'
      language C stable strict;
-comment on function veil_intersect_from_bitmap_hash(text, text, text) is
+comment on function veil.intersect_from_bitmap_hash(text, text, text) is
 'Into BITMAP, intersect the bits from the bitmap in BMHASH identified by
 KEY.
 
@@ -479,63 +494,63 @@ Return TRUE.';
 
 
 create or replace
-function veil_bitmap_hash_bits(text, text) returns setof int4
+function veil.bitmap_hash_bits(bmhash text, key text) returns setof int4
      as '@LIBPATH@', 
    'veil_bitmap_hash_bits'
      language C stable strict;
 
-comment on function veil_bitmap_hash_bits(text, text) is
+comment on function veil.bitmap_hash_bits(text, text) is
 'Return the set of bits in the bitset from BMHASH identfied by KEY.';
 
 
 create or replace
-function veil_bitmap_hash_range(text) returns veil_range_t
+function veil.bitmap_hash_range(bmhash text) returns veil.veil_range_t
      as '@LIBPATH@', 
    'veil_bitmap_hash_range'
      language C stable strict;
 
-comment on function veil_bitmap_hash_range(text) is
+comment on function veil.bitmap_hash_range(text) is
 'Return the range of all bitmaps in BMHASH.';
 
 
 create or replace
-function veil_bitmap_hash_entries(text) returns setof text
+function veil.bitmap_hash_entries(bmhash text) returns setof text
      as '@LIBPATH@', 
    'veil_bitmap_hash_entries'
      language C stable strict;
 
-comment on function veil_bitmap_hash_entries(text) is
+comment on function veil.bitmap_hash_entries(text) is
 'Return the keys of all bitmaps in BMHASH.';
 
 
 create or replace
-function veil_int4_set(text, int4) returns int4
+function veil.int4_set(name text, value int4) returns int4
      as '@LIBPATH@', 
    'veil_int4_set'
      language C stable;
 
-comment on function veil_int4_set(text, int4) is
+comment on function veil.int4_set(text, int4) is
 'Set the int4 variable NAME to VALUE.
 
 Return the new value';
 
 
 create or replace
-function veil_int4_get(text) returns int4
+function veil.int4_get(name text) returns int4
      as '@LIBPATH@', 
    'veil_int4_get'
      language C stable strict;
 
-comment on function veil_int4_get(text) is
+comment on function veil.int4_get(text) is
 'Return the value of int4 variable NAME.';
 
 
 create or replace
-function veil_init_int4array(text, text) returns bool
+function veil.init_int4array(arrayname text, range text) returns bool
      as '@LIBPATH@', 'veil_init_int4array'
      language C stable strict;
 
-comment on function veil_init_int4array(text, text) is
+comment on function veil.init_int4array(text, text) is
 'Initialise the int4 array ARRAYNAME, with an index range of RANGE.
 
 Each entry in the array is set to zero.
@@ -544,11 +559,11 @@ Return TRUE.';
 
 
 create or replace
-function veil_clear_int4array(text) returns bool
+function veil.clear_int4array(arrayname text) returns bool
      as '@LIBPATH@', 
    'veil_clear_int4array'
      language C stable strict;
-comment on function veil_clear_int4array(text) is
+comment on function veil.clear_int4array(text) is
 'Reset each entry in the int4 array ARRAYNAME to zero.
 
 Return TRUE.';
@@ -556,44 +571,45 @@ Return TRUE.';
 
 
 create or replace
-function veil_int4array_set(text, int4, int4) returns int4
+function veil.int4array_set(arrayname text, idx int4, value int4) returns int4
      as '@LIBPATH@', 
    'veil_int4array_set'
      language C stable;
 
-comment on function veil_int4array_set(text, int4, int4) is
-'Set the ARRAY element IDX to VALUE.
+comment on function veil.int4array_set(text, int4, int4) is
+'Set the ARRAYNAME element IDX to VALUE.
 
 Return the new value.';
 
 
 create or replace
-function veil_int4array_get(text, int4) returns int4
+function veil.int4array_get(arrayname text, idx int4) returns int4
      as '@LIBPATH@', 
    'veil_int4array_get'
      language C stable strict;
 
-comment on function veil_int4array_get(text, int4) is
-'Return the value of ARRAY element IDX.';
+comment on function veil.int4array_get(text, int4) is
+'Return the value of ARRAYNAME element IDX.';
 
 
 create or replace
-function veil_init(bool) returns bool 
+function veil.veil_init(doing_reset bool) returns bool 
      as '@LIBPATH@', 
    'veil_init'
      language C stable strict;
 
-comment on function veil_init(bool) is
-'This is the default version of veil_init, which does nothing except
-raise an error.';
+comment on function veil.veil_init(bool) is
+'This calls all registered init functions, passing the DOING_RESET
+parameter to them, in priority order.  If there are no registered
+functions, an exception is raised.';
 
 
 create or replace
-function veil_perform_reset() returns bool
+function veil.veil_perform_reset() returns bool
      as '@LIBPATH@', 'veil_perform_reset'
      language C stable;
 
-comment on function veil_perform_reset() is
+comment on function veil.veil_perform_reset() is
 'Allow userspace to force call of veil_init.
 
 This function may fail due to outstanding transactions possibly holding
@@ -605,33 +621,34 @@ Return TRUE if successful, FALSE otherwise.';
 
 
 create or replace
-function veil_force_reset() returns bool
+function veil.veil_force_reset() returns bool
      as '@LIBPATH@', 'veil_force_reset'
      language C stable;
 
-comment on function veil_force_reset() is
+comment on function veil.veil_force_reset() is
 'Allow userspace to force an unconditional reset of veil shared memory.
 
 This always causes a PANIC, causing the database to fully reset.';
 
 
+
 create or replace
-function veil_version() returns text
+function veil.version() returns text
      as '@LIBPATH@', 'veil_version'
      language C stable;
 
-comment on function veil_version() is
+comment on function veil.version() is
 'Return a text string identifying the current veil version.';
 
 
 
 create or replace
-function veil_serialise(varname text) returns text
+function veil.serialise(varname text) returns text
      as '@LIBPATH@', 
    'veil_serialise'
      language C stable strict;
 
-comment on function veil_serialise(varname text) is
+comment on function veil.serialise(varname text) is
 'Return a serialised copy of a variable VARNAME in text form.
 
 This is intended to be used with pgmemcache so that session variables
@@ -643,12 +660,12 @@ The value can be restored by de-serialising it.';
 
 
 create or replace
-function veil_serialize(text) returns text
+function veil.serialize(varname text) returns text
      as '@LIBPATH@', 
    'veil_serialise'
      language C stable strict;
 
-comment on function veil_serialize(varname text) is
+comment on function veil.serialize(varname text) is
 'Return a serialised copy of a variable VARNAME in text form.
 
 This is intended to be used with pgmemcache so that session variables
@@ -660,12 +677,12 @@ The value can be restored by de-serializing it.';
 
 
 create or replace
-function veil_deserialise(text) returns int4
+function veil.deserialise(stream text) returns int4
      as '@LIBPATH@', 
    'veil_deserialise'
      language C stable strict;
 
-comment on function veil_deserialise(text) is
+comment on function veil.deserialise(text) is
 'Reset the contents of a set of serialised variable from STREAM.
 
 Return the number of items de-serialised.';
@@ -673,77 +690,79 @@ Return the number of items de-serialised.';
 
 -- Ditto for victims of webster.
 create or replace
-function veil_deserialize(text) returns int4
+function veil.deserialize(stream text) returns int4
      as '@LIBPATH@', 
    'veil_deserialise'
      language C stable strict;
 
-comment on function veil_deserialize(text) is
+comment on function veil.deserialize(text) is
 'Reset the contents of a set of serialized variable from STREAM.
 
 Return the number of items de-serialized.';
 
 
-revoke execute on function veil_share(text) from public;
-revoke execute on function veil_variables() from public;
-revoke execute on function veil_init_range(text, int4,int4) from public;
-revoke execute on function veil_range(text) from public;
+revoke execute on function veil.share(text) from public;
+revoke execute on function veil.veil_variables() from public;
+revoke execute on function veil.init_range(text, int4, int4) from public;
+revoke execute on function veil.range(text) from public;
 
-revoke execute on function veil_init_bitmap(text, text) from public;
-revoke execute on function veil_clear_bitmap(text) from public;
-revoke execute on function veil_bitmap_setbit(text, int4) from public;
-revoke execute on function veil_bitmap_testbit(text, int4) from public;
-revoke execute on function veil_bitmap_bits(text) from public;
-revoke execute on function veil_bitmap_range(text) from public;
+revoke execute on function veil.init_bitmap(text, text) from public;
+revoke execute on function veil.clear_bitmap(text) from public;
+revoke execute on function veil.bitmap_setbit(text, int4) from public;
+revoke execute on function veil.bitmap_testbit(text, int4) from public;
+revoke execute on function veil.bitmap_bits(text) from public;
+revoke execute on function veil.bitmap_range(text) from public;
 
-revoke execute on function veil_init_bitmap_array(text, text, text)
+revoke execute on function veil.init_bitmap_array(text, text, text)
   from public;
-revoke execute on function veil_clear_bitmap_array(text) from public;
-revoke execute on function veil_bitmap_from_array(text, text, int4)
+revoke execute on function veil.clear_bitmap_array(text) from public;
+revoke execute on function veil.bitmap_from_array(text, text, int4)
   from public;
-revoke execute on function veil_bitmap_array_setbit(text, int4, int4)
+revoke execute on function veil.bitmap_array_setbit(text, int4, int4)
   from public;
-revoke execute on function veil_bitmap_array_testbit(text, int4, int4)
+revoke execute on function veil.bitmap_array_testbit(text, int4, int4)
   from public;
-revoke execute on function veil_union_from_bitmap_array(text, text, int4)
+revoke execute on function veil.union_from_bitmap_array(text, text, int4)
   from public;
-revoke execute on function veil_intersect_from_bitmap_array(text, text, int4)
+revoke execute on function veil.intersect_from_bitmap_array(text, text, int4)
   from public;
-revoke execute on function veil_bitmap_array_bits(text, int4) from public;
-revoke execute on function veil_bitmap_array_arange(text) from public;
-revoke execute on function veil_bitmap_array_brange(text) from public;
+revoke execute on function veil.bitmap_array_bits(text, int4) from public;
+revoke execute on function veil.bitmap_array_arange(text) from public;
+revoke execute on function veil.bitmap_array_brange(text) from public;
 
 
-revoke execute on function veil_init_bitmap_hash(text, text) from public;
-revoke execute on function veil_clear_bitmap_hash(text) from public;
-revoke execute on function veil_bitmap_hash_key_exists(text, text)
+revoke execute on function veil.init_bitmap_hash(text, text) from public;
+revoke execute on function veil.clear_bitmap_hash(text) from public;
+revoke execute on function veil.bitmap_hash_key_exists(text, text)
   from public;
-revoke execute on function veil_bitmap_from_hash(text, text, text)
+revoke execute on function veil.bitmap_from_hash(text, text, text)
   from public;
-revoke execute on function veil_bitmap_hash_setbit(text, text, int4)
+revoke execute on function veil.bitmap_hash_setbit(text, text, int4)
   from public;
-revoke execute on function veil_bitmap_hash_testbit(text, text, int4)
+revoke execute on function veil.bitmap_hash_testbit(text, text, int4)
   from public;
-revoke execute on function veil_union_into_bitmap_hash(text, text, text)
+revoke execute on function veil.union_into_bitmap_hash(text, text, text)
   from public;
-revoke execute on function veil_union_from_bitmap_hash(text, text, text)
+revoke execute on function veil.union_from_bitmap_hash(text, text, text)
   from public;
-revoke execute on function veil_intersect_from_bitmap_hash(text, text, text)
+revoke execute on function veil.intersect_from_bitmap_hash(text, text, text)
   from public;
-revoke execute on function veil_bitmap_hash_bits(text, text) from public;
-revoke execute on function veil_bitmap_hash_range(text) from public;
-revoke execute on function veil_bitmap_hash_entries(text) from public;
-
-revoke execute on function veil_init_int4array(text, text) from public;
-revoke execute on function veil_clear_int4array(text) from public;
-revoke execute on function veil_int4array_set(text, int4, int4) from public;
-revoke execute on function veil_int4array_get(text, int4) from public;
-
-revoke execute on function veil_init(bool) from public;
-
-revoke execute on function veil_serialise(text) from public;
-revoke execute on function veil_serialize(text) from public;
-revoke execute on function veil_deserialise(text) from public;
-revoke execute on function veil_deserialize(text) from public;
+revoke execute on function veil.bitmap_hash_bits(text, text) from public;
+revoke execute on function veil.bitmap_hash_range(text) from public;
+revoke execute on function veil.bitmap_hash_entries(text) from public;
+
+revoke execute on function veil.init_int4array(text, text) from public;
+revoke execute on function veil.clear_int4array(text) from public;
+revoke execute on function veil.int4array_set(text, int4, int4) from public;
+revoke execute on function veil.int4array_get(text, int4) from public;
+
+revoke execute on function veil.veil_init(bool) from public;
+revoke execute on function veil.veil_perform_reset() from public;
+revoke execute on function veil.veil_force_reset() from public;
+
+revoke execute on function veil.serialise(text) from public;
+revoke execute on function veil.serialize(text) from public;
+revoke execute on function veil.deserialise(text) from public;
+revoke execute on function veil.deserialize(text) from public;
 
 
index 0f2f715fa58594663cfa6305c222506ac0550b5d..12d3018fa58db133db8229e5786bad3d66aeb8b2 100644 (file)
@@ -11,7 +11,7 @@
 
 
 /*! \mainpage Veil
-\version 1.0.0 (Stable))
+\version 9.1.0 (Stable))
 \section license License
 BSD
 \section intro_sec Introduction
@@ -69,13 +69,13 @@ As an example let's assume that we have a secured view, users, that
 allows a user to see only their own record.  When Alice queries the
 view, she will see this:
 
-\code
+\verbatim
 select * from users;
 
   userid  |   username
 ----------+-----------
    12345  |   Alice
-\endcode
+\endverbatim
 
 Alice should not be able to see any details for Bob or even, strictly
 speaking, tell whether there is an entry for Bob.  This query though:
@@ -107,7 +107,7 @@ the where clause, if the function is deemed inexpensive enough, will see
 every row in the table and so will be able to leak supposedly protected
 data.  This type of exploit can be protected against easily enough by
 preventing users from defining their own functions, however there are
-postgres' builtins that can be potentially be exploited in the same way.
+postgres builtins that can be potentially be exploited in the same way.
 
 \subsection GoodNews The Good News
 
@@ -159,12 +159,10 @@ create table persons (
 The secured view would be defined something like this:
 \verbatim
 create view persons(
-       person_id,
-       person_name) as
-select person_id,
-       person_name
-from   persons
-where  i_have_personal_priv(10013, person_id);
+       person_id, person_name) as
+select person_id, person_name
+  from persons
+ where i_have_personal_priv(10013, person_id);
 \endverbatim
 
 A query performed on the view will return rows only for those persons
@@ -269,7 +267,7 @@ given context.  There are three types of security context:
    data about a staff member.  Note that determining a user's access
    rights in a relational context may require extra queries to be
    performed for each function call.  Your design should aim to minimise
-   this.  Some applications may require a number of distinct relational 
+   this.  Some applications may require several distinct relational 
    contexts.
 
 \subsection over-funcs2 Access Functions and Security Contexts
@@ -374,6 +372,8 @@ sections
 - \subpage API-serialisation
 - \subpage API-control
 
+Note that all veil objects are placed in the veil schema.
+
 \section API-intro Veil API Overview
 Veil is an API that simply provides a set of state variable types, and 
 operations on those variable types, which are optimised for privilege
@@ -409,8 +409,8 @@ Shared variables are global across all sessions.  Once a shared variable
 is defined, all sessions will have access to it.  Shared variables are
 defined in two steps.  First, the variable is defined as shared, and
 then it is initialised and accessed in the same way as for session
-variables.  Note that shared variables should only be modified within
-the function veil_init().
+variables.  Note that shared variables should only be created within
+\ref API-control-registered-init or \ref API-control-init.
 
 Note that bitmap refs and bitmap hashes may not be stored in shared
 variables.
@@ -434,28 +434,30 @@ Note again that session variables are created on usage.  Their is no
 specific function for creating a variable in the variables API.  For an
 example of a function to create a variable see \ref API-bitmap-init.
 
-\section API-variables-share veil_share(name text)
-\code
-function veil_share(name text) returns bool
-\endcode
+\section API-variables-share share(name text)
+\verbatim
+function veil.share(name text) returns bool
+\endverbatim
 
-This is used to define a specific variable as being shared.  A shared
-variable is accessible to all sessions and exists to reduce the need for
-multiple copies of identical data.  For instance in the Veil demo,
-role_privileges are recorded in a shared variable as they will be
-identical for all sessions, and to create a copy for each session  would
-be an unnecessary overhead.  This function should only be called from
-veil_init().
+Implemented by C function veil_share(), this is used to define a
+specific variable as being shared.  A shared variable is accessible to
+all sessions and exists to reduce the need for multiple copies of
+identical data.  For instance in the Veil demo, role_privileges are
+recorded in a shared variable as they will be identical for all
+sessions, and to create a copy for each session would be an unnecessary
+overhead.  This function should only be called from 
+\ref API-control-registered-init or \ref API-control-init. 
 
 \section API-variables-var veil_variables()
-\code
-function veil_variables() returns setof veil_variable_t
-\endcode
+\verbatim
+function veil.veil_variables() returns setof veil_variable_t
+\endverbatim
 
-This function returns a description for each variable known to the
-session.  It provides the name, the type, and whether the variable is
-shared.  It is primarily intended for interactive use when developing
-and debugging Veil-based systems.
+This function, implemented by C function veil_variables(), returns a
+description for each variable known to the session.  It provides the
+name, the type, and whether the variable is shared.  It is primarily
+intended for interactive use when developing and debugging Veil-based
+systems.
 
 Next: \ref API-simple
 */
@@ -464,8 +466,20 @@ Next: \ref API-simple
 Veil's basic types are those that do not contain repeating groups
 (arrays, hashes, etc).  
 
-Ranges consist of a pair of values and are generally used to initialise
-the bounds of array and bitmap types.  Ranges may not contain nulls.
+Ranges, implemented by the type \ref veil_range_t,
+consist of a pair of values and are generally used to initialise the
+bounds of array and bitmap types.
+
+\anchor veil_range_t \ref veil_range_t is defined as:
+
+\verbatim
+create type veil.veil_range_t as (
+    min  int4,
+    max  int4
+);
+\endverbatim
+
+Ranges may not contain nulls.
 
 The int4 type is used to record a simple nullable integer.  This is
 typically used to record the id of the connected user in a session.
@@ -477,34 +491,37 @@ The following functions comprise the Veil basic types API:
 - <code>\ref API-basic-int4-set</code>
 - <code>\ref API-basic-int4-get</code>
 
-\section API-basic-init-range veil_init_range(name text, min int4, max int4)
-\code
-function veil_init_range(name text, min int4, max int4) returns int4
-\endcode
+\section API-basic-init-range init_range(name text, min int4, max int4)
+\verbatim
+function veil.init_range(name text, min int4, max int4) returns int4
+\endverbatim
 
-This defines a range, and returns the extent of that range.
+This, implemented by veil_init_range() defines a range, and returns the
+extent of that range.
 
-\section API-basic-range veil_range(name text)
-\code
-function veil_range(name text) returns veil_range_t
-\endcode
+\section API-basic-range range(name text)
+\verbatim
+function veil.range(name text) returns veil.range_t
+\endverbatim
 
-This returns the contents of a range.  It is intended primarily for
-interactive use.
+This, implemented by C function veil_range() returns the contents
+of a range.  It is intended primarily for interactive use.
 
-\section API-basic-int4-set veil_int4_set(text, int4)
-\code
-function veil_int4_set(text, int4) returns int4
-\endcode
+\section API-basic-int4-set int4_set(name text, value int4)
+\verbatim
+function veil.int4_set(name text, value int4) returns int4
+\endverbatim
 
-Sets an int4 variable to a value, returning that same value.
+Sets an int4 variable to a value, returning that same value.  It is
+implemented by C function veil_int4_set().
 
-\section API-basic-int4-get veil_int4_get(text)
-\code
-function veil_int4_get(text) returns int4
-\endcode
+\section API-basic-int4-get int4_get(name text)
+\verbatim
+function veil.int4_get(name text) returns int4
+\endverbatim
 
-Returns the value of an int4 variable.
+Returns the value of the int4 variable given by name.  Implemented by C
+function veil_int4_get().
 
 
 Next: \ref API-bitmaps
@@ -536,64 +553,74 @@ The following functions comprise the Veil bitmaps API:
 - <code>\ref API-bitmap-bits</code>
 - <code>\ref API-bitmap-range</code>
 
-\section API-bitmap-init veil_init_bitmap(bitmap_name text, range_name text)
-\code
-function veil_init_bitmap(bitmap_name text, range_name text) returns bool
-\endcode
+\section API-bitmap-init init_bitmap(bitmap_name text, range_name text)
+\verbatim
+function veil.init_bitmap(bitmap_name text, range_name text) returns bool
+\endverbatim
 This is used to create or resize a bitmap.  The first parameter provides
 the name of the bitmap, the second is the name of a range variable that
-will govern the size of the bitmap.
+will govern the size of the bitmap.  It is implemented by C function
+veil_init_bitmap().
 
-\section API-bitmap-clear veil_clear_bitmap(name text)
-\code
-function veil_clear_bitmap(name text) returns bool
-\endcode
-This is used to clear (set to zero) all bits in the bitmap.
+\section API-bitmap-clear clear_bitmap(bitmap_name text)
+\verbatim
+function veil.clear_bitmap(bitmap_name text) returns bool
+\endverbatim
+This is used to clear (set to zero) all bits in the bitmap.  It is
+implemented by C function veil_clear_bitmap().
 
-\section API-bitmap-setbit veil_bitmap_setbit(name text, bit_number int4)
-\code
-function veil_bitmap_setbit(text, int4) returns bool
-\endcode
-This is used to set a specified bit in a bitmap.
+\section API-bitmap-setbit bitmap_setbit(bitmap_name text, bit_number int4)
+\verbatim
+function veil.bitmap_setbit(bitmap_name text, bit_number int4) returns bool
+\endverbatim
+This is used to set a specified bit, given by bit_number in the bitmap
+identified by bitmap_name.  It is implemented by C function
+veil_bitmap_setbit().
 
-\section API-bitmap-clearbit veil_bitmap_clearbit(name text, bit_number int4)
-\code
-function veil_bitmap_clearbit(name text, bit_number int4) returns bool
-\endcode
-This is used to clear (set to zero) a specified bit in a bitmap.
+\section API-bitmap-clearbit bitmap_clearbit(bitmap_name text, bit_number int4)
+\verbatim
+function veil.bitmap_clearbit(bitmap_name text, bit_number int4) returns bool
+\endverbatim
+This is used to clear (set to zero) a specified bit in a bitmap.  It is
+implemented by C function veil_bitmap_clearbit().
 
-\section API-bitmap-testbit veil_bitmap_testbit(name text, bit_number int4)
-\code
-function veil_bitmap_testbit(name text, bit_number int4) returns bool
-\endcode
+\section API-bitmap-testbit bitmap_testbit(bitmap_name text, bit_number int4)
+\verbatim
+function veil.bitmap_testbit(bitmap_name text, bit_number int4) returns bool
+\endverbatim
 This is used to test a specified bit in a bitmap.  It returns true if
-the bit is set, false otherwise.
+the bit is set, false otherwise.  It is implemented by C function
+veil_bitmap_testbit().
 
-\section API-bitmap-union veil_bitmap_union(result_name text, name2 text)
-\code
-function veil_bitmap_union(result_name text, name2 text) returns bool
-\endcode
+\section API-bitmap-union bitmap_union(result_name text, bm2_name text)
+\verbatim
+function veil.bitmap_union(result_name text, bm2_name text) returns bool
+\endverbatim
 Form the union of two bitmaps with the result going into the first.
+Implemented by C function veil_bitmap_union().
 
-\section API-bitmap-intersect veil_bitmap_intersect(result_name text, name2 text)
-\code
-function veil_bitmap_intersect(result_name text, name2 text) returns bool
-\endcode
-Form the intersection of two bitmaps with the result going into the first.
+\section API-bitmap-intersect bitmap_intersect(result_name text, bm2_name text)
+\verbatim
+function veil.bitmap_intersect(result_name text, bm2_name text) returns bool
+\endverbatim
+Form the intersection of two bitmaps with the result going into the
+first.  Implemented by C function veil_bitmap_intersect().
 
-\section API-bitmap-bits veil_bitmap_bits(name text)
-\code
-function veil_bitmap_bits(name text) returns setof int4
-\endcode
+\section API-bitmap-bits bitmap_bits(bitmap_name text)
+\verbatim
+function veil.bitmap_bits(bitmap_name text) returns setof int4
+\endverbatim
 This is used to list all bits set within a bitmap.  It is primarily for
 interactive use during development and debugging of Veil-based systems.
+It is implemented by C function veil_bitmap_bits().
 
-\section API-bitmap-range veil_bitmap_range(name text)
-\code
-function veil_bitmap_range(name text) returns veil_range_t
-\endcode
-This returns the range of a bitmap.  It is primarily intended for
-interactive use.
+\section API-bitmap-range bitmap_range(bitmap_name text)
+\verbatim
+function veil.bitmap_range(bitmap_name text) returns veil.range_t
+\endverbatim
+This returns the range, as a \ref veil_range_t, of a
+bitmap.  It is primarily intended for interactive use.  It is
+implemented by C function veil_bitmap_range().
 
 Next: \ref API-bitmap-arrays
 */
@@ -620,85 +647,100 @@ The following functions comprise the Veil bitmap arrays API:
 - <code>\ref API-bmarray-arange</code>
 - <code>\ref API-bmarray-brange</code>
 
-\section API-bmarray-init veil_init_bitmap_array(bmarray text, array_range text, bitmap_range text)
-\code
-function veil_init_bitmap_array(bmarray text, array_range text, bitmap_range text) returns bool
-\endcode
-Creates or resets (clears) a bitmap array.
+\section API-bmarray-init init_bitmap_array(bmarray text, array_range text, bitmap_range text)
+\verbatim
+function veil.init_bitmap_array(bmarray text, array_range text, bitmap_range text) returns bool
+\endverbatim
+Creates or resets (clears) the bitmap array named <code>bmarray</code>.
+The last two parameters are the names of ranges used to bound the
+dimensions of the array, and the range of bits within the array's
+bitmaps.  Implemented by C function veil_init_bitmap_array().
 
-\section API-bmarray-clear veil_clear_bitmap_array(bmarray text)
-\code
-function veil_clear_bitmap_array(bmarray text) returns bool
-\endcode
-Clear all bits in all bitmaps of a bitmap array
+\section API-bmarray-clear clear_bitmap_array(bmarray text)
+\verbatim
+function veil.clear_bitmap_array(bmarray text) returns bool
+\endverbatim
+Clear all bits in all bitmaps of the bitmap array named
+<code>bmarray</code>.  Implemented by C function veil_clear_bitmap_array().
 
-\section API-bmarray-bmap veil_bitmap_from_array(bmref text, bmarray text, index int4)
-\code
-function veil_bitmap_from_array(bmref text, bmarray text, index int4) returns text
-\endcode
-Generate a reference to a specific bitmap in a bitmap array
+\section API-bmarray-bmap bitmap_from_array(bmref_name text, bmarray text, index int4)
+\verbatim
+function veil.bitmap_from_array(bmref_name text, bmarray text, index int4) returns text
+\endverbatim
+Place a reference into <code>bmref_name</code> to the bitmap identified
+by <code>index</code> in bitmap array <code>bmarray</code>.  Implemented
+by C function veil_bitmap_from_array().
 
-\section API-bmarray-testbit veil_bitmap_array_testbit(bmarray text, arr_idx int4, bitno int4)
-\code
-function veil_bitmap_array_testbit(bmarray text, arr_idx int4, bitno int4) returns bool
-\endcode
-Test a specific bit in a bitmap array.
+\section API-bmarray-testbit bitmap_array_testbit(bmarray text, arr_idx int4, bitno int4)
+\verbatim
+function veil.bitmap_array_testbit(bmarray text, arr_idx int4, bitno int4) returns bool
+\endverbatim
+Test a specific bit in a bitmap array.  Implemented by C function
+veil_bitmap_array_testbit().
 
-\section API-bmarray-setbit veil_bitmap_array_setbit(bmarray text, arr_idx int4, bitno int4)
-\code
-function veil_bitmap_array_setbit(bmarray text, arr_idx int4, bitno int4) returns bool
-\endcode
-Set a specific bit in a bitmap array.
+\section API-bmarray-setbit bitmap_array_setbit(bmarray text, arr_idx int4, bitno int4)
+\verbatim
+function veil.bitmap_array_setbit(bmarray text, arr_idx int4, bitno int4) returns bool
+\endverbatim
+Set a specific bit in a bitmap array.  Implemented by C function
+veil_bitmap_array_setbit().
 
-\section API-bmarray-clearbit veil_bitmap_array_clearbit(bmarray text, arr_idx int4, bitno int4)
-\code
-function veil_bitmap_array_clearbit(bmarray text, arr_idx int4, bitno int4) returns bool
-\endcode
-Clear a specific bit in a bitmap array.
+\section API-bmarray-clearbit bitmap_array_clearbit(bmarray text, arr_idx int4, bitno int4)
+\verbatim
+function veil.bitmap_array_clearbit(bmarray text, arr_idx int4, bitno int4) returns bool
+\endverbatim
+Clear a specific bit in a bitmap array.  Implemented by C function
+veil_bitmap_array_clearbit().
 
-\section API-bmarray-union veil_union_from_bitmap_array(bitmap text, bmarray text, arr_idx int4)
-\code
-function veil_union_from_bitmap_array(bitmap text, bmarray text, arr_idx int4) returns bool
-\endcode
+\section API-bmarray-union union_from_bitmap_array(bitmap text, bmarray text, arr_idx int4)
+\verbatim
+function veil.union_from_bitmap_array(bitmap text, bmarray text, arr_idx int4) returns bool
+\endverbatim
 Union a bitmap with a specified bitmap from an array, with the result in
-the bitmap.  This is a faster shortcut for:
+the bitmap.    Implemented by C function
+veil_union_from_bitmap_array().  This is a faster shortcut for the
+following logical construction:
 
-<code>
-veil_bitmap_union(&lt;bitmap>, veil_bitmap_from_array(&lt;bitmap_array>, &lt;index>))
-</code>.
+\verbatim
+veil.bitmap_union(<bitmap>, veil.bitmap_from_array(<bitmap_array>, <index>))
+\endverbatim
 
-\section API-bmarray-intersect veil_intersect_from_bitmap_array(bitmap text, bmarray text, arr_idx int4)
-\code
-function veil_intersect_from_bitmap_array(bitmap text, bmarray text, arr_idx int4) returns bool
-\endcode
+\section API-bmarray-intersect intersect_from_bitmap_array(bitmap text, bmarray text, arr_idx int4)
+\verbatim
+function veil.intersect_from_bitmap_array(bitmap text, bmarray text, arr_idx int4) returns bool
+\endverbatim
 Intersect a bitmap with a specified bitmap from an array, with the result in
-the bitmap.  This is a faster shortcut for:
+the bitmap.    Implemented by C function
+veil_intersect_from_bitmap_array().  This is a faster shortcut for the
+following logical construction:
 
-<code>
-veil_bitmap_intersect(&lt;bitmap>, veil_bitmap_from_array(&lt;bitmap_array>, &lt;index>))
-</code>.
+\verbatim
+veil.bitmap_intersect(<bitmap>, veil.bitmap_from_array(<bitmap_array>,<index>))
+\endverbatim
 
-\section API-bmarray-bits veil_bitmap_array_bits(bmarray text, arr_idx int4)
-\code
-function veil_bitmap_array_bits(bmarray text, arr_idx int4) returns setof int4
-\endcode
+\section API-bmarray-bits bitmap_array_bits(bmarray text, arr_idx int4)
+\verbatim
+function veil.bitmap_array_bits(bmarray text, arr_idx int4) returns setof int4
+\endverbatim
 Show all bits in the specific bitmap within an array.  This is primarily
 intended for interactive use when developing and debugging Veil-based
-systems.
+systems.  Implemented by C function veil_bitmap_array_bits().
 
-\section API-bmarray-arange veil_bitmap_array_arange(bmarray text)
-\code
-function veil_bitmap_array_arange(bmarray text) returns veil_range_t
-\endcode
-Show the range of array indices for the specified bitmap array.
-Primarily for interactive use.
+\section API-bmarray-arange bitmap_array_arange(bmarray text)
+\verbatim
+function veil.bitmap_array_arange(bmarray text) returns veil_range_t
+\endverbatim
+Return the range of array indices, as a \ref veil_range_t, for the
+specified bitmap array.  Primarily for interactive use.  Implemented by
+C function veil_bitmap_array_arange().
 
-\section API-bmarray-brange veil_bitmap_array_brange(bmarray text)
-\code
-function veil_bitmap_array_brange(bmarray text) returns veil_range_t
-\endcode
-Show the range of all bitmaps in the specified bitmap array.
-Primarily for interactive use.
+\section API-bmarray-brange bitmap_array_brange(bmarray text)
+\verbatim
+function veil.bitmap_array_brange(bmarray text) returns veil_range_t
+\endverbatim
+Show the range, as a \ref veil_range_t, of all bitmaps in the specified
+bitmap array.  Primarily for interactive use.  Implemented by
+C function veil_bitmap_array_range().
 
 
 Next: \ref API-bitmap-hashes
@@ -728,101 +770,116 @@ The following functions comprise the Veil bitmap hashes API:
 - <code>\ref API-bmhash-range</code>
 - <code>\ref API-bmhash-entries</code>
 
-\section API-bmhash-init veil_init_bitmap_hash(bmhash text, range text)
-\code
-function veil_init_bitmap_hash(bmhash text, range text) returns bool
-\endcode
-Creates, or resets, a bitmap hash.
+\section API-bmhash-init init_bitmap_hash(bmhash text, range text)
+\verbatim
+function veil.init_bitmap_hash(bmhash text, range text) returns bool
+\endverbatim
+Creates, or resets, a bitmap hash.  Implemented by
+C function veil_init_bitmap_hash().
 
-\section API-bmhash-clear veil_clear_bitmap_hash(bmhash text)
-\code
-function veil_clear_bitmap_hash(bmhash text) returns bool
-\endcode
-Clear all bits in a bitmap hash.
+\section API-bmhash-clear clear_bitmap_hash(bmhash text)
+\verbatim
+function veil.clear_bitmap_hash(bmhash text) returns bool
+\endverbatim
+Clear all bits in all bitmaps of a bitmap hash.  Implemented by
+C function veil_clear_bitmap_hash().  Implemented by
+C function veil_clear_bitmap_hash().
 
-\section API-bmhash-key-exists veil_bitmap_hash_key_exists(bmhash text, key text)
-\code
-function veil_bitmap_hash_key_exists(bmhash text, key text) returns bool
-\endcode
+\section API-bmhash-key-exists bitmap_hash_key_exists(bmhash text, key text)
+\verbatim
+function veil.bitmap_hash_key_exists(bmhash text, key text) returns bool
+\endverbatim
 Determine whether a given key exists in the hash (contains a bitmap).
+Implemented by C function veil_bitmap_hash_key_exists().
 
-\section API-bmhash-from veil_bitmap_from_hash(text, text, text)
-\code
-function veil_bitmap_from_hash(text, text, text) returns text
-\endcode
-Generate a reference to a specific bitmap in a bitmap hash.
+\section API-bmhash-from bitmap_from_hash(bmref text, bmhash text, key text)
+\verbatim
+function veil.bitmap_from_hash(bmref text, bmhash text, key text) returns text
+\endverbatim
+Generate a reference to a specific bitmap in a bitmap hash.  Implemented by
+C function veil_bitmap_from_hash().
 
-\section API-bmhash-testbit veil_bitmap_hash_testbit(text, text, int4)
-\code
-function veil_bitmap_hash_testbit(text, text, int4) returns bool
-\endcode
-Test a specific bit in a bitmap hash.
+\section API-bmhash-testbit bitmap_hash_testbit(bmhash text, key text, bitno int4)
+\verbatim
+function veil.bitmap_hash_testbit(bmhash text, key text, bitno int4) returns bool
+\endverbatim
+Test a specific bit in a bitmap hash.  Implemented by
+C function veil_bitmap_hash_testbit().
 
-\section API-bmhash-setbit veil_bitmap_hash_setbit(text, text, int4)
-\code
-function veil_bitmap_hash_setbit(text, text, int4) returns bool
-\endcode
-Set a specific bit in a bitmap hash.
+\section API-bmhash-setbit bitmap_hash_setbit(bmhash text, kay text, bitno int4)
+\verbatim
+function veil.bitmap_hash_setbit(bmhash text, key text, bitno int4) returns bool
+\endverbatim
+Set a specific bit in a bitmap hash.  Implemented by
+C function veil_bitmap_hash_setbit().
 
-\section API-bmhash-clearbit veil_bitmap_hash_clearbit(text, text, int4)
-\code
-function veil_bitmap_hash_clearbit(text, text, int4) returns bool
-\endcode
-Clear a specific bit in a bitmap hash.
+\section API-bmhash-clearbit bitmap_hash_clearbit(bmhash text, key text, bitno int4)
+\verbatim
+function veil.bitmap_hash_clearbit(bmhash text, key text, bitno int4) returns bool
+\endverbatim
+Clear a specific bit in a bitmap hash.  Implemented by
+C function veil_bitmap_hash_clearbit().
 
-\section API-bmhash-union-into veil_union_into_bitmap_hash(text, text, text)
-\code
-function veil_union_into_bitmap_hash(text, text, text) returns bool
-\endcode
+\section API-bmhash-union-into union_into_bitmap_hash(bmhash text, key text, bitmap text)
+\verbatim
+function veil.union_into_bitmap_hash(bmhash text, key text, bitmap text) returns bool
+\endverbatim
 Union a specified bitmap from a hash with a bitmap, with the result in
-the bitmap hash.  This is a faster shortcut for:
+the bitmap hash.  Implemented by C function
+veil_union_into_bitmap_hash().  This is a faster shortcut for the
+following logical construction:
 
-<code>
-veil_bitmap_union(veil_bitmap_from_hash(&lt;bitmap_hash>, &lt;key>), &lt;bitmap>)
-</code>.
+\verbatim
+veil.bitmap_union(veil.bitmap_from_hash(<bitmap_hash>, <key>), <bitmap>)
+\endverbatim
 
-\section API-bmhash-union-from veil_union_from_bitmap_hash(text, text, text)
-\code
-function veil_union_from_bitmap_hash(text, text, text) returns bool
-\endcode
+\section API-bmhash-union-from union_from_bitmap_hash(bmhash text, key text, bitmap text)
+\verbatim
+function veil.union_from_bitmap_hash(bmhash text, key text, bitmap text) returns bool
+\endverbatim
 Union a bitmap with a specified bitmap from a hash, with the result in
-the bitmap.  This is a faster shortcut for:
+the bitmap.  Implemented by C function veil_union_from_bitmap_hash().
+This is a faster shortcut for the following logical construction:
 
-<code>
-veil_bitmap_union(&lt;bitmap>, veil_bitmap_from_hash(&lt;bitmap_array>, &lt;key>))
-</code>.
+\verbatim
+veil.bitmap_union(<bitmap>, veil.bitmap_from_hash(<bitmap_array>, <key>))
+\endverbatim
 
-\section API-bmhash-intersect-from veil_intersect_from_bitmap_hash(text, text, text)
-\code
-function veil_intersect_from_bitmap_hash(text, text, text) returns bool
-\endcode
-Intersect a bitmap with a specified bitmap from a hash, with the result in
-the bitmap.  This is a faster shortcut for:
+\section API-bmhash-intersect-from intersect_from_bitmap_hash(bitmap text, bmhash text, key text)
+\verbatim
+function veil.intersect_from_bitmap_hash(bitmap text, bmhash text, key text) returns bool
+\endverbatim
+Intersect a bitmap with a specified bitmap from a hash, with the result
+in the bitmap.  Implemented by C function
+veil_intersect_from_bitmap_hash().  This is a faster shortcut for the
+following logical construction:
 
-<code>
-veil_bitmap_intersect(&lt;bitmap>, veil_bitmap_from_hash(&lt;bitmap_array>, &lt;key>))
-</code>.
+\verbatim
+veil.bitmap_intersect(<bitmap>, veil.bitmap_from_hash(<bitmap_array>, <key>))
+\endverbatim
 
-\section API-bmhash-bits veil_bitmap_hash_bits(text, text)
-\code
-function veil_bitmap_hash_bits(text, text) returns setof int4
-\endcode
+\section API-bmhash-bits bitmap_hash_bits(bmhash text, key text)
+\verbatim
+function veil.bitmap_hash_bits(bmhash text, key text) returns setof int4
+\endverbatim
 Show all bits in the specific bitmap within a hash.  This is primarily
 intended for interactive use when developing and debugging Veil-based
-systems.
+systems.  Implemented by C function veil_bitmap_hash_bits().
 
-\section API-bmhash-range veil_bitmap_hash_range(text)
-\code
-function veil_bitmap_hash_range(text) returns veil_range_t
-\endcode
-Show the range of all bitmaps in the hash.  Primarily intended for
-interactive use. 
+\section API-bmhash-range bitmap_hash_range(bmhash text)
+\verbatim
+function veil.bitmap_hash_range(bmhash text) returns veil_range_t
+\endverbatim
+Show the range, as a \ref veil_range_t, of all bitmaps in the hash.
+Primarily intended for interactive use.   Implemented by
+C function veil_bitmap_hash_range().
 
-\section API-bmhash-entries veil_bitmap_hash_entries(text)
-\code
-function veil_bitmap_hash_entries(text) returns setof text
-\endcode
+\section API-bmhash-entries bitmap_hash_entries(bmhash text)
+\verbatim
+function veil.bitmap_hash_entries(bmhash text) returns setof text
+\endverbatim
 Show every key in the hash.  Primarily intended for interactive use.
+Implemented by C function veil_bitmap_hash_entries().
 
 Next: \ref API-int-arrays
 */
@@ -842,29 +899,33 @@ The following functions comprise the Veil int arrays API:
 - <code>\ref API-intarray-set</code>
 - <code>\ref API-intarray-get</code>
 
-\section API-intarray-init veil_init_int4array(text, text)
-\code
-function veil_init_int4array(text, text) returns bool
-\endcode
-Creates, or resets the ranges of, an int array.
+\section API-intarray-init init_int4array(arrayname text, range text)
+\verbatim
+function veil.init_int4array(arrayname text, range text) returns bool
+\endverbatim
+Creates, or resets the ranges of, an int array.  Implemented by
+C function veil_init_int4array().
 
-\section API-intarray-clear veil_clear_int4array(text)
-\code
-function veil_clear_int4array(text) returns bool
-\endcode
-Clears (zeroes) an int array.
+\section API-intarray-clear clear_int4array(arrayname text)
+\verbatim
+function veil.clear_int4array(arrayname text) returns bool
+\endverbatim
+Clears (zeroes) an int array.  Implemented by
+C function veil_clear_int4array().
 
-\section API-intarray-set veil_int4array_set(text, int4, int4)
-\code
-function veil_int4array_set(text, int4, int4) returns int4
-\endcode
-Set the value of an element in an int array.
+\section API-intarray-set int4array_set(arrayname text, idx int4, value int4)
+\verbatim
+function veil.int4array_set(arrayname text, idx int4, value int4) returns int4
+\endverbatim
+Set the value of an element in an int array.  Implemented by
+C function veil_int4array_set().
 
-\section API-intarray-get veil_int4array_get(text, int4)
-\code
-function veil_int4array_get(text, int4) returns int4
-\endcode
-Get the value of an element from an int array.
+\section API-intarray-get int4array_get(arrayname text, idx int4)
+\verbatim
+function int4array_get(arrayname text, idx int4) returns int4
+\endverbatim
+Get the value of an element from an int array.  Implemented by
+C function veil_int4array_get().
 
 Next: \ref API-serialisation
 */
@@ -886,34 +947,35 @@ The following functions comprise the Veil serialisatation API:
 - <code>\ref API-serialize</code>
 - <code>\ref API-deserialize</code>
 
-\section API-serialise veil_serialise(text)
-\code
-function veil_serialise(text) returns text
-\endcode
+\section API-serialise serialise(varname text)
+\verbatim
+function veil.serialise(varname text) returns text
+\endverbatim
 This creates a serialised textual representation of the named session
 variable.  The results of this function may be concatenated into a
 single string, which can be deserialised in a single call to
-veil_deserialise()
+veil_deserialise().  Implemented by C function veil_serialise().
 
-\section API-deserialise veil_deserialise(text)
-\code
-function veil_deserialise(text) returns text
-\endcode
+\section API-deserialise deserialise(stream text)
+\verbatim
+function veil.deserialise(stream text) returns text
+\endverbatim
 This takes a serialised representation of one or more variables as
 created by concatenating the results of veil_serialise(), and
 de-serialises them, creating new variables as needed and resetting their
-values to those they had when they were serialised.
+values to those they had when they were serialised.  Implemented by C
+function veil_deserialise().
 
-\section API-serialize veil_serialize(text)
-\code
-function veil_serialize(text) returns text
-\endcode
+\section API-serialize serialize(varname text)
+\verbatim
+function veil.serialize(varname text) returns text
+\endverbatim
 Synonym for veil_serialise()
 
-\section API-deserialize veil_deserialize(text)
-\code
-function veil_deserialize(text) returns text
-\endcode
+\section API-deserialize deserialize(stream text)
+\verbatim
+function veil.deserialize(stream text) returns text
+\endverbatim
 Synonym for veil_deserialise()
 
 Next: \ref API-control
@@ -930,41 +992,78 @@ place.  All subsequent transactions will see the new set.
 
 The following functions comprise the Veil control functions API:
 
+- <code>\ref API-control-registered-init</code>
 - <code>\ref API-control-init</code>
 - <code>\ref API-control-reset</code>
-- <code>\ref API-control-force</code>
 - <code>\ref API-version</code>
 
-\section API-control-init veil_init(bool)
-\code
-function veil_init(bool) returns bool
-\endcode
-This function must be redefined by the application.  The default
-installed version simply raises an error telling you to redefine it.
-See \ref Implementation for a more detailed description of this function.
+\section API-control-registered-init registered initialisation functions
 
-\section API-control-reset veil_perform_reset()
-\code
-function veil_perform_reset() returns bool
-\endcode
-This is used to reset Veil's shared variables.  It causes veil_init() to
-be called.
+A registered initialisation function is one which will be called from
+the standard veil \ref API-control-init function.  Such functions are
+responsible for defining and, usually, initialising shared variables.
 
-\section API-control-force veil_force_reset(bool)
-\code
-function veil_force_reset() returns bool
-\endcode
-In the event of veil_perform_reset() failing to complete and leaving
-shared variables in a state of limbo, this function may be called to
-force the reset.  After forcing the reset, this function raises a panic
-which will reset the database server.  Use this at your peril.
+Initialisation functions may be written in any language supported by
+PostgreSQL, and must conform to the following function prototype:
 
-\section API-version veil_version()
-\code
-function veil_version() returns text
-\endcode
+\verbatim
+function init_function(doing_reset bool) returns bool
+\endverbatim
+
+The <code>doing_reset</code> parameter will be set to true if we are
+completely resetting veil and redefining all of its variables.  In this
+case, we must declare and, probably, initialise shared variables prior to 
+any session initialisation actions.  The parameter will be false, if the
+function is solely being called to initialise a new session.  Check \ref
+demo-sec for an example. 
+
+Initialisation functions are registered by inserting their name into
+the configuration table <code>veil.veil_init_fns</code>.  The functions
+listed in this table are executed in order of the <code>priority</code>
+column.  Eg, to register <code>veil.init_roles()</code> to execute
+before <code>veil.init_role_privs()</code>, we would use the following
+insert statement:
+
+\verbatim
+insert into veil.veil_init_fns
+       (fn_name, priority)
+values ('veil.init_roles', 1),
+       ('veil.init_role_privs', 2);
+\endverbatim
+
+\section API-control-init veil_init(doing_reset bool)
+\verbatim
+function veil.veil_init(doing_reset bool) returns bool
+\endverbatim
+
+This function, implemented by the C function veil_init(), is reponsible
+for initialising each veil session.  The <code>doing_reset</code>
+parameter is true if we are to completely reset Veil, redefining all
+shared variables.
+
+The builtin implementation of veil_init() will call each registered
+initialisation function (see \ref API-control-registered-init) in turn.
+
+If no initialisation functions are registered, veil_init() raises an
+exception.
+
+As an alternative to registering initialisation functions, a Veil-based
+application may instead simply redefine veil.veil_init(), though this
+usage is deprecated.
+
+\section API-control-reset veil_perform_reset()
+\verbatim
+function veil.veil_perform_reset() returns bool
+\endverbatim
+This is used to reset Veil's shared variables.  It causes \ref
+API-control-init to be called.  Implemented by C function veil_perform_reset().
+
+\section API-version version()
+\verbatim
+function veil.version() returns text
+\endverbatim
 This function returns a string describing the installed version of
-veil.
+veil.  Implemented by C function veil_version().
 
 Next: \ref Building
 
@@ -1103,16 +1202,35 @@ essentially 4 options:
 
 \subsection Implementation Implement the Initialisation Function
 
-The initialisation function \ref API-control-init is a critical
-function and must be defined.  It will be called by Veil, when the first
-in-built Veil function is invoked.  It is responsible for three distinct
-tasks:
+Proper initialisation of veil is critical.  There are two ways to manage
+this.  The traditional way is to write your own version of \ref
+API-control-init, replacing the supplied version.  The newer, better,
+alternative is to register your own initialisation functions in the
+table veil.veil_init_fns, and have the standard \ref API-control-init,
+call them.  If there are multiple initialisation functions, they are
+called in order of their priority values as specified in the table
+<code>veil.veil_init_fns</code>.
+
+The newer approach has a number of advantages:
+
+- it fully supports the PostgreSQL extension mechanism, allowing
+  extensions to be created and dropped;
+- it allows different security subsystems to have their own separate
+  initialisation routines, allowing more modular code and better
+  separation of responsibilities;
+- it is way cooler.
+
+Initialisation functions \ref API-control-init are critical elements.
+They will be called by automatically by Veil, when the first in-built
+Veil function is invoked.  Initialisation functions are responsible for
+three distinct tasks:
 
 - Initialisation of session variables
 - Initialisation of shared variables
 - Re-initialisation of variables during reset
 
-The boolean parameter to veil_init will be false on initial session
+The boolean parameter to veil_init (which is passed to registered
+initialisation functions) will be false on initial session
 startup, and true when performing a reset (\ref API-control-reset).
 
 Shared variables are created using \ref API-variables-share.  This
@@ -1120,16 +1238,16 @@ returns a boolean result describing whether the variable already
 existed.  If so, and we are not performing a reset, the current session
 need not initialise it.
 
-Session variables are simply created by referring to them.  It is worth
+Session variables are simply created by using them.  It is worth
 creating and initialising all session variables to "fix" their data
 types.  This will prevent other functions from misusing them.
 
-If the boolean parameter to veil_init is true, then we are performing a
-memory reset, and all shared variables should be re-initialised.  A
-memory reset will be performed whenever underlying, essentially static,
-data has been modified.  For example, when new privileges have been
-added, we must rebuild all privilege bitmaps to accommodate the new
-values.
+If the boolean parameter to an initialisation fuction is true, then we
+are performing a memory reset, and all shared variables should be
+re-initialised.  A memory reset will be performed whenever underlying,
+essentially static, data has been modified.  For example, when new
+privileges have been added, we must rebuild all privilege bitmaps to
+accommodate the new values.
 
 \subsection Implementation2 Implement the Connection Functions
 
@@ -1149,7 +1267,7 @@ the demo (\ref demo-sec) for a working example of this.
 \subsection Implementation3 Implement the Access Functions
 
 Access functions provide the low-level access controls to individual
-records.  As such their performance is critical.  It is generally better
+records.  As such, their performance is critical.  It is generally better
 to make the connection functions to more work, and the access functions
 less.  Bear in mind that if you perform a query that returns 10,000 rows
 from a table, your access function for that view is going to be called
@@ -1198,8 +1316,7 @@ user accounts.
 Note that the bulk of the code in a Veil application is in the
 definition of secured views and instead-of triggers, and that this code
 is all very similar.  Consider using a code-generation tool to implement
-this.  A suitable code-generator for Veil may be provided in subsequent
-releases.
+this. 
 
 Next: \ref Demo
 
@@ -1228,7 +1345,7 @@ a database containing the veil_demo application:
 - create a new database
 - connect to that database
 - execute <code>create extension veil;</code>
-- execute <code>create extension veil_demo;</code
+- execute <code>create extension veil_demo;</code>
 
 Next: \ref demo-model
 
@@ -1259,9 +1376,9 @@ contains those privileges.
 
 In this application there is a special role, <code>Personal
 Context</code> that contains the set of privileges that apply to all
-users in their personal context.  This role does not need to be
-explicitly assigned to users, and should probably never be explicitly
-assigned.
+users in their personal context.  Since all users have the same personal
+context privileges, the demo application provides this role to all users
+implicitly; there is no need for it to be explicitly assigned.
 
 Assignments of roles in the global context are made through
 person_roles, and in the project (relational) context through
@@ -1282,7 +1399,7 @@ table is currently left as an exercise for the reader.
 
 This describes each person.  A person is someone who owns data and who
 may connect to the database.  This table should contain authentication
-information etc.  In actuality it just maps a name to a person_id.
+information etc.  In the demo it just maps a name to a person_id.
 
 \subsection demo-projects Projects
 
@@ -1390,7 +1507,7 @@ Using your favourite tool connect to your veil_demo database.
 You will be able to see all of the demo views, both the secured views and
 the helpers.  But you will not initially be able to see any records:
 each view will appear to contain no data.  To gain some privileges you
-must identify yourself using the <code>connect_person()</code> function.
+must identify yourself using the \ref demo-code-connect-person function.
 
 There are 6 persons in the demo.  You may connect as any of them and see
 different subsets of data.  The persons are
@@ -1496,20 +1613,22 @@ Next: \ref demo-code
 
 */
 /*! \page demo-code The Demo Code
-\dontinclude funcs.sql
 \section demo-codesec The Code
-\subsection demo-code-veil-init veil_init(bool)
+\subsection demo-code-veil-init veil.veil_demo_init(performing_reset bool)
 
 This function is called at the start of each session, and whenever
 \ref API-control-reset is called.  The parameter, doing_reset, is
 false when called to initialise a session and true when called from
-veil_perform_reset().
+veil_perform_reset().  It is registered with \ref API-control-init
+through the <code>veil.veil_demo_init_fns</code> table which is created
+as an inherited table of <code>veil.veil_init_fns</code>.  By
+registering the initialisation functions using a veil_demo-specific
+inherited table, when the veil_demo extension is dropped, so is the
+registration data for \ref demo-code-veil-init.
 
-This definition replaces the standard default, do-nothing,
-implementation that is shipped with Veil (see \ref API-control-init).
-
-\skip veil_init(bool)
-\until veil_share(''det_types_privs'')
+\dontinclude veil_demo.sqs
+\skip veil_demo_init(doing
+\until init_reqd =
 
 The first task of veil_init() is to declare a set of Veil shared
 variables.  This is done by calling \ref API-variables-share.  This function
@@ -1520,6 +1639,8 @@ These variables are defined as shared because they will be identical for
 each session.  Making them shared means that only one session has to
 deal with the overhead of their initialisation.
 
+\dontinclude veil_demo.sqs
+\skip init_reqd =
 \until end if;
 
 We then check whether the shared variables must be initialised.  We will
@@ -1548,7 +1669,7 @@ initialisation and population is handled in much the same way as
 described above for Int4Arrays, using the functions \ref
 API-bmarray-init and \ref API-bmarray-setbit.
 
-\until end;
+\until language
 
 The final section of code defines and initialises a set of session
 variables.  These are defined here to avoid getting undefined variable
@@ -1563,15 +1684,15 @@ must have no privileges on the base objects, or on the raw Veil
 functions themselves.  The only access to objects protected by Veil must
 be through user-defined functions and views.
 
-\subsection demo-code-connect-person connect_person(int4)
+\subsection demo-code-connect-person connect_person(_person_id int4)
 
 This function is used to establish a connection from a specific person.
 In a real application this function would be provided with some form of
 authentication token for the user.  For the sake of simplicity the demo
 allows unauthenticated connection requests.
 
-\skip connect_person(int4)
-\until end;
+\skip connect_person(_per
+\until language
 
 This function identifies the user, ensures that they have can_connect
 privilege.  It initialises the global_context bitmap to contain the
@@ -1579,94 +1700,89 @@ union of all privileges for each role the person is assigned through
 person_roles.  It also sets up a bitmap hash containing a bitmap of
 privileges for each project to which the person is assigned.
 
-\subsection demo-code-global-priv i_have_global_priv(int4)
+\subsection demo-code-global-priv i_have_global_priv(priv_id int4)
 
 This function is used to determine whether a user has a specified
 privilege in the global context.  It tests that the user is connected
-using <code>veil_int4_get()</code>, and then checks whether the
+using \ref API-basic-int4-get, and then checks whether the
 specified privilege is present in the <code>global_context</code>
 bitmap.
 
-\skip function i_have_global_priv(int4)
+\skip function i_have_global_priv(priv
 \until security definer;
 
 The following example shows this function in use by the secured view,
 <code>privileges</code>:
 
-\dontinclude views.sql
 \skip create view privileges
-\until i_have_global_priv(10004);
+\until grant
 
 The privileges used above are <code>select_privileges</code> (10001),
 <code>insert_privileges</code> (10002), <code>update_privileges</code>
 (10003), and <code>delete_privileges</code> (10004).
 
-\subsection demo-code-personal-priv i_have_personal_priv(int4, int4)
+\subsection demo-code-personal-priv i_have_personal_priv(priv_id int4, person_id int4)
 
 This function determines whether a user has a specified privilege to a
 specified user's data, in the global or personal contexts.  It performs
-the same tests as for <code>i_have_global_context()</code>.  If the user
+the same tests as for \ref demo-code-global-priv.  If the user
 does not have access in the global context, and the connected user is
 the same user as the owner of the data we are looking at, then we test
 whether the specified privilege exists in the <code>role_privs</code>
 bitmap array for the <code>Personal Context</code> role.
 
-\dontinclude funcs.sql
-\skip function i_have_personal_priv(int4, int4)
-\until end;
+\dontinclude veil_demo.sqs
+\skip function i_have_personal_priv(pr
+\until language
 
 Here is an example of this function in use from the persons secured view:
 
-\dontinclude views.sql
 \skip create view persons
-\until i_have_personal_priv(10013, person_id);
+\until grant
 
-\subsection demo-code-project-priv i_have_project_priv(int4, int4)
+\subsection demo-code-project-priv i_have_project_priv(priv_id int4, project_id int4)
 This function determines whether a user has a specified privilege in the
 global or project contexts.  If the user does not have the global
 privilege, we check whether they have the privilege defined in the
 project_context BitmapHash.
 
-\dontinclude funcs.sql
-\skip function i_have_project_priv(int4, int4)
-\until security definer;
+\dontinclude veil_demo.sqs
+\skip function i_have_project_priv(pr
+\until language
 
 Here is an example of this function in use from the instead-of insert
 trigger for the projects secured view:
 
-\dontinclude views.sql
 \skip create rule ii_projects 
 \until i_have_project_priv(10018, new.project_id);
 
-\subsection demo-code-proj-pers-priv i_have_proj_or_pers_priv(int4, int4, int4)
+\subsection demo-code-proj-pers-priv i_have_proj_or_pers_priv(priv_id int4, project_id int4, person_id int4)
 This function checks all privileges.  It starts with the cheapest check
 first, and short-circuits as soon as a privilege is found.
 
-\dontinclude funcs.sql
-\skip function i_have_proj_or_pers_priv(int4, int4, int4)
-\until security definer;
+\dontinclude veil_demo.sqs
+\skip function i_have_proj_or_pers_priv(
+\until language
 
 Here is an example of this function in use from the instead-of update
 trigger for the assignments secured view:
 
-\dontinclude views.sql
 \skip create rule ii_assignments 
 \until i_have_proj_or_pers_priv(10027, old.project_id, old.person_id);
 
-\subsection demo-code-pers-detail-priv i_have_person_detail_priv(int4, int4)
+\subsection demo-code-pers-detail-priv i_have_person_detail_priv(detail_id int4, person_id int4)
 This function is used to determine which types of person details are
 accessible to each user.  This provides distinct access controls to each
 attribute that may be recorded for a person.
 
-\dontinclude funcs.sql
-\skip function i_have_person_detail_priv(int4, int4)
-\until security definer;
+\dontinclude veil_demo.sqs
+\skip function i_have_person_detail_priv(
+\until language
 
 The function is shown in use, below, in the instead-of delete trigger
 for person_details.  Note that two distinct access functions are being
 used here.
 
-\dontinclude views.sql
 \skip create rule id_person_details
 \until i_have_person_detail_priv(old.detail_type_id, old.person_id);
 
@@ -1860,11 +1976,6 @@ The regression tests are all contained within the regress directory and
 are run by the regress.sh shell script.  Use the -h option to get
 fairly detailed help.
 
-\subsection Demodb_install Demo Database
-As with the regression tests, you will need to be a privileged database
-user to be able to create the demo database.  For more on installing the
-demo database see \ref demo-install.
-
 \subsection Debugging Debugging
 If you encounter problems with Veil, you may want to try building with
 debug enabled.  Define the variable VEIL_DEBUG on the make command line
@@ -1873,23 +1984,25 @@ to add extra debug code to the executable:
 $ make clean; make VEIL_DEBUG=1 all
 \endverbatim
 
-This is a new feature and not yet fully formed but is worth trying if
-Veil appears to be misbehaving.  If any of the debug code encounters a
-problem, ERRORs will be raised.
+This is a transient feature and not as pervasive as it could be.  If you
+need help with debugging please contact the author.
 
 Next: \ref History
 
 */
 /*! \page History History and Compatibility
 \section past Changes History
-\subsection v1_0 Version 1.0.0 (Stable) (2011-07-22)
-This is the first version of Veil to be considered production ready, and
+\subsection v1_0 Version 9.1.0 (Stable) (2011-07-22)
+This is the first version of Veil to be considered production ready and
 completely stable.  It is for use only with PostgreSQL 9.1.  Support for
 older versions of PostgreSQL has been removed in this version.
 
 Major changes include:
 - revamp of the build system to use PGXS and the new PostgreSQL 9.1
   extensions mechanism.  Veil is now built as an extension.
+- modification to the veil_init() mechanism, allowing custom
+  initialisation functions to be registered through the table
+  veil.veil_init_fns
 - removal of the old veil_trial mechanism, which allowed Veil to be
   tried out without fully installing it.  This has removed much
   unnecessary complexity.
@@ -2124,7 +2237,7 @@ pre-production versions will be removed from this documentation.
     <TD>-</TD>
   </TR>
   <TR>
-    <TD>1.0.0 (Stable)</TD>
+    <TD>9.1.0 (Stable)</TD>
     <TD>-</TD>
     <TD>-</TD>
     <TD>-</TD>
index af9234fc5e93d1daafed54ca4a506cdf69ed38d0..9199a6e7c6030b958ad3ba02c82fe0b67cce79f4 100644 (file)
@@ -35,18 +35,6 @@ typedef bool (Fetch_fn)(HeapTuple, TupleDesc, void *);
 #define FETCH_SIZE    20
 
 
-/**
- * Counter to assess depth of recursive spi calls, so that we can
- * sensibly and safely use spi_push and spi_pop when appropriate.
- */
-static int4 query_depth = 0;
-
-/**
- * State variable used to assess whther query_depth may have been left
- * in an invalid state following an error being raised.
- */
-static TransactionId connection_xid = 0;
-
 /**
  * If already connected in this session, push the current connection,
  * and get a new one.
@@ -55,36 +43,28 @@ static TransactionId connection_xid = 0;
  * - and the current transaction id matches the saved transaction id
  */
 int
-vl_spi_connect(void)
+vl_spi_connect(bool *p_pushed)
 {
-   TransactionId xid = GetCurrentTransactionId();
-
-   if (query_depth > 0) {
-       if (xid == connection_xid) {
-           SPI_push();
-       }
-       else {
-           /* The previous transaction must have aborted without
-            * resetting query_depth */
-           query_depth = 0;
-       }
+   int result = SPI_connect();
+   if (result == SPI_ERROR_CONNECT) {
+       SPI_push();
+       *p_pushed = TRUE;
+       return SPI_connect();
    }
-
-   connection_xid = xid;
-   return SPI_connect();
+   *p_pushed = FALSE;
+   return result;
 }
 
 /**
  * Reciprocal function for vl_spi_connect()
  */
 int
-vl_spi_finish(void)
+vl_spi_finish(bool pushed)
 {
    int spi_result = SPI_finish();
-   if (query_depth > 0) {
+   if (pushed) {
        SPI_pop();
    }
-
    return spi_result;
 }
 
@@ -177,24 +157,26 @@ query(const char *qry,
       Fetch_fn process_row,
       void *fn_param)
 {
-    int    row;
-   int    fetched = 0;
+    int  row;
+   int  fetched;
+   int  processed = 0;
+   bool cntinue;
+   SPITupleTable *tuptab;
 
-   query_depth++;
     prepare_query(qry, nargs, argtypes, args, read_only, saved_plan);
-   
-   for(row = 0; row < SPI_processed; row++) {
-       fetched++;
+   fetched = SPI_processed;
+   tuptab = SPI_tuptable;
+   for(row = 0; row < fetched; row++) {
+       processed++;
        /* Process a row using the processor function */
-       if (!process_row(SPI_tuptable->vals[row], 
-                        SPI_tuptable->tupdesc,
-                        fn_param)) 
-       {
+       cntinue = process_row(tuptab->vals[row], 
+                             tuptab->tupdesc,
+                             fn_param);
+       if (!cntinue) {
            break;
        }
    }
-   query_depth--;
-    return fetched;
+    return processed;
 }
 
 
@@ -289,7 +271,6 @@ str_from_oid_query(const char *qry,
  * 
  * @result True if the database exists.
  */
-
 extern bool
 vl_db_exists(Oid db_id)
 {
@@ -300,3 +281,85 @@ vl_db_exists(Oid db_id)
 }
 
 
+/** 
+ * ::Fetch_fn function for executing registered veil_init() functions for
+ * ::query.
+ * \param tuple The row to be processed
+ * \param tupdesc Descriptor for the types of the fields in the tuple.
+ * \param p_param Pointer to a boolean value which is the value of the
+ * argument to the init function being called.
+ * \return true.  This allows ::query to process further rows.
+ */
+static bool
+exec_init_fn(HeapTuple tuple, TupleDesc tupdesc, void *p_param)
+{
+    char *col = SPI_getvalue(tuple, tupdesc, 1);
+   char *qry = palloc(strlen(col) + 15);
+   bool pushed;
+   bool result;
+   bool found;
+   int ok;
+
+   (void) sprintf(qry, "select %s(%s)", col, 
+                  *((bool *) p_param)? "true": "false");
+
+   ok = vl_spi_connect(&pushed);
+   if (ok != SPI_OK_CONNECT) {
+       ereport(ERROR,
+               (errcode(ERRCODE_INTERNAL_ERROR),
+                errmsg("failed to execute exec_init_fn() (1)"),
+                errdetail("SPI_connect() failed, returning %d.", ok)));
+   }
+
+   found = vl_bool_from_query(qry, &result);
+
+
+   ok = vl_spi_finish(pushed);
+   if (ok != SPI_OK_FINISH) {
+       ereport(ERROR,
+               (errcode(ERRCODE_INTERNAL_ERROR),
+                errmsg("failed to execute exec_init_fn() (2)"),
+                errdetail("SPI_finish() failed, returning %d.", ok)));
+   }
+
+    return true;
+}
+
+
+/** 
+ * Identify any registered init_functions and execute them.
+ * 
+ * @param param The boolean parameter to be passed to each init_function.
+ * 
+ * @result The number of init_functions executed.
+ */
+int
+vl_call_init_fns(bool param)
+{
+    Oid     argtypes[0];
+    Datum   args[0];
+   char   *qry = "select fn_name from veil.veil_init_fns order by priority";
+   bool    pushed;
+   int     rows;
+   int     ok;
+
+   ok = vl_spi_connect(&pushed);
+   if (ok != SPI_OK_CONNECT) {
+       ereport(ERROR,
+               (errcode(ERRCODE_INTERNAL_ERROR),
+                errmsg("failed to execute vl_call_init_fns() (1)"),
+                errdetail("SPI_connect() failed, returning %d.", ok)));
+   }
+
+   rows = query(qry, 0, argtypes, args, false, NULL, 
+                exec_init_fn, (void *) &param);
+
+   ok = vl_spi_finish(pushed);
+   if (ok != SPI_OK_FINISH) {
+       ereport(ERROR,
+               (errcode(ERRCODE_INTERNAL_ERROR),
+                errmsg("failed to execute vl_call_init_fns() (2)"),
+                errdetail("SPI_finish() failed, returning %d.", ok)));
+   }
+    return rows;
+}
index 8bad207b7dc7c595001908ec816968dbc9524a64..1fba434b13ff123a7ee8a749f4091f5f165b19a1 100644 (file)
@@ -13,7 +13,7 @@
 
 /** The version number for this version of veil
  */
-#define VEIL_VERSION "1.0.0"
+#define VEIL_VERSION "9.1.0"
 /** The version number suffix, indicating stability.
  */
 #define VEIL_VERSION_INFO "Stable"
diff --git a/veil--1.0.sql b/veil--1.0.sql
deleted file mode 100644 (file)
index 4dff5cb..0000000
+++ /dev/null
@@ -1,743 +0,0 @@
-/* ----------
- * veil_interface.sqs (or a file derived from it)
- *
- *      Source file from which veil--<version>.sql is generated using
- * sed. 
- *
- *      Copyright (c) 2005 - 2011 Marc Munro
- *      Author:  Marc Munro
- * License: BSD
- *
- * ----------
- */
-
-create type veil_range_t as (
-    min  int4,
-    max  int4
-);
-comment on type veil_range_t is
-'Veil type used to record ranges.  A range is a pair of integers identifying
-the minimum and maximum values of the range.  Ranges are used to
-constrain the size of a bitmap or bitmap array.';
-
-create type veil_variable_t as (
-    name    text,
-    type    text,
-    shared  bool
-);
-comment on type veil_variable_t is
-'Veil type used as the result type of veil_variables(), to describe each
-variable known to a veil instance.';
-
-
-create or replace
-function veil_share(name text) returns bool
-     as '$libdir/veil', 'veil_share'
-     language C stable strict;
-
-comment on function veil_share(name text) is
-'Create a shared variable named NAME.
-
-Return TRUE if successful, else raise an error.
-
-Create a veil variable as a shared variable.  Variables are named
-containers for various types of values.  They are referenced by name,
-passing the name as a string to the various veil functions.
-
-Variables may be shared variables in which case they are available, with
-the same value, to all sessions, or session variables in which case each
-session will have its own instance.  Variables are by default created as
-session variables, and are created by assignment, or initialisation.  To
-create a shared variable, call veil_share() with the name of the
-variable you wish to create, then create and use the variable as you
-would a session variable.  Shared variables should only be created and
-initialised from veil_init() in order to prevent race conditions.  If a
-variable has already been created as a session variable, it cannot be
-repurposed as a shared variable.';
-
-
-create or replace
-function veil_variables() returns setof veil_variable_t
-     as '$libdir/veil', 'veil_variables'
-     language C stable;
-
-comment on function veil_variables() is
-'List all current veil_variables.
-Return a set of veil_variable_t results, detailing each existant
-variable
-
-This is intended for interactive use for debugging purposes.';
-
-
-create or replace
-function veil_init_range(name text, min int4, max int4) returns int4
-     as '$libdir/veil', 'veil_init_range'
-     language C stable strict;
-
-comment on function veil_init_range(text, int4, int4) is
-'Initialise a Range variable called NAME constrained by MIN and MAX.
-
-Return the number of  elements in the range.
-
-Ranges may be examined using the veil_range() function.';
-
-
-create or replace
-function veil_range(name text) returns veil_range_t
-     as '$libdir/veil', 'veil_range'
-     language C stable strict;
-
-comment on function veil_range(name text) is
-'Return the range for range variable NAME.';
-
-
-create or replace
-function veil_init_bitmap(bitmap_name text, range_name text) returns bool
-     as '$libdir/veil', 'veil_init_bitmap'
-     language C stable strict;
-
-comment on function veil_init_bitmap(text, text) is
-'Create or re-initialise the Bitmap named BITMAP_NAME, for the range of
-bits given by RANGE_NAME.
-
-Return TRUE on success, raise an error otherwise.
-
-All bits in the bitmap will be zero (cleared).';
-
-
-create or replace
-function veil_clear_bitmap(name text) returns bool
-     as '$libdir/veil', 'veil_clear_bitmap'
-     language C stable strict;
-
-comment on function veil_clear_bitmap(text) is
-'Clear the Bitmap or BitmapRef identified by NAME.
-
-Return TRUE, or raise an error.
-
-Clear (set to zero) all bits in the named bitmap.';
-
-
-create or replace
-function veil_bitmap_setbit(name text, bit_number int4) returns bool
-     as '$libdir/veil', 'veil_bitmap_setbit'
-     language C stable strict;
-
-comment on function veil_bitmap_setbit(text, int4) is
-'In the Bitmap or BitmapRef identified by NAME, set the bit given by
-BIT_NUMBER.
-
-Return TRUE or raise an error.
-
-Set to 1, the identified bit.';
-
-
-create or replace
-function veil_bitmap_clearbit(name text, bit_number int4) returns bool
-     as '$libdir/veil', 'veil_bitmap_clearbit'
-     language C stable strict;
-
-comment on function veil_bitmap_clearbit(text, int4) is
-'In the Bitmap or BitmapRef identified by NAME, clear the bit given by
-BIT_NUMBER.
-
-Return TRUE or raise an error.
-
-Set to 0, the identified bit.';
-
-
-create or replace
-function veil_bitmap_testbit(name text, bit_number int4) returns bool
-     as '$libdir/veil', 'veil_bitmap_testbit'
-     language C stable strict;
-
-comment on function veil_bitmap_testbit(text, int4) is
-'In the Bitmap or BitmapRef identified by NAME, test the bit given by
-BIT_NUMBER.
-
-Return TRUE if the bit is set, FALSE if it is zero.';
-
-
-create or replace
-function veil_bitmap_union(result_name text, name2 text) returns bool
-     as '$libdir/veil', 'veil_bitmap_union'
-     language C stable strict;
-
-comment on function veil_bitmap_union(text, text) is
-'Union two Bitmaps, RESULT_NAME and NAME2, with the result going into
-the first.
-
-Return TRUE, or raise an error.';
-
-
-create or replace
-function veil_bitmap_intersect(result_name text, name2 text) returns bool
-     as '$libdir/veil', 
-   'veil_bitmap_intersect'
-     language C stable strict;
-
-comment on function veil_bitmap_intersect(text, text) is
-'Intersect two Bitmaps, RESULT_NAME and NAME2, with the result going into
-the first.
-
-Return TRUE, or raise an error.';
-
-
-create or replace
-function veil_bitmap_bits(name text) returns setof int4
-     as '$libdir/veil', 'veil_bitmap_bits'
-     language C stable strict;
-
-comment on function veil_bitmap_bits(text) is
-'Return each bit in the bitmap NAME.
-
-This is primarily intended for interactive use for debugging, etc.';
-
-
-create or replace
-function veil_bitmap_range(name text) returns veil_range_t
-     as '$libdir/veil', 'veil_bitmap_range'
-     language C stable strict;
-
-comment on function veil_bitmap_range(text) is
-'Return the range of bitmap NAME.  
-
-It is primarily intended for interactive use.';
-
-
-
-create or replace
-function veil_init_bitmap_array(bmarray text, array_range text, 
-               bitmap_range text) returns bool
-     as '$libdir/veil', 'veil_init_bitmap_array'
-     language C stable strict;
-
-comment on function veil_init_bitmap_array(text, text, text) is
-'Creates or resets (clears) BMARRAY, to have ARRAY_RANGE bitmaps of
-BITMAP_RANGE bits.
-
-Returns TRUE or raises an error';
-
-
-create or replace
-function veil_clear_bitmap_array(bmarray text) returns bool
-     as '$libdir/veil', 'veil_clear_bitmap_array'
-     language C stable strict;
-
-comment on function veil_clear_bitmap_array(text) is
-'Clear all bits in all bitmaps of bitmap array BMARRAY.
-
-Return TRUE or raise an error';
-
-
-create or replace
-function veil_bitmap_from_array(bmref text, bmarray text, 
-               index int4) returns text
-     as '$libdir/veil', 
-   'veil_bitmap_from_array'
-     language C stable strict;
-
-comment on function veil_bitmap_from_array(text, text, int4) is
-'Set BitmapRef BMREF to the bitmap from BMARRAY indexed by INDEX.
-
-Return the name of the BitmapRef.
-
-This is used to isolate a single bitmap from a bitmap array, recording
-it in a BitmapRef.  That bitmap can then be manipulated by ordinary veil
-bitmap functions.  Note that BitMapRefs can only be referenced within
-the transaction they are defined.';
-
-
-create or replace
-function veil_bitmap_array_testbit(
-    bmarray text, arr_idx int4, bitno int4) returns bool
-     as '$libdir/veil', 
-   'veil_bitmap_array_testbit'
-     language C stable strict;
-
-comment on function veil_bitmap_array_testbit(text, int4, int4) is
-'Test a bit in BMARRAY, from the bitmap indexed by ARR_IDX, checking the
-bit identified by BITNO.
-
-Return TRUE if the bit is set, else FALSE';
-
-
-create or replace
-function veil_bitmap_array_setbit(
-    bmarray text, arr_idx int4, bitno int4) returns bool
-     as '$libdir/veil', 
-   'veil_bitmap_array_setbit'
-     language C stable strict;
-
-comment on function veil_bitmap_array_setbit(text, int4, int4) is
-'Set a bit in BMARRAY, from the bitmap indexed by ARR_IDX, setting the
-bit identified by BITNO.
-
-Return TRUE';
-
-
-create or replace
-function veil_bitmap_array_clearbit(
-    bmarray text, arr_idx int4, bitno int4) returns bool
-     as '$libdir/veil', 
-   'veil_bitmap_array_clearbit'
-     language C stable strict;
-
-comment on function veil_bitmap_array_clearbit(text, int4, int4) is
-'Clear a bit in BMARRAY, from the bitmap indexed by ARR_IDX, clearing the
-bit identified by BITNO.
-
-Return TRUE';
-
-
-create or replace
-function veil_union_from_bitmap_array(
-    bitmap text, bmarray text, arr_idx int4) returns bool
-     as '$libdir/veil', 
-   'veil_union_from_bitmap_array'
-     language C stable strict;
-
-comment on function veil_union_from_bitmap_array(text, text, int4) is
-'Union BITMAP with BMARRAY[ARR_IDX], with the result going into bitmap.
-
-Return TRUE';
-
-
-create or replace
-function veil_intersect_from_bitmap_array(
-    bitmap text, bmarray text, arr_idx int4) returns bool
-     as '$libdir/veil', 
-   'veil_intersect_from_bitmap_array'
-     language C stable strict;
-
-comment on function veil_intersect_from_bitmap_array(text, text, int4) is
-'Intersect BITMAP with BMARRAY[ARR_IDX], with the result going into bitmap.
-
-Return TRUE';
-
-
-create or replace
-function veil_bitmap_array_bits(bmarray text, arr_idx int4) returns setof int4
-     as '$libdir/veil', 
-   'veil_bitmap_array_bits'
-     language C stable strict;
-
-comment on function veil_bitmap_array_bits(text, int4) is
-'Return all bits in the bitmap given by BMARRAY[ARR_IDX].
-
-This is primarily intended for interactive use: for debugging, etc.';
-
-
-create or replace
-function veil_bitmap_array_arange(bmarray text) returns veil_range_t
-     as '$libdir/veil', 
-   'veil_bitmap_array_arange'
-     language C stable strict;
-
-comment on function veil_bitmap_array_arange(text) is
-'Return the array bounds for BMARRAY.';
-
-
-create or replace
-function veil_bitmap_array_brange(bmarray text) returns veil_range_t
-     as '$libdir/veil', 
-   'veil_bitmap_array_brange'
-     language C stable strict;
-
-comment on function veil_bitmap_array_brange(text) is
-'Return the range of the bitmaps in BMARRAY.';
-
-
-
-create or replace
-function veil_init_bitmap_hash(bmhash text, range text) returns bool
-     as '$libdir/veil', 'veil_init_bitmap_hash'
-     language C stable strict;
-
-comment on function veil_init_bitmap_hash(text, text) is
-'Initialise a bitmap hash variable called BMHASH to contain bitmaps of
-size RANGE.
-
-Return TRUE.';
-
-
-create or replace
-function veil_clear_bitmap_hash(bmhash text) returns bool
-     as '$libdir/veil', 'veil_clear_bitmap_hash'
-     language C stable strict;
-
-comment on function veil_clear_bitmap_hash(text) is
-'Clear all bits in an existing bitmap hash named BMHASH.
-
-Return TRUE.';
-
-
-create or replace
-function veil_bitmap_hash_key_exists(bmhash text, key text) returns bool
-     as '$libdir/veil', 
-   'veil_bitmap_hash_key_exists'
-     language C stable strict;
-
-comment on function veil_bitmap_hash_key_exists(text, text) is
-'Determine whether in BMHASH the given KEY already exists.
-
-Return TRUE if the key exists, else FALSE.';
-
-
-create or replace
-function veil_bitmap_from_hash(text, text, text) returns text
-     as '$libdir/veil', 
-   'veil_bitmap_from_hash'
-     language C stable strict;
-
-comment on function veil_bitmap_from_hash(text, text, text) is
-'Set BitmapRef BMREF to the bitmap from BMHASH identfied by KEY.
-
-Return the name of BMREF.';
-
-
-create or replace
-function veil_bitmap_hash_testbit(text, text, int4) returns bool
-     as '$libdir/veil', 
-   'veil_bitmap_hash_testbit'
-     language C stable strict;
-
-comment on function veil_bitmap_hash_testbit(text, text, int4) is
-'Test the bit, in the bitmap from BMHASH identified by KEY, given by
-BITNO.
-
-Return TRUE if the bit is set, else FALSE.';
-
-
-create or replace
-function veil_bitmap_hash_setbit(text, text, int4) returns bool
-     as '$libdir/veil', 
-   'veil_bitmap_hash_setbit'
-     language C stable strict;
-
-comment on function veil_bitmap_hash_setbit(text, text, int4) is
-'Set the bit, in the bitmap from BMHASH identified by KEY, given by
-BITNO to TRUE.
-
-Return TRUE.';
-
-
-create or replace
-function veil_bitmap_hash_clearbit(text, text, int4) returns bool
-     as '$libdir/veil', 
-   'veil_bitmap_hash_clearbit'
-     language C stable strict;
-
-comment on function veil_bitmap_hash_clearbit(text, text, int4) is
-'Set the bit, in the bitmap from BMHASH identified by KEY, given by
-BITNO to FALSE.
-
-Return TRUE.';
-
-
-create or replace
-function veil_union_into_bitmap_hash(text, text, text) returns bool
-     as '$libdir/veil', 
-   'veil_union_into_bitmap_hash'
-     language C stable strict;
-
-comment on function veil_union_into_bitmap_hash(text, text, text) is
-'Into the bitmap from BMHASH, identified by KEY, and union the bits from
-BITMAP (which may be a bitmap or bitmap_ref).
-
-Return TRUE.';
-
-
-create or replace
-function veil_union_from_bitmap_hash(text, text, text) returns bool
-     as '$libdir/veil', 
-   'veil_union_from_bitmap_hash'
-     language C stable strict;
-comment on function veil_union_from_bitmap_hash(text, text, text) is
-'Retrieve the bitmap from BMHASH, identified by KEY, and union it into
-BITMAP (which may be a bitmap or bitmap_ref).
-
-Return TRUE.';
-
-
-create or replace
-function veil_intersect_from_bitmap_hash(text, text, text) returns bool
-     as '$libdir/veil', 
-   'veil_intersect_from_bitmap_hash'
-     language C stable strict;
-comment on function veil_intersect_from_bitmap_hash(text, text, text) is
-'Into BITMAP, intersect the bits from the bitmap in BMHASH identified by
-KEY.
-
-Return TRUE.';
-
-
-create or replace
-function veil_bitmap_hash_bits(text, text) returns setof int4
-     as '$libdir/veil', 
-   'veil_bitmap_hash_bits'
-     language C stable strict;
-
-comment on function veil_bitmap_hash_bits(text, text) is
-'Return the set of bits in the bitset from BMHASH identfied by KEY.';
-
-
-create or replace
-function veil_bitmap_hash_range(text) returns veil_range_t
-     as '$libdir/veil', 
-   'veil_bitmap_hash_range'
-     language C stable strict;
-
-comment on function veil_bitmap_hash_range(text) is
-'Return the range of all bitmaps in BMHASH.';
-
-
-create or replace
-function veil_bitmap_hash_entries(text) returns setof text
-     as '$libdir/veil', 
-   'veil_bitmap_hash_entries'
-     language C stable strict;
-
-comment on function veil_bitmap_hash_entries(text) is
-'Return the keys of all bitmaps in BMHASH.';
-
-
-create or replace
-function veil_int4_set(text, int4) returns int4
-     as '$libdir/veil', 
-   'veil_int4_set'
-     language C stable;
-
-comment on function veil_int4_set(text, int4) is
-'Set the int4 variable NAME to VALUE.
-
-Return the new value';
-
-
-create or replace
-function veil_int4_get(text) returns int4
-     as '$libdir/veil', 
-   'veil_int4_get'
-     language C stable strict;
-
-comment on function veil_int4_get(text) is
-'Return the value of int4 variable NAME.';
-
-
-create or replace
-function veil_init_int4array(text, text) returns bool
-     as '$libdir/veil', 'veil_init_int4array'
-     language C stable strict;
-
-comment on function veil_init_int4array(text, text) is
-'Initialise the int4 array ARRAYNAME, with an index range of RANGE.
-
-Each entry in the array is set to zero.
-
-Return TRUE.';
-
-
-create or replace
-function veil_clear_int4array(text) returns bool
-     as '$libdir/veil', 
-   'veil_clear_int4array'
-     language C stable strict;
-comment on function veil_clear_int4array(text) is
-'Reset each entry in the int4 array ARRAYNAME to zero.
-
-Return TRUE.';
-
-
-
-create or replace
-function veil_int4array_set(text, int4, int4) returns int4
-     as '$libdir/veil', 
-   'veil_int4array_set'
-     language C stable;
-
-comment on function veil_int4array_set(text, int4, int4) is
-'Set the ARRAY element IDX to VALUE.
-
-Return the new value.';
-
-
-create or replace
-function veil_int4array_get(text, int4) returns int4
-     as '$libdir/veil', 
-   'veil_int4array_get'
-     language C stable strict;
-
-comment on function veil_int4array_get(text, int4) is
-'Return the value of ARRAY element IDX.';
-
-
-create or replace
-function veil_init(bool) returns bool 
-     as '$libdir/veil', 
-   'veil_init'
-     language C stable strict;
-
-comment on function veil_init(bool) is
-'This is the default version of veil_init, which does nothing except
-raise an error.';
-
-
-create or replace
-function veil_perform_reset() returns bool
-     as '$libdir/veil', 'veil_perform_reset'
-     language C stable;
-
-comment on function veil_perform_reset() is
-'Allow userspace to force call of veil_init.
-
-This function may fail due to outstanding transactions possibly holding
-shared memory that we wish to re-use.  In this case a warning will be
-issued.  Once any long running transactions have completed, a retry
-should succeed.
-
-Return TRUE if successful, FALSE otherwise.';
-
-
-create or replace
-function veil_force_reset() returns bool
-     as '$libdir/veil', 'veil_force_reset'
-     language C stable;
-
-comment on function veil_force_reset() is
-'Allow userspace to force an unconditional reset of veil shared memory.
-
-This always causes a PANIC, causing the database to fully reset.';
-
-
-create or replace
-function veil_version() returns text
-     as '$libdir/veil', 'veil_version'
-     language C stable;
-
-comment on function veil_version() is
-'Return a text string identifying the current veil version.';
-
-
-
-create or replace
-function veil_serialise(varname text) returns text
-     as '$libdir/veil', 
-   'veil_serialise'
-     language C stable strict;
-
-comment on function veil_serialise(varname text) is
-'Return a serialised copy of a variable VARNAME in text form.
-
-This is intended to be used with pgmemcache so that session variables
-can be efficiently cached.  Serialised values can be concatenated
-together as a single string and then deserialised in a single operation.
-
-The value can be restored by de-serialising it.';
-
-
-
-create or replace
-function veil_serialize(text) returns text
-     as '$libdir/veil', 
-   'veil_serialise'
-     language C stable strict;
-
-comment on function veil_serialize(varname text) is
-'Return a serialised copy of a variable VARNAME in text form.
-
-This is intended to be used with pgmemcache so that session variables
-can be efficiently cached.  Serialized values can be concatenated
-together as a single string and then deserialized in a single operation.
-
-The value can be restored by de-serializing it.';
-
-
-
-create or replace
-function veil_deserialise(text) returns int4
-     as '$libdir/veil', 
-   'veil_deserialise'
-     language C stable strict;
-
-comment on function veil_deserialise(text) is
-'Reset the contents of a set of serialised variable from STREAM.
-
-Return the number of items de-serialised.';
-
-
--- Ditto for victims of webster.
-create or replace
-function veil_deserialize(text) returns int4
-     as '$libdir/veil', 
-   'veil_deserialise'
-     language C stable strict;
-
-comment on function veil_deserialize(text) is
-'Reset the contents of a set of serialized variable from STREAM.
-
-Return the number of items de-serialized.';
-
-
-revoke execute on function veil_share(text) from public;
-revoke execute on function veil_variables() from public;
-revoke execute on function veil_init_range(text, int4,int4) from public;
-revoke execute on function veil_range(text) from public;
-
-revoke execute on function veil_init_bitmap(text, text) from public;
-revoke execute on function veil_clear_bitmap(text) from public;
-revoke execute on function veil_bitmap_setbit(text, int4) from public;
-revoke execute on function veil_bitmap_testbit(text, int4) from public;
-revoke execute on function veil_bitmap_bits(text) from public;
-revoke execute on function veil_bitmap_range(text) from public;
-
-revoke execute on function veil_init_bitmap_array(text, text, text)
-  from public;
-revoke execute on function veil_clear_bitmap_array(text) from public;
-revoke execute on function veil_bitmap_from_array(text, text, int4)
-  from public;
-revoke execute on function veil_bitmap_array_setbit(text, int4, int4)
-  from public;
-revoke execute on function veil_bitmap_array_testbit(text, int4, int4)
-  from public;
-revoke execute on function veil_union_from_bitmap_array(text, text, int4)
-  from public;
-revoke execute on function veil_intersect_from_bitmap_array(text, text, int4)
-  from public;
-revoke execute on function veil_bitmap_array_bits(text, int4) from public;
-revoke execute on function veil_bitmap_array_arange(text) from public;
-revoke execute on function veil_bitmap_array_brange(text) from public;
-
-
-revoke execute on function veil_init_bitmap_hash(text, text) from public;
-revoke execute on function veil_clear_bitmap_hash(text) from public;
-revoke execute on function veil_bitmap_hash_key_exists(text, text)
-  from public;
-revoke execute on function veil_bitmap_from_hash(text, text, text)
-  from public;
-revoke execute on function veil_bitmap_hash_setbit(text, text, int4)
-  from public;
-revoke execute on function veil_bitmap_hash_testbit(text, text, int4)
-  from public;
-revoke execute on function veil_union_into_bitmap_hash(text, text, text)
-  from public;
-revoke execute on function veil_union_from_bitmap_hash(text, text, text)
-  from public;
-revoke execute on function veil_intersect_from_bitmap_hash(text, text, text)
-  from public;
-revoke execute on function veil_bitmap_hash_bits(text, text) from public;
-revoke execute on function veil_bitmap_hash_range(text) from public;
-revoke execute on function veil_bitmap_hash_entries(text) from public;
-
-revoke execute on function veil_init_int4array(text, text) from public;
-revoke execute on function veil_clear_int4array(text) from public;
-revoke execute on function veil_int4array_set(text, int4, int4) from public;
-revoke execute on function veil_int4array_get(text, int4) from public;
-
-revoke execute on function veil_init(bool) from public;
-
-revoke execute on function veil_serialise(text) from public;
-revoke execute on function veil_serialize(text) from public;
-revoke execute on function veil_deserialise(text) from public;
-revoke execute on function veil_deserialize(text) from public;
-
-
index a55c85d718a5bda064f2aa4fdbf3653421098d33..f9e6127d44d3aee173577ae95a480ed04d34c86f 100644 (file)
@@ -7,8 +7,8 @@
 #      License: BSD
 #
 
-directory       = 'extension/veil'
-default_version = '1.0'
+directory       = 'extension'
+default_version = '9.1'
 module_pathname = '$libdir/veil'
 superuser       = true
 relocatable     = false
diff --git a/veil_demo--1.0.sql b/veil_demo--1.0.sql
deleted file mode 100644 (file)
index 491cd1d..0000000
+++ /dev/null
@@ -1,1265 +0,0 @@
-create schema hidden;
-revoke all on schema hidden from public;
-
-create table hidden.privileges (
-    privilege_id   integer not null,
-    privilege_name varchar(80) not null
-);
-alter table hidden.privileges add constraint privilege__pk
-    primary key(privilege_id);
-
-
-create table hidden.roles (
-    role_id    integer not null,
-    role_name  varchar(80) not null
-);
-alter table hidden.roles add constraint role__pk
-    primary key(role_id);
-
-
-create table hidden.role_privileges (
-    role_id        integer not null,
-    privilege_id   integer not null
-);
-
-alter table hidden.role_privileges add constraint role_privilege__pk
-    primary key(role_id, privilege_id);
-
-alter table hidden.role_privileges add constraint role_privilege__role_fk
-    foreign key(role_id)
-    references hidden.roles(role_id);
-
-alter table hidden.role_privileges add constraint role_privilege__priv_fk
-    foreign key(privilege_id)
-    references hidden.privileges(privilege_id);
-
-create table hidden.role_roles (
-    role_id        integer not null,
-    has_role_id        integer not null
-);
-
-alter table hidden.role_roles add constraint role_role__pk
-    primary key(role_id, has_role_id);
-
-alter table hidden.role_roles add constraint role_role__role_fk
-    foreign key(role_id)
-    references hidden.roles(role_id);
-
-alter table hidden.role_roles add constraint role_role__has_role_fk
-    foreign key(has_role_id)
-    references hidden.roles(role_id);
-
-
-create sequence person_id_seq;
-create table hidden.persons (
-    person_id      integer not null,
-    person_name        varchar(80) not null
-);
-alter table hidden.persons add constraint person__pk
-    primary key(person_id);
-
-
-create sequence project_id_seq;
-create table hidden.projects (
-    project_id     integer not null,
-    project_name   varchar(80) not null
-);
-alter table hidden.projects add constraint project__pk
-    primary key(project_id);
-
-
-create table hidden.detail_types (
-    detail_type_id   integer not null,
-    required_privilege_id integer not null,
-    detail_type_name     varchar(80) not null
-);
-alter table hidden.detail_types add constraint detail_type__pk
-    primary key(detail_type_id);
-
-alter table hidden.detail_types add constraint detail_type__priv_fk
-    foreign key(required_privilege_id)
-    references hidden.privileges(privilege_id);
-
-
-create table hidden.assignments (
-    project_id     integer not null,
-    person_id      integer not null,
-    role_id        integer not null
-);
-alter table hidden.assignments add constraint assignment__pk
-    primary key(project_id, person_id);
-
-alter table hidden.assignments add constraint assignment__project_fk
-    foreign key(project_id)
-    references hidden.projects(project_id);
-
-alter table hidden.assignments add constraint assignment__person_fk
-    foreign key(person_id)
-    references hidden.persons(person_id);
-
-alter table hidden.assignments add constraint assignment__role_fk
-    foreign key(role_id)
-    references hidden.roles(role_id);
-
-
-create table hidden.person_roles (
-    person_id      integer not null,
-    role_id        integer not null
-);
-alter table hidden.person_roles add constraint person_role__pk
-    primary key(person_id, role_id);
-
-alter table hidden.person_roles add constraint person_role__person_fk
-    foreign key(person_id)
-    references hidden.persons(person_id);
-
-alter table hidden.person_roles add constraint person_role__role_fk
-    foreign key(role_id)
-    references hidden.roles(role_id);
-
-
-create table hidden.project_details (
-    project_id     integer not null,
-    detail_type_id integer not null,
-    value      text not null
-);
-alter table hidden.project_details add constraint project_detail__pk
-    primary key(project_id, detail_type_id);
-
-alter table hidden.project_details add constraint project_detail__project_fk
-    foreign key(project_id)
-    references hidden.projects(project_id);
-
-alter table hidden.project_details add constraint project_detail__detail_fk
-    foreign key(detail_type_id)
-    references hidden.detail_types(detail_type_id);
-
-
-create table hidden.person_details (
-    person_id      integer not null,
-    detail_type_id integer not null,
-    value      text not null
-);
-alter table hidden.person_details add constraint person_detail__pk
-    primary key(person_id, detail_type_id);
-
-alter table hidden.person_details add constraint person_detail__person_fk
-    foreign key(person_id)
-    references hidden.persons(person_id);
-
-alter table hidden.person_details add constraint person_detail__detail_fk
-    foreign key(detail_type_id)
-    references hidden.detail_types(detail_type_id);
-
-
-insert into hidden.privileges (privilege_id, privilege_name) values
-(10001,    'select_privileges'),
-(10002,    'insert_privileges'),
-(10003,    'update_privileges'),
-(10004,    'delete_privileges'),
-(10005,    'select_roles'),
-(10006,    'insert_roles'),
-(10007,    'update_roles'),
-(10008,    'delete_roles'),
-(10009,    'select_role_privileges'),
-(10010,    'insert_role_privileges'),
-(10011,    'update_role_privileges'),
-(10012,    'delete_role_privileges'),
-(10013,    'select_persons'),
-(10014,    'insert_persons'),
-(10015,    'update_persons'),
-(10016,    'delete_persons'),
-(10017,    'select_projects'),
-(10018,    'insert_projects'),
-(10019,    'update_projects'),
-(10020,    'delete_projects'),
-(10021,    'select_detail_types'),
-(10022,    'insert_detail_types'),
-(10023,    'update_detail_types'),
-(10024,    'delete_detail_types'),
-(10025,    'select_assignments'),
-(10026,    'insert_assignments'),
-(10027,    'update_assignments'),
-(10028,    'delete_assignments'),
-(10029,    'select_person_roles'),
-(10030,    'insert_person_roles'),
-(10031,    'update_person_roles'),
-(10032,    'delete_person_roles'),
-(10033,    'select_project_details'),
-(10034,    'insert_project_details'),
-(10035,    'update_project_details'),
-(10036,    'delete_project_details'),
-(10037,    'select_person_details'),
-(10038,    'insert_person_details'),
-(10039,    'update_person_details'),
-(10040,    'delete_person_details'),
-(10041,    'select_role_roles'),
-(10042,    'insert_role_roles'),
-(10043,    'update_role_roles'),
-(10044,    'delete_role_roles'),
-(10100,    'can_connect'),
-(10150,    'view_basic'),
-(10151,    'view_personal'),
-(10152,    'view_personal_secure'),
-(10153,    'view_project_confidential');
-
-insert into hidden.roles (role_id, role_name) values
-(11001,    'DBA'),
-(11002,    'Personal Context'),
-(11003,    'Employee'),
-(11004,    'Worker'),
-(11005,    'Project Manager'),
-(11006,    'Director'),
-(11007,    'Manager');
-
--- DBA can do anything (but is not automatically an employee)
-insert into hidden.role_privileges (role_id, privilege_id)
-select 11001, privilege_id
-from   hidden.privileges
-where  privilege_id != 10100;
-
--- Personal Context allows update of personal details
-insert into hidden.role_privileges (role_id, privilege_id) values
-(11002,    10013),
-(11002,    10015),
-(11002,    10025),
-(11002,    10029),
-(11002,    10037),
-(11002,    10038),
-(11002,    10039),
-(11002,    10040),
-(11002,    10150),
-(11002,    10151),
-(11002,    10152);
-
--- Basic Access can see lookup data
-insert into hidden.role_privileges (role_id, privilege_id)
-select 11003, privilege_id
-from   hidden.privileges
-where  privilege_name in ('select_privileges', 'select_roles',
-             'select_role_privileges', 'select_detail_types');
-
-insert into hidden.role_privileges (role_id, privilege_id)
-select 11003, 10100;
-
--- Workers can modify project info
-insert into hidden.role_privileges (role_id, privilege_id)
-select 11004, privilege_id
-from   hidden.privileges
-where  privilege_name like '%project%'
-and    privilege_name not like 'delete%'
-and    privilege_name not like '%confidential';
-
-insert into hidden.role_privileges (role_id, privilege_id)
-select 11004, 10025;
-insert into hidden.role_privileges (role_id, privilege_id)
-select 11004, 10150;
-
--- Project Manager can do anything to project info and can see personal info
-insert into hidden.role_privileges (role_id, privilege_id)
-select 11005, privilege_id
-from   hidden.privileges
-where  privilege_name like '%project%'
-or     privilege_name like '%assignment%';
-
-insert into hidden.role_privileges (role_id, privilege_id)
-select 11005, privilege_id
-from   hidden.privileges
-where  privilege_name like 'select_person%';
-
-insert into hidden.role_privileges (role_id, privilege_id)
-select 11005, 10150;
-insert into hidden.role_privileges (role_id, privilege_id)
-select 11005, 10151;
-
--- Director can do anything except modify personal details
-insert into hidden.role_privileges (role_id, privilege_id)
-select 11006, privilege_id
-from   hidden.privileges
-where  privilege_name not like '%person%';
-
-insert into hidden.role_privileges (role_id, privilege_id)
-select 11006, privilege_id
-from   hidden.privileges
-where  privilege_name like 'select_person%';
-
-insert into hidden.role_privileges (role_id, privilege_id)
-select 11006, 10014;
-
-insert into hidden.role_privileges (role_id, privilege_id)
-select 11006, 10151;
-
-insert into hidden.role_privileges (role_id, privilege_id)
-select 11006, 10152;
-
--- Manager can see personal info
-insert into hidden.role_privileges (role_id, privilege_id)
-select 11007, privilege_id
-from   hidden.privileges
-where  privilege_name like 'select_person%';
-
-insert into hidden.role_privileges (role_id, privilege_id)
-select 11007, 10150;
-insert into hidden.role_privileges (role_id, privilege_id)
-select 11007, 10151;
-
-
-insert into hidden.persons (person_id, person_name) values
-(1, 'Deb (the DBA)'),
-(2, 'Pat (the PM)'),
-(3, 'Derick (the director)'),
-(4, 'Will (the worker)'),
-(5, 'Wilma (the worker)'),
-(6, 'Fred (the fired DBA)');
-
-insert into hidden.person_roles (person_id, role_id) values
-(1, 11001),
-(1, 11003),
-(2, 11003),
-(2, 11007),
-(3, 11003),
-(3, 11006),
-(4, 11003),
-(5, 11003),
-(6, 11001);
-
-insert into hidden.projects (project_id, project_name) values
-(101, 'Secret Project'),
-(102, 'Public project');
-
-insert into hidden.assignments (project_id, person_id, role_id) values
-(101, 3, 11005),
-(101, 5, 11004),
-(102, 2, 11005),
-(102, 4, 11004),
-(102, 5, 11004);
-
-insert into hidden.detail_types (detail_type_id, required_privilege_id, 
-                   detail_type_name) values
-(1001, 10150, 'start_date'),
-(1002, 10150, 'status'),
-(1003, 10150, 'join_date'),
-(1004, 10152, 'salary'),
-(1005, 10151, 'date of birth'),
-(1006, 10152, 'sin'),
-(1007, 10150, 'skills'),
-(1008, 10153, 'contract value');
-
-insert into hidden.person_details (person_id, detail_type_id, value) values
-(1, 1003, '20050102'),
-(2, 1003, '20050103'),
-(3, 1003, '20050104'),
-(4, 1003, '20050105'),
-(5, 1003, '20050106'),
-(6, 1003, '20050107'),
-(1, 1002, 'Employee'),
-(2, 1002, 'Employee'),
-(3, 1002, 'Employee'),
-(4, 1002, 'Employee'),
-(5, 1002, 'Employee'),
-(6, 1002, 'Terminated'),
-(1, 1004, '50,000'),
-(2, 1004, '50,000'),
-(3, 1004, '80,000'),
-(4, 1004, '30,000'),
-(5, 1004, '30,000'),
-(6, 1004, '40,000'),
-(1, 1005, '19610102'),
-(2, 1005, '19600102'),
-(3, 1005, '19650102'),
-(4, 1005, '19660102'),
-(5, 1005, '19670102'),
-(1, 1006, '123456789'),
-(2, 1006, '123456789'),
-(3, 1006, '123456789'),
-(4, 1006, '123456789'),
-(5, 1006, '123456789'),
-(1, 1007, 'Oracle, C, SQL'),
-(2, 1007, 'Soft peoply-stuff'),
-(3, 1007, 'None at all'),
-(4, 1007, 'Subservience'),
-(5, 1007, 'Subservience');
-
-
-insert into hidden.project_details (project_id, detail_type_id, value) values
-(101, 1001, '20050101'),
-(101, 1002, 'Secretly ongoing'),
-(101, 1008, '$800,000'),
-(102, 1001, '20050101'),
-(102, 1002, 'Ongoing'),
-(102, 1008, '$100,000');
-
-
--- Veil Variables:
---   Shared:
---     privs_range Range The range of privilege_id in the privileges table
---     roles_range Range The range of role_id in the roles table
---     role_privs Bitmap Array Array of privilege bitmaps indexed by role_id
---     det_types_range Range The range of detail_type_id in detail_types
---     det_types_privs Int4Array Mapping of detail_type_id to the privilege
---       required to access details of that type
---     
---   Session:
---     person_id Int4 The id of the currently connected person
---     global_context Bitmap The global privileges of the connected person
---     project_context Bitmap Hash Hash of privilege bitmaps, indexed by
---       project_id, giving the connected person's project privileges.
---
--- Security Contexts:
---   Global
---     Privileges are identified in variable global_context
---   Personal
---     Privileges are identified in role_privs[11002].
---   Project
---     A relational context.  Privileges are identified in
---     project_context[project_id].
-
--- Replacement for default version of veil_init.
--- Initialise and load all shared variables.
---
-create or replace
-function veil_init(bool) returns bool as '
-declare
-    doing_reset alias for $1;
-    exists_privs_range bool;
-    exists_roles_range bool;
-    exists_role_privs  bool;
-    exists_det_types_range bool;
-    exists_det_types_privs bool;
-    init_reqd bool;
-    dummy     bool;
-    dummy2    bool;
-    dummyint  int4;
-    _count    int4;
-begin
-    -- Declare all shared variables.
-
-    select into exists_privs_range, exists_roles_range,
-       exists_role_privs, exists_det_types_range,
-       exists_det_types_privs
-           veil_share(''privs_range''), veil_share(''roles_range''),
-      veil_share(''role_privs''), veil_share(''det_types_range''),
-      veil_share(''det_types_privs'');
-
-    init_reqd = not (exists_privs_range and exists_role_privs and
-            exists_role_privs and exists_det_types_range and
-            exists_det_types_privs);
-
-    if init_reqd or doing_reset then
-       -- Load ranges for privs and roles.
-       select into dummyint
-              veil_init_range(''roles_range'', min(role_id), max(role_id))
-       from   hidden.roles;
-
-       select into dummyint
-              veil_init_range(''privs_range'', min(privilege_id), 
-                     max(privilege_id))
-       from   hidden.privileges;
-
-   -- Load range for detail_types
-       select into dummyint
-              veil_init_range(''det_types_range'', 
-                      min(detail_type_id), max(detail_type_id))
-       from   hidden.detail_types;
-
-   -- Initialise array of required privs for detail_types
-       select into dummy
-              veil_init_int4array(''det_types_privs'', ''det_types_range'');
-       select into _count
-              count(veil_int4array_set(''det_types_privs'', 
-                               detail_type_id, required_privilege_id))
-       from   hidden.detail_types;
-
-       -- Initialise role_privs bitmap_array
-       select into dummy
-              veil_init_bitmap_array(''role_privs'', ''roles_range'', 
-                        ''privs_range'');
-
-       -- Populate role_privs bitmap_array
-       select into _count
-              count(veil_bitmap_array_setbit(''role_privs'', 
-                            role_id, privilege_id))
-       from   hidden.role_privileges;
-
-    end if;
-
-    -- Declare important session variables, so that we do not 
-    -- get odd, undefined variable, error messages.
-    select into dummyint, dummy, dummy2
-      veil_int4_set(''person_id'',  null),
-      veil_init_bitmap(''global_context'', ''privs_range''),
-      veil_init_bitmap_hash(''project_context'', ''privs_range'');
-
-    return true;               
-end;
-' language plpgsql
-stable 
-security definer;
-
-revoke execute on function veil_init(bool) from public;
-
-
-create or replace
-function connect_person(int4) returns bool as '
-declare
-    _person_id alias for $1;
-    dummy    int4;
-    _connect bool;
-    proj_roles record;
-    last_proj int4;
-    first_rec bool;
-begin
-    -- In reality this function would require some authentication token such 
-    -- as a password.  This is just a dumb demo version.
-
-    select into _connect disconnect_person();
-
-    -- Test whether provided person exists.  This is where we would, in a
-    -- real version, do proper authentication.
-    select into dummy 1
-    from   hidden.persons
-    where  person_id = _person_id;
-
-    if found then
-   -- The person exists and passes authentication
-
-   -- From the persons roles set the global_context bitmap.
-   select into dummy
-          count(veil_union_from_bitmap_array(''global_context'',
-                         ''role_privs'', role_id))
-   from   hidden.person_roles
-   where  person_id = _person_id;
-
-   -- Check that user has can_connect privilege
-   select into _connect
-       veil_bitmap_testbit(''global_context'', 10100);
-
-   if not _connect then
-       select into _connect disconnect_person();
-       return false;
-   end if;
-
-
-   -- From the persons assignments set the project_context bitmap hash.
-   select into dummy
-          count(veil_union_into_bitmap_hash(''project_context'',
-           project_id::text,
-           veil_bitmap_from_array(''scratch_bitmap'',
-                          ''role_privs'', role_id)))
-   from   hidden.assignments
-   where  person_id = _person_id;
-
-   -- Finally, record the person_id for the connection.
-   select into dummy veil_int4_set(''person_id'', _person_id);
-
-   return true;
-    else
-   return false;
-    end if;
-
-end;
-' language plpgsql
-stable 
-security definer;
-
-create or replace
-function disconnect_person() returns bool as '
-declare
-    dummy int4;
-    dummy2 bool;
-    dummy3 bool;
-begin
-    -- Clear session bitmaps, and reset the person_id
-    select into dummy, dummy2, dummy3
-      veil_int4_set(''person_id'', null),
-      veil_init_bitmap(''global_context'', ''privs_range''),
-      veil_init_bitmap_hash(''project_context'', ''privs_range'');
-    return false;
-end;
-' language plpgsql
-stable 
-security definer;
-
-
-create or replace
-function i_have_global_priv(int4) returns bool as '
-declare
-    priv_id alias for $1;
-    connection_id int4;
-    result bool;
-begin
-    select into connection_id, result 
-           veil_int4_get(''person_id''), 
-           veil_bitmap_testbit(''global_context'', priv_id);
-    if connection_id is null then
-   return false;
-    else
-        return result;
-    end if;
-end;
-' language plpgsql
-stable 
-security definer;
-
-
-create or replace
-function i_have_personal_priv(int4, int4) returns bool as '
-declare
-    priv_id alias for $1;
-    person_id alias for $2;
-    connection_id int4;
-    result bool;
-begin
-    select into connection_id, result 
-           veil_int4_get(''person_id''), 
-           veil_bitmap_testbit(''global_context'', priv_id);
-    if connection_id is null then
-   -- No-one is connected
-   return false;
-    else
-   if result then
-       -- We have the required privilege in global context.  No need
-       -- to check any further
-       return true;
-   else
-       if person_id = connection_id then
-       -- We are connected as the owner of this record.  Check
-       -- whether we have the required privilege in personal 
-       -- context.
-       select into result
-                  veil_bitmap_array_testbit(''role_privs'', 
-                           11002, priv_id);
-       return result;
-       else
-       -- We have no personal context rights to this record
-       return false;
-       end if;
-   end if;
-    end if;
-end;
-' language plpgsql
-stable 
-security definer;
-
-
-create or replace
-function i_have_project_priv(int4, int4) returns bool as '
-declare
-    priv_id alias for $1;
-    project_id alias for $2;
-    connection_id int4;
-    result bool;
-begin
-    select into connection_id, result 
-           veil_int4_get(''person_id''), 
-           veil_bitmap_testbit(''global_context'', priv_id);
-    if connection_id is null then
-   -- No-one is connected
-   return false;
-    else
-   if result then
-       -- We have the required privilege in global context.  No need
-       -- to check any further
-       return true;
-   else
-       select into result
-           veil_bitmap_hash_testbit(''project_context'', 
-                        project_id::text, priv_id);
-       return result;
-   end if;
-    end if;
-end;
-' language plpgsql
-stable 
-security definer;
-
-
-create or replace
-function i_have_proj_or_pers_priv(int4, int4, int4) returns bool as '
-declare
-    priv_id alias for $1;
-    project_id alias for $2;
-    person_id alias for $3;
-    connection_id int4;
-    result bool;
-begin
-    select into connection_id, result 
-           veil_int4_get(''person_id''), 
-           veil_bitmap_testbit(''global_context'', priv_id);
-    if connection_id is null then
-   -- No-one is connected
-   return false;
-    else
-   if result then
-       -- We have the required privilege in global context.  No need
-       -- to check any further
-       return true;
-   else
-       if person_id = connection_id then
-       -- We are connected as the owner of this record.  Check
-       -- whether we have the required privilege in personal 
-       -- context.
-       select into result
-                  veil_bitmap_array_testbit(''role_privs'', 
-                           11002, priv_id);
-       return result;
-       end if;
-       select into result
-           veil_bitmap_hash_testbit(''project_context'', 
-                        project_id::text, priv_id);
-       return result;
-       -- We have no personal context rights to this record
-       -- so check project context
-       return false;
-   end if;
-    end if;
-end;
-' language plpgsql
-stable 
-security definer;
-
-create or replace
-function i_have_project_detail_priv(int4, int4) returns bool as '
-declare
-    result bool;
-    detail_id alias for $1;
-    proj_id alias for $2;
-begin
-    select into result 
-        i_have_project_priv(veil_int4array_get(''det_types_privs'', detail_id),
-               proj_id);
-    return result;
-end;
-' language plpgsql
-stable 
-security definer;
-
-create or replace
-function i_have_person_detail_priv(int4, int4) returns bool as '
-declare
-    result bool;
-    detail_id alias for $1;
-    person_id alias for $2;
-begin
-    select into result 
-       i_have_personal_priv(veil_int4array_get(''det_types_privs'', detail_id),
-               person_id);
-    return result;
-end;
-' language plpgsql
-stable 
-security definer;
-
-create view privileges(
-       privilege_id,
-       privilege_name) as
-select privilege_id,
-       privilege_name
-from   hidden.privileges
-where  i_have_global_priv(10001);
-
-create rule ii_privileges as
-on insert to privileges
-do instead 
-    insert into hidden.privileges
-      (privilege_id, privilege_name)
-    select new.privilege_id, new.privilege_name 
-    where  i_have_global_priv(10002);
-
-create rule iu_privileges as
-on update to privileges
-do instead
-    update hidden.privileges
-    set    privilege_name = new.privilege_name,
-      privilege_id = new.privilege_id
-    where  privilege_id = old.privilege_id
-    and    i_have_global_priv(10003);
-create rule id_privileges as
-on delete to privileges
-do instead
-    delete from hidden.privileges
-    where  privilege_id = old.privilege_id
-    and    i_have_global_priv(10004);
-
-grant select, insert, update, delete on privileges to public;    
-
-create view roles(
-       role_id,
-       role_name) as
-select role_id,
-       role_name
-from   hidden.roles
-where  i_have_global_priv(10005);
-
-create rule ii_roles as
-on insert to roles
-do instead 
-    insert into hidden.roles
-      (role_id, role_name)
-    select new.role_id, new.role_name
-    where  i_have_global_priv(10006);
-
-create rule iu_roles as
-on update to roles
-do instead
-    update hidden.roles
-    set    role_name = new.role_name,
-      role_id = new.role_id
-    where  role_id = old.role_id
-    and    i_have_global_priv(10007);
-create rule id_roles as
-on delete to roles
-do instead
-    delete from hidden.roles
-    where  role_id = old.role_id
-    and    i_have_global_priv(10008);
-
-grant select, insert, update, delete on roles to public;    
-
-create view role_privileges(
-       role_id,
-       privilege_id) as
-select role_id,
-       privilege_id
-from   hidden.role_privileges
-where  i_have_global_priv(10009);
-
-create rule ii_role_privileges as
-on insert to role_privileges
-do instead 
-    insert into hidden.role_privileges
-      (role_id, privilege_id)
-    select new.role_id, new.privilege_id
-    where  i_have_global_priv(10010);
-
-create rule iu_role_privileges as
-on update to role_privileges
-do instead
-    update hidden.role_privileges
-    set    role_id = new.role_id, 
-      privilege_id = new.privilege_id
-    where  role_id = old.role_id
-    and    privilege_id = old.privilege_id
-    and    i_have_global_priv(10011);
-create rule id_role_privileges as
-on delete to role_privileges
-do instead
-    delete from hidden.role_privileges
-    where  role_id = old.role_id
-    and    i_have_global_priv(10012);
-
-grant select, insert, update, delete on role_privileges to public;    
-
-
-create view role_roles(
-       role_id,
-       has_role_id) as
-select role_id,
-       has_role_id
-from   hidden.role_roles
-where  i_have_global_priv(10041);
-
-create rule ii_role_roles as
-on insert to role_roles
-do instead 
-    insert into hidden.role_roles
-      (role_id, has_role_id)
-    select new.role_id, new.has_role_id
-    where  i_have_global_priv(10042);
-
-create rule iu_role_roles as
-on update to role_roles
-do instead
-    update hidden.role_roles
-    set    role_id = new.role_id,
-      has_role_id = new.has_role_id
-    where  role_id = old.role_id
-    and    i_have_global_priv(10043);
-create rule id_role_roles as
-on delete to role_roles
-do instead
-    delete from hidden.role_roles
-    where  role_id = old.role_id
-    and    i_have_global_priv(10044);
-
-grant select, insert, update, delete on role_roles to public;    
-
-
-create view persons(
-       person_id,
-       person_name) as
-select person_id,
-       person_name
-from   hidden.persons
-where  i_have_personal_priv(10013, person_id);
-
-create rule ii_persons as
-on insert to persons
-do instead 
-    insert into hidden.persons
-      (person_id, person_name)
-    select new.person_id, new.person_name
-    where  i_have_personal_priv(10014, new.person_id);
-
-create rule iu_persons as
-on update to persons
-do instead
-    update hidden.persons
-    set    person_id = new.person_id,
-      person_name = new.person_name
-    where  person_id = old.person_id
-    and    i_have_personal_priv(10015, old.person_id);
-create rule id_persons as
-on delete to persons
-do instead
-    delete from hidden.persons
-    where  person_id = old.person_id
-    and    i_have_personal_priv(10016, old.person_id);
-
-grant select, insert, update, delete on persons to public;    
-
-
-create view projects(
-       project_id,
-       project_name) as
-select project_id,
-       project_name
-from   hidden.projects
-where  i_have_project_priv(10017, project_id);
-
-create rule ii_projects as
-on insert to projects
-do instead 
-    insert into hidden.projects
-      (project_id, project_name)
-    select new.project_id, new.project_name
-    where  i_have_project_priv(10018, new.project_id);
-
-create rule iu_projects as
-on update to projects
-do instead
-    update hidden.projects
-    set    project_id = new.project_id,
-      project_name = new.project_name
-    where  project_id = old.project_id
-    and    i_have_project_priv(10019, old.project_id);
-create rule id_projects as
-on delete to projects
-do instead
-    delete from hidden.projects
-    where  project_id = old.project_id
-    and    i_have_project_priv(10020, old.project_id);
-
-grant select, insert, update, delete on projects to public;    
-
-
-create view detail_types (
-       detail_type_id,
-       required_privilege_id,
-       detail_type_name) as 
-select detail_type_id,
-       required_privilege_id,
-       detail_type_name
-from   hidden.detail_types
-where  i_have_global_priv(10021);
-
-create rule ii_detail_types as
-on insert to detail_types
-do instead 
-    insert into hidden.detail_types
-      (detail_type_id, detail_type_name)
-    select new.detail_type_id, new.detail_type_name
-    where  i_have_global_priv(10022);
-
-create rule iu_detail_types as
-on update to detail_types
-do instead
-    update hidden.detail_types
-    set    detail_type_id = new.detail_type_id, 
-      detail_type_name = new.detail_type_name
-    where  detail_type_id = old.detail_type_id
-    and    i_have_global_priv(10023);
-create rule id_detail_types as
-on delete to detail_types
-do instead
-    delete from hidden.detail_types
-    where  detail_type_id = old.detail_type_id
-    and    i_have_global_priv(10024);
-
-grant select, insert, update, delete on detail_types to public;    
-
-
-create view assignments (
-       project_id,
-       person_id,
-       role_id) as
-select project_id,
-       person_id,
-       role_id
-from   hidden.assignments
-where  i_have_proj_or_pers_priv(10025, project_id, person_id);
-
-create rule ii_assignments as
-on insert to assignments
-do instead 
-    insert into hidden.assignments
-      (project_id, person_id, role_id)
-    select new.project_id, new.person_id, new.role_id
-    where  i_have_proj_or_pers_priv(10026, new.project_id, new.person_id);
-
-create rule iu_assignments as
-on update to assignments
-do instead
-    update hidden.assignments
-    set    project_id = new.project_id,
-      person_id = new.person_id, 
-      role_id = new.person_id
-    where  project_id = old.project_id
-    and    person_id = old.person_id
-    and    i_have_proj_or_pers_priv(10027, old.project_id, old.person_id);
-create rule id_assignments as
-on delete to assignments
-do instead
-    delete from hidden.assignments
-    where  project_id = old.project_id
-    and    person_id = old.person_id
-    and    i_have_proj_or_pers_priv(10028, old.project_id, old.person_id);
-
-grant select, insert, update, delete on assignments to public;    
-
-
-create view person_roles (
-       person_id,
-       role_id) as
-select person_id,
-       role_id
-from   hidden.person_roles
-where  i_have_personal_priv(10029, person_id);
-
-create rule ii_person_roles as
-on insert to person_roles
-do instead 
-    insert into hidden.person_roles
-      (person_id, role_id)
-    select new.person_id, new.role_id
-    where  i_have_personal_priv(10030, new.person_id);
-
-create rule iu_person_roles as
-on update to person_roles
-do instead
-    update hidden.person_roles
-    set    person_id = new.person_id,
-      role_id = new.role_id
-    where  person_id = old.person_id
-    and    role_id = old.role_id
-    and    i_have_personal_priv(10031, old.person_id);
-create rule id_person_roles as
-on delete to person_roles
-do instead
-    delete from hidden.person_roles
-    where  person_id = old.person_id
-    and    role_id = old.role_id
-    and    i_have_personal_priv(10032, old.person_id);
-
-grant select, insert, update, delete on person_roles to public;    
-
-
-create view project_details (
-       project_id,
-       detail_type_id,
-       value) as
-select project_id,
-       detail_type_id,
-       value
-from   hidden.project_details
-where  i_have_project_priv(10033, project_id)
-and    i_have_project_detail_priv(detail_type_id, project_id);
-
-create rule ii_project_details as
-on insert to project_details
-do instead 
-    insert into hidden.project_details
-      (project_id, detail_type_id, value)
-    select new.project_id, new.detail_type_id, new.value
-    where  i_have_project_priv(10034, new.project_id)
-    and    i_have_project_detail_priv(new.detail_type_id, new.project_id);
-
-create rule iu_project_details as
-on update to project_details
-do instead
-    update hidden.project_details
-    set    project_id = new.project_id, 
-      detail_type_id = new.detail_type_id, 
-      value = new.value
-    where  project_id = old.project_id
-    and    detail_type_id = old.detail_type_id
-    and    i_have_project_priv(10035, old.project_id)
-    and    i_have_project_detail_priv(old.detail_type_id, old.project_id);
-create rule id_project_details as
-on delete to project_details
-do instead
-    delete from hidden.project_details
-    where  project_id = old.project_id
-    and    detail_type_id = old.detail_type_id
-    and    i_have_project_priv(10036, old.project_id)
-    and    i_have_project_detail_priv(old.detail_type_id, old.project_id);
-
-grant select, insert, update, delete on project_details to public;    
-
-
-create view person_details (
-       person_id,
-       detail_type_id,
-       value) as
-select person_id,
-       detail_type_id,
-       value
-from   hidden.person_details
-where  i_have_personal_priv(10037, person_id)
-and    i_have_person_detail_priv(detail_type_id, person_id);
-
-create rule ii_person_details as
-on insert to person_details
-do instead 
-    insert into hidden.person_details
-      (person_id, detail_type_id, value)
-    select new.person_id, new.detail_type_id, new.value
-    where  i_have_personal_priv(10038, new.person_id)
-    and    i_have_person_detail_priv(new.detail_type_id, new.person_id);
-
-create rule iu_person_details as
-on update to person_details
-do instead
-    update hidden.person_details
-    set    person_id = new.person_id, 
-      detail_type_id = new.detail_type_id, 
-      value = new.value
-    where  person_id = old.person_id
-    and    detail_type_id = old.detail_type_id
-    and    i_have_personal_priv(10039, old.person_id)
-    and    i_have_person_detail_priv(old.detail_type_id, old.person_id);
-create rule id_person_details as
-on delete to person_details
-do instead
-    delete from hidden.person_details
-    where  person_id = old.person_id
-    and    detail_type_id = old.detail_type_id
-    and    i_have_personal_priv(10040, old.person_id)
-    and    i_have_person_detail_priv(old.detail_type_id, old.person_id);
-
-
-grant select, insert, update, delete on person_details to public;    
-
-
-create or replace
-function global_privs_qry() returns setof int4 as '
-select * from veil_bitmap_bits(''global_context'');
-' language sql
-stable security definer;
-
-create or replace view my_global_privs (
-       privilege_id) as
-select * from global_privs_qry();
-
-grant select on my_global_privs to public;    
-
-
-create or replace
-function personal_privs_qry() returns setof int4 as '
-select * from veil_bitmap_array_bits(''role_privs'', 11002);
-' language sql
-stable security definer;
-
-create or replace view my_personal_privs (
-       privilege_id) as
-select * from personal_privs_qry();
-
-grant select on my_personal_privs to public;    
-
-
-create or replace
-function projects_qry() returns setof varchar as '
-select * from veil_bitmap_hash_entries(''project_context'');
-' language sql
-stable security definer;
-
-create or replace view my_projects (
-       project_id) as
-select * from projects_qry();
-
-grant select on my_projects to public;    
-
-
-create type hidden.proj_privs as (
-    project_id  int4,
-    privilege_id int4
-);
-
-create or replace
-function project_privs() returns setof hidden.proj_privs as '
-declare
-    _project record;
-    _priv    record;
-    _result  hidden.proj_privs;
-begin
-    for _project in 
-        select * from veil_bitmap_hash_entries(''project_context'')
-    loop
-        _result.project_id = _project.veil_bitmap_hash_entries;
-        for _priv in
-            select * from veil_bitmap_hash_bits(''project_context'', 
-                                                _result.project_id)
-        loop
-            _result.privilege_id = _priv.veil_bitmap_hash_bits;
-            return next _result;
-        end loop;
-    end loop;
-    return;
-end;
-' language plpgsql
-stable security definer;
-
-grant execute on function project_privs() to public;
-
-create or replace view my_project_privs (
-       project_id,
-       privilege_id) as
-select * from project_privs();
-
-grant select on my_project_privs to public;    
-
-
-create or replace view my_privs (
-    context,
-    project,
-    privilege_id,
-    privilege_name)
-as 
-select a.context, a.project, a.id, p.privilege_name
-from   (
-        select 'Project' as context, project_id as project,
-               privilege_id as id, 3 as seq
-        from   my_project_privs
-        union all
-        select 'Global', null, privilege_id, 1
-        from   my_global_privs
-        union all
-        select 'Personal', null, privilege_id, 2
-        from   my_personal_privs
-       ) a,
-       privileges p
-where  p.privilege_id = a.id
-order by a.seq, a.context, a.project, a.id;
-
-grant select on my_privs to public;