Rename plpgsql_1.out to plpgsq.out to match upstream
authorTomas Vondra <[email protected]>
Sat, 17 Jun 2017 19:09:21 +0000 (21:09 +0200)
committerTomas Vondra <[email protected]>
Sat, 17 Jun 2017 19:09:21 +0000 (21:09 +0200)
There's no plpgsql_1.out at the upstream, only plpgsql.out. So make it
consistent, which means the file will also receive upstream changes.

src/test/regress/expected/plpgsql.out
src/test/regress/expected/plpgsql_1.out [deleted file]

index 96d91fe48671909d8dfb715a8041937a80d01c62..e1185201e2b5b8af5951f62d93d97b8011269ee1 100644 (file)
@@ -35,7 +35,7 @@ create unique index WSlot_name on WSlot using btree (slotname bpchar_ops);
 create table PField (
     name       text,
     comment    text
-);
+) distribute by replication;
 create unique index PField_name on PField using btree (name text_ops);
 create table PSlot (
     slotname   char(20),
@@ -103,6 +103,8 @@ end;
 ' language plpgsql;
 create trigger tg_room_au after update
     on Room for each row execute procedure tg_room_au();
+ERROR:  Postgres-XL does not support TRIGGER yet
+DETAIL:  The feature is not currently supported
 -- ************************************************************
 -- * AFTER DELETE on Room
 -- *   - delete wall slots in this room
@@ -115,6 +117,8 @@ end;
 ' language plpgsql;
 create trigger tg_room_ad after delete
     on Room for each row execute procedure tg_room_ad();
+ERROR:  Postgres-XL does not support TRIGGER yet
+DETAIL:  The feature is not currently supported
 -- ************************************************************
 -- * BEFORE INSERT or UPDATE on WSlot
 -- *   - Check that room exists
@@ -129,6 +133,8 @@ end;
 $$ language plpgsql;
 create trigger tg_wslot_biu before insert or update
     on WSlot for each row execute procedure tg_wslot_biu();
+ERROR:  Postgres-XL does not support TRIGGER yet
+DETAIL:  The feature is not currently supported
 -- ************************************************************
 -- * AFTER UPDATE on PField
 -- *   - Let PSlots of this field follow
@@ -143,6 +149,8 @@ end;
 ' language plpgsql;
 create trigger tg_pfield_au after update
     on PField for each row execute procedure tg_pfield_au();
+ERROR:  Postgres-XL does not support TRIGGER yet
+DETAIL:  The feature is not currently supported
 -- ************************************************************
 -- * AFTER DELETE on PField
 -- *   - Remove all slots of this patchfield
@@ -155,6 +163,8 @@ end;
 ' language plpgsql;
 create trigger tg_pfield_ad after delete
     on PField for each row execute procedure tg_pfield_ad();
+ERROR:  Postgres-XL does not support TRIGGER yet
+DETAIL:  The feature is not currently supported
 -- ************************************************************
 -- * BEFORE INSERT or UPDATE on PSlot
 -- *   - Ensure that our patchfield does exist
@@ -173,6 +183,8 @@ end;
 $proc$ language plpgsql;
 create trigger tg_pslot_biu before insert or update
     on PSlot for each row execute procedure tg_pslot_biu();
+ERROR:  Postgres-XL does not support TRIGGER yet
+DETAIL:  The feature is not currently supported
 -- ************************************************************
 -- * AFTER UPDATE on System
 -- *   - If system name changes let interfaces follow
@@ -187,6 +199,8 @@ end;
 ' language plpgsql;
 create trigger tg_system_au after update
     on System for each row execute procedure tg_system_au();
+ERROR:  Postgres-XL does not support TRIGGER yet
+DETAIL:  The feature is not currently supported
 -- ************************************************************
 -- * BEFORE INSERT or UPDATE on IFace
 -- *   - set the slotname to IF.sysname.ifname
@@ -212,6 +226,8 @@ end;
 $$ language plpgsql;
 create trigger tg_iface_biu before insert or update
     on IFace for each row execute procedure tg_iface_biu();
+ERROR:  Postgres-XL does not support TRIGGER yet
+DETAIL:  The feature is not currently supported
 -- ************************************************************
 -- * AFTER INSERT or UPDATE or DELETE on Hub
 -- *   - insert/delete/rename slots as required
@@ -240,6 +256,8 @@ end;
 ' language plpgsql;
 create trigger tg_hub_a after insert or update or delete
     on Hub for each row execute procedure tg_hub_a();
+ERROR:  Postgres-XL does not support TRIGGER yet
+DETAIL:  The feature is not currently supported
 -- ************************************************************
 -- * Support function to add/remove slots of Hub
 -- ************************************************************
@@ -302,6 +320,8 @@ end;
 ' language plpgsql;
 create trigger tg_hslot_biu before insert or update
     on HSlot for each row execute procedure tg_hslot_biu();
+ERROR:  Postgres-XL does not support TRIGGER yet
+DETAIL:  The feature is not currently supported
 -- ************************************************************
 -- * BEFORE DELETE on HSlot
 -- *   - prevent from manual manipulation
@@ -322,6 +342,8 @@ end;
 ' language plpgsql;
 create trigger tg_hslot_bd before delete
     on HSlot for each row execute procedure tg_hslot_bd();
+ERROR:  Postgres-XL does not support TRIGGER yet
+DETAIL:  The feature is not currently supported
 -- ************************************************************
 -- * BEFORE INSERT on all slots
 -- *   - Check name prefix
@@ -336,14 +358,24 @@ end;
 ' language plpgsql;
 create trigger tg_chkslotname before insert
     on PSlot for each row execute procedure tg_chkslotname('PS');
+ERROR:  Postgres-XL does not support TRIGGER yet
+DETAIL:  The feature is not currently supported
 create trigger tg_chkslotname before insert
     on WSlot for each row execute procedure tg_chkslotname('WS');
+ERROR:  Postgres-XL does not support TRIGGER yet
+DETAIL:  The feature is not currently supported
 create trigger tg_chkslotname before insert
     on PLine for each row execute procedure tg_chkslotname('PL');
+ERROR:  Postgres-XL does not support TRIGGER yet
+DETAIL:  The feature is not currently supported
 create trigger tg_chkslotname before insert
     on IFace for each row execute procedure tg_chkslotname('IF');
+ERROR:  Postgres-XL does not support TRIGGER yet
+DETAIL:  The feature is not currently supported
 create trigger tg_chkslotname before insert
     on PHone for each row execute procedure tg_chkslotname('PH');
+ERROR:  Postgres-XL does not support TRIGGER yet
+DETAIL:  The feature is not currently supported
 -- ************************************************************
 -- * BEFORE INSERT or UPDATE on all slots with slotlink
 -- *   - Set slotlink to empty string if NULL value given
@@ -358,14 +390,24 @@ end;
 ' language plpgsql;
 create trigger tg_chkslotlink before insert or update
     on PSlot for each row execute procedure tg_chkslotlink();
+ERROR:  Postgres-XL does not support TRIGGER yet
+DETAIL:  The feature is not currently supported
 create trigger tg_chkslotlink before insert or update
     on WSlot for each row execute procedure tg_chkslotlink();
+ERROR:  Postgres-XL does not support TRIGGER yet
+DETAIL:  The feature is not currently supported
 create trigger tg_chkslotlink before insert or update
     on IFace for each row execute procedure tg_chkslotlink();
+ERROR:  Postgres-XL does not support TRIGGER yet
+DETAIL:  The feature is not currently supported
 create trigger tg_chkslotlink before insert or update
     on HSlot for each row execute procedure tg_chkslotlink();
+ERROR:  Postgres-XL does not support TRIGGER yet
+DETAIL:  The feature is not currently supported
 create trigger tg_chkslotlink before insert or update
     on PHone for each row execute procedure tg_chkslotlink();
+ERROR:  Postgres-XL does not support TRIGGER yet
+DETAIL:  The feature is not currently supported
 -- ************************************************************
 -- * BEFORE INSERT or UPDATE on all slots with backlink
 -- *   - Set backlink to empty string if NULL value given
@@ -380,10 +422,16 @@ end;
 ' language plpgsql;
 create trigger tg_chkbacklink before insert or update
     on PSlot for each row execute procedure tg_chkbacklink();
+ERROR:  Postgres-XL does not support TRIGGER yet
+DETAIL:  The feature is not currently supported
 create trigger tg_chkbacklink before insert or update
     on WSlot for each row execute procedure tg_chkbacklink();
+ERROR:  Postgres-XL does not support TRIGGER yet
+DETAIL:  The feature is not currently supported
 create trigger tg_chkbacklink before insert or update
     on PLine for each row execute procedure tg_chkbacklink();
+ERROR:  Postgres-XL does not support TRIGGER yet
+DETAIL:  The feature is not currently supported
 -- ************************************************************
 -- * BEFORE UPDATE on PSlot
 -- *   - do delete/insert instead of update if name changes
@@ -410,6 +458,8 @@ end;
 ' language plpgsql;
 create trigger tg_pslot_bu before update
     on PSlot for each row execute procedure tg_pslot_bu();
+ERROR:  Postgres-XL does not support TRIGGER yet
+DETAIL:  The feature is not currently supported
 -- ************************************************************
 -- * BEFORE UPDATE on WSlot
 -- *   - do delete/insert instead of update if name changes
@@ -436,6 +486,8 @@ end;
 ' language plpgsql;
 create trigger tg_wslot_bu before update
     on WSlot for each row execute procedure tg_Wslot_bu();
+ERROR:  Postgres-XL does not support TRIGGER yet
+DETAIL:  The feature is not currently supported
 -- ************************************************************
 -- * BEFORE UPDATE on PLine
 -- *   - do delete/insert instead of update if name changes
@@ -462,6 +514,8 @@ end;
 ' language plpgsql;
 create trigger tg_pline_bu before update
     on PLine for each row execute procedure tg_pline_bu();
+ERROR:  Postgres-XL does not support TRIGGER yet
+DETAIL:  The feature is not currently supported
 -- ************************************************************
 -- * BEFORE UPDATE on IFace
 -- *   - do delete/insert instead of update if name changes
@@ -488,6 +542,8 @@ end;
 ' language plpgsql;
 create trigger tg_iface_bu before update
     on IFace for each row execute procedure tg_iface_bu();
+ERROR:  Postgres-XL does not support TRIGGER yet
+DETAIL:  The feature is not currently supported
 -- ************************************************************
 -- * BEFORE UPDATE on HSlot
 -- *   - do delete/insert instead of update if name changes
@@ -514,6 +570,8 @@ end;
 ' language plpgsql;
 create trigger tg_hslot_bu before update
     on HSlot for each row execute procedure tg_hslot_bu();
+ERROR:  Postgres-XL does not support TRIGGER yet
+DETAIL:  The feature is not currently supported
 -- ************************************************************
 -- * BEFORE UPDATE on PHone
 -- *   - do delete/insert instead of update if name changes
@@ -538,6 +596,8 @@ end;
 ' language plpgsql;
 create trigger tg_phone_bu before update
     on PHone for each row execute procedure tg_phone_bu();
+ERROR:  Postgres-XL does not support TRIGGER yet
+DETAIL:  The feature is not currently supported
 -- ************************************************************
 -- * AFTER INSERT or UPDATE or DELETE on slot with backlink
 -- *   - Ensure that the opponent correctly points back to us
@@ -577,10 +637,16 @@ end;
 ' language plpgsql;
 create trigger tg_backlink_a after insert or update or delete
     on PSlot for each row execute procedure tg_backlink_a('PS');
+ERROR:  Postgres-XL does not support TRIGGER yet
+DETAIL:  The feature is not currently supported
 create trigger tg_backlink_a after insert or update or delete
     on WSlot for each row execute procedure tg_backlink_a('WS');
+ERROR:  Postgres-XL does not support TRIGGER yet
+DETAIL:  The feature is not currently supported
 create trigger tg_backlink_a after insert or update or delete
     on PLine for each row execute procedure tg_backlink_a('PL');
+ERROR:  Postgres-XL does not support TRIGGER yet
+DETAIL:  The feature is not currently supported
 -- ************************************************************
 -- * Support function to set the opponents backlink field
 -- * if it does not already point to the requested slot
@@ -719,14 +785,24 @@ end;
 ' language plpgsql;
 create trigger tg_slotlink_a after insert or update or delete
     on PSlot for each row execute procedure tg_slotlink_a('PS');
+ERROR:  Postgres-XL does not support TRIGGER yet
+DETAIL:  The feature is not currently supported
 create trigger tg_slotlink_a after insert or update or delete
     on WSlot for each row execute procedure tg_slotlink_a('WS');
+ERROR:  Postgres-XL does not support TRIGGER yet
+DETAIL:  The feature is not currently supported
 create trigger tg_slotlink_a after insert or update or delete
     on IFace for each row execute procedure tg_slotlink_a('IF');
+ERROR:  Postgres-XL does not support TRIGGER yet
+DETAIL:  The feature is not currently supported
 create trigger tg_slotlink_a after insert or update or delete
     on HSlot for each row execute procedure tg_slotlink_a('HS');
+ERROR:  Postgres-XL does not support TRIGGER yet
+DETAIL:  The feature is not currently supported
 create trigger tg_slotlink_a after insert or update or delete
     on PHone for each row execute procedure tg_slotlink_a('PH');
+ERROR:  Postgres-XL does not support TRIGGER yet
+DETAIL:  The feature is not currently supported
 -- ************************************************************
 -- * Support function to set the opponents slotlink field
 -- * if it does not already point to the requested slot
@@ -1146,8 +1222,8 @@ update PSlot set backlink = 'WS.001.1b' where slotname = 'PS.base.a3';
 select * from WSlot where roomno = '001' order by slotname;
        slotname       |  roomno  |       slotlink       |       backlink       
 ----------------------+----------+----------------------+----------------------
- WS.001.1a            | 001      |                      | PS.base.a1          
- WS.001.1b            | 001      |                      | PS.base.a3          
+ WS.001.1a            | 001      |                      |                     
+ WS.001.1b            | 001      |                      |                     
  WS.001.2a            | 001      |                      |                     
  WS.001.2b            | 001      |                      |                     
  WS.001.3a            | 001      |                      |                     
@@ -1169,9 +1245,9 @@ update PSlot set backlink = 'WS.001.2a' where slotname = 'PS.base.a3';
 select * from WSlot where roomno = '001' order by slotname;
        slotname       |  roomno  |       slotlink       |       backlink       
 ----------------------+----------+----------------------+----------------------
- WS.001.1a            | 001      |                      | PS.base.a1          
+ WS.001.1a            | 001      |                      |                     
  WS.001.1b            | 001      |                      |                     
- WS.001.2a            | 001      |                      | PS.base.a3          
+ WS.001.2a            | 001      |                      |                     
  WS.001.2b            | 001      |                      |                     
  WS.001.3a            | 001      |                      |                     
  WS.001.3b            | 001      |                      |                     
@@ -1192,9 +1268,9 @@ update PSlot set backlink = 'WS.001.1b' where slotname = 'PS.base.a2';
 select * from WSlot where roomno = '001' order by slotname;
        slotname       |  roomno  |       slotlink       |       backlink       
 ----------------------+----------+----------------------+----------------------
- WS.001.1a            | 001      |                      | PS.base.a1          
- WS.001.1b            | 001      |                      | PS.base.a2          
- WS.001.2a            | 001      |                      | PS.base.a3          
+ WS.001.1a            | 001      |                      |                     
+ WS.001.1b            | 001      |                      |                     
+ WS.001.2a            | 001      |                      |                     
  WS.001.2b            | 001      |                      |                     
  WS.001.3a            | 001      |                      |                     
  WS.001.3b            | 001      |                      |                     
@@ -1221,9 +1297,9 @@ update WSlot set backlink = 'PS.base.a6' where slotname = 'WS.001.3a';
 select * from WSlot where roomno = '001' order by slotname;
        slotname       |  roomno  |       slotlink       |       backlink       
 ----------------------+----------+----------------------+----------------------
- WS.001.1a            | 001      |                      | PS.base.a1          
- WS.001.1b            | 001      |                      | PS.base.a2          
- WS.001.2a            | 001      |                      | PS.base.a3          
+ WS.001.1a            | 001      |                      |                     
+ WS.001.1b            | 001      |                      |                     
+ WS.001.2a            | 001      |                      |                     
  WS.001.2b            | 001      |                      | PS.base.a4          
  WS.001.3a            | 001      |                      | PS.base.a6          
  WS.001.3b            | 001      |                      |                     
@@ -1235,20 +1311,20 @@ select * from PSlot where slotname ~ 'PS.base.a' order by slotname;
  PS.base.a1           | PF0_1  |                      | WS.001.1a           
  PS.base.a2           | PF0_1  |                      | WS.001.1b           
  PS.base.a3           | PF0_1  |                      | WS.001.2a           
- PS.base.a4           | PF0_1  |                      | WS.001.2b           
+ PS.base.a4           | PF0_1  |                      |                     
  PS.base.a5           | PF0_1  |                      |                     
- PS.base.a6           | PF0_1  |                      | WS.001.3a           
+ PS.base.a6           | PF0_1  |                      |                     
 (6 rows)
 
 update WSlot set backlink = 'PS.base.a6' where slotname = 'WS.001.3b';
 select * from WSlot where roomno = '001' order by slotname;
        slotname       |  roomno  |       slotlink       |       backlink       
 ----------------------+----------+----------------------+----------------------
- WS.001.1a            | 001      |                      | PS.base.a1          
- WS.001.1b            | 001      |                      | PS.base.a2          
- WS.001.2a            | 001      |                      | PS.base.a3          
+ WS.001.1a            | 001      |                      |                     
+ WS.001.1b            | 001      |                      |                     
+ WS.001.2a            | 001      |                      |                     
  WS.001.2b            | 001      |                      | PS.base.a4          
- WS.001.3a            | 001      |                      |                     
+ WS.001.3a            | 001      |                      | PS.base.a6          
  WS.001.3b            | 001      |                      | PS.base.a6          
 (6 rows)
 
@@ -1258,18 +1334,18 @@ select * from PSlot where slotname ~ 'PS.base.a' order by slotname;
  PS.base.a1           | PF0_1  |                      | WS.001.1a           
  PS.base.a2           | PF0_1  |                      | WS.001.1b           
  PS.base.a3           | PF0_1  |                      | WS.001.2a           
- PS.base.a4           | PF0_1  |                      | WS.001.2b           
+ PS.base.a4           | PF0_1  |                      |                     
  PS.base.a5           | PF0_1  |                      |                     
- PS.base.a6           | PF0_1  |                      | WS.001.3b           
+ PS.base.a6           | PF0_1  |                      |                     
 (6 rows)
 
 update WSlot set backlink = 'PS.base.a5' where slotname = 'WS.001.3a';
 select * from WSlot where roomno = '001' order by slotname;
        slotname       |  roomno  |       slotlink       |       backlink       
 ----------------------+----------+----------------------+----------------------
- WS.001.1a            | 001      |                      | PS.base.a1          
- WS.001.1b            | 001      |                      | PS.base.a2          
- WS.001.2a            | 001      |                      | PS.base.a3          
+ WS.001.1a            | 001      |                      |                     
+ WS.001.1b            | 001      |                      |                     
+ WS.001.2a            | 001      |                      |                     
  WS.001.2b            | 001      |                      | PS.base.a4          
  WS.001.3a            | 001      |                      | PS.base.a5          
  WS.001.3b            | 001      |                      | PS.base.a6          
@@ -1281,9 +1357,9 @@ select * from PSlot where slotname ~ 'PS.base.a' order by slotname;
  PS.base.a1           | PF0_1  |                      | WS.001.1a           
  PS.base.a2           | PF0_1  |                      | WS.001.1b           
  PS.base.a3           | PF0_1  |                      | WS.001.2a           
- PS.base.a4           | PF0_1  |                      | WS.001.2b           
- PS.base.a5           | PF0_1  |                      | WS.001.3a           
- PS.base.a6           | PF0_1  |                      | WS.001.3b           
+ PS.base.a4           | PF0_1  |                      |                     
+ PS.base.a5           | PF0_1  |                      |                     
+ PS.base.a6           | PF0_1  |                      |                     
 (6 rows)
 
 insert into PField values ('PF1_2', 'Phonelines first floor');
@@ -1309,9 +1385,9 @@ select * from PSlot order by slotname;
  PS.base.a1           | PF0_1  |                      | WS.001.1a           
  PS.base.a2           | PF0_1  |                      | WS.001.1b           
  PS.base.a3           | PF0_1  |                      | WS.001.2a           
- PS.base.a4           | PF0_1  |                      | WS.001.2b           
- PS.base.a5           | PF0_1  |                      | WS.001.3a           
- PS.base.a6           | PF0_1  |                      | WS.001.3b           
+ PS.base.a4           | PF0_1  |                      |                     
+ PS.base.a5           | PF0_1  |                      |                     
+ PS.base.a6           | PF0_1  |                      |                     
  PS.base.b1           | PF0_1  |                      | WS.002.1a           
  PS.base.b2           | PF0_1  |                      | WS.002.1b           
  PS.base.b3           | PF0_1  |                      | WS.002.2a           
@@ -1324,18 +1400,18 @@ select * from PSlot order by slotname;
  PS.base.c4           | PF0_1  |                      | WS.003.2b           
  PS.base.c5           | PF0_1  |                      | WS.003.3a           
  PS.base.c6           | PF0_1  |                      | WS.003.3b           
- PS.base.ta1          | PF0_2  |                      |                     
- PS.base.ta2          | PF0_2  |                      |                     
- PS.base.ta3          | PF0_2  |                      |                     
- PS.base.ta4          | PF0_2  |                      |                     
- PS.base.ta5          | PF0_2  |                      |                     
- PS.base.ta6          | PF0_2  |                      |                     
- PS.base.tb1          | PF0_2  |                      |                     
- PS.base.tb2          | PF0_2  |                      |                     
- PS.base.tb3          | PF0_2  |                      |                     
- PS.base.tb4          | PF0_2  |                      |                     
- PS.base.tb5          | PF0_2  |                      |                     
- PS.base.tb6          | PF0_2  |                      |                     
+ PS.base.ta1          | PF0_X  |                      |                     
+ PS.base.ta2          | PF0_X  |                      |                     
+ PS.base.ta3          | PF0_X  |                      |                     
+ PS.base.ta4          | PF0_X  |                      |                     
+ PS.base.ta5          | PF0_X  |                      |                     
+ PS.base.ta6          | PF0_X  |                      |                     
+ PS.base.tb1          | PF0_X  |                      |                     
+ PS.base.tb2          | PF0_X  |                      |                     
+ PS.base.tb3          | PF0_X  |                      |                     
+ PS.base.tb4          | PF0_X  |                      |                     
+ PS.base.tb5          | PF0_X  |                      |                     
+ PS.base.tb6          | PF0_X  |                      |                     
  PS.first.a1          | PF1_1  |                      | WS.101.1a           
  PS.first.a2          | PF1_1  |                      | WS.101.1b           
  PS.first.a3          | PF1_1  |                      | WS.101.2a           
@@ -1377,48 +1453,48 @@ select * from PSlot order by slotname;
 select * from WSlot order by slotname;
        slotname       |  roomno  |       slotlink       |       backlink       
 ----------------------+----------+----------------------+----------------------
- WS.001.1a            | 001      |                      | PS.base.a1          
- WS.001.1b            | 001      |                      | PS.base.a2          
- WS.001.2a            | 001      |                      | PS.base.a3          
+ WS.001.1a            | 001      |                      |                     
+ WS.001.1b            | 001      |                      |                     
+ WS.001.2a            | 001      |                      |                     
  WS.001.2b            | 001      |                      | PS.base.a4          
  WS.001.3a            | 001      |                      | PS.base.a5          
  WS.001.3b            | 001      |                      | PS.base.a6          
- WS.002.1a            | 002      |                      | PS.base.b1          
- WS.002.1b            | 002      |                      | PS.base.b2          
- WS.002.2a            | 002      |                      | PS.base.b3          
- WS.002.2b            | 002      |                      | PS.base.b4          
- WS.002.3a            | 002      |                      | PS.base.b5          
- WS.002.3b            | 002      |                      | PS.base.b6          
- WS.003.1a            | 003      |                      | PS.base.c1          
- WS.003.1b            | 003      |                      | PS.base.c2          
- WS.003.2a            | 003      |                      | PS.base.c3          
- WS.003.2b            | 003      |                      | PS.base.c4          
- WS.003.3a            | 003      |                      | PS.base.c5          
- WS.003.3b            | 003      |                      | PS.base.c6          
- WS.101.1a            | 101      |                      | PS.first.a1         
- WS.101.1b            | 101      |                      | PS.first.a2         
- WS.101.2a            | 101      |                      | PS.first.a3         
- WS.101.2b            | 101      |                      | PS.first.a4         
- WS.101.3a            | 101      |                      | PS.first.a5         
- WS.101.3b            | 101      |                      | PS.first.a6         
- WS.102.1a            | 102      |                      | PS.first.b1         
- WS.102.1b            | 102      |                      | PS.first.b2         
- WS.102.2a            | 102      |                      | PS.first.b3         
- WS.102.2b            | 102      |                      | PS.first.b4         
- WS.102.3a            | 102      |                      | PS.first.b5         
- WS.102.3b            | 102      |                      | PS.first.b6         
- WS.105.1a            | 105      |                      | PS.first.c1         
- WS.105.1b            | 105      |                      | PS.first.c2         
- WS.105.2a            | 105      |                      | PS.first.c3         
- WS.105.2b            | 105      |                      | PS.first.c4         
- WS.105.3a            | 105      |                      | PS.first.c5         
- WS.105.3b            | 105      |                      | PS.first.c6         
- WS.106.1a            | 106      |                      | PS.first.d1         
- WS.106.1b            | 106      |                      | PS.first.d2         
- WS.106.2a            | 106      |                      | PS.first.d3         
- WS.106.2b            | 106      |                      | PS.first.d4         
- WS.106.3a            | 106      |                      | PS.first.d5         
- WS.106.3b            | 106      |                      | PS.first.d6         
+ WS.002.1a            | 002      |                      |                     
+ WS.002.1b            | 002      |                      |                     
+ WS.002.2a            | 002      |                      |                     
+ WS.002.2b            | 002      |                      |                     
+ WS.002.3a            | 002      |                      |                     
+ WS.002.3b            | 002      |                      |                     
+ WS.003.1a            | 003      |                      |                     
+ WS.003.1b            | 003      |                      |                     
+ WS.003.2a            | 003      |                      |                     
+ WS.003.2b            | 003      |                      |                     
+ WS.003.3a            | 003      |                      |                     
+ WS.003.3b            | 003      |                      |                     
+ WS.101.1a            | 101      |                      |                     
+ WS.101.1b            | 101      |                      |                     
+ WS.101.2a            | 101      |                      |                     
+ WS.101.2b            | 101      |                      |                     
+ WS.101.3a            | 101      |                      |                     
+ WS.101.3b            | 101      |                      |                     
+ WS.102.1a            | 102      |                      |                     
+ WS.102.1b            | 102      |                      |                     
+ WS.102.2a            | 102      |                      |                     
+ WS.102.2b            | 102      |                      |                     
+ WS.102.3a            | 102      |                      |                     
+ WS.102.3b            | 102      |                      |                     
+ WS.105.1a            | 105      |                      |                     
+ WS.105.1b            | 105      |                      |                     
+ WS.105.2a            | 105      |                      |                     
+ WS.105.2b            | 105      |                      |                     
+ WS.105.3a            | 105      |                      |                     
+ WS.105.3b            | 105      |                      |                     
+ WS.106.1a            | 106      |                      |                     
+ WS.106.1b            | 106      |                      |                     
+ WS.106.2a            | 106      |                      |                     
+ WS.106.2b            | 106      |                      |                     
+ WS.106.3a            | 106      |                      |                     
+ WS.106.3b            | 106      |                      |                     
 (42 rows)
 
 --
@@ -1470,45 +1546,34 @@ update PSlot set slotlink = 'HS.base.hub1.1' where slotname = 'PS.base.b2';
 --
 -- Now we take a look at the patchfield
 --
+-- PGXCTODO: This is failing due to issue 3522907, complicated SELECT queries in plpgsql functions
 select * from PField_v1 where pfname = 'PF0_1' order by slotname;
- pfname |       slotname       |                         backside                         |                     patch                     
---------+----------------------+----------------------------------------------------------+-----------------------------------------------
- PF0_1  | PS.base.a1           | WS.001.1a in room 001 -> Phone PH.hc001 (Hicom standard) | PS.base.ta1 -> Phone line -0 (Central call)
- PF0_1  | PS.base.a2           | WS.001.1b in room 001 -> -                               | -
- PF0_1  | PS.base.a3           | WS.001.2a in room 001 -> Phone PH.fax001 (Canon fax)     | PS.base.ta2 -> Phone line -501 (Fax entrance)
- PF0_1  | PS.base.a4           | WS.001.2b in room 001 -> -                               | -
- PF0_1  | PS.base.a5           | WS.001.3a in room 001 -> -                               | -
- PF0_1  | PS.base.a6           | WS.001.3b in room 001 -> -                               | -
- PF0_1  | PS.base.b1           | WS.002.1a in room 002 -> Phone PH.hc002 (Hicom standard) | PS.base.ta5 -> Phone line -103
- PF0_1  | PS.base.b2           | WS.002.1b in room 002 -> orion IF eth0 (PC)              | Patchfield PF0_1 hub slot 1
- PF0_1  | PS.base.b3           | WS.002.2a in room 002 -> Phone PH.hc003 (Hicom standard) | PS.base.tb2 -> Phone line -106
- PF0_1  | PS.base.b4           | WS.002.2b in room 002 -> -                               | -
- PF0_1  | PS.base.b5           | WS.002.3a in room 002 -> -                               | -
- PF0_1  | PS.base.b6           | WS.002.3b in room 002 -> -                               | -
- PF0_1  | PS.base.c1           | WS.003.1a in room 003 -> -                               | -
- PF0_1  | PS.base.c2           | WS.003.1b in room 003 -> -                               | -
- PF0_1  | PS.base.c3           | WS.003.2a in room 003 -> -                               | -
- PF0_1  | PS.base.c4           | WS.003.2b in room 003 -> -                               | -
- PF0_1  | PS.base.c5           | WS.003.3a in room 003 -> -                               | -
- PF0_1  | PS.base.c6           | WS.003.3b in room 003 -> -                               | -
+ pfname |       slotname       |          backside          |      patch      
+--------+----------------------+----------------------------+-----------------
+ PF0_1  | PS.base.a1           | WS.001.1a in room 001 -> - | PS.base.ta1 -> 
+ PF0_1  | PS.base.a2           |                            | -
+ PF0_1  | PS.base.a3           | WS.001.2a in room 001 -> - | PS.base.ta2 -> 
+ PF0_1  | PS.base.a4           | -                          | -
+ PF0_1  | PS.base.a5           | -                          | -
+ PF0_1  | PS.base.a6           | -                          | -
+ PF0_1  | PS.base.b1           |                            | PS.base.ta5 -> 
+ PF0_1  | PS.base.b2           |                            | 
+ PF0_1  | PS.base.b3           |                            | PS.base.tb2 -> 
+ PF0_1  | PS.base.b4           |                            | -
+ PF0_1  | PS.base.b5           | WS.002.3a in room 002 -> - | -
+ PF0_1  | PS.base.b6           |                            | -
+ PF0_1  | PS.base.c1           | WS.003.1a in room 003 -> - | -
+ PF0_1  | PS.base.c2           | WS.003.1b in room 003 -> - | -
+ PF0_1  | PS.base.c3           | WS.003.2a in room 003 -> - | -
+ PF0_1  | PS.base.c4           |                            | -
+ PF0_1  | PS.base.c5           | WS.003.3a in room 003 -> - | -
+ PF0_1  | PS.base.c6           |                            | -
 (18 rows)
 
 select * from PField_v1 where pfname = 'PF0_2' order by slotname;
- pfname |       slotname       |            backside            |                                 patch                                  
---------+----------------------+--------------------------------+------------------------------------------------------------------------
- PF0_2  | PS.base.ta1          | Phone line -0 (Central call)   | PS.base.a1 -> WS.001.1a in room 001 -> Phone PH.hc001 (Hicom standard)
- PF0_2  | PS.base.ta2          | Phone line -501 (Fax entrance) | PS.base.a3 -> WS.001.2a in room 001 -> Phone PH.fax001 (Canon fax)
- PF0_2  | PS.base.ta3          | Phone line -102                | -
- PF0_2  | PS.base.ta4          | -                              | -
- PF0_2  | PS.base.ta5          | Phone line -103                | PS.base.b1 -> WS.002.1a in room 002 -> Phone PH.hc002 (Hicom standard)
- PF0_2  | PS.base.ta6          | Phone line -104                | -
- PF0_2  | PS.base.tb1          | -                              | -
- PF0_2  | PS.base.tb2          | Phone line -106                | PS.base.b3 -> WS.002.2a in room 002 -> Phone PH.hc003 (Hicom standard)
- PF0_2  | PS.base.tb3          | Phone line -108                | -
- PF0_2  | PS.base.tb4          | Phone line -109                | -
- PF0_2  | PS.base.tb5          | Phone line -121                | -
- PF0_2  | PS.base.tb6          | Phone line -122                | -
-(12 rows)
+ pfname | slotname | backside | patch 
+--------+----------+----------+-------
+(0 rows)
 
 --
 -- Finally we want errors
@@ -1517,36 +1582,20 @@ insert into PField values ('PF1_1', 'should fail due to unique index');
 ERROR:  duplicate key value violates unique constraint "pfield_name"
 DETAIL:  Key (name)=(PF1_1) already exists.
 update PSlot set backlink = 'WS.not.there' where slotname = 'PS.base.a1';
-ERROR:  WS.not.there         does not exist
-CONTEXT:  PL/pgSQL function tg_backlink_set(character,character) line 30 at RAISE
-PL/pgSQL function tg_backlink_a() line 17 at assignment
 update PSlot set backlink = 'XX.illegal' where slotname = 'PS.base.a1';
-ERROR:  illegal backlink beginning with XX
-CONTEXT:  PL/pgSQL function tg_backlink_set(character,character) line 47 at RAISE
-PL/pgSQL function tg_backlink_a() line 17 at assignment
 update PSlot set slotlink = 'PS.not.there' where slotname = 'PS.base.a1';
-ERROR:  PS.not.there         does not exist
-CONTEXT:  PL/pgSQL function tg_slotlink_set(character,character) line 30 at RAISE
-PL/pgSQL function tg_slotlink_a() line 17 at assignment
 update PSlot set slotlink = 'XX.illegal' where slotname = 'PS.base.a1';
-ERROR:  illegal slotlink beginning with XX
-CONTEXT:  PL/pgSQL function tg_slotlink_set(character,character) line 77 at RAISE
-PL/pgSQL function tg_slotlink_a() line 17 at assignment
 insert into HSlot values ('HS', 'base.hub1', 1, '');
-ERROR:  duplicate key value violates unique constraint "hslot_name"
-DETAIL:  Key (slotname)=(HS.base.hub1.1      ) already exists.
 insert into HSlot values ('HS', 'base.hub1', 20, '');
-ERROR:  no manual manipulation of HSlot
-CONTEXT:  PL/pgSQL function tg_hslot_biu() line 12 at RAISE
+ERROR:  duplicate key value violates unique constraint "hslot_name"
+DETAIL:  Key (slotname)=(HS                  ) already exists.
 delete from HSlot;
-ERROR:  no manual manipulation of HSlot
-CONTEXT:  PL/pgSQL function tg_hslot_bd() line 12 at RAISE
 insert into IFace values ('IF', 'notthere', 'eth0', '');
-ERROR:  system "notthere" does not exist
-CONTEXT:  PL/pgSQL function tg_iface_biu() line 8 at RAISE
+ERROR:  duplicate key value violates unique constraint "iface_name"
+DETAIL:  Key (slotname)=(IF                  ) already exists.
 insert into IFace values ('IF', 'orion', 'ethernet_interface_name_too_long', '');
-ERROR:  IFace slotname "IF.orion.ethernet_interface_name_too_long" too long (20 char max)
-CONTEXT:  PL/pgSQL function tg_iface_biu() line 14 at RAISE
+ERROR:  duplicate key value violates unique constraint "iface_name"
+DETAIL:  Key (slotname)=(IF                  ) already exists.
 --
 -- The following tests are unrelated to the scenario outlined above;
 -- they merely exercise specific parts of PL/pgSQL
@@ -1573,7 +1622,7 @@ SELECT recursion_test(4,3);
 --
 -- Test the FOUND magic variable
 --
-CREATE TABLE found_test_tbl (a int);
+CREATE TABLE found_test_tbl (a int) distribute by roundrobin;
 create function test_found()
   returns boolean as '
   declare
@@ -1941,37 +1990,17 @@ begin
        return x;
 end$$ language plpgsql;
 select trap_zero_divide(50);
-NOTICE:  should see this
-NOTICE:  should see this only if 50 <> 0
-NOTICE:  should see this only if 50 fits in smallint
- trap_zero_divide 
-------------------
-                2
-(1 row)
-
+ERROR:  Internal subtransactions not supported in Postgres-XL
+CONTEXT:  PL/pgSQL function trap_zero_divide(integer) line 5 during statement block entry
 select trap_zero_divide(0);
-NOTICE:  should see this
-NOTICE:  caught division_by_zero
- trap_zero_divide 
-------------------
-               -1
-(1 row)
-
+ERROR:  Internal subtransactions not supported in Postgres-XL
+CONTEXT:  PL/pgSQL function trap_zero_divide(integer) line 5 during statement block entry
 select trap_zero_divide(100000);
-NOTICE:  should see this
-NOTICE:  should see this only if 100000 <> 0
-NOTICE:  caught numeric_value_out_of_range
- trap_zero_divide 
-------------------
-               -2
-(1 row)
-
+ERROR:  Internal subtransactions not supported in Postgres-XL
+CONTEXT:  PL/pgSQL function trap_zero_divide(integer) line 5 during statement block entry
 select trap_zero_divide(-100);
-NOTICE:  should see this
-NOTICE:  should see this only if -100 <> 0
-NOTICE:  should see this only if -100 fits in smallint
-ERROR:  -100 is less than zero
-CONTEXT:  PL/pgSQL function trap_zero_divide(integer) line 12 at RAISE
+ERROR:  Internal subtransactions not supported in Postgres-XL
+CONTEXT:  PL/pgSQL function trap_zero_divide(integer) line 5 during statement block entry
 create function trap_matching_test(int) returns int as $$
 declare x int;
        sx smallint;
@@ -1992,33 +2021,20 @@ begin
        end;
        return x;
 end$$ language plpgsql;
+-- PGXCTODO: This is failing due to issue 3522907, complicated SELECT queries in plpgsql functions
 select trap_matching_test(50);
- trap_matching_test 
---------------------
-                  2
-(1 row)
-
+ERROR:  Internal subtransactions not supported in Postgres-XL
+CONTEXT:  PL/pgSQL function trap_matching_test(integer) line 6 during statement block entry
 select trap_matching_test(0);
-NOTICE:  caught data_exception
- trap_matching_test 
---------------------
-                 -1
-(1 row)
-
+ERROR:  Internal subtransactions not supported in Postgres-XL
+CONTEXT:  PL/pgSQL function trap_matching_test(integer) line 6 during statement block entry
 select trap_matching_test(100000);
-NOTICE:  caught data_exception
- trap_matching_test 
---------------------
-                 -1
-(1 row)
-
+ERROR:  Internal subtransactions not supported in Postgres-XL
+CONTEXT:  PL/pgSQL function trap_matching_test(integer) line 6 during statement block entry
+-- PGXCTODO: This is failing due to issue 3522907, complicated SELECT queries in plpgsql functions
 select trap_matching_test(1);
-NOTICE:  caught numeric_value_out_of_range or cardinality_violation
- trap_matching_test 
---------------------
-                 -2
-(1 row)
-
+ERROR:  Internal subtransactions not supported in Postgres-XL
+CONTEXT:  PL/pgSQL function trap_matching_test(integer) line 6 during statement block entry
 create temp table foo (f1 int);
 create function subxact_rollback_semantics() returns int as $$
 declare x int;
@@ -2037,18 +2053,13 @@ begin
   return x;
 end$$ language plpgsql;
 select subxact_rollback_semantics();
- subxact_rollback_semantics 
-----------------------------
-                         20
-(1 row)
-
-reset statement_timeout;
-select * from foo order by 1;
+ERROR:  Internal subtransactions not supported in Postgres-XL
+CONTEXT:  PL/pgSQL function subxact_rollback_semantics() line 6 during statement block entry
+select * from foo;
  f1 
 ----
   1
- 20
-(2 rows)
+(1 row)
 
 drop table foo;
 create function trap_timeout() returns void as $$
@@ -2070,9 +2081,8 @@ end$$ language plpgsql;
 begin;
 set statement_timeout to 2000;
 select trap_timeout();
-NOTICE:  nyeah nyeah, can't stop me
-ERROR:  end of function
-CONTEXT:  PL/pgSQL function trap_timeout() line 15 at RAISE
+ERROR:  Internal subtransactions not supported in Postgres-XL
+CONTEXT:  PL/pgSQL function trap_timeout() line 4 during statement block entry
 rollback;
 -- Test for pass-by-ref values being stored in proper context
 create function test_variable_storage() returns text as $$
@@ -2090,14 +2100,8 @@ begin
   return x;
 end$$ language plpgsql;
 select test_variable_storage();
-NOTICE:  should see this
-NOTICE:  should see this only if -100 <> 0
-NOTICE:  should see this only if -100 fits in smallint
- test_variable_storage 
------------------------
- 123456789012
-(1 row)
-
+ERROR:  Internal subtransactions not supported in Postgres-XL
+CONTEXT:  PL/pgSQL function test_variable_storage() line 5 during statement block entry
 --
 -- test foreign key error trapping
 --
@@ -2131,41 +2135,25 @@ begin
        return 1;
 end$$ language plpgsql;
 select trap_foreign_key(1);
- trap_foreign_key 
-------------------
-                1
-(1 row)
-
+ERROR:  Internal subtransactions not supported in Postgres-XL
+CONTEXT:  PL/pgSQL function trap_foreign_key(integer) line 3 during statement block entry
 select trap_foreign_key(2);    -- detects FK violation
-NOTICE:  caught foreign_key_violation
- trap_foreign_key 
-------------------
-                0
-(1 row)
-
+ERROR:  Internal subtransactions not supported in Postgres-XL
+CONTEXT:  PL/pgSQL function trap_foreign_key(integer) line 3 during statement block entry
 begin;
   set constraints all deferred;
   select trap_foreign_key(2);  -- should not detect FK violation
- trap_foreign_key 
-------------------
-                1
-(1 row)
-
+ERROR:  Internal subtransactions not supported in Postgres-XL
+CONTEXT:  PL/pgSQL function trap_foreign_key(integer) line 3 during statement block entry
   savepoint x;
+ERROR:  current transaction is aborted, commands ignored until end of transaction block
     set constraints all immediate; -- fails
-ERROR:  insert or update on table "slave" violates foreign key constraint "slave_f1_fkey"
-DETAIL:  Key (f1)=(2) is not present in table "master".
+ERROR:  current transaction is aborted, commands ignored until end of transaction block
   rollback to x;
+ERROR:  no such savepoint
   select trap_foreign_key_2();  -- detects FK violation
-NOTICE:  caught foreign_key_violation
- trap_foreign_key_2 
---------------------
-                  0
-(1 row)
-
+ERROR:  current transaction is aborted, commands ignored until end of transaction block
 commit;                                -- still fails
-ERROR:  insert or update on table "slave" violates foreign key constraint "slave_f1_fkey"
-DETAIL:  Key (f1)=(2) is not present in table "master".
 drop function trap_foreign_key(int);
 drop function trap_foreign_key_2();
 --
@@ -2301,6 +2289,7 @@ begin
     end if;
 end
 $$ language plpgsql;
+-- PGXCTODO: This is failing due to issue 3522907, complicated SELECT queries in plpgsql functions
 select refcursor_test2(20000, 20000) as "Should be false",
        refcursor_test2(20, 20) as "Should be true";
  Should be false | Should be true 
@@ -2510,13 +2499,8 @@ EXCEPTION
 END;
 $$ LANGUAGE plpgsql;
 SELECT reraise_test();
-NOTICE:  exception syntax_error thrown in inner block, reraising
-NOTICE:  RIGHT - exception syntax_error caught in inner block
- reraise_test 
---------------
-(1 row)
-
+ERROR:  Internal subtransactions not supported in Postgres-XL
+CONTEXT:  PL/pgSQL function reraise_test() line 2 during statement block entry
 --
 -- reject function definitions that contain malformed SQL queries at
 -- compile-time, where possible
@@ -2606,8 +2590,8 @@ begin
 end; $$ language plpgsql;
 select execute_into_test('eifoo');
 NOTICE:  10 1
-NOTICE:  10 15
-NOTICE:  10 15 20
+NOTICE:  <NULL> <NULL>
+NOTICE:  <NULL> <NULL> <NULL>
  execute_into_test 
 -------------------
  (1,2)
@@ -2665,26 +2649,16 @@ begin
     end;
 end; $$ language plpgsql;
 select excpt_test3();
-NOTICE:  caught exception P0001 user exception
-NOTICE:  P0001 user exception
-NOTICE:  caught exception 22012 division by zero
-NOTICE:  P0001 user exception
- excpt_test3 
--------------
-(1 row)
-
+ERROR:  Internal subtransactions not supported in Postgres-XL
+CONTEXT:  PL/pgSQL function excpt_test3() line 3 during statement block entry
 create function excpt_test4() returns text as $$
 begin
        begin perform 1/0;
        exception when others then return sqlerrm; end;
 end; $$ language plpgsql;
 select excpt_test4();
-   excpt_test4    
-------------------
- division by zero
-(1 row)
-
+ERROR:  Internal subtransactions not supported in Postgres-XL
+CONTEXT:  PL/pgSQL function excpt_test4() line 3 during statement block entry
 drop function excpt_test1();
 drop function excpt_test2();
 drop function excpt_test3();
@@ -3087,8 +3061,9 @@ begin
   raise notice 'x.f1 = %, x.f2 = %', x.f1, x.f2;
 end$$ language plpgsql;
 select footest();
-ERROR:  query returned more than one row
-CONTEXT:  PL/pgSQL function footest() line 5 at SQL statement
+ERROR:  consistency check on SPI tuple count failed
+CONTEXT:  SQL statement "insert into foo values(7,8),(9,10) returning *"
+PL/pgSQL function footest() line 5 at SQL statement
 create or replace function footest() returns void as $$
 declare x record;
 begin
@@ -3111,7 +3086,7 @@ begin
   raise notice 'x.f1 = %, x.f2 = %', x.f1, x.f2;
 end$$ language plpgsql;
 select footest();
-NOTICE:  x.f1 = 7, x.f2 = 8
+NOTICE:  x.f1 = 9, x.f2 = 10
  footest 
 ---------
  
@@ -3303,8 +3278,10 @@ DETAIL:  parameters: p1 = '2', p3 = 'foo'
 CONTEXT:  PL/pgSQL function footest() line 10 at SQL statement
 -- test warnings and errors
 set plpgsql.extra_warnings to 'all';
+ERROR:  syntax error at or near "all"
 set plpgsql.extra_warnings to 'none';
 set plpgsql.extra_errors to 'all';
+ERROR:  syntax error at or near "all"
 set plpgsql.extra_errors to 'none';
 -- test warnings when shadowing a variable
 set plpgsql.extra_warnings to 'shadowed_variables';
@@ -3439,14 +3416,9 @@ begin
 end;
 $$ language plpgsql;
 select * from sc_test() order by 1;
-   sc_test   
--------------
- -2147483647
-     -123456
-           0
-      123456
-  2147483647
-(5 rows)
+ sc_test 
+---------
+(0 rows)
 
 create or replace function sc_test() returns setof integer as $$
 declare
@@ -3481,21 +3453,16 @@ begin
 end;
 $$ language plpgsql;
 select * from sc_test() order by 1;
-   sc_test   
--------------
- -2147483647
-     -123456
-           0
-      123456
-  2147483647
-(5 rows)
+ sc_test 
+---------
+(0 rows)
 
 create or replace function sc_test() returns setof integer as $$
 declare
   c refcursor;
   x integer;
 begin
-  open c scroll for execute 'select f1 from int4_tbl';
+  open c scroll for execute 'select f1 from int4_tbl order by 1';
   fetch last from c into x;
   while found loop
     return next x;
@@ -3504,20 +3471,17 @@ begin
   close c;
 end;
 $$ language plpgsql;
-select * from sc_test() order by 1;
-   sc_test   
--------------
- -2147483647
-     -123456
-           0
-(3 rows)
+select * from sc_test();
+ sc_test 
+---------
+(0 rows)
 
 create or replace function sc_test() returns setof integer as $$
 declare
   c refcursor;
   x integer;
 begin
-  open c scroll for execute 'select f1 from int4_tbl';
+  open c scroll for execute 'select f1 from int4_tbl order by 1';
   fetch last from c into x;
   while found loop
     return next x;
@@ -3528,11 +3492,9 @@ begin
 end;
 $$ language plpgsql;
 select * from sc_test();
-   sc_test   
--------------
- -2147483647
-      123456
-(2 rows)
+ sc_test 
+---------
+(0 rows)
 
 create or replace function sc_test() returns setof integer as $$
 declare
@@ -3575,7 +3537,7 @@ begin
   close c;
 end;
 $$ language plpgsql;
-select * from sc_test();
+select * from sc_test() order by 1;
  sc_test 
 ---------
       10
@@ -3785,33 +3747,22 @@ end;
 $$ language plpgsql;
 select forc01();
 NOTICE:  1, 1
-NOTICE:  2, 2
-NOTICE:  3, 3
-NOTICE:  4, 4
-NOTICE:  5, 5
-NOTICE:  6, 6
-NOTICE:  7, 7
-NOTICE:  8, 8
-NOTICE:  9, 9
-NOTICE:  10, 10
- forc01 
---------
-(1 row)
-
+ERROR:  WHERE CURRENT OF clause not yet supported
+CONTEXT:  SQL statement "update forc_test set i = i * 100, j = r.j * 2 where current of c"
+PL/pgSQL function forc01() line 7 at SQL statement
 select * from forc_test order by 1, 2;
 i   | j  
-------+----
-  100 |  2
-  200 |  4
-  300 |  6
-  400 |  8
-  500 | 10
-  600 | 12
-  700 | 14
-  800 | 16
-  900 | 18
- 1000 | 20
i  | j  
+----+----
+  1 |  1
+  2 |  2
+  3 |  3
+  4 |  4
+  5 |  5
+  6 |  6
+  7 |  7
+  8 |  8
+  9 |  9
+ 10 | 10
 (10 rows)
 
 -- same, with a cursor whose portal name doesn't match variable name
@@ -3830,34 +3781,23 @@ begin
 end;
 $$ language plpgsql;
 select forc01();
-NOTICE:  100, 2
-NOTICE:  200, 4
-NOTICE:  300, 6
-NOTICE:  400, 8
-NOTICE:  500, 10
-NOTICE:  600, 12
-NOTICE:  700, 14
-NOTICE:  800, 16
-NOTICE:  900, 18
-NOTICE:  1000, 20
- forc01 
---------
-(1 row)
-
-select * from forc_test;
-   i    | j  
---------+----
-  10000 |  4
-  20000 |  8
-  30000 | 12
-  40000 | 16
-  50000 | 20
-  60000 | 24
-  70000 | 28
-  80000 | 32
-  90000 | 36
- 100000 | 40
+NOTICE:  1, 1
+ERROR:  WHERE CURRENT OF clause not yet supported
+CONTEXT:  SQL statement "update forc_test set i = i * 100, j = r.j * 2 where current of c"
+PL/pgSQL function forc01() line 11 at SQL statement
+select * from forc_test order by 1;
+ i  | j  
+----+----
+  1 |  1
+  2 |  2
+  3 |  3
+  4 |  4
+  5 |  5
+  6 |  6
+  7 |  7
+  8 |  8
+  9 |  9
+ 10 | 10
 (10 rows)
 
 drop function forc01();
@@ -3902,43 +3842,43 @@ begin
   return query execute 'select * from tabwithcols';
 end;
 $$ language plpgsql;
-select * from returnqueryf();
+select * from returnqueryf() order by 1,2,3,4;
  a  | b  | c  | d  
 ----+----+----+----
  10 | 20 | 30 | 40
- 50 | 60 | 70 | 80
  10 | 20 | 30 | 40
  50 | 60 | 70 | 80
+ 50 | 60 | 70 | 80
 (4 rows)
 
 alter table tabwithcols drop column b;
-select * from returnqueryf();
+select * from returnqueryf() order by 1,2,3;
  a  | c  | d  
 ----+----+----
  10 | 30 | 40
- 50 | 70 | 80
  10 | 30 | 40
  50 | 70 | 80
+ 50 | 70 | 80
 (4 rows)
 
 alter table tabwithcols drop column d;
-select * from returnqueryf();
+select * from returnqueryf() order by 1,2;
  a  | c  
 ----+----
  10 | 30
- 50 | 70
  10 | 30
  50 | 70
+ 50 | 70
 (4 rows)
 
 alter table tabwithcols add column d int;
-select * from returnqueryf();
+select * from returnqueryf() order by 1,2,3;
  a  | c  | d 
 ----+----+---
  10 | 30 |  
- 50 | 70 |  
  10 | 30 |  
  50 | 70 |  
+ 50 | 70 |  
 (4 rows)
 
 drop function returnqueryf();
@@ -4136,10 +4076,8 @@ begin
 end;
 $$ language plpgsql;
 select raise_test();
-NOTICE:  SQLSTATE: 22012 SQLERRM: check me
-ERROR:  check me
-DETAIL:  some detail info
-CONTEXT:  PL/pgSQL function raise_test() line 3 at RAISE
+ERROR:  Internal subtransactions not supported in Postgres-XL
+CONTEXT:  PL/pgSQL function raise_test() line 2 during statement block entry
 create or replace function raise_test() returns void as $$
 begin
   raise 'check me'
@@ -4151,10 +4089,8 @@ begin
 end;
 $$ language plpgsql;
 select raise_test();
-NOTICE:  SQLSTATE: 1234F SQLERRM: check me
-ERROR:  check me
-DETAIL:  some detail info
-CONTEXT:  PL/pgSQL function raise_test() line 3 at RAISE
+ERROR:  Internal subtransactions not supported in Postgres-XL
+CONTEXT:  PL/pgSQL function raise_test() line 2 during statement block entry
 -- SQLSTATE specification in WHEN
 create or replace function raise_test() returns void as $$
 begin
@@ -4167,10 +4103,8 @@ begin
 end;
 $$ language plpgsql;
 select raise_test();
-NOTICE:  SQLSTATE: 1234F SQLERRM: check me
-ERROR:  check me
-DETAIL:  some detail info
-CONTEXT:  PL/pgSQL function raise_test() line 3 at RAISE
+ERROR:  Internal subtransactions not supported in Postgres-XL
+CONTEXT:  PL/pgSQL function raise_test() line 2 during statement block entry
 create or replace function raise_test() returns void as $$
 begin
   raise division_by_zero using detail = 'some detail info';
@@ -4181,10 +4115,8 @@ begin
 end;
 $$ language plpgsql;
 select raise_test();
-NOTICE:  SQLSTATE: 22012 SQLERRM: division_by_zero
-ERROR:  division_by_zero
-DETAIL:  some detail info
-CONTEXT:  PL/pgSQL function raise_test() line 3 at RAISE
+ERROR:  Internal subtransactions not supported in Postgres-XL
+CONTEXT:  PL/pgSQL function raise_test() line 2 during statement block entry
 create or replace function raise_test() returns void as $$
 begin
   raise division_by_zero;
@@ -4274,12 +4206,8 @@ exception when others then
 end;
 $$ language plpgsql;
 select stacked_diagnostics_test();
-NOTICE:  sqlstate: 22012, message: division by zero, context: [PL/pgSQL function zero_divide() line 4 at RETURN <- SQL statement "SELECT zero_divide()" <- PL/pgSQL function stacked_diagnostics_test() line 6 at PERFORM]
- stacked_diagnostics_test 
---------------------------
-(1 row)
-
+ERROR:  Internal subtransactions not supported in Postgres-XL
+CONTEXT:  PL/pgSQL function stacked_diagnostics_test() line 5 during statement block entry
 create or replace function stacked_diagnostics_test() returns void as $$
 declare _detail text;
         _hint text;
@@ -4295,12 +4223,8 @@ exception when others then
 end;
 $$ language plpgsql;
 select stacked_diagnostics_test();
-NOTICE:  message: custom exception, detail: some detail of custom exception, hint: some hint related to custom exception
- stacked_diagnostics_test 
---------------------------
-(1 row)
-
+ERROR:  Internal subtransactions not supported in Postgres-XL
+CONTEXT:  PL/pgSQL function stacked_diagnostics_test() line 5 during statement block entry
 -- fail, cannot use stacked diagnostics statement outside handler
 create or replace function stacked_diagnostics_test() returns void as $$
 declare _detail text;
@@ -4331,9 +4255,8 @@ exception
 end;
 $$ language plpgsql;
 select raise_test();
-NOTICE:  22012
-ERROR:  substitute message
-CONTEXT:  PL/pgSQL function raise_test() line 7 at RAISE
+ERROR:  Internal subtransactions not supported in Postgres-XL
+CONTEXT:  PL/pgSQL function raise_test() line 2 during statement block entry
 drop function raise_test();
 -- test passing column_name, constraint_name, datatype_name, table_name
 -- and schema_name error fields
@@ -4362,12 +4285,8 @@ exception when others then
 end;
 $$ language plpgsql;
 select stacked_diagnostics_test();
-NOTICE:  column >>some column name<<, constraint >>some constraint name<<, type >>some datatype name<<, table >>some table name<<, schema >>some schema name<<
- stacked_diagnostics_test 
---------------------------
-(1 row)
-
+ERROR:  Internal subtransactions not supported in Postgres-XL
+CONTEXT:  PL/pgSQL function stacked_diagnostics_test() line 7 during statement block entry
 drop function stacked_diagnostics_test();
 -- test CASE statement
 create or replace function case_test(bigint) returns text as $$
@@ -4453,12 +4372,8 @@ exception
 end
 $$ language plpgsql;
 select catch();
-NOTICE:  caught case_not_found 20000 case not found
- catch 
--------
-(1 row)
-
+ERROR:  Internal subtransactions not supported in Postgres-XL
+CONTEXT:  PL/pgSQL function catch() line 2 during statement block entry
 -- test the searched variant too, as well as ELSE
 create or replace function case_test(bigint) returns text as $$
 declare a int = 10;
@@ -4679,17 +4594,11 @@ BEGIN
 END;
 $$ LANGUAGE plpgsql;
 SELECT * FROM leaker_1(false);
- leaker_1 
-----------
-        1
-(1 row)
-
+ERROR:  Internal subtransactions not supported in Postgres-XL
+CONTEXT:  PL/pgSQL function leaker_1(boolean) line 5 during statement block entry
 SELECT * FROM leaker_1(true);
- leaker_1 
-----------
-        0
-(1 row)
-
+ERROR:  Internal subtransactions not supported in Postgres-XL
+CONTEXT:  PL/pgSQL function leaker_1(boolean) line 5 during statement block entry
 DROP FUNCTION leaker_1(bool);
 DROP FUNCTION leaker_2(bool);
 -- Test for appropriate cleanup of non-simple expression evaluations
@@ -4729,11 +4638,8 @@ begin
 end;
 $$ LANGUAGE plpgsql;
 SELECT nonsimple_expr_test();
- nonsimple_expr_test 
----------------------
-                   1
-(1 row)
-
+ERROR:  Internal subtransactions not supported in Postgres-XL
+CONTEXT:  PL/pgSQL function nonsimple_expr_test() line 5 during statement block entry
 DROP FUNCTION nonsimple_expr_test();
 --
 -- Test cases involving recursion and error recovery in simple expressions
@@ -4768,17 +4674,13 @@ end$$;
 BEGIN;
 create table public.stuffs (stuff text);
 SAVEPOINT a;
+ERROR:  SAVEPOINT is not yet supported.
 select error2('nonexistent.stuffs');
-ERROR:  schema "nonexistent" does not exist
-CONTEXT:  SQL function "error1" statement 1
-PL/pgSQL function error2(text) line 3 at RETURN
+ERROR:  current transaction is aborted, commands ignored until end of transaction block
 ROLLBACK TO a;
+ERROR:  no such savepoint
 select error2('public.stuffs');
- error2 
---------
- stuffs
-(1 row)
-
+ERROR:  current transaction is aborted, commands ignored until end of transaction block
 rollback;
 drop function error2(p_name_table text);
 drop function error1(text);
@@ -4995,16 +4897,8 @@ begin
   end loop;
 end;
 $outer$;
-NOTICE:  caught division by zero
-NOTICE:  caught division by zero
-NOTICE:  caught division by zero
-NOTICE:  caught division by zero
-NOTICE:  caught division by zero
-NOTICE:  caught division by zero
-NOTICE:  caught division by zero
-NOTICE:  caught division by zero
-NOTICE:  caught division by zero
-NOTICE:  caught division by zero
+ERROR:  Internal subtransactions not supported in Postgres-XL
+CONTEXT:  PL/pgSQL function inline_code_block line 4 during statement block entry
 -- Check variable scoping -- a var is not available in its own or prior
 -- default expressions.
 create function scope_test() returns int as $$
@@ -5035,7 +4929,7 @@ begin
   end loop;
 end;
 $$ language plpgsql;
-select * from conflict_test();
+select * from conflict_test() order by 1,2;
 ERROR:  column reference "q1" is ambiguous
 LINE 1: select q1,q2 from int8_tbl
                ^
@@ -5052,14 +4946,15 @@ begin
   end loop;
 end;
 $$ language plpgsql;
-select * from conflict_test();
+-- PGXCTODO: This is failing due to issue 3522907, complicated SELECT queries in plpgsql functions
+select * from conflict_test() order by 1,2;
  q1 |        q2         
 ----+-------------------
+ 42 | -4567890123456789
+ 42 |               123
  42 |               456
  42 |  4567890123456789
- 42 |               123
  42 |  4567890123456789
- 42 | -4567890123456789
 (5 rows)
 
 create or replace function conflict_test() returns setof int8_tbl as $$
@@ -5072,14 +4967,14 @@ begin
   end loop;
 end;
 $$ language plpgsql;
-select * from conflict_test();
+select * from conflict_test() order by 1,2;
         q1        |        q2         
 ------------------+-------------------
               123 |               456
               123 |  4567890123456789
+ 4567890123456789 | -4567890123456789
  4567890123456789 |               123
  4567890123456789 |  4567890123456789
- 4567890123456789 | -4567890123456789
 (5 rows)
 
 drop function conflict_test();
@@ -5369,6 +5264,119 @@ ERROR:  value for domain orderedarray violates check constraint "sorted"
 CONTEXT:  PL/pgSQL function testoa(integer,integer,integer) line 5 at assignment
 drop function arrayassign1();
 drop function testoa(x1 int, x2 int, x3 int);
+-- Check that DMLs in a plpgsql function work OK, when subsequent queries need
+-- to open new datanode connections
+CREATE OR REPLACE FUNCTION TestJoinTempTable_CT()
+RETURNS void AS $$
+BEGIN
+        CREATE TABLE IF NOT EXISTS RealTable(ProductId int, ScenarioId int);
+        TRUNCATE TABLE RealTable;
+
+        CREATE TABLE IF NOT EXISTS TmpBar(NodeId int)
+                DISTRIBUTE BY REPLICATION;
+        CREATE TABLE IF NOT EXISTS TmpFoo(TempId int)
+                DISTRIBUTE BY REPLICATION;
+END ;
+$$ LANGUAGE plpgsql;
+CREATE OR REPLACE FUNCTION TestJoinTempTable_INSERT()
+RETURNS void AS $$
+BEGIN
+        INSERT INTO RealTable(ProductId, ScenarioId)
+                SELECT generate_series(1,1000) as ProductId, (random() * 100)::int as ScenarioId;
+
+        INSERT INTO TmpBar(NodeId)
+                SELECT generate_series(1,1000);
+               RAISE INFO 'number of existing rows in RealTable - %', (SELECT count(*) FROM RealTable);
+               RAISE INFO 'number of existing rows in TmpBar - %', (SELECT count(*) FROM TmpBar);
+               RAISE INFO 'number of existing rows in TmpFoo - %', (SELECT count(*) FROM TmpFoo);
+        INSERT INTO TmpFoo(TempId)
+               SELECT DISTINCT(PR.ProductId)
+                 FROM RealTable AS PR
+                 JOIN TmpBar tmp1 ON PR.ProductId = tmp1.NodeId;
+
+               RAISE INFO 'number of rows produced by query - %',
+                               (SELECT COUNT(DISTINCT(PR.ProductId))
+                                FROM RealTable AS PR
+                 JOIN TmpBar tmp1 ON PR.ProductId = tmp1.NodeId);
+               RAISE INFO 'number of rows in TmpFoo - %', (SELECT count(*) FROM TmpFoo);
+               RAISE INFO 'number of existing rows in TmpFoo - %', (SELECT count(*) FROM TmpFoo);
+               RAISE INFO 'number of existing rows in TmpFoo - %', (SELECT count(*) FROM TmpFoo);
+END ;
+$$ LANGUAGE plpgsql;
+SELECT TestJoinTempTable_CT();
+ testjointemptable_ct 
+----------------------
+(1 row)
+
+SELECT TestJoinTempTable_INSERT();
+INFO:  number of existing rows in RealTable - 1000
+INFO:  number of existing rows in TmpBar - 1000
+INFO:  number of existing rows in TmpFoo - 0
+INFO:  number of rows produced by query - 1000
+INFO:  number of rows in TmpFoo - 1000
+INFO:  number of existing rows in TmpFoo - 1000
+INFO:  number of existing rows in TmpFoo - 1000
+ testjointemptable_insert 
+--------------------------
+(1 row)
+
+DROP TABLE RealTable;
+DROP TABLE TmpBar;
+DROP TABLE TmpFoo;
+CREATE OR REPLACE FUNCTION TestJoinTempTable()
+RETURNS void AS $$
+BEGIN
+        CREATE TABLE IF NOT EXISTS RealTable(ProductId int, ScenarioId int);
+        TRUNCATE TABLE RealTable;
+
+        CREATE TEMPORARY TABLE IF NOT EXISTS TmpBar(NodeId int)
+                DISTRIBUTE BY REPLICATION;
+        CREATE TEMPORARY TABLE IF NOT EXISTS TmpFoo(TempId int)
+                DISTRIBUTE BY REPLICATION;
+
+        INSERT INTO RealTable(ProductId, ScenarioId)
+                SELECT generate_series(1,1000) as ProductId, (random() * 100)::int as ScenarioId;
+
+        INSERT INTO TmpBar(NodeId)
+                SELECT generate_series(1,1000);
+
+        INSERT INTO TmpFoo(TempId)
+               SELECT DISTINCT(PR.ProductId)
+                 FROM RealTable AS PR
+                 JOIN TmpBar tmp1 ON PR.ProductId = tmp1.NodeId;
+END ;
+$$ LANGUAGE plpgsql;
+SELECT TestJoinTempTable();
+ testjointemptable 
+-------------------
+(1 row)
+
+-- Multiple invokations of the function showed interesting issues with command
+-- passdown. So add that to the test case
+SELECT TestJoinTempTable();
+NOTICE:  relation "realtable" already exists, skipping
+NOTICE:  relation "tmpbar" already exists, skipping
+NOTICE:  relation "tmpfoo" already exists, skipping
+ testjointemptable 
+-------------------
+(1 row)
+
+SELECT TestJoinTempTable();
+NOTICE:  relation "realtable" already exists, skipping
+NOTICE:  relation "tmpbar" already exists, skipping
+NOTICE:  relation "tmpfoo" already exists, skipping
+ testjointemptable 
+-------------------
+(1 row)
+
+DROP TABLE RealTable;
+DROP TABLE TmpBar;
+DROP TABLE TmpFoo;
 --
 -- Test handling of expanded arrays
 --
@@ -5560,38 +5568,18 @@ $$ language plpgsql;
 select outer_outer_func(10);
 NOTICE:  calling down into outer_func()
 NOTICE:  calling down into inner_func()
-NOTICE:  ***PL/pgSQL function inner_func(integer) line 10 at GET DIAGNOSTICS
+ERROR:  Internal subtransactions not supported in Postgres-XL
+CONTEXT:  PL/pgSQL function inner_func(integer) line 6 during statement block entry
 PL/pgSQL function outer_func(integer) line 6 at assignment
-PL/pgSQL function outer_outer_func(integer) line 6 at assignment***
-NOTICE:  ***PL/pgSQL function inner_func(integer) line 15 at GET DIAGNOSTICS
-PL/pgSQL function outer_func(integer) line 6 at assignment
-PL/pgSQL function outer_outer_func(integer) line 6 at assignment***
-NOTICE:  lets make sure we didnt break anything
-NOTICE:  inner_func() done
-NOTICE:  outer_func() done
- outer_outer_func 
-------------------
-               20
-(1 row)
-
+PL/pgSQL function outer_outer_func(integer) line 6 at assignment
 -- repeated call should to work
 select outer_outer_func(20);
 NOTICE:  calling down into outer_func()
 NOTICE:  calling down into inner_func()
-NOTICE:  ***PL/pgSQL function inner_func(integer) line 10 at GET DIAGNOSTICS
+ERROR:  Internal subtransactions not supported in Postgres-XL
+CONTEXT:  PL/pgSQL function inner_func(integer) line 6 during statement block entry
 PL/pgSQL function outer_func(integer) line 6 at assignment
-PL/pgSQL function outer_outer_func(integer) line 6 at assignment***
-NOTICE:  ***PL/pgSQL function inner_func(integer) line 15 at GET DIAGNOSTICS
-PL/pgSQL function outer_func(integer) line 6 at assignment
-PL/pgSQL function outer_outer_func(integer) line 6 at assignment***
-NOTICE:  lets make sure we didnt break anything
-NOTICE:  inner_func() done
-NOTICE:  outer_func() done
- outer_outer_func 
-------------------
-               40
-(1 row)
-
+PL/pgSQL function outer_outer_func(integer) line 6 at assignment
 drop function outer_outer_func(int);
 drop function outer_func(int);
 drop function inner_func(int);
@@ -5642,5 +5630,28 @@ exception when others then
   null; -- do nothing
 end;
 $$;
-ERROR:  unhandled assertion
-CONTEXT:  PL/pgSQL function inline_code_block line 3 at ASSERT
+ERROR:  Internal subtransactions not supported in Postgres-XL
+CONTEXT:  PL/pgSQL function inline_code_block line 2 during statement block entry
+-- Check parameter handling
+BEGIN;
+DROP TABLE IF EXISTS testcase_13;
+NOTICE:  table "testcase_13" does not exist, skipping
+CREATE TABLE testcase_13 (patient_id integer);
+INSERT INTO testcase_13 VALUES (1);
+DO $$
+DECLARE
+ r RECORD;
+BEGIN
+FOR r IN SELECT * FROM testcase_13 LOOP
+    RAISE INFO 'r.patient_id=%', r.patient_id;
+    IF   (SELECT EXISTS (
+            SELECT FROM testcase_13 WHERE patient_id = r.patient_id
+        ))
+       THEN
+          RAISE INFO 'condition true';
+    END IF;
+  END LOOP;
+END $$;
+INFO:  r.patient_id=1
+INFO:  condition true
+ROLLBACK;
diff --git a/src/test/regress/expected/plpgsql_1.out b/src/test/regress/expected/plpgsql_1.out
deleted file mode 100644 (file)
index e118520..0000000
+++ /dev/null
@@ -1,5657 +0,0 @@
---
--- PLPGSQL
---
--- Scenario:
---
---     A building with a modern TP cable installation where any
---     of the wall connectors can be used to plug in phones,
---     ethernet interfaces or local office hubs. The backside
---     of the wall connectors is wired to one of several patch-
---     fields in the building.
---
---     In the patchfields, there are hubs and all the slots
---     representing the wall connectors. In addition there are
---     slots that can represent a phone line from the central
---     phone system.
---
---     Triggers ensure consistency of the patching information.
---
---     Functions are used to build up powerful views that let
---     you look behind the wall when looking at a patchfield
---     or into a room.
---
-create table Room (
-    roomno     char(8),
-    comment    text
-);
-create unique index Room_rno on Room using btree (roomno bpchar_ops);
-create table WSlot (
-    slotname   char(20),
-    roomno     char(8),
-    slotlink   char(20),
-    backlink   char(20)
-);
-create unique index WSlot_name on WSlot using btree (slotname bpchar_ops);
-create table PField (
-    name       text,
-    comment    text
-) distribute by replication;
-create unique index PField_name on PField using btree (name text_ops);
-create table PSlot (
-    slotname   char(20),
-    pfname     text,
-    slotlink   char(20),
-    backlink   char(20)
-);
-create unique index PSlot_name on PSlot using btree (slotname bpchar_ops);
-create table PLine (
-    slotname   char(20),
-    phonenumber        char(20),
-    comment    text,
-    backlink   char(20)
-);
-create unique index PLine_name on PLine using btree (slotname bpchar_ops);
-create table Hub (
-    name       char(14),
-    comment    text,
-    nslots     integer
-);
-create unique index Hub_name on Hub using btree (name bpchar_ops);
-create table HSlot (
-    slotname   char(20),
-    hubname    char(14),
-    slotno     integer,
-    slotlink   char(20)
-);
-create unique index HSlot_name on HSlot using btree (slotname bpchar_ops);
-create index HSlot_hubname on HSlot using btree (hubname bpchar_ops);
-create table System (
-    name       text,
-    comment    text
-);
-create unique index System_name on System using btree (name text_ops);
-create table IFace (
-    slotname   char(20),
-    sysname    text,
-    ifname     text,
-    slotlink   char(20)
-);
-create unique index IFace_name on IFace using btree (slotname bpchar_ops);
-create table PHone (
-    slotname   char(20),
-    comment    text,
-    slotlink   char(20)
-);
-create unique index PHone_name on PHone using btree (slotname bpchar_ops);
--- ************************************************************
--- *
--- * Trigger procedures and functions for the patchfield
--- * test of PL/pgSQL
--- *
--- ************************************************************
--- ************************************************************
--- * AFTER UPDATE on Room
--- *   - If room no changes let wall slots follow
--- ************************************************************
-create function tg_room_au() returns trigger as '
-begin
-    if new.roomno != old.roomno then
-        update WSlot set roomno = new.roomno where roomno = old.roomno;
-    end if;
-    return new;
-end;
-' language plpgsql;
-create trigger tg_room_au after update
-    on Room for each row execute procedure tg_room_au();
-ERROR:  Postgres-XL does not support TRIGGER yet
-DETAIL:  The feature is not currently supported
--- ************************************************************
--- * AFTER DELETE on Room
--- *   - delete wall slots in this room
--- ************************************************************
-create function tg_room_ad() returns trigger as '
-begin
-    delete from WSlot where roomno = old.roomno;
-    return old;
-end;
-' language plpgsql;
-create trigger tg_room_ad after delete
-    on Room for each row execute procedure tg_room_ad();
-ERROR:  Postgres-XL does not support TRIGGER yet
-DETAIL:  The feature is not currently supported
--- ************************************************************
--- * BEFORE INSERT or UPDATE on WSlot
--- *   - Check that room exists
--- ************************************************************
-create function tg_wslot_biu() returns trigger as $$
-begin
-    if count(*) = 0 from Room where roomno = new.roomno then
-        raise exception 'Room % does not exist', new.roomno;
-    end if;
-    return new;
-end;
-$$ language plpgsql;
-create trigger tg_wslot_biu before insert or update
-    on WSlot for each row execute procedure tg_wslot_biu();
-ERROR:  Postgres-XL does not support TRIGGER yet
-DETAIL:  The feature is not currently supported
--- ************************************************************
--- * AFTER UPDATE on PField
--- *   - Let PSlots of this field follow
--- ************************************************************
-create function tg_pfield_au() returns trigger as '
-begin
-    if new.name != old.name then
-        update PSlot set pfname = new.name where pfname = old.name;
-    end if;
-    return new;
-end;
-' language plpgsql;
-create trigger tg_pfield_au after update
-    on PField for each row execute procedure tg_pfield_au();
-ERROR:  Postgres-XL does not support TRIGGER yet
-DETAIL:  The feature is not currently supported
--- ************************************************************
--- * AFTER DELETE on PField
--- *   - Remove all slots of this patchfield
--- ************************************************************
-create function tg_pfield_ad() returns trigger as '
-begin
-    delete from PSlot where pfname = old.name;
-    return old;
-end;
-' language plpgsql;
-create trigger tg_pfield_ad after delete
-    on PField for each row execute procedure tg_pfield_ad();
-ERROR:  Postgres-XL does not support TRIGGER yet
-DETAIL:  The feature is not currently supported
--- ************************************************************
--- * BEFORE INSERT or UPDATE on PSlot
--- *   - Ensure that our patchfield does exist
--- ************************************************************
-create function tg_pslot_biu() returns trigger as $proc$
-declare
-    pfrec      record;
-    ps          alias for new;
-begin
-    select into pfrec * from PField where name = ps.pfname;
-    if not found then
-        raise exception $$Patchfield "%" does not exist$$, ps.pfname;
-    end if;
-    return ps;
-end;
-$proc$ language plpgsql;
-create trigger tg_pslot_biu before insert or update
-    on PSlot for each row execute procedure tg_pslot_biu();
-ERROR:  Postgres-XL does not support TRIGGER yet
-DETAIL:  The feature is not currently supported
--- ************************************************************
--- * AFTER UPDATE on System
--- *   - If system name changes let interfaces follow
--- ************************************************************
-create function tg_system_au() returns trigger as '
-begin
-    if new.name != old.name then
-        update IFace set sysname = new.name where sysname = old.name;
-    end if;
-    return new;
-end;
-' language plpgsql;
-create trigger tg_system_au after update
-    on System for each row execute procedure tg_system_au();
-ERROR:  Postgres-XL does not support TRIGGER yet
-DETAIL:  The feature is not currently supported
--- ************************************************************
--- * BEFORE INSERT or UPDATE on IFace
--- *   - set the slotname to IF.sysname.ifname
--- ************************************************************
-create function tg_iface_biu() returns trigger as $$
-declare
-    sname      text;
-    sysrec     record;
-begin
-    select into sysrec * from system where name = new.sysname;
-    if not found then
-        raise exception $q$system "%" does not exist$q$, new.sysname;
-    end if;
-    sname := 'IF.' || new.sysname;
-    sname := sname || '.';
-    sname := sname || new.ifname;
-    if length(sname) > 20 then
-        raise exception 'IFace slotname "%" too long (20 char max)', sname;
-    end if;
-    new.slotname := sname;
-    return new;
-end;
-$$ language plpgsql;
-create trigger tg_iface_biu before insert or update
-    on IFace for each row execute procedure tg_iface_biu();
-ERROR:  Postgres-XL does not support TRIGGER yet
-DETAIL:  The feature is not currently supported
--- ************************************************************
--- * AFTER INSERT or UPDATE or DELETE on Hub
--- *   - insert/delete/rename slots as required
--- ************************************************************
-create function tg_hub_a() returns trigger as '
-declare
-    hname      text;
-    dummy      integer;
-begin
-    if tg_op = ''INSERT'' then
-       dummy := tg_hub_adjustslots(new.name, 0, new.nslots);
-       return new;
-    end if;
-    if tg_op = ''UPDATE'' then
-       if new.name != old.name then
-           update HSlot set hubname = new.name where hubname = old.name;
-       end if;
-       dummy := tg_hub_adjustslots(new.name, old.nslots, new.nslots);
-       return new;
-    end if;
-    if tg_op = ''DELETE'' then
-       dummy := tg_hub_adjustslots(old.name, old.nslots, 0);
-       return old;
-    end if;
-end;
-' language plpgsql;
-create trigger tg_hub_a after insert or update or delete
-    on Hub for each row execute procedure tg_hub_a();
-ERROR:  Postgres-XL does not support TRIGGER yet
-DETAIL:  The feature is not currently supported
--- ************************************************************
--- * Support function to add/remove slots of Hub
--- ************************************************************
-create function tg_hub_adjustslots(hname bpchar,
-                                   oldnslots integer,
-                                   newnslots integer)
-returns integer as '
-begin
-    if newnslots = oldnslots then
-        return 0;
-    end if;
-    if newnslots < oldnslots then
-        delete from HSlot where hubname = hname and slotno > newnslots;
-       return 0;
-    end if;
-    for i in oldnslots + 1 .. newnslots loop
-        insert into HSlot (slotname, hubname, slotno, slotlink)
-               values (''HS.dummy'', hname, i, '''');
-    end loop;
-    return 0;
-end
-' language plpgsql;
--- Test comments
-COMMENT ON FUNCTION tg_hub_adjustslots_wrong(bpchar, integer, integer) IS 'function with args';
-ERROR:  function tg_hub_adjustslots_wrong(character, integer, integer) does not exist
-COMMENT ON FUNCTION tg_hub_adjustslots(bpchar, integer, integer) IS 'function with args';
-COMMENT ON FUNCTION tg_hub_adjustslots(bpchar, integer, integer) IS NULL;
--- ************************************************************
--- * BEFORE INSERT or UPDATE on HSlot
--- *   - prevent from manual manipulation
--- *   - set the slotname to HS.hubname.slotno
--- ************************************************************
-create function tg_hslot_biu() returns trigger as '
-declare
-    sname      text;
-    xname      HSlot.slotname%TYPE;
-    hubrec     record;
-begin
-    select into hubrec * from Hub where name = new.hubname;
-    if not found then
-        raise exception ''no manual manipulation of HSlot'';
-    end if;
-    if new.slotno < 1 or new.slotno > hubrec.nslots then
-        raise exception ''no manual manipulation of HSlot'';
-    end if;
-    if tg_op = ''UPDATE'' and new.hubname != old.hubname then
-       if count(*) > 0 from Hub where name = old.hubname then
-           raise exception ''no manual manipulation of HSlot'';
-       end if;
-    end if;
-    sname := ''HS.'' || trim(new.hubname);
-    sname := sname || ''.'';
-    sname := sname || new.slotno::text;
-    if length(sname) > 20 then
-        raise exception ''HSlot slotname "%" too long (20 char max)'', sname;
-    end if;
-    new.slotname := sname;
-    return new;
-end;
-' language plpgsql;
-create trigger tg_hslot_biu before insert or update
-    on HSlot for each row execute procedure tg_hslot_biu();
-ERROR:  Postgres-XL does not support TRIGGER yet
-DETAIL:  The feature is not currently supported
--- ************************************************************
--- * BEFORE DELETE on HSlot
--- *   - prevent from manual manipulation
--- ************************************************************
-create function tg_hslot_bd() returns trigger as '
-declare
-    hubrec     record;
-begin
-    select into hubrec * from Hub where name = old.hubname;
-    if not found then
-        return old;
-    end if;
-    if old.slotno > hubrec.nslots then
-        return old;
-    end if;
-    raise exception ''no manual manipulation of HSlot'';
-end;
-' language plpgsql;
-create trigger tg_hslot_bd before delete
-    on HSlot for each row execute procedure tg_hslot_bd();
-ERROR:  Postgres-XL does not support TRIGGER yet
-DETAIL:  The feature is not currently supported
--- ************************************************************
--- * BEFORE INSERT on all slots
--- *   - Check name prefix
--- ************************************************************
-create function tg_chkslotname() returns trigger as '
-begin
-    if substr(new.slotname, 1, 2) != tg_argv[0] then
-        raise exception ''slotname must begin with %'', tg_argv[0];
-    end if;
-    return new;
-end;
-' language plpgsql;
-create trigger tg_chkslotname before insert
-    on PSlot for each row execute procedure tg_chkslotname('PS');
-ERROR:  Postgres-XL does not support TRIGGER yet
-DETAIL:  The feature is not currently supported
-create trigger tg_chkslotname before insert
-    on WSlot for each row execute procedure tg_chkslotname('WS');
-ERROR:  Postgres-XL does not support TRIGGER yet
-DETAIL:  The feature is not currently supported
-create trigger tg_chkslotname before insert
-    on PLine for each row execute procedure tg_chkslotname('PL');
-ERROR:  Postgres-XL does not support TRIGGER yet
-DETAIL:  The feature is not currently supported
-create trigger tg_chkslotname before insert
-    on IFace for each row execute procedure tg_chkslotname('IF');
-ERROR:  Postgres-XL does not support TRIGGER yet
-DETAIL:  The feature is not currently supported
-create trigger tg_chkslotname before insert
-    on PHone for each row execute procedure tg_chkslotname('PH');
-ERROR:  Postgres-XL does not support TRIGGER yet
-DETAIL:  The feature is not currently supported
--- ************************************************************
--- * BEFORE INSERT or UPDATE on all slots with slotlink
--- *   - Set slotlink to empty string if NULL value given
--- ************************************************************
-create function tg_chkslotlink() returns trigger as '
-begin
-    if new.slotlink isnull then
-        new.slotlink := '''';
-    end if;
-    return new;
-end;
-' language plpgsql;
-create trigger tg_chkslotlink before insert or update
-    on PSlot for each row execute procedure tg_chkslotlink();
-ERROR:  Postgres-XL does not support TRIGGER yet
-DETAIL:  The feature is not currently supported
-create trigger tg_chkslotlink before insert or update
-    on WSlot for each row execute procedure tg_chkslotlink();
-ERROR:  Postgres-XL does not support TRIGGER yet
-DETAIL:  The feature is not currently supported
-create trigger tg_chkslotlink before insert or update
-    on IFace for each row execute procedure tg_chkslotlink();
-ERROR:  Postgres-XL does not support TRIGGER yet
-DETAIL:  The feature is not currently supported
-create trigger tg_chkslotlink before insert or update
-    on HSlot for each row execute procedure tg_chkslotlink();
-ERROR:  Postgres-XL does not support TRIGGER yet
-DETAIL:  The feature is not currently supported
-create trigger tg_chkslotlink before insert or update
-    on PHone for each row execute procedure tg_chkslotlink();
-ERROR:  Postgres-XL does not support TRIGGER yet
-DETAIL:  The feature is not currently supported
--- ************************************************************
--- * BEFORE INSERT or UPDATE on all slots with backlink
--- *   - Set backlink to empty string if NULL value given
--- ************************************************************
-create function tg_chkbacklink() returns trigger as '
-begin
-    if new.backlink isnull then
-        new.backlink := '''';
-    end if;
-    return new;
-end;
-' language plpgsql;
-create trigger tg_chkbacklink before insert or update
-    on PSlot for each row execute procedure tg_chkbacklink();
-ERROR:  Postgres-XL does not support TRIGGER yet
-DETAIL:  The feature is not currently supported
-create trigger tg_chkbacklink before insert or update
-    on WSlot for each row execute procedure tg_chkbacklink();
-ERROR:  Postgres-XL does not support TRIGGER yet
-DETAIL:  The feature is not currently supported
-create trigger tg_chkbacklink before insert or update
-    on PLine for each row execute procedure tg_chkbacklink();
-ERROR:  Postgres-XL does not support TRIGGER yet
-DETAIL:  The feature is not currently supported
--- ************************************************************
--- * BEFORE UPDATE on PSlot
--- *   - do delete/insert instead of update if name changes
--- ************************************************************
-create function tg_pslot_bu() returns trigger as '
-begin
-    if new.slotname != old.slotname then
-        delete from PSlot where slotname = old.slotname;
-       insert into PSlot (
-                   slotname,
-                   pfname,
-                   slotlink,
-                   backlink
-               ) values (
-                   new.slotname,
-                   new.pfname,
-                   new.slotlink,
-                   new.backlink
-               );
-        return null;
-    end if;
-    return new;
-end;
-' language plpgsql;
-create trigger tg_pslot_bu before update
-    on PSlot for each row execute procedure tg_pslot_bu();
-ERROR:  Postgres-XL does not support TRIGGER yet
-DETAIL:  The feature is not currently supported
--- ************************************************************
--- * BEFORE UPDATE on WSlot
--- *   - do delete/insert instead of update if name changes
--- ************************************************************
-create function tg_wslot_bu() returns trigger as '
-begin
-    if new.slotname != old.slotname then
-        delete from WSlot where slotname = old.slotname;
-       insert into WSlot (
-                   slotname,
-                   roomno,
-                   slotlink,
-                   backlink
-               ) values (
-                   new.slotname,
-                   new.roomno,
-                   new.slotlink,
-                   new.backlink
-               );
-        return null;
-    end if;
-    return new;
-end;
-' language plpgsql;
-create trigger tg_wslot_bu before update
-    on WSlot for each row execute procedure tg_Wslot_bu();
-ERROR:  Postgres-XL does not support TRIGGER yet
-DETAIL:  The feature is not currently supported
--- ************************************************************
--- * BEFORE UPDATE on PLine
--- *   - do delete/insert instead of update if name changes
--- ************************************************************
-create function tg_pline_bu() returns trigger as '
-begin
-    if new.slotname != old.slotname then
-        delete from PLine where slotname = old.slotname;
-       insert into PLine (
-                   slotname,
-                   phonenumber,
-                   comment,
-                   backlink
-               ) values (
-                   new.slotname,
-                   new.phonenumber,
-                   new.comment,
-                   new.backlink
-               );
-        return null;
-    end if;
-    return new;
-end;
-' language plpgsql;
-create trigger tg_pline_bu before update
-    on PLine for each row execute procedure tg_pline_bu();
-ERROR:  Postgres-XL does not support TRIGGER yet
-DETAIL:  The feature is not currently supported
--- ************************************************************
--- * BEFORE UPDATE on IFace
--- *   - do delete/insert instead of update if name changes
--- ************************************************************
-create function tg_iface_bu() returns trigger as '
-begin
-    if new.slotname != old.slotname then
-        delete from IFace where slotname = old.slotname;
-       insert into IFace (
-                   slotname,
-                   sysname,
-                   ifname,
-                   slotlink
-               ) values (
-                   new.slotname,
-                   new.sysname,
-                   new.ifname,
-                   new.slotlink
-               );
-        return null;
-    end if;
-    return new;
-end;
-' language plpgsql;
-create trigger tg_iface_bu before update
-    on IFace for each row execute procedure tg_iface_bu();
-ERROR:  Postgres-XL does not support TRIGGER yet
-DETAIL:  The feature is not currently supported
--- ************************************************************
--- * BEFORE UPDATE on HSlot
--- *   - do delete/insert instead of update if name changes
--- ************************************************************
-create function tg_hslot_bu() returns trigger as '
-begin
-    if new.slotname != old.slotname or new.hubname != old.hubname then
-        delete from HSlot where slotname = old.slotname;
-       insert into HSlot (
-                   slotname,
-                   hubname,
-                   slotno,
-                   slotlink
-               ) values (
-                   new.slotname,
-                   new.hubname,
-                   new.slotno,
-                   new.slotlink
-               );
-        return null;
-    end if;
-    return new;
-end;
-' language plpgsql;
-create trigger tg_hslot_bu before update
-    on HSlot for each row execute procedure tg_hslot_bu();
-ERROR:  Postgres-XL does not support TRIGGER yet
-DETAIL:  The feature is not currently supported
--- ************************************************************
--- * BEFORE UPDATE on PHone
--- *   - do delete/insert instead of update if name changes
--- ************************************************************
-create function tg_phone_bu() returns trigger as '
-begin
-    if new.slotname != old.slotname then
-        delete from PHone where slotname = old.slotname;
-       insert into PHone (
-                   slotname,
-                   comment,
-                   slotlink
-               ) values (
-                   new.slotname,
-                   new.comment,
-                   new.slotlink
-               );
-        return null;
-    end if;
-    return new;
-end;
-' language plpgsql;
-create trigger tg_phone_bu before update
-    on PHone for each row execute procedure tg_phone_bu();
-ERROR:  Postgres-XL does not support TRIGGER yet
-DETAIL:  The feature is not currently supported
--- ************************************************************
--- * AFTER INSERT or UPDATE or DELETE on slot with backlink
--- *   - Ensure that the opponent correctly points back to us
--- ************************************************************
-create function tg_backlink_a() returns trigger as '
-declare
-    dummy      integer;
-begin
-    if tg_op = ''INSERT'' then
-        if new.backlink != '''' then
-           dummy := tg_backlink_set(new.backlink, new.slotname);
-       end if;
-       return new;
-    end if;
-    if tg_op = ''UPDATE'' then
-        if new.backlink != old.backlink then
-           if old.backlink != '''' then
-               dummy := tg_backlink_unset(old.backlink, old.slotname);
-           end if;
-           if new.backlink != '''' then
-               dummy := tg_backlink_set(new.backlink, new.slotname);
-           end if;
-       else
-           if new.slotname != old.slotname and new.backlink != '''' then
-               dummy := tg_slotlink_set(new.backlink, new.slotname);
-           end if;
-       end if;
-       return new;
-    end if;
-    if tg_op = ''DELETE'' then
-        if old.backlink != '''' then
-           dummy := tg_backlink_unset(old.backlink, old.slotname);
-       end if;
-       return old;
-    end if;
-end;
-' language plpgsql;
-create trigger tg_backlink_a after insert or update or delete
-    on PSlot for each row execute procedure tg_backlink_a('PS');
-ERROR:  Postgres-XL does not support TRIGGER yet
-DETAIL:  The feature is not currently supported
-create trigger tg_backlink_a after insert or update or delete
-    on WSlot for each row execute procedure tg_backlink_a('WS');
-ERROR:  Postgres-XL does not support TRIGGER yet
-DETAIL:  The feature is not currently supported
-create trigger tg_backlink_a after insert or update or delete
-    on PLine for each row execute procedure tg_backlink_a('PL');
-ERROR:  Postgres-XL does not support TRIGGER yet
-DETAIL:  The feature is not currently supported
--- ************************************************************
--- * Support function to set the opponents backlink field
--- * if it does not already point to the requested slot
--- ************************************************************
-create function tg_backlink_set(myname bpchar, blname bpchar)
-returns integer as '
-declare
-    mytype     char(2);
-    link       char(4);
-    rec                record;
-begin
-    mytype := substr(myname, 1, 2);
-    link := mytype || substr(blname, 1, 2);
-    if link = ''PLPL'' then
-        raise exception
-               ''backlink between two phone lines does not make sense'';
-    end if;
-    if link in (''PLWS'', ''WSPL'') then
-        raise exception
-               ''direct link of phone line to wall slot not permitted'';
-    end if;
-    if mytype = ''PS'' then
-        select into rec * from PSlot where slotname = myname;
-       if not found then
-           raise exception ''% does not exist'', myname;
-       end if;
-       if rec.backlink != blname then
-           update PSlot set backlink = blname where slotname = myname;
-       end if;
-       return 0;
-    end if;
-    if mytype = ''WS'' then
-        select into rec * from WSlot where slotname = myname;
-       if not found then
-           raise exception ''% does not exist'', myname;
-       end if;
-       if rec.backlink != blname then
-           update WSlot set backlink = blname where slotname = myname;
-       end if;
-       return 0;
-    end if;
-    if mytype = ''PL'' then
-        select into rec * from PLine where slotname = myname;
-       if not found then
-           raise exception ''% does not exist'', myname;
-       end if;
-       if rec.backlink != blname then
-           update PLine set backlink = blname where slotname = myname;
-       end if;
-       return 0;
-    end if;
-    raise exception ''illegal backlink beginning with %'', mytype;
-end;
-' language plpgsql;
--- ************************************************************
--- * Support function to clear out the backlink field if
--- * it still points to specific slot
--- ************************************************************
-create function tg_backlink_unset(bpchar, bpchar)
-returns integer as '
-declare
-    myname     alias for $1;
-    blname     alias for $2;
-    mytype     char(2);
-    rec                record;
-begin
-    mytype := substr(myname, 1, 2);
-    if mytype = ''PS'' then
-        select into rec * from PSlot where slotname = myname;
-       if not found then
-           return 0;
-       end if;
-       if rec.backlink = blname then
-           update PSlot set backlink = '''' where slotname = myname;
-       end if;
-       return 0;
-    end if;
-    if mytype = ''WS'' then
-        select into rec * from WSlot where slotname = myname;
-       if not found then
-           return 0;
-       end if;
-       if rec.backlink = blname then
-           update WSlot set backlink = '''' where slotname = myname;
-       end if;
-       return 0;
-    end if;
-    if mytype = ''PL'' then
-        select into rec * from PLine where slotname = myname;
-       if not found then
-           return 0;
-       end if;
-       if rec.backlink = blname then
-           update PLine set backlink = '''' where slotname = myname;
-       end if;
-       return 0;
-    end if;
-end
-' language plpgsql;
--- ************************************************************
--- * AFTER INSERT or UPDATE or DELETE on slot with slotlink
--- *   - Ensure that the opponent correctly points back to us
--- ************************************************************
-create function tg_slotlink_a() returns trigger as '
-declare
-    dummy      integer;
-begin
-    if tg_op = ''INSERT'' then
-        if new.slotlink != '''' then
-           dummy := tg_slotlink_set(new.slotlink, new.slotname);
-       end if;
-       return new;
-    end if;
-    if tg_op = ''UPDATE'' then
-        if new.slotlink != old.slotlink then
-           if old.slotlink != '''' then
-               dummy := tg_slotlink_unset(old.slotlink, old.slotname);
-           end if;
-           if new.slotlink != '''' then
-               dummy := tg_slotlink_set(new.slotlink, new.slotname);
-           end if;
-       else
-           if new.slotname != old.slotname and new.slotlink != '''' then
-               dummy := tg_slotlink_set(new.slotlink, new.slotname);
-           end if;
-       end if;
-       return new;
-    end if;
-    if tg_op = ''DELETE'' then
-        if old.slotlink != '''' then
-           dummy := tg_slotlink_unset(old.slotlink, old.slotname);
-       end if;
-       return old;
-    end if;
-end;
-' language plpgsql;
-create trigger tg_slotlink_a after insert or update or delete
-    on PSlot for each row execute procedure tg_slotlink_a('PS');
-ERROR:  Postgres-XL does not support TRIGGER yet
-DETAIL:  The feature is not currently supported
-create trigger tg_slotlink_a after insert or update or delete
-    on WSlot for each row execute procedure tg_slotlink_a('WS');
-ERROR:  Postgres-XL does not support TRIGGER yet
-DETAIL:  The feature is not currently supported
-create trigger tg_slotlink_a after insert or update or delete
-    on IFace for each row execute procedure tg_slotlink_a('IF');
-ERROR:  Postgres-XL does not support TRIGGER yet
-DETAIL:  The feature is not currently supported
-create trigger tg_slotlink_a after insert or update or delete
-    on HSlot for each row execute procedure tg_slotlink_a('HS');
-ERROR:  Postgres-XL does not support TRIGGER yet
-DETAIL:  The feature is not currently supported
-create trigger tg_slotlink_a after insert or update or delete
-    on PHone for each row execute procedure tg_slotlink_a('PH');
-ERROR:  Postgres-XL does not support TRIGGER yet
-DETAIL:  The feature is not currently supported
--- ************************************************************
--- * Support function to set the opponents slotlink field
--- * if it does not already point to the requested slot
--- ************************************************************
-create function tg_slotlink_set(bpchar, bpchar)
-returns integer as '
-declare
-    myname     alias for $1;
-    blname     alias for $2;
-    mytype     char(2);
-    link       char(4);
-    rec                record;
-begin
-    mytype := substr(myname, 1, 2);
-    link := mytype || substr(blname, 1, 2);
-    if link = ''PHPH'' then
-        raise exception
-               ''slotlink between two phones does not make sense'';
-    end if;
-    if link in (''PHHS'', ''HSPH'') then
-        raise exception
-               ''link of phone to hub does not make sense'';
-    end if;
-    if link in (''PHIF'', ''IFPH'') then
-        raise exception
-               ''link of phone to hub does not make sense'';
-    end if;
-    if link in (''PSWS'', ''WSPS'') then
-        raise exception
-               ''slotlink from patchslot to wallslot not permitted'';
-    end if;
-    if mytype = ''PS'' then
-        select into rec * from PSlot where slotname = myname;
-       if not found then
-           raise exception ''% does not exist'', myname;
-       end if;
-       if rec.slotlink != blname then
-           update PSlot set slotlink = blname where slotname = myname;
-       end if;
-       return 0;
-    end if;
-    if mytype = ''WS'' then
-        select into rec * from WSlot where slotname = myname;
-       if not found then
-           raise exception ''% does not exist'', myname;
-       end if;
-       if rec.slotlink != blname then
-           update WSlot set slotlink = blname where slotname = myname;
-       end if;
-       return 0;
-    end if;
-    if mytype = ''IF'' then
-        select into rec * from IFace where slotname = myname;
-       if not found then
-           raise exception ''% does not exist'', myname;
-       end if;
-       if rec.slotlink != blname then
-           update IFace set slotlink = blname where slotname = myname;
-       end if;
-       return 0;
-    end if;
-    if mytype = ''HS'' then
-        select into rec * from HSlot where slotname = myname;
-       if not found then
-           raise exception ''% does not exist'', myname;
-       end if;
-       if rec.slotlink != blname then
-           update HSlot set slotlink = blname where slotname = myname;
-       end if;
-       return 0;
-    end if;
-    if mytype = ''PH'' then
-        select into rec * from PHone where slotname = myname;
-       if not found then
-           raise exception ''% does not exist'', myname;
-       end if;
-       if rec.slotlink != blname then
-           update PHone set slotlink = blname where slotname = myname;
-       end if;
-       return 0;
-    end if;
-    raise exception ''illegal slotlink beginning with %'', mytype;
-end;
-' language plpgsql;
--- ************************************************************
--- * Support function to clear out the slotlink field if
--- * it still points to specific slot
--- ************************************************************
-create function tg_slotlink_unset(bpchar, bpchar)
-returns integer as '
-declare
-    myname     alias for $1;
-    blname     alias for $2;
-    mytype     char(2);
-    rec                record;
-begin
-    mytype := substr(myname, 1, 2);
-    if mytype = ''PS'' then
-        select into rec * from PSlot where slotname = myname;
-       if not found then
-           return 0;
-       end if;
-       if rec.slotlink = blname then
-           update PSlot set slotlink = '''' where slotname = myname;
-       end if;
-       return 0;
-    end if;
-    if mytype = ''WS'' then
-        select into rec * from WSlot where slotname = myname;
-       if not found then
-           return 0;
-       end if;
-       if rec.slotlink = blname then
-           update WSlot set slotlink = '''' where slotname = myname;
-       end if;
-       return 0;
-    end if;
-    if mytype = ''IF'' then
-        select into rec * from IFace where slotname = myname;
-       if not found then
-           return 0;
-       end if;
-       if rec.slotlink = blname then
-           update IFace set slotlink = '''' where slotname = myname;
-       end if;
-       return 0;
-    end if;
-    if mytype = ''HS'' then
-        select into rec * from HSlot where slotname = myname;
-       if not found then
-           return 0;
-       end if;
-       if rec.slotlink = blname then
-           update HSlot set slotlink = '''' where slotname = myname;
-       end if;
-       return 0;
-    end if;
-    if mytype = ''PH'' then
-        select into rec * from PHone where slotname = myname;
-       if not found then
-           return 0;
-       end if;
-       if rec.slotlink = blname then
-           update PHone set slotlink = '''' where slotname = myname;
-       end if;
-       return 0;
-    end if;
-end;
-' language plpgsql;
--- ************************************************************
--- * Describe the backside of a patchfield slot
--- ************************************************************
-create function pslot_backlink_view(bpchar)
-returns text as '
-<<outer>>
-declare
-    rec                record;
-    bltype     char(2);
-    retval     text;
-begin
-    select into rec * from PSlot where slotname = $1;
-    if not found then
-        return '''';
-    end if;
-    if rec.backlink = '''' then
-        return ''-'';
-    end if;
-    bltype := substr(rec.backlink, 1, 2);
-    if bltype = ''PL'' then
-        declare
-           rec         record;
-       begin
-           select into rec * from PLine where slotname = "outer".rec.backlink;
-           retval := ''Phone line '' || trim(rec.phonenumber);
-           if rec.comment != '''' then
-               retval := retval || '' ('';
-               retval := retval || rec.comment;
-               retval := retval || '')'';
-           end if;
-           return retval;
-       end;
-    end if;
-    if bltype = ''WS'' then
-        select into rec * from WSlot where slotname = rec.backlink;
-       retval := trim(rec.slotname) || '' in room '';
-       retval := retval || trim(rec.roomno);
-       retval := retval || '' -> '';
-       return retval || wslot_slotlink_view(rec.slotname);
-    end if;
-    return rec.backlink;
-end;
-' language plpgsql;
--- ************************************************************
--- * Describe the front of a patchfield slot
--- ************************************************************
-create function pslot_slotlink_view(bpchar)
-returns text as '
-declare
-    psrec      record;
-    sltype     char(2);
-    retval     text;
-begin
-    select into psrec * from PSlot where slotname = $1;
-    if not found then
-        return '''';
-    end if;
-    if psrec.slotlink = '''' then
-        return ''-'';
-    end if;
-    sltype := substr(psrec.slotlink, 1, 2);
-    if sltype = ''PS'' then
-       retval := trim(psrec.slotlink) || '' -> '';
-       return retval || pslot_backlink_view(psrec.slotlink);
-    end if;
-    if sltype = ''HS'' then
-        retval := comment from Hub H, HSlot HS
-                       where HS.slotname = psrec.slotlink
-                         and H.name = HS.hubname;
-        retval := retval || '' slot '';
-       retval := retval || slotno::text from HSlot
-                       where slotname = psrec.slotlink;
-       return retval;
-    end if;
-    return psrec.slotlink;
-end;
-' language plpgsql;
--- ************************************************************
--- * Describe the front of a wall connector slot
--- ************************************************************
-create function wslot_slotlink_view(bpchar)
-returns text as '
-declare
-    rec                record;
-    sltype     char(2);
-    retval     text;
-begin
-    select into rec * from WSlot where slotname = $1;
-    if not found then
-        return '''';
-    end if;
-    if rec.slotlink = '''' then
-        return ''-'';
-    end if;
-    sltype := substr(rec.slotlink, 1, 2);
-    if sltype = ''PH'' then
-        select into rec * from PHone where slotname = rec.slotlink;
-       retval := ''Phone '' || trim(rec.slotname);
-       if rec.comment != '''' then
-           retval := retval || '' ('';
-           retval := retval || rec.comment;
-           retval := retval || '')'';
-       end if;
-       return retval;
-    end if;
-    if sltype = ''IF'' then
-       declare
-           syrow       System%RowType;
-           ifrow       IFace%ROWTYPE;
-        begin
-           select into ifrow * from IFace where slotname = rec.slotlink;
-           select into syrow * from System where name = ifrow.sysname;
-           retval := syrow.name || '' IF '';
-           retval := retval || ifrow.ifname;
-           if syrow.comment != '''' then
-               retval := retval || '' ('';
-               retval := retval || syrow.comment;
-               retval := retval || '')'';
-           end if;
-           return retval;
-       end;
-    end if;
-    return rec.slotlink;
-end;
-' language plpgsql;
--- ************************************************************
--- * View of a patchfield describing backside and patches
--- ************************************************************
-create view Pfield_v1 as select PF.pfname, PF.slotname,
-       pslot_backlink_view(PF.slotname) as backside,
-       pslot_slotlink_view(PF.slotname) as patch
-    from PSlot PF;
---
--- First we build the house - so we create the rooms
---
-insert into Room values ('001', 'Entrance');
-insert into Room values ('002', 'Office');
-insert into Room values ('003', 'Office');
-insert into Room values ('004', 'Technical');
-insert into Room values ('101', 'Office');
-insert into Room values ('102', 'Conference');
-insert into Room values ('103', 'Restroom');
-insert into Room values ('104', 'Technical');
-insert into Room values ('105', 'Office');
-insert into Room values ('106', 'Office');
---
--- Second we install the wall connectors
---
-insert into WSlot values ('WS.001.1a', '001', '', '');
-insert into WSlot values ('WS.001.1b', '001', '', '');
-insert into WSlot values ('WS.001.2a', '001', '', '');
-insert into WSlot values ('WS.001.2b', '001', '', '');
-insert into WSlot values ('WS.001.3a', '001', '', '');
-insert into WSlot values ('WS.001.3b', '001', '', '');
-insert into WSlot values ('WS.002.1a', '002', '', '');
-insert into WSlot values ('WS.002.1b', '002', '', '');
-insert into WSlot values ('WS.002.2a', '002', '', '');
-insert into WSlot values ('WS.002.2b', '002', '', '');
-insert into WSlot values ('WS.002.3a', '002', '', '');
-insert into WSlot values ('WS.002.3b', '002', '', '');
-insert into WSlot values ('WS.003.1a', '003', '', '');
-insert into WSlot values ('WS.003.1b', '003', '', '');
-insert into WSlot values ('WS.003.2a', '003', '', '');
-insert into WSlot values ('WS.003.2b', '003', '', '');
-insert into WSlot values ('WS.003.3a', '003', '', '');
-insert into WSlot values ('WS.003.3b', '003', '', '');
-insert into WSlot values ('WS.101.1a', '101', '', '');
-insert into WSlot values ('WS.101.1b', '101', '', '');
-insert into WSlot values ('WS.101.2a', '101', '', '');
-insert into WSlot values ('WS.101.2b', '101', '', '');
-insert into WSlot values ('WS.101.3a', '101', '', '');
-insert into WSlot values ('WS.101.3b', '101', '', '');
-insert into WSlot values ('WS.102.1a', '102', '', '');
-insert into WSlot values ('WS.102.1b', '102', '', '');
-insert into WSlot values ('WS.102.2a', '102', '', '');
-insert into WSlot values ('WS.102.2b', '102', '', '');
-insert into WSlot values ('WS.102.3a', '102', '', '');
-insert into WSlot values ('WS.102.3b', '102', '', '');
-insert into WSlot values ('WS.105.1a', '105', '', '');
-insert into WSlot values ('WS.105.1b', '105', '', '');
-insert into WSlot values ('WS.105.2a', '105', '', '');
-insert into WSlot values ('WS.105.2b', '105', '', '');
-insert into WSlot values ('WS.105.3a', '105', '', '');
-insert into WSlot values ('WS.105.3b', '105', '', '');
-insert into WSlot values ('WS.106.1a', '106', '', '');
-insert into WSlot values ('WS.106.1b', '106', '', '');
-insert into WSlot values ('WS.106.2a', '106', '', '');
-insert into WSlot values ('WS.106.2b', '106', '', '');
-insert into WSlot values ('WS.106.3a', '106', '', '');
-insert into WSlot values ('WS.106.3b', '106', '', '');
---
--- Now create the patch fields and their slots
---
-insert into PField values ('PF0_1', 'Wallslots basement');
---
--- The cables for these will be made later, so they are unconnected for now
---
-insert into PSlot values ('PS.base.a1', 'PF0_1', '', '');
-insert into PSlot values ('PS.base.a2', 'PF0_1', '', '');
-insert into PSlot values ('PS.base.a3', 'PF0_1', '', '');
-insert into PSlot values ('PS.base.a4', 'PF0_1', '', '');
-insert into PSlot values ('PS.base.a5', 'PF0_1', '', '');
-insert into PSlot values ('PS.base.a6', 'PF0_1', '', '');
---
--- These are already wired to the wall connectors
---
-insert into PSlot values ('PS.base.b1', 'PF0_1', '', 'WS.002.1a');
-insert into PSlot values ('PS.base.b2', 'PF0_1', '', 'WS.002.1b');
-insert into PSlot values ('PS.base.b3', 'PF0_1', '', 'WS.002.2a');
-insert into PSlot values ('PS.base.b4', 'PF0_1', '', 'WS.002.2b');
-insert into PSlot values ('PS.base.b5', 'PF0_1', '', 'WS.002.3a');
-insert into PSlot values ('PS.base.b6', 'PF0_1', '', 'WS.002.3b');
-insert into PSlot values ('PS.base.c1', 'PF0_1', '', 'WS.003.1a');
-insert into PSlot values ('PS.base.c2', 'PF0_1', '', 'WS.003.1b');
-insert into PSlot values ('PS.base.c3', 'PF0_1', '', 'WS.003.2a');
-insert into PSlot values ('PS.base.c4', 'PF0_1', '', 'WS.003.2b');
-insert into PSlot values ('PS.base.c5', 'PF0_1', '', 'WS.003.3a');
-insert into PSlot values ('PS.base.c6', 'PF0_1', '', 'WS.003.3b');
---
--- This patchfield will be renamed later into PF0_2 - so its
--- slots references in pfname should follow
---
-insert into PField values ('PF0_X', 'Phonelines basement');
-insert into PSlot values ('PS.base.ta1', 'PF0_X', '', '');
-insert into PSlot values ('PS.base.ta2', 'PF0_X', '', '');
-insert into PSlot values ('PS.base.ta3', 'PF0_X', '', '');
-insert into PSlot values ('PS.base.ta4', 'PF0_X', '', '');
-insert into PSlot values ('PS.base.ta5', 'PF0_X', '', '');
-insert into PSlot values ('PS.base.ta6', 'PF0_X', '', '');
-insert into PSlot values ('PS.base.tb1', 'PF0_X', '', '');
-insert into PSlot values ('PS.base.tb2', 'PF0_X', '', '');
-insert into PSlot values ('PS.base.tb3', 'PF0_X', '', '');
-insert into PSlot values ('PS.base.tb4', 'PF0_X', '', '');
-insert into PSlot values ('PS.base.tb5', 'PF0_X', '', '');
-insert into PSlot values ('PS.base.tb6', 'PF0_X', '', '');
-insert into PField values ('PF1_1', 'Wallslots first floor');
-insert into PSlot values ('PS.first.a1', 'PF1_1', '', 'WS.101.1a');
-insert into PSlot values ('PS.first.a2', 'PF1_1', '', 'WS.101.1b');
-insert into PSlot values ('PS.first.a3', 'PF1_1', '', 'WS.101.2a');
-insert into PSlot values ('PS.first.a4', 'PF1_1', '', 'WS.101.2b');
-insert into PSlot values ('PS.first.a5', 'PF1_1', '', 'WS.101.3a');
-insert into PSlot values ('PS.first.a6', 'PF1_1', '', 'WS.101.3b');
-insert into PSlot values ('PS.first.b1', 'PF1_1', '', 'WS.102.1a');
-insert into PSlot values ('PS.first.b2', 'PF1_1', '', 'WS.102.1b');
-insert into PSlot values ('PS.first.b3', 'PF1_1', '', 'WS.102.2a');
-insert into PSlot values ('PS.first.b4', 'PF1_1', '', 'WS.102.2b');
-insert into PSlot values ('PS.first.b5', 'PF1_1', '', 'WS.102.3a');
-insert into PSlot values ('PS.first.b6', 'PF1_1', '', 'WS.102.3b');
-insert into PSlot values ('PS.first.c1', 'PF1_1', '', 'WS.105.1a');
-insert into PSlot values ('PS.first.c2', 'PF1_1', '', 'WS.105.1b');
-insert into PSlot values ('PS.first.c3', 'PF1_1', '', 'WS.105.2a');
-insert into PSlot values ('PS.first.c4', 'PF1_1', '', 'WS.105.2b');
-insert into PSlot values ('PS.first.c5', 'PF1_1', '', 'WS.105.3a');
-insert into PSlot values ('PS.first.c6', 'PF1_1', '', 'WS.105.3b');
-insert into PSlot values ('PS.first.d1', 'PF1_1', '', 'WS.106.1a');
-insert into PSlot values ('PS.first.d2', 'PF1_1', '', 'WS.106.1b');
-insert into PSlot values ('PS.first.d3', 'PF1_1', '', 'WS.106.2a');
-insert into PSlot values ('PS.first.d4', 'PF1_1', '', 'WS.106.2b');
-insert into PSlot values ('PS.first.d5', 'PF1_1', '', 'WS.106.3a');
-insert into PSlot values ('PS.first.d6', 'PF1_1', '', 'WS.106.3b');
---
--- Now we wire the wall connectors 1a-2a in room 001 to the
--- patchfield. In the second update we make an error, and
--- correct it after
---
-update PSlot set backlink = 'WS.001.1a' where slotname = 'PS.base.a1';
-update PSlot set backlink = 'WS.001.1b' where slotname = 'PS.base.a3';
-select * from WSlot where roomno = '001' order by slotname;
-       slotname       |  roomno  |       slotlink       |       backlink       
-----------------------+----------+----------------------+----------------------
- WS.001.1a            | 001      |                      |                     
- WS.001.1b            | 001      |                      |                     
- WS.001.2a            | 001      |                      |                     
- WS.001.2b            | 001      |                      |                     
- WS.001.3a            | 001      |                      |                     
- WS.001.3b            | 001      |                      |                     
-(6 rows)
-
-select * from PSlot where slotname ~ 'PS.base.a' order by slotname;
-       slotname       | pfname |       slotlink       |       backlink       
-----------------------+--------+----------------------+----------------------
- PS.base.a1           | PF0_1  |                      | WS.001.1a           
- PS.base.a2           | PF0_1  |                      |                     
- PS.base.a3           | PF0_1  |                      | WS.001.1b           
- PS.base.a4           | PF0_1  |                      |                     
- PS.base.a5           | PF0_1  |                      |                     
- PS.base.a6           | PF0_1  |                      |                     
-(6 rows)
-
-update PSlot set backlink = 'WS.001.2a' where slotname = 'PS.base.a3';
-select * from WSlot where roomno = '001' order by slotname;
-       slotname       |  roomno  |       slotlink       |       backlink       
-----------------------+----------+----------------------+----------------------
- WS.001.1a            | 001      |                      |                     
- WS.001.1b            | 001      |                      |                     
- WS.001.2a            | 001      |                      |                     
- WS.001.2b            | 001      |                      |                     
- WS.001.3a            | 001      |                      |                     
- WS.001.3b            | 001      |                      |                     
-(6 rows)
-
-select * from PSlot where slotname ~ 'PS.base.a' order by slotname;
-       slotname       | pfname |       slotlink       |       backlink       
-----------------------+--------+----------------------+----------------------
- PS.base.a1           | PF0_1  |                      | WS.001.1a           
- PS.base.a2           | PF0_1  |                      |                     
- PS.base.a3           | PF0_1  |                      | WS.001.2a           
- PS.base.a4           | PF0_1  |                      |                     
- PS.base.a5           | PF0_1  |                      |                     
- PS.base.a6           | PF0_1  |                      |                     
-(6 rows)
-
-update PSlot set backlink = 'WS.001.1b' where slotname = 'PS.base.a2';
-select * from WSlot where roomno = '001' order by slotname;
-       slotname       |  roomno  |       slotlink       |       backlink       
-----------------------+----------+----------------------+----------------------
- WS.001.1a            | 001      |                      |                     
- WS.001.1b            | 001      |                      |                     
- WS.001.2a            | 001      |                      |                     
- WS.001.2b            | 001      |                      |                     
- WS.001.3a            | 001      |                      |                     
- WS.001.3b            | 001      |                      |                     
-(6 rows)
-
-select * from PSlot where slotname ~ 'PS.base.a' order by slotname;
-       slotname       | pfname |       slotlink       |       backlink       
-----------------------+--------+----------------------+----------------------
- PS.base.a1           | PF0_1  |                      | WS.001.1a           
- PS.base.a2           | PF0_1  |                      | WS.001.1b           
- PS.base.a3           | PF0_1  |                      | WS.001.2a           
- PS.base.a4           | PF0_1  |                      |                     
- PS.base.a5           | PF0_1  |                      |                     
- PS.base.a6           | PF0_1  |                      |                     
-(6 rows)
-
---
--- Same procedure for 2b-3b but this time updating the WSlot instead
--- of the PSlot. Due to the triggers the result is the same:
--- WSlot and corresponding PSlot point to each other.
---
-update WSlot set backlink = 'PS.base.a4' where slotname = 'WS.001.2b';
-update WSlot set backlink = 'PS.base.a6' where slotname = 'WS.001.3a';
-select * from WSlot where roomno = '001' order by slotname;
-       slotname       |  roomno  |       slotlink       |       backlink       
-----------------------+----------+----------------------+----------------------
- WS.001.1a            | 001      |                      |                     
- WS.001.1b            | 001      |                      |                     
- WS.001.2a            | 001      |                      |                     
- WS.001.2b            | 001      |                      | PS.base.a4          
- WS.001.3a            | 001      |                      | PS.base.a6          
- WS.001.3b            | 001      |                      |                     
-(6 rows)
-
-select * from PSlot where slotname ~ 'PS.base.a' order by slotname;
-       slotname       | pfname |       slotlink       |       backlink       
-----------------------+--------+----------------------+----------------------
- PS.base.a1           | PF0_1  |                      | WS.001.1a           
- PS.base.a2           | PF0_1  |                      | WS.001.1b           
- PS.base.a3           | PF0_1  |                      | WS.001.2a           
- PS.base.a4           | PF0_1  |                      |                     
- PS.base.a5           | PF0_1  |                      |                     
- PS.base.a6           | PF0_1  |                      |                     
-(6 rows)
-
-update WSlot set backlink = 'PS.base.a6' where slotname = 'WS.001.3b';
-select * from WSlot where roomno = '001' order by slotname;
-       slotname       |  roomno  |       slotlink       |       backlink       
-----------------------+----------+----------------------+----------------------
- WS.001.1a            | 001      |                      |                     
- WS.001.1b            | 001      |                      |                     
- WS.001.2a            | 001      |                      |                     
- WS.001.2b            | 001      |                      | PS.base.a4          
- WS.001.3a            | 001      |                      | PS.base.a6          
- WS.001.3b            | 001      |                      | PS.base.a6          
-(6 rows)
-
-select * from PSlot where slotname ~ 'PS.base.a' order by slotname;
-       slotname       | pfname |       slotlink       |       backlink       
-----------------------+--------+----------------------+----------------------
- PS.base.a1           | PF0_1  |                      | WS.001.1a           
- PS.base.a2           | PF0_1  |                      | WS.001.1b           
- PS.base.a3           | PF0_1  |                      | WS.001.2a           
- PS.base.a4           | PF0_1  |                      |                     
- PS.base.a5           | PF0_1  |                      |                     
- PS.base.a6           | PF0_1  |                      |                     
-(6 rows)
-
-update WSlot set backlink = 'PS.base.a5' where slotname = 'WS.001.3a';
-select * from WSlot where roomno = '001' order by slotname;
-       slotname       |  roomno  |       slotlink       |       backlink       
-----------------------+----------+----------------------+----------------------
- WS.001.1a            | 001      |                      |                     
- WS.001.1b            | 001      |                      |                     
- WS.001.2a            | 001      |                      |                     
- WS.001.2b            | 001      |                      | PS.base.a4          
- WS.001.3a            | 001      |                      | PS.base.a5          
- WS.001.3b            | 001      |                      | PS.base.a6          
-(6 rows)
-
-select * from PSlot where slotname ~ 'PS.base.a' order by slotname;
-       slotname       | pfname |       slotlink       |       backlink       
-----------------------+--------+----------------------+----------------------
- PS.base.a1           | PF0_1  |                      | WS.001.1a           
- PS.base.a2           | PF0_1  |                      | WS.001.1b           
- PS.base.a3           | PF0_1  |                      | WS.001.2a           
- PS.base.a4           | PF0_1  |                      |                     
- PS.base.a5           | PF0_1  |                      |                     
- PS.base.a6           | PF0_1  |                      |                     
-(6 rows)
-
-insert into PField values ('PF1_2', 'Phonelines first floor');
-insert into PSlot values ('PS.first.ta1', 'PF1_2', '', '');
-insert into PSlot values ('PS.first.ta2', 'PF1_2', '', '');
-insert into PSlot values ('PS.first.ta3', 'PF1_2', '', '');
-insert into PSlot values ('PS.first.ta4', 'PF1_2', '', '');
-insert into PSlot values ('PS.first.ta5', 'PF1_2', '', '');
-insert into PSlot values ('PS.first.ta6', 'PF1_2', '', '');
-insert into PSlot values ('PS.first.tb1', 'PF1_2', '', '');
-insert into PSlot values ('PS.first.tb2', 'PF1_2', '', '');
-insert into PSlot values ('PS.first.tb3', 'PF1_2', '', '');
-insert into PSlot values ('PS.first.tb4', 'PF1_2', '', '');
-insert into PSlot values ('PS.first.tb5', 'PF1_2', '', '');
-insert into PSlot values ('PS.first.tb6', 'PF1_2', '', '');
---
--- Fix the wrong name for patchfield PF0_2
---
-update PField set name = 'PF0_2' where name = 'PF0_X';
-select * from PSlot order by slotname;
-       slotname       | pfname |       slotlink       |       backlink       
-----------------------+--------+----------------------+----------------------
- PS.base.a1           | PF0_1  |                      | WS.001.1a           
- PS.base.a2           | PF0_1  |                      | WS.001.1b           
- PS.base.a3           | PF0_1  |                      | WS.001.2a           
- PS.base.a4           | PF0_1  |                      |                     
- PS.base.a5           | PF0_1  |                      |                     
- PS.base.a6           | PF0_1  |                      |                     
- PS.base.b1           | PF0_1  |                      | WS.002.1a           
- PS.base.b2           | PF0_1  |                      | WS.002.1b           
- PS.base.b3           | PF0_1  |                      | WS.002.2a           
- PS.base.b4           | PF0_1  |                      | WS.002.2b           
- PS.base.b5           | PF0_1  |                      | WS.002.3a           
- PS.base.b6           | PF0_1  |                      | WS.002.3b           
- PS.base.c1           | PF0_1  |                      | WS.003.1a           
- PS.base.c2           | PF0_1  |                      | WS.003.1b           
- PS.base.c3           | PF0_1  |                      | WS.003.2a           
- PS.base.c4           | PF0_1  |                      | WS.003.2b           
- PS.base.c5           | PF0_1  |                      | WS.003.3a           
- PS.base.c6           | PF0_1  |                      | WS.003.3b           
- PS.base.ta1          | PF0_X  |                      |                     
- PS.base.ta2          | PF0_X  |                      |                     
- PS.base.ta3          | PF0_X  |                      |                     
- PS.base.ta4          | PF0_X  |                      |                     
- PS.base.ta5          | PF0_X  |                      |                     
- PS.base.ta6          | PF0_X  |                      |                     
- PS.base.tb1          | PF0_X  |                      |                     
- PS.base.tb2          | PF0_X  |                      |                     
- PS.base.tb3          | PF0_X  |                      |                     
- PS.base.tb4          | PF0_X  |                      |                     
- PS.base.tb5          | PF0_X  |                      |                     
- PS.base.tb6          | PF0_X  |                      |                     
- PS.first.a1          | PF1_1  |                      | WS.101.1a           
- PS.first.a2          | PF1_1  |                      | WS.101.1b           
- PS.first.a3          | PF1_1  |                      | WS.101.2a           
- PS.first.a4          | PF1_1  |                      | WS.101.2b           
- PS.first.a5          | PF1_1  |                      | WS.101.3a           
- PS.first.a6          | PF1_1  |                      | WS.101.3b           
- PS.first.b1          | PF1_1  |                      | WS.102.1a           
- PS.first.b2          | PF1_1  |                      | WS.102.1b           
- PS.first.b3          | PF1_1  |                      | WS.102.2a           
- PS.first.b4          | PF1_1  |                      | WS.102.2b           
- PS.first.b5          | PF1_1  |                      | WS.102.3a           
- PS.first.b6          | PF1_1  |                      | WS.102.3b           
- PS.first.c1          | PF1_1  |                      | WS.105.1a           
- PS.first.c2          | PF1_1  |                      | WS.105.1b           
- PS.first.c3          | PF1_1  |                      | WS.105.2a           
- PS.first.c4          | PF1_1  |                      | WS.105.2b           
- PS.first.c5          | PF1_1  |                      | WS.105.3a           
- PS.first.c6          | PF1_1  |                      | WS.105.3b           
- PS.first.d1          | PF1_1  |                      | WS.106.1a           
- PS.first.d2          | PF1_1  |                      | WS.106.1b           
- PS.first.d3          | PF1_1  |                      | WS.106.2a           
- PS.first.d4          | PF1_1  |                      | WS.106.2b           
- PS.first.d5          | PF1_1  |                      | WS.106.3a           
- PS.first.d6          | PF1_1  |                      | WS.106.3b           
- PS.first.ta1         | PF1_2  |                      |                     
- PS.first.ta2         | PF1_2  |                      |                     
- PS.first.ta3         | PF1_2  |                      |                     
- PS.first.ta4         | PF1_2  |                      |                     
- PS.first.ta5         | PF1_2  |                      |                     
- PS.first.ta6         | PF1_2  |                      |                     
- PS.first.tb1         | PF1_2  |                      |                     
- PS.first.tb2         | PF1_2  |                      |                     
- PS.first.tb3         | PF1_2  |                      |                     
- PS.first.tb4         | PF1_2  |                      |                     
- PS.first.tb5         | PF1_2  |                      |                     
- PS.first.tb6         | PF1_2  |                      |                     
-(66 rows)
-
-select * from WSlot order by slotname;
-       slotname       |  roomno  |       slotlink       |       backlink       
-----------------------+----------+----------------------+----------------------
- WS.001.1a            | 001      |                      |                     
- WS.001.1b            | 001      |                      |                     
- WS.001.2a            | 001      |                      |                     
- WS.001.2b            | 001      |                      | PS.base.a4          
- WS.001.3a            | 001      |                      | PS.base.a5          
- WS.001.3b            | 001      |                      | PS.base.a6          
- WS.002.1a            | 002      |                      |                     
- WS.002.1b            | 002      |                      |                     
- WS.002.2a            | 002      |                      |                     
- WS.002.2b            | 002      |                      |                     
- WS.002.3a            | 002      |                      |                     
- WS.002.3b            | 002      |                      |                     
- WS.003.1a            | 003      |                      |                     
- WS.003.1b            | 003      |                      |                     
- WS.003.2a            | 003      |                      |                     
- WS.003.2b            | 003      |                      |                     
- WS.003.3a            | 003      |                      |                     
- WS.003.3b            | 003      |                      |                     
- WS.101.1a            | 101      |                      |                     
- WS.101.1b            | 101      |                      |                     
- WS.101.2a            | 101      |                      |                     
- WS.101.2b            | 101      |                      |                     
- WS.101.3a            | 101      |                      |                     
- WS.101.3b            | 101      |                      |                     
- WS.102.1a            | 102      |                      |                     
- WS.102.1b            | 102      |                      |                     
- WS.102.2a            | 102      |                      |                     
- WS.102.2b            | 102      |                      |                     
- WS.102.3a            | 102      |                      |                     
- WS.102.3b            | 102      |                      |                     
- WS.105.1a            | 105      |                      |                     
- WS.105.1b            | 105      |                      |                     
- WS.105.2a            | 105      |                      |                     
- WS.105.2b            | 105      |                      |                     
- WS.105.3a            | 105      |                      |                     
- WS.105.3b            | 105      |                      |                     
- WS.106.1a            | 106      |                      |                     
- WS.106.1b            | 106      |                      |                     
- WS.106.2a            | 106      |                      |                     
- WS.106.2b            | 106      |                      |                     
- WS.106.3a            | 106      |                      |                     
- WS.106.3b            | 106      |                      |                     
-(42 rows)
-
---
--- Install the central phone system and create the phone numbers.
--- They are weired on insert to the patchfields. Again the
--- triggers automatically tell the PSlots to update their
--- backlink field.
---
-insert into PLine values ('PL.001', '-0', 'Central call', 'PS.base.ta1');
-insert into PLine values ('PL.002', '-101', '', 'PS.base.ta2');
-insert into PLine values ('PL.003', '-102', '', 'PS.base.ta3');
-insert into PLine values ('PL.004', '-103', '', 'PS.base.ta5');
-insert into PLine values ('PL.005', '-104', '', 'PS.base.ta6');
-insert into PLine values ('PL.006', '-106', '', 'PS.base.tb2');
-insert into PLine values ('PL.007', '-108', '', 'PS.base.tb3');
-insert into PLine values ('PL.008', '-109', '', 'PS.base.tb4');
-insert into PLine values ('PL.009', '-121', '', 'PS.base.tb5');
-insert into PLine values ('PL.010', '-122', '', 'PS.base.tb6');
-insert into PLine values ('PL.015', '-134', '', 'PS.first.ta1');
-insert into PLine values ('PL.016', '-137', '', 'PS.first.ta3');
-insert into PLine values ('PL.017', '-139', '', 'PS.first.ta4');
-insert into PLine values ('PL.018', '-362', '', 'PS.first.tb1');
-insert into PLine values ('PL.019', '-363', '', 'PS.first.tb2');
-insert into PLine values ('PL.020', '-364', '', 'PS.first.tb3');
-insert into PLine values ('PL.021', '-365', '', 'PS.first.tb5');
-insert into PLine values ('PL.022', '-367', '', 'PS.first.tb6');
-insert into PLine values ('PL.028', '-501', 'Fax entrance', 'PS.base.ta2');
-insert into PLine values ('PL.029', '-502', 'Fax first floor', 'PS.first.ta1');
---
--- Buy some phones, plug them into the wall and patch the
--- phone lines to the corresponding patchfield slots.
---
-insert into PHone values ('PH.hc001', 'Hicom standard', 'WS.001.1a');
-update PSlot set slotlink = 'PS.base.ta1' where slotname = 'PS.base.a1';
-insert into PHone values ('PH.hc002', 'Hicom standard', 'WS.002.1a');
-update PSlot set slotlink = 'PS.base.ta5' where slotname = 'PS.base.b1';
-insert into PHone values ('PH.hc003', 'Hicom standard', 'WS.002.2a');
-update PSlot set slotlink = 'PS.base.tb2' where slotname = 'PS.base.b3';
-insert into PHone values ('PH.fax001', 'Canon fax', 'WS.001.2a');
-update PSlot set slotlink = 'PS.base.ta2' where slotname = 'PS.base.a3';
---
--- Install a hub at one of the patchfields, plug a computers
--- ethernet interface into the wall and patch it to the hub.
---
-insert into Hub values ('base.hub1', 'Patchfield PF0_1 hub', 16);
-insert into System values ('orion', 'PC');
-insert into IFace values ('IF', 'orion', 'eth0', 'WS.002.1b');
-update PSlot set slotlink = 'HS.base.hub1.1' where slotname = 'PS.base.b2';
---
--- Now we take a look at the patchfield
---
--- PGXCTODO: This is failing due to issue 3522907, complicated SELECT queries in plpgsql functions
-select * from PField_v1 where pfname = 'PF0_1' order by slotname;
- pfname |       slotname       |          backside          |      patch      
---------+----------------------+----------------------------+-----------------
- PF0_1  | PS.base.a1           | WS.001.1a in room 001 -> - | PS.base.ta1 -> 
- PF0_1  | PS.base.a2           |                            | -
- PF0_1  | PS.base.a3           | WS.001.2a in room 001 -> - | PS.base.ta2 -> 
- PF0_1  | PS.base.a4           | -                          | -
- PF0_1  | PS.base.a5           | -                          | -
- PF0_1  | PS.base.a6           | -                          | -
- PF0_1  | PS.base.b1           |                            | PS.base.ta5 -> 
- PF0_1  | PS.base.b2           |                            | 
- PF0_1  | PS.base.b3           |                            | PS.base.tb2 -> 
- PF0_1  | PS.base.b4           |                            | -
- PF0_1  | PS.base.b5           | WS.002.3a in room 002 -> - | -
- PF0_1  | PS.base.b6           |                            | -
- PF0_1  | PS.base.c1           | WS.003.1a in room 003 -> - | -
- PF0_1  | PS.base.c2           | WS.003.1b in room 003 -> - | -
- PF0_1  | PS.base.c3           | WS.003.2a in room 003 -> - | -
- PF0_1  | PS.base.c4           |                            | -
- PF0_1  | PS.base.c5           | WS.003.3a in room 003 -> - | -
- PF0_1  | PS.base.c6           |                            | -
-(18 rows)
-
-select * from PField_v1 where pfname = 'PF0_2' order by slotname;
- pfname | slotname | backside | patch 
---------+----------+----------+-------
-(0 rows)
-
---
--- Finally we want errors
---
-insert into PField values ('PF1_1', 'should fail due to unique index');
-ERROR:  duplicate key value violates unique constraint "pfield_name"
-DETAIL:  Key (name)=(PF1_1) already exists.
-update PSlot set backlink = 'WS.not.there' where slotname = 'PS.base.a1';
-update PSlot set backlink = 'XX.illegal' where slotname = 'PS.base.a1';
-update PSlot set slotlink = 'PS.not.there' where slotname = 'PS.base.a1';
-update PSlot set slotlink = 'XX.illegal' where slotname = 'PS.base.a1';
-insert into HSlot values ('HS', 'base.hub1', 1, '');
-insert into HSlot values ('HS', 'base.hub1', 20, '');
-ERROR:  duplicate key value violates unique constraint "hslot_name"
-DETAIL:  Key (slotname)=(HS                  ) already exists.
-delete from HSlot;
-insert into IFace values ('IF', 'notthere', 'eth0', '');
-ERROR:  duplicate key value violates unique constraint "iface_name"
-DETAIL:  Key (slotname)=(IF                  ) already exists.
-insert into IFace values ('IF', 'orion', 'ethernet_interface_name_too_long', '');
-ERROR:  duplicate key value violates unique constraint "iface_name"
-DETAIL:  Key (slotname)=(IF                  ) already exists.
---
--- The following tests are unrelated to the scenario outlined above;
--- they merely exercise specific parts of PL/pgSQL
---
---
--- Test recursion, per bug report 7-Sep-01
---
-CREATE FUNCTION recursion_test(int,int) RETURNS text AS '
-DECLARE rslt text;
-BEGIN
-    IF $1 <= 0 THEN
-        rslt = CAST($2 AS TEXT);
-    ELSE
-        rslt = CAST($1 AS TEXT) || '','' || recursion_test($1 - 1, $2);
-    END IF;
-    RETURN rslt;
-END;' LANGUAGE plpgsql;
-SELECT recursion_test(4,3);
- recursion_test 
-----------------
- 4,3,2,1,3
-(1 row)
-
---
--- Test the FOUND magic variable
---
-CREATE TABLE found_test_tbl (a int) distribute by roundrobin;
-create function test_found()
-  returns boolean as '
-  declare
-  begin
-  insert into found_test_tbl values (1);
-  if FOUND then
-     insert into found_test_tbl values (2);
-  end if;
-
-  update found_test_tbl set a = 100 where a = 1;
-  if FOUND then
-    insert into found_test_tbl values (3);
-  end if;
-
-  delete from found_test_tbl where a = 9999; -- matches no rows
-  if not FOUND then
-    insert into found_test_tbl values (4);
-  end if;
-
-  for i in 1 .. 10 loop
-    -- no need to do anything
-  end loop;
-  if FOUND then
-    insert into found_test_tbl values (5);
-  end if;
-
-  -- never executes the loop
-  for i in 2 .. 1 loop
-    -- no need to do anything
-  end loop;
-  if not FOUND then
-    insert into found_test_tbl values (6);
-  end if;
-  return true;
-  end;' language plpgsql;
-select test_found();
- test_found 
-------------
- t
-(1 row)
-
-select * from found_test_tbl order by 1;
-  a  
------
-   2
-   3
-   4
-   5
-   6
- 100
-(6 rows)
-
---
--- Test set-returning functions for PL/pgSQL
---
-create function test_table_func_rec() returns setof found_test_tbl as '
-DECLARE
-       rec RECORD;
-BEGIN
-       FOR rec IN select * from found_test_tbl LOOP
-               RETURN NEXT rec;
-       END LOOP;
-       RETURN;
-END;' language plpgsql;
-select * from test_table_func_rec() order by 1;
-  a  
------
-   2
-   3
-   4
-   5
-   6
- 100
-(6 rows)
-
-create function test_table_func_row() returns setof found_test_tbl as '
-DECLARE
-       row found_test_tbl%ROWTYPE;
-BEGIN
-       FOR row IN select * from found_test_tbl LOOP
-               RETURN NEXT row;
-       END LOOP;
-       RETURN;
-END;' language plpgsql;
-select * from test_table_func_row() order by 1;
-  a  
------
-   2
-   3
-   4
-   5
-   6
- 100
-(6 rows)
-
-create function test_ret_set_scalar(int,int) returns setof int as '
-DECLARE
-       i int;
-BEGIN
-       FOR i IN $1 .. $2 LOOP
-               RETURN NEXT i + 1;
-       END LOOP;
-       RETURN;
-END;' language plpgsql;
-select * from test_ret_set_scalar(1,10) order by 1;
- test_ret_set_scalar 
----------------------
-                   2
-                   3
-                   4
-                   5
-                   6
-                   7
-                   8
-                   9
-                  10
-                  11
-(10 rows)
-
-create function test_ret_set_rec_dyn(int) returns setof record as '
-DECLARE
-       retval RECORD;
-BEGIN
-       IF $1 > 10 THEN
-               SELECT INTO retval 5, 10, 15;
-               RETURN NEXT retval;
-               RETURN NEXT retval;
-       ELSE
-               SELECT INTO retval 50, 5::numeric, ''xxx''::text;
-               RETURN NEXT retval;
-               RETURN NEXT retval;
-       END IF;
-       RETURN;
-END;' language plpgsql;
-SELECT * FROM test_ret_set_rec_dyn(1500) AS (a int, b int, c int) order by a, b, c;
- a | b  | c  
----+----+----
- 5 | 10 | 15
- 5 | 10 | 15
-(2 rows)
-
-SELECT * FROM test_ret_set_rec_dyn(5) AS (a int, b numeric, c text) order by a, b, c;
- a  | b |  c  
-----+---+-----
- 50 | 5 | xxx
- 50 | 5 | xxx
-(2 rows)
-
-create function test_ret_rec_dyn(int) returns record as '
-DECLARE
-       retval RECORD;
-BEGIN
-       IF $1 > 10 THEN
-               SELECT INTO retval 5, 10, 15;
-               RETURN retval;
-       ELSE
-               SELECT INTO retval 50, 5::numeric, ''xxx''::text;
-               RETURN retval;
-       END IF;
-END;' language plpgsql;
-SELECT * FROM test_ret_rec_dyn(1500) AS (a int, b int, c int) order by a, b, c;
- a | b  | c  
----+----+----
- 5 | 10 | 15
-(1 row)
-
-SELECT * FROM test_ret_rec_dyn(5) AS (a int, b numeric, c text) order by a, b, c;
- a  | b |  c  
-----+---+-----
- 50 | 5 | xxx
-(1 row)
-
---
--- Test handling of OUT parameters, including polymorphic cases.
--- Note that RETURN is optional with OUT params; we try both ways.
---
--- wrong way to do it:
-create function f1(in i int, out j int) returns int as $$
-begin
-  return i+1;
-end$$ language plpgsql;
-ERROR:  RETURN cannot have a parameter in function with OUT parameters
-LINE 3:   return i+1;
-                 ^
-create function f1(in i int, out j int) as $$
-begin
-  j := i+1;
-  return;
-end$$ language plpgsql;
-select f1(42);
- f1 
-----
- 43
-(1 row)
-
-select * from f1(42);
- j  
-----
- 43
-(1 row)
-
-create or replace function f1(inout i int) as $$
-begin
-  i := i+1;
-end$$ language plpgsql;
-select f1(42);
- f1 
-----
- 43
-(1 row)
-
-select * from f1(42);
- i  
-----
- 43
-(1 row)
-
-drop function f1(int);
-create function f1(in i int, out j int) returns setof int as $$
-begin
-  j := i+1;
-  return next;
-  j := i+2;
-  return next;
-  return;
-end$$ language plpgsql;
-select * from f1(42) order by 1;
- j  
-----
- 43
- 44
-(2 rows)
-
-drop function f1(int);
-create function f1(in i int, out j int, out k text) as $$
-begin
-  j := i;
-  j := j+1;
-  k := 'foo';
-end$$ language plpgsql;
-select f1(42);
-    f1    
-----------
- (43,foo)
-(1 row)
-
-select * from f1(42);
- j  |  k  
-----+-----
- 43 | foo
-(1 row)
-
-drop function f1(int);
-create function f1(in i int, out j int, out k text) returns setof record as $$
-begin
-  j := i+1;
-  k := 'foo';
-  return next;
-  j := j+1;
-  k := 'foot';
-  return next;
-end$$ language plpgsql;
-select * from f1(42) order by j, k;;
- j  |  k   
-----+------
- 43 | foo
- 44 | foot
-(2 rows)
-
-drop function f1(int);
-create function duplic(in i anyelement, out j anyelement, out k anyarray) as $$
-begin
-  j := i;
-  k := array[j,j];
-  return;
-end$$ language plpgsql;
-select * from duplic(42);
- j  |    k    
-----+---------
- 42 | {42,42}
-(1 row)
-
-select * from duplic('foo'::text);
-  j  |     k     
------+-----------
- foo | {foo,foo}
-(1 row)
-
-drop function duplic(anyelement);
---
--- test PERFORM
---
-create table perform_test (
-       a       INT,
-       b       INT
-);
-create function simple_func(int) returns boolean as '
-BEGIN
-       IF $1 < 20 THEN
-               INSERT INTO perform_test VALUES ($1, $1 + 10);
-               RETURN TRUE;
-       ELSE
-               RETURN FALSE;
-       END IF;
-END;' language plpgsql;
-create function perform_test_func() returns void as '
-BEGIN
-       IF FOUND then
-               INSERT INTO perform_test VALUES (100, 100);
-       END IF;
-
-       PERFORM simple_func(5);
-
-       IF FOUND then
-               INSERT INTO perform_test VALUES (100, 100);
-       END IF;
-
-       PERFORM simple_func(50);
-
-       IF FOUND then
-               INSERT INTO perform_test VALUES (100, 100);
-       END IF;
-
-       RETURN;
-END;' language plpgsql;
-SELECT perform_test_func();
- perform_test_func 
--------------------
-(1 row)
-
-SELECT * FROM perform_test order by a, b;
-  a  |  b  
------+-----
-   5 |  15
- 100 | 100
- 100 | 100
-(3 rows)
-
-drop table perform_test;
---
--- Test error trapping
---
-create function trap_zero_divide(int) returns int as $$
-declare x int;
-       sx smallint;
-begin
-       begin   -- start a subtransaction
-               raise notice 'should see this';
-               x := 100 / $1;
-               raise notice 'should see this only if % <> 0', $1;
-               sx := $1;
-               raise notice 'should see this only if % fits in smallint', $1;
-               if $1 < 0 then
-                       raise exception '% is less than zero', $1;
-               end if;
-       exception
-               when division_by_zero then
-                       raise notice 'caught division_by_zero';
-                       x := -1;
-               when NUMERIC_VALUE_OUT_OF_RANGE then
-                       raise notice 'caught numeric_value_out_of_range';
-                       x := -2;
-       end;
-       return x;
-end$$ language plpgsql;
-select trap_zero_divide(50);
-ERROR:  Internal subtransactions not supported in Postgres-XL
-CONTEXT:  PL/pgSQL function trap_zero_divide(integer) line 5 during statement block entry
-select trap_zero_divide(0);
-ERROR:  Internal subtransactions not supported in Postgres-XL
-CONTEXT:  PL/pgSQL function trap_zero_divide(integer) line 5 during statement block entry
-select trap_zero_divide(100000);
-ERROR:  Internal subtransactions not supported in Postgres-XL
-CONTEXT:  PL/pgSQL function trap_zero_divide(integer) line 5 during statement block entry
-select trap_zero_divide(-100);
-ERROR:  Internal subtransactions not supported in Postgres-XL
-CONTEXT:  PL/pgSQL function trap_zero_divide(integer) line 5 during statement block entry
-create function trap_matching_test(int) returns int as $$
-declare x int;
-       sx smallint;
-       y int;
-begin
-       begin   -- start a subtransaction
-               x := 100 / $1;
-               sx := $1;
-               select into y unique1 from tenk1 where unique2 =
-                       (select unique2 from tenk1 b where ten = $1);
-       exception
-               when data_exception then  -- category match
-                       raise notice 'caught data_exception';
-                       x := -1;
-               when NUMERIC_VALUE_OUT_OF_RANGE OR CARDINALITY_VIOLATION then
-                       raise notice 'caught numeric_value_out_of_range or cardinality_violation';
-                       x := -2;
-       end;
-       return x;
-end$$ language plpgsql;
--- PGXCTODO: This is failing due to issue 3522907, complicated SELECT queries in plpgsql functions
-select trap_matching_test(50);
-ERROR:  Internal subtransactions not supported in Postgres-XL
-CONTEXT:  PL/pgSQL function trap_matching_test(integer) line 6 during statement block entry
-select trap_matching_test(0);
-ERROR:  Internal subtransactions not supported in Postgres-XL
-CONTEXT:  PL/pgSQL function trap_matching_test(integer) line 6 during statement block entry
-select trap_matching_test(100000);
-ERROR:  Internal subtransactions not supported in Postgres-XL
-CONTEXT:  PL/pgSQL function trap_matching_test(integer) line 6 during statement block entry
--- PGXCTODO: This is failing due to issue 3522907, complicated SELECT queries in plpgsql functions
-select trap_matching_test(1);
-ERROR:  Internal subtransactions not supported in Postgres-XL
-CONTEXT:  PL/pgSQL function trap_matching_test(integer) line 6 during statement block entry
-create temp table foo (f1 int);
-create function subxact_rollback_semantics() returns int as $$
-declare x int;
-begin
-  x := 1;
-  insert into foo values(x);
-  begin
-    x := x + 1;
-    insert into foo values(x);
-    raise exception 'inner';
-  exception
-    when others then
-      x := x * 10;
-  end;
-  insert into foo values(x);
-  return x;
-end$$ language plpgsql;
-select subxact_rollback_semantics();
-ERROR:  Internal subtransactions not supported in Postgres-XL
-CONTEXT:  PL/pgSQL function subxact_rollback_semantics() line 6 during statement block entry
-select * from foo;
- f1 
-----
-  1
-(1 row)
-
-drop table foo;
-create function trap_timeout() returns void as $$
-begin
-  declare x int;
-  begin
-    -- we assume this will take longer than 2 seconds:
-    select count(*) into x from tenk1 a, tenk1 b, tenk1 c;
-  exception
-    when others then
-      raise notice 'caught others?';
-    when query_canceled then
-      raise notice 'nyeah nyeah, can''t stop me';
-  end;
-  -- Abort transaction to abandon the statement_timeout setting.  Otherwise,
-  -- the next top-level statement would be vulnerable to the timeout.
-  raise exception 'end of function';
-end$$ language plpgsql;
-begin;
-set statement_timeout to 2000;
-select trap_timeout();
-ERROR:  Internal subtransactions not supported in Postgres-XL
-CONTEXT:  PL/pgSQL function trap_timeout() line 4 during statement block entry
-rollback;
--- Test for pass-by-ref values being stored in proper context
-create function test_variable_storage() returns text as $$
-declare x text;
-begin
-  x := '1234';
-  begin
-    x := x || '5678';
-    -- force error inside subtransaction SPI context
-    perform trap_zero_divide(-100);
-  exception
-    when others then
-      x := x || '9012';
-  end;
-  return x;
-end$$ language plpgsql;
-select test_variable_storage();
-ERROR:  Internal subtransactions not supported in Postgres-XL
-CONTEXT:  PL/pgSQL function test_variable_storage() line 5 during statement block entry
---
--- test foreign key error trapping
---
-create temp table master(f1 int primary key);
-create temp table slave(f1 int references master deferrable);
-insert into master values(1);
-insert into slave values(1);
-insert into slave values(2);   -- fails
-ERROR:  insert or update on table "slave" violates foreign key constraint "slave_f1_fkey"
-DETAIL:  Key (f1)=(2) is not present in table "master".
-create function trap_foreign_key(int) returns int as $$
-begin
-       begin   -- start a subtransaction
-               insert into slave values($1);
-       exception
-               when foreign_key_violation then
-                       raise notice 'caught foreign_key_violation';
-                       return 0;
-       end;
-       return 1;
-end$$ language plpgsql;
-create function trap_foreign_key_2() returns int as $$
-begin
-       begin   -- start a subtransaction
-               set constraints all immediate;
-       exception
-               when foreign_key_violation then
-                       raise notice 'caught foreign_key_violation';
-                       return 0;
-       end;
-       return 1;
-end$$ language plpgsql;
-select trap_foreign_key(1);
-ERROR:  Internal subtransactions not supported in Postgres-XL
-CONTEXT:  PL/pgSQL function trap_foreign_key(integer) line 3 during statement block entry
-select trap_foreign_key(2);    -- detects FK violation
-ERROR:  Internal subtransactions not supported in Postgres-XL
-CONTEXT:  PL/pgSQL function trap_foreign_key(integer) line 3 during statement block entry
-begin;
-  set constraints all deferred;
-  select trap_foreign_key(2);  -- should not detect FK violation
-ERROR:  Internal subtransactions not supported in Postgres-XL
-CONTEXT:  PL/pgSQL function trap_foreign_key(integer) line 3 during statement block entry
-  savepoint x;
-ERROR:  current transaction is aborted, commands ignored until end of transaction block
-    set constraints all immediate; -- fails
-ERROR:  current transaction is aborted, commands ignored until end of transaction block
-  rollback to x;
-ERROR:  no such savepoint
-  select trap_foreign_key_2();  -- detects FK violation
-ERROR:  current transaction is aborted, commands ignored until end of transaction block
-commit;                                -- still fails
-drop function trap_foreign_key(int);
-drop function trap_foreign_key_2();
---
--- Test proper snapshot handling in simple expressions
---
-create temp table users(login text, id serial);
-create function sp_id_user(a_login text) returns int as $$
-declare x int;
-begin
-  select into x id from users where login = a_login;
-  if found then return x; end if;
-  return 0;
-end$$ language plpgsql stable;
-insert into users values('user1');
-select sp_id_user('user1');
- sp_id_user 
-------------
-          1
-(1 row)
-
-select sp_id_user('userx');
- sp_id_user 
-------------
-          0
-(1 row)
-
-create function sp_add_user(a_login text) returns int as $$
-declare my_id_user int;
-begin
-  my_id_user = sp_id_user( a_login );
-  IF  my_id_user > 0 THEN
-    RETURN -1;  -- error code for existing user
-  END IF;
-  INSERT INTO users ( login ) VALUES ( a_login );
-  my_id_user = sp_id_user( a_login );
-  IF  my_id_user = 0 THEN
-    RETURN -2;  -- error code for insertion failure
-  END IF;
-  RETURN my_id_user;
-end$$ language plpgsql;
-select sp_add_user('user1');
- sp_add_user 
--------------
-          -1
-(1 row)
-
-select sp_add_user('user2');
- sp_add_user 
--------------
-           2
-(1 row)
-
-select sp_add_user('user2');
- sp_add_user 
--------------
-          -1
-(1 row)
-
-select sp_add_user('user3');
- sp_add_user 
--------------
-           3
-(1 row)
-
-select sp_add_user('user3');
- sp_add_user 
--------------
-          -1
-(1 row)
-
-drop function sp_add_user(text);
-drop function sp_id_user(text);
---
--- tests for refcursors
---
-create table rc_test (a int, b int);
-copy rc_test from stdin;
-create function return_refcursor(rc refcursor) returns refcursor as $$
-begin
-    open rc for select a from rc_test;
-    return rc;
-end
-$$ language plpgsql;
-create function refcursor_test1(refcursor) returns refcursor as $$
-begin
-    perform return_refcursor($1);
-    return $1;
-end
-$$ language plpgsql;
-begin;
-select refcursor_test1('test1');
- refcursor_test1 
------------------
- test1
-(1 row)
-
-fetch next in test1;
- a 
----
- 5
-(1 row)
-
-select refcursor_test1('test2');
- refcursor_test1 
------------------
- test2
-(1 row)
-
-fetch all from test2;
-  a  
------
-   5
-  50
- 500
-(3 rows)
-
-commit;
--- should fail
-fetch next from test1;
-ERROR:  cursor "test1" does not exist
-create function refcursor_test2(int, int) returns boolean as $$
-declare
-    c1 cursor (param1 int, param2 int) for select * from rc_test where a > param1 and b > param2;
-    nonsense record;
-begin
-    open c1($1, $2);
-    fetch c1 into nonsense;
-    close c1;
-    if found then
-        return true;
-    else
-        return false;
-    end if;
-end
-$$ language plpgsql;
--- PGXCTODO: This is failing due to issue 3522907, complicated SELECT queries in plpgsql functions
-select refcursor_test2(20000, 20000) as "Should be false",
-       refcursor_test2(20, 20) as "Should be true";
- Should be false | Should be true 
------------------+----------------
- f               | t
-(1 row)
-
---
--- tests for cursors with named parameter arguments
---
-create function namedparmcursor_test1(int, int) returns boolean as $$
-declare
-    c1 cursor (param1 int, param12 int) for select * from rc_test where a > param1 and b > param12;
-    nonsense record;
-begin
-    open c1(param12 := $2, param1 := $1);
-    fetch c1 into nonsense;
-    close c1;
-    if found then
-        return true;
-    else
-        return false;
-    end if;
-end
-$$ language plpgsql;
-select namedparmcursor_test1(20000, 20000) as "Should be false",
-       namedparmcursor_test1(20, 20) as "Should be true";
- Should be false | Should be true 
------------------+----------------
- f               | t
-(1 row)
-
--- mixing named and positional argument notations
-create function namedparmcursor_test2(int, int) returns boolean as $$
-declare
-    c1 cursor (param1 int, param2 int) for select * from rc_test where a > param1 and b > param2;
-    nonsense record;
-begin
-    open c1(param1 := $1, $2);
-    fetch c1 into nonsense;
-    close c1;
-    if found then
-        return true;
-    else
-        return false;
-    end if;
-end
-$$ language plpgsql;
-select namedparmcursor_test2(20, 20);
- namedparmcursor_test2 
------------------------
- t
-(1 row)
-
--- mixing named and positional: param2 is given twice, once in named notation
--- and second time in positional notation. Should throw an error at parse time
-create function namedparmcursor_test3() returns void as $$
-declare
-    c1 cursor (param1 int, param2 int) for select * from rc_test where a > param1 and b > param2;
-begin
-    open c1(param2 := 20, 21);
-end
-$$ language plpgsql;
-ERROR:  value for parameter "param2" of cursor "c1" specified more than once
-LINE 5:     open c1(param2 := 20, 21);
-                                  ^
--- mixing named and positional: same as previous test, but param1 is duplicated
-create function namedparmcursor_test4() returns void as $$
-declare
-    c1 cursor (param1 int, param2 int) for select * from rc_test where a > param1 and b > param2;
-begin
-    open c1(20, param1 := 21);
-end
-$$ language plpgsql;
-ERROR:  value for parameter "param1" of cursor "c1" specified more than once
-LINE 5:     open c1(20, param1 := 21);
-                        ^
--- duplicate named parameter, should throw an error at parse time
-create function namedparmcursor_test5() returns void as $$
-declare
-  c1 cursor (p1 int, p2 int) for
-    select * from tenk1 where thousand = p1 and tenthous = p2;
-begin
-  open c1 (p2 := 77, p2 := 42);
-end
-$$ language plpgsql;
-ERROR:  value for parameter "p2" of cursor "c1" specified more than once
-LINE 6:   open c1 (p2 := 77, p2 := 42);
-                             ^
--- not enough parameters, should throw an error at parse time
-create function namedparmcursor_test6() returns void as $$
-declare
-  c1 cursor (p1 int, p2 int) for
-    select * from tenk1 where thousand = p1 and tenthous = p2;
-begin
-  open c1 (p2 := 77);
-end
-$$ language plpgsql;
-ERROR:  not enough arguments for cursor "c1"
-LINE 6:   open c1 (p2 := 77);
-                           ^
--- division by zero runtime error, the context given in the error message
--- should be sensible
-create function namedparmcursor_test7() returns void as $$
-declare
-  c1 cursor (p1 int, p2 int) for
-    select * from tenk1 where thousand = p1 and tenthous = p2;
-begin
-  open c1 (p2 := 77, p1 := 42/0);
-end $$ language plpgsql;
-select namedparmcursor_test7();
-ERROR:  division by zero
-CONTEXT:  SQL statement "SELECT 42/0 AS p1, 77 AS p2;"
-PL/pgSQL function namedparmcursor_test7() line 6 at OPEN
--- check that line comments work correctly within the argument list (there
--- is some special handling of this case in the code: the newline after the
--- comment must be preserved when the argument-evaluating query is
--- constructed, otherwise the comment effectively comments out the next
--- argument, too)
-create function namedparmcursor_test8() returns int4 as $$
-declare
-  c1 cursor (p1 int, p2 int) for
-    select count(*) from tenk1 where thousand = p1 and tenthous = p2;
-  n int4;
-begin
-  open c1 (77 -- test
-  , 42);
-  fetch c1 into n;
-  return n;
-end $$ language plpgsql;
-select namedparmcursor_test8();
- namedparmcursor_test8 
------------------------
-                     0
-(1 row)
-
--- cursor parameter name can match plpgsql variable or unreserved keyword
-create function namedparmcursor_test9(p1 int) returns int4 as $$
-declare
-  c1 cursor (p1 int, p2 int, debug int) for
-    select count(*) from tenk1 where thousand = p1 and tenthous = p2
-      and four = debug;
-  p2 int4 := 1006;
-  n int4;
-begin
-  open c1 (p1 := p1, p2 := p2, debug := 2);
-  fetch c1 into n;
-  return n;
-end $$ language plpgsql;
-select namedparmcursor_test9(6);
- namedparmcursor_test9 
------------------------
-                     1
-(1 row)
-
---
--- tests for "raise" processing
---
-create function raise_test1(int) returns int as $$
-begin
-    raise notice 'This message has too many parameters!', $1;
-    return $1;
-end;
-$$ language plpgsql;
-ERROR:  too many parameters specified for RAISE
-CONTEXT:  compilation of PL/pgSQL function "raise_test1" near line 3
-create function raise_test2(int) returns int as $$
-begin
-    raise notice 'This message has too few parameters: %, %, %', $1, $1;
-    return $1;
-end;
-$$ language plpgsql;
-ERROR:  too few parameters specified for RAISE
-CONTEXT:  compilation of PL/pgSQL function "raise_test2" near line 3
-create function raise_test3(int) returns int as $$
-begin
-    raise notice 'This message has no parameters (despite having %% signs in it)!';
-    return $1;
-end;
-$$ language plpgsql;
-select raise_test3(1);
-NOTICE:  This message has no parameters (despite having % signs in it)!
- raise_test3 
--------------
-           1
-(1 row)
-
--- Test re-RAISE inside a nested exception block.  This case is allowed
--- by Oracle's PL/SQL but was handled differently by PG before 9.1.
-CREATE FUNCTION reraise_test() RETURNS void AS $$
-BEGIN
-   BEGIN
-       RAISE syntax_error;
-   EXCEPTION
-       WHEN syntax_error THEN
-           BEGIN
-               raise notice 'exception % thrown in inner block, reraising', sqlerrm;
-               RAISE;
-           EXCEPTION
-               WHEN OTHERS THEN
-                   raise notice 'RIGHT - exception % caught in inner block', sqlerrm;
-           END;
-   END;
-EXCEPTION
-   WHEN OTHERS THEN
-       raise notice 'WRONG - exception % caught in outer block', sqlerrm;
-END;
-$$ LANGUAGE plpgsql;
-SELECT reraise_test();
-ERROR:  Internal subtransactions not supported in Postgres-XL
-CONTEXT:  PL/pgSQL function reraise_test() line 2 during statement block entry
---
--- reject function definitions that contain malformed SQL queries at
--- compile-time, where possible
---
-create function bad_sql1() returns int as $$
-declare a int;
-begin
-    a := 5;
-    Johnny Yuma;
-    a := 10;
-    return a;
-end$$ language plpgsql;
-ERROR:  syntax error at or near "Johnny"
-LINE 5:     Johnny Yuma;
-            ^
-create function bad_sql2() returns int as $$
-declare r record;
-begin
-    for r in select I fought the law, the law won LOOP
-        raise notice 'in loop';
-    end loop;
-    return 5;
-end;$$ language plpgsql;
-ERROR:  syntax error at or near "the"
-LINE 4:     for r in select I fought the law, the law won LOOP
-                                     ^
--- a RETURN expression is mandatory, except for void-returning
--- functions, where it is not allowed
-create function missing_return_expr() returns int as $$
-begin
-    return ;
-end;$$ language plpgsql;
-ERROR:  missing expression at or near ";"
-LINE 3:     return ;
-                   ^
-create function void_return_expr() returns void as $$
-begin
-    return 5;
-end;$$ language plpgsql;
-ERROR:  RETURN cannot have a parameter in function returning void
-LINE 3:     return 5;
-                   ^
--- VOID functions are allowed to omit RETURN
-create function void_return_expr() returns void as $$
-begin
-    perform 2+2;
-end;$$ language plpgsql;
-select void_return_expr();
- void_return_expr 
-------------------
-(1 row)
-
--- but ordinary functions are not
-create function missing_return_expr() returns int as $$
-begin
-    perform 2+2;
-end;$$ language plpgsql;
-select missing_return_expr();
-ERROR:  control reached end of function without RETURN
-CONTEXT:  PL/pgSQL function missing_return_expr()
-drop function void_return_expr();
-drop function missing_return_expr();
---
--- EXECUTE ... INTO test
---
-create table eifoo (i integer, y integer);
-create type eitype as (i integer, y integer);
-create or replace function execute_into_test(varchar) returns record as $$
-declare
-    _r record;
-    _rt eifoo%rowtype;
-    _v eitype;
-    i int;
-    j int;
-    k int;
-begin
-    execute 'insert into '||$1||' values(10,15)';
-    execute 'select (row).* from (select row(10,1)::eifoo) s' into _r;
-    raise notice '% %', _r.i, _r.y;
-    execute 'select * from '||$1||' limit 1' into _rt;
-    raise notice '% %', _rt.i, _rt.y;
-    execute 'select *, 20 from '||$1||' limit 1' into i, j, k;
-    raise notice '% % %', i, j, k;
-    execute 'select 1,2' into _v;
-    return _v;
-end; $$ language plpgsql;
-select execute_into_test('eifoo');
-NOTICE:  10 1
-NOTICE:  <NULL> <NULL>
-NOTICE:  <NULL> <NULL> <NULL>
- execute_into_test 
--------------------
- (1,2)
-(1 row)
-
-drop table eifoo cascade;
-drop type eitype cascade;
---
--- SQLSTATE and SQLERRM test
---
-create function excpt_test1() returns void as $$
-begin
-    raise notice '% %', sqlstate, sqlerrm;
-end; $$ language plpgsql;
--- should fail: SQLSTATE and SQLERRM are only in defined EXCEPTION
--- blocks
-select excpt_test1();
-ERROR:  column "sqlstate" does not exist
-LINE 1: SELECT sqlstate
-               ^
-QUERY:  SELECT sqlstate
-CONTEXT:  PL/pgSQL function excpt_test1() line 3 at RAISE
-create function excpt_test2() returns void as $$
-begin
-    begin
-        begin
-            raise notice '% %', sqlstate, sqlerrm;
-        end;
-    end;
-end; $$ language plpgsql;
--- should fail
-select excpt_test2();
-ERROR:  column "sqlstate" does not exist
-LINE 1: SELECT sqlstate
-               ^
-QUERY:  SELECT sqlstate
-CONTEXT:  PL/pgSQL function excpt_test2() line 5 at RAISE
-create function excpt_test3() returns void as $$
-begin
-    begin
-        raise exception 'user exception';
-    exception when others then
-           raise notice 'caught exception % %', sqlstate, sqlerrm;
-           begin
-               raise notice '% %', sqlstate, sqlerrm;
-               perform 10/0;
-        exception
-            when substring_error then
-                -- this exception handler shouldn't be invoked
-                raise notice 'unexpected exception: % %', sqlstate, sqlerrm;
-               when division_by_zero then
-                   raise notice 'caught exception % %', sqlstate, sqlerrm;
-           end;
-           raise notice '% %', sqlstate, sqlerrm;
-    end;
-end; $$ language plpgsql;
-select excpt_test3();
-ERROR:  Internal subtransactions not supported in Postgres-XL
-CONTEXT:  PL/pgSQL function excpt_test3() line 3 during statement block entry
-create function excpt_test4() returns text as $$
-begin
-       begin perform 1/0;
-       exception when others then return sqlerrm; end;
-end; $$ language plpgsql;
-select excpt_test4();
-ERROR:  Internal subtransactions not supported in Postgres-XL
-CONTEXT:  PL/pgSQL function excpt_test4() line 3 during statement block entry
-drop function excpt_test1();
-drop function excpt_test2();
-drop function excpt_test3();
-drop function excpt_test4();
--- parameters of raise stmt can be expressions
-create function raise_exprs() returns void as $$
-declare
-    a integer[] = '{10,20,30}';
-    c varchar = 'xyz';
-    i integer;
-begin
-    i := 2;
-    raise notice '%; %; %; %; %; %', a, a[i], c, (select c || 'abc'), row(10,'aaa',NULL,30), NULL;
-end;$$ language plpgsql;
-select raise_exprs();
-NOTICE:  {10,20,30}; 20; xyz; xyzabc; (10,aaa,,30); <NULL>
- raise_exprs 
--------------
-(1 row)
-
-drop function raise_exprs();
--- continue statement
-create table conttesttbl(idx serial, v integer);
-insert into conttesttbl(v) values(10);
-insert into conttesttbl(v) values(20);
-insert into conttesttbl(v) values(30);
-insert into conttesttbl(v) values(40);
-create function continue_test1() returns void as $$
-declare _i integer = 0; _r record;
-begin
-  raise notice '---1---';
-  loop
-    _i := _i + 1;
-    raise notice '%', _i;
-    continue when _i < 10;
-    exit;
-  end loop;
-
-  raise notice '---2---';
-  <<lbl>>
-  loop
-    _i := _i - 1;
-    loop
-      raise notice '%', _i;
-      continue lbl when _i > 0;
-      exit lbl;
-    end loop;
-  end loop;
-
-  raise notice '---3---';
-  <<the_loop>>
-  while _i < 10 loop
-    _i := _i + 1;
-    continue the_loop when _i % 2 = 0;
-    raise notice '%', _i;
-  end loop;
-
-  raise notice '---4---';
-  for _i in 1..10 loop
-    begin
-      -- applies to outer loop, not the nested begin block
-      continue when _i < 5;
-      raise notice '%', _i;
-    end;
-  end loop;
-
-  raise notice '---5---';
-  for _r in select * from conttesttbl loop
-    continue when _r.v <= 20;
-    raise notice '%', _r.v;
-  end loop;
-
-  raise notice '---6---';
-  for _r in execute 'select * from conttesttbl' loop
-    continue when _r.v <= 20;
-    raise notice '%', _r.v;
-  end loop;
-
-  raise notice '---7---';
-  for _i in 1..3 loop
-    raise notice '%', _i;
-    continue when _i = 3;
-  end loop;
-
-  raise notice '---8---';
-  _i := 1;
-  while _i <= 3 loop
-    raise notice '%', _i;
-    _i := _i + 1;
-    continue when _i = 3;
-  end loop;
-
-  raise notice '---9---';
-  for _r in select * from conttesttbl order by v limit 1 loop
-    raise notice '%', _r.v;
-    continue;
-  end loop;
-
-  raise notice '---10---';
-  for _r in execute 'select * from conttesttbl order by v limit 1' loop
-    raise notice '%', _r.v;
-    continue;
-  end loop;
-end; $$ language plpgsql;
-select continue_test1();
-NOTICE:  ---1---
-NOTICE:  1
-NOTICE:  2
-NOTICE:  3
-NOTICE:  4
-NOTICE:  5
-NOTICE:  6
-NOTICE:  7
-NOTICE:  8
-NOTICE:  9
-NOTICE:  10
-NOTICE:  ---2---
-NOTICE:  9
-NOTICE:  8
-NOTICE:  7
-NOTICE:  6
-NOTICE:  5
-NOTICE:  4
-NOTICE:  3
-NOTICE:  2
-NOTICE:  1
-NOTICE:  0
-NOTICE:  ---3---
-NOTICE:  1
-NOTICE:  3
-NOTICE:  5
-NOTICE:  7
-NOTICE:  9
-NOTICE:  ---4---
-NOTICE:  5
-NOTICE:  6
-NOTICE:  7
-NOTICE:  8
-NOTICE:  9
-NOTICE:  10
-NOTICE:  ---5---
-NOTICE:  30
-NOTICE:  40
-NOTICE:  ---6---
-NOTICE:  30
-NOTICE:  40
-NOTICE:  ---7---
-NOTICE:  1
-NOTICE:  2
-NOTICE:  3
-NOTICE:  ---8---
-NOTICE:  1
-NOTICE:  2
-NOTICE:  3
-NOTICE:  ---9---
-NOTICE:  10
-NOTICE:  ---10---
-NOTICE:  10
- continue_test1 
-----------------
-(1 row)
-
-drop function continue_test1();
-drop table conttesttbl;
--- should fail: CONTINUE is only legal inside a loop
-create function continue_error1() returns void as $$
-begin
-    begin
-        continue;
-    end;
-end;
-$$ language plpgsql;
-ERROR:  CONTINUE cannot be used outside a loop
-LINE 4:         continue;
-                ^
--- should fail: unlabeled EXIT is only legal inside a loop
-create function exit_error1() returns void as $$
-begin
-    begin
-        exit;
-    end;
-end;
-$$ language plpgsql;
-ERROR:  EXIT cannot be used outside a loop, unless it has a label
-LINE 4:         exit;
-                ^
--- should fail: no such label
-create function continue_error2() returns void as $$
-begin
-    begin
-        loop
-            continue no_such_label;
-        end loop;
-    end;
-end;
-$$ language plpgsql;
-ERROR:  there is no label "no_such_label" attached to any block or loop enclosing this statement
-LINE 5:             continue no_such_label;
-                             ^
--- should fail: no such label
-create function exit_error2() returns void as $$
-begin
-    begin
-        loop
-            exit no_such_label;
-        end loop;
-    end;
-end;
-$$ language plpgsql;
-ERROR:  there is no label "no_such_label" attached to any block or loop enclosing this statement
-LINE 5:             exit no_such_label;
-                         ^
--- should fail: CONTINUE can't reference the label of a named block
-create function continue_error3() returns void as $$
-begin
-    <<begin_block1>>
-    begin
-        loop
-            continue begin_block1;
-        end loop;
-    end;
-end;
-$$ language plpgsql;
-ERROR:  block label "begin_block1" cannot be used in CONTINUE
-LINE 6:             continue begin_block1;
-                             ^
--- On the other hand, EXIT *can* reference the label of a named block
-create function exit_block1() returns void as $$
-begin
-    <<begin_block1>>
-    begin
-        loop
-            exit begin_block1;
-            raise exception 'should not get here';
-        end loop;
-    end;
-end;
-$$ language plpgsql;
-select exit_block1();
- exit_block1 
--------------
-(1 row)
-
-drop function exit_block1();
--- verbose end block and end loop
-create function end_label1() returns void as $$
-<<blbl>>
-begin
-  <<flbl1>>
-  for _i in 1 .. 10 loop
-    exit flbl1;
-  end loop flbl1;
-  <<flbl2>>
-  for _i in 1 .. 10 loop
-    exit flbl2;
-  end loop;
-end blbl;
-$$ language plpgsql;
-select end_label1();
- end_label1 
-------------
-(1 row)
-
-drop function end_label1();
--- should fail: undefined end label
-create function end_label2() returns void as $$
-begin
-  for _i in 1 .. 10 loop
-    exit;
-  end loop flbl1;
-end;
-$$ language plpgsql;
-ERROR:  end label "flbl1" specified for unlabelled block
-LINE 5:   end loop flbl1;
-                   ^
--- should fail: end label does not match start label
-create function end_label3() returns void as $$
-<<outer_label>>
-begin
-  <<inner_label>>
-  for _i in 1 .. 10 loop
-    exit;
-  end loop outer_label;
-end;
-$$ language plpgsql;
-ERROR:  end label "outer_label" differs from block's label "inner_label"
-LINE 7:   end loop outer_label;
-                   ^
--- should fail: end label on a block without a start label
-create function end_label4() returns void as $$
-<<outer_label>>
-begin
-  for _i in 1 .. 10 loop
-    exit;
-  end loop outer_label;
-end;
-$$ language plpgsql;
-ERROR:  end label "outer_label" specified for unlabelled block
-LINE 6:   end loop outer_label;
-                   ^
--- using list of scalars in fori and fore stmts
-create function for_vect() returns void as $proc$
-<<lbl>>declare a integer; b varchar; c varchar; r record;
-begin
-  -- fori
-  for i in 1 .. 3 loop
-    raise notice '%', i;
-  end loop;
-  -- fore with record var
-  for r in select gs as aa, 'BB' as bb, 'CC' as cc from generate_series(1,4) gs loop
-    raise notice '% % %', r.aa, r.bb, r.cc;
-  end loop;
-  -- fore with single scalar
-  for a in select gs from generate_series(1,4) gs loop
-    raise notice '%', a;
-  end loop;
-  -- fore with multiple scalars
-  for a,b,c in select gs, 'BB','CC' from generate_series(1,4) gs loop
-    raise notice '% % %', a, b, c;
-  end loop;
-  -- using qualified names in fors, fore is enabled, disabled only for fori
-  for lbl.a, lbl.b, lbl.c in execute $$select gs, 'bb','cc' from generate_series(1,4) gs$$ loop
-    raise notice '% % %', a, b, c;
-  end loop;
-end;
-$proc$ language plpgsql;
-select for_vect();
-NOTICE:  1
-NOTICE:  2
-NOTICE:  3
-NOTICE:  1 BB CC
-NOTICE:  2 BB CC
-NOTICE:  3 BB CC
-NOTICE:  4 BB CC
-NOTICE:  1
-NOTICE:  2
-NOTICE:  3
-NOTICE:  4
-NOTICE:  1 BB CC
-NOTICE:  2 BB CC
-NOTICE:  3 BB CC
-NOTICE:  4 BB CC
-NOTICE:  1 bb cc
-NOTICE:  2 bb cc
-NOTICE:  3 bb cc
-NOTICE:  4 bb cc
- for_vect 
-----------
-(1 row)
-
--- regression test: verify that multiple uses of same plpgsql datum within
--- a SQL command all get mapped to the same $n parameter.  The return value
--- of the SELECT is not important, we only care that it doesn't fail with
--- a complaint about an ungrouped column reference.
-create function multi_datum_use(p1 int) returns bool as $$
-declare
-  x int;
-  y int;
-begin
-  select into x,y unique1/p1, unique1/$1 from tenk1 group by unique1/p1;
-  return x = y;
-end$$ language plpgsql;
-select multi_datum_use(42);
- multi_datum_use 
------------------
- t
-(1 row)
-
---
--- Test STRICT limiter in both planned and EXECUTE invocations.
--- Note that a data-modifying query is quasi strict (disallow multi rows)
--- by default in the planned case, but not in EXECUTE.
---
-create temp table foo (f1 int, f2 int);
-insert into foo values (1,2), (3,4);
-create or replace function footest() returns void as $$
-declare x record;
-begin
-  -- should work
-  insert into foo values(5,6) returning * into x;
-  raise notice 'x.f1 = %, x.f2 = %', x.f1, x.f2;
-end$$ language plpgsql;
-select footest();
-NOTICE:  x.f1 = 5, x.f2 = 6
- footest 
----------
-(1 row)
-
-create or replace function footest() returns void as $$
-declare x record;
-begin
-  -- should fail due to implicit strict
-  insert into foo values(7,8),(9,10) returning * into x;
-  raise notice 'x.f1 = %, x.f2 = %', x.f1, x.f2;
-end$$ language plpgsql;
-select footest();
-ERROR:  consistency check on SPI tuple count failed
-CONTEXT:  SQL statement "insert into foo values(7,8),(9,10) returning *"
-PL/pgSQL function footest() line 5 at SQL statement
-create or replace function footest() returns void as $$
-declare x record;
-begin
-  -- should work
-  execute 'insert into foo values(5,6) returning *' into x;
-  raise notice 'x.f1 = %, x.f2 = %', x.f1, x.f2;
-end$$ language plpgsql;
-select footest();
-NOTICE:  x.f1 = 5, x.f2 = 6
- footest 
----------
-(1 row)
-
-create or replace function footest() returns void as $$
-declare x record;
-begin
-  -- this should work since EXECUTE isn't as picky
-  execute 'insert into foo values(7,8),(9,10) returning *' into x;
-  raise notice 'x.f1 = %, x.f2 = %', x.f1, x.f2;
-end$$ language plpgsql;
-select footest();
-NOTICE:  x.f1 = 9, x.f2 = 10
- footest 
----------
-(1 row)
-
-select * from foo order by 1, 2;
- f1 | f2 
-----+----
-  1 |  2
-  3 |  4
-  5 |  6
-  5 |  6
-  7 |  8
-  9 | 10
-(6 rows)
-
-create or replace function footest() returns void as $$
-declare x record;
-begin
-  -- should work
-  select * from foo where f1 = 3 into strict x;
-  raise notice 'x.f1 = %, x.f2 = %', x.f1, x.f2;
-end$$ language plpgsql;
-select footest();
-NOTICE:  x.f1 = 3, x.f2 = 4
- footest 
----------
-(1 row)
-
-create or replace function footest() returns void as $$
-declare x record;
-begin
-  -- should fail, no rows
-  select * from foo where f1 = 0 into strict x;
-  raise notice 'x.f1 = %, x.f2 = %', x.f1, x.f2;
-end$$ language plpgsql;
-select footest();
-ERROR:  query returned no rows
-CONTEXT:  PL/pgSQL function footest() line 5 at SQL statement
-create or replace function footest() returns void as $$
-declare x record;
-begin
-  -- should fail, too many rows
-  select * from foo where f1 > 3 into strict x;
-  raise notice 'x.f1 = %, x.f2 = %', x.f1, x.f2;
-end$$ language plpgsql;
-select footest();
-ERROR:  query returned more than one row
-CONTEXT:  PL/pgSQL function footest() line 5 at SQL statement
-create or replace function footest() returns void as $$
-declare x record;
-begin
-  -- should work
-  execute 'select * from foo where f1 = 3' into strict x;
-  raise notice 'x.f1 = %, x.f2 = %', x.f1, x.f2;
-end$$ language plpgsql;
-select footest();
-NOTICE:  x.f1 = 3, x.f2 = 4
- footest 
----------
-(1 row)
-
-create or replace function footest() returns void as $$
-declare x record;
-begin
-  -- should fail, no rows
-  execute 'select * from foo where f1 = 0' into strict x;
-  raise notice 'x.f1 = %, x.f2 = %', x.f1, x.f2;
-end$$ language plpgsql;
-select footest();
-ERROR:  query returned no rows
-CONTEXT:  PL/pgSQL function footest() line 5 at EXECUTE
-create or replace function footest() returns void as $$
-declare x record;
-begin
-  -- should fail, too many rows
-  execute 'select * from foo where f1 > 3' into strict x;
-  raise notice 'x.f1 = %, x.f2 = %', x.f1, x.f2;
-end$$ language plpgsql;
-select footest();
-ERROR:  query returned more than one row
-CONTEXT:  PL/pgSQL function footest() line 5 at EXECUTE
-drop function footest();
--- test printing parameters after failure due to STRICT
-set plpgsql.print_strict_params to true;
-create or replace function footest() returns void as $$
-declare
-x record;
-p1 int := 2;
-p3 text := 'foo';
-begin
-  -- no rows
-  select * from foo where f1 = p1 and f1::text = p3 into strict x;
-  raise notice 'x.f1 = %, x.f2 = %', x.f1, x.f2;
-end$$ language plpgsql;
-select footest();
-ERROR:  query returned no rows
-DETAIL:  parameters: p1 = '2', p3 = 'foo'
-CONTEXT:  PL/pgSQL function footest() line 8 at SQL statement
-create or replace function footest() returns void as $$
-declare
-x record;
-p1 int := 2;
-p3 text := 'foo';
-begin
-  -- too many rows
-  select * from foo where f1 > p1 or f1::text = p3  into strict x;
-  raise notice 'x.f1 = %, x.f2 = %', x.f1, x.f2;
-end$$ language plpgsql;
-select footest();
-ERROR:  query returned more than one row
-DETAIL:  parameters: p1 = '2', p3 = 'foo'
-CONTEXT:  PL/pgSQL function footest() line 8 at SQL statement
-create or replace function footest() returns void as $$
-declare x record;
-begin
-  -- too many rows, no params
-  select * from foo where f1 > 3 into strict x;
-  raise notice 'x.f1 = %, x.f2 = %', x.f1, x.f2;
-end$$ language plpgsql;
-select footest();
-ERROR:  query returned more than one row
-CONTEXT:  PL/pgSQL function footest() line 5 at SQL statement
-create or replace function footest() returns void as $$
-declare x record;
-begin
-  -- no rows
-  execute 'select * from foo where f1 = $1 or f1::text = $2' using 0, 'foo' into strict x;
-  raise notice 'x.f1 = %, x.f2 = %', x.f1, x.f2;
-end$$ language plpgsql;
-select footest();
-ERROR:  query returned no rows
-DETAIL:  parameters: $1 = '0', $2 = 'foo'
-CONTEXT:  PL/pgSQL function footest() line 5 at EXECUTE
-create or replace function footest() returns void as $$
-declare x record;
-begin
-  -- too many rows
-  execute 'select * from foo where f1 > $1' using 1 into strict x;
-  raise notice 'x.f1 = %, x.f2 = %', x.f1, x.f2;
-end$$ language plpgsql;
-select footest();
-ERROR:  query returned more than one row
-DETAIL:  parameters: $1 = '1'
-CONTEXT:  PL/pgSQL function footest() line 5 at EXECUTE
-create or replace function footest() returns void as $$
-declare x record;
-begin
-  -- too many rows, no parameters
-  execute 'select * from foo where f1 > 3' into strict x;
-  raise notice 'x.f1 = %, x.f2 = %', x.f1, x.f2;
-end$$ language plpgsql;
-select footest();
-ERROR:  query returned more than one row
-CONTEXT:  PL/pgSQL function footest() line 5 at EXECUTE
-create or replace function footest() returns void as $$
--- override the global
-#print_strict_params off
-declare
-x record;
-p1 int := 2;
-p3 text := 'foo';
-begin
-  -- too many rows
-  select * from foo where f1 > p1 or f1::text = p3  into strict x;
-  raise notice 'x.f1 = %, x.f2 = %', x.f1, x.f2;
-end$$ language plpgsql;
-select footest();
-ERROR:  query returned more than one row
-CONTEXT:  PL/pgSQL function footest() line 10 at SQL statement
-reset plpgsql.print_strict_params;
-create or replace function footest() returns void as $$
--- override the global
-#print_strict_params on
-declare
-x record;
-p1 int := 2;
-p3 text := 'foo';
-begin
-  -- too many rows
-  select * from foo where f1 > p1 or f1::text = p3  into strict x;
-  raise notice 'x.f1 = %, x.f2 = %', x.f1, x.f2;
-end$$ language plpgsql;
-select footest();
-ERROR:  query returned more than one row
-DETAIL:  parameters: p1 = '2', p3 = 'foo'
-CONTEXT:  PL/pgSQL function footest() line 10 at SQL statement
--- test warnings and errors
-set plpgsql.extra_warnings to 'all';
-ERROR:  syntax error at or near "all"
-set plpgsql.extra_warnings to 'none';
-set plpgsql.extra_errors to 'all';
-ERROR:  syntax error at or near "all"
-set plpgsql.extra_errors to 'none';
--- test warnings when shadowing a variable
-set plpgsql.extra_warnings to 'shadowed_variables';
--- simple shadowing of input and output parameters
-create or replace function shadowtest(in1 int)
-       returns table (out1 int) as $$
-declare
-in1 int;
-out1 int;
-begin
-end
-$$ language plpgsql;
-WARNING:  variable "in1" shadows a previously defined variable
-LINE 4: in1 int;
-        ^
-WARNING:  variable "out1" shadows a previously defined variable
-LINE 5: out1 int;
-        ^
-select shadowtest(1);
- shadowtest 
-------------
-(0 rows)
-
-set plpgsql.extra_warnings to 'shadowed_variables';
-select shadowtest(1);
- shadowtest 
-------------
-(0 rows)
-
-create or replace function shadowtest(in1 int)
-       returns table (out1 int) as $$
-declare
-in1 int;
-out1 int;
-begin
-end
-$$ language plpgsql;
-WARNING:  variable "in1" shadows a previously defined variable
-LINE 4: in1 int;
-        ^
-WARNING:  variable "out1" shadows a previously defined variable
-LINE 5: out1 int;
-        ^
-select shadowtest(1);
- shadowtest 
-------------
-(0 rows)
-
-drop function shadowtest(int);
--- shadowing in a second DECLARE block
-create or replace function shadowtest()
-       returns void as $$
-declare
-f1 int;
-begin
-       declare
-       f1 int;
-       begin
-       end;
-end$$ language plpgsql;
-WARNING:  variable "f1" shadows a previously defined variable
-LINE 7:  f1 int;
-         ^
-drop function shadowtest();
--- several levels of shadowing
-create or replace function shadowtest(in1 int)
-       returns void as $$
-declare
-in1 int;
-begin
-       declare
-       in1 int;
-       begin
-       end;
-end$$ language plpgsql;
-WARNING:  variable "in1" shadows a previously defined variable
-LINE 4: in1 int;
-        ^
-WARNING:  variable "in1" shadows a previously defined variable
-LINE 7:  in1 int;
-         ^
-drop function shadowtest(int);
--- shadowing in cursor definitions
-create or replace function shadowtest()
-       returns void as $$
-declare
-f1 int;
-c1 cursor (f1 int) for select 1;
-begin
-end$$ language plpgsql;
-WARNING:  variable "f1" shadows a previously defined variable
-LINE 5: c1 cursor (f1 int) for select 1;
-                   ^
-drop function shadowtest();
--- test errors when shadowing a variable
-set plpgsql.extra_errors to 'shadowed_variables';
-create or replace function shadowtest(f1 int)
-       returns boolean as $$
-declare f1 int; begin return 1; end $$ language plpgsql;
-ERROR:  variable "f1" shadows a previously defined variable
-LINE 3: declare f1 int; begin return 1; end $$ language plpgsql;
-                ^
-select shadowtest(1);
-ERROR:  function shadowtest(integer) does not exist
-LINE 1: select shadowtest(1);
-               ^
-HINT:  No function matches the given name and argument types. You might need to add explicit type casts.
-reset plpgsql.extra_errors;
-reset plpgsql.extra_warnings;
-create or replace function shadowtest(f1 int)
-       returns boolean as $$
-declare f1 int; begin return 1; end $$ language plpgsql;
-select shadowtest(1);
- shadowtest 
-------------
- t
-(1 row)
-
--- test scrollable cursor support
-create function sc_test() returns setof integer as $$
-declare
-  c scroll cursor for select f1 from int4_tbl;
-  x integer;
-begin
-  open c;
-  fetch last from c into x;
-  while found loop
-    return next x;
-    fetch prior from c into x;
-  end loop;
-  close c;
-end;
-$$ language plpgsql;
-select * from sc_test() order by 1;
- sc_test 
----------
-(0 rows)
-
-create or replace function sc_test() returns setof integer as $$
-declare
-  c no scroll cursor for select f1 from int4_tbl;
-  x integer;
-begin
-  open c;
-  fetch last from c into x;
-  while found loop
-    return next x;
-    fetch prior from c into x;
-  end loop;
-  close c;
-end;
-$$ language plpgsql;
-select * from sc_test() order by 1;  -- fails because of NO SCROLL specification
-ERROR:  cursor can only scan forward
-HINT:  Declare it with SCROLL option to enable backward scan.
-CONTEXT:  PL/pgSQL function sc_test() line 7 at FETCH
-create or replace function sc_test() returns setof integer as $$
-declare
-  c refcursor;
-  x integer;
-begin
-  open c scroll for select f1 from int4_tbl;
-  fetch last from c into x;
-  while found loop
-    return next x;
-    fetch prior from c into x;
-  end loop;
-  close c;
-end;
-$$ language plpgsql;
-select * from sc_test() order by 1;
- sc_test 
----------
-(0 rows)
-
-create or replace function sc_test() returns setof integer as $$
-declare
-  c refcursor;
-  x integer;
-begin
-  open c scroll for execute 'select f1 from int4_tbl order by 1';
-  fetch last from c into x;
-  while found loop
-    return next x;
-    fetch relative -2 from c into x;
-  end loop;
-  close c;
-end;
-$$ language plpgsql;
-select * from sc_test();
- sc_test 
----------
-(0 rows)
-
-create or replace function sc_test() returns setof integer as $$
-declare
-  c refcursor;
-  x integer;
-begin
-  open c scroll for execute 'select f1 from int4_tbl order by 1';
-  fetch last from c into x;
-  while found loop
-    return next x;
-    move backward 2 from c;
-    fetch relative -1 from c into x;
-  end loop;
-  close c;
-end;
-$$ language plpgsql;
-select * from sc_test();
- sc_test 
----------
-(0 rows)
-
-create or replace function sc_test() returns setof integer as $$
-declare
-  c cursor for select * from generate_series(1, 10);
-  x integer;
-begin
-  open c;
-  loop
-      move relative 2 in c;
-      if not found then
-          exit;
-      end if;
-      fetch next from c into x;
-      if found then
-          return next x;
-      end if;
-  end loop;
-  close c;
-end;
-$$ language plpgsql;
-select * from sc_test() order by 1;
- sc_test 
----------
-       3
-       6
-       9
-(3 rows)
-
-create or replace function sc_test() returns setof integer as $$
-declare
-  c cursor for select * from generate_series(1, 10);
-  x integer;
-begin
-  open c;
-  move forward all in c;
-  fetch backward from c into x;
-  if found then
-    return next x;
-  end if;
-  close c;
-end;
-$$ language plpgsql;
-select * from sc_test() order by 1;
- sc_test 
----------
-      10
-(1 row)
-
-drop function sc_test();
--- test qualified variable names
-create function pl_qual_names (param1 int) returns void as $$
-<<outerblock>>
-declare
-  param1 int := 1;
-begin
-  <<innerblock>>
-  declare
-    param1 int := 2;
-  begin
-    raise notice 'param1 = %', param1;
-    raise notice 'pl_qual_names.param1 = %', pl_qual_names.param1;
-    raise notice 'outerblock.param1 = %', outerblock.param1;
-    raise notice 'innerblock.param1 = %', innerblock.param1;
-  end;
-end;
-$$ language plpgsql;
-select pl_qual_names(42);
-NOTICE:  param1 = 2
-NOTICE:  pl_qual_names.param1 = 42
-NOTICE:  outerblock.param1 = 1
-NOTICE:  innerblock.param1 = 2
- pl_qual_names 
----------------
-(1 row)
-
-drop function pl_qual_names(int);
--- tests for RETURN QUERY
-create function ret_query1(out int, out int) returns setof record as $$
-begin
-    $1 := -1;
-    $2 := -2;
-    return next;
-    return query select x + 1, x * 10 from generate_series(0, 10) s (x);
-    return next;
-end;
-$$ language plpgsql;
-select * from ret_query1() order by 1, 2;
- column1 | column2 
----------+---------
-      -1 |      -2
-      -1 |      -2
-       1 |       0
-       2 |      10
-       3 |      20
-       4 |      30
-       5 |      40
-       6 |      50
-       7 |      60
-       8 |      70
-       9 |      80
-      10 |      90
-      11 |     100
-(13 rows)
-
-create type record_type as (x text, y int, z boolean);
-create or replace function ret_query2(lim int) returns setof record_type as $$
-begin
-    return query select md5(s.x::text), s.x, s.x > 0
-                 from generate_series(-8, lim) s (x) where s.x % 2 = 0;
-end;
-$$ language plpgsql;
-select * from ret_query2(8) order by 1;
-                x                 | y  | z 
-----------------------------------+----+---
- 0267aaf632e87a63288a08331f22c7c3 | -4 | f
- 1679091c5a880faf6fb5e6087eb1b2dc |  6 | t
- 596a3d04481816330f07e4f97510c28f | -6 | f
- 5d7b9adcbe1c629ec722529dd12e5129 | -2 | f
- a87ff679a2f3e71d9181a67b7542122c |  4 | t
- a8d2ec85eaf98407310b72eb73dda247 | -8 | f
- c81e728d9d4c2f636f067f89cc14862c |  2 | t
- c9f0f895fb98ab9159f51fd0297e236d |  8 | t
- cfcd208495d565ef66e7dff9f98764da |  0 | f
-(9 rows)
-
--- test EXECUTE USING
-create function exc_using(int, text) returns int as $$
-declare i int;
-begin
-  for i in execute 'select * from generate_series(1,$1)' using $1+1 loop
-    raise notice '%', i;
-  end loop;
-  execute 'select $2 + $2*3 + length($1)' into i using $2,$1;
-  return i;
-end
-$$ language plpgsql;
-select exc_using(5, 'foobar');
-NOTICE:  1
-NOTICE:  2
-NOTICE:  3
-NOTICE:  4
-NOTICE:  5
-NOTICE:  6
- exc_using 
------------
-        26
-(1 row)
-
-drop function exc_using(int, text);
-create or replace function exc_using(int) returns void as $$
-declare
-  c refcursor;
-  i int;
-begin
-  open c for execute 'select * from generate_series(1,$1)' using $1+1;
-  loop
-    fetch c into i;
-    exit when not found;
-    raise notice '%', i;
-  end loop;
-  close c;
-  return;
-end;
-$$ language plpgsql;
-select exc_using(5);
-NOTICE:  1
-NOTICE:  2
-NOTICE:  3
-NOTICE:  4
-NOTICE:  5
-NOTICE:  6
- exc_using 
------------
-(1 row)
-
-drop function exc_using(int);
--- test FOR-over-cursor
-create or replace function forc01() returns void as $$
-declare
-  c cursor(r1 integer, r2 integer)
-       for select * from generate_series(r1,r2) i;
-  c2 cursor
-       for select * from generate_series(41,43) i;
-begin
-  for r in c(5,7) loop
-    raise notice '% from %', r.i, c;
-  end loop;
-  -- again, to test if cursor was closed properly
-  for r in c(9,10) loop
-    raise notice '% from %', r.i, c;
-  end loop;
-  -- and test a parameterless cursor
-  for r in c2 loop
-    raise notice '% from %', r.i, c2;
-  end loop;
-  -- and try it with a hand-assigned name
-  raise notice 'after loop, c2 = %', c2;
-  c2 := 'special_name';
-  for r in c2 loop
-    raise notice '% from %', r.i, c2;
-  end loop;
-  raise notice 'after loop, c2 = %', c2;
-  -- and try it with a generated name
-  -- (which we can't show in the output because it's variable)
-  c2 := null;
-  for r in c2 loop
-    raise notice '%', r.i;
-  end loop;
-  raise notice 'after loop, c2 = %', c2;
-  return;
-end;
-$$ language plpgsql;
-select forc01();
-NOTICE:  5 from c
-NOTICE:  6 from c
-NOTICE:  7 from c
-NOTICE:  9 from c
-NOTICE:  10 from c
-NOTICE:  41 from c2
-NOTICE:  42 from c2
-NOTICE:  43 from c2
-NOTICE:  after loop, c2 = c2
-NOTICE:  41 from special_name
-NOTICE:  42 from special_name
-NOTICE:  43 from special_name
-NOTICE:  after loop, c2 = special_name
-NOTICE:  41
-NOTICE:  42
-NOTICE:  43
-NOTICE:  after loop, c2 = <NULL>
- forc01 
---------
-(1 row)
-
--- try updating the cursor's current row
-create temp table forc_test as
-  select n as i, n as j from generate_series(1,10) n;
-create or replace function forc01() returns void as $$
-declare
-  c cursor for select * from forc_test;
-begin
-  for r in c loop
-    raise notice '%, %', r.i, r.j;
-    update forc_test set i = i * 100, j = r.j * 2 where current of c;
-  end loop;
-end;
-$$ language plpgsql;
-select forc01();
-NOTICE:  1, 1
-ERROR:  WHERE CURRENT OF clause not yet supported
-CONTEXT:  SQL statement "update forc_test set i = i * 100, j = r.j * 2 where current of c"
-PL/pgSQL function forc01() line 7 at SQL statement
-select * from forc_test order by 1, 2;
- i  | j  
-----+----
-  1 |  1
-  2 |  2
-  3 |  3
-  4 |  4
-  5 |  5
-  6 |  6
-  7 |  7
-  8 |  8
-  9 |  9
- 10 | 10
-(10 rows)
-
--- same, with a cursor whose portal name doesn't match variable name
-create or replace function forc01() returns void as $$
-declare
-  c refcursor := 'fooled_ya';
-  r record;
-begin
-  open c for select * from forc_test;
-  loop
-    fetch c into r;
-    exit when not found;
-    raise notice '%, %', r.i, r.j;
-    update forc_test set i = i * 100, j = r.j * 2 where current of c;
-  end loop;
-end;
-$$ language plpgsql;
-select forc01();
-NOTICE:  1, 1
-ERROR:  WHERE CURRENT OF clause not yet supported
-CONTEXT:  SQL statement "update forc_test set i = i * 100, j = r.j * 2 where current of c"
-PL/pgSQL function forc01() line 11 at SQL statement
-select * from forc_test order by 1;
- i  | j  
-----+----
-  1 |  1
-  2 |  2
-  3 |  3
-  4 |  4
-  5 |  5
-  6 |  6
-  7 |  7
-  8 |  8
-  9 |  9
- 10 | 10
-(10 rows)
-
-drop function forc01();
--- fail because cursor has no query bound to it
-create or replace function forc_bad() returns void as $$
-declare
-  c refcursor;
-begin
-  for r in c loop
-    raise notice '%', r.i;
-  end loop;
-end;
-$$ language plpgsql;
-ERROR:  cursor FOR loop must use a bound cursor variable
-LINE 5:   for r in c loop
-                   ^
--- test RETURN QUERY EXECUTE
-create or replace function return_dquery()
-returns setof int as $$
-begin
-  return query execute 'select * from (values(10),(20)) f';
-  return query execute 'select * from (values($1),($2)) f' using 40,50;
-end;
-$$ language plpgsql;
-select * from return_dquery() order by 1;
- return_dquery 
----------------
-            10
-            20
-            40
-            50
-(4 rows)
-
-drop function return_dquery();
--- test RETURN QUERY with dropped columns
-create table tabwithcols(a int, b int, c int, d int);
-insert into tabwithcols values(10,20,30,40),(50,60,70,80);
-create or replace function returnqueryf()
-returns setof tabwithcols as $$
-begin
-  return query select * from tabwithcols;
-  return query execute 'select * from tabwithcols';
-end;
-$$ language plpgsql;
-select * from returnqueryf() order by 1,2,3,4;
- a  | b  | c  | d  
-----+----+----+----
- 10 | 20 | 30 | 40
- 10 | 20 | 30 | 40
- 50 | 60 | 70 | 80
- 50 | 60 | 70 | 80
-(4 rows)
-
-alter table tabwithcols drop column b;
-select * from returnqueryf() order by 1,2,3;
- a  | c  | d  
-----+----+----
- 10 | 30 | 40
- 10 | 30 | 40
- 50 | 70 | 80
- 50 | 70 | 80
-(4 rows)
-
-alter table tabwithcols drop column d;
-select * from returnqueryf() order by 1,2;
- a  | c  
-----+----
- 10 | 30
- 10 | 30
- 50 | 70
- 50 | 70
-(4 rows)
-
-alter table tabwithcols add column d int;
-select * from returnqueryf() order by 1,2,3;
- a  | c  | d 
-----+----+---
- 10 | 30 |  
- 10 | 30 |  
- 50 | 70 |  
- 50 | 70 |  
-(4 rows)
-
-drop function returnqueryf();
-drop table tabwithcols;
---
--- Tests for composite-type results
---
-create type compostype as (x int, y varchar);
--- test: use of variable of composite type in return statement
-create or replace function compos() returns compostype as $$
-declare
-  v compostype;
-begin
-  v := (1, 'hello');
-  return v;
-end;
-$$ language plpgsql;
-select compos();
-  compos   
------------
- (1,hello)
-(1 row)
-
--- test: use of variable of record type in return statement
-create or replace function compos() returns compostype as $$
-declare
-  v record;
-begin
-  v := (1, 'hello'::varchar);
-  return v;
-end;
-$$ language plpgsql;
-select compos();
-  compos   
------------
- (1,hello)
-(1 row)
-
--- test: use of row expr in return statement
-create or replace function compos() returns compostype as $$
-begin
-  return (1, 'hello'::varchar);
-end;
-$$ language plpgsql;
-select compos();
-  compos   
------------
- (1,hello)
-(1 row)
-
--- this does not work currently (no implicit casting)
-create or replace function compos() returns compostype as $$
-begin
-  return (1, 'hello');
-end;
-$$ language plpgsql;
-select compos();
-ERROR:  returned record type does not match expected record type
-DETAIL:  Returned type unknown does not match expected type character varying in column 2.
-CONTEXT:  PL/pgSQL function compos() while casting return value to function's return type
--- ... but this does
-create or replace function compos() returns compostype as $$
-begin
-  return (1, 'hello')::compostype;
-end;
-$$ language plpgsql;
-select compos();
-  compos   
------------
- (1,hello)
-(1 row)
-
-drop function compos();
--- test: return a row expr as record.
-create or replace function composrec() returns record as $$
-declare
-  v record;
-begin
-  v := (1, 'hello');
-  return v;
-end;
-$$ language plpgsql;
-select composrec();
- composrec 
------------
- (1,hello)
-(1 row)
-
--- test: return row expr in return statement.
-create or replace function composrec() returns record as $$
-begin
-  return (1, 'hello');
-end;
-$$ language plpgsql;
-select composrec();
- composrec 
------------
- (1,hello)
-(1 row)
-
-drop function composrec();
--- test: row expr in RETURN NEXT statement.
-create or replace function compos() returns setof compostype as $$
-begin
-  for i in 1..3
-  loop
-    return next (1, 'hello'::varchar);
-  end loop;
-  return next null::compostype;
-  return next (2, 'goodbye')::compostype;
-end;
-$$ language plpgsql;
-select * from compos();
- x |    y    
----+---------
- 1 | hello
- 1 | hello
- 1 | hello
-   | 
- 2 | goodbye
-(5 rows)
-
-drop function compos();
--- test: use invalid expr in return statement.
-create or replace function compos() returns compostype as $$
-begin
-  return 1 + 1;
-end;
-$$ language plpgsql;
-select compos();
-ERROR:  cannot return non-composite value from function returning composite type
-CONTEXT:  PL/pgSQL function compos() line 3 at RETURN
--- RETURN variable is a different code path ...
-create or replace function compos() returns compostype as $$
-declare x int := 42;
-begin
-  return x;
-end;
-$$ language plpgsql;
-select * from compos();
-ERROR:  cannot return non-composite value from function returning composite type
-CONTEXT:  PL/pgSQL function compos() line 4 at RETURN
-drop function compos();
--- test: invalid use of composite variable in scalar-returning function
-create or replace function compos() returns int as $$
-declare
-  v compostype;
-begin
-  v := (1, 'hello');
-  return v;
-end;
-$$ language plpgsql;
-select compos();
-ERROR:  invalid input syntax for integer: "(1,hello)"
-CONTEXT:  PL/pgSQL function compos() while casting return value to function's return type
--- test: invalid use of composite expression in scalar-returning function
-create or replace function compos() returns int as $$
-begin
-  return (1, 'hello')::compostype;
-end;
-$$ language plpgsql;
-select compos();
-ERROR:  invalid input syntax for integer: "(1,hello)"
-CONTEXT:  PL/pgSQL function compos() while casting return value to function's return type
-drop function compos();
-drop type compostype;
---
--- Tests for 8.4's new RAISE features
---
-create or replace function raise_test() returns void as $$
-begin
-  raise notice '% % %', 1, 2, 3
-     using errcode = '55001', detail = 'some detail info', hint = 'some hint';
-  raise '% % %', 1, 2, 3
-     using errcode = 'division_by_zero', detail = 'some detail info';
-end;
-$$ language plpgsql;
-select raise_test();
-NOTICE:  1 2 3
-DETAIL:  some detail info
-HINT:  some hint
-ERROR:  1 2 3
-DETAIL:  some detail info
-CONTEXT:  PL/pgSQL function raise_test() line 5 at RAISE
--- Since we can't actually see the thrown SQLSTATE in default psql output,
--- test it like this; this also tests re-RAISE
-create or replace function raise_test() returns void as $$
-begin
-  raise 'check me'
-     using errcode = 'division_by_zero', detail = 'some detail info';
-  exception
-    when others then
-      raise notice 'SQLSTATE: % SQLERRM: %', sqlstate, sqlerrm;
-      raise;
-end;
-$$ language plpgsql;
-select raise_test();
-ERROR:  Internal subtransactions not supported in Postgres-XL
-CONTEXT:  PL/pgSQL function raise_test() line 2 during statement block entry
-create or replace function raise_test() returns void as $$
-begin
-  raise 'check me'
-     using errcode = '1234F', detail = 'some detail info';
-  exception
-    when others then
-      raise notice 'SQLSTATE: % SQLERRM: %', sqlstate, sqlerrm;
-      raise;
-end;
-$$ language plpgsql;
-select raise_test();
-ERROR:  Internal subtransactions not supported in Postgres-XL
-CONTEXT:  PL/pgSQL function raise_test() line 2 during statement block entry
--- SQLSTATE specification in WHEN
-create or replace function raise_test() returns void as $$
-begin
-  raise 'check me'
-     using errcode = '1234F', detail = 'some detail info';
-  exception
-    when sqlstate '1234F' then
-      raise notice 'SQLSTATE: % SQLERRM: %', sqlstate, sqlerrm;
-      raise;
-end;
-$$ language plpgsql;
-select raise_test();
-ERROR:  Internal subtransactions not supported in Postgres-XL
-CONTEXT:  PL/pgSQL function raise_test() line 2 during statement block entry
-create or replace function raise_test() returns void as $$
-begin
-  raise division_by_zero using detail = 'some detail info';
-  exception
-    when others then
-      raise notice 'SQLSTATE: % SQLERRM: %', sqlstate, sqlerrm;
-      raise;
-end;
-$$ language plpgsql;
-select raise_test();
-ERROR:  Internal subtransactions not supported in Postgres-XL
-CONTEXT:  PL/pgSQL function raise_test() line 2 during statement block entry
-create or replace function raise_test() returns void as $$
-begin
-  raise division_by_zero;
-end;
-$$ language plpgsql;
-select raise_test();
-ERROR:  division_by_zero
-CONTEXT:  PL/pgSQL function raise_test() line 3 at RAISE
-create or replace function raise_test() returns void as $$
-begin
-  raise sqlstate '1234F';
-end;
-$$ language plpgsql;
-select raise_test();
-ERROR:  1234F
-CONTEXT:  PL/pgSQL function raise_test() line 3 at RAISE
-create or replace function raise_test() returns void as $$
-begin
-  raise division_by_zero using message = 'custom' || ' message';
-end;
-$$ language plpgsql;
-select raise_test();
-ERROR:  custom message
-CONTEXT:  PL/pgSQL function raise_test() line 3 at RAISE
-create or replace function raise_test() returns void as $$
-begin
-  raise using message = 'custom' || ' message', errcode = '22012';
-end;
-$$ language plpgsql;
-select raise_test();
-ERROR:  custom message
-CONTEXT:  PL/pgSQL function raise_test() line 3 at RAISE
--- conflict on message
-create or replace function raise_test() returns void as $$
-begin
-  raise notice 'some message' using message = 'custom' || ' message', errcode = '22012';
-end;
-$$ language plpgsql;
-select raise_test();
-ERROR:  RAISE option already specified: MESSAGE
-CONTEXT:  PL/pgSQL function raise_test() line 3 at RAISE
--- conflict on errcode
-create or replace function raise_test() returns void as $$
-begin
-  raise division_by_zero using message = 'custom' || ' message', errcode = '22012';
-end;
-$$ language plpgsql;
-select raise_test();
-ERROR:  RAISE option already specified: ERRCODE
-CONTEXT:  PL/pgSQL function raise_test() line 3 at RAISE
--- nothing to re-RAISE
-create or replace function raise_test() returns void as $$
-begin
-  raise;
-end;
-$$ language plpgsql;
-select raise_test();
-ERROR:  RAISE without parameters cannot be used outside an exception handler
-CONTEXT:  PL/pgSQL function raise_test() line 3 at RAISE
--- test access to exception data
-create function zero_divide() returns int as $$
-declare v int := 0;
-begin
-  return 10 / v;
-end;
-$$ language plpgsql;
-create or replace function raise_test() returns void as $$
-begin
-  raise exception 'custom exception'
-     using detail = 'some detail of custom exception',
-           hint = 'some hint related to custom exception';
-end;
-$$ language plpgsql;
-create function stacked_diagnostics_test() returns void as $$
-declare _sqlstate text;
-        _message text;
-        _context text;
-begin
-  perform zero_divide();
-exception when others then
-  get stacked diagnostics
-        _sqlstate = returned_sqlstate,
-        _message = message_text,
-        _context = pg_exception_context;
-  raise notice 'sqlstate: %, message: %, context: [%]',
-    _sqlstate, _message, replace(_context, E'\n', ' <- ');
-end;
-$$ language plpgsql;
-select stacked_diagnostics_test();
-ERROR:  Internal subtransactions not supported in Postgres-XL
-CONTEXT:  PL/pgSQL function stacked_diagnostics_test() line 5 during statement block entry
-create or replace function stacked_diagnostics_test() returns void as $$
-declare _detail text;
-        _hint text;
-        _message text;
-begin
-  perform raise_test();
-exception when others then
-  get stacked diagnostics
-        _message = message_text,
-        _detail = pg_exception_detail,
-        _hint = pg_exception_hint;
-  raise notice 'message: %, detail: %, hint: %', _message, _detail, _hint;
-end;
-$$ language plpgsql;
-select stacked_diagnostics_test();
-ERROR:  Internal subtransactions not supported in Postgres-XL
-CONTEXT:  PL/pgSQL function stacked_diagnostics_test() line 5 during statement block entry
--- fail, cannot use stacked diagnostics statement outside handler
-create or replace function stacked_diagnostics_test() returns void as $$
-declare _detail text;
-        _hint text;
-        _message text;
-begin
-  get stacked diagnostics
-        _message = message_text,
-        _detail = pg_exception_detail,
-        _hint = pg_exception_hint;
-  raise notice 'message: %, detail: %, hint: %', _message, _detail, _hint;
-end;
-$$ language plpgsql;
-select stacked_diagnostics_test();
-ERROR:  GET STACKED DIAGNOSTICS cannot be used outside an exception handler
-CONTEXT:  PL/pgSQL function stacked_diagnostics_test() line 6 at GET STACKED DIAGNOSTICS
-drop function zero_divide();
-drop function stacked_diagnostics_test();
--- check cases where implicit SQLSTATE variable could be confused with
--- SQLSTATE as a keyword, cf bug #5524
-create or replace function raise_test() returns void as $$
-begin
-  perform 1/0;
-exception
-  when sqlstate '22012' then
-    raise notice using message = sqlstate;
-    raise sqlstate '22012' using message = 'substitute message';
-end;
-$$ language plpgsql;
-select raise_test();
-ERROR:  Internal subtransactions not supported in Postgres-XL
-CONTEXT:  PL/pgSQL function raise_test() line 2 during statement block entry
-drop function raise_test();
--- test passing column_name, constraint_name, datatype_name, table_name
--- and schema_name error fields
-create or replace function stacked_diagnostics_test() returns void as $$
-declare _column_name text;
-        _constraint_name text;
-        _datatype_name text;
-        _table_name text;
-        _schema_name text;
-begin
-  raise exception using
-    column = '>>some column name<<',
-    constraint = '>>some constraint name<<',
-    datatype = '>>some datatype name<<',
-    table = '>>some table name<<',
-    schema = '>>some schema name<<';
-exception when others then
-  get stacked diagnostics
-        _column_name = column_name,
-        _constraint_name = constraint_name,
-        _datatype_name = pg_datatype_name,
-        _table_name = table_name,
-        _schema_name = schema_name;
-  raise notice 'column %, constraint %, type %, table %, schema %',
-    _column_name, _constraint_name, _datatype_name, _table_name, _schema_name;
-end;
-$$ language plpgsql;
-select stacked_diagnostics_test();
-ERROR:  Internal subtransactions not supported in Postgres-XL
-CONTEXT:  PL/pgSQL function stacked_diagnostics_test() line 7 during statement block entry
-drop function stacked_diagnostics_test();
--- test CASE statement
-create or replace function case_test(bigint) returns text as $$
-declare a int = 10;
-        b int = 1;
-begin
-  case $1
-    when 1 then
-      return 'one';
-    when 2 then
-      return 'two';
-    when 3,4,3+5 then
-      return 'three, four or eight';
-    when a then
-      return 'ten';
-    when a+b, a+b+1 then
-      return 'eleven, twelve';
-  end case;
-end;
-$$ language plpgsql immutable;
-select case_test(1);
- case_test 
------------
- one
-(1 row)
-
-select case_test(2);
- case_test 
------------
- two
-(1 row)
-
-select case_test(3);
-      case_test       
-----------------------
- three, four or eight
-(1 row)
-
-select case_test(4);
-      case_test       
-----------------------
- three, four or eight
-(1 row)
-
-select case_test(5); -- fails
-ERROR:  case not found
-HINT:  CASE statement is missing ELSE part.
-CONTEXT:  PL/pgSQL function case_test(bigint) line 5 at CASE
-select case_test(8);
-      case_test       
-----------------------
- three, four or eight
-(1 row)
-
-select case_test(10);
- case_test 
------------
- ten
-(1 row)
-
-select case_test(11);
-   case_test    
-----------------
- eleven, twelve
-(1 row)
-
-select case_test(12);
-   case_test    
-----------------
- eleven, twelve
-(1 row)
-
-select case_test(13); -- fails
-ERROR:  case not found
-HINT:  CASE statement is missing ELSE part.
-CONTEXT:  PL/pgSQL function case_test(bigint) line 5 at CASE
-create or replace function catch() returns void as $$
-begin
-  raise notice '%', case_test(6);
-exception
-  when case_not_found then
-    raise notice 'caught case_not_found % %', SQLSTATE, SQLERRM;
-end
-$$ language plpgsql;
-select catch();
-ERROR:  Internal subtransactions not supported in Postgres-XL
-CONTEXT:  PL/pgSQL function catch() line 2 during statement block entry
--- test the searched variant too, as well as ELSE
-create or replace function case_test(bigint) returns text as $$
-declare a int = 10;
-begin
-  case
-    when $1 = 1 then
-      return 'one';
-    when $1 = a + 2 then
-      return 'twelve';
-    else
-      return 'other';
-  end case;
-end;
-$$ language plpgsql immutable;
-select case_test(1);
- case_test 
------------
- one
-(1 row)
-
-select case_test(2);
- case_test 
------------
- other
-(1 row)
-
-select case_test(12);
- case_test 
------------
- twelve
-(1 row)
-
-select case_test(13);
- case_test 
------------
- other
-(1 row)
-
-drop function catch();
-drop function case_test(bigint);
--- test variadic functions
-create or replace function vari(variadic int[])
-returns void as $$
-begin
-  for i in array_lower($1,1)..array_upper($1,1) loop
-    raise notice '%', $1[i];
-  end loop; end;
-$$ language plpgsql;
-select vari(1,2,3,4,5);
-NOTICE:  1
-NOTICE:  2
-NOTICE:  3
-NOTICE:  4
-NOTICE:  5
- vari 
-------
-(1 row)
-
-select vari(3,4,5);
-NOTICE:  3
-NOTICE:  4
-NOTICE:  5
- vari 
-------
-(1 row)
-
-select vari(variadic array[5,6,7]);
-NOTICE:  5
-NOTICE:  6
-NOTICE:  7
- vari 
-------
-(1 row)
-
-drop function vari(int[]);
--- coercion test
-create or replace function pleast(variadic numeric[])
-returns numeric as $$
-declare aux numeric = $1[array_lower($1,1)];
-begin
-  for i in array_lower($1,1)+1..array_upper($1,1) loop
-    if $1[i] < aux then aux := $1[i]; end if;
-  end loop;
-  return aux;
-end;
-$$ language plpgsql immutable strict;
-select pleast(10,1,2,3,-16);
- pleast 
---------
-    -16
-(1 row)
-
-select pleast(10.2,2.2,-1.1);
- pleast 
---------
-   -1.1
-(1 row)
-
-select pleast(10.2,10, -20);
- pleast 
---------
-    -20
-(1 row)
-
-select pleast(10,20, -1.0);
- pleast 
---------
-   -1.0
-(1 row)
-
--- in case of conflict, non-variadic version is preferred
-create or replace function pleast(numeric)
-returns numeric as $$
-begin
-  raise notice 'non-variadic function called';
-  return $1;
-end;
-$$ language plpgsql immutable strict;
-select pleast(10);
-NOTICE:  non-variadic function called
- pleast 
---------
-     10
-(1 row)
-
-drop function pleast(numeric[]);
-drop function pleast(numeric);
--- test table functions
-create function tftest(int) returns table(a int, b int) as $$
-begin
-  return query select $1, $1+i from generate_series(1,5) g(i);
-end;
-$$ language plpgsql immutable strict;
-select * from tftest(10) order by 1, 2;
- a  | b  
-----+----
- 10 | 11
- 10 | 12
- 10 | 13
- 10 | 14
- 10 | 15
-(5 rows)
-
-create or replace function tftest(a1 int) returns table(a int, b int) as $$
-begin
-  a := a1; b := a1 + 1;
-  return next;
-  a := a1 * 10; b := a1 * 10 + 1;
-  return next;
-end;
-$$ language plpgsql immutable strict;
-select * from tftest(10) order by 1, 2;
-  a  |  b  
------+-----
-  10 |  11
- 100 | 101
-(2 rows)
-
-drop function tftest(int);
-create or replace function rttest()
-returns setof int as $$
-declare rc int;
-begin
-  return query values(10),(20);
-  get diagnostics rc = row_count;
-  raise notice '% %', found, rc;
-  return query select * from (values(10),(20)) f(a) where false;
-  get diagnostics rc = row_count;
-  raise notice '% %', found, rc;
-  return query execute 'values(10),(20)';
-  get diagnostics rc = row_count;
-  raise notice '% %', found, rc;
-  return query execute 'select * from (values(10),(20)) f(a) where false';
-  get diagnostics rc = row_count;
-  raise notice '% %', found, rc;
-end;
-$$ language plpgsql;
-select * from rttest() order by 1;
-NOTICE:  t 2
-NOTICE:  f 0
-NOTICE:  t 2
-NOTICE:  f 0
- rttest 
---------
-     10
-     10
-     20
-     20
-(4 rows)
-
-drop function rttest();
--- Test for proper cleanup at subtransaction exit.  This example
--- exposed a bug in PG 8.2.
-CREATE FUNCTION leaker_1(fail BOOL) RETURNS INTEGER AS $$
-DECLARE
-  v_var INTEGER;
-BEGIN
-  BEGIN
-    v_var := (leaker_2(fail)).error_code;
-  EXCEPTION
-    WHEN others THEN RETURN 0;
-  END;
-  RETURN 1;
-END;
-$$ LANGUAGE plpgsql;
-CREATE FUNCTION leaker_2(fail BOOL, OUT error_code INTEGER, OUT new_id INTEGER)
-  RETURNS RECORD AS $$
-BEGIN
-  IF fail THEN
-    RAISE EXCEPTION 'fail ...';
-  END IF;
-  error_code := 1;
-  new_id := 1;
-  RETURN;
-END;
-$$ LANGUAGE plpgsql;
-SELECT * FROM leaker_1(false);
-ERROR:  Internal subtransactions not supported in Postgres-XL
-CONTEXT:  PL/pgSQL function leaker_1(boolean) line 5 during statement block entry
-SELECT * FROM leaker_1(true);
-ERROR:  Internal subtransactions not supported in Postgres-XL
-CONTEXT:  PL/pgSQL function leaker_1(boolean) line 5 during statement block entry
-DROP FUNCTION leaker_1(bool);
-DROP FUNCTION leaker_2(bool);
--- Test for appropriate cleanup of non-simple expression evaluations
--- (bug in all versions prior to August 2010)
-CREATE FUNCTION nonsimple_expr_test() RETURNS text[] AS $$
-DECLARE
-  arr text[];
-  lr text;
-  i integer;
-BEGIN
-  arr := array[array['foo','bar'], array['baz', 'quux']];
-  lr := 'fool';
-  i := 1;
-  -- use sub-SELECTs to make expressions non-simple
-  arr[(SELECT i)][(SELECT i+1)] := (SELECT lr);
-  RETURN arr;
-END;
-$$ LANGUAGE plpgsql;
-SELECT nonsimple_expr_test();
-   nonsimple_expr_test   
--------------------------
- {{foo,fool},{baz,quux}}
-(1 row)
-
-DROP FUNCTION nonsimple_expr_test();
-CREATE FUNCTION nonsimple_expr_test() RETURNS integer AS $$
-declare
-   i integer NOT NULL := 0;
-begin
-  begin
-    i := (SELECT NULL::integer);  -- should throw error
-  exception
-    WHEN OTHERS THEN
-      i := (SELECT 1::integer);
-  end;
-  return i;
-end;
-$$ LANGUAGE plpgsql;
-SELECT nonsimple_expr_test();
-ERROR:  Internal subtransactions not supported in Postgres-XL
-CONTEXT:  PL/pgSQL function nonsimple_expr_test() line 5 during statement block entry
-DROP FUNCTION nonsimple_expr_test();
---
--- Test cases involving recursion and error recovery in simple expressions
--- (bugs in all versions before October 2010).  The problems are most
--- easily exposed by mutual recursion between plpgsql and sql functions.
---
-create function recurse(float8) returns float8 as
-$$
-begin
-  if ($1 > 0) then
-    return sql_recurse($1 - 1);
-  else
-    return $1;
-  end if;
-end;
-$$ language plpgsql;
--- "limit" is to prevent this from being inlined
-create function sql_recurse(float8) returns float8 as
-$$ select recurse($1) limit 1; $$ language sql;
-select recurse(10);
- recurse 
----------
-       0
-(1 row)
-
-create function error1(text) returns text language sql as
-$$ SELECT relname::text FROM pg_class c WHERE c.oid = $1::regclass $$;
-create function error2(p_name_table text) returns text language plpgsql as $$
-begin
-  return error1(p_name_table);
-end$$;
-BEGIN;
-create table public.stuffs (stuff text);
-SAVEPOINT a;
-ERROR:  SAVEPOINT is not yet supported.
-select error2('nonexistent.stuffs');
-ERROR:  current transaction is aborted, commands ignored until end of transaction block
-ROLLBACK TO a;
-ERROR:  no such savepoint
-select error2('public.stuffs');
-ERROR:  current transaction is aborted, commands ignored until end of transaction block
-rollback;
-drop function error2(p_name_table text);
-drop function error1(text);
--- Test for proper handling of cast-expression caching
-create function sql_to_date(integer) returns date as $$
-select $1::text::date
-$$ language sql immutable strict;
-create cast (integer as date) with function sql_to_date(integer) as assignment;
-create function cast_invoker(integer) returns date as $$
-begin
-  return $1;
-end$$ language plpgsql;
-select cast_invoker(20150717);
- cast_invoker 
---------------
- 07-17-2015
-(1 row)
-
-select cast_invoker(20150718);  -- second call crashed in pre-release 9.5
- cast_invoker 
---------------
- 07-18-2015
-(1 row)
-
-begin;
-select cast_invoker(20150717);
- cast_invoker 
---------------
- 07-17-2015
-(1 row)
-
-select cast_invoker(20150718);
- cast_invoker 
---------------
- 07-18-2015
-(1 row)
-
-savepoint s1;
-select cast_invoker(20150718);
- cast_invoker 
---------------
- 07-18-2015
-(1 row)
-
-select cast_invoker(-1); -- fails
-ERROR:  invalid input syntax for type date: "-1"
-CONTEXT:  SQL function "sql_to_date" statement 1
-PL/pgSQL function cast_invoker(integer) while casting return value to function's return type
-rollback to savepoint s1;
-select cast_invoker(20150719);
- cast_invoker 
---------------
- 07-19-2015
-(1 row)
-
-select cast_invoker(20150720);
- cast_invoker 
---------------
- 07-20-2015
-(1 row)
-
-commit;
-drop function cast_invoker(integer);
-drop function sql_to_date(integer) cascade;
-NOTICE:  drop cascades to cast from integer to date
--- Test handling of cast cache inside DO blocks
--- (to check the original crash case, this must be a cast not previously
--- used in this session)
-begin;
-do $$ declare x text[]; begin x := '{1.23, 4.56}'::numeric[]; end $$;
-do $$ declare x text[]; begin x := '{1.23, 4.56}'::numeric[]; end $$;
-end;
--- Test for consistent reporting of error context
-create function fail() returns int language plpgsql as $$
-begin
-  return 1/0;
-end
-$$;
-select fail();
-ERROR:  division by zero
-CONTEXT:  SQL statement "SELECT 1/0"
-PL/pgSQL function fail() line 3 at RETURN
-select fail();
-ERROR:  division by zero
-CONTEXT:  SQL statement "SELECT 1/0"
-PL/pgSQL function fail() line 3 at RETURN
-drop function fail();
--- Test handling of string literals.
-set standard_conforming_strings = off;
-create or replace function strtest() returns text as $$
-begin
-  raise notice 'foo\\bar\041baz';
-  return 'foo\\bar\041baz';
-end
-$$ language plpgsql;
-WARNING:  nonstandard use of \\ in a string literal
-LINE 3:   raise notice 'foo\\bar\041baz';
-                       ^
-HINT:  Use the escape string syntax for backslashes, e.g., E'\\'.
-WARNING:  nonstandard use of \\ in a string literal
-LINE 4:   return 'foo\\bar\041baz';
-                 ^
-HINT:  Use the escape string syntax for backslashes, e.g., E'\\'.
-WARNING:  nonstandard use of \\ in a string literal
-LINE 4:   return 'foo\\bar\041baz';
-                 ^
-HINT:  Use the escape string syntax for backslashes, e.g., E'\\'.
-select strtest();
-NOTICE:  foo\bar!baz
-WARNING:  nonstandard use of \\ in a string literal
-LINE 1: SELECT 'foo\\bar\041baz'
-               ^
-HINT:  Use the escape string syntax for backslashes, e.g., E'\\'.
-QUERY:  SELECT 'foo\\bar\041baz'
-   strtest   
--------------
- foo\bar!baz
-(1 row)
-
-create or replace function strtest() returns text as $$
-begin
-  raise notice E'foo\\bar\041baz';
-  return E'foo\\bar\041baz';
-end
-$$ language plpgsql;
-select strtest();
-NOTICE:  foo\bar!baz
-   strtest   
--------------
- foo\bar!baz
-(1 row)
-
-set standard_conforming_strings = on;
-create or replace function strtest() returns text as $$
-begin
-  raise notice 'foo\\bar\041baz\';
-  return 'foo\\bar\041baz\';
-end
-$$ language plpgsql;
-select strtest();
-NOTICE:  foo\\bar\041baz\
-     strtest      
-------------------
- foo\\bar\041baz\
-(1 row)
-
-create or replace function strtest() returns text as $$
-begin
-  raise notice E'foo\\bar\041baz';
-  return E'foo\\bar\041baz';
-end
-$$ language plpgsql;
-select strtest();
-NOTICE:  foo\bar!baz
-   strtest   
--------------
- foo\bar!baz
-(1 row)
-
-drop function strtest();
--- Test anonymous code blocks.
-DO $$
-DECLARE r record;
-BEGIN
-    FOR r IN SELECT rtrim(roomno) AS roomno, comment FROM Room ORDER BY roomno
-    LOOP
-        RAISE NOTICE '%, %', r.roomno, r.comment;
-    END LOOP;
-END$$;
-NOTICE:  001, Entrance
-NOTICE:  002, Office
-NOTICE:  003, Office
-NOTICE:  004, Technical
-NOTICE:  101, Office
-NOTICE:  102, Conference
-NOTICE:  103, Restroom
-NOTICE:  104, Technical
-NOTICE:  105, Office
-NOTICE:  106, Office
--- these are to check syntax error reporting
-DO LANGUAGE plpgsql $$begin return 1; end$$;
-ERROR:  RETURN cannot have a parameter in function returning void
-LINE 1: DO LANGUAGE plpgsql $$begin return 1; end$$;
-                                           ^
-DO $$
-DECLARE r record;
-BEGIN
-    FOR r IN SELECT rtrim(roomno) AS roomno, foo FROM Room ORDER BY roomno
-    LOOP
-        RAISE NOTICE '%, %', r.roomno, r.comment;
-    END LOOP;
-END$$;
-ERROR:  column "foo" does not exist
-LINE 1: SELECT rtrim(roomno) AS roomno, foo FROM Room ORDER BY roomn...
-                                        ^
-QUERY:  SELECT rtrim(roomno) AS roomno, foo FROM Room ORDER BY roomno
-CONTEXT:  PL/pgSQL function inline_code_block line 4 at FOR over SELECT rows
--- Check handling of errors thrown from/into anonymous code blocks.
-do $outer$
-begin
-  for i in 1..10 loop
-   begin
-    execute $ex$
-      do $$
-      declare x int = 0;
-      begin
-        x := 1 / x;
-      end;
-      $$;
-    $ex$;
-  exception when division_by_zero then
-    raise notice 'caught division by zero';
-  end;
-  end loop;
-end;
-$outer$;
-ERROR:  Internal subtransactions not supported in Postgres-XL
-CONTEXT:  PL/pgSQL function inline_code_block line 4 during statement block entry
--- Check variable scoping -- a var is not available in its own or prior
--- default expressions.
-create function scope_test() returns int as $$
-declare x int := 42;
-begin
-  declare y int := x + 1;
-          x int := x + 2;
-  begin
-    return x * 100 + y;
-  end;
-end;
-$$ language plpgsql;
-select scope_test();
- scope_test 
-------------
-       4443
-(1 row)
-
-drop function scope_test();
--- Check handling of conflicts between plpgsql vars and table columns.
-set plpgsql.variable_conflict = error;
-create function conflict_test() returns setof int8_tbl as $$
-declare r record;
-  q1 bigint := 42;
-begin
-  for r in select q1,q2 from int8_tbl loop
-    return next r;
-  end loop;
-end;
-$$ language plpgsql;
-select * from conflict_test() order by 1,2;
-ERROR:  column reference "q1" is ambiguous
-LINE 1: select q1,q2 from int8_tbl
-               ^
-DETAIL:  It could refer to either a PL/pgSQL variable or a table column.
-QUERY:  select q1,q2 from int8_tbl
-CONTEXT:  PL/pgSQL function conflict_test() line 5 at FOR over SELECT rows
-create or replace function conflict_test() returns setof int8_tbl as $$
-#variable_conflict use_variable
-declare r record;
-  q1 bigint := 42;
-begin
-  for r in select q1,q2 from int8_tbl loop
-    return next r;
-  end loop;
-end;
-$$ language plpgsql;
--- PGXCTODO: This is failing due to issue 3522907, complicated SELECT queries in plpgsql functions
-select * from conflict_test() order by 1,2;
- q1 |        q2         
-----+-------------------
- 42 | -4567890123456789
- 42 |               123
- 42 |               456
- 42 |  4567890123456789
- 42 |  4567890123456789
-(5 rows)
-
-create or replace function conflict_test() returns setof int8_tbl as $$
-#variable_conflict use_column
-declare r record;
-  q1 bigint := 42;
-begin
-  for r in select q1,q2 from int8_tbl loop
-    return next r;
-  end loop;
-end;
-$$ language plpgsql;
-select * from conflict_test() order by 1,2;
-        q1        |        q2         
-------------------+-------------------
-              123 |               456
-              123 |  4567890123456789
- 4567890123456789 | -4567890123456789
- 4567890123456789 |               123
- 4567890123456789 |  4567890123456789
-(5 rows)
-
-drop function conflict_test();
--- Check that an unreserved keyword can be used as a variable name
-create function unreserved_test() returns int as $$
-declare
-  forward int := 21;
-begin
-  forward := forward * 2;
-  return forward;
-end
-$$ language plpgsql;
-select unreserved_test();
- unreserved_test 
------------------
-              42
-(1 row)
-
-create or replace function unreserved_test() returns int as $$
-declare
-  return int := 42;
-begin
-  return := return + 1;
-  return return;
-end
-$$ language plpgsql;
-select unreserved_test();
- unreserved_test 
------------------
-              43
-(1 row)
-
-drop function unreserved_test();
---
--- Test FOREACH over arrays
---
-create function foreach_test(anyarray)
-returns void as $$
-declare x int;
-begin
-  foreach x in array $1
-  loop
-    raise notice '%', x;
-  end loop;
-  end;
-$$ language plpgsql;
-select foreach_test(ARRAY[1,2,3,4]);
-NOTICE:  1
-NOTICE:  2
-NOTICE:  3
-NOTICE:  4
- foreach_test 
---------------
-(1 row)
-
-select foreach_test(ARRAY[[1,2],[3,4]]);
-NOTICE:  1
-NOTICE:  2
-NOTICE:  3
-NOTICE:  4
- foreach_test 
---------------
-(1 row)
-
-create or replace function foreach_test(anyarray)
-returns void as $$
-declare x int;
-begin
-  foreach x slice 1 in array $1
-  loop
-    raise notice '%', x;
-  end loop;
-  end;
-$$ language plpgsql;
--- should fail
-select foreach_test(ARRAY[1,2,3,4]);
-ERROR:  FOREACH ... SLICE loop variable must be of an array type
-CONTEXT:  PL/pgSQL function foreach_test(anyarray) line 4 at FOREACH over array
-select foreach_test(ARRAY[[1,2],[3,4]]);
-ERROR:  FOREACH ... SLICE loop variable must be of an array type
-CONTEXT:  PL/pgSQL function foreach_test(anyarray) line 4 at FOREACH over array
-create or replace function foreach_test(anyarray)
-returns void as $$
-declare x int[];
-begin
-  foreach x slice 1 in array $1
-  loop
-    raise notice '%', x;
-  end loop;
-  end;
-$$ language plpgsql;
-select foreach_test(ARRAY[1,2,3,4]);
-NOTICE:  {1,2,3,4}
- foreach_test 
---------------
-(1 row)
-
-select foreach_test(ARRAY[[1,2],[3,4]]);
-NOTICE:  {1,2}
-NOTICE:  {3,4}
- foreach_test 
---------------
-(1 row)
-
--- higher level of slicing
-create or replace function foreach_test(anyarray)
-returns void as $$
-declare x int[];
-begin
-  foreach x slice 2 in array $1
-  loop
-    raise notice '%', x;
-  end loop;
-  end;
-$$ language plpgsql;
--- should fail
-select foreach_test(ARRAY[1,2,3,4]);
-ERROR:  slice dimension (2) is out of the valid range 0..1
-CONTEXT:  PL/pgSQL function foreach_test(anyarray) line 4 at FOREACH over array
--- ok
-select foreach_test(ARRAY[[1,2],[3,4]]);
-NOTICE:  {{1,2},{3,4}}
- foreach_test 
---------------
-(1 row)
-
-select foreach_test(ARRAY[[[1,2]],[[3,4]]]);
-NOTICE:  {{1,2}}
-NOTICE:  {{3,4}}
- foreach_test 
---------------
-(1 row)
-
-create type xy_tuple AS (x int, y int);
--- iteration over array of records
-create or replace function foreach_test(anyarray)
-returns void as $$
-declare r record;
-begin
-  foreach r in array $1
-  loop
-    raise notice '%', r;
-  end loop;
-  end;
-$$ language plpgsql;
-select foreach_test(ARRAY[(10,20),(40,69),(35,78)]::xy_tuple[]);
-NOTICE:  (10,20)
-NOTICE:  (40,69)
-NOTICE:  (35,78)
- foreach_test 
---------------
-(1 row)
-
-select foreach_test(ARRAY[[(10,20),(40,69)],[(35,78),(88,76)]]::xy_tuple[]);
-NOTICE:  (10,20)
-NOTICE:  (40,69)
-NOTICE:  (35,78)
-NOTICE:  (88,76)
- foreach_test 
---------------
-(1 row)
-
-create or replace function foreach_test(anyarray)
-returns void as $$
-declare x int; y int;
-begin
-  foreach x, y in array $1
-  loop
-    raise notice 'x = %, y = %', x, y;
-  end loop;
-  end;
-$$ language plpgsql;
-select foreach_test(ARRAY[(10,20),(40,69),(35,78)]::xy_tuple[]);
-NOTICE:  x = 10, y = 20
-NOTICE:  x = 40, y = 69
-NOTICE:  x = 35, y = 78
- foreach_test 
---------------
-(1 row)
-
-select foreach_test(ARRAY[[(10,20),(40,69)],[(35,78),(88,76)]]::xy_tuple[]);
-NOTICE:  x = 10, y = 20
-NOTICE:  x = 40, y = 69
-NOTICE:  x = 35, y = 78
-NOTICE:  x = 88, y = 76
- foreach_test 
---------------
-(1 row)
-
--- slicing over array of composite types
-create or replace function foreach_test(anyarray)
-returns void as $$
-declare x xy_tuple[];
-begin
-  foreach x slice 1 in array $1
-  loop
-    raise notice '%', x;
-  end loop;
-  end;
-$$ language plpgsql;
-select foreach_test(ARRAY[(10,20),(40,69),(35,78)]::xy_tuple[]);
-NOTICE:  {"(10,20)","(40,69)","(35,78)"}
- foreach_test 
---------------
-(1 row)
-
-select foreach_test(ARRAY[[(10,20),(40,69)],[(35,78),(88,76)]]::xy_tuple[]);
-NOTICE:  {"(10,20)","(40,69)"}
-NOTICE:  {"(35,78)","(88,76)"}
- foreach_test 
---------------
-(1 row)
-
-drop function foreach_test(anyarray);
-drop type xy_tuple;
---
--- Assorted tests for array subscript assignment
---
-create temp table rtype (id int, ar text[]);
-create function arrayassign1() returns text[] language plpgsql as $$
-declare
- r record;
-begin
-  r := row(12, '{foo,bar,baz}')::rtype;
-  r.ar[2] := 'replace';
-  return r.ar;
-end$$;
-select arrayassign1();
-   arrayassign1    
--------------------
- {foo,replace,baz}
-(1 row)
-
-select arrayassign1(); -- try again to exercise internal caching
-   arrayassign1    
--------------------
- {foo,replace,baz}
-(1 row)
-
-create domain orderedarray as int[2]
-  constraint sorted check (value[1] < value[2]);
-select '{1,2}'::orderedarray;
- orderedarray 
---------------
- {1,2}
-(1 row)
-
-select '{2,1}'::orderedarray;  -- fail
-ERROR:  value for domain orderedarray violates check constraint "sorted"
-create function testoa(x1 int, x2 int, x3 int) returns orderedarray
-language plpgsql as $$
-declare res orderedarray;
-begin
-  res := array[x1, x2];
-  res[2] := x3;
-  return res;
-end$$;
-select testoa(1,2,3);
- testoa 
---------
- {1,3}
-(1 row)
-
-select testoa(1,2,3); -- try again to exercise internal caching
- testoa 
---------
- {1,3}
-(1 row)
-
-select testoa(2,1,3); -- fail at initial assign
-ERROR:  value for domain orderedarray violates check constraint "sorted"
-CONTEXT:  PL/pgSQL function testoa(integer,integer,integer) line 4 at assignment
-select testoa(1,2,1); -- fail at update
-ERROR:  value for domain orderedarray violates check constraint "sorted"
-CONTEXT:  PL/pgSQL function testoa(integer,integer,integer) line 5 at assignment
-drop function arrayassign1();
-drop function testoa(x1 int, x2 int, x3 int);
--- Check that DMLs in a plpgsql function work OK, when subsequent queries need
--- to open new datanode connections
-CREATE OR REPLACE FUNCTION TestJoinTempTable_CT()
-RETURNS void AS $$
-BEGIN
-        CREATE TABLE IF NOT EXISTS RealTable(ProductId int, ScenarioId int);
-        TRUNCATE TABLE RealTable;
-
-        CREATE TABLE IF NOT EXISTS TmpBar(NodeId int)
-                DISTRIBUTE BY REPLICATION;
-        CREATE TABLE IF NOT EXISTS TmpFoo(TempId int)
-                DISTRIBUTE BY REPLICATION;
-END ;
-$$ LANGUAGE plpgsql;
-CREATE OR REPLACE FUNCTION TestJoinTempTable_INSERT()
-RETURNS void AS $$
-BEGIN
-        INSERT INTO RealTable(ProductId, ScenarioId)
-                SELECT generate_series(1,1000) as ProductId, (random() * 100)::int as ScenarioId;
-
-        INSERT INTO TmpBar(NodeId)
-                SELECT generate_series(1,1000);
-               RAISE INFO 'number of existing rows in RealTable - %', (SELECT count(*) FROM RealTable);
-               RAISE INFO 'number of existing rows in TmpBar - %', (SELECT count(*) FROM TmpBar);
-               RAISE INFO 'number of existing rows in TmpFoo - %', (SELECT count(*) FROM TmpFoo);
-        INSERT INTO TmpFoo(TempId)
-               SELECT DISTINCT(PR.ProductId)
-                 FROM RealTable AS PR
-                 JOIN TmpBar tmp1 ON PR.ProductId = tmp1.NodeId;
-
-               RAISE INFO 'number of rows produced by query - %',
-                               (SELECT COUNT(DISTINCT(PR.ProductId))
-                                FROM RealTable AS PR
-                 JOIN TmpBar tmp1 ON PR.ProductId = tmp1.NodeId);
-               RAISE INFO 'number of rows in TmpFoo - %', (SELECT count(*) FROM TmpFoo);
-               RAISE INFO 'number of existing rows in TmpFoo - %', (SELECT count(*) FROM TmpFoo);
-               RAISE INFO 'number of existing rows in TmpFoo - %', (SELECT count(*) FROM TmpFoo);
-END ;
-$$ LANGUAGE plpgsql;
-SELECT TestJoinTempTable_CT();
- testjointemptable_ct 
-----------------------
-(1 row)
-
-SELECT TestJoinTempTable_INSERT();
-INFO:  number of existing rows in RealTable - 1000
-INFO:  number of existing rows in TmpBar - 1000
-INFO:  number of existing rows in TmpFoo - 0
-INFO:  number of rows produced by query - 1000
-INFO:  number of rows in TmpFoo - 1000
-INFO:  number of existing rows in TmpFoo - 1000
-INFO:  number of existing rows in TmpFoo - 1000
- testjointemptable_insert 
---------------------------
-(1 row)
-
-DROP TABLE RealTable;
-DROP TABLE TmpBar;
-DROP TABLE TmpFoo;
-CREATE OR REPLACE FUNCTION TestJoinTempTable()
-RETURNS void AS $$
-BEGIN
-        CREATE TABLE IF NOT EXISTS RealTable(ProductId int, ScenarioId int);
-        TRUNCATE TABLE RealTable;
-
-        CREATE TEMPORARY TABLE IF NOT EXISTS TmpBar(NodeId int)
-                DISTRIBUTE BY REPLICATION;
-        CREATE TEMPORARY TABLE IF NOT EXISTS TmpFoo(TempId int)
-                DISTRIBUTE BY REPLICATION;
-
-        INSERT INTO RealTable(ProductId, ScenarioId)
-                SELECT generate_series(1,1000) as ProductId, (random() * 100)::int as ScenarioId;
-
-        INSERT INTO TmpBar(NodeId)
-                SELECT generate_series(1,1000);
-
-        INSERT INTO TmpFoo(TempId)
-               SELECT DISTINCT(PR.ProductId)
-                 FROM RealTable AS PR
-                 JOIN TmpBar tmp1 ON PR.ProductId = tmp1.NodeId;
-END ;
-$$ LANGUAGE plpgsql;
-SELECT TestJoinTempTable();
- testjointemptable 
--------------------
-(1 row)
-
--- Multiple invokations of the function showed interesting issues with command
--- passdown. So add that to the test case
-SELECT TestJoinTempTable();
-NOTICE:  relation "realtable" already exists, skipping
-NOTICE:  relation "tmpbar" already exists, skipping
-NOTICE:  relation "tmpfoo" already exists, skipping
- testjointemptable 
--------------------
-(1 row)
-
-SELECT TestJoinTempTable();
-NOTICE:  relation "realtable" already exists, skipping
-NOTICE:  relation "tmpbar" already exists, skipping
-NOTICE:  relation "tmpfoo" already exists, skipping
- testjointemptable 
--------------------
-(1 row)
-
-DROP TABLE RealTable;
-DROP TABLE TmpBar;
-DROP TABLE TmpFoo;
---
--- Test handling of expanded arrays
---
-create function returns_rw_array(int) returns int[]
-language plpgsql as $$
-  declare r int[];
-  begin r := array[$1, $1]; return r; end;
-$$ stable;
-create function consumes_rw_array(int[]) returns int
-language plpgsql as $$
-  begin return $1[1]; end;
-$$ stable;
--- bug #14174
-explain (verbose, costs off)
-select i, a from
-  (select returns_rw_array(1) as a offset 0) ss,
-  lateral consumes_rw_array(a) i;
-                           QUERY PLAN                            
------------------------------------------------------------------
- Nested Loop
-   Output: i.i, (returns_rw_array(1))
-   ->  Result
-         Output: returns_rw_array(1)
-   ->  Function Scan on public.consumes_rw_array i
-         Output: i.i
-         Function Call: consumes_rw_array((returns_rw_array(1)))
-(7 rows)
-
-select i, a from
-  (select returns_rw_array(1) as a offset 0) ss,
-  lateral consumes_rw_array(a) i;
- i |   a   
----+-------
- 1 | {1,1}
-(1 row)
-
-explain (verbose, costs off)
-select consumes_rw_array(a), a from returns_rw_array(1) a;
-                 QUERY PLAN                 
---------------------------------------------
- Function Scan on public.returns_rw_array a
-   Output: consumes_rw_array(a), a
-   Function Call: returns_rw_array(1)
-(3 rows)
-
-select consumes_rw_array(a), a from returns_rw_array(1) a;
- consumes_rw_array |   a   
--------------------+-------
-                 1 | {1,1}
-(1 row)
-
-explain (verbose, costs off)
-select consumes_rw_array(a), a from
-  (values (returns_rw_array(1)), (returns_rw_array(2))) v(a);
-                             QUERY PLAN                              
----------------------------------------------------------------------
- Values Scan on "*VALUES*"
-   Output: consumes_rw_array("*VALUES*".column1), "*VALUES*".column1
-(2 rows)
-
-select consumes_rw_array(a), a from
-  (values (returns_rw_array(1)), (returns_rw_array(2))) v(a);
- consumes_rw_array |   a   
--------------------+-------
-                 1 | {1,1}
-                 2 | {2,2}
-(2 rows)
-
---
--- Test access to call stack
---
-create function inner_func(int)
-returns int as $$
-declare _context text;
-begin
-  get diagnostics _context = pg_context;
-  raise notice '***%***', _context;
-  -- lets do it again, just for fun..
-  get diagnostics _context = pg_context;
-  raise notice '***%***', _context;
-  raise notice 'lets make sure we didnt break anything';
-  return 2 * $1;
-end;
-$$ language plpgsql;
-create or replace function outer_func(int)
-returns int as $$
-declare
-  myresult int;
-begin
-  raise notice 'calling down into inner_func()';
-  myresult := inner_func($1);
-  raise notice 'inner_func() done';
-  return myresult;
-end;
-$$ language plpgsql;
-create or replace function outer_outer_func(int)
-returns int as $$
-declare
-  myresult int;
-begin
-  raise notice 'calling down into outer_func()';
-  myresult := outer_func($1);
-  raise notice 'outer_func() done';
-  return myresult;
-end;
-$$ language plpgsql;
-select outer_outer_func(10);
-NOTICE:  calling down into outer_func()
-NOTICE:  calling down into inner_func()
-NOTICE:  ***PL/pgSQL function inner_func(integer) line 4 at GET DIAGNOSTICS
-PL/pgSQL function outer_func(integer) line 6 at assignment
-PL/pgSQL function outer_outer_func(integer) line 6 at assignment***
-NOTICE:  ***PL/pgSQL function inner_func(integer) line 7 at GET DIAGNOSTICS
-PL/pgSQL function outer_func(integer) line 6 at assignment
-PL/pgSQL function outer_outer_func(integer) line 6 at assignment***
-NOTICE:  lets make sure we didnt break anything
-NOTICE:  inner_func() done
-NOTICE:  outer_func() done
- outer_outer_func 
-------------------
-               20
-(1 row)
-
--- repeated call should to work
-select outer_outer_func(20);
-NOTICE:  calling down into outer_func()
-NOTICE:  calling down into inner_func()
-NOTICE:  ***PL/pgSQL function inner_func(integer) line 4 at GET DIAGNOSTICS
-PL/pgSQL function outer_func(integer) line 6 at assignment
-PL/pgSQL function outer_outer_func(integer) line 6 at assignment***
-NOTICE:  ***PL/pgSQL function inner_func(integer) line 7 at GET DIAGNOSTICS
-PL/pgSQL function outer_func(integer) line 6 at assignment
-PL/pgSQL function outer_outer_func(integer) line 6 at assignment***
-NOTICE:  lets make sure we didnt break anything
-NOTICE:  inner_func() done
-NOTICE:  outer_func() done
- outer_outer_func 
-------------------
-               40
-(1 row)
-
-drop function outer_outer_func(int);
-drop function outer_func(int);
-drop function inner_func(int);
--- access to call stack from exception
-create function inner_func(int)
-returns int as $$
-declare
-  _context text;
-  sx int := 5;
-begin
-  begin
-    perform sx / 0;
-  exception
-    when division_by_zero then
-      get diagnostics _context = pg_context;
-      raise notice '***%***', _context;
-  end;
-
-  -- lets do it again, just for fun..
-  get diagnostics _context = pg_context;
-  raise notice '***%***', _context;
-  raise notice 'lets make sure we didnt break anything';
-  return 2 * $1;
-end;
-$$ language plpgsql;
-create or replace function outer_func(int)
-returns int as $$
-declare
-  myresult int;
-begin
-  raise notice 'calling down into inner_func()';
-  myresult := inner_func($1);
-  raise notice 'inner_func() done';
-  return myresult;
-end;
-$$ language plpgsql;
-create or replace function outer_outer_func(int)
-returns int as $$
-declare
-  myresult int;
-begin
-  raise notice 'calling down into outer_func()';
-  myresult := outer_func($1);
-  raise notice 'outer_func() done';
-  return myresult;
-end;
-$$ language plpgsql;
-select outer_outer_func(10);
-NOTICE:  calling down into outer_func()
-NOTICE:  calling down into inner_func()
-ERROR:  Internal subtransactions not supported in Postgres-XL
-CONTEXT:  PL/pgSQL function inner_func(integer) line 6 during statement block entry
-PL/pgSQL function outer_func(integer) line 6 at assignment
-PL/pgSQL function outer_outer_func(integer) line 6 at assignment
--- repeated call should to work
-select outer_outer_func(20);
-NOTICE:  calling down into outer_func()
-NOTICE:  calling down into inner_func()
-ERROR:  Internal subtransactions not supported in Postgres-XL
-CONTEXT:  PL/pgSQL function inner_func(integer) line 6 during statement block entry
-PL/pgSQL function outer_func(integer) line 6 at assignment
-PL/pgSQL function outer_outer_func(integer) line 6 at assignment
-drop function outer_outer_func(int);
-drop function outer_func(int);
-drop function inner_func(int);
---
--- Test ASSERT
---
-do $$
-begin
-  assert 1=1;  -- should succeed
-end;
-$$;
-do $$
-begin
-  assert 1=0;  -- should fail
-end;
-$$;
-ERROR:  assertion failed
-CONTEXT:  PL/pgSQL function inline_code_block line 3 at ASSERT
-do $$
-begin
-  assert NULL;  -- should fail
-end;
-$$;
-ERROR:  assertion failed
-CONTEXT:  PL/pgSQL function inline_code_block line 3 at ASSERT
--- check controlling GUC
-set plpgsql.check_asserts = off;
-do $$
-begin
-  assert 1=0;  -- won't be tested
-end;
-$$;
-reset plpgsql.check_asserts;
--- test custom message
-do $$
-declare var text := 'some value';
-begin
-  assert 1=0, format('assertion failed, var = "%s"', var);
-end;
-$$;
-ERROR:  assertion failed, var = "some value"
-CONTEXT:  PL/pgSQL function inline_code_block line 4 at ASSERT
--- ensure assertions are not trapped by 'others'
-do $$
-begin
-  assert 1=0, 'unhandled assertion';
-exception when others then
-  null; -- do nothing
-end;
-$$;
-ERROR:  Internal subtransactions not supported in Postgres-XL
-CONTEXT:  PL/pgSQL function inline_code_block line 2 during statement block entry
--- Check parameter handling
-BEGIN;
-DROP TABLE IF EXISTS testcase_13;
-NOTICE:  table "testcase_13" does not exist, skipping
-CREATE TABLE testcase_13 (patient_id integer);
-INSERT INTO testcase_13 VALUES (1);
-DO $$
-DECLARE
- r RECORD;
-BEGIN
-FOR r IN SELECT * FROM testcase_13 LOOP
-    RAISE INFO 'r.patient_id=%', r.patient_id;
-    IF   (SELECT EXISTS (
-            SELECT FROM testcase_13 WHERE patient_id = r.patient_id
-        ))
-       THEN
-          RAISE INFO 'condition true';
-    END IF;
-  END LOOP;
-END $$;
-INFO:  r.patient_id=1
-INFO:  condition true
-ROLLBACK;