blob: 4c0362c3e763b6bb00313b80c1d954fcd3bf5ed9 [file] [log] [blame]
ij> --
-- Licensed to the Apache Software Foundation (ASF) under one or more
-- contributor license agreements. See the NOTICE file distributed with
-- this work for additional information regarding copyright ownership.
-- The ASF licenses this file to You under the Apache License, Version 2.0
-- (the "License"); you may not use this file except in compliance with
-- the License. You may obtain a copy of the License at
--
-- http://www.apache.org/licenses/LICENSE-2.0
--
-- Unless required by applicable law or agreed to in writing, software
-- distributed under the License is distributed on an "AS IS" BASIS,
-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-- See the License for the specific language governing permissions and
-- limitations under the License.
--
------------------------------------------------------------------------------
-- TEST CASES SPECIFIC TO STORE IMPLEMENTATION OF READ UNCOMMITTED:
-- overview:
-- TEST 0: Test a scan positioned on a row which is deleted from it.
-- TEST 1: Test a scan positioned on a row which is purged from it.
------------------------------------------------------------------------------
--
------------------------------------------------------------------------------
run resource 'createTestProcedures.subsql';
ij> CREATE FUNCTION PADSTRING (DATA VARCHAR(32000), LENGTH INTEGER) RETURNS VARCHAR(32000) EXTERNAL NAME 'com.ibm.db2j.testing.Formatters.padString' LANGUAGE JAVA PARAMETER STYLE JAVA;
0 rows inserted/updated/deleted
ij> CREATE PROCEDURE WAIT_FOR_POST_COMMIT() DYNAMIC RESULT SETS 0 LANGUAGE JAVA EXTERNAL NAME 'com.ibm.db2j.testing.T_Access.waitForPostCommitToFinish' PARAMETER STYLE JAVA;
0 rows inserted/updated/deleted
ij> call SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.storage.pageSize', '4096');
0 rows inserted/updated/deleted
ij> connect 'wombat' as scanner;
ij(SCANNER)> autocommit off;
ij(SCANNER)> connect 'wombat' as deleter;
ij(DELETER)> autocommit off;
ij(DELETER)> ------------------------------------------------------------------------------
-- TEST 0: Test a scan positioned on a row which is deleted from it.
------------------------------------------------------------------------------
set connection scanner;
ij(SCANNER)> set current isolation to UR;
0 rows inserted/updated/deleted
ij(SCANNER)> drop table data;
ERROR 42Y55: 'DROP TABLE' cannot be performed on 'DATA' because it does not exist.
ij(SCANNER)> -- create a table with 2 rows per index page.
create table data (keycol int, data varchar(1600)) ;
0 rows inserted/updated/deleted
ij(SCANNER)> insert into data values (0, PADSTRING('0',1600));
1 row inserted/updated/deleted
ij(SCANNER)> insert into data values (10, PADSTRING('100',1600));
1 row inserted/updated/deleted
ij(SCANNER)> insert into data values (20, PADSTRING('200',1600));
1 row inserted/updated/deleted
ij(SCANNER)> insert into data values (30, PADSTRING('300',1600));
1 row inserted/updated/deleted
ij(SCANNER)> insert into data values (40, PADSTRING('400',1600));
1 row inserted/updated/deleted
ij(SCANNER)> insert into data values (50, PADSTRING('100',1600));
1 row inserted/updated/deleted
ij(SCANNER)> insert into data values (60, PADSTRING('200',1600));
1 row inserted/updated/deleted
ij(SCANNER)> insert into data values (70, PADSTRING('300',1600));
1 row inserted/updated/deleted
ij(SCANNER)> insert into data values (80, PADSTRING('400',1600));
1 row inserted/updated/deleted
ij(SCANNER)> create index idx on data (keycol, data) ;
0 rows inserted/updated/deleted
ij(SCANNER)> commit;
ij(SCANNER)> set connection deleter;
ij(DELETER)> SET ISOLATION READ COMMITTED;
0 rows inserted/updated/deleted
ij(DELETER)> commit;
ij(DELETER)> -- position scanner with no bulk fetch on 40,400
set connection scanner;
ij(SCANNER)> CALL SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.language.bulkFetchDefault','1');
0 rows inserted/updated/deleted
ij(SCANNER)> get cursor scan_cursor as
'select keycol from data';
ij(SCANNER)> call SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.language.bulkFetchDefault', '16');
0 rows inserted/updated/deleted
ij(SCANNER)> next scan_cursor;
KEYCOL
-----------
0
ij(SCANNER)> next scan_cursor;
KEYCOL
-----------
10
ij(SCANNER)> next scan_cursor;
KEYCOL
-----------
20
ij(SCANNER)> next scan_cursor;
KEYCOL
-----------
30
ij(SCANNER)> next scan_cursor;
KEYCOL
-----------
40
ij(SCANNER)> -- now delete all the rows except for 70 and 80
set connection deleter;
ij(DELETER)> delete from data where keycol < 70;
7 rows inserted/updated/deleted
ij(DELETER)> -- scanner should automatically jump to 70
set connection scanner;
ij(SCANNER)> next scan_cursor;
KEYCOL
-----------
70
ij(SCANNER)> -- cleanup
close scan_cursor;
ij(SCANNER)> commit;
ij(SCANNER)> set connection deleter;
ij(DELETER)> commit;
ij(DELETER)> ------------------------------------------------------------------------------
-- TEST 1: Test a scan positioned on a row which is purged.
------------------------------------------------------------------------------
set connection scanner;
ij(SCANNER)> set isolation read uncommitted;
0 rows inserted/updated/deleted
ij(SCANNER)> drop table data;
0 rows inserted/updated/deleted
ij(SCANNER)> -- create a table with 3 rows per index page.
create table data (keycol int, data varchar(1200));
0 rows inserted/updated/deleted
ij(SCANNER)> insert into data values (0, PADSTRING('0',1200));
1 row inserted/updated/deleted
ij(SCANNER)> insert into data values (10, PADSTRING('100',1200));
1 row inserted/updated/deleted
ij(SCANNER)> insert into data values (20, PADSTRING('200',1200));
1 row inserted/updated/deleted
ij(SCANNER)> insert into data values (30, PADSTRING('300',1200));
1 row inserted/updated/deleted
ij(SCANNER)> insert into data values (40, PADSTRING('400',1200));
1 row inserted/updated/deleted
ij(SCANNER)> insert into data values (50, PADSTRING('100',1200));
1 row inserted/updated/deleted
ij(SCANNER)> insert into data values (60, PADSTRING('200',1200));
1 row inserted/updated/deleted
ij(SCANNER)> insert into data values (70, PADSTRING('300',1200));
1 row inserted/updated/deleted
ij(SCANNER)> insert into data values (80, PADSTRING('400',1200));
1 row inserted/updated/deleted
ij(SCANNER)> create index idx on data (keycol, data) ;
0 rows inserted/updated/deleted
ij(SCANNER)> commit;
ij(SCANNER)> -- position scanner with no bulk fetch on 0,0 (first row in btree)
set connection scanner;
ij(SCANNER)> CALL SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.language.bulkFetchDefault','1');
0 rows inserted/updated/deleted
ij(SCANNER)> get cursor scan_cursor as
'select keycol from data';
ij(SCANNER)> call SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.language.bulkFetchDefault', '16');
0 rows inserted/updated/deleted
ij(SCANNER)> next scan_cursor;
KEYCOL
-----------
0
ij(SCANNER)> -- delete all the rows in the table except for the last few pages, and the 1st;
set connection deleter;
ij(DELETER)> delete from data where keycol < 50 and keycol > 0;
4 rows inserted/updated/deleted
ij(DELETER)> -- insert enough rows after the first to force a split by the scanner on the 1st
-- page, it will now be positioned by key on the (0, 0) key. Then delete the
-- rows that we just inserted.
set connection scanner;
ij(SCANNER)> insert into data values (9, '3'), (9, '2'), (9, '1');
3 rows inserted/updated/deleted
ij(SCANNER)> delete from data where keycol = 9;
3 rows inserted/updated/deleted
ij(SCANNER)> -- delete the key that the scan is positioned on.
set connection deleter;
ij(DELETER)> delete from data where keycol = 0;
1 row inserted/updated/deleted
ij(DELETER)> commit;
ij(DELETER)> set connection scanner;
ij(SCANNER)> -- this should now cause another split on the first page in the btree, this
-- time it should reclaim row 0.
insert into data values (8, '3'), (8, '2'), (8, '1');
3 rows inserted/updated/deleted
ij(SCANNER)> -- scanner should automatically jump to 8, handling the fact that row (0,0)
-- no longer exists in the table.
set connection scanner;
ij(SCANNER)> next scan_cursor;
KEYCOL
-----------
50
ij(SCANNER)> next scan_cursor;
KEYCOL
-----------
60
ij(SCANNER)> next scan_cursor;
KEYCOL
-----------
70
ij(SCANNER)> next scan_cursor;
KEYCOL
-----------
80
ij(SCANNER)> -- delete all the rows that remain except the last;
set connection deleter;
ij(DELETER)> delete from data where keycol > 10 and keycol < 80;
3 rows inserted/updated/deleted
ij(DELETER)> commit;
ij(DELETER)> -- position scan on last row of scan.
set connection scanner;
ij(SCANNER)> next scan_cursor;
KEYCOL
-----------
8
ij(SCANNER)> -- now repeat process from above to make the current scan position disappear to
-- test code path executed when closing a scan where the last scan position has
-- disappeared.
set connection scanner;
ij(SCANNER)> insert into data values (82, '3'), (82, '2'), (82, '1');
3 rows inserted/updated/deleted
ij(SCANNER)> delete from data where keycol = 81;
0 rows inserted/updated/deleted
ij(SCANNER)> set connection deleter;
ij(DELETER)> delete from data where keycol = 80;
1 row inserted/updated/deleted
ij(DELETER)> commit;
ij(DELETER)> set connection scanner;
ij(SCANNER)> -- this statement will purge (80, 800) from the table.
insert into data values (81, '3'), (81, '2'), (81, '1');
3 rows inserted/updated/deleted
ij(SCANNER)> delete from data where keycol = 81;
3 rows inserted/updated/deleted
ij(SCANNER)> -- this statement will execute code which will look for last key positioned on
-- while closing the statement.
close scan_cursor;
ij(SCANNER)> -- cleanup
set connection scanner;
ij(SCANNER)> commit;
ij(SCANNER)> set connection deleter;
ij(DELETER)> commit;
ij(DELETER)>