473,386 Members | 1,733 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,386 software developers and data experts.

insert rule not firing on insert with exists subselect

Hello all,

We have run into what appears to be a problem with rules and subselects in
postgres 7.4.1. We have boiled it down to the following test case. If
anyone has any thoughts as to why this would be happening, we would
appreciate feedback.

We have tested on 7.3.4, 7.3.6 and 7.4.1 and all exhibit the same behavior.
Test case one tries to populate table2 from table1 with records that are not
in table2 already. Table2 gets populated correctly, but table3 does not as
one would expect with the rule on table2.

The second test case creates a temporary table to hold the values in table2
and the same statement is run to populate table2 except the exists statement
runs off of the temp table. This works as expected. The values get inserted
into table2 and table3.

As a side note, we rewrote this test case with a trigger and that worked as
expected. Due to the complication of replacing a large number of rules, we
are hoping there is an answer as to why this is not working that is simpler
the rewriting as triggers.

Thanks,

-Chris

-- test case 1 - with exists subselect on same table
-- Fails to insert items into table3
-- cleanup
drop table table1;
drop table table2;
drop table table3;

-- set up stuff
create table table1 (col1 int);
create table table2 (col1 int);
create table table3 (col1 int);
insert into table1 (col1) values (1);
insert into table1 (col1) values (2);
insert into table1 (col1) values (3);
insert into table1 (col1) values (3);
insert into table1 (col1) values (4);
insert into table1 (col1) values (4);
insert into table1 (col1) values (4);
insert into table1 (col1) values (5);
create rule mycopyrule as on insert to table2 do insert into table3 (col1)
values (new.col1);

-- failing test
insert into table2 (col1) values (4); -- works
select count(*) from table3;
insert into table2 (col1) select col1 from table1 where not exists (select 1
from table2 where table2.col1 = table1.col1); -- doesn't work
select count(*) from table3; -- Should be 6, shows 1

-- test case 2 - w/o exists subselect on same table
-- Inserts records from table2 into table3
-- cleanup
drop table table1;
drop table table2;
drop table table2_hold;
drop table table3;

-- set up stuff
create table table1 (col1 int);
create table table2 (col1 int);
create table table3 (col1 int);
insert into table1 (col1) values (1);
insert into table1 (col1) values (2);
insert into table1 (col1) values (3);
insert into table1 (col1) values (3);
insert into table1 (col1) values (4);
insert into table1 (col1) values (4);
insert into table1 (col1) values (4);
insert into table1 (col1) values (5);
create rule mycopyrule as on insert to table2 do insert into table3 (col1)
values (new.col1);

-- passing test
insert into table2 (col1) values (4); -- works
select count(*) from table3;
create temp table table2_hold as select * from table2;
insert into table2 (col1) select col1 from table1 where not exists (select 1
from table2_hold where table2_hold.col1 = table1.col1);
select count(*) from table3; -- Shows 6 as expected
--
Chris Kratz
Systems Analyst/Programmer
VistaShare LLC

---------------------------(end of broadcast)---------------------------
TIP 8: explain analyze is your friend

Nov 23 '05 #1
4 5461
Chris Kratz <ch*********@vistashare.com> writes:
create rule mycopyrule as on insert to table2 do insert into table3 (col1)
values (new.col1); insert into table2 (col1) select col1 from table1 where not exists (select 1
from table2 where table2.col1 = table1.col1); -- doesn't work


The rule-generated query executes after the original INSERT, and can see
its results. So by the time the rule fires, there *is* an entry in
table2 matching the table1 value, and of course the EXISTS condition
fails.

Rules are not triggers and make poor substitutes for them. You're going
to need to use a trigger for this...

regards, tom lane

---------------------------(end of broadcast)---------------------------
TIP 7: don't forget to increase your free space map settings

Nov 23 '05 #2
Thanks Tom for your quick response.

At the risk of sounding really stupid, how can this be the case? The rule is
simply on an insert into table2, insert an additional record in table3. The
subselect on the actual insert is the one using the exists clause and is
working correctly (as far as inserting the records). The records are being
inserted into table2 as expected. But the rule which should have fired for
each insert doesn't happen and table3 is empty.

What am I missing?

-Chris

On Tuesday 13 April 2004 4:40 pm, Tom Lane wrote:
Chris Kratz <ch*********@vistashare.com> writes:
create rule mycopyrule as on insert to table2 do insert into table3
(col1) values (new.col1);

insert into table2 (col1) select col1 from table1 where not exists
(select 1 from table2 where table2.col1 = table1.col1); -- doesn't work


The rule-generated query executes after the original INSERT, and can see
its results. So by the time the rule fires, there *is* an entry in
table2 matching the table1 value, and of course the EXISTS condition
fails.

Rules are not triggers and make poor substitutes for them. You're going
to need to use a trigger for this...

regards, tom lane


--
Chris Kratz
Systems Analyst/Programmer
VistaShare LLC
www.vistashare.com

---------------------------(end of broadcast)---------------------------
TIP 9: the planner will ignore your desire to choose an index scan if your
joining column's datatypes do not match

