rules.out 62.6 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13
--
-- RULES
-- From Jan's original setup_ruletest.sql and run_ruletest.sql
-- - thomas 1998-09-13
--
--
-- Tables and rules for the view test
--
create table rtest_t1 (a int4, b int4);
create table rtest_t2 (a int4, b int4);
create table rtest_t3 (a int4, b int4);
create view rtest_v1 as select * from rtest_t1;
create rule rtest_v1_ins as on insert to rtest_v1 do instead
14
	insert into rtest_t1 values (new.a, new.b);
15
create rule rtest_v1_upd as on update to rtest_v1 do instead
16
	update rtest_t1 set a = new.a, b = new.b
17
	where a = old.a;
18
create rule rtest_v1_del as on delete to rtest_v1 do instead
19
	delete from rtest_t1 where a = old.a;
20 21 22 23 24 25 26 27 28 29 30 31 32 33
--
-- Tables and rules for the constraint update/delete test
--
-- Note:
-- 	Now that we have multiple action rule support, we check
-- 	both possible syntaxes to define them (The last action
--  can but must not have a semicolon at the end).
--
create table rtest_system (sysname text, sysdesc text);
create table rtest_interface (sysname text, ifname text);
create table rtest_person (pname text, pdesc text);
create table rtest_admin (pname text, sysname text);
create rule rtest_sys_upd as on update to rtest_system do (
	update rtest_interface set sysname = new.sysname 
34
		where sysname = old.sysname;
35
	update rtest_admin set sysname = new.sysname 
36
		where sysname = old.sysname
37
	);
38
create rule rtest_sys_del as on delete to rtest_system do (
39 40
	delete from rtest_interface where sysname = old.sysname;
	delete from rtest_admin where sysname = old.sysname;
41
	);
42
create rule rtest_pers_upd as on update to rtest_person do 
43
	update rtest_admin set pname = new.pname where pname = old.pname;
44
create rule rtest_pers_del as on delete to rtest_person do 
45
	delete from rtest_admin where pname = old.pname;
46 47 48 49 50 51 52
--
-- Tables and rules for the logging test
--
create table rtest_emp (ename char(20), salary money);
create table rtest_emplog (ename char(20), who name, action char(10), newsal money, oldsal money);
create table rtest_empmass (ename char(20), salary money);
create rule rtest_emp_ins as on insert to rtest_emp do
53 54
	insert into rtest_emplog values (new.ename, current_user,
			'hired', new.salary, '0.00');
55
create rule rtest_emp_upd as on update to rtest_emp where new.salary != old.salary do
56
	insert into rtest_emplog values (new.ename, current_user,
57
			'honored', new.salary, old.salary);
58
create rule rtest_emp_del as on delete to rtest_emp do
59 60
	insert into rtest_emplog values (old.ename, current_user,
			'fired', '0.00', old.salary);
61 62 63 64 65 66 67 68 69 70 71
--
-- Tables and rules for the multiple cascaded qualified instead
-- rule test 
--
create table rtest_t4 (a int4, b text);
create table rtest_t5 (a int4, b text);
create table rtest_t6 (a int4, b text);
create table rtest_t7 (a int4, b text);
create table rtest_t8 (a int4, b text);
create table rtest_t9 (a int4, b text);
create rule rtest_t4_ins1 as on insert to rtest_t4
72 73
		where new.a >= 10 and new.a < 20 do instead
	insert into rtest_t5 values (new.a, new.b);
74
create rule rtest_t4_ins2 as on insert to rtest_t4
75 76
		where new.a >= 20 and new.a < 30 do
	insert into rtest_t6 values (new.a, new.b);
77
create rule rtest_t5_ins as on insert to rtest_t5
78 79
		where new.a > 15 do
	insert into rtest_t7 values (new.a, new.b);
80
create rule rtest_t6_ins as on insert to rtest_t6
81 82
		where new.a > 25 do instead
	insert into rtest_t8 values (new.a, new.b);
83 84 85
--
-- Tables and rules for the rule fire order test
--
86 87 88
-- As of PG 7.3, the rules should fire in order by name, regardless
-- of INSTEAD attributes or creation order.
--
89 90 91 92
create table rtest_order1 (a int4);
create table rtest_order2 (a int4, b int4, c text);
create sequence rtest_seq;
create rule rtest_order_r3 as on insert to rtest_order1 do instead
93
	insert into rtest_order2 values (new.a, nextval('rtest_seq'),
94
		'rule 3 - this should run 3rd');
95
create rule rtest_order_r4 as on insert to rtest_order1
96 97
		where a < 100 do instead
	insert into rtest_order2 values (new.a, nextval('rtest_seq'),
98
		'rule 4 - this should run 4th');
99
create rule rtest_order_r2 as on insert to rtest_order1 do
100
	insert into rtest_order2 values (new.a, nextval('rtest_seq'),
101
		'rule 2 - this should run 2nd');
102
create rule rtest_order_r1 as on insert to rtest_order1 do instead
103
	insert into rtest_order2 values (new.a, nextval('rtest_seq'),
104
		'rule 1 - this should run 1st');
105 106 107 108 109 110 111 112
--
-- Tables and rules for the instead nothing test
--
create table rtest_nothn1 (a int4, b text);
create table rtest_nothn2 (a int4, b text);
create table rtest_nothn3 (a int4, b text);
create table rtest_nothn4 (a int4, b text);
create rule rtest_nothn_r1 as on insert to rtest_nothn1
113
	where new.a >= 10 and new.a < 20 do instead nothing;
114
create rule rtest_nothn_r2 as on insert to rtest_nothn1
115
	where new.a >= 30 and new.a < 40 do instead nothing;
116
create rule rtest_nothn_r3 as on insert to rtest_nothn2
117 118
	where new.a >= 100 do instead
	insert into rtest_nothn3 values (new.a, new.b);
119
create rule rtest_nothn_r4 as on insert to rtest_nothn2
120
	do instead nothing;
121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144
--
-- Tests on a view that is select * of a table
-- and has insert/update/delete instead rules to
-- behave close like the real table.
--
--
-- We need test date later
--
insert into rtest_t2 values (1, 21);
insert into rtest_t2 values (2, 22);
insert into rtest_t2 values (3, 23);
insert into rtest_t3 values (1, 31);
insert into rtest_t3 values (2, 32);
insert into rtest_t3 values (3, 33);
insert into rtest_t3 values (4, 34);
insert into rtest_t3 values (5, 35);
-- insert values
insert into rtest_v1 values (1, 11);
insert into rtest_v1 values (2, 12);
select * from rtest_v1;
 a | b  
---+----
 1 | 11
 2 | 12
145 146
(2 rows)

147 148 149 150 151 152
-- delete with constant expression
delete from rtest_v1 where a = 1;
select * from rtest_v1;
 a | b  
---+----
 2 | 12
153 154
(1 row)

155 156 157 158 159 160
insert into rtest_v1 values (1, 11);
delete from rtest_v1 where b = 12;
select * from rtest_v1;
 a | b  
---+----
 1 | 11
161 162
(1 row)

163 164 165 166 167 168 169 170
insert into rtest_v1 values (2, 12);
insert into rtest_v1 values (2, 13);
select * from rtest_v1;
 a | b  
---+----
 1 | 11
 2 | 12
 2 | 13
171 172 173
(3 rows)

** Remember the delete rule on rtest_v1: It says
174
** DO INSTEAD DELETE FROM rtest_t1 WHERE a = old.a
175
** So this time both rows with a = 2 must get deleted
176 177 178 179 180 181 182 183 184 185
\p
** Remember the delete rule on rtest_v1: It says
** DO INSTEAD DELETE FROM rtest_t1 WHERE a = old.a
** So this time both rows with a = 2 must get deleted
\r
delete from rtest_v1 where b = 12;
select * from rtest_v1;
 a | b  
---+----
 1 | 11
186 187
(1 row)

188 189 190 191 192 193 194 195 196
delete from rtest_v1;
-- insert select
insert into rtest_v1 select * from rtest_t2;
select * from rtest_v1;
 a | b  
---+----
 1 | 21
 2 | 22
 3 | 23
197 198
(3 rows)

199 200 201 202 203 204 205 206 207
delete from rtest_v1;
-- same with swapped targetlist
insert into rtest_v1 (b, a) select b, a from rtest_t2;
select * from rtest_v1;
 a | b  
---+----
 1 | 21
 2 | 22
 3 | 23
208 209
(3 rows)

210 211 212 213 214 215 216 217 218 219 220 221 222
-- now with only one target attribute
insert into rtest_v1 (a) select a from rtest_t3;
select * from rtest_v1;
 a | b  
---+----
 1 | 21
 2 | 22
 3 | 23
 1 |   
 2 |   
 3 |   
 4 |   
 5 |   
223 224
(8 rows)

225 226 227 228 229 230 231 232
select * from rtest_v1 where b isnull;
 a | b 
---+---
 1 |  
 2 |  
 3 |  
 4 |  
 5 |  
233 234
(5 rows)

235 236 237 238 239 240 241 242 243
-- let attribute a differ (must be done on rtest_t1 - see above)
update rtest_t1 set a = a + 10 where b isnull;
delete from rtest_v1 where b isnull;
select * from rtest_v1;
 a | b  
---+----
 1 | 21
 2 | 22
 3 | 23
244 245
(3 rows)

246 247 248 249 250 251 252 253
-- now updates with constant expression
update rtest_v1 set b = 42 where a = 2;
select * from rtest_v1;
 a | b  
---+----
 1 | 21
 3 | 23
 2 | 42
254 255
(3 rows)

256 257 258 259 260 261 262
update rtest_v1 set b = 99 where b = 42;
select * from rtest_v1;
 a | b  
---+----
 1 | 21
 3 | 23
 2 | 99
263 264
(3 rows)

265 266 267 268 269 270 271
update rtest_v1 set b = 88 where b < 50;
select * from rtest_v1;
 a | b  
---+----
 2 | 99
 1 | 88
 3 | 88
272 273
(3 rows)

