You are viewing a plain text version of this content. The canonical link for it is here.
Posted to issues@trafodion.apache.org by "Suresh Subbiah (JIRA)" <ji...@apache.org> on 2015/06/29 00:04:05 UTC
[jira] [Commented] (TRAFODION-14) upsert or merge into a table with
indexes can result in inconsistency between index and table
[ https://issues.apache.org/jira/browse/TRAFODION-14?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=14604942#comment-14604942 ]
Suresh Subbiah commented on TRAFODION-14:
-----------------------------------------
Thank you very much for catching this issue.
I think what you are saying is that if we update a table with an index, then we get a plan with a merge union with an index_delete and index_insert as its two children. Either one of these 2 children could execute first. If the index_insert executes first, then the delete could actually remove the newly inserted row into the index_table. Your suggestion is to add a timestamp predicate to the index_delete so that the newer row will never be deleted. I think that is a sound idea.
Please check if your solution will solve a similar issue for this testcase too.
--- testcase 1
create table t015t1 (a int not null, b int default 2 not null, primary key(a)) salt using 2 partitions ;
create index t015t1i2 on t015t1(b);
merge into t015t1 on a = 1 when matched then update set b = -1
when not matched then insert values (1,2);
select * from t015t1;
merge into t015t1 on a = 1 when matched then update set b = -1
when not matched then insert values (1,2);
-- this select will show 2 rows after a few runs
select * from t015t1 ;
delete from t015t1 ;
merge into t015t1 on a = 1 when matched then update set b = -1
when not matched then insert values (1,2);
select * from t015t1;
merge into t015t1 on a = 1 when matched then update set b = -1
when not matched then insert values (1,2);
-- this select will show 2 rows after a few runs
select * from t015t1 ;
delete from t015t1 ;
>From this explanation this problem should be present for an update statement and not for merge statement alone.
Also please take a look at Testcase 2 also. I think your solution (maybe with some tweaks such as setting the timestamp to a really small value so that no row will ever be deleted when a merge statement actually results in an insert into the base table) can apply to that also.
-- Testcase 2
-- Merge onto a table with unique index and merge goes to when not matched clause
insert into t015t7 values (1,1,1) ;
merge into t015t7 on a = 2
when matched then update set (b,c) = (1,2)
when not matched then insert values (2,1,2) ;
select * from t015t7;
select b from t015t7 order by 1;
-- index should have one row less. Check that first select is using base table
-- and second select is using index
Thanks again for finding such a good solution to the problem.
> upsert or merge into a table with indexes can result in inconsistency between index and table
> ---------------------------------------------------------------------------------------------
>
> Key: TRAFODION-14
> URL: https://issues.apache.org/jira/browse/TRAFODION-14
> Project: Apache Trafodion
> Issue Type: Bug
> Reporter: Selvaganesan
> Priority: Critical
>
> Steps to reproduce this problem
> set schema seabase ;
> CREATE TABLE TRAFODION.SEABASE.TEST1
> (
> A INT NO DEFAULT NOT NULL NOT DROPPABLE
> , B INT DEFAULT NULL
> , PRIMARY KEY (A ASC)
> )
> ;
> CREATE INDEX IDX1 ON TRAFODION.SEABASE.TEST1
> (
> B ASC
> )
> ;
> CREATE TABLE TRAFODION.SEABASE.TEST2
> (
> A INT NO DEFAULT NOT NULL NOT DROPPABLE
> , B INT DEFAULT NULL
> , PRIMARY KEY (A ASC)
> )
> ;
> insert into test2 values (1,1),(2,2),(3,3),(4,4),(5,5),(6,6),(7,7),(8,8),(9,9),(10,10) ;
> prepare s2 from upsert into test1 select * from test2;
> 1) execute s2;
> 2) select * from test1 ;
> If you repeat steps 1 and 2 more than once, at times fewer than 10 rows are selected from the step 2.
> In this particular case select * from test1 involves index scan plan.
--
This message was sent by Atlassian JIRA
(v6.3.4#6332)