blob: ab05c55e5e108f9551a62dde23150ec063a994e2 [file] [log] [blame]
--
-- 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 multi user lock interaction under isolation level 2. default isolation
-- level has been set as a property to serializable.
--------------------------------------------------------------------------------
run resource '/org/apache/derbyTesting/functionTests/tests/store/createTestProcedures.subsql';
call SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.storage.pageSize', '4096');
autocommit off;
-- by default, holdability of ResultSet objects created using this Connection object is true. Following will set it to false for this connection.
NoHoldForConnection;
--------------------------------------------------------------------------------
-- Test 0: verify isolation level by seeing if a read lock is released or not.
--------------------------------------------------------------------------------
connect 'wombat' as scanner;
-- by default, holdability of ResultSet objects created using this Connection object is true. Following will set it to false for this connection.
NoHoldForConnection;
connect 'wombat' as writer;
-- by default, holdability of ResultSet objects created using this Connection object is true. Following will set it to false for this connection.
NoHoldForConnection;
-- set up
set connection scanner;
autocommit off;
create table test_0 (a int);
insert into test_0 values (1);
commit;
set connection writer;
autocommit off;
-- isolation 2 scanner should release read lock on table after statement.
set connection scanner;
select * from test_0;
-- writer should be able to insert into table - scanner released read lock.
set connection writer;
insert into test_0 values (2);
-- scanner will now block on uncommitted insert, and get lock timeout
set connection scanner;
select * from test_0;
commit;
-- commit writer - releasing all locks.
set connection writer;
commit;
-- scanner will now see 2 rows
set connection scanner;
select * from test_0;
commit;
-- cleanup
set connection scanner;
drop table test_0;
commit;
disconnect;
set connection writer;
disconnect;
--------------------------------------------------------------------------------
-- Test 1: make sure a leaf root growing get's the right lock.
--------------------------------------------------------------------------------
--------------------------------------------------------------------------------
-- Test setup - create a 1 page btree, with the page ready to split.
--------------------------------------------------------------------------------
connect 'wombat' as scanner;
-- by default, holdability of ResultSet objects created using this Connection object is true. Following will set it to false for this connection.
NoHoldForConnection;
connect 'wombat' as rootgrower;
-- by default, holdability of ResultSet objects created using this Connection object is true. Following will set it to false for this connection.
NoHoldForConnection;
set connection scanner;
autocommit off;
create table a (a varchar(1200), b varchar(1000)) ;
insert into a values (PADSTRING('a',1200), PADSTRING('a',1000));
insert into a values (PADSTRING('b',1200), PADSTRING('b',1000));
insert into a values (PADSTRING('c',1200), PADSTRING('c',1000));
create index a_idx on a (a) ;
commit;
set connection rootgrower;
autocommit off;
commit;
--------------------------------------------------------------------------------
-- Set up scanner to be doing a row locked covered scan on the index.
--------------------------------------------------------------------------------
set connection scanner;
autocommit off;
CALL SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.language.bulkFetchDefault','1');
get cursor scan_cursor as
'select a from a where a >= PADSTRING(''a'',1200) and a < PADSTRING(''c'',1200) ';
call SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.language.bulkFetchDefault', '16');
next scan_cursor;
--------------------------------------------------------------------------------
-- Before DERBY-2991 the attempt to split the root would time out because the
-- scan had locked the first page.
--------------------------------------------------------------------------------
set connection rootgrower;
autocommit off;
insert into a values (PADSTRING('d',1200), PADSTRING('d',1000));
rollback;
--------------------------------------------------------------------------------
-- The scan should continue unaffected.
--------------------------------------------------------------------------------
set connection scanner;
next scan_cursor;
next scan_cursor;
--------------------------------------------------------------------------------
-- This insert will block on the previous key lock of the scanner.
--------------------------------------------------------------------------------
set connection rootgrower;
insert into a values (PADSTRING('ab',1200), PADSTRING('ab',1000));
--------------------------------------------------------------------------------
-- Now the grow root should be allowed (note that cursor scan has locks
-- on the leaf page being grown - just not the scan lock).
-- (Scan locks are no longer used after DERBY-2991.)
--------------------------------------------------------------------------------
set connection rootgrower;
insert into a values (PADSTRING('d',1200), PADSTRING('d',1000));
select a from a;
--------------------------------------------------------------------------------
-- cleanup.
--------------------------------------------------------------------------------
set connection rootgrower;
commit;
disconnect;
set connection scanner;
commit;
drop table a;
commit;
disconnect;
--------------------------------------------------------------------------------
-- Test 2: make sure previous key locks are gotten correctly.
--------------------------------------------------------------------------------
connect 'wombat' as client_1;
-- by default, holdability of ResultSet objects created using this Connection object is true. Following will set it to false for this connection.
NoHoldForConnection;
connect 'wombat' as client_2;
-- by default, holdability of ResultSet objects created using this Connection object is true. Following will set it to false for this connection.
NoHoldForConnection;
set connection client_1;
autocommit off;
create table a (a varchar(1000), b varchar(1000)) ;
create unique index a_idx on a (a) ;
insert into a values (PADSTRING('b',1000), PADSTRING('b',1000));
insert into a values (PADSTRING('c',1000), PADSTRING('c',1000));
insert into a values (PADSTRING('e',1000), PADSTRING('e',1000));
insert into a values (PADSTRING('f',1000), PADSTRING('f',1000));
insert into a values (PADSTRING('g',1000), PADSTRING('g',1000));
commit;
set connection client_2;
autocommit off;
--------------------------------------------------------------------------------
-- client 1 will get exclusive locks on 'c'.
--------------------------------------------------------------------------------
set connection client_1;
update a set b = 'new value' where a > 'b' and a <= 'd';
-- run resource '/org/apache/derbyTesting/functionTests/tests/store/LockTableQuery.subsql';
set connection client_2;
--------------------------------------------------------------------------------
-- the following will not time out, the insert
-- will get a previous key insert lock which will not conflict with the
-- non-insert read-committed exclusive lock on 'c'.
--------------------------------------------------------------------------------
insert into a values (PADSTRING('d',1000), PADSTRING('d',1000));
--------------------------------------------------------------------------------
-- the following should NOT cause a time out
--------------------------------------------------------------------------------
insert into a values (PADSTRING('a',1000), PADSTRING('a',1000));
--------------------------------------------------------------------------------
-- the following will block because it is a unique index, and the insert is of
-- the same row being locked by client_1
--------------------------------------------------------------------------------
insert into a values (PADSTRING('c',1000), PADSTRING('c',1000));
-- run resource '/org/apache/derbyTesting/functionTests/tests/store/LockTableQuery.subsql';
--------------------------------------------------------------------------------
-- cleanup.
--------------------------------------------------------------------------------
set connection client_1;
select * from a;
commit;
set connection client_2;
commit;
select * from a;
drop table a;
commit;
--------------------------------------------------------------------------------
-- Test 3: make sure an exact key insert into unique key index blocks.
--------------------------------------------------------------------------------
set connection client_1;
autocommit off;
create table a (a varchar(1000), b varchar(1000)) ;
create unique index a_idx on a (a) ;
commit;
insert into a values (PADSTRING('b',1000), PADSTRING('b',1000));
set connection client_2;
autocommit off;
--------------------------------------------------------------------------------
-- the following should cause a time out, as the previous
-- key lock will conflict with client_1's lock on 'b'
--------------------------------------------------------------------------------
insert into a values (PADSTRING('b',1000), PADSTRING('b',1000));
--------------------------------------------------------------------------------
-- Test 4: make sure that row lock wait in a heap scan works
--------------------------------------------------------------------------------
set connection client_1;
autocommit off;
create table test_4 (a int, b varchar(1000), c varchar(1000)) ;
commit;
set connection client_2;
autocommit off;
commit;
-- client_1 will get a single row lock in the heap.
set connection client_1;
insert into test_4 values (1, PADSTRING('a',1000), PADSTRING('b',1000));
-- client_2 scans table, blocking on a row lock on the client_1 insert row,
-- will get timeout message.
set connection client_2;
select * from test_4;
-- release the insert lock.
set connection client_1;
commit;
-- reader should be able to see row now.
set connection client_2;
select * from test_4;
commit;
-- cleanup
set connection client_1;
drop table test_4;
commit;
--------------------------------------------------------------------------------
-- Test 5: make sure a that a group fetch through a secondary index correctly
-- handles a row that is deleted after it has read a row from the index
-- but before it has read the row from the base table.
--------------------------------------------------------------------------------
--------------------------------------------------------------------------------
-- Test setup - create a 1 page btre, with the page ready to split.
--------------------------------------------------------------------------------
connect 'wombat' as scanner;
-- by default, holdability of ResultSet objects created using this Connection object is true. Following will set it to false for this connection.
NoHoldForConnection;
connect 'wombat' as deleter;
-- by default, holdability of ResultSet objects created using this Connection object is true. Following will set it to false for this connection.
NoHoldForConnection;
set connection scanner;
autocommit off;
create table test_5 (a int, a2 int, b varchar(1000), c varchar(1000)) ;
insert into test_5 values (1, 10, PADSTRING('a',1000), PADSTRING('a',1000));
insert into test_5 values (2, 20, PADSTRING('b',1000), PADSTRING('b',1000));
insert into test_5 values (3, 30, PADSTRING('c',1000), PADSTRING('c',1000));
insert into test_5 values (4, 40, PADSTRING('d',1000), PADSTRING('d',1000));
insert into test_5 values (5, 50, PADSTRING('e',1000), PADSTRING('e',1000));
insert into test_5 values (6, 60, PADSTRING('f',1000), PADSTRING('f',1000));
create index test_5_idx on test_5 (a);
commit;
set connection deleter;
autocommit off;
commit;
--------------------------------------------------------------------------------
-- Set up scanner to be doing a row locked index to base row scan on the index.
-- By using group fetch it will read and release locks on multiple rows from
-- the index and save away row pointers from the index.
--------------------------------------------------------------------------------
set connection scanner;
CALL SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.language.bulkFetchDefault','10');
get cursor scan_cursor as
'select a, a2 from test_5 where a > 1 ';
call SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.language.bulkFetchDefault', '16');
-- because of group locking will get locks on 1, 2, 3, 4, and 5 and then will
-- release the locks on 1, 2, 3, and 4. The last one is released on close or
-- on next call emptying the cursor.
next scan_cursor;
--------------------------------------------------------------------------------
-- Delete a row that the scanner has looked at but not reported back to the
-- caller.
--------------------------------------------------------------------------------
set connection deleter;
delete from test_5 where a = 4;
--------------------------------------------------------------------------------
-- The scan will requalify rows when it goes to the base table, thus it will
-- see 3, but block when it gets to the key of deleted row (4).
--------------------------------------------------------------------------------
set connection scanner;
next scan_cursor;
next scan_cursor;
-- commit the delete
set connection deleter;
commit;
-- scanner should see 1,2,3,4,6
set connection scanner;
close scan_cursor;
select a,b from test_5;
--------------------------------------------------------------------------------
-- cleanup.
--------------------------------------------------------------------------------
set connection deleter;
commit;
disconnect;
set connection scanner;
commit;
drop table test_5;
commit;
disconnect;
--------------------------------------------------------------------------------
-- Test 6: make sure a that heap scans which cross page boundaries release
-- locks correctly.
--------------------------------------------------------------------------------
-- Test setup - create a heap with one row per page.
connect 'wombat' as scanner;
-- by default, holdability of ResultSet objects created using this Connection object is true. Following will set it to false for this connection.
NoHoldForConnection;
connect 'wombat' as deleter;
-- by default, holdability of ResultSet objects created using this Connection object is true. Following will set it to false for this connection.
NoHoldForConnection;
set connection scanner;
autocommit off;
create table test_6 (a int, a2 int, b varchar(2000), c varchar(2000)) ;
insert into test_6 values (1, 10, PADSTRING('a',2000), PADSTRING('a',2000));
insert into test_6 values (2, 20, PADSTRING('b',2000), PADSTRING('b',2000));
insert into test_6 values (3, 30, PADSTRING('c',2000), PADSTRING('c',2000));
insert into test_6 values (4, 40, PADSTRING('d',2000), PADSTRING('d',2000));
insert into test_6 values (5, 50, PADSTRING('e',2000), PADSTRING('e',2000));
create index test_6_idx on test_6 (a);
commit;
set connection deleter;
autocommit off;
commit;
--------------------------------------------------------------------------------
-- Set up scanner to be doing a row locked index to base row scan on the index.
-- By using group fetch it will read and release locks on multiple rows from
-- the index and save away row pointers from the index.
--------------------------------------------------------------------------------
set connection scanner;
get cursor scan_cursor as
'select a, a2 from test_6';
next scan_cursor;
next scan_cursor;
next scan_cursor;
next scan_cursor;
next scan_cursor;
--------------------------------------------------------------------------------
-- Delete all rows that the scanner has looked at, and should have released the
-- lock on.
--------------------------------------------------------------------------------
set connection deleter;
delete from test_6 where a = 1;
delete from test_6 where a = 2;
delete from test_6 where a = 3;
delete from test_6 where a = 4;
--------------------------------------------------------------------------------
-- The scan should either block on the delete or continue and not return the
-- the deleted row.
--------------------------------------------------------------------------------
set connection scanner;
next scan_cursor;
close scan_cursor;
-- commit the delete
set connection deleter;
delete from test_6 where a = 5;
commit;
-- scanner should see no rows.
set connection scanner;
select a,b from test_6;
--------------------------------------------------------------------------------
-- cleanup.
--------------------------------------------------------------------------------
set connection deleter;
commit;
disconnect;
set connection scanner;
commit;
drop table test_6;
commit;
disconnect;
--------------------------------------------------------------------------------
-- Test 7: make sure that 2 heap cursor scans in same transaction work (at one
-- point there was a problem where releasing locks in one of the cursors
-- released locks in the other cursor).
--------------------------------------------------------------------------------
-- Test setup - create a heap with one row per page.
connect 'wombat' as scanner;
-- by default, holdability of ResultSet objects created using this Connection object is true. Following will set it to false for this connection.
NoHoldForConnection;
connect 'wombat' as deleter;
-- by default, holdability of ResultSet objects created using this Connection object is true. Following will set it to false for this connection.
NoHoldForConnection;
--------------------------------------------------------------------------------
-- HEAP SCAN
--------------------------------------------------------------------------------
set connection scanner;
autocommit off;
create table test_7 (a int, a2 int, b varchar(2000), c varchar(2000)) ;
insert into test_7 values (1, 10, PADSTRING('a',2000), PADSTRING('a',2000));
insert into test_7 values (2, 20, PADSTRING('b',2000), PADSTRING('b',2000));
insert into test_7 values (3, 30, PADSTRING('c',2000), PADSTRING('c',2000));
insert into test_7 values (4, 40, PADSTRING('d',2000), PADSTRING('d',2000));
insert into test_7 values (5, 50, PADSTRING('e',2000), PADSTRING('e',2000));
commit;
set connection deleter;
autocommit off;
commit;
-- Set up scanner to be doing a row locked heap scan, going one row at a time.
set connection scanner;
CALL SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.language.bulkFetchDefault','1');
get cursor scan_cursor_1 as
'select a, a2 from test_7';
get cursor scan_cursor_2 as
'select a, a2 from test_7';
call SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.language.bulkFetchDefault', '16');
next scan_cursor_1;
next scan_cursor_1;
next scan_cursor_1;
next scan_cursor_1;
next scan_cursor_1;
next scan_cursor_2;
close scan_cursor_2;
-- Get exclusive table lock on test_7. Should fail with table cannot be locked.
set connection deleter;
lock table test_7 in exclusive mode;
-- release all read locks, by moving the cursor past all the rows.
set connection scanner;
next scan_cursor_1;
close scan_cursor_1;
-- Get exclusive table lock on test_7. Now that both scan closed this should
-- work.
set connection deleter;
delete from test_7;
commit;
-- scanner should see no rows.
set connection scanner;
select a,b from test_7;
commit;
--------------------------------------------------------------------------------
-- cleanup.
--------------------------------------------------------------------------------
set connection deleter;
commit;
disconnect;
set connection scanner;
commit;
drop table test_7;
commit;
disconnect;
--------------------------------------------------------------------------------
-- Test 8: Exercise post commit cases, force the code through the path, no easy
-- way to make sure the post commit work is actually doing something.
-- All these case were run with lock debugging by hand to make sure the
-- right thing was happening:
--
-- 8.1 - heap post commit successfully gets table X lock and cleans up.
-- 8.2 - heap post commit can't get table X lock, so gives up and let's
-- client continue on with work.
-- 8.3 - btree post commit successfully gets table X lock and cleans up.
-- 8.4 - btree post commit can't get table X lock, so gives up and let's
-- client continue on with work.
-- client continue on with work.
--
--------------------------------------------------------------------------------
--------------------------------------------------------------------------------
-- 8.1 setup
--------------------------------------------------------------------------------
set connection client_1;
create table test_8 (a int, a2 int, b varchar(2000), c char(10))
;
create index test_8_idx on test_8 (a);
insert into test_8 values (1, 10, PADSTRING('a',2000), 'test 8.1');
insert into test_8 values (2, 20, PADSTRING('b',2000), 'test 8.1');
insert into test_8 values (3, 30, PADSTRING('c',2000), 'test 8.1');
insert into test_8 values (4, 40, PADSTRING('d',2000), 'test 8.1');
insert into test_8 values (5, 50, PADSTRING('e',2000), 'test 8.1');
commit;
--------------------------------------------------------------------------------
-- 8.1 test - simply delete rows from table, heap post commit will run and
-- reclaim all pages.
--------------------------------------------------------------------------------
set connection client_1;
delete from test_8;
commit;
select a from test_8;
commit;
--------------------------------------------------------------------------------
-- 8.2 setup
--------------------------------------------------------------------------------
drop table test_8;
create table test_8 (a int, a2 int, b varchar(1000), c char(10))
;
create index test_8_idx on test_8 (a);
insert into test_8 values (1, 10, PADSTRING('a',1000), 'test 8.2');
insert into test_8 values (2, 20, PADSTRING('b',1000), 'test 8.2');
insert into test_8 values (3, 30, PADSTRING('c',1000), 'test 8.2');
insert into test_8 values (4, 40, PADSTRING('d',1000), 'test 8.2');
insert into test_8 values (5, 50, PADSTRING('e',1000), 'test 8.2');
commit;
--------------------------------------------------------------------------------
-- 8.2 test - client 1 holds row lock which will prevent client 2 post commit.
--------------------------------------------------------------------------------
set connection client_1;
insert into test_8 values (6, 60, PADSTRING('a',1000), 'test 8.2');
set connection client_2;
delete from test_8 where a < 5;
commit;
set connection client_1;
select a from test_8;
commit;
set connection client_2;
select a from test_8;
commit;
--------------------------------------------------------------------------------
-- 8.3 setup
--------------------------------------------------------------------------------
drop table test_8;
create table test_8 (a int, a2 int, b varchar(1500), c char(10));
create index test_8_idx on test_8 (a, b)
;
insert into test_8 values (1, 10, PADSTRING('a',1500), 'test 8.3');
insert into test_8 values (2, 20, PADSTRING('b',1500), 'test 8.3');
insert into test_8 values (3, 30, PADSTRING('c',1500), 'test 8.3');
insert into test_8 values (4, 40, PADSTRING('d',1500), 'test 8.3');
insert into test_8 values (5, 50, PADSTRING('e',1500), 'test 8.3');
commit;
--------------------------------------------------------------------------------
-- 8.3 test - simply delete rows from index table, btree post commit will run
-- and reclaim all pages.
--------------------------------------------------------------------------------
set connection client_1;
delete from test_8;
commit;
select a from test_8;
commit;
--------------------------------------------------------------------------------
-- 8.4 setup
--------------------------------------------------------------------------------
drop table test_8;
create table test_8 (a int, a2 int, b varchar(1500), c char(10)) ;
create index test_8_idx1 on test_8 (a);
create index test_8_idx2 on test_8 (a, b)
;
insert into test_8 values (1, 10, PADSTRING('a',1500), 'test 8.4');
insert into test_8 values (2, 20, PADSTRING('b',1500), 'test 8.4');
insert into test_8 values (3, 30, PADSTRING('c',1500), 'test 8.4');
insert into test_8 values (4, 40, PADSTRING('d',1500), 'test 8.4');
insert into test_8 values (5, 50, PADSTRING('e',1500), 'test 8.4');
commit;
--------------------------------------------------------------------------------
-- 8.4 test - client 1 holds row lock which will prevent client 2 post commit.
--------------------------------------------------------------------------------
set connection client_1;
insert into test_8 values (6, 60, PADSTRING('a',1500), 'test 8.4');
set connection client_2;
delete from test_8 where a < 5;
commit;
set connection client_1;
select a from test_8;
commit;
set connection client_2;
select a from test_8;
commit;
--------------------------------------------------------------------------------
-- cleanup.
--------------------------------------------------------------------------------
set connection client_1;
drop table test_8;
commit;
disconnect;
set connection client_2;
commit;
disconnect;
--------------------------------------------------------------------------------
-- Test 9: Make sure scan positioning in the beginning of a unique scan
-- properly gets the scan lock to block with splits.
-- (Scan locks are no longer used after DERBY-2991.)
--
--------------------------------------------------------------------------------
--------------------------------------------------------------------------------
-- 9.1 setup
--------------------------------------------------------------------------------
connect 'wombat' as scanner;
-- by default, holdability of ResultSet objects created using this Connection object is true. Following will set it to false for this connection.
NoHoldForConnection;
autocommit off;
commit;
connect 'wombat' as splitter;
-- by default, holdability of ResultSet objects created using this Connection object is true. Following will set it to false for this connection.
NoHoldForConnection;
autocommit off;
commit;
set connection scanner;
create table test_9 (a int, a2 int, b varchar(1000), c char(10))
;
insert into test_9 values (5, 50, PADSTRING('e',1000), 'test 9.1');
insert into test_9 values (4, 40, PADSTRING('d',1000), 'test 9.1');
insert into test_9 values (3, 30, PADSTRING('c',1000), 'test 9.1');
insert into test_9 values (2, 20, PADSTRING('b',1000), 'test 9.1');
insert into test_9 values (1, 10, PADSTRING('a',1000), 'test 9.1');
create unique index test_9_idx on test_9 (b) ;
commit;
--------------------------------------------------------------------------------
-- 9.1 test - open a cursor for update on table, and make sure splitter waits
-- on the scan position.
--------------------------------------------------------------------------------
set connection scanner;
CALL SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.language.bulkFetchDefault','1');
get cursor scan_cursor as
'select b from test_9 where b >= ''a'' ';
call SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.language.bulkFetchDefault', '16');
next scan_cursor;
next scan_cursor;
-- the following will get a couple of rows and then block on the split.
set connection splitter;
insert into test_9 values (0, 10, PADSTRING('aa',1000), 'test 9.1');
commit;
insert into test_9 values (0, 10, PADSTRING('ab',1000), 'test 9.1');
commit;
-- insert ahead in the cursor to make sure we pick it up later.
-- This would time out before DERBY-2991.
insert into test_9 values (0, 10, PADSTRING('dd',1000), 'test 9.1');
rollback;
set connection scanner;
next scan_cursor;
next scan_cursor;
next scan_cursor;
next scan_cursor;
commit;
--------------------------------------------------------------------------------
-- cleanup.
--------------------------------------------------------------------------------
set connection scanner;
drop table test_9;
commit;
disconnect;
set connection splitter;
commit;
disconnect;
--------------------------------------------------------------------------------
-- Test 10: Make sure a ddl does not block the lock table vti.
--------------------------------------------------------------------------------
--------------------------------------------------------------------------------
-- 10 setup
--------------------------------------------------------------------------------
connect 'wombat' as ddl;
-- by default, holdability of ResultSet objects created using this Connection object is true. Following will set it to false for this connection.
NoHoldForConnection;
autocommit off;
commit;
connect 'wombat' as locktable;
-- by default, holdability of ResultSet objects created using this Connection object is true. Following will set it to false for this connection.
NoHoldForConnection;
autocommit off;
commit;
set connection ddl;
run resource '/org/apache/derbyTesting/functionTests/tests/store/LockTableQuery.subsql';
commit;
--------------------------------------------------------------------------------
-- 10 test - do ddl in one connection and look at lock table in another
-- connection.
--------------------------------------------------------------------------------
set connection ddl;
create table test_10 (a int, a2 int, b varchar(1000), c char(10))
;
insert into test_10 values (4, 40, PADSTRING('d',1000), 'test 9.1');
insert into test_10 values (3, 30, PADSTRING('c',1000), 'test 9.1');
insert into test_10 values (2, 20, PADSTRING('b',1000), 'test 9.1');
insert into test_10 values (1, 10, PADSTRING('a',1000), 'test 9.1');
set connection locktable;
-- this should not block on the other thread.
select * from lock_table order by tabname, type desc, mode, cnt, lockname;
commit;
--------------------------------------------------------------------------------
-- cleanup.
--------------------------------------------------------------------------------
set connection ddl;
drop table test_10;
commit;
disconnect;
set connection locktable;
commit;
disconnect;
--------------------------------------------------------------------------------
-- Test 11: test update locks
--------------------------------------------------------------------------------
connect 'wombat' as t11scanner;
-- by default, holdability of ResultSet objects created using this Connection object is true. Following will set it to false for this connection.
NoHoldForConnection;
connect 'wombat' as t11updater;
-- by default, holdability of ResultSet objects created using this Connection object is true. Following will set it to false for this connection.
NoHoldForConnection;
connect 'wombat' as t11writer;
-- by default, holdability of ResultSet objects created using this Connection object is true. Following will set it to false for this connection.
NoHoldForConnection;
-- set up
set connection t11updater;
autocommit off;
create table test_11 (a int, b int);
insert into test_11 values (1,1);
insert into test_11 values (2,2);
insert into test_11 values (8,8);
create index test11_idx on test_11 (a);
commit;
select * from lock_table order by tabname, type desc, mode, cnt, lockname;
--
--==================================================
-- t11updater gets an update lock on row where a=1
--==================================================
get cursor update_cursor as
'select b from test_11 where a=1 for update of b';
select * from lock_table order by tabname, type desc, mode, cnt, lockname;
next update_cursor;
select * from lock_table order by tabname, type desc, mode, cnt, lockname;
set connection t11scanner;
autocommit off;
--
--------------------------------------------------
-- try to scan the table, readers are compatible with update lock.
--------------------------------------------------
select * from test_11;
select * from lock_table order by tabname, type desc, mode, cnt, lockname;
--
--------------------------------------------------
-- try to update the table, should timeout
--------------------------------------------------
update test_11 set b=99 where a = 1;
--
--------------------------------------------------
-- try to update the table, should go through
--------------------------------------------------
update test_11 set b=99 where a = 8;
select * from lock_table order by tabname, type desc, mode, cnt, lockname;
commit;
select * from lock_table order by tabname, type desc, mode, cnt, lockname;
--
--------------------------------------------------
-- try to get an update lock
--------------------------------------------------
get cursor update_cursor2 as
'select b from test_11 where a=1 for update of b';
select * from lock_table order by tabname, type desc, mode, cnt, lockname;
--
--------------------------------------------------
-- should timeout (other transaction has a shared lock on this row)
--------------------------------------------------
next update_cursor2;
select * from lock_table order by tabname, type desc, mode, cnt, lockname;
--
--------------------------------------------------
-- should succeed (no other transaction has a shared lock on this row)
--------------------------------------------------
get cursor update_cursor3 as
'select b from test_11 where a=8 for update of b';
select type, cnt, mode, tabname, lockname, state from lock_table2 order by tabname, type desc, mode, cnt, lockname;
next update_cursor3;
select * from lock_table order by tabname, type desc, mode, cnt, lockname;
commit;
close update_cursor2;
close update_cursor3;
set connection t11updater;
commit;
close update_cursor;
set connection t11scanner;
select * from lock_table order by tabname, type desc, mode, cnt, lockname;
--
--==================================================
-- t11scanner gets a read lock
--==================================================
select b from test_11 where a=1;
select * from lock_table order by tabname, type desc, mode, cnt, lockname;
--
--------------------------------------------------
-- should succeed (can get an update lock if there is already a shared lock)
--------------------------------------------------
set connection t11updater;
get cursor update_cursor as
'select b from test_11 where a=1 for update of b';
next update_cursor;
select * from lock_table order by tabname, type desc, mode, cnt, lockname;
commit;
close update_cursor;
set connection t11scanner;
commit;
--
--==================================================
-- t11writer gets a write lock
--==================================================
set connection t11writer;
autocommit off;
update test_11 set b=77 where a=2;
select * from lock_table order by tabname, type desc, mode, cnt, lockname;
set connection t11updater;
get cursor update_cursor as
'select b from test_11 where a=2 for update of b';
select * from lock_table order by tabname, type desc, mode, cnt, lockname;
--
----------------------------------------------------
-- should timeout
----------------------------------------------------
next update_cursor;
--------------------------------------------------------------------------------
-- cleanup.
--------------------------------------------------------------------------------
set connection t11updater;
close update_cursor;
drop table test_11;
commit;
disconnect;
set connection t11scanner;
disconnect;
set connection t11writer;
disconnect;
exit;