274 275 276 277 278 279 280 281
delete from rtest_v1;
insert into rtest_v1 select rtest_t2.a, rtest_t3.b where rtest_t2.a = rtest_t3.a;
select * from rtest_v1;
 a | b  
---+----
 1 | 31
 2 | 32
 3 | 33
282 283
(3 rows)

284 285 286 287 288 289 290 291
-- updates in a mergejoin
update rtest_v1 set b = rtest_t2.b where a = rtest_t2.a;
select * from rtest_v1;
 a | b  
---+----
 1 | 21
 2 | 22
 3 | 23
292 293
(3 rows)

294 295 296 297 298 299 300 301 302 303 304 305
insert into rtest_v1 select * from rtest_t3;
select * from rtest_v1;
 a | b  
---+----
 1 | 21
 2 | 22
 3 | 23
 1 | 31
 2 | 32
 3 | 33
 4 | 34
 5 | 35
306 307
(8 rows)

308 309 310 311 312 313 314 315 316 317 318 319
update rtest_t1 set a = a + 10 where b > 30;
select * from rtest_v1;
 a  | b  
----+----
  1 | 21
  2 | 22
  3 | 23
 11 | 31
 12 | 32
 13 | 33
 14 | 34
 15 | 35
320 321
(8 rows)

322 323 324 325 326 327 328 329 330 331 332 333
update rtest_v1 set a = rtest_t3.a + 20 where b = rtest_t3.b;
select * from rtest_v1;
 a  | b  
----+----
  1 | 21
  2 | 22
  3 | 23
 21 | 31
 22 | 32
 23 | 33
 24 | 34
 25 | 35
334 335
(8 rows)

336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358
--
-- Test for constraint updates/deletes
--
insert into rtest_system values ('orion', 'Linux Jan Wieck');
insert into rtest_system values ('notjw', 'WinNT Jan Wieck (notebook)');
insert into rtest_system values ('neptun', 'Fileserver');
insert into rtest_interface values ('orion', 'eth0');
insert into rtest_interface values ('orion', 'eth1');
insert into rtest_interface values ('notjw', 'eth0');
insert into rtest_interface values ('neptun', 'eth0');
insert into rtest_person values ('jw', 'Jan Wieck');
insert into rtest_person values ('bm', 'Bruce Momjian');
insert into rtest_admin values ('jw', 'orion');
insert into rtest_admin values ('jw', 'notjw');
insert into rtest_admin values ('bm', 'neptun');
update rtest_system set sysname = 'pluto' where sysname = 'neptun';
select * from rtest_interface;
 sysname | ifname 
---------+--------
 orion   | eth0
 orion   | eth1
 notjw   | eth0
 pluto   | eth0
359 360
(4 rows)

361 362 363 364 365 366
select * from rtest_admin;
 pname | sysname 
-------+---------
 jw    | orion
 jw    | notjw
 bm    | pluto
367 368
(3 rows)

369 370 371 372 373 374 375 376 377 378
update rtest_person set pname = 'jwieck' where pdesc = 'Jan Wieck';
-- Note: use ORDER BY here to ensure consistent output across all systems.
-- The above UPDATE affects two rows with equal keys, so they could be
-- updated in either order depending on the whim of the local qsort().
select * from rtest_admin order by pname, sysname;
 pname  | sysname 
--------+---------
 bm     | pluto
 jwieck | notjw
 jwieck | orion
379 380
(3 rows)

381 382 383 384 385 386
delete from rtest_system where sysname = 'orion';
select * from rtest_interface;
 sysname | ifname 
---------+--------
 notjw   | eth0
 pluto   | eth0
387 388
(2 rows)

389 390 391 392 393
select * from rtest_admin;
 pname  | sysname 
--------+---------
 bm     | pluto
 jwieck | notjw
394 395
(2 rows)

396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412
--
-- Rule qualification test
--
insert into rtest_emp values ('wiech', '5000.00');
insert into rtest_emp values ('gates', '80000.00');
update rtest_emp set ename = 'wiecx' where ename = 'wiech';
update rtest_emp set ename = 'wieck', salary = '6000.00' where ename = 'wiecx';
update rtest_emp set salary = '7000.00' where ename = 'wieck';
delete from rtest_emp where ename = 'gates';
select ename, who = current_user as "matches user", action, newsal, oldsal from rtest_emplog order by ename, action, newsal;
        ename         | matches user |   action   |   newsal   |   oldsal   
----------------------+--------------+------------+------------+------------
 gates                | t            | fired      |      $0.00 | $80,000.00
 gates                | t            | hired      | $80,000.00 |      $0.00
 wiech                | t            | hired      |  $5,000.00 |      $0.00
 wieck                | t            | honored    |  $6,000.00 |  $5,000.00
 wieck                | t            | honored    |  $7,000.00 |  $6,000.00
413 414
(5 rows)

415 416 417 418 419 420 421 422 423 424 425 426 427 428 429
insert into rtest_empmass values ('meyer', '4000.00');
insert into rtest_empmass values ('maier', '5000.00');
insert into rtest_empmass values ('mayr', '6000.00');
insert into rtest_emp select * from rtest_empmass;
select ename, who = current_user as "matches user", action, newsal, oldsal from rtest_emplog order by ename, action, newsal;
        ename         | matches user |   action   |   newsal   |   oldsal   
----------------------+--------------+------------+------------+------------
 gates                | t            | fired      |      $0.00 | $80,000.00
 gates                | t            | hired      | $80,000.00 |      $0.00
 maier                | t            | hired      |  $5,000.00 |      $0.00
 mayr                 | t            | hired      |  $6,000.00 |      $0.00
 meyer                | t            | hired      |  $4,000.00 |      $0.00
 wiech                | t            | hired      |  $5,000.00 |      $0.00
 wieck                | t            | honored    |  $6,000.00 |  $5,000.00
 wieck                | t            | honored    |  $7,000.00 |  $6,000.00
430 431
(8 rows)

432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447
update rtest_empmass set salary = salary + '1000.00';
update rtest_emp set salary = rtest_empmass.salary where ename = rtest_empmass.ename;
select ename, who = current_user as "matches user", action, newsal, oldsal from rtest_emplog order by ename, action, newsal;
        ename         | matches user |   action   |   newsal   |   oldsal   
----------------------+--------------+------------+------------+------------
 gates                | t            | fired      |      $0.00 | $80,000.00
 gates                | t            | hired      | $80,000.00 |      $0.00
 maier                | t            | hired      |  $5,000.00 |      $0.00
 maier                | t            | honored    |  $6,000.00 |  $5,000.00
 mayr                 | t            | hired      |  $6,000.00 |      $0.00
 mayr                 | t            | honored    |  $7,000.00 |  $6,000.00
 meyer                | t            | hired      |  $4,000.00 |      $0.00
 meyer                | t            | honored    |  $5,000.00 |  $4,000.00
 wiech                | t            | hired      |  $5,000.00 |      $0.00
 wieck                | t            | honored    |  $6,000.00 |  $5,000.00
 wieck                | t            | honored    |  $7,000.00 |  $6,000.00
448 449
(11 rows)

450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467
delete from rtest_emp where ename = rtest_empmass.ename;
select ename, who = current_user as "matches user", action, newsal, oldsal from rtest_emplog order by ename, action, newsal;
        ename         | matches user |   action   |   newsal   |   oldsal   
----------------------+--------------+------------+------------+------------
 gates                | t            | fired      |      $0.00 | $80,000.00
 gates                | t            | hired      | $80,000.00 |      $0.00
 maier                | t            | fired      |      $0.00 |  $6,000.00
 maier                | t            | hired      |  $5,000.00 |      $0.00
 maier                | t            | honored    |  $6,000.00 |  $5,000.00
 mayr                 | t            | fired      |      $0.00 |  $7,000.00
 mayr                 | t            | hired      |  $6,000.00 |      $0.00
 mayr                 | t            | honored    |  $7,000.00 |  $6,000.00
 meyer                | t            | fired      |      $0.00 |  $5,000.00
 meyer                | t            | hired      |  $4,000.00 |      $0.00
 meyer                | t            | honored    |  $5,000.00 |  $4,000.00
 wiech                | t            | hired      |  $5,000.00 |      $0.00
 wieck                | t            | honored    |  $6,000.00 |  $5,000.00
 wieck                | t            | honored    |  $7,000.00 |  $6,000.00
468 469
(14 rows)

470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492
--
-- Multiple cascaded qualified instead rule test
--
insert into rtest_t4 values (1, 'Record should go to rtest_t4');
insert into rtest_t4 values (2, 'Record should go to rtest_t4');
insert into rtest_t4 values (10, 'Record should go to rtest_t5');
insert into rtest_t4 values (15, 'Record should go to rtest_t5');
insert into rtest_t4 values (19, 'Record should go to rtest_t5 and t7');
insert into rtest_t4 values (20, 'Record should go to rtest_t4 and t6');
insert into rtest_t4 values (26, 'Record should go to rtest_t4 and t8');
insert into rtest_t4 values (28, 'Record should go to rtest_t4 and t8');
insert into rtest_t4 values (30, 'Record should go to rtest_t4');
insert into rtest_t4 values (40, 'Record should go to rtest_t4');
select * from rtest_t4;
 a  |                  b                  
----+-------------------------------------
  1 | Record should go to rtest_t4
  2 | Record should go to rtest_t4
 20 | Record should go to rtest_t4 and t6
 26 | Record should go to rtest_t4 and t8
 28 | Record should go to rtest_t4 and t8
 30 | Record should go to rtest_t4
 40 | Record should go to rtest_t4
493 494
(7 rows)

495 496 497 498 499 500
select * from rtest_t5;
 a  |                  b                  
----+-------------------------------------
 10 | Record should go to rtest_t5
 15 | Record should go to rtest_t5
 19 | Record should go to rtest_t5 and t7
501 502
(3 rows)

503 504 505 506
select * from rtest_t6;
 a  |                  b                  
----+-------------------------------------
 20 | Record should go to rtest_t4 and t6