Nov 23 '05 #3
Chris Kratz <ch*********@vistashare.com> writes:
What am I missing?


You're thinking that the rule is a trigger. It's not. It's a query
transformation mechanism that adds a new query to be executed after your
INSERT. What actually gets executed is effectively

Original query:

insert into table2 (col1) select col1 from table1 where not exists
(select 1 from table2 where table2.col1 = table1.col1);

Query added by rule:

insert into table3 (col1)
select col1 from table1 where not exists
(select 1 from table2 where table2.col1 = table1.col1);

By the time the second query begins, there *is* a table2 row matching
every row in table1, because you just got done inserting ones to match
any that didn't have a match. So in the second query, the EXISTS test
succeeds at every row of table1 and no rows are produced to insert into
table3.

This could be made to work if the order of the queries were reversed,
but that isn't going to happen because it would break other uses of
ON INSERT rules that need to be able to see the inserted row(s).
So AFAICS you're gonna have to use a trigger.

regards, tom lane

---------------------------(end of broadcast)---------------------------
TIP 6: Have you searched our list archives?

http://archives.postgresql.org

Nov 23 '05 #4
OK, that makes sense. I guess we will be implementing some triggers.

Thanks,

-Chris

On Tuesday 13 April 2004 5:13 pm, Tom Lane wrote:
Chris Kratz <ch*********@vistashare.com> writes:
What am I missing?


You're thinking that the rule is a trigger. It's not. It's a query
transformation mechanism that adds a new query to be executed after your
INSERT. What actually gets executed is effectively

Original query:

insert into table2 (col1) select col1 from table1 where not exists
(select 1 from table2 where table2.col1 = table1.col1);

Query added by rule:

insert into table3 (col1)
select col1 from table1 where not exists
(select 1 from table2 where table2.col1 = table1.col1);

By the time the second query begins, there *is* a table2 row matching
every row in table1, because you just got done inserting ones to match
any that didn't have a match. So in the second query, the EXISTS test
succeeds at every row of table1 and no rows are produced to insert into
table3.

This could be made to work if the order of the queries were reversed,
but that isn't going to happen because it would break other uses of
ON INSERT rules that need to be able to see the inserted row(s).
So AFAICS you're gonna have to use a trigger.

regards, tom lane


--
Chris Kratz
Systems Analyst/Programmer
VistaShare LLC
www.vistashare.com

---------------------------(end of broadcast)---------------------------
TIP 7: don't forget to increase your free space map settings

Nov 23 '05 #5

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

4
by: lawrence | last post by:
Google can't find me a good example of how to use the "if exists" syntax in MySql. Is it right that to use it this way: INSERT INTO IF EXISTS tMyTable VALUES("xxlk", "lkjlkjlkjljk") I want...
2
by: Ford Desperado | last post by:
I've been reading the docs and playing around, but I'm still not getting the difference. For instance, create table a(i int check(i>0)) create table a_src(i int) go create unique index ai on...
10
by: smorrey | last post by:
Hello all, I am writing an app in PHP that uses a PostGres database. One thing i have noticed is that what should/could be a single line of SQL code takes about 6 lines of PHP. This seem...
0
by: jtocci | last post by:
I'm having a big problem with CREATE RULE...ON INSERT...INSERT INTO...SELECT...FROM...WHERE when I want to INSERT several (20~50) records based on a single INSERT to a view. Either I get a 'too...
1
by: gmccallum | last post by:
I would have expected to be able to find this easily, but I couldn't. I am using the TableAdapter.Insert command to insert a record. I would like to then get an ID field from that record after...
15
by: dataguy | last post by:
I am trying to insert into a temporary table but only the first n number of rows. I thought I could use the combination of insert into and fect first row command ,but it won't work. Does anyone...
1
by: abhi81 | last post by:
Hello All, I have a table on which I have created a insert,Update and a Delete trigger. All these triggers write a entry to another audit table with the unique key for each table and the timestamp....
0
by: magnolia | last post by:
i created a trigger that will record the changes made to a table .everything works fine except the insert query.whenerever i try to insert a record it fires insert and update triger at the same time...
2
by: lenygold via DBMonster.com | last post by:
Hi Everebody: I have a table: CREATE TABLE CROSS_REFERENCE (ROW# INTEGER NOT NULL ,KEY_WORD CHAR(16) NOT NULL ,QUERY_DESCR VARCHAR(330) NOT NULL ,PRIMARY KEY (ROW#,KEY_WORD)); It is a...
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
0
by: aa123db | last post by:
Variable and constants Use var or let for variables and const fror constants. Var foo ='bar'; Let foo ='bar';const baz ='bar'; Functions function $name$ ($parameters$) { } ...
0
by: ryjfgjl | last post by:
If we have dozens or hundreds of excel to import into the database, if we use the excel import function provided by database editors such as navicat, it will be extremely tedious and time-consuming...
0
by: ryjfgjl | last post by:
In our work, we often receive Excel tables with data in the same format. If we want to analyze these data, it can be difficult to analyze them because the data is spread across multiple Excel files...
0
by: emmanuelkatto | last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud. Please let me know. Thanks! Emmanuel
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...
0
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
0
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers,...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.