We have verified this problem under both 7.3.2 and the CVS tip. The attached example is far simpler than the actual code in our application, but may nevertheless benefit from some explanation. We have several tables with two ON INSERT rules:
[TABLE policy_accounts] | | ON INSERT V RULE executor_active <- [TABLE accounts_on_hold] | V [TABLE policy_accounts_active] | | ON INSERT V RULE executor_hamlet <- [TABLE policy_hamlet_atoms] | V [TABLE account_instances] The accounts_on_hold lists user accounts for which no changes or updates should currently be made; so the the executor_active rule copies new rows from policy_accounts to policy_accounts_active only for accounts which are not listed in accounts_on_hold. Our system manages computer accounts across a university campus. Since a given account might exist on several machines, we have given the name `account instance' to the idea of an account on a particular system - so if the account `tgl' were given access to both a Linux interactive machine and a web email server, we would say that two `instances' of the account currently existed. The policy_hamlet_atoms table lists, for each policy, which systems the policy grants access to. So when a new row appears in policy_accounts_active, linking an account to a new policy, the executor_hamlet rule examines the policy_hamlet_atoms table and creates any new account_instances that are necessary. (Thus hamlet decides which account instances are to be, or not to be.) Our problem is that if we add a NOT IN clause to the executor_active rule to prevent duplicate inserts into the policy_accounts_active table, then the executor_hamlet rule will not fire for rows inserted by the executor_active rule. While we are beginning to learn how to read parse trees, we are not yet proficient enough to see what is going on here. Two test cases are attached. The `broken' test case has the NOT IN clause, and incorrectly does *not* create an account_instances row when executor_active does an INSERT to policy_accounts_active. The test code then goes on to delete and re-insert the row by hand, showing that executor_hamlet *will* fire if the INSERT to policy_accounts_active is not done through executor_active. The `working' test case omits the AND (account, policy) NOT IN (SELECT account, policy FROM policy_accounts_active) condition from the end of executor_active, which magically makes the executor_hamlet rule start firing as it should. Any help or correction of our techniques will be appreciated!
test-broken.sql
Description: Binary data
test-working.sql
Description: Binary data
-- Brandon Craig Rhodes http://www.rhodesmill.org/brandon Georgia Tech [EMAIL PROTECTED]
---------------------------(end of broadcast)--------------------------- TIP 6: Have you searched our list archives? http://archives.postgresql.org