507 508
(1 row)

509 510 511 512
select * from rtest_t7;
 a  |                  b                  
----+-------------------------------------
 19 | Record should go to rtest_t5 and t7
513 514
(1 row)

515 516 517 518 519
select * from rtest_t8;
 a  |                  b                  
----+-------------------------------------
 26 | Record should go to rtest_t4 and t8
 28 | Record should go to rtest_t4 and t8
520 521
(2 rows)

522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542
delete from rtest_t4;
delete from rtest_t5;
delete from rtest_t6;
delete from rtest_t7;
delete from rtest_t8;
insert into rtest_t9 values (1, 'Record should go to rtest_t4');
insert into rtest_t9 values (2, 'Record should go to rtest_t4');
insert into rtest_t9 values (10, 'Record should go to rtest_t5');
insert into rtest_t9 values (15, 'Record should go to rtest_t5');
insert into rtest_t9 values (19, 'Record should go to rtest_t5 and t7');
insert into rtest_t9 values (20, 'Record should go to rtest_t4 and t6');
insert into rtest_t9 values (26, 'Record should go to rtest_t4 and t8');
insert into rtest_t9 values (28, 'Record should go to rtest_t4 and t8');
insert into rtest_t9 values (30, 'Record should go to rtest_t4');
insert into rtest_t9 values (40, 'Record should go to rtest_t4');
insert into rtest_t4 select * from rtest_t9 where a < 20;
select * from rtest_t4;
 a |              b               
---+------------------------------
 1 | Record should go to rtest_t4
 2 | Record should go to rtest_t4
543 544
(2 rows)

545 546 547 548 549 550
select * from rtest_t5;
 a  |                  b                  
----+-------------------------------------
 10 | Record should go to rtest_t5
 15 | Record should go to rtest_t5
 19 | Record should go to rtest_t5 and t7
551 552
(3 rows)

553 554 555
select * from rtest_t6;
 a | b 
---+---
556 557
(0 rows)

558 559 560 561
select * from rtest_t7;
 a  |                  b                  
----+-------------------------------------
 19 | Record should go to rtest_t5 and t7
562 563
(1 row)

564 565 566
select * from rtest_t8;
 a | b 
---+---
567 568
(0 rows)

569 570 571 572 573 574 575 576
insert into rtest_t4 select * from rtest_t9 where b ~ 'and t8';
select * from rtest_t4;
 a  |                  b                  
----+-------------------------------------
  1 | Record should go to rtest_t4
  2 | Record should go to rtest_t4
 26 | Record should go to rtest_t4 and t8
 28 | Record should go to rtest_t4 and t8
577 578
(4 rows)

579 580 581 582 583 584
select * from rtest_t5;
 a  |                  b                  
----+-------------------------------------
 10 | Record should go to rtest_t5
 15 | Record should go to rtest_t5
 19 | Record should go to rtest_t5 and t7
585 586
(3 rows)

587 588 589
select * from rtest_t6;
 a | b 
---+---
590 591
(0 rows)

592 593 594 595
select * from rtest_t7;
 a  |                  b                  
----+-------------------------------------
 19 | Record should go to rtest_t5 and t7
596 597
(1 row)

598 599 600 601 602
select * from rtest_t8;
 a  |                  b                  
----+-------------------------------------
 26 | Record should go to rtest_t4 and t8
 28 | Record should go to rtest_t4 and t8
603 604
(2 rows)

605 606 607 608 609 610 611 612 613 614 615
insert into rtest_t4 select a + 1, b from rtest_t9 where a in (20, 30, 40);
select * from rtest_t4;
 a  |                  b                  
----+-------------------------------------
  1 | Record should go to rtest_t4
  2 | Record should go to rtest_t4
 26 | Record should go to rtest_t4 and t8
 28 | Record should go to rtest_t4 and t8
 21 | Record should go to rtest_t4 and t6
 31 | Record should go to rtest_t4
 41 | Record should go to rtest_t4
616 617
(7 rows)

618 619 620 621 622 623
select * from rtest_t5;
 a  |                  b                  
----+-------------------------------------
 10 | Record should go to rtest_t5
 15 | Record should go to rtest_t5
 19 | Record should go to rtest_t5 and t7
624 625
(3 rows)

626 627 628 629
select * from rtest_t6;
 a  |                  b                  
----+-------------------------------------
 21 | Record should go to rtest_t4 and t6
630 631
(1 row)

632 633 634 635
select * from rtest_t7;
 a  |                  b                  
----+-------------------------------------
 19 | Record should go to rtest_t5 and t7
636 637
(1 row)

638 639 640 641 642
select * from rtest_t8;
 a  |                  b                  
----+-------------------------------------
 26 | Record should go to rtest_t4 and t8
 28 | Record should go to rtest_t4 and t8
643 644
(2 rows)

645 646 647 648 649
--
-- Check that the ordering of rules fired is correct
--
insert into rtest_order1 values (1);
select * from rtest_order2;
650 651 652 653 654 655
 a | b |              c               
---+---+------------------------------
 1 | 1 | rule 1 - this should run 1st
 1 | 2 | rule 2 - this should run 2nd
 1 | 3 | rule 3 - this should run 3rd
 1 | 4 | rule 4 - this should run 4th
656 657
(4 rows)

658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681
--
-- Check if instead nothing w/without qualification works
--
insert into rtest_nothn1 values (1, 'want this');
insert into rtest_nothn1 values (2, 'want this');
insert into rtest_nothn1 values (10, 'don''t want this');
insert into rtest_nothn1 values (19, 'don''t want this');
insert into rtest_nothn1 values (20, 'want this');
insert into rtest_nothn1 values (29, 'want this');
insert into rtest_nothn1 values (30, 'don''t want this');
insert into rtest_nothn1 values (39, 'don''t want this');
insert into rtest_nothn1 values (40, 'want this');
insert into rtest_nothn1 values (50, 'want this');
insert into rtest_nothn1 values (60, 'want this');
select * from rtest_nothn1;
 a  |     b     
----+-----------
  1 | want this
  2 | want this
 20 | want this
 29 | want this
 40 | want this
 50 | want this
 60 | want this
682 683
(7 rows)

684 685 686 687 688 689 690
insert into rtest_nothn2 values (10, 'too small');
insert into rtest_nothn2 values (50, 'too small');
insert into rtest_nothn2 values (100, 'OK');
insert into rtest_nothn2 values (200, 'OK');
select * from rtest_nothn2;
 a | b 
---+---
691 692
(0 rows)

693 694 695 696 697
select * from rtest_nothn3;
  a  | b  
-----+----
 100 | OK
 200 | OK
698 699
(2 rows)

700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724
delete from rtest_nothn1;
delete from rtest_nothn2;
delete from rtest_nothn3;
insert into rtest_nothn4 values (1, 'want this');
insert into rtest_nothn4 values (2, 'want this');
insert into rtest_nothn4 values (10, 'don''t want this');
insert into rtest_nothn4 values (19, 'don''t want this');
insert into rtest_nothn4 values (20, 'want this');
insert into rtest_nothn4 values (29, 'want this');
insert into rtest_nothn4 values (30, 'don''t want this');
insert into rtest_nothn4 values (39, 'don''t want this');
insert into rtest_nothn4 values (40, 'want this');
insert into rtest_nothn4 values (50, 'want this');
insert into rtest_nothn4 values (60, 'want this');
insert into rtest_nothn1 select * from rtest_nothn4;
select * from rtest_nothn1;
 a  |     b     
----+-----------
  1 | want this
  2 | want this
 20 | want this
 29 | want this
 40 | want this
 50 | want this
 60 | want this
725 726
(7 rows)

727 728 729 730 731 732 733 734 735
delete from rtest_nothn4;
insert into rtest_nothn4 values (10, 'too small');
insert into rtest_nothn4 values (50, 'too small');
insert into rtest_nothn4 values (100, 'OK');
insert into rtest_nothn4 values (200, 'OK');
insert into rtest_nothn2 select * from rtest_nothn4;
select * from rtest_nothn2;
 a | b 
---+---
736 737
(0 rows)

738 739 740 741 742
select * from rtest_nothn3;
  a  | b  
-----+----
 100 | OK
 200 | OK
743 744
(2 rows)

745 746 747 748 749
create table rtest_view1 (a int4, b text, v bool);
create table rtest_view2 (a int4);
create table rtest_view3 (a int4, b text);
create table rtest_view4 (a int4, b text, c int4);
create view rtest_vview1 as select a, b from rtest_view1 X 
750
	where 0 < (select count(*) from rtest_view2 Y where Y.a = X.a);
751 752
create view rtest_vview2 as select a, b from rtest_view1 where v;
create view rtest_vview3 as select a, b from rtest_vview2 X
753
	where 0 < (select count(*) from rtest_view2 Y where Y.a = X.a);
754
create view rtest_vview4 as select X.a, X.b, count(Y.a) as refcount
755 756 757
	from rtest_view1 X, rtest_view2 Y
	where X.a = Y.a
	group by X.a, X.b;
758
create function rtest_viewfunc1(int4) returns int4 as
759
	'select count(*)::int4 from rtest_view2 where a = $1'
760
	language 'sql';
761
create view rtest_vview5 as select a, b, rtest_viewfunc1(a) as refcount
762
	from rtest_view1;
763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785
insert into rtest_view1 values (1, 'item 1', 't');
insert into rtest_view1 values (2, 'item 2', 't');
insert into rtest_view1 values (3, 'item 3', 't');
insert into rtest_view1 values (4, 'item 4', 'f');
insert into rtest_view1 values (5, 'item 5', 't');
insert into rtest_view1 values (6, 'item 6', 'f');
insert into rtest_view1 values (7, 'item 7', 't');
insert into rtest_view1 values (8, 'item 8', 't');
insert into rtest_view2 values (2);
insert into rtest_view2 values (2);
insert into rtest_view2 values (4);
insert into rtest_view2 values (5);
insert into rtest_view2 values (7);
insert into rtest_view2 values (7);
insert into rtest_view2 values (7);
insert into rtest_view2 values (7);
select * from rtest_vview1;
 a |   b    
---+--------
 2 | item 2
 4 | item 4
 5 | item 5
 7 | item 7
786 787
(4 rows)

788 789 790 791 792 793 794 795 796
select * from rtest_vview2;
 a |   b    
---+--------
 1 | item 1
 2 | item 2
 3 | item 3
 5 | item 5
 7 | item 7
 8 | item 8
797 798
(6 rows)

799 800 801 802 803 804
select * from rtest_vview3;
 a |   b    
---+--------
 2 | item 2
 5 | item 5
 7 | item 7
805 806
(3 rows)

807
select * from rtest_vview4 order by a, b;
808 809 810 811 812 813
 a |   b    | refcount 
---+--------+----------
 2 | item 2 |        2
 4 | item 4 |        1
 5 | item 5 |        1
 7 | item 7 |        4
814 815
(4 rows)

816 817 818 819 820 821 822 823 824 825 826
select * from rtest_vview5;
 a |   b    | refcount 
---+--------+----------
 1 | item 1 |        0
 2 | item 2 |        2
 3 | item 3 |        0
 4 | item 4 |        1
 5 | item 5 |        1
 6 | item 6 |        0
 7 | item 7 |        4
 8 | item 8 |        0
827 828
(8 rows)

829 830 831 832 833 834 835
insert into rtest_view3 select * from rtest_vview1 where a < 7;
select * from rtest_view3;
 a |   b    
---+--------
 2 | item 2
 4 | item 4
 5 | item 5
836 837
(3 rows)

838 839 840 841 842 843 844 845 846
delete from rtest_view3;
insert into rtest_view3 select * from rtest_vview2 where a != 5 and b !~ '2';
select * from rtest_view3;
 a |   b    
---+--------
 1 | item 1
 3 | item 3
 7 | item 7
 8 | item 8
847 848
(4 rows)

849 850 851 852 853 854 855 856
delete from rtest_view3;
insert into rtest_view3 select * from rtest_vview3;
select * from rtest_view3;
 a |   b    
---+--------
 2 | item 2
 5 | item 5
 7 | item 7
857 858
(3 rows)

859 860
delete from rtest_view3;
insert into rtest_view4 select * from rtest_vview4 where 3 > refcount;
861
select * from rtest_view4 order by a, b;
862 863 864 865 866
 a |   b    | c 
---+--------+---
 2 | item 2 | 2
 4 | item 4 | 1
 5 | item 5 | 1
867 868
(3 rows)

869 870
delete from rtest_view4;
insert into rtest_view4 select * from rtest_vview5 where a > 2 and refcount = 0;
871
select * from rtest_view4;
872 873 874 875 876
 a |   b    | c 
---+--------+---
 3 | item 3 | 0
 6 | item 6 | 0
 8 | item 8 | 0
877 878
(3 rows)

879 880 881 882 883
delete from rtest_view4;
--
-- Test for computations in views
--
create table rtest_comp (
884 885 886 887
	part	text,
	unit	char(4),
	size	float
);
888
create table rtest_unitfact (
889 890 891
	unit	char(4),
	factor	float
);
892
create view rtest_vcomp as 
893 894 895
	select X.part, (X.size * Y.factor) as size_in_cm
			from rtest_comp X, rtest_unitfact Y
			where X.unit = Y.unit;
896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 912 913
insert into rtest_unitfact values ('m', 100.0);
insert into rtest_unitfact values ('cm', 1.0);
insert into rtest_unitfact values ('inch', 2.54);
insert into rtest_comp values ('p1', 'm', 5.0);
insert into rtest_comp values ('p2', 'm', 3.0);
insert into rtest_comp values ('p3', 'cm', 5.0);
insert into rtest_comp values ('p4', 'cm', 15.0);
insert into rtest_comp values ('p5', 'inch', 7.0);
insert into rtest_comp values ('p6', 'inch', 4.4);
select * from rtest_vcomp order by part;
 part | size_in_cm 
------+------------
 p1   |        500
 p2   |        300
 p3   |          5
 p4   |         15
 p5   |      17.78
 p6   |     11.176
914 915
(6 rows)

916 917 918 919 920 921 922 923
select * from rtest_vcomp where size_in_cm > 10.0 order by size_in_cm using >;
 part | size_in_cm 
------+------------
 p1   |        500
 p2   |        300
 p5   |      17.78
 p4   |         15
 p6   |     11.176
924 925
(5 rows)

926 927 928 929 930 931 932 933 934 935 936
--
-- In addition run the (slightly modified) queries from the
-- programmers manual section on the rule system.
--
CREATE TABLE shoe_data (
	shoename   char(10),      -- primary key
	sh_avail   integer,       -- available # of pairs
	slcolor    char(10),      -- preferred shoelace color
	slminlen   float,         -- miminum shoelace length
	slmaxlen   float,         -- maximum shoelace length
	slunit     char(8)        -- length unit
937
);
938 939 940 941 942 943
CREATE TABLE shoelace_data (
	sl_name    char(10),      -- primary key
	sl_avail   integer,       -- available # of pairs
	sl_color   char(10),      -- shoelace color
	sl_len     float,         -- shoelace length
	sl_unit    char(8)        -- length unit
944
);
945 946 947
CREATE TABLE unit (
	un_name    char(8),       -- the primary key
	un_fact    float          -- factor to transform to cm
948
);
949
CREATE VIEW shoe AS
950 951 952 953 954 955 956 957 958 959
	SELECT sh.shoename,
		   sh.sh_avail,
		   sh.slcolor,
		   sh.slminlen,
		   sh.slminlen * un.un_fact AS slminlen_cm,
		   sh.slmaxlen,
		   sh.slmaxlen * un.un_fact AS slmaxlen_cm,
		   sh.slunit
	  FROM shoe_data sh, unit un
	 WHERE sh.slunit = un.un_name;
960
CREATE VIEW shoelace AS
961 962 963 964 965 966 967 968
	SELECT s.sl_name,
		   s.sl_avail,
		   s.sl_color,
		   s.sl_len,
		   s.sl_unit,
		   s.sl_len * u.un_fact AS sl_len_cm
	  FROM shoelace_data s, unit u
	 WHERE s.sl_unit = u.un_name;
969
CREATE VIEW shoe_ready AS
970 971 972 973 974 975 976 977 978
	SELECT rsh.shoename,
		   rsh.sh_avail,
		   rsl.sl_name,
		   rsl.sl_avail,
		   int4smaller(rsh.sh_avail, rsl.sl_avail) AS total_avail
	  FROM shoe rsh, shoelace rsl
	 WHERE rsl.sl_color = rsh.slcolor
	   AND rsl.sl_len_cm >= rsh.slminlen_cm
	   AND rsl.sl_len_cm <= rsh.slmaxlen_cm;
979 980 981 982 983 984 985 986 987 988 989 990 991 992 993 994 995 996 997 998 999 1000 1001 1002 1003 1004 1005
INSERT INTO unit VALUES ('cm', 1.0);
INSERT INTO unit VALUES ('m', 100.0);
INSERT INTO unit VALUES ('inch', 2.54);
INSERT INTO shoe_data VALUES ('sh1', 2, 'black', 70.0, 90.0, 'cm');
INSERT INTO shoe_data VALUES ('sh2', 0, 'black', 30.0, 40.0, 'inch');
INSERT INTO shoe_data VALUES ('sh3', 4, 'brown', 50.0, 65.0, 'cm');
INSERT INTO shoe_data VALUES ('sh4', 3, 'brown', 40.0, 50.0, 'inch');
INSERT INTO shoelace_data VALUES ('sl1', 5, 'black', 80.0, 'cm');
INSERT INTO shoelace_data VALUES ('sl2', 6, 'black', 100.0, 'cm');
INSERT INTO shoelace_data VALUES ('sl3', 0, 'black', 35.0 , 'inch');
INSERT INTO shoelace_data VALUES ('sl4', 8, 'black', 40.0 , 'inch');
INSERT INTO shoelace_data VALUES ('sl5', 4, 'brown', 1.0 , 'm');
INSERT INTO shoelace_data VALUES ('sl6', 0, 'brown', 0.9 , 'm');
INSERT INTO shoelace_data VALUES ('sl7', 7, 'brown', 60 , 'cm');
INSERT INTO shoelace_data VALUES ('sl8', 1, 'brown', 40 , 'inch');
-- SELECTs in doc
SELECT * FROM shoelace ORDER BY sl_name;
  sl_name   | sl_avail |  sl_color  | sl_len | sl_unit  | sl_len_cm 
------------+----------+------------+--------+----------+-----------
 sl1        |        5 | black      |     80 | cm       |        80
 sl2        |        6 | black      |    100 | cm       |       100
 sl3        |        0 | black      |     35 | inch     |      88.9
 sl4        |        8 | black      |     40 | inch     |     101.6
 sl5        |        4 | brown      |      1 | m        |       100
 sl6        |        0 | brown      |    0.9 | m        |        90
 sl7        |        7 | brown      |     60 | cm       |        60
 sl8        |        1 | brown      |     40 | inch     |     101.6
1006 1007
(8 rows)

1008
SELECT * FROM shoe_ready WHERE total_avail >= 2 ORDER BY 1;
1009 1010 1011 1012
  shoename  | sh_avail |  sl_name   | sl_avail | total_avail 
------------+----------+------------+----------+-------------
 sh1        |        2 | sl1        |        5 |           2
 sh3        |        4 | sl7        |        7 |           4
1013 1014
(2 rows)

1015 1016 1017 1018
    CREATE TABLE shoelace_log (
        sl_name    char(10),      -- shoelace changed
        sl_avail   integer,       -- new available value
        log_who    name,          -- who did it
1019
        log_when   timestamp      -- when
1020
    );
1021 1022 1023 1024
-- Want "log_who" to be CURRENT_USER,
-- but that is non-portable for the regression test
-- - thomas 1999-02-21
    CREATE RULE log_shoelace AS ON UPDATE TO shoelace_data
1025 1026 1027 1028
        WHERE NEW.sl_avail != OLD.sl_avail
        DO INSERT INTO shoelace_log VALUES (
                                        NEW.sl_name,
                                        NEW.sl_avail,
1029
                                        'Al Bundy',
1030
                                        'epoch'
1031
                                    );
1032 1033
UPDATE shoelace_data SET sl_avail = 6 WHERE  sl_name = 'sl7';
SELECT * FROM shoelace_log;
1034 1035 1036
  sl_name   | sl_avail | log_who  |         log_when         
------------+----------+----------+--------------------------
 sl7        |        6 | Al Bundy | Thu Jan 01 00:00:00 1970
1037 1038
(1 row)

1039
    CREATE RULE shoelace_ins AS ON INSERT TO shoelace
1040 1041 1042 1043 1044 1045 1046
        DO INSTEAD
        INSERT INTO shoelace_data VALUES (
               NEW.sl_name,
               NEW.sl_avail,
               NEW.sl_color,
               NEW.sl_len,
               NEW.sl_unit);
1047
    CREATE RULE shoelace_upd AS ON UPDATE TO shoelace
1048 1049 1050 1051 1052 1053 1054 1055
        DO INSTEAD
        UPDATE shoelace_data SET
               sl_name = NEW.sl_name,
               sl_avail = NEW.sl_avail,
               sl_color = NEW.sl_color,
               sl_len = NEW.sl_len,
               sl_unit = NEW.sl_unit
         WHERE sl_name = OLD.sl_name;
1056
    CREATE RULE shoelace_del AS ON DELETE TO shoelace
1057 1058 1059
        DO INSTEAD
        DELETE FROM shoelace_data
         WHERE sl_name = OLD.sl_name;
1060
    CREATE TABLE shoelace_arrive (
1061 1062 1063
        arr_name    char(10),
        arr_quant   integer
    );
1064
    CREATE TABLE shoelace_ok (
1065 1066 1067
        ok_name     char(10),
        ok_quant    integer
    );
1068
    CREATE RULE shoelace_ok_ins AS ON INSERT TO shoelace_ok
1069 1070 1071 1072
        DO INSTEAD
        UPDATE shoelace SET
               sl_avail = sl_avail + NEW.ok_quant
         WHERE sl_name = NEW.ok_name;
1073 1074 1075 1076 1077 1078 1079 1080 1081 1082 1083 1084 1085 1086
INSERT INTO shoelace_arrive VALUES ('sl3', 10);
INSERT INTO shoelace_arrive VALUES ('sl6', 20);
INSERT INTO shoelace_arrive VALUES ('sl8', 20);
SELECT * FROM shoelace ORDER BY sl_name;
  sl_name   | sl_avail |  sl_color  | sl_len | sl_unit  | sl_len_cm 
------------+----------+------------+--------+----------+-----------
 sl1        |        5 | black      |     80 | cm       |        80
 sl2        |        6 | black      |    100 | cm       |       100
 sl3        |        0 | black      |     35 | inch     |      88.9
 sl4        |        8 | black      |     40 | inch     |     101.6
 sl5        |        4 | brown      |      1 | m        |       100
 sl6        |        0 | brown      |    0.9 | m        |        90
 sl7        |        6 | brown      |     60 | cm       |        60
 sl8        |        1 | brown      |     40 | inch     |     101.6
1087 1088
(8 rows)

1089
insert into shoelace_ok select * from shoelace_arrive;
1090 1091 1092 1093 1094 1095 1096 1097 1098 1099 1100 1101 1102 1103
SELECT * FROM shoelace ORDER BY sl_name;
  sl_name   | sl_avail |  sl_color  | sl_len | sl_unit  | sl_len_cm 
------------+----------+------------+--------+----------+-----------
 sl1        |        5 | black      |     80 | cm       |        80
 sl2        |        6 | black      |    100 | cm       |       100
 sl3        |       10 | black      |     35 | inch     |      88.9
 sl4        |        8 | black      |     40 | inch     |     101.6
 sl5        |        4 | brown      |      1 | m        |       100
 sl6        |       20 | brown      |    0.9 | m        |        90
 sl7        |        6 | brown      |     60 | cm       |        60
 sl8        |       21 | brown      |     40 | inch     |     101.6
(8 rows)

SELECT * FROM shoelace_log ORDER BY sl_name;
1104 1105 1106 1107 1108 1109
  sl_name   | sl_avail | log_who  |         log_when         
------------+----------+----------+--------------------------
 sl3        |       10 | Al Bundy | Thu Jan 01 00:00:00 1970
 sl6        |       20 | Al Bundy | Thu Jan 01 00:00:00 1970
 sl7        |        6 | Al Bundy | Thu Jan 01 00:00:00 1970
 sl8        |       21 | Al Bundy | Thu Jan 01 00:00:00 1970
1110 1111 1112 1113 1114 1115 1116 1117 1118 1119 1120 1121 1122 1123 1124 1125 1126 1127 1128 1129 1130 1131 1132 1133 1134 1135 1136 1137 1138 1139 1140 1141 1142 1143 1144 1145 1146 1147 1148 1149 1150 1151 1152 1153 1154 1155 1156 1157 1158 1159 1160 1161 1162 1163 1164 1165 1166 1167 1168 1169 1170 1171 1172 1173 1174 1175 1176 1177 1178
(4 rows)

    CREATE VIEW shoelace_obsolete AS
	SELECT * FROM shoelace WHERE NOT EXISTS
	    (SELECT shoename FROM shoe WHERE slcolor = sl_color);
    CREATE VIEW shoelace_candelete AS
	SELECT * FROM shoelace_obsolete WHERE sl_avail = 0;
insert into shoelace values ('sl9', 0, 'pink', 35.0, 'inch', 0.0);
insert into shoelace values ('sl10', 1000, 'magenta', 40.0, 'inch', 0.0);
SELECT * FROM shoelace_obsolete;
  sl_name   | sl_avail |  sl_color  | sl_len | sl_unit  | sl_len_cm 
------------+----------+------------+--------+----------+-----------
 sl9        |        0 | pink       |     35 | inch     |      88.9
 sl10       |     1000 | magenta    |     40 | inch     |     101.6
(2 rows)

SELECT * FROM shoelace_candelete;
  sl_name   | sl_avail |  sl_color  | sl_len | sl_unit  | sl_len_cm 
------------+----------+------------+--------+----------+-----------
 sl9        |        0 | pink       |     35 | inch     |      88.9
(1 row)

DELETE FROM shoelace WHERE EXISTS
    (SELECT * FROM shoelace_candelete
             WHERE sl_name = shoelace.sl_name);
SELECT * FROM shoelace ORDER BY sl_name;
  sl_name   | sl_avail |  sl_color  | sl_len | sl_unit  | sl_len_cm 
------------+----------+------------+--------+----------+-----------
 sl1        |        5 | black      |     80 | cm       |        80
 sl10       |     1000 | magenta    |     40 | inch     |     101.6
 sl2        |        6 | black      |    100 | cm       |       100
 sl3        |       10 | black      |     35 | inch     |      88.9
 sl4        |        8 | black      |     40 | inch     |     101.6
 sl5        |        4 | brown      |      1 | m        |       100
 sl6        |       20 | brown      |    0.9 | m        |        90
 sl7        |        6 | brown      |     60 | cm       |        60
 sl8        |       21 | brown      |     40 | inch     |     101.6
(9 rows)

SELECT * FROM shoe ORDER BY shoename;
  shoename  | sh_avail |  slcolor   | slminlen | slminlen_cm | slmaxlen | slmaxlen_cm |  slunit  
------------+----------+------------+----------+-------------+----------+-------------+----------
 sh1        |        2 | black      |       70 |          70 |       90 |          90 | cm      
 sh2        |        0 | black      |       30 |        76.2 |       40 |       101.6 | inch    
 sh3        |        4 | brown      |       50 |          50 |       65 |          65 | cm      
 sh4        |        3 | brown      |       40 |       101.6 |       50 |         127 | inch    
(4 rows)

SELECT count(*) FROM shoe;
 count 
-------
     4
(1 row)

--
-- Simple test of qualified ON INSERT ... this did not work in 7.0 ...
--
create table foo (f1 int);
create table foo2 (f1 int);
create rule foorule as on insert to foo where f1 < 100
do instead nothing;
insert into foo values(1);
insert into foo values(1001);
select * from foo;
  f1  
------
 1001
(1 row)

1179
drop rule foorule on foo;
1180 1181 1182
-- this should fail because f1 is not exposed for unqualified reference:
create rule foorule as on insert to foo where f1 < 100
do instead insert into foo2 values (f1);
1183
ERROR:  Attribute "f1" not found
1184 1185 1186 1187 1188 1189 1190 1191 1192 1193 1194 1195 1196 1197 1198 1199 1200 1201
-- this is the correct way:
create rule foorule as on insert to foo where f1 < 100
do instead insert into foo2 values (new.f1);
insert into foo values(2);
insert into foo values(100);
select * from foo;
  f1  
------
 1001
  100
(2 rows)

select * from foo2;
 f1 
----
  2
(1 row)

1202
drop rule foorule on foo;
1203 1204 1205
drop table foo;
drop table foo2;
--
1206 1207 1208 1209 1210 1211 1212 1213 1214 1215 1216 1217 1218 1219 1220 1221 1222 1223 1224 1225 1226 1227 1228 1229 1230 1231 1232 1233 1234 1235 1236 1237 1238 1239 1240 1241 1242 1243 1244 1245 1246 1247 1248 1249 1250 1251 1252 1253 1254 1255 1256 1257 1258 1259 1260 1261
-- Test rules containing INSERT ... SELECT, which is a very ugly special
-- case as of 7.1.  Example is based on bug report from Joel Burton.
--
create table pparent (pid int, txt text);
insert into pparent values (1,'parent1');
insert into pparent values (2,'parent2');
create table cchild (pid int, descrip text);
insert into cchild values (1,'descrip1');
create view vview as
  select pparent.pid, txt, descrip from
    pparent left join cchild using (pid);
create rule rrule as
  on update to vview do instead
(
  insert into cchild (pid, descrip)
    select old.pid, new.descrip where old.descrip isnull; 
  update cchild set descrip = new.descrip where cchild.pid = old.pid;
);
select * from vview;
 pid |   txt   | descrip  
-----+---------+----------
   1 | parent1 | descrip1
   2 | parent2 | 
(2 rows)

update vview set descrip='test1' where pid=1;
select * from vview;
 pid |   txt   | descrip 
-----+---------+---------
   1 | parent1 | test1
   2 | parent2 | 
(2 rows)

update vview set descrip='test2' where pid=2;
select * from vview;
 pid |   txt   | descrip 
-----+---------+---------
   1 | parent1 | test1
   2 | parent2 | test2
(2 rows)

update vview set descrip='test3' where pid=3;
select * from vview;
 pid |   txt   | descrip 
-----+---------+---------
   1 | parent1 | test1
   2 | parent2 | test2
(2 rows)

select * from cchild;
 pid | descrip 
-----+---------
   1 | test1
   2 | test2
(2 rows)

1262
drop rule rrule on vview;
1263 1264 1265 1266
drop view vview;
drop table pparent;
drop table cchild;
--
1267 1268 1269
-- Check that ruleutils are working
--
SELECT viewname, definition FROM pg_views ORDER BY viewname;
1270 1271
         viewname         |                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                   definition                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    
--------------------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
1272
 iexit                    | SELECT ih.name, ih.thepath, interpt_pp(ih.thepath, r.thepath) AS exit FROM ihighway ih, ramp r WHERE (ih.thepath ## r.thepath);
1273
 pg_indexes               | SELECT n.nspname AS schemaname, c.relname AS tablename, i.relname AS indexname, pg_get_indexdef(i.oid) AS indexdef FROM (((pg_index x JOIN pg_class c ON ((c.oid = x.indrelid))) JOIN pg_class i ON ((i.oid = x.indexrelid))) LEFT JOIN pg_namespace n ON ((n.oid = c.relnamespace))) WHERE ((c.relkind = 'r'::"char") AND (i.relkind = 'i'::"char"));
1274
 pg_locks                 | SELECT l.relation, l."database", l."transaction", l.pid, l."mode", l.granted FROM pg_lock_status() l(relation oid, "database" oid, "transaction" xid, pid integer, "mode" text, granted boolean);
1275
 pg_rules                 | SELECT n.nspname AS schemaname, c.relname AS tablename, r.rulename, pg_get_ruledef(r.oid) AS definition FROM ((pg_rewrite r JOIN pg_class c ON ((c.oid = r.ev_class))) LEFT JOIN pg_namespace n ON ((n.oid = c.relnamespace))) WHERE (r.rulename <> '_RETURN'::name);
1276
 pg_settings              | SELECT a.name, a.setting FROM pg_show_all_settings() a(name text, setting text);
1277
 pg_stat_activity         | SELECT d.oid AS datid, d.datname, pg_stat_get_backend_pid(s.backendid) AS procpid, pg_stat_get_backend_userid(s.backendid) AS usesysid, u.usename, pg_stat_get_backend_activity(s.backendid) AS current_query FROM pg_database d, (SELECT pg_stat_get_backend_idset() AS backendid) s, pg_shadow u WHERE ((pg_stat_get_backend_dbid(s.backendid) = d.oid) AND (pg_stat_get_backend_userid(s.backendid) = (u.usesysid)::oid));
1278 1279
 pg_stat_all_indexes      | SELECT c.oid AS relid, i.oid AS indexrelid, n.nspname AS schemaname, c.relname, i.relname AS indexrelname, pg_stat_get_numscans(i.oid) AS idx_scan, pg_stat_get_tuples_returned(i.oid) AS idx_tup_read, pg_stat_get_tuples_fetched(i.oid) AS idx_tup_fetch FROM (((pg_class c JOIN pg_index x ON ((c.oid = x.indrelid))) JOIN pg_class i ON ((i.oid = x.indexrelid))) LEFT JOIN pg_namespace n ON ((n.oid = c.relnamespace))) WHERE (c.relkind = 'r'::"char");
 pg_stat_all_tables       | SELECT c.oid AS relid, n.nspname AS schemaname, c.relname, pg_stat_get_numscans(c.oid) AS seq_scan, pg_stat_get_tuples_returned(c.oid) AS seq_tup_read, sum(pg_stat_get_numscans(i.indexrelid)) AS idx_scan, sum(pg_stat_get_tuples_fetched(i.indexrelid)) AS idx_tup_fetch, pg_stat_get_tuples_inserted(c.oid) AS n_tup_ins, pg_stat_get_tuples_updated(c.oid) AS n_tup_upd, pg_stat_get_tuples_deleted(c.oid) AS n_tup_del FROM ((pg_class c LEFT JOIN pg_index i ON ((c.oid = i.indrelid))) LEFT JOIN pg_namespace n ON ((n.oid = c.relnamespace))) WHERE (c.relkind = 'r'::"char") GROUP BY c.oid, n.nspname, c.relname;
1280
 pg_stat_database         | SELECT d.oid AS datid, d.datname, pg_stat_get_db_numbackends(d.oid) AS numbackends, pg_stat_get_db_xact_commit(d.oid) AS xact_commit, pg_stat_get_db_xact_rollback(d.oid) AS xact_rollback, (pg_stat_get_db_blocks_fetched(d.oid) - pg_stat_get_db_blocks_hit(d.oid)) AS blks_read, pg_stat_get_db_blocks_hit(d.oid) AS blks_hit FROM pg_database d;
1281 1282 1283 1284 1285 1286 1287 1288 1289 1290 1291 1292 1293 1294 1295
 pg_stat_sys_indexes      | SELECT pg_stat_all_indexes.relid, pg_stat_all_indexes.indexrelid, pg_stat_all_indexes.schemaname, pg_stat_all_indexes.relname, pg_stat_all_indexes.indexrelname, pg_stat_all_indexes.idx_scan, pg_stat_all_indexes.idx_tup_read, pg_stat_all_indexes.idx_tup_fetch FROM pg_stat_all_indexes WHERE ((pg_stat_all_indexes.schemaname = 'pg_catalog'::name) OR (pg_stat_all_indexes.schemaname = 'pg_toast'::name));
 pg_stat_sys_tables       | SELECT pg_stat_all_tables.relid, pg_stat_all_tables.schemaname, pg_stat_all_tables.relname, pg_stat_all_tables.seq_scan, pg_stat_all_tables.seq_tup_read, pg_stat_all_tables.idx_scan, pg_stat_all_tables.idx_tup_fetch, pg_stat_all_tables.n_tup_ins, pg_stat_all_tables.n_tup_upd, pg_stat_all_tables.n_tup_del FROM pg_stat_all_tables WHERE ((pg_stat_all_tables.schemaname = 'pg_catalog'::name) OR (pg_stat_all_tables.schemaname = 'pg_toast'::name));
 pg_stat_user_indexes     | SELECT pg_stat_all_indexes.relid, pg_stat_all_indexes.indexrelid, pg_stat_all_indexes.schemaname, pg_stat_all_indexes.relname, pg_stat_all_indexes.indexrelname, pg_stat_all_indexes.idx_scan, pg_stat_all_indexes.idx_tup_read, pg_stat_all_indexes.idx_tup_fetch FROM pg_stat_all_indexes WHERE ((pg_stat_all_indexes.schemaname <> 'pg_catalog'::name) AND (pg_stat_all_indexes.schemaname <> 'pg_toast'::name));
 pg_stat_user_tables      | SELECT pg_stat_all_tables.relid, pg_stat_all_tables.schemaname, pg_stat_all_tables.relname, pg_stat_all_tables.seq_scan, pg_stat_all_tables.seq_tup_read, pg_stat_all_tables.idx_scan, pg_stat_all_tables.idx_tup_fetch, pg_stat_all_tables.n_tup_ins, pg_stat_all_tables.n_tup_upd, pg_stat_all_tables.n_tup_del FROM pg_stat_all_tables WHERE ((pg_stat_all_tables.schemaname <> 'pg_catalog'::name) AND (pg_stat_all_tables.schemaname <> 'pg_toast'::name));
 pg_statio_all_indexes    | SELECT c.oid AS relid, i.oid AS indexrelid, n.nspname AS schemaname, c.relname, i.relname AS indexrelname, (pg_stat_get_blocks_fetched(i.oid) - pg_stat_get_blocks_hit(i.oid)) AS idx_blks_read, pg_stat_get_blocks_hit(i.oid) AS idx_blks_hit FROM (((pg_class c JOIN pg_index x ON ((c.oid = x.indrelid))) JOIN pg_class i ON ((i.oid = x.indexrelid))) LEFT JOIN pg_namespace n ON ((n.oid = c.relnamespace))) WHERE (c.relkind = 'r'::"char");
 pg_statio_all_sequences  | SELECT c.oid AS relid, n.nspname AS schemaname, c.relname, (pg_stat_get_blocks_fetched(c.oid) - pg_stat_get_blocks_hit(c.oid)) AS blks_read, pg_stat_get_blocks_hit(c.oid) AS blks_hit FROM (pg_class c LEFT JOIN pg_namespace n ON ((n.oid = c.relnamespace))) WHERE (c.relkind = 'S'::"char");
 pg_statio_all_tables     | SELECT c.oid AS relid, n.nspname AS schemaname, c.relname, (pg_stat_get_blocks_fetched(c.oid) - pg_stat_get_blocks_hit(c.oid)) AS heap_blks_read, pg_stat_get_blocks_hit(c.oid) AS heap_blks_hit, sum((pg_stat_get_blocks_fetched(i.indexrelid) - pg_stat_get_blocks_hit(i.indexrelid))) AS idx_blks_read, sum(pg_stat_get_blocks_hit(i.indexrelid)) AS idx_blks_hit, (pg_stat_get_blocks_fetched(t.oid) - pg_stat_get_blocks_hit(t.oid)) AS toast_blks_read, pg_stat_get_blocks_hit(t.oid) AS toast_blks_hit, (pg_stat_get_blocks_fetched(x.oid) - pg_stat_get_blocks_hit(x.oid)) AS tidx_blks_read, pg_stat_get_blocks_hit(x.oid) AS tidx_blks_hit FROM ((((pg_class c LEFT JOIN pg_index i ON ((c.oid = i.indrelid))) LEFT JOIN pg_class t ON ((c.reltoastrelid = t.oid))) LEFT JOIN pg_class x ON ((t.reltoastidxid = x.oid))) LEFT JOIN pg_namespace n ON ((n.oid = c.relnamespace))) WHERE (c.relkind = 'r'::"char") GROUP BY c.oid, n.nspname, c.relname, t.oid, x.oid;
 pg_statio_sys_indexes    | SELECT pg_statio_all_indexes.relid, pg_statio_all_indexes.indexrelid, pg_statio_all_indexes.schemaname, pg_statio_all_indexes.relname, pg_statio_all_indexes.indexrelname, pg_statio_all_indexes.idx_blks_read, pg_statio_all_indexes.idx_blks_hit FROM pg_statio_all_indexes WHERE ((pg_statio_all_indexes.schemaname = 'pg_catalog'::name) OR (pg_statio_all_indexes.schemaname = 'pg_toast'::name));
 pg_statio_sys_sequences  | SELECT pg_statio_all_sequences.relid, pg_statio_all_sequences.schemaname, pg_statio_all_sequences.relname, pg_statio_all_sequences.blks_read, pg_statio_all_sequences.blks_hit FROM pg_statio_all_sequences WHERE ((pg_statio_all_sequences.schemaname = 'pg_catalog'::name) OR (pg_statio_all_sequences.schemaname = 'pg_toast'::name));
 pg_statio_sys_tables     | SELECT pg_statio_all_tables.relid, pg_statio_all_tables.schemaname, pg_statio_all_tables.relname, pg_statio_all_tables.heap_blks_read, pg_statio_all_tables.heap_blks_hit, pg_statio_all_tables.idx_blks_read, pg_statio_all_tables.idx_blks_hit, pg_statio_all_tables.toast_blks_read, pg_statio_all_tables.toast_blks_hit, pg_statio_all_tables.tidx_blks_read, pg_statio_all_tables.tidx_blks_hit FROM pg_statio_all_tables WHERE ((pg_statio_all_tables.schemaname = 'pg_catalog'::name) OR (pg_statio_all_tables.schemaname = 'pg_toast'::name));
 pg_statio_user_indexes   | SELECT pg_statio_all_indexes.relid, pg_statio_all_indexes.indexrelid, pg_statio_all_indexes.schemaname, pg_statio_all_indexes.relname, pg_statio_all_indexes.indexrelname, pg_statio_all_indexes.idx_blks_read, pg_statio_all_indexes.idx_blks_hit FROM pg_statio_all_indexes WHERE ((pg_statio_all_indexes.schemaname <> 'pg_catalog'::name) AND (pg_statio_all_indexes.schemaname <> 'pg_toast'::name));
 pg_statio_user_sequences | SELECT pg_statio_all_sequences.relid, pg_statio_all_sequences.schemaname, pg_statio_all_sequences.relname, pg_statio_all_sequences.blks_read, pg_statio_all_sequences.blks_hit FROM pg_statio_all_sequences WHERE ((pg_statio_all_sequences.schemaname <> 'pg_catalog'::name) AND (pg_statio_all_sequences.schemaname <> 'pg_toast'::name));
 pg_statio_user_tables    | SELECT pg_statio_all_tables.relid, pg_statio_all_tables.schemaname, pg_statio_all_tables.relname, pg_statio_all_tables.heap_blks_read, pg_statio_all_tables.heap_blks_hit, pg_statio_all_tables.idx_blks_read, pg_statio_all_tables.idx_blks_hit, pg_statio_all_tables.toast_blks_read, pg_statio_all_tables.toast_blks_hit, pg_statio_all_tables.tidx_blks_read, pg_statio_all_tables.tidx_blks_hit FROM pg_statio_all_tables WHERE ((pg_statio_all_tables.schemaname <> 'pg_catalog'::name) AND (pg_statio_all_tables.schemaname <> 'pg_toast'::name));
 pg_stats                 | SELECT nspname AS schemaname, relname AS tablename, attname, stanullfrac AS null_frac, stawidth AS avg_width, stadistinct AS n_distinct, CASE WHEN (1 = stakind1) THEN stavalues1 WHEN (1 = stakind2) THEN stavalues2 WHEN (1 = stakind3) THEN stavalues3 WHEN (1 = stakind4) THEN stavalues4 ELSE NULL::text[] END AS most_common_vals, CASE WHEN (1 = stakind1) THEN stanumbers1 WHEN (1 = stakind2) THEN stanumbers2 WHEN (1 = stakind3) THEN stanumbers3 WHEN (1 = stakind4) THEN stanumbers4 ELSE NULL::real[] END AS most_common_freqs, CASE WHEN (2 = stakind1) THEN stavalues1 WHEN (2 = stakind2) THEN stavalues2 WHEN (2 = stakind3) THEN stavalues3 WHEN (2 = stakind4) THEN stavalues4 ELSE NULL::text[] END AS histogram_bounds, CASE WHEN (3 = stakind1) THEN stanumbers1[1] WHEN (3 = stakind2) THEN stanumbers2[1] WHEN (3 = stakind3) THEN stanumbers3[1] WHEN (3 = stakind4) THEN stanumbers4[1] ELSE NULL::real END AS correlation FROM (((pg_statistic s JOIN pg_class c ON ((c.oid = s.starelid))) JOIN pg_attribute a ON (((c.oid = a.attrelid) AND (a.attnum = s.staattnum)))) LEFT JOIN pg_namespace n ON ((n.oid = c.relnamespace))) WHERE has_table_privilege(c.oid, 'select'::text);
 pg_tables                | SELECT n.nspname AS schemaname, c.relname AS tablename, pg_get_userbyid(c.relowner) AS tableowner, c.relhasindex AS hasindexes, c.relhasrules AS hasrules, (c.reltriggers > 0) AS hastriggers FROM (pg_class c LEFT JOIN pg_namespace n ON ((n.oid = c.relnamespace))) WHERE ((c.relkind = 'r'::"char") OR (c.relkind = 's'::"char"));
1296
 pg_user                  | SELECT pg_shadow.usename, pg_shadow.usesysid, pg_shadow.usecreatedb, pg_shadow.usesuper, pg_shadow.usecatupd, '********'::text AS passwd, pg_shadow.valuntil, pg_shadow.useconfig FROM pg_shadow;
1297
 pg_views                 | SELECT n.nspname AS schemaname, c.relname AS viewname, pg_get_userbyid(c.relowner) AS viewowner, pg_get_viewdef(c.oid) AS definition FROM (pg_class c LEFT JOIN pg_namespace n ON ((n.oid = c.relnamespace))) WHERE (c.relkind = 'v'::"char");
1298 1299 1300 1301 1302 1303 1304 1305 1306 1307 1308 1309 1310 1311
 rtest_v1                 | SELECT rtest_t1.a, rtest_t1.b FROM rtest_t1;
 rtest_vcomp              | SELECT x.part, (x.size * y.factor) AS size_in_cm FROM rtest_comp x, rtest_unitfact y WHERE (x.unit = y.unit);
 rtest_vview1             | SELECT x.a, x.b FROM rtest_view1 x WHERE (0 < (SELECT count(*) AS count FROM rtest_view2 y WHERE (y.a = x.a)));
 rtest_vview2             | SELECT rtest_view1.a, rtest_view1.b FROM rtest_view1 WHERE rtest_view1.v;
 rtest_vview3             | SELECT x.a, x.b FROM rtest_vview2 x WHERE (0 < (SELECT count(*) AS count FROM rtest_view2 y WHERE (y.a = x.a)));
 rtest_vview4             | SELECT x.a, x.b, count(y.a) AS refcount FROM rtest_view1 x, rtest_view2 y WHERE (x.a = y.a) GROUP BY x.a, x.b;
 rtest_vview5             | SELECT rtest_view1.a, rtest_view1.b, rtest_viewfunc1(rtest_view1.a) AS refcount FROM rtest_view1;
 shoe                     | SELECT sh.shoename, sh.sh_avail, sh.slcolor, sh.slminlen, (sh.slminlen * un.un_fact) AS slminlen_cm, sh.slmaxlen, (sh.slmaxlen * un.un_fact) AS slmaxlen_cm, sh.slunit FROM shoe_data sh, unit un WHERE (sh.slunit = un.un_name);
 shoe_ready               | SELECT rsh.shoename, rsh.sh_avail, rsl.sl_name, rsl.sl_avail, int4smaller(rsh.sh_avail, rsl.sl_avail) AS total_avail FROM shoe rsh, shoelace rsl WHERE (((rsl.sl_color = rsh.slcolor) AND (rsl.sl_len_cm >= rsh.slminlen_cm)) AND (rsl.sl_len_cm <= rsh.slmaxlen_cm));
 shoelace                 | SELECT s.sl_name, s.sl_avail, s.sl_color, s.sl_len, s.sl_unit, (s.sl_len * u.un_fact) AS sl_len_cm FROM shoelace_data s, unit u WHERE (s.sl_unit = u.un_name);
 shoelace_candelete       | SELECT shoelace_obsolete.sl_name, shoelace_obsolete.sl_avail, shoelace_obsolete.sl_color, shoelace_obsolete.sl_len, shoelace_obsolete.sl_unit, shoelace_obsolete.sl_len_cm FROM shoelace_obsolete WHERE (shoelace_obsolete.sl_avail = 0);
 shoelace_obsolete        | SELECT shoelace.sl_name, shoelace.sl_avail, shoelace.sl_color, shoelace.sl_len, shoelace.sl_unit, shoelace.sl_len_cm FROM shoelace WHERE (NOT (EXISTS (SELECT shoe.shoename FROM shoe WHERE (shoe.slcolor = shoelace.sl_color))));
 street                   | SELECT r.name, r.thepath, c.cname FROM ONLY road r, real_city c WHERE (c.outline ## r.thepath);
 toyemp                   | SELECT emp.name, emp.age, emp."location", (12 * emp.salary) AS annualsal FROM emp;
1312
(40 rows)
1313 1314 1315

SELECT tablename, rulename, definition FROM pg_rules 
	ORDER BY tablename, rulename;
1316 1317
   tablename   |    rulename     |                                                                                                                                  definition                                                                                                                                   
---------------+-----------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
1318
 pg_settings   | pg_settings_n   | CREATE RULE pg_settings_n AS ON UPDATE TO pg_settings DO INSTEAD NOTHING;
1319
 pg_settings   | pg_settings_u   | CREATE RULE pg_settings_u AS ON UPDATE TO pg_settings WHERE (new.name = old.name) DO SELECT set_config(old.name, new.setting, false) AS set_config;
1320 1321 1322
 rtest_emp     | rtest_emp_del   | CREATE RULE rtest_emp_del AS ON DELETE TO rtest_emp DO INSERT INTO rtest_emplog (ename, who, "action", newsal, oldsal) VALUES (old.ename, "current_user"(), 'fired     '::bpchar, '$0.00'::money, old.salary);
 rtest_emp     | rtest_emp_ins   | CREATE RULE rtest_emp_ins AS ON INSERT TO rtest_emp DO INSERT INTO rtest_emplog (ename, who, "action", newsal, oldsal) VALUES (new.ename, "current_user"(), 'hired     '::bpchar, new.salary, '$0.00'::money);
 rtest_emp     | rtest_emp_upd   | CREATE RULE rtest_emp_upd AS ON UPDATE TO rtest_emp WHERE (new.salary <> old.salary) DO INSERT INTO rtest_emplog (ename, who, "action", newsal, oldsal) VALUES (new.ename, "current_user"(), 'honored   '::bpchar, new.salary, old.salary);
1323
 rtest_nothn1  | rtest_nothn_r1  | CREATE RULE rtest_nothn_r1 AS ON INSERT TO rtest_nothn1 WHERE ((new.a >= 10) AND (new.a < 20)) DO INSTEAD NOTHING;
1324 1325 1326
 rtest_nothn1  | rtest_nothn_r2  | CREATE RULE rtest_nothn_r2 AS ON INSERT TO rtest_nothn1 WHERE ((new.a >= 30) AND (new.a < 40)) DO INSTEAD NOTHING;
 rtest_nothn2  | rtest_nothn_r3  | CREATE RULE rtest_nothn_r3 AS ON INSERT TO rtest_nothn2 WHERE (new.a >= 100) DO INSTEAD INSERT INTO rtest_nothn3 (a, b) VALUES (new.a, new.b);
 rtest_nothn2  | rtest_nothn_r4  | CREATE RULE rtest_nothn_r4 AS ON INSERT TO rtest_nothn2 DO INSTEAD NOTHING;
1327 1328 1329 1330
 rtest_order1  | rtest_order_r1  | CREATE RULE rtest_order_r1 AS ON INSERT TO rtest_order1 DO INSTEAD INSERT INTO rtest_order2 (a, b, c) VALUES (new.a, nextval('rtest_seq'::text), 'rule 1 - this should run 1st'::text);
 rtest_order1  | rtest_order_r2  | CREATE RULE rtest_order_r2 AS ON INSERT TO rtest_order1 DO INSERT INTO rtest_order2 (a, b, c) VALUES (new.a, nextval('rtest_seq'::text), 'rule 2 - this should run 2nd'::text);
 rtest_order1  | rtest_order_r3  | CREATE RULE rtest_order_r3 AS ON INSERT TO rtest_order1 DO INSTEAD INSERT INTO rtest_order2 (a, b, c) VALUES (new.a, nextval('rtest_seq'::text), 'rule 3 - this should run 3rd'::text);
 rtest_order1  | rtest_order_r4  | CREATE RULE rtest_order_r4 AS ON INSERT TO rtest_order1 WHERE (new.a < 100) DO INSTEAD INSERT INTO rtest_order2 (a, b, c) VALUES (new.a, nextval('rtest_seq'::text), 'rule 4 - this should run 4th'::text);
1331 1332 1333 1334 1335 1336 1337 1338 1339 1340 1341 1342 1343 1344
 rtest_person  | rtest_pers_del  | CREATE RULE rtest_pers_del AS ON DELETE TO rtest_person DO DELETE FROM rtest_admin WHERE (rtest_admin.pname = old.pname);
 rtest_person  | rtest_pers_upd  | CREATE RULE rtest_pers_upd AS ON UPDATE TO rtest_person DO UPDATE rtest_admin SET pname = new.pname WHERE (rtest_admin.pname = old.pname);
 rtest_system  | rtest_sys_del   | CREATE RULE rtest_sys_del AS ON DELETE TO rtest_system DO (DELETE FROM rtest_interface WHERE (rtest_interface.sysname = old.sysname); DELETE FROM rtest_admin WHERE (rtest_admin.sysname = old.sysname); );
 rtest_system  | rtest_sys_upd   | CREATE RULE rtest_sys_upd AS ON UPDATE TO rtest_system DO (UPDATE rtest_interface SET sysname = new.sysname WHERE (rtest_interface.sysname = old.sysname); UPDATE rtest_admin SET sysname = new.sysname WHERE (rtest_admin.sysname = old.sysname); );
 rtest_t4      | rtest_t4_ins1   | CREATE RULE rtest_t4_ins1 AS ON INSERT TO rtest_t4 WHERE ((new.a >= 10) AND (new.a < 20)) DO INSTEAD INSERT INTO rtest_t5 (a, b) VALUES (new.a, new.b);
 rtest_t4      | rtest_t4_ins2   | CREATE RULE rtest_t4_ins2 AS ON INSERT TO rtest_t4 WHERE ((new.a >= 20) AND (new.a < 30)) DO INSERT INTO rtest_t6 (a, b) VALUES (new.a, new.b);
 rtest_t5      | rtest_t5_ins    | CREATE RULE rtest_t5_ins AS ON INSERT TO rtest_t5 WHERE (new.a > 15) DO INSERT INTO rtest_t7 (a, b) VALUES (new.a, new.b);
 rtest_t6      | rtest_t6_ins    | CREATE RULE rtest_t6_ins AS ON INSERT TO rtest_t6 WHERE (new.a > 25) DO INSTEAD INSERT INTO rtest_t8 (a, b) VALUES (new.a, new.b);
 rtest_v1      | rtest_v1_del    | CREATE RULE rtest_v1_del AS ON DELETE TO rtest_v1 DO INSTEAD DELETE FROM rtest_t1 WHERE (rtest_t1.a = old.a);
 rtest_v1      | rtest_v1_ins    | CREATE RULE rtest_v1_ins AS ON INSERT TO rtest_v1 DO INSTEAD INSERT INTO rtest_t1 (a, b) VALUES (new.a, new.b);
 rtest_v1      | rtest_v1_upd    | CREATE RULE rtest_v1_upd AS ON UPDATE TO rtest_v1 DO INSTEAD UPDATE rtest_t1 SET a = new.a, b = new.b WHERE (rtest_t1.a = old.a);
 shoelace      | shoelace_del    | CREATE RULE shoelace_del AS ON DELETE TO shoelace DO INSTEAD DELETE FROM shoelace_data WHERE (shoelace_data.sl_name = old.sl_name);
 shoelace      | shoelace_ins    | CREATE RULE shoelace_ins AS ON INSERT TO shoelace DO INSTEAD INSERT INTO shoelace_data (sl_name, sl_avail, sl_color, sl_len, sl_unit) VALUES (new.sl_name, new.sl_avail, new.sl_color, new.sl_len, new.sl_unit);
 shoelace      | shoelace_upd    | CREATE RULE shoelace_upd AS ON UPDATE TO shoelace DO INSTEAD UPDATE shoelace_data SET sl_name = new.sl_name, sl_avail = new.sl_avail, sl_color = new.sl_color, sl_len = new.sl_len, sl_unit = new.sl_unit WHERE (shoelace_data.sl_name = old.sl_name);
1345
 shoelace_data | log_shoelace    | CREATE RULE log_shoelace AS ON UPDATE TO shoelace_data WHERE (new.sl_avail <> old.sl_avail) DO INSERT INTO shoelace_log (sl_name, sl_avail, log_who, log_when) VALUES (new.sl_name, new.sl_avail, 'Al Bundy'::name, 'Thu Jan 01 00:00:00 1970'::timestamp without time zone);
1346
 shoelace_ok   | shoelace_ok_ins | CREATE RULE shoelace_ok_ins AS ON INSERT TO shoelace_ok DO INSTEAD UPDATE shoelace SET sl_avail = (shoelace.sl_avail + new.ok_quant) WHERE (shoelace.sl_name = new.ok_name);
1347
(29 rows)
1348

1349 1350 1351 1352 1353 1354 1355 1356 1357 1358 1359 1360 1361 1362 1363 1364 1365 1366
--
-- CREATE OR REPLACE RULE
--
CREATE TABLE ruletest_tbl (a int, b int);
CREATE TABLE ruletest_tbl2 (a int, b int);
CREATE OR REPLACE RULE myrule AS ON INSERT TO ruletest_tbl
	DO INSTEAD INSERT INTO ruletest_tbl2 VALUES (10, 10);
INSERT INTO ruletest_tbl VALUES (99, 99);
CREATE OR REPLACE RULE myrule AS ON INSERT TO ruletest_tbl
	DO INSTEAD INSERT INTO ruletest_tbl2 VALUES (1000, 1000);
INSERT INTO ruletest_tbl VALUES (99, 99);
SELECT * FROM ruletest_tbl2;
  a   |  b   
------+------
   10 |   10
 1000 | 1000
(2 rows)