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. -- -- Very basic single user testing of update row locking. autocommit off; ij> run resource 'createTestProcedures.subsql'; 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. -- CREATE FUNCTION PADSTRING (DATA VARCHAR(32000), LENGTH INTEGER) RETURNS VARCHAR(32000) EXTERNAL NAME 'org.apache.derbyTesting.functionTests.util.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 'org.apache.derbyTesting.functionTests.util.T_Access.waitForPostCommitToFinish' PARAMETER STYLE JAVA; 0 rows inserted/updated/deleted ij> run resource 'LockTableQuery.subsql'; 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. -- create view lock_table as select cast(username as char(8)) as username, cast(t.type as char(8)) as trantype, cast(l.type as char(8)) as type, cast(lockcount as char(3)) as cnt, mode, cast(tablename as char(12)) as tabname, cast(lockname as char(10)) as lockname, state, status from syscs_diag.lock_table l right outer join syscs_diag.transaction_table t on l.xid = t.xid where l.tableType <> 'S' and t.type='UserTransaction'; 0 rows inserted/updated/deleted ij> --on l.xid = t.xid where l.tableType <> 'S' or l.tableType is null -- order by -- tabname, type desc, mode, cnt, lockname -- lock table with system catalog locks included. create view full_lock_table as select cast(username as char(8)) as username, cast(t.type as char(8)) as trantype, cast(l.type as char(8)) as type, cast(lockcount as char(3)) as cnt, mode, cast(tablename as char(12)) as tabname, cast(lockname as char(10)) as lockname, state, status from syscs_diag.lock_table l right outer join syscs_diag.transaction_table t on l.xid = t.xid where l.tableType <> 'S' ; 0 rows inserted/updated/deleted ij> -- lock table with no join. create view lock_table2 as select cast(l.xid as char(8)) as xid, cast(l.type as char(8)) as type, cast(lockcount as char(3)) as cnt, mode, cast(tablename as char(12)) as tabname, cast(lockname as char(10)) as lockname, state from syscs_diag.lock_table l where l.tableType <> 'S' ; 0 rows inserted/updated/deleted ij> -- transaction table with no join. create view tran_table as select * from syscs_diag.transaction_table; 0 rows inserted/updated/deleted ij> commit; ij> call SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.storage.pageSize', '4096'); 0 rows inserted/updated/deleted ij> -- READ UNCOMMITTED TEST set isolation read uncommitted; 0 rows inserted/updated/deleted ij> commit; ij> -- run each test with rows on one page in the interesting conglomerate (heap in -- the non-index tests, and in the index in the index based tests). -- cursor, no index run drop table a; ERROR 42Y55: 'DROP TABLE' cannot be performed on 'A' because it does not exist. ij> -- to create tables of page size 4k and still keep the following tbl -- create table a (a int, b int, c varchar(1900)); create table a(a int, b int); 0 rows inserted/updated/deleted ij> alter table a add column c varchar(1900); 0 rows inserted/updated/deleted ij> insert into a values (1, 10, 'one'); 1 row inserted/updated/deleted ij> insert into a values (2, 20, 'two'); 1 row inserted/updated/deleted ij> insert into a values (3, 30, 'three'); 1 row inserted/updated/deleted ij> insert into a values (4, 40, 'four'); 1 row inserted/updated/deleted ij> insert into a values (5, 50, 'five'); 1 row inserted/updated/deleted ij> insert into a values (6, 60, 'six'); 1 row inserted/updated/deleted ij> insert into a values (7, 70, 'seven'); 1 row inserted/updated/deleted ij> commit; ij> run resource 'readCursorLocks.subsql'; 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. -- -- Very basic single user testing of read locks on cursors on heap tables. -- This ".subsql" test is -- meant to be run from another test such that it gets run under multiple -- isolation levels. This is important as they behave -- differently, depending on isolation levels. -- -- assume's caller has already done: run 'LockTableQuery.subsql'; to get -- easy access to the lock VTI. -- TEST 0: heap cursor scan, group fetch = 1 -- TEST 1: heap cursor scan, group fetch = 2 -- TEST 2: heap cursor scan, group fetch = 1, stop scan in middle of set -- TEST 3: heap cursor scan, group fetch = 4, stop scan in middle of set -- TEST 4: heap cursor scan, group fetch = 1 (scan table with some deleted rows) -- TEST 5: heap cursor scan, group fetch = 2 (scan with committed deleted rows) -- TEST 6: heap cursor scan, group fetch = 1 (scan with "<" qualifier) -- TEST 7: heap cursor scan, group fetch = 2 (scan with "<" qualifier) -- TEST 8: heap cursor scan, group fetch = 1 (scan with equals qualifier) -- TEST 9: heap cursor scan, group fetch = 2 (scan with equals qualifier) -- TEST 10: heap cursor scan, group fetch = 1 (equals qualifier, no rows return) autocommit off; ij> -------------------------------------------------------------------------------- -- Assumes that calling routine has set up the following simple dataset, -- a heap, no indexes with following initial values: -- create table (a int, b int, c somesortofchar); -- 1, 10, 'one' -- 2, 20, 'two' -- 3, 30, 'three' -- 4, 40, 'four' -- 5, 50, 'five' -- 6, 60, 'six' -- 7, 70, 'seven' -------------------------------------------------------------------------------- select * from a; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 1 |10 |one 2 |20 |two 3 |30 |three 4 |40 |four 5 |50 |five 6 |60 |six 7 |70 |seven ij> commit; ij> -------------------------------------------------------------------------------- -- TEST 0: heap cursor scan, group fetch = 1 -- Test full cursor scan which does no updates. -- SERIALIZABLE - will get table level S lock. -- REPEATABLE READ - TABLE IS, will get row S locks as it visits each row. -- READ COMMITTED - TABLE IS, will hold single S lock on current row. -- READ UNCOMMITTED - TABLE IS, no row locks. -------------------------------------------------------------------------------- CALL SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.language.bulkFetchDefault','1'); 0 rows inserted/updated/deleted ij> get cursor scan_cursor as 'select a, b, c from a'; ij> call SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.language.bulkFetchDefault', '16'); 0 rows inserted/updated/deleted ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 1 |10 |one ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 2 |20 |two ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 3 |30 |three ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 4 |40 |four ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 5 |50 |five ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 6 |60 |six ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 7 |70 |seven ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; No current row ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE ij> close scan_cursor; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> -------------------------------------------------------------------------------- -- TEST 1: heap cursor scan, group fetch = 2 -- Test full cursor scan which does no updates. -- SERIALIZABLE - will get table level S lock. -- REPEATABLE READ - TABLE IS, will get row S locks as it visits each row. -- READ COMMITTED - TABLE IS, will get instantaneous locks and release -- READ UNCOMMITTED - TABLE IS, no row locks. -------------------------------------------------------------------------------- CALL SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.language.bulkFetchDefault','2'); 0 rows inserted/updated/deleted ij> -- RESOLVE: missing row locks -- WORKAROUND: creating an index and dropping it -- to force the query 'select a, b, c from a' to be recompiled create index ix1 on a(a); 0 rows inserted/updated/deleted ij> drop index ix1; 0 rows inserted/updated/deleted ij> commit; ij> get cursor scan_cursor as 'select a, b, c from a'; ij> call SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.language.bulkFetchDefault', '16'); 0 rows inserted/updated/deleted ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 1 |10 |one ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 2 |20 |two ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 3 |30 |three ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 4 |40 |four ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 5 |50 |five ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 6 |60 |six ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 7 |70 |seven ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; No current row ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE ij> close scan_cursor; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> -------------------------------------------------------------------------------- -- TEST 2: heap cursor scan, group fetch = 1, stop scan in middle of set -- Test full cursor scan which does no updates. -- SERIALIZABLE - will get table level S lock. -- REPEATABLE READ - TABLE IS, will get row S locks as it visits each row. -- READ COMMITTED - TABLE IS, will hold single S lock on current row. -- READ UNCOMMITTED - TABLE IS, no row locks. -------------------------------------------------------------------------------- CALL SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.language.bulkFetchDefault','1'); 0 rows inserted/updated/deleted ij> -- RESOLVE: missing row locks -- WORKAROUND: creating an index and dropping it -- to force the query 'select a, b, c from a' to be recompiled create index ix1 on a(a); 0 rows inserted/updated/deleted ij> drop index ix1; 0 rows inserted/updated/deleted ij> commit; ij> get cursor scan_cursor as 'select a, b, c from a'; ij> call SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.language.bulkFetchDefault', '16'); 0 rows inserted/updated/deleted ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 1 |10 |one ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 2 |20 |two ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE ij> close scan_cursor; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> -------------------------------------------------------------------------------- -- TEST 3: heap cursor scan, group fetch = 4, stop scan in middle of set -- Test full cursor scan which does no updates. -- SERIALIZABLE - will get table level S lock. -- REPEATABLE READ - TABLE IS, will get row S locks as it visits each row. -- READ COMMITTED - TABLE IS, will hold single S lock on current row. -- READ UNCOMMITTED - TABLE IS, no row locks. -------------------------------------------------------------------------------- CALL SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.language.bulkFetchDefault','4'); 0 rows inserted/updated/deleted ij> -- RESOLVE: missing row locks -- WORKAROUND: creating an index and dropping it -- to force the query 'select a, b, c from a' to be recompiled create index ix1 on a(a); 0 rows inserted/updated/deleted ij> drop index ix1; 0 rows inserted/updated/deleted ij> commit; ij> get cursor scan_cursor as 'select a, b, c from a'; ij> call SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.language.bulkFetchDefault', '16'); 0 rows inserted/updated/deleted ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 1 |10 |one ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 2 |20 |two ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE ij> close scan_cursor; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> -------------------------------------------------------------------------------- -- TEST 4: heap cursor scan, group fetch = 1 (scan table with some deleted rows) -- Test full cursor scan on a data set with some deleted rows (the "even" ones). -- SERIALIZABLE - will get table level S lock. -- REPEATABLE READ - TABLE IS, will get row S locks as it visits each row -- (including deleted ones). -- READ COMMITTED - TABLE IS, will get instantaneous locks and release -- READ UNCOMMITTED - TABLE IS, no row locks. -- -- After the delete the table should look like: -- 1, 10, 'one' -- 3, 30, 'three' -- 5, 50, 'five' -- 7, 70, 'seven' -------------------------------------------------------------------------------- delete from a where a = 2 or a = 4 or a = 6; 3 rows inserted/updated/deleted ij> commit; ij> CALL SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.language.bulkFetchDefault','1'); 0 rows inserted/updated/deleted ij> -- RESOLVE: missing row locks -- WORKAROUND: creating an index and dropping it -- to force the query 'select a, b, c from a' to be recompiled create index ix1 on a(a); 0 rows inserted/updated/deleted ij> drop index ix1; 0 rows inserted/updated/deleted ij> commit; ij> get cursor scan_cursor as 'select a, b, c from a'; ij> call SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.language.bulkFetchDefault', '16'); 0 rows inserted/updated/deleted ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 1 |10 |one ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 3 |30 |three ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 5 |50 |five ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 7 |70 |seven ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; No current row ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE ij> close scan_cursor; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> -------------------------------------------------------------------------------- -- TEST 5: heap cursor scan, group fetch = 2 (scan with committed deleted rows) -- Test full cursor scan on a data set with some deleted rows (the "even" ones). -- SERIALIZABLE - will get table level S lock. -- REPEATABLE READ - TABLE IS, will get row S locks as it visits each row -- (including deleted ones). -- READ COMMITTED - TABLE IS, will get instantaneous locks and release -- READ UNCOMMITTED - TABLE IS, no row locks. -- -- At this point the table should look like: -- 1, 10, 'one' -- 3, 30, 'three' -- 5, 50, 'five' -- 7, 70, 'seven' -------------------------------------------------------------------------------- CALL SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.language.bulkFetchDefault','2'); 0 rows inserted/updated/deleted ij> -- RESOLVE: missing row locks -- WORKAROUND: creating an index and dropping it -- to force the query 'select a, b, c from a' to be recompiled create index ix1 on a(a); 0 rows inserted/updated/deleted ij> drop index ix1; 0 rows inserted/updated/deleted ij> commit; ij> get cursor scan_cursor as 'select a, b, c from a'; ij> call SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.language.bulkFetchDefault', '16'); 0 rows inserted/updated/deleted ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 1 |10 |one ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 3 |30 |three ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 5 |50 |five ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 7 |70 |seven ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; No current row ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE ij> close scan_cursor; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> -------------------------------------------------------------------------------- -- TEST 6: heap cursor scan, group fetch = 1 (scan with "<" qualifier) -- Test "less than" qualified cursor scan on a data set. -- SERIALIZABLE - will get table level S lock. -- REPEATABLE READ - TABLE IS, will get row S locks as it visits each row -- (including deleted ones). -- READ COMMITTED - TABLE IS, will get instantaneous locks and release -- READ UNCOMMITTED - TABLE IS, no row locks. -- -- At this point the table should look like: -- 1, 10, 'one' -- 3, 30, 'three' -- 5, 50, 'five' -- 7, 70, 'seven' -------------------------------------------------------------------------------- CALL SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.language.bulkFetchDefault','1'); 0 rows inserted/updated/deleted ij> get cursor scan_cursor as 'select a, b, c from a where a < 3'; ij> call SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.language.bulkFetchDefault', '16'); 0 rows inserted/updated/deleted ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 1 |10 |one ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; No current row ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE ij> close scan_cursor; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> -------------------------------------------------------------------------------- -- TEST 7: heap cursor scan, group fetch = 2 (scan with "<" qualifier) -- Test "less than" qualified cursor scan on a data set. -- SERIALIZABLE - will get table level S lock. -- REPEATABLE READ - TABLE IS, will get row S locks as it visits each row -- (including deleted ones). -- READ COMMITTED - TABLE IS, will get instantaneous locks and release -- READ UNCOMMITTED - TABLE IS, no row locks. -- -- At this point the table should look like: -- 1, 10, 'one' -- 3, 30, 'three' -- 5, 50, 'five' -- 7, 70, 'seven' -------------------------------------------------------------------------------- CALL SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.language.bulkFetchDefault','2'); 0 rows inserted/updated/deleted ij> -- RESOLVE: missing row locks -- WORKAROUND: creating an index and dropping it -- to force the statement to be recompiled create index ix1 on a(a); 0 rows inserted/updated/deleted ij> drop index ix1; 0 rows inserted/updated/deleted ij> commit; ij> get cursor scan_cursor as 'select a, b, c from a where a < 3'; ij> call SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.language.bulkFetchDefault', '16'); 0 rows inserted/updated/deleted ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 1 |10 |one ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; No current row ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE ij> close scan_cursor; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> -------------------------------------------------------------------------------- -- TEST 8: heap cursor scan, group fetch = 1 (scan with equals qualifier) -- Test "equals" qualified cursor scan on a data set. -- SERIALIZABLE - will get table level S lock. -- REPEATABLE READ - TABLE IS, will get row S locks as it visits each row -- (including deleted ones). -- READ COMMITTED - TABLE IS, will get instantaneous locks and release -- READ UNCOMMITTED - TABLE IS, no row locks. -- -- At this point the table should look like: -- 1, 10, 'one' -- 3, 30, 'three' -- 5, 50, 'five' -- 7, 70, 'seven' -------------------------------------------------------------------------------- CALL SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.language.bulkFetchDefault','1'); 0 rows inserted/updated/deleted ij> get cursor scan_cursor as 'select a, b, c from a where a = 5'; ij> call SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.language.bulkFetchDefault', '16'); 0 rows inserted/updated/deleted ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 5 |50 |five ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; No current row ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE ij> close scan_cursor; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> -------------------------------------------------------------------------------- -- TEST 9: heap cursor scan, group fetch = 2 (scan with equals qualifier) -- Test "equals" qualified cursor scan on a data set. -- SERIALIZABLE - will get table level S lock. -- REPEATABLE READ - TABLE IS, will get row S locks as it visits each row -- (including deleted ones). -- READ COMMITTED - TABLE IS, will get instantaneous locks and release -- READ UNCOMMITTED - TABLE IS, no row locks. -- -- At this point the table should look like: -- 1, 10, 'one' -- 3, 30, 'three' -- 5, 50, 'five' -- 7, 70, 'seven' -------------------------------------------------------------------------------- CALL SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.language.bulkFetchDefault','2'); 0 rows inserted/updated/deleted ij> get cursor scan_cursor as 'select a, b, c from a where a = 7'; ij> call SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.language.bulkFetchDefault', '16'); 0 rows inserted/updated/deleted ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 7 |70 |seven ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; No current row ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE ij> close scan_cursor; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> -------------------------------------------------------------------------------- -- TEST 10: heap cursor scan, group fetch = 1 (equals qualifier, no rows return) -- Test "equals" qualified cursor scan on a data set, no rows returned. -- SERIALIZABLE - will get table level S lock. -- REPEATABLE READ - TABLE IS, will get row S locks as it visits each row -- (including deleted ones). -- READ COMMITTED - TABLE IS, will get instantaneous locks and release -- READ UNCOMMITTED - TABLE IS, no row locks. -- -- At this point the table should look like: -- 1, 10, 'one' -- 3, 30, 'three' -- 5, 50, 'five' -- 7, 70, 'seven' -------------------------------------------------------------------------------- CALL SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.language.bulkFetchDefault','1'); 0 rows inserted/updated/deleted ij> -- RESOLVE: missing row locks -- WORKAROUND: creating an index and dropping it -- to force the statement to be recompiled create index ix1 on a(a); 0 rows inserted/updated/deleted ij> drop index ix1; 0 rows inserted/updated/deleted ij> commit; ij> get cursor scan_cursor as 'select a, b, c from a where a = 7'; ij> CALL SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.language.bulkFetchDefault','16'); 0 rows inserted/updated/deleted ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 7 |70 |seven ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; No current row ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE ij> close scan_cursor; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> drop table a; 0 rows inserted/updated/deleted ij> -- non cursor, no index run drop table a; ERROR 42Y55: 'DROP TABLE' cannot be performed on 'A' because it does not exist. ij> -- to create tables of page size 4k and still keep the following tbl -- create table a (a int, b int, c varchar(1900)); create table a(a int, b int); 0 rows inserted/updated/deleted ij> alter table a add column c varchar(1900); 0 rows inserted/updated/deleted ij> insert into a values (1, 10, 'one'); 1 row inserted/updated/deleted ij> insert into a values (2, 20, 'two'); 1 row inserted/updated/deleted ij> insert into a values (3, 30, 'three'); 1 row inserted/updated/deleted ij> insert into a values (4, 40, 'four'); 1 row inserted/updated/deleted ij> insert into a values (5, 50, 'five'); 1 row inserted/updated/deleted ij> insert into a values (6, 60, 'six'); 1 row inserted/updated/deleted ij> insert into a values (7, 70, 'seven'); 1 row inserted/updated/deleted ij> commit; ij> run resource 'readSetLocks.subsql'; 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. -- -- Very basic single user testing of read locks in "set" queries on heap tables. -- This ".subsql" test is -- meant to be run from another test such that it gets run under multiple -- isolation levels. This is important as they behave -- differently, depending on isolation levels. -- -- assume's caller has already done: run 'LockTableQuery.subsql'; to get -- easy access to the lock VTI. -- TEST 0: heap scan. -- TEST 1: heap scan, some rows deleted. -- TEST 2: heap scan, (scan with "<" qualifier) -- TEST 3: heap scan, (scan with equals qualifier) -- TEST 4: heap scan, (equals qualifier, no rows return) autocommit off; ij> -------------------------------------------------------------------------------- -- Assumes that calling routine has set up the following simple dataset, -- a heap, no indexes with following initial values: -- create table (a int, b int, c somesortofchar); -- 1, 10, 'one' -- 2, 20, 'two' -- 3, 30, 'three' -- 4, 40, 'four' -- 5, 50, 'five' -- 6, 60, 'six' -- 7, 70, 'seven' -------------------------------------------------------------------------------- select * from a; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 1 |10 |one 2 |20 |two 3 |30 |three 4 |40 |four 5 |50 |five 6 |60 |six 7 |70 |seven ij> commit; ij> -------------------------------------------------------------------------------- -- TEST 0: heap scan. -- Test full cursor scan which does no updates. -- SERIALIZABLE - will get table level S lock, held to end of xact. -- REPEATABLE READ - TABLE IS, will get row S locks as it visits each row -- (including deleted ones). held to end of xact. -- READ COMMITTED - TABLE IS, will get instantaneous locks and release. No -- locks held when statement completes. -- READ UNCOMMITTED - TABLE IS, no row locks. No locks after statement ends. -------------------------------------------------------------------------------- select a, b, c from a; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 1 |10 |one 2 |20 |two 3 |30 |three 4 |40 |four 5 |50 |five 6 |60 |six 7 |70 |seven ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> -------------------------------------------------------------------------------- -- TEST 1: heap scan, some rows deleted. -- Test full cursor scan on a data set with some deleted rows (the "even" ones). -- SERIALIZABLE - will get table level S lock. -- REPEATABLE READ - TABLE IS, will get row S locks as it visits each row -- (including deleted ones). -- READ COMMITTED - TABLE IS, will get instantaneous locks and release -- READ UNCOMMITTED - TABLE IS, no row locks. -- SERIALIZABLE - will get table level S lock, held to end of xact. -- REPEATABLE READ - TABLE IS, will get row S locks as it visits each row -- (including deleted ones). held to end of xact. -- READ COMMITTED - TABLE IS, will get instantaneous locks and release. No -- locks held when statement completes. -- READ UNCOMMITTED - TABLE IS, no row locks. No locks after statement ends. -- -- After the delete the table should look like: -- 1, 10, 'one' -- 3, 30, 'three' -- 5, 50, 'five' -- 7, 70, 'seven' -------------------------------------------------------------------------------- delete from a where a = 2 or a = 4 or a = 6; 3 rows inserted/updated/deleted ij> commit; ij> select a, b, c from a; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 1 |10 |one 3 |30 |three 5 |50 |five 7 |70 |seven ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> -------------------------------------------------------------------------------- -- TEST 2: heap scan, (scan with "<" qualifier) -- Test "less than" qualified cursor scan on a data set. -- SERIALIZABLE - will get table level S lock, held to end of xact. -- REPEATABLE READ - TABLE IS, will get row S locks as it visits each row -- (including deleted ones). held to end of xact. -- READ COMMITTED - TABLE IS, will get instantaneous locks and release. No -- locks held when statement completes. -- READ UNCOMMITTED - TABLE IS, no row locks. No locks after statement ends. -- -- At this point the table should look like: -- 1, 10, 'one' -- 3, 30, 'three' -- 5, 50, 'five' -- 7, 70, 'seven' -------------------------------------------------------------------------------- select a, b, c from a; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 1 |10 |one 3 |30 |three 5 |50 |five 7 |70 |seven ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> -------------------------------------------------------------------------------- -- TEST 3: heap scan, (scan with equals qualifier) -- Test "equals" qualified cursor scan on a data set. -- SERIALIZABLE - will get table level S lock, held to end of xact. -- REPEATABLE READ - TABLE IS, will get row S locks as it visits each row -- (including deleted ones). held to end of xact. -- READ COMMITTED - TABLE IS, will get instantaneous locks and release. No -- locks held when statement completes. -- READ UNCOMMITTED - TABLE IS, no row locks. No locks after statement ends. -- -- At this point the table should look like: -- 1, 10, 'one' -- 3, 30, 'three' -- 5, 50, 'five' -- 7, 70, 'seven' -------------------------------------------------------------------------------- select a, b, c from a where a = 5; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 5 |50 |five ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> -------------------------------------------------------------------------------- -- TEST 4: heap scan, (equals qualifier, no rows return) -- Test "equals" qualified cursor scan on a data set, no rows returned. -- SERIALIZABLE - will get table level S lock, held to end of xact. -- REPEATABLE READ - TABLE IS, will get row S locks as it visits each row -- (including deleted ones). held to end of xact. -- READ COMMITTED - TABLE IS, will get instantaneous locks and release. No -- locks held when statement completes. -- READ UNCOMMITTED - TABLE IS, no row locks. No locks after statement ends. -- -- At this point the table should look like: -- 1, 10, 'one' -- 3, 30, 'three' -- 5, 50, 'five' -- 7, 70, 'seven' -------------------------------------------------------------------------------- select a, b, c from a where a = 7; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 7 |70 |seven ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> drop table a; 0 rows inserted/updated/deleted ij> -- cursor, unique index run drop table a; ERROR 42Y55: 'DROP TABLE' cannot be performed on 'A' because it does not exist. ij> -- to create tables of page size 4k and still keep the following tbl -- create table a (a int, b int, c varchar(1900)); create table a(a int, b int); 0 rows inserted/updated/deleted ij> alter table a add column c varchar(1900); 0 rows inserted/updated/deleted ij> insert into a values (1, 10, 'one'); 1 row inserted/updated/deleted ij> insert into a values (2, 20, 'two'); 1 row inserted/updated/deleted ij> insert into a values (3, 30, 'three'); 1 row inserted/updated/deleted ij> insert into a values (4, 40, 'four'); 1 row inserted/updated/deleted ij> insert into a values (5, 50, 'five'); 1 row inserted/updated/deleted ij> insert into a values (6, 60, 'six'); 1 row inserted/updated/deleted ij> insert into a values (7, 70, 'seven'); 1 row inserted/updated/deleted ij> create unique index a_idx on a (a); 0 rows inserted/updated/deleted ij> commit; ij> run resource 'readBtreeCursorLocks.subsql'; 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. -- -- Very basic single user testing of read locks on cursors on indexes. -- This ".subsql" test is -- meant to be run from another test such that it gets run under multiple -- isolation levels. This is important as they behave -- differently, depending on isolation levels. -- -- assume's caller has already done: run 'LockTableQuery.subsql'; to get -- easy access to the lock VTI. -- TEST 0: btree cursor scan, group fetch = 1 -- TEST 1: btree cursor scan, group fetch = 2 -- TEST 2: btree cursor scan, group fetch = 1 stop scan in middle of set -- TEST 3: btree cursor scan, group fetch = 4 stop scan in middle of set -- TEST 4: btree cursor scan, group fetch = 1 (scan with some deleted rows) -- TEST 5: btree cursor scan, group fetch = 2(scan with committed deleted rows) -- TEST 6: btree cursor scan, group fetch = 1 (scan with "<" qualifier) -- TEST 7: btree cursor scan, group fetch = 2 (scan with "<" qualifier) -- TEST 8: btree cursor scan, group fetch = 1 (scan with equals qualifier) -- TEST 9: btree cursor scan, group fetch = 2 (scan with equals qualifier) -- TEST 10: btree cursor scan, group fetch = 1 ("=" qualifier, no rows return) autocommit off; ij> -------------------------------------------------------------------------------- -- Assumes that calling routine has set up the following simple dataset, -- a heap, and index with following initial values: -- create table a (a int, b int, c somesortofchar, [index_pad]); -- create index a_idx on a (a) or a_idx on a (a, index_pad); -- -- 1, 10, 'one' -- 2, 20, 'two' -- 3, 30, 'three' -- 4, 40, 'four' -- 5, 50, 'five' -- 6, 60, 'six' -- 7, 70, 'seven' -------------------------------------------------------------------------------- select * from a; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 1 |10 |one 2 |20 |two 3 |30 |three 4 |40 |four 5 |50 |five 6 |60 |six 7 |70 |seven ij> commit; ij> -------------------------------------------------------------------------------- -- TEST 0: btree cursor scan, group fetch = 1 -- Test full cursor scan which does no updates. -- ALL MODES - TABLE IS, "scan page lockname of form (pageno, 1) -- SERIALIZABLE - row S locks as it visits each row, held until end xact -- REPEATABLE READ - row S locks as it visits each row, held until end xact -- READ COMMITTED - row S lock on current row, released on move to next row -- READ UNCOMMITTED - no row locks. ------------------------------------------------------------------------------- CALL SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.language.bulkFetchDefault','1'); 0 rows inserted/updated/deleted ij> -- RESOLVE: missing row locks -- WORKAROUND: creating an index and dropping it -- to force the statement to be recompiled create index ix1 on a(a); 0 rows inserted/updated/deleted WARNING 01504: The new index is a duplicate of an existing index: A_IDX. ij> drop index ix1; ERROR 42X65: Index 'IX1' does not exist. ij> commit; ij> get cursor scan_cursor as 'select a from a'; ij> call SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.language.bulkFetchDefault', '16'); 0 rows inserted/updated/deleted ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A ----------- 1 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,1) |GRANT|ACTIVE ij> next scan_cursor; A ----------- 2 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,1) |GRANT|ACTIVE ij> next scan_cursor; A ----------- 3 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,1) |GRANT|ACTIVE ij> next scan_cursor; A ----------- 4 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,1) |GRANT|ACTIVE ij> next scan_cursor; A ----------- 5 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,1) |GRANT|ACTIVE ij> next scan_cursor; A ----------- 6 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,1) |GRANT|ACTIVE ij> next scan_cursor; A ----------- 7 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,1) |GRANT|ACTIVE ij> next scan_cursor; No current row ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE ij> close scan_cursor; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> -------------------------------------------------------------------------------- -- TEST 1: btree cursor scan, group fetch = 2 -- Test full cursor scan which does no updates. -- ALL MODES - TABLE IS, "scan page lockname of form (pageno, 1) -- SERIALIZABLE - row S locks as it visits each row, held until end xact -- REPEATABLE READ - row S locks as it visits each row, held until end xact -- READ COMMITTED - row S lock on current row, released on move to next row -- READ UNCOMMITTED - no row locks. -------------------------------------------------------------------------------- CALL SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.language.bulkFetchDefault','2'); 0 rows inserted/updated/deleted ij> -- RESOLVE: missing row locks -- WORKAROUND: creating an index and dropping it -- to force the statement to be recompiled create index ix1 on a(a); 0 rows inserted/updated/deleted WARNING 01504: The new index is a duplicate of an existing index: A_IDX. ij> drop index ix1; ERROR 42X65: Index 'IX1' does not exist. ij> commit; ij> get cursor scan_cursor as 'select a from a'; ij> call SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.language.bulkFetchDefault', '16'); 0 rows inserted/updated/deleted ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A ----------- 1 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,1) |GRANT|ACTIVE ij> next scan_cursor; A ----------- 2 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,1) |GRANT|ACTIVE ij> next scan_cursor; A ----------- 3 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,1) |GRANT|ACTIVE ij> next scan_cursor; A ----------- 4 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,1) |GRANT|ACTIVE ij> next scan_cursor; A ----------- 5 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,1) |GRANT|ACTIVE ij> next scan_cursor; A ----------- 6 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,1) |GRANT|ACTIVE ij> next scan_cursor; A ----------- 7 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; No current row ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE ij> close scan_cursor; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> -------------------------------------------------------------------------------- -- TEST 2: btree cursor scan, group fetch = 1, stop scan in middle of set -- Test full cursor scan which does no updates. -- ALL MODES - TABLE IS, "scan page lockname of form (pageno, 1) -- SERIALIZABLE - row S locks as it visits each row, held until end xact -- REPEATABLE READ - row S locks as it visits each row, held until end xact -- READ COMMITTED - row S lock on current row, released on move to next row -- READ UNCOMMITTED - no row locks. -------------------------------------------------------------------------------- CALL SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.language.bulkFetchDefault','1'); 0 rows inserted/updated/deleted ij> -- RESOLVE: missing row locks -- WORKAROUND: creating an index and dropping it -- to force the statement to be recompiled create index ix1 on a(a); 0 rows inserted/updated/deleted WARNING 01504: The new index is a duplicate of an existing index: A_IDX. ij> drop index ix1; ERROR 42X65: Index 'IX1' does not exist. ij> commit; ij> get cursor scan_cursor as 'select a from a'; ij> call SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.language.bulkFetchDefault', '16'); 0 rows inserted/updated/deleted ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A ----------- 1 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,1) |GRANT|ACTIVE ij> next scan_cursor; A ----------- 2 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,1) |GRANT|ACTIVE ij> close scan_cursor; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> -------------------------------------------------------------------------------- -- TEST 3: btree cursor scan, group fetch = 4, stop scan in middle of set -- Test full cursor scan which does no updates. -- ALL MODES - TABLE IS, "scan page lockname of form (pageno, 1) -- SERIALIZABLE - row S locks as it visits each row, held until end xact -- REPEATABLE READ - row S locks as it visits each row, held until end xact -- READ COMMITTED - row S lock on current row, released on move to next row -- READ UNCOMMITTED - no row locks. -------------------------------------------------------------------------------- CALL SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.language.bulkFetchDefault','4'); 0 rows inserted/updated/deleted ij> -- RESOLVE: missing row locks -- WORKAROUND: creating an index and dropping it -- to force the statement to be recompiled create index ix1 on a(a); 0 rows inserted/updated/deleted WARNING 01504: The new index is a duplicate of an existing index: A_IDX. ij> drop index ix1; ERROR 42X65: Index 'IX1' does not exist. ij> commit; ij> get cursor scan_cursor as 'select a from a'; ij> call SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.language.bulkFetchDefault', '16'); 0 rows inserted/updated/deleted ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A ----------- 1 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,1) |GRANT|ACTIVE ij> next scan_cursor; A ----------- 2 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,1) |GRANT|ACTIVE ij> close scan_cursor; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> -------------------------------------------------------------------------------- -- TEST 4: btree cursor scan, group fetch = 1 (scan table with some deleted rows) -- Test full cursor scan on a data set with some deleted rows (the "even" ones). -- ALL MODES - TABLE IS, "scan page lockname of form (pageno, 1) -- SERIALIZABLE - row S locks as it visits each row, held until end xact -- REPEATABLE READ - row S locks as it visits each row, held until end xact -- READ COMMITTED - row S lock on current row, released on move to next row -- READ UNCOMMITTED - no row locks. -- -- After the delete the base table should look like: -- 1, 10, 'one' -- 3, 30, 'three' -- 5, 50, 'five' -- 7, 70, 'seven' -------------------------------------------------------------------------------- delete from a where a = 2 or a = 4 or a = 6; 3 rows inserted/updated/deleted ij> commit; ij> CALL SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.language.bulkFetchDefault','1'); 0 rows inserted/updated/deleted ij> -- RESOLVE: missing row locks -- WORKAROUND: creating an index and dropping it -- to force the statement to be recompiled create index ix1 on a(a); 0 rows inserted/updated/deleted WARNING 01504: The new index is a duplicate of an existing index: A_IDX. ij> drop index ix1; ERROR 42X65: Index 'IX1' does not exist. ij> commit; ij> get cursor scan_cursor as 'select a from a'; ij> call SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.language.bulkFetchDefault', '16'); 0 rows inserted/updated/deleted ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A ----------- 1 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,1) |GRANT|ACTIVE ij> next scan_cursor; A ----------- 3 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,1) |GRANT|ACTIVE ij> next scan_cursor; A ----------- 5 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,1) |GRANT|ACTIVE ij> next scan_cursor; A ----------- 7 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,1) |GRANT|ACTIVE ij> next scan_cursor; No current row ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE ij> close scan_cursor; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> -------------------------------------------------------------------------------- -- TEST 5: btree cursor scan, group fetch = 2 (scan with committed deleted rows) -- Test full cursor scan on a data set with some deleted rows (the "even" ones). -- ALL MODES - TABLE IS, "scan page lockname of form (pageno, 1) -- SERIALIZABLE - row S locks as it visits each row, held until end xact -- REPEATABLE READ - row S locks as it visits each row, held until end xact -- READ COMMITTED - row S lock on current row, released on move to next row -- READ UNCOMMITTED - no row locks. -- -- At this point the base table should look like: -- 1, 10, 'one' -- 3, 30, 'three' -- 5, 50, 'five' -- 7, 70, 'seven' -------------------------------------------------------------------------------- CALL SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.language.bulkFetchDefault','2'); 0 rows inserted/updated/deleted ij> -- RESOLVE: missing row locks -- WORKAROUND: creating an index and dropping it -- to force the statement to be recompiled create index ix1 on a(a); 0 rows inserted/updated/deleted WARNING 01504: The new index is a duplicate of an existing index: A_IDX. ij> drop index ix1; ERROR 42X65: Index 'IX1' does not exist. ij> commit; ij> get cursor scan_cursor as 'select a from a'; ij> call SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.language.bulkFetchDefault', '16'); 0 rows inserted/updated/deleted ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A ----------- 1 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,1) |GRANT|ACTIVE ij> next scan_cursor; A ----------- 3 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,1) |GRANT|ACTIVE ij> next scan_cursor; A ----------- 5 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,1) |GRANT|ACTIVE ij> next scan_cursor; A ----------- 7 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,1) |GRANT|ACTIVE ij> next scan_cursor; No current row ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE ij> close scan_cursor; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> -------------------------------------------------------------------------------- -- TEST 6: btree cursor scan, group fetch = 1 (scan with "<" qualifier) -- Test "less than" qualified cursor scan on a data set. -- ALL MODES - TABLE IS, "scan page lockname of form (pageno, 1) -- SERIALIZABLE - row S locks as it visits each row, held until end xact -- REPEATABLE READ - row S locks as it visits each row, held until end xact -- READ COMMITTED - row S lock on current row, released on move to next row -- READ UNCOMMITTED - no row locks. -- -- At this point the base table should look like: -- 1, 10, 'one' -- 3, 30, 'three' -- 5, 50, 'five' -- 7, 70, 'seven' -------------------------------------------------------------------------------- CALL SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.language.bulkFetchDefault','1'); 0 rows inserted/updated/deleted ij> -- RESOLVE: missing row locks -- WORKAROUND: creating an index and dropping it -- to force the statement to be recompiled create index ix1 on a(a); 0 rows inserted/updated/deleted WARNING 01504: The new index is a duplicate of an existing index: A_IDX. ij> drop index ix1; ERROR 42X65: Index 'IX1' does not exist. ij> commit; ij> get cursor scan_cursor as 'select a from a where a < 3'; ij> call SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.language.bulkFetchDefault', '16'); 0 rows inserted/updated/deleted ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A ----------- 1 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,1) |GRANT|ACTIVE ij> next scan_cursor; No current row ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE ij> close scan_cursor; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> -------------------------------------------------------------------------------- -- TEST 7: btree cursor scan, group fetch = 2 (scan with "<" qualifier) -- Test "less than" qualified cursor scan on a data set. -- ALL MODES - TABLE IS, "scan page lockname of form (pageno, 1) -- SERIALIZABLE - row S locks as it visits each row, held until end xact -- REPEATABLE READ - row S locks as it visits each row, held until end xact -- READ COMMITTED - row S lock on current row, released on move to next row -- READ UNCOMMITTED - no row locks. -- -- At this point the base table should look like: -- 1, 10, 'one' -- 3, 30, 'three' -- 5, 50, 'five' -- 7, 70, 'seven' -------------------------------------------------------------------------------- CALL SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.language.bulkFetchDefault','2'); 0 rows inserted/updated/deleted ij> -- RESOLVE: missing row locks -- WORKAROUND: creating an index and dropping it -- to force the statement to be recompiled create index ix1 on a(a); 0 rows inserted/updated/deleted WARNING 01504: The new index is a duplicate of an existing index: A_IDX. ij> drop index ix1; ERROR 42X65: Index 'IX1' does not exist. ij> commit; ij> get cursor scan_cursor as 'select a from a where a < 3'; ij> call SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.language.bulkFetchDefault', '16'); 0 rows inserted/updated/deleted ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A ----------- 1 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; No current row ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE ij> close scan_cursor; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> -------------------------------------------------------------------------------- -- TEST 8: btree cursor scan, group fetch = 1 (scan with equals qualifier) -- Test "equals" qualified cursor scan on a data set. -- ALL MODES - TABLE IS, "scan page lockname of form (pageno, 1) -- SERIALIZABLE - row S locks as it visits each row, held until end xact -- REPEATABLE READ - row S locks as it visits each row, held until end xact -- READ COMMITTED - row S lock on current row, released on move to next row -- READ UNCOMMITTED - no row locks. -- -- At this point the base table should look like: -- 1, 10, 'one' -- 3, 30, 'three' -- 5, 50, 'five' -- 7, 70, 'seven' -------------------------------------------------------------------------------- CALL SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.language.bulkFetchDefault','1'); 0 rows inserted/updated/deleted ij> -- RESOLVE: missing row locks -- WORKAROUND: creating an index and dropping it -- to force the statement to be recompiled create index ix1 on a(a); 0 rows inserted/updated/deleted WARNING 01504: The new index is a duplicate of an existing index: A_IDX. ij> drop index ix1; ERROR 42X65: Index 'IX1' does not exist. ij> commit; ij> get cursor scan_cursor as 'select a from a where a = 5'; ij> call SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.language.bulkFetchDefault', '16'); 0 rows inserted/updated/deleted ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A ----------- 5 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,1) |GRANT|ACTIVE ij> next scan_cursor; No current row ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,1) |GRANT|ACTIVE ij> close scan_cursor; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> -------------------------------------------------------------------------------- -- TEST 9: btree cursor scan, group fetch = 2 (scan with equals qualifier) -- Test "equals" qualified cursor scan on a data set. -- ALL MODES - TABLE IS, "scan page lockname of form (pageno, 1) -- SERIALIZABLE - row S locks as it visits each row, held until end xact -- REPEATABLE READ - row S locks as it visits each row, held until end xact -- READ COMMITTED - row S lock on current row, released on move to next row -- READ UNCOMMITTED - no row locks. -- -- At this point the base table should look like: -- 1, 10, 'one' -- 3, 30, 'three' -- 5, 50, 'five' -- 7, 70, 'seven' -------------------------------------------------------------------------------- CALL SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.language.bulkFetchDefault','2'); 0 rows inserted/updated/deleted ij> -- RESOLVE: missing row locks -- WORKAROUND: creating an index and dropping it -- to force the statement to be recompiled create index ix1 on a(a); 0 rows inserted/updated/deleted WARNING 01504: The new index is a duplicate of an existing index: A_IDX. ij> drop index ix1; ERROR 42X65: Index 'IX1' does not exist. ij> commit; ij> get cursor scan_cursor as 'select a from a where a = 5 or a = 7'; ij> call SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.language.bulkFetchDefault', '16'); 0 rows inserted/updated/deleted ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A ----------- 5 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,1) |GRANT|ACTIVE ij> next scan_cursor; A ----------- 7 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,1) |GRANT|ACTIVE ij> close scan_cursor; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> -------------------------------------------------------------------------------- -- TEST 10: btree cursor scan, group fetch = 1 (equals qualifier, no rows return) -- Test "equals" qualified cursor scan on a data set, no rows returned. -- ALL MODES - TABLE IS, "scan page lockname of form (pageno, 1) -- SERIALIZABLE - row S locks as it visits each row, held until end xact -- REPEATABLE READ - row S locks as it visits each row, held until end xact -- READ COMMITTED - row S lock on current row, released on move to next row -- READ UNCOMMITTED - no row locks. -- -- At this point the base table should look like: -- 1, 10, 'one' -- 3, 30, 'three' -- 5, 50, 'five' -- 7, 70, 'seven' -------------------------------------------------------------------------------- -- no rows expected to qualify CALL SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.language.bulkFetchDefault','1'); 0 rows inserted/updated/deleted ij> -- RESOLVE: missing row locks -- WORKAROUND: creating an index and dropping it -- to force the statement to be recompiled create index ix1 on a(a); 0 rows inserted/updated/deleted WARNING 01504: The new index is a duplicate of an existing index: A_IDX. ij> drop index ix1; ERROR 42X65: Index 'IX1' does not exist. ij> commit; ij> get cursor scan_cursor as 'select a from a where a = 42'; ij> call SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.language.bulkFetchDefault', '16'); 0 rows inserted/updated/deleted ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; No current row ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; No current row ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE ij> close scan_cursor; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> drop table a; 0 rows inserted/updated/deleted ij> -- cursor, non-unique index run drop table a; ERROR 42Y55: 'DROP TABLE' cannot be performed on 'A' because it does not exist. ij> -- to create tables of page size 4k and still keep the following tbl -- create table a (a int, b int, c varchar(1900)); create table a(a int, b int); 0 rows inserted/updated/deleted ij> alter table a add column c varchar(1900); 0 rows inserted/updated/deleted ij> insert into a values (1, 10, 'one'); 1 row inserted/updated/deleted ij> insert into a values (2, 20, 'two'); 1 row inserted/updated/deleted ij> insert into a values (3, 30, 'three'); 1 row inserted/updated/deleted ij> insert into a values (4, 40, 'four'); 1 row inserted/updated/deleted ij> insert into a values (5, 50, 'five'); 1 row inserted/updated/deleted ij> insert into a values (6, 60, 'six'); 1 row inserted/updated/deleted ij> insert into a values (7, 70, 'seven'); 1 row inserted/updated/deleted ij> create index a_idx on a (a); 0 rows inserted/updated/deleted ij> commit; ij> run resource 'readBtreeCursorLocks.subsql'; 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. -- -- Very basic single user testing of read locks on cursors on indexes. -- This ".subsql" test is -- meant to be run from another test such that it gets run under multiple -- isolation levels. This is important as they behave -- differently, depending on isolation levels. -- -- assume's caller has already done: run 'LockTableQuery.subsql'; to get -- easy access to the lock VTI. -- TEST 0: btree cursor scan, group fetch = 1 -- TEST 1: btree cursor scan, group fetch = 2 -- TEST 2: btree cursor scan, group fetch = 1 stop scan in middle of set -- TEST 3: btree cursor scan, group fetch = 4 stop scan in middle of set -- TEST 4: btree cursor scan, group fetch = 1 (scan with some deleted rows) -- TEST 5: btree cursor scan, group fetch = 2(scan with committed deleted rows) -- TEST 6: btree cursor scan, group fetch = 1 (scan with "<" qualifier) -- TEST 7: btree cursor scan, group fetch = 2 (scan with "<" qualifier) -- TEST 8: btree cursor scan, group fetch = 1 (scan with equals qualifier) -- TEST 9: btree cursor scan, group fetch = 2 (scan with equals qualifier) -- TEST 10: btree cursor scan, group fetch = 1 ("=" qualifier, no rows return) autocommit off; ij> -------------------------------------------------------------------------------- -- Assumes that calling routine has set up the following simple dataset, -- a heap, and index with following initial values: -- create table a (a int, b int, c somesortofchar, [index_pad]); -- create index a_idx on a (a) or a_idx on a (a, index_pad); -- -- 1, 10, 'one' -- 2, 20, 'two' -- 3, 30, 'three' -- 4, 40, 'four' -- 5, 50, 'five' -- 6, 60, 'six' -- 7, 70, 'seven' -------------------------------------------------------------------------------- select * from a; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 1 |10 |one 2 |20 |two 3 |30 |three 4 |40 |four 5 |50 |five 6 |60 |six 7 |70 |seven ij> commit; ij> -------------------------------------------------------------------------------- -- TEST 0: btree cursor scan, group fetch = 1 -- Test full cursor scan which does no updates. -- ALL MODES - TABLE IS, "scan page lockname of form (pageno, 1) -- SERIALIZABLE - row S locks as it visits each row, held until end xact -- REPEATABLE READ - row S locks as it visits each row, held until end xact -- READ COMMITTED - row S lock on current row, released on move to next row -- READ UNCOMMITTED - no row locks. ------------------------------------------------------------------------------- CALL SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.language.bulkFetchDefault','1'); 0 rows inserted/updated/deleted ij> -- RESOLVE: missing row locks -- WORKAROUND: creating an index and dropping it -- to force the statement to be recompiled create index ix1 on a(a); 0 rows inserted/updated/deleted WARNING 01504: The new index is a duplicate of an existing index: A_IDX. ij> drop index ix1; ERROR 42X65: Index 'IX1' does not exist. ij> commit; ij> get cursor scan_cursor as 'select a from a'; ij> call SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.language.bulkFetchDefault', '16'); 0 rows inserted/updated/deleted ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A ----------- 1 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,1) |GRANT|ACTIVE ij> next scan_cursor; A ----------- 2 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,1) |GRANT|ACTIVE ij> next scan_cursor; A ----------- 3 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,1) |GRANT|ACTIVE ij> next scan_cursor; A ----------- 4 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,1) |GRANT|ACTIVE ij> next scan_cursor; A ----------- 5 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,1) |GRANT|ACTIVE ij> next scan_cursor; A ----------- 6 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,1) |GRANT|ACTIVE ij> next scan_cursor; A ----------- 7 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,1) |GRANT|ACTIVE ij> next scan_cursor; No current row ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE ij> close scan_cursor; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> -------------------------------------------------------------------------------- -- TEST 1: btree cursor scan, group fetch = 2 -- Test full cursor scan which does no updates. -- ALL MODES - TABLE IS, "scan page lockname of form (pageno, 1) -- SERIALIZABLE - row S locks as it visits each row, held until end xact -- REPEATABLE READ - row S locks as it visits each row, held until end xact -- READ COMMITTED - row S lock on current row, released on move to next row -- READ UNCOMMITTED - no row locks. -------------------------------------------------------------------------------- CALL SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.language.bulkFetchDefault','2'); 0 rows inserted/updated/deleted ij> -- RESOLVE: missing row locks -- WORKAROUND: creating an index and dropping it -- to force the statement to be recompiled create index ix1 on a(a); 0 rows inserted/updated/deleted WARNING 01504: The new index is a duplicate of an existing index: A_IDX. ij> drop index ix1; ERROR 42X65: Index 'IX1' does not exist. ij> commit; ij> get cursor scan_cursor as 'select a from a'; ij> call SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.language.bulkFetchDefault', '16'); 0 rows inserted/updated/deleted ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A ----------- 1 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,1) |GRANT|ACTIVE ij> next scan_cursor; A ----------- 2 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,1) |GRANT|ACTIVE ij> next scan_cursor; A ----------- 3 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,1) |GRANT|ACTIVE ij> next scan_cursor; A ----------- 4 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,1) |GRANT|ACTIVE ij> next scan_cursor; A ----------- 5 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,1) |GRANT|ACTIVE ij> next scan_cursor; A ----------- 6 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,1) |GRANT|ACTIVE ij> next scan_cursor; A ----------- 7 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; No current row ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE ij> close scan_cursor; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> -------------------------------------------------------------------------------- -- TEST 2: btree cursor scan, group fetch = 1, stop scan in middle of set -- Test full cursor scan which does no updates. -- ALL MODES - TABLE IS, "scan page lockname of form (pageno, 1) -- SERIALIZABLE - row S locks as it visits each row, held until end xact -- REPEATABLE READ - row S locks as it visits each row, held until end xact -- READ COMMITTED - row S lock on current row, released on move to next row -- READ UNCOMMITTED - no row locks. -------------------------------------------------------------------------------- CALL SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.language.bulkFetchDefault','1'); 0 rows inserted/updated/deleted ij> -- RESOLVE: missing row locks -- WORKAROUND: creating an index and dropping it -- to force the statement to be recompiled create index ix1 on a(a); 0 rows inserted/updated/deleted WARNING 01504: The new index is a duplicate of an existing index: A_IDX. ij> drop index ix1; ERROR 42X65: Index 'IX1' does not exist. ij> commit; ij> get cursor scan_cursor as 'select a from a'; ij> call SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.language.bulkFetchDefault', '16'); 0 rows inserted/updated/deleted ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A ----------- 1 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,1) |GRANT|ACTIVE ij> next scan_cursor; A ----------- 2 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,1) |GRANT|ACTIVE ij> close scan_cursor; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> -------------------------------------------------------------------------------- -- TEST 3: btree cursor scan, group fetch = 4, stop scan in middle of set -- Test full cursor scan which does no updates. -- ALL MODES - TABLE IS, "scan page lockname of form (pageno, 1) -- SERIALIZABLE - row S locks as it visits each row, held until end xact -- REPEATABLE READ - row S locks as it visits each row, held until end xact -- READ COMMITTED - row S lock on current row, released on move to next row -- READ UNCOMMITTED - no row locks. -------------------------------------------------------------------------------- CALL SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.language.bulkFetchDefault','4'); 0 rows inserted/updated/deleted ij> -- RESOLVE: missing row locks -- WORKAROUND: creating an index and dropping it -- to force the statement to be recompiled create index ix1 on a(a); 0 rows inserted/updated/deleted WARNING 01504: The new index is a duplicate of an existing index: A_IDX. ij> drop index ix1; ERROR 42X65: Index 'IX1' does not exist. ij> commit; ij> get cursor scan_cursor as 'select a from a'; ij> call SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.language.bulkFetchDefault', '16'); 0 rows inserted/updated/deleted ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A ----------- 1 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,1) |GRANT|ACTIVE ij> next scan_cursor; A ----------- 2 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,1) |GRANT|ACTIVE ij> close scan_cursor; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> -------------------------------------------------------------------------------- -- TEST 4: btree cursor scan, group fetch = 1 (scan table with some deleted rows) -- Test full cursor scan on a data set with some deleted rows (the "even" ones). -- ALL MODES - TABLE IS, "scan page lockname of form (pageno, 1) -- SERIALIZABLE - row S locks as it visits each row, held until end xact -- REPEATABLE READ - row S locks as it visits each row, held until end xact -- READ COMMITTED - row S lock on current row, released on move to next row -- READ UNCOMMITTED - no row locks. -- -- After the delete the base table should look like: -- 1, 10, 'one' -- 3, 30, 'three' -- 5, 50, 'five' -- 7, 70, 'seven' -------------------------------------------------------------------------------- delete from a where a = 2 or a = 4 or a = 6; 3 rows inserted/updated/deleted ij> commit; ij> CALL SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.language.bulkFetchDefault','1'); 0 rows inserted/updated/deleted ij> -- RESOLVE: missing row locks -- WORKAROUND: creating an index and dropping it -- to force the statement to be recompiled create index ix1 on a(a); 0 rows inserted/updated/deleted WARNING 01504: The new index is a duplicate of an existing index: A_IDX. ij> drop index ix1; ERROR 42X65: Index 'IX1' does not exist. ij> commit; ij> get cursor scan_cursor as 'select a from a'; ij> call SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.language.bulkFetchDefault', '16'); 0 rows inserted/updated/deleted ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A ----------- 1 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,1) |GRANT|ACTIVE ij> next scan_cursor; A ----------- 3 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,1) |GRANT|ACTIVE ij> next scan_cursor; A ----------- 5 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,1) |GRANT|ACTIVE ij> next scan_cursor; A ----------- 7 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,1) |GRANT|ACTIVE ij> next scan_cursor; No current row ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE ij> close scan_cursor; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> -------------------------------------------------------------------------------- -- TEST 5: btree cursor scan, group fetch = 2 (scan with committed deleted rows) -- Test full cursor scan on a data set with some deleted rows (the "even" ones). -- ALL MODES - TABLE IS, "scan page lockname of form (pageno, 1) -- SERIALIZABLE - row S locks as it visits each row, held until end xact -- REPEATABLE READ - row S locks as it visits each row, held until end xact -- READ COMMITTED - row S lock on current row, released on move to next row -- READ UNCOMMITTED - no row locks. -- -- At this point the base table should look like: -- 1, 10, 'one' -- 3, 30, 'three' -- 5, 50, 'five' -- 7, 70, 'seven' -------------------------------------------------------------------------------- CALL SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.language.bulkFetchDefault','2'); 0 rows inserted/updated/deleted ij> -- RESOLVE: missing row locks -- WORKAROUND: creating an index and dropping it -- to force the statement to be recompiled create index ix1 on a(a); 0 rows inserted/updated/deleted WARNING 01504: The new index is a duplicate of an existing index: A_IDX. ij> drop index ix1; ERROR 42X65: Index 'IX1' does not exist. ij> commit; ij> get cursor scan_cursor as 'select a from a'; ij> call SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.language.bulkFetchDefault', '16'); 0 rows inserted/updated/deleted ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A ----------- 1 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,1) |GRANT|ACTIVE ij> next scan_cursor; A ----------- 3 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,1) |GRANT|ACTIVE ij> next scan_cursor; A ----------- 5 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,1) |GRANT|ACTIVE ij> next scan_cursor; A ----------- 7 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,1) |GRANT|ACTIVE ij> next scan_cursor; No current row ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE ij> close scan_cursor; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> -------------------------------------------------------------------------------- -- TEST 6: btree cursor scan, group fetch = 1 (scan with "<" qualifier) -- Test "less than" qualified cursor scan on a data set. -- ALL MODES - TABLE IS, "scan page lockname of form (pageno, 1) -- SERIALIZABLE - row S locks as it visits each row, held until end xact -- REPEATABLE READ - row S locks as it visits each row, held until end xact -- READ COMMITTED - row S lock on current row, released on move to next row -- READ UNCOMMITTED - no row locks. -- -- At this point the base table should look like: -- 1, 10, 'one' -- 3, 30, 'three' -- 5, 50, 'five' -- 7, 70, 'seven' -------------------------------------------------------------------------------- CALL SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.language.bulkFetchDefault','1'); 0 rows inserted/updated/deleted ij> -- RESOLVE: missing row locks -- WORKAROUND: creating an index and dropping it -- to force the statement to be recompiled create index ix1 on a(a); 0 rows inserted/updated/deleted WARNING 01504: The new index is a duplicate of an existing index: A_IDX. ij> drop index ix1; ERROR 42X65: Index 'IX1' does not exist. ij> commit; ij> get cursor scan_cursor as 'select a from a where a < 3'; ij> call SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.language.bulkFetchDefault', '16'); 0 rows inserted/updated/deleted ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A ----------- 1 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,1) |GRANT|ACTIVE ij> next scan_cursor; No current row ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE ij> close scan_cursor; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> -------------------------------------------------------------------------------- -- TEST 7: btree cursor scan, group fetch = 2 (scan with "<" qualifier) -- Test "less than" qualified cursor scan on a data set. -- ALL MODES - TABLE IS, "scan page lockname of form (pageno, 1) -- SERIALIZABLE - row S locks as it visits each row, held until end xact -- REPEATABLE READ - row S locks as it visits each row, held until end xact -- READ COMMITTED - row S lock on current row, released on move to next row -- READ UNCOMMITTED - no row locks. -- -- At this point the base table should look like: -- 1, 10, 'one' -- 3, 30, 'three' -- 5, 50, 'five' -- 7, 70, 'seven' -------------------------------------------------------------------------------- CALL SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.language.bulkFetchDefault','2'); 0 rows inserted/updated/deleted ij> -- RESOLVE: missing row locks -- WORKAROUND: creating an index and dropping it -- to force the statement to be recompiled create index ix1 on a(a); 0 rows inserted/updated/deleted WARNING 01504: The new index is a duplicate of an existing index: A_IDX. ij> drop index ix1; ERROR 42X65: Index 'IX1' does not exist. ij> commit; ij> get cursor scan_cursor as 'select a from a where a < 3'; ij> call SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.language.bulkFetchDefault', '16'); 0 rows inserted/updated/deleted ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A ----------- 1 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; No current row ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE ij> close scan_cursor; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> -------------------------------------------------------------------------------- -- TEST 8: btree cursor scan, group fetch = 1 (scan with equals qualifier) -- Test "equals" qualified cursor scan on a data set. -- ALL MODES - TABLE IS, "scan page lockname of form (pageno, 1) -- SERIALIZABLE - row S locks as it visits each row, held until end xact -- REPEATABLE READ - row S locks as it visits each row, held until end xact -- READ COMMITTED - row S lock on current row, released on move to next row -- READ UNCOMMITTED - no row locks. -- -- At this point the base table should look like: -- 1, 10, 'one' -- 3, 30, 'three' -- 5, 50, 'five' -- 7, 70, 'seven' -------------------------------------------------------------------------------- CALL SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.language.bulkFetchDefault','1'); 0 rows inserted/updated/deleted ij> -- RESOLVE: missing row locks -- WORKAROUND: creating an index and dropping it -- to force the statement to be recompiled create index ix1 on a(a); 0 rows inserted/updated/deleted WARNING 01504: The new index is a duplicate of an existing index: A_IDX. ij> drop index ix1; ERROR 42X65: Index 'IX1' does not exist. ij> commit; ij> get cursor scan_cursor as 'select a from a where a = 5'; ij> call SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.language.bulkFetchDefault', '16'); 0 rows inserted/updated/deleted ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A ----------- 5 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,1) |GRANT|ACTIVE ij> next scan_cursor; No current row ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE ij> close scan_cursor; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> -------------------------------------------------------------------------------- -- TEST 9: btree cursor scan, group fetch = 2 (scan with equals qualifier) -- Test "equals" qualified cursor scan on a data set. -- ALL MODES - TABLE IS, "scan page lockname of form (pageno, 1) -- SERIALIZABLE - row S locks as it visits each row, held until end xact -- REPEATABLE READ - row S locks as it visits each row, held until end xact -- READ COMMITTED - row S lock on current row, released on move to next row -- READ UNCOMMITTED - no row locks. -- -- At this point the base table should look like: -- 1, 10, 'one' -- 3, 30, 'three' -- 5, 50, 'five' -- 7, 70, 'seven' -------------------------------------------------------------------------------- CALL SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.language.bulkFetchDefault','2'); 0 rows inserted/updated/deleted ij> -- RESOLVE: missing row locks -- WORKAROUND: creating an index and dropping it -- to force the statement to be recompiled create index ix1 on a(a); 0 rows inserted/updated/deleted WARNING 01504: The new index is a duplicate of an existing index: A_IDX. ij> drop index ix1; ERROR 42X65: Index 'IX1' does not exist. ij> commit; ij> get cursor scan_cursor as 'select a from a where a = 5 or a = 7'; ij> call SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.language.bulkFetchDefault', '16'); 0 rows inserted/updated/deleted ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A ----------- 5 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,1) |GRANT|ACTIVE ij> next scan_cursor; A ----------- 7 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,1) |GRANT|ACTIVE ij> close scan_cursor; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> -------------------------------------------------------------------------------- -- TEST 10: btree cursor scan, group fetch = 1 (equals qualifier, no rows return) -- Test "equals" qualified cursor scan on a data set, no rows returned. -- ALL MODES - TABLE IS, "scan page lockname of form (pageno, 1) -- SERIALIZABLE - row S locks as it visits each row, held until end xact -- REPEATABLE READ - row S locks as it visits each row, held until end xact -- READ COMMITTED - row S lock on current row, released on move to next row -- READ UNCOMMITTED - no row locks. -- -- At this point the base table should look like: -- 1, 10, 'one' -- 3, 30, 'three' -- 5, 50, 'five' -- 7, 70, 'seven' -------------------------------------------------------------------------------- -- no rows expected to qualify CALL SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.language.bulkFetchDefault','1'); 0 rows inserted/updated/deleted ij> -- RESOLVE: missing row locks -- WORKAROUND: creating an index and dropping it -- to force the statement to be recompiled create index ix1 on a(a); 0 rows inserted/updated/deleted WARNING 01504: The new index is a duplicate of an existing index: A_IDX. ij> drop index ix1; ERROR 42X65: Index 'IX1' does not exist. ij> commit; ij> get cursor scan_cursor as 'select a from a where a = 42'; ij> call SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.language.bulkFetchDefault', '16'); 0 rows inserted/updated/deleted ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; No current row ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; No current row ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE ij> close scan_cursor; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> drop table a; 0 rows inserted/updated/deleted ij> -- non cursor, unique index run drop table a; ERROR 42Y55: 'DROP TABLE' cannot be performed on 'A' because it does not exist. ij> -- to create tables of page size 4k and still keep the following tbl -- create table a (a int, b int, c varchar(1900)); create table a(a int, b int); 0 rows inserted/updated/deleted ij> alter table a add column c varchar(1900); 0 rows inserted/updated/deleted ij> insert into a values (1, 10, 'one'); 1 row inserted/updated/deleted ij> insert into a values (2, 20, 'two'); 1 row inserted/updated/deleted ij> insert into a values (3, 30, 'three'); 1 row inserted/updated/deleted ij> insert into a values (4, 40, 'four'); 1 row inserted/updated/deleted ij> insert into a values (5, 50, 'five'); 1 row inserted/updated/deleted ij> insert into a values (6, 60, 'six'); 1 row inserted/updated/deleted ij> insert into a values (7, 70, 'seven'); 1 row inserted/updated/deleted ij> create unique index a_idx on a (a); 0 rows inserted/updated/deleted ij> commit; ij> run resource 'readBtreeSetLocks.subsql'; 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. -- -- Basic single user testing of read locks on select "set" queries on indexes. -- -- This ".subsql" test is -- meant to be run from another test such that it gets run under multiple -- isolation levels. This is important as they behave -- differently, depending on isolation levels. -- -- assume's caller has already done: run 'LockTableQuery.subsql'; to get -- easy access to the lock VTI. -- TEST 0: btree scan -- TEST 1: btree scan, (scan table with some deleted rows) -- TEST 2: btree scan, (scan with "<" qualifier) -- TEST 3: btree scan, (scan with equals qualifier) -- TEST 4: btree scan, (equals qualifier, no rows return) autocommit off; ij> -------------------------------------------------------------------------------- -- Assumes that calling routine has set up the following simple dataset, -- a heap, and index with following initial values: -- create table a (a int, b int, c somesortofchar, [index_pad]); -- create index a_idx on a (a) or a_idx on a (a, index_pad); -- -- 1, 10, 'one' -- 2, 20, 'two' -- 3, 30, 'three' -- 4, 40, 'four' -- 5, 50, 'five' -- 6, 60, 'six' -- 7, 70, 'seven' -------------------------------------------------------------------------------- select * from a; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 1 |10 |one 2 |20 |two 3 |30 |three 4 |40 |four 5 |50 |five 6 |60 |six 7 |70 |seven ij> commit; ij> -------------------------------------------------------------------------------- -- TEST 0: btree scan -- Test full scan. -- ALL MODES - TABLE IS, "scan page lockname of form (pageno, 1) -- SERIALIZABLE - row S locks as it visits each row, row/table lock -- held until end xact. Also holds one previous key lock. -- REPEATABLE READ - row S locks as it visits each row, row/table locks held -- until end of transaction. -- READ COMMITTED - instantaneous S locks requested on each row. No locks -- held after query finishes. -- READ UNCOMMITTED - no row locks. No locks held after query finishes. -------------------------------------------------------------------------------- select a from a; A ----------- 1 2 3 4 5 6 7 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> -------------------------------------------------------------------------------- -- TEST 1: btree scan, (scan table with some deleted rows) -- Test full scan on a data set with some deleted rows (the "even" ones). -- ALL MODES - TABLE IS, "scan page lockname of form (pageno, 1) -- SERIALIZABLE - row S locks as it visits each row, row/table lock -- held until end xact. Also holds one previous key lock. -- REPEATABLE READ - row S locks as it visits each row, row/table locks held -- until end of transaction. -- READ COMMITTED - instantaneous S locks requested on each row. No locks -- held after query finishes. -- READ UNCOMMITTED - no row locks. No locks held after query finishes. -- -- After the delete the base table should look like: -- 1, 10, 'one' -- 3, 30, 'three' -- 5, 50, 'five' -- 7, 70, 'seven' -------------------------------------------------------------------------------- delete from a where a = 2 or a = 4 or a = 6; 3 rows inserted/updated/deleted ij> commit; ij> -- The above delete and commit can allow post commit processing to run before -- the subsequent select is run, most likely if this run is on a table where -- there is one row per page. To get reproducible results from the subsequent -- lock calls, wait for post commit to finish before running the select. -- Without this wait "extra" locks sometimes might show up - these are locks -- on the committed deleted rows which have not been cleaned yet depending -- on timing. CALL WAIT_FOR_POST_COMMIT(); 0 rows inserted/updated/deleted ij> select a from a; A ----------- 1 3 5 7 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> -------------------------------------------------------------------------------- -- TEST 2: btree scan, (scan with "<" qualifier) -- Test "less than" qualified scan on a data set. -- ALL MODES - TABLE IS, "scan page lockname of form (pageno, 1) -- SERIALIZABLE - row S locks as it visits each row, row/table lock -- held until end xact. Also holds one previous key lock. -- REPEATABLE READ - row S locks as it visits each row, row/table locks held -- until end of transaction. -- READ COMMITTED - instantaneous S locks requested on each row. No locks -- held after query finishes. -- READ UNCOMMITTED - no row locks. No locks held after query finishes. -- -- At this point the base table should look like: -- 1, 10, 'one' -- 3, 30, 'three' -- 5, 50, 'five' -- 7, 70, 'seven' -------------------------------------------------------------------------------- select a from a where a < 3; A ----------- 1 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> -------------------------------------------------------------------------------- -- TEST 3: btree scan, (scan with equals qualifier) -- Test "equals" qualified cursor scan on a data set. -- ALL MODES - TABLE IS, "scan page lockname of form (pageno, 1) -- SERIALIZABLE - row S locks as it visits each row, row/table lock -- held until end xact. Also holds one previous key lock. -- REPEATABLE READ - row S locks as it visits each row, row/table locks held -- until end of transaction. -- READ COMMITTED - instantaneous S locks requested on each row. No locks -- held after query finishes. -- READ UNCOMMITTED - no row locks. No locks held after query finishes. -- -- At this point the base table should look like: -- 1, 10, 'one' -- 3, 30, 'three' -- 5, 50, 'five' -- 7, 70, 'seven' -------------------------------------------------------------------------------- select a from a where a = 5; A ----------- 5 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> -------------------------------------------------------------------------------- -- TEST 4: btree scan, (equals qualifier, no rows return) -- Test "equals" qualified scan on a data set, no rows returned. -- ALL MODES - TABLE IS, "scan page lockname of form (pageno, 1) -- SERIALIZABLE - row S locks as it visits each row, row/table lock -- held until end xact. Also holds one previous key lock. -- REPEATABLE READ - row S locks as it visits each row, row/table locks held -- until end of transaction. -- READ COMMITTED - instantaneous S locks requested on each row. No locks -- held after query finishes. -- READ UNCOMMITTED - no row locks. No locks held after query finishes. -- -- At this point the base table should look like: -- 1, 10, 'one' -- 3, 30, 'three' -- 5, 50, 'five' -- 7, 70, 'seven' -------------------------------------------------------------------------------- -- no rows expected to qualify select a from a where a = 42; A ----------- ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> drop table a; 0 rows inserted/updated/deleted ij> -- non cursor, non-unique index run drop table a; ERROR 42Y55: 'DROP TABLE' cannot be performed on 'A' because it does not exist. ij> -- to create tables of page size 4k and still keep the following tbl -- create table a (a int, b int, c varchar(1900)); create table a(a int, b int); 0 rows inserted/updated/deleted ij> alter table a add column c varchar(1900); 0 rows inserted/updated/deleted ij> insert into a values (1, 10, 'one'); 1 row inserted/updated/deleted ij> insert into a values (2, 20, 'two'); 1 row inserted/updated/deleted ij> insert into a values (3, 30, 'three'); 1 row inserted/updated/deleted ij> insert into a values (4, 40, 'four'); 1 row inserted/updated/deleted ij> insert into a values (5, 50, 'five'); 1 row inserted/updated/deleted ij> insert into a values (6, 60, 'six'); 1 row inserted/updated/deleted ij> insert into a values (7, 70, 'seven'); 1 row inserted/updated/deleted ij> create index a_idx on a (a); 0 rows inserted/updated/deleted ij> commit; ij> run resource 'readBtreeSetLocks.subsql'; 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. -- -- Basic single user testing of read locks on select "set" queries on indexes. -- -- This ".subsql" test is -- meant to be run from another test such that it gets run under multiple -- isolation levels. This is important as they behave -- differently, depending on isolation levels. -- -- assume's caller has already done: run 'LockTableQuery.subsql'; to get -- easy access to the lock VTI. -- TEST 0: btree scan -- TEST 1: btree scan, (scan table with some deleted rows) -- TEST 2: btree scan, (scan with "<" qualifier) -- TEST 3: btree scan, (scan with equals qualifier) -- TEST 4: btree scan, (equals qualifier, no rows return) autocommit off; ij> -------------------------------------------------------------------------------- -- Assumes that calling routine has set up the following simple dataset, -- a heap, and index with following initial values: -- create table a (a int, b int, c somesortofchar, [index_pad]); -- create index a_idx on a (a) or a_idx on a (a, index_pad); -- -- 1, 10, 'one' -- 2, 20, 'two' -- 3, 30, 'three' -- 4, 40, 'four' -- 5, 50, 'five' -- 6, 60, 'six' -- 7, 70, 'seven' -------------------------------------------------------------------------------- select * from a; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 1 |10 |one 2 |20 |two 3 |30 |three 4 |40 |four 5 |50 |five 6 |60 |six 7 |70 |seven ij> commit; ij> -------------------------------------------------------------------------------- -- TEST 0: btree scan -- Test full scan. -- ALL MODES - TABLE IS, "scan page lockname of form (pageno, 1) -- SERIALIZABLE - row S locks as it visits each row, row/table lock -- held until end xact. Also holds one previous key lock. -- REPEATABLE READ - row S locks as it visits each row, row/table locks held -- until end of transaction. -- READ COMMITTED - instantaneous S locks requested on each row. No locks -- held after query finishes. -- READ UNCOMMITTED - no row locks. No locks held after query finishes. -------------------------------------------------------------------------------- select a from a; A ----------- 1 2 3 4 5 6 7 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> -------------------------------------------------------------------------------- -- TEST 1: btree scan, (scan table with some deleted rows) -- Test full scan on a data set with some deleted rows (the "even" ones). -- ALL MODES - TABLE IS, "scan page lockname of form (pageno, 1) -- SERIALIZABLE - row S locks as it visits each row, row/table lock -- held until end xact. Also holds one previous key lock. -- REPEATABLE READ - row S locks as it visits each row, row/table locks held -- until end of transaction. -- READ COMMITTED - instantaneous S locks requested on each row. No locks -- held after query finishes. -- READ UNCOMMITTED - no row locks. No locks held after query finishes. -- -- After the delete the base table should look like: -- 1, 10, 'one' -- 3, 30, 'three' -- 5, 50, 'five' -- 7, 70, 'seven' -------------------------------------------------------------------------------- delete from a where a = 2 or a = 4 or a = 6; 3 rows inserted/updated/deleted ij> commit; ij> -- The above delete and commit can allow post commit processing to run before -- the subsequent select is run, most likely if this run is on a table where -- there is one row per page. To get reproducible results from the subsequent -- lock calls, wait for post commit to finish before running the select. -- Without this wait "extra" locks sometimes might show up - these are locks -- on the committed deleted rows which have not been cleaned yet depending -- on timing. CALL WAIT_FOR_POST_COMMIT(); 0 rows inserted/updated/deleted ij> select a from a; A ----------- 1 3 5 7 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> -------------------------------------------------------------------------------- -- TEST 2: btree scan, (scan with "<" qualifier) -- Test "less than" qualified scan on a data set. -- ALL MODES - TABLE IS, "scan page lockname of form (pageno, 1) -- SERIALIZABLE - row S locks as it visits each row, row/table lock -- held until end xact. Also holds one previous key lock. -- REPEATABLE READ - row S locks as it visits each row, row/table locks held -- until end of transaction. -- READ COMMITTED - instantaneous S locks requested on each row. No locks -- held after query finishes. -- READ UNCOMMITTED - no row locks. No locks held after query finishes. -- -- At this point the base table should look like: -- 1, 10, 'one' -- 3, 30, 'three' -- 5, 50, 'five' -- 7, 70, 'seven' -------------------------------------------------------------------------------- select a from a where a < 3; A ----------- 1 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> -------------------------------------------------------------------------------- -- TEST 3: btree scan, (scan with equals qualifier) -- Test "equals" qualified cursor scan on a data set. -- ALL MODES - TABLE IS, "scan page lockname of form (pageno, 1) -- SERIALIZABLE - row S locks as it visits each row, row/table lock -- held until end xact. Also holds one previous key lock. -- REPEATABLE READ - row S locks as it visits each row, row/table locks held -- until end of transaction. -- READ COMMITTED - instantaneous S locks requested on each row. No locks -- held after query finishes. -- READ UNCOMMITTED - no row locks. No locks held after query finishes. -- -- At this point the base table should look like: -- 1, 10, 'one' -- 3, 30, 'three' -- 5, 50, 'five' -- 7, 70, 'seven' -------------------------------------------------------------------------------- select a from a where a = 5; A ----------- 5 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> -------------------------------------------------------------------------------- -- TEST 4: btree scan, (equals qualifier, no rows return) -- Test "equals" qualified scan on a data set, no rows returned. -- ALL MODES - TABLE IS, "scan page lockname of form (pageno, 1) -- SERIALIZABLE - row S locks as it visits each row, row/table lock -- held until end xact. Also holds one previous key lock. -- REPEATABLE READ - row S locks as it visits each row, row/table locks held -- until end of transaction. -- READ COMMITTED - instantaneous S locks requested on each row. No locks -- held after query finishes. -- READ UNCOMMITTED - no row locks. No locks held after query finishes. -- -- At this point the base table should look like: -- 1, 10, 'one' -- 3, 30, 'three' -- 5, 50, 'five' -- 7, 70, 'seven' -------------------------------------------------------------------------------- -- no rows expected to qualify select a from a where a = 42; A ----------- ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> drop table a; 0 rows inserted/updated/deleted ij> -- run each test with rows across multiple pages in the interesting -- conglomerate (heap in the non-index tests, and in the index in the index -- based tests). -- cursor, no index run drop table a; ERROR 42Y55: 'DROP TABLE' cannot be performed on 'A' because it does not exist. ij> -- to create tables of page size 4k and still keep the following tbl -- create table a (a int, b int, c varchar(1900)); create table a(a int, b int); 0 rows inserted/updated/deleted ij> alter table a add column c varchar(1900); 0 rows inserted/updated/deleted ij> insert into a values (1, 10, 'one'); 1 row inserted/updated/deleted ij> insert into a values (2, 20, 'two'); 1 row inserted/updated/deleted ij> insert into a values (3, 30, 'three'); 1 row inserted/updated/deleted ij> insert into a values (4, 40, 'four'); 1 row inserted/updated/deleted ij> insert into a values (5, 50, 'five'); 1 row inserted/updated/deleted ij> insert into a values (6, 60, 'six'); 1 row inserted/updated/deleted ij> insert into a values (7, 70, 'seven'); 1 row inserted/updated/deleted ij> commit; ij> run resource 'readCursorLocks.subsql'; 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. -- -- Very basic single user testing of read locks on cursors on heap tables. -- This ".subsql" test is -- meant to be run from another test such that it gets run under multiple -- isolation levels. This is important as they behave -- differently, depending on isolation levels. -- -- assume's caller has already done: run 'LockTableQuery.subsql'; to get -- easy access to the lock VTI. -- TEST 0: heap cursor scan, group fetch = 1 -- TEST 1: heap cursor scan, group fetch = 2 -- TEST 2: heap cursor scan, group fetch = 1, stop scan in middle of set -- TEST 3: heap cursor scan, group fetch = 4, stop scan in middle of set -- TEST 4: heap cursor scan, group fetch = 1 (scan table with some deleted rows) -- TEST 5: heap cursor scan, group fetch = 2 (scan with committed deleted rows) -- TEST 6: heap cursor scan, group fetch = 1 (scan with "<" qualifier) -- TEST 7: heap cursor scan, group fetch = 2 (scan with "<" qualifier) -- TEST 8: heap cursor scan, group fetch = 1 (scan with equals qualifier) -- TEST 9: heap cursor scan, group fetch = 2 (scan with equals qualifier) -- TEST 10: heap cursor scan, group fetch = 1 (equals qualifier, no rows return) autocommit off; ij> -------------------------------------------------------------------------------- -- Assumes that calling routine has set up the following simple dataset, -- a heap, no indexes with following initial values: -- create table (a int, b int, c somesortofchar); -- 1, 10, 'one' -- 2, 20, 'two' -- 3, 30, 'three' -- 4, 40, 'four' -- 5, 50, 'five' -- 6, 60, 'six' -- 7, 70, 'seven' -------------------------------------------------------------------------------- select * from a; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 1 |10 |one 2 |20 |two 3 |30 |three 4 |40 |four 5 |50 |five 6 |60 |six 7 |70 |seven ij> commit; ij> -------------------------------------------------------------------------------- -- TEST 0: heap cursor scan, group fetch = 1 -- Test full cursor scan which does no updates. -- SERIALIZABLE - will get table level S lock. -- REPEATABLE READ - TABLE IS, will get row S locks as it visits each row. -- READ COMMITTED - TABLE IS, will hold single S lock on current row. -- READ UNCOMMITTED - TABLE IS, no row locks. -------------------------------------------------------------------------------- CALL SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.language.bulkFetchDefault','1'); 0 rows inserted/updated/deleted ij> get cursor scan_cursor as 'select a, b, c from a'; ij> call SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.language.bulkFetchDefault', '16'); 0 rows inserted/updated/deleted ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 1 |10 |one ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 2 |20 |two ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 3 |30 |three ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 4 |40 |four ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 5 |50 |five ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 6 |60 |six ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 7 |70 |seven ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; No current row ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE ij> close scan_cursor; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> -------------------------------------------------------------------------------- -- TEST 1: heap cursor scan, group fetch = 2 -- Test full cursor scan which does no updates. -- SERIALIZABLE - will get table level S lock. -- REPEATABLE READ - TABLE IS, will get row S locks as it visits each row. -- READ COMMITTED - TABLE IS, will get instantaneous locks and release -- READ UNCOMMITTED - TABLE IS, no row locks. -------------------------------------------------------------------------------- CALL SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.language.bulkFetchDefault','2'); 0 rows inserted/updated/deleted ij> -- RESOLVE: missing row locks -- WORKAROUND: creating an index and dropping it -- to force the query 'select a, b, c from a' to be recompiled create index ix1 on a(a); 0 rows inserted/updated/deleted ij> drop index ix1; 0 rows inserted/updated/deleted ij> commit; ij> get cursor scan_cursor as 'select a, b, c from a'; ij> call SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.language.bulkFetchDefault', '16'); 0 rows inserted/updated/deleted ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 1 |10 |one ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 2 |20 |two ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 3 |30 |three ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 4 |40 |four ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 5 |50 |five ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 6 |60 |six ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 7 |70 |seven ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; No current row ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE ij> close scan_cursor; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> -------------------------------------------------------------------------------- -- TEST 2: heap cursor scan, group fetch = 1, stop scan in middle of set -- Test full cursor scan which does no updates. -- SERIALIZABLE - will get table level S lock. -- REPEATABLE READ - TABLE IS, will get row S locks as it visits each row. -- READ COMMITTED - TABLE IS, will hold single S lock on current row. -- READ UNCOMMITTED - TABLE IS, no row locks. -------------------------------------------------------------------------------- CALL SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.language.bulkFetchDefault','1'); 0 rows inserted/updated/deleted ij> -- RESOLVE: missing row locks -- WORKAROUND: creating an index and dropping it -- to force the query 'select a, b, c from a' to be recompiled create index ix1 on a(a); 0 rows inserted/updated/deleted ij> drop index ix1; 0 rows inserted/updated/deleted ij> commit; ij> get cursor scan_cursor as 'select a, b, c from a'; ij> call SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.language.bulkFetchDefault', '16'); 0 rows inserted/updated/deleted ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 1 |10 |one ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 2 |20 |two ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE ij> close scan_cursor; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> -------------------------------------------------------------------------------- -- TEST 3: heap cursor scan, group fetch = 4, stop scan in middle of set -- Test full cursor scan which does no updates. -- SERIALIZABLE - will get table level S lock. -- REPEATABLE READ - TABLE IS, will get row S locks as it visits each row. -- READ COMMITTED - TABLE IS, will hold single S lock on current row. -- READ UNCOMMITTED - TABLE IS, no row locks. -------------------------------------------------------------------------------- CALL SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.language.bulkFetchDefault','4'); 0 rows inserted/updated/deleted ij> -- RESOLVE: missing row locks -- WORKAROUND: creating an index and dropping it -- to force the query 'select a, b, c from a' to be recompiled create index ix1 on a(a); 0 rows inserted/updated/deleted ij> drop index ix1; 0 rows inserted/updated/deleted ij> commit; ij> get cursor scan_cursor as 'select a, b, c from a'; ij> call SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.language.bulkFetchDefault', '16'); 0 rows inserted/updated/deleted ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 1 |10 |one ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 2 |20 |two ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE ij> close scan_cursor; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> -------------------------------------------------------------------------------- -- TEST 4: heap cursor scan, group fetch = 1 (scan table with some deleted rows) -- Test full cursor scan on a data set with some deleted rows (the "even" ones). -- SERIALIZABLE - will get table level S lock. -- REPEATABLE READ - TABLE IS, will get row S locks as it visits each row -- (including deleted ones). -- READ COMMITTED - TABLE IS, will get instantaneous locks and release -- READ UNCOMMITTED - TABLE IS, no row locks. -- -- After the delete the table should look like: -- 1, 10, 'one' -- 3, 30, 'three' -- 5, 50, 'five' -- 7, 70, 'seven' -------------------------------------------------------------------------------- delete from a where a = 2 or a = 4 or a = 6; 3 rows inserted/updated/deleted ij> commit; ij> CALL SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.language.bulkFetchDefault','1'); 0 rows inserted/updated/deleted ij> -- RESOLVE: missing row locks -- WORKAROUND: creating an index and dropping it -- to force the query 'select a, b, c from a' to be recompiled create index ix1 on a(a); 0 rows inserted/updated/deleted ij> drop index ix1; 0 rows inserted/updated/deleted ij> commit; ij> get cursor scan_cursor as 'select a, b, c from a'; ij> call SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.language.bulkFetchDefault', '16'); 0 rows inserted/updated/deleted ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 1 |10 |one ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 3 |30 |three ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 5 |50 |five ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 7 |70 |seven ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; No current row ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE ij> close scan_cursor; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> -------------------------------------------------------------------------------- -- TEST 5: heap cursor scan, group fetch = 2 (scan with committed deleted rows) -- Test full cursor scan on a data set with some deleted rows (the "even" ones). -- SERIALIZABLE - will get table level S lock. -- REPEATABLE READ - TABLE IS, will get row S locks as it visits each row -- (including deleted ones). -- READ COMMITTED - TABLE IS, will get instantaneous locks and release -- READ UNCOMMITTED - TABLE IS, no row locks. -- -- At this point the table should look like: -- 1, 10, 'one' -- 3, 30, 'three' -- 5, 50, 'five' -- 7, 70, 'seven' -------------------------------------------------------------------------------- CALL SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.language.bulkFetchDefault','2'); 0 rows inserted/updated/deleted ij> -- RESOLVE: missing row locks -- WORKAROUND: creating an index and dropping it -- to force the query 'select a, b, c from a' to be recompiled create index ix1 on a(a); 0 rows inserted/updated/deleted ij> drop index ix1; 0 rows inserted/updated/deleted ij> commit; ij> get cursor scan_cursor as 'select a, b, c from a'; ij> call SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.language.bulkFetchDefault', '16'); 0 rows inserted/updated/deleted ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 1 |10 |one ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 3 |30 |three ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 5 |50 |five ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 7 |70 |seven ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; No current row ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE ij> close scan_cursor; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> -------------------------------------------------------------------------------- -- TEST 6: heap cursor scan, group fetch = 1 (scan with "<" qualifier) -- Test "less than" qualified cursor scan on a data set. -- SERIALIZABLE - will get table level S lock. -- REPEATABLE READ - TABLE IS, will get row S locks as it visits each row -- (including deleted ones). -- READ COMMITTED - TABLE IS, will get instantaneous locks and release -- READ UNCOMMITTED - TABLE IS, no row locks. -- -- At this point the table should look like: -- 1, 10, 'one' -- 3, 30, 'three' -- 5, 50, 'five' -- 7, 70, 'seven' -------------------------------------------------------------------------------- CALL SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.language.bulkFetchDefault','1'); 0 rows inserted/updated/deleted ij> get cursor scan_cursor as 'select a, b, c from a where a < 3'; ij> call SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.language.bulkFetchDefault', '16'); 0 rows inserted/updated/deleted ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 1 |10 |one ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; No current row ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE ij> close scan_cursor; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> -------------------------------------------------------------------------------- -- TEST 7: heap cursor scan, group fetch = 2 (scan with "<" qualifier) -- Test "less than" qualified cursor scan on a data set. -- SERIALIZABLE - will get table level S lock. -- REPEATABLE READ - TABLE IS, will get row S locks as it visits each row -- (including deleted ones). -- READ COMMITTED - TABLE IS, will get instantaneous locks and release -- READ UNCOMMITTED - TABLE IS, no row locks. -- -- At this point the table should look like: -- 1, 10, 'one' -- 3, 30, 'three' -- 5, 50, 'five' -- 7, 70, 'seven' -------------------------------------------------------------------------------- CALL SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.language.bulkFetchDefault','2'); 0 rows inserted/updated/deleted ij> -- RESOLVE: missing row locks -- WORKAROUND: creating an index and dropping it -- to force the statement to be recompiled create index ix1 on a(a); 0 rows inserted/updated/deleted ij> drop index ix1; 0 rows inserted/updated/deleted ij> commit; ij> get cursor scan_cursor as 'select a, b, c from a where a < 3'; ij> call SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.language.bulkFetchDefault', '16'); 0 rows inserted/updated/deleted ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 1 |10 |one ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; No current row ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE ij> close scan_cursor; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> -------------------------------------------------------------------------------- -- TEST 8: heap cursor scan, group fetch = 1 (scan with equals qualifier) -- Test "equals" qualified cursor scan on a data set. -- SERIALIZABLE - will get table level S lock. -- REPEATABLE READ - TABLE IS, will get row S locks as it visits each row -- (including deleted ones). -- READ COMMITTED - TABLE IS, will get instantaneous locks and release -- READ UNCOMMITTED - TABLE IS, no row locks. -- -- At this point the table should look like: -- 1, 10, 'one' -- 3, 30, 'three' -- 5, 50, 'five' -- 7, 70, 'seven' -------------------------------------------------------------------------------- CALL SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.language.bulkFetchDefault','1'); 0 rows inserted/updated/deleted ij> get cursor scan_cursor as 'select a, b, c from a where a = 5'; ij> call SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.language.bulkFetchDefault', '16'); 0 rows inserted/updated/deleted ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 5 |50 |five ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; No current row ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE ij> close scan_cursor; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> -------------------------------------------------------------------------------- -- TEST 9: heap cursor scan, group fetch = 2 (scan with equals qualifier) -- Test "equals" qualified cursor scan on a data set. -- SERIALIZABLE - will get table level S lock. -- REPEATABLE READ - TABLE IS, will get row S locks as it visits each row -- (including deleted ones). -- READ COMMITTED - TABLE IS, will get instantaneous locks and release -- READ UNCOMMITTED - TABLE IS, no row locks. -- -- At this point the table should look like: -- 1, 10, 'one' -- 3, 30, 'three' -- 5, 50, 'five' -- 7, 70, 'seven' -------------------------------------------------------------------------------- CALL SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.language.bulkFetchDefault','2'); 0 rows inserted/updated/deleted ij> get cursor scan_cursor as 'select a, b, c from a where a = 7'; ij> call SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.language.bulkFetchDefault', '16'); 0 rows inserted/updated/deleted ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 7 |70 |seven ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; No current row ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE ij> close scan_cursor; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> -------------------------------------------------------------------------------- -- TEST 10: heap cursor scan, group fetch = 1 (equals qualifier, no rows return) -- Test "equals" qualified cursor scan on a data set, no rows returned. -- SERIALIZABLE - will get table level S lock. -- REPEATABLE READ - TABLE IS, will get row S locks as it visits each row -- (including deleted ones). -- READ COMMITTED - TABLE IS, will get instantaneous locks and release -- READ UNCOMMITTED - TABLE IS, no row locks. -- -- At this point the table should look like: -- 1, 10, 'one' -- 3, 30, 'three' -- 5, 50, 'five' -- 7, 70, 'seven' -------------------------------------------------------------------------------- CALL SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.language.bulkFetchDefault','1'); 0 rows inserted/updated/deleted ij> -- RESOLVE: missing row locks -- WORKAROUND: creating an index and dropping it -- to force the statement to be recompiled create index ix1 on a(a); 0 rows inserted/updated/deleted ij> drop index ix1; 0 rows inserted/updated/deleted ij> commit; ij> get cursor scan_cursor as 'select a, b, c from a where a = 7'; ij> CALL SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.language.bulkFetchDefault','16'); 0 rows inserted/updated/deleted ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 7 |70 |seven ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; No current row ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE ij> close scan_cursor; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> drop table a; 0 rows inserted/updated/deleted ij> -- non cursor, no index run drop table a; ERROR 42Y55: 'DROP TABLE' cannot be performed on 'A' because it does not exist. ij> -- to create tables of page size 4k and still keep the following tbl -- create table a (a int, b int, c varchar(1900)); create table a(a int, b int); 0 rows inserted/updated/deleted ij> alter table a add column c varchar(1900); 0 rows inserted/updated/deleted ij> insert into a values (1, 10, 'one'); 1 row inserted/updated/deleted ij> insert into a values (2, 20, 'two'); 1 row inserted/updated/deleted ij> insert into a values (3, 30, 'three'); 1 row inserted/updated/deleted ij> insert into a values (4, 40, 'four'); 1 row inserted/updated/deleted ij> insert into a values (5, 50, 'five'); 1 row inserted/updated/deleted ij> insert into a values (6, 60, 'six'); 1 row inserted/updated/deleted ij> insert into a values (7, 70, 'seven'); 1 row inserted/updated/deleted ij> commit; ij> run resource 'readSetLocks.subsql'; 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. -- -- Very basic single user testing of read locks in "set" queries on heap tables. -- This ".subsql" test is -- meant to be run from another test such that it gets run under multiple -- isolation levels. This is important as they behave -- differently, depending on isolation levels. -- -- assume's caller has already done: run 'LockTableQuery.subsql'; to get -- easy access to the lock VTI. -- TEST 0: heap scan. -- TEST 1: heap scan, some rows deleted. -- TEST 2: heap scan, (scan with "<" qualifier) -- TEST 3: heap scan, (scan with equals qualifier) -- TEST 4: heap scan, (equals qualifier, no rows return) autocommit off; ij> -------------------------------------------------------------------------------- -- Assumes that calling routine has set up the following simple dataset, -- a heap, no indexes with following initial values: -- create table (a int, b int, c somesortofchar); -- 1, 10, 'one' -- 2, 20, 'two' -- 3, 30, 'three' -- 4, 40, 'four' -- 5, 50, 'five' -- 6, 60, 'six' -- 7, 70, 'seven' -------------------------------------------------------------------------------- select * from a; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 1 |10 |one 2 |20 |two 3 |30 |three 4 |40 |four 5 |50 |five 6 |60 |six 7 |70 |seven ij> commit; ij> -------------------------------------------------------------------------------- -- TEST 0: heap scan. -- Test full cursor scan which does no updates. -- SERIALIZABLE - will get table level S lock, held to end of xact. -- REPEATABLE READ - TABLE IS, will get row S locks as it visits each row -- (including deleted ones). held to end of xact. -- READ COMMITTED - TABLE IS, will get instantaneous locks and release. No -- locks held when statement completes. -- READ UNCOMMITTED - TABLE IS, no row locks. No locks after statement ends. -------------------------------------------------------------------------------- select a, b, c from a; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 1 |10 |one 2 |20 |two 3 |30 |three 4 |40 |four 5 |50 |five 6 |60 |six 7 |70 |seven ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> -------------------------------------------------------------------------------- -- TEST 1: heap scan, some rows deleted. -- Test full cursor scan on a data set with some deleted rows (the "even" ones). -- SERIALIZABLE - will get table level S lock. -- REPEATABLE READ - TABLE IS, will get row S locks as it visits each row -- (including deleted ones). -- READ COMMITTED - TABLE IS, will get instantaneous locks and release -- READ UNCOMMITTED - TABLE IS, no row locks. -- SERIALIZABLE - will get table level S lock, held to end of xact. -- REPEATABLE READ - TABLE IS, will get row S locks as it visits each row -- (including deleted ones). held to end of xact. -- READ COMMITTED - TABLE IS, will get instantaneous locks and release. No -- locks held when statement completes. -- READ UNCOMMITTED - TABLE IS, no row locks. No locks after statement ends. -- -- After the delete the table should look like: -- 1, 10, 'one' -- 3, 30, 'three' -- 5, 50, 'five' -- 7, 70, 'seven' -------------------------------------------------------------------------------- delete from a where a = 2 or a = 4 or a = 6; 3 rows inserted/updated/deleted ij> commit; ij> select a, b, c from a; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 1 |10 |one 3 |30 |three 5 |50 |five 7 |70 |seven ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> -------------------------------------------------------------------------------- -- TEST 2: heap scan, (scan with "<" qualifier) -- Test "less than" qualified cursor scan on a data set. -- SERIALIZABLE - will get table level S lock, held to end of xact. -- REPEATABLE READ - TABLE IS, will get row S locks as it visits each row -- (including deleted ones). held to end of xact. -- READ COMMITTED - TABLE IS, will get instantaneous locks and release. No -- locks held when statement completes. -- READ UNCOMMITTED - TABLE IS, no row locks. No locks after statement ends. -- -- At this point the table should look like: -- 1, 10, 'one' -- 3, 30, 'three' -- 5, 50, 'five' -- 7, 70, 'seven' -------------------------------------------------------------------------------- select a, b, c from a; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 1 |10 |one 3 |30 |three 5 |50 |five 7 |70 |seven ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> -------------------------------------------------------------------------------- -- TEST 3: heap scan, (scan with equals qualifier) -- Test "equals" qualified cursor scan on a data set. -- SERIALIZABLE - will get table level S lock, held to end of xact. -- REPEATABLE READ - TABLE IS, will get row S locks as it visits each row -- (including deleted ones). held to end of xact. -- READ COMMITTED - TABLE IS, will get instantaneous locks and release. No -- locks held when statement completes. -- READ UNCOMMITTED - TABLE IS, no row locks. No locks after statement ends. -- -- At this point the table should look like: -- 1, 10, 'one' -- 3, 30, 'three' -- 5, 50, 'five' -- 7, 70, 'seven' -------------------------------------------------------------------------------- select a, b, c from a where a = 5; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 5 |50 |five ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> -------------------------------------------------------------------------------- -- TEST 4: heap scan, (equals qualifier, no rows return) -- Test "equals" qualified cursor scan on a data set, no rows returned. -- SERIALIZABLE - will get table level S lock, held to end of xact. -- REPEATABLE READ - TABLE IS, will get row S locks as it visits each row -- (including deleted ones). held to end of xact. -- READ COMMITTED - TABLE IS, will get instantaneous locks and release. No -- locks held when statement completes. -- READ UNCOMMITTED - TABLE IS, no row locks. No locks after statement ends. -- -- At this point the table should look like: -- 1, 10, 'one' -- 3, 30, 'three' -- 5, 50, 'five' -- 7, 70, 'seven' -------------------------------------------------------------------------------- select a, b, c from a where a = 7; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 7 |70 |seven ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> drop table a; 0 rows inserted/updated/deleted ij> -- cursor, unique index run drop table a; ERROR 42Y55: 'DROP TABLE' cannot be performed on 'A' because it does not exist. ij> create table a (a int, b int, c varchar(1900), index_pad varchar(600) ) ; 0 rows inserted/updated/deleted ij> insert into a values (1, 10, PADSTRING('one', 1900), PADSTRING('index pad 1',600)); 1 row inserted/updated/deleted ij> insert into a values (2, 20, PADSTRING('two', 1900), PADSTRING('index pad 2',600)); 1 row inserted/updated/deleted ij> insert into a values (3, 30, PADSTRING('three', 1900), PADSTRING('index pad 3',600)); 1 row inserted/updated/deleted ij> insert into a values (4, 40, PADSTRING('four', 1900), PADSTRING('index pad 4',600)); 1 row inserted/updated/deleted ij> insert into a values (5, 50, PADSTRING('five', 1900), PADSTRING('index pad 5',600)); 1 row inserted/updated/deleted ij> insert into a values (6, 60, PADSTRING('six', 1900), PADSTRING('index pad 6',600)); 1 row inserted/updated/deleted ij> insert into a values (7, 70, PADSTRING('seven', 1900), PADSTRING('index pad 7',600)); 1 row inserted/updated/deleted ij> create unique index a_idx on a (a, index_pad) ; 0 rows inserted/updated/deleted ij> commit; ij> run resource 'readBtreeCursorLocks.subsql'; 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. -- -- Very basic single user testing of read locks on cursors on indexes. -- This ".subsql" test is -- meant to be run from another test such that it gets run under multiple -- isolation levels. This is important as they behave -- differently, depending on isolation levels. -- -- assume's caller has already done: run 'LockTableQuery.subsql'; to get -- easy access to the lock VTI. -- TEST 0: btree cursor scan, group fetch = 1 -- TEST 1: btree cursor scan, group fetch = 2 -- TEST 2: btree cursor scan, group fetch = 1 stop scan in middle of set -- TEST 3: btree cursor scan, group fetch = 4 stop scan in middle of set -- TEST 4: btree cursor scan, group fetch = 1 (scan with some deleted rows) -- TEST 5: btree cursor scan, group fetch = 2(scan with committed deleted rows) -- TEST 6: btree cursor scan, group fetch = 1 (scan with "<" qualifier) -- TEST 7: btree cursor scan, group fetch = 2 (scan with "<" qualifier) -- TEST 8: btree cursor scan, group fetch = 1 (scan with equals qualifier) -- TEST 9: btree cursor scan, group fetch = 2 (scan with equals qualifier) -- TEST 10: btree cursor scan, group fetch = 1 ("=" qualifier, no rows return) autocommit off; ij> -------------------------------------------------------------------------------- -- Assumes that calling routine has set up the following simple dataset, -- a heap, and index with following initial values: -- create table a (a int, b int, c somesortofchar, [index_pad]); -- create index a_idx on a (a) or a_idx on a (a, index_pad); -- -- 1, 10, 'one' -- 2, 20, 'two' -- 3, 30, 'three' -- 4, 40, 'four' -- 5, 50, 'five' -- 6, 60, 'six' -- 7, 70, 'seven' -------------------------------------------------------------------------------- select * from a; A |B |C |INDEX_PAD ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- 1 |10 |one &|index pad 1 & 2 |20 |two &|index pad 2 & 3 |30 |three &|index pad 3 & 4 |40 |four &|index pad 4 & 5 |50 |five &|index pad 5 & 6 |60 |six &|index pad 6 & 7 |70 |seven &|index pad 7 & ij> commit; ij> -------------------------------------------------------------------------------- -- TEST 0: btree cursor scan, group fetch = 1 -- Test full cursor scan which does no updates. -- ALL MODES - TABLE IS, "scan page lockname of form (pageno, 1) -- SERIALIZABLE - row S locks as it visits each row, held until end xact -- REPEATABLE READ - row S locks as it visits each row, held until end xact -- READ COMMITTED - row S lock on current row, released on move to next row -- READ UNCOMMITTED - no row locks. ------------------------------------------------------------------------------- CALL SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.language.bulkFetchDefault','1'); 0 rows inserted/updated/deleted ij> -- RESOLVE: missing row locks -- WORKAROUND: creating an index and dropping it -- to force the statement to be recompiled create index ix1 on a(a); 0 rows inserted/updated/deleted ij> drop index ix1; 0 rows inserted/updated/deleted ij> commit; ij> get cursor scan_cursor as 'select a from a'; ij> call SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.language.bulkFetchDefault', '16'); 0 rows inserted/updated/deleted ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A ----------- 1 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(2,1) |GRANT|ACTIVE ij> next scan_cursor; A ----------- 2 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(2,1) |GRANT|ACTIVE ij> next scan_cursor; A ----------- 3 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(2,1) |GRANT|ACTIVE ij> next scan_cursor; A ----------- 4 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(2,1) |GRANT|ACTIVE ij> next scan_cursor; A ----------- 5 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(2,1) |GRANT|ACTIVE ij> next scan_cursor; A ----------- 6 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(3,1) |GRANT|ACTIVE ij> next scan_cursor; A ----------- 7 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(3,1) |GRANT|ACTIVE ij> next scan_cursor; No current row ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE ij> close scan_cursor; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> -------------------------------------------------------------------------------- -- TEST 1: btree cursor scan, group fetch = 2 -- Test full cursor scan which does no updates. -- ALL MODES - TABLE IS, "scan page lockname of form (pageno, 1) -- SERIALIZABLE - row S locks as it visits each row, held until end xact -- REPEATABLE READ - row S locks as it visits each row, held until end xact -- READ COMMITTED - row S lock on current row, released on move to next row -- READ UNCOMMITTED - no row locks. -------------------------------------------------------------------------------- CALL SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.language.bulkFetchDefault','2'); 0 rows inserted/updated/deleted ij> -- RESOLVE: missing row locks -- WORKAROUND: creating an index and dropping it -- to force the statement to be recompiled create index ix1 on a(a); 0 rows inserted/updated/deleted ij> drop index ix1; 0 rows inserted/updated/deleted ij> commit; ij> get cursor scan_cursor as 'select a from a'; ij> call SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.language.bulkFetchDefault', '16'); 0 rows inserted/updated/deleted ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A ----------- 1 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(2,1) |GRANT|ACTIVE ij> next scan_cursor; A ----------- 2 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(2,1) |GRANT|ACTIVE ij> next scan_cursor; A ----------- 3 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(2,1) |GRANT|ACTIVE ij> next scan_cursor; A ----------- 4 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(2,1) |GRANT|ACTIVE ij> next scan_cursor; A ----------- 5 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(3,1) |GRANT|ACTIVE ij> next scan_cursor; A ----------- 6 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(3,1) |GRANT|ACTIVE ij> next scan_cursor; A ----------- 7 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; No current row ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE ij> close scan_cursor; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> -------------------------------------------------------------------------------- -- TEST 2: btree cursor scan, group fetch = 1, stop scan in middle of set -- Test full cursor scan which does no updates. -- ALL MODES - TABLE IS, "scan page lockname of form (pageno, 1) -- SERIALIZABLE - row S locks as it visits each row, held until end xact -- REPEATABLE READ - row S locks as it visits each row, held until end xact -- READ COMMITTED - row S lock on current row, released on move to next row -- READ UNCOMMITTED - no row locks. -------------------------------------------------------------------------------- CALL SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.language.bulkFetchDefault','1'); 0 rows inserted/updated/deleted ij> -- RESOLVE: missing row locks -- WORKAROUND: creating an index and dropping it -- to force the statement to be recompiled create index ix1 on a(a); 0 rows inserted/updated/deleted ij> drop index ix1; 0 rows inserted/updated/deleted ij> commit; ij> get cursor scan_cursor as 'select a from a'; ij> call SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.language.bulkFetchDefault', '16'); 0 rows inserted/updated/deleted ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A ----------- 1 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(2,1) |GRANT|ACTIVE ij> next scan_cursor; A ----------- 2 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(2,1) |GRANT|ACTIVE ij> close scan_cursor; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> -------------------------------------------------------------------------------- -- TEST 3: btree cursor scan, group fetch = 4, stop scan in middle of set -- Test full cursor scan which does no updates. -- ALL MODES - TABLE IS, "scan page lockname of form (pageno, 1) -- SERIALIZABLE - row S locks as it visits each row, held until end xact -- REPEATABLE READ - row S locks as it visits each row, held until end xact -- READ COMMITTED - row S lock on current row, released on move to next row -- READ UNCOMMITTED - no row locks. -------------------------------------------------------------------------------- CALL SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.language.bulkFetchDefault','4'); 0 rows inserted/updated/deleted ij> -- RESOLVE: missing row locks -- WORKAROUND: creating an index and dropping it -- to force the statement to be recompiled create index ix1 on a(a); 0 rows inserted/updated/deleted ij> drop index ix1; 0 rows inserted/updated/deleted ij> commit; ij> get cursor scan_cursor as 'select a from a'; ij> call SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.language.bulkFetchDefault', '16'); 0 rows inserted/updated/deleted ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A ----------- 1 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(2,1) |GRANT|ACTIVE ij> next scan_cursor; A ----------- 2 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(2,1) |GRANT|ACTIVE ij> close scan_cursor; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> -------------------------------------------------------------------------------- -- TEST 4: btree cursor scan, group fetch = 1 (scan table with some deleted rows) -- Test full cursor scan on a data set with some deleted rows (the "even" ones). -- ALL MODES - TABLE IS, "scan page lockname of form (pageno, 1) -- SERIALIZABLE - row S locks as it visits each row, held until end xact -- REPEATABLE READ - row S locks as it visits each row, held until end xact -- READ COMMITTED - row S lock on current row, released on move to next row -- READ UNCOMMITTED - no row locks. -- -- After the delete the base table should look like: -- 1, 10, 'one' -- 3, 30, 'three' -- 5, 50, 'five' -- 7, 70, 'seven' -------------------------------------------------------------------------------- delete from a where a = 2 or a = 4 or a = 6; 3 rows inserted/updated/deleted ij> commit; ij> CALL SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.language.bulkFetchDefault','1'); 0 rows inserted/updated/deleted ij> -- RESOLVE: missing row locks -- WORKAROUND: creating an index and dropping it -- to force the statement to be recompiled create index ix1 on a(a); 0 rows inserted/updated/deleted ij> drop index ix1; 0 rows inserted/updated/deleted ij> commit; ij> get cursor scan_cursor as 'select a from a'; ij> call SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.language.bulkFetchDefault', '16'); 0 rows inserted/updated/deleted ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A ----------- 1 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(2,1) |GRANT|ACTIVE ij> next scan_cursor; A ----------- 3 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(2,1) |GRANT|ACTIVE ij> next scan_cursor; A ----------- 5 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(2,1) |GRANT|ACTIVE ij> next scan_cursor; A ----------- 7 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(3,1) |GRANT|ACTIVE ij> next scan_cursor; No current row ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE ij> close scan_cursor; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> -------------------------------------------------------------------------------- -- TEST 5: btree cursor scan, group fetch = 2 (scan with committed deleted rows) -- Test full cursor scan on a data set with some deleted rows (the "even" ones). -- ALL MODES - TABLE IS, "scan page lockname of form (pageno, 1) -- SERIALIZABLE - row S locks as it visits each row, held until end xact -- REPEATABLE READ - row S locks as it visits each row, held until end xact -- READ COMMITTED - row S lock on current row, released on move to next row -- READ UNCOMMITTED - no row locks. -- -- At this point the base table should look like: -- 1, 10, 'one' -- 3, 30, 'three' -- 5, 50, 'five' -- 7, 70, 'seven' -------------------------------------------------------------------------------- CALL SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.language.bulkFetchDefault','2'); 0 rows inserted/updated/deleted ij> -- RESOLVE: missing row locks -- WORKAROUND: creating an index and dropping it -- to force the statement to be recompiled create index ix1 on a(a); 0 rows inserted/updated/deleted ij> drop index ix1; 0 rows inserted/updated/deleted ij> commit; ij> get cursor scan_cursor as 'select a from a'; ij> call SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.language.bulkFetchDefault', '16'); 0 rows inserted/updated/deleted ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A ----------- 1 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(2,1) |GRANT|ACTIVE ij> next scan_cursor; A ----------- 3 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(2,1) |GRANT|ACTIVE ij> next scan_cursor; A ----------- 5 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(3,1) |GRANT|ACTIVE ij> next scan_cursor; A ----------- 7 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(3,1) |GRANT|ACTIVE ij> next scan_cursor; No current row ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE ij> close scan_cursor; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> -------------------------------------------------------------------------------- -- TEST 6: btree cursor scan, group fetch = 1 (scan with "<" qualifier) -- Test "less than" qualified cursor scan on a data set. -- ALL MODES - TABLE IS, "scan page lockname of form (pageno, 1) -- SERIALIZABLE - row S locks as it visits each row, held until end xact -- REPEATABLE READ - row S locks as it visits each row, held until end xact -- READ COMMITTED - row S lock on current row, released on move to next row -- READ UNCOMMITTED - no row locks. -- -- At this point the base table should look like: -- 1, 10, 'one' -- 3, 30, 'three' -- 5, 50, 'five' -- 7, 70, 'seven' -------------------------------------------------------------------------------- CALL SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.language.bulkFetchDefault','1'); 0 rows inserted/updated/deleted ij> -- RESOLVE: missing row locks -- WORKAROUND: creating an index and dropping it -- to force the statement to be recompiled create index ix1 on a(a); 0 rows inserted/updated/deleted ij> drop index ix1; 0 rows inserted/updated/deleted ij> commit; ij> get cursor scan_cursor as 'select a from a where a < 3'; ij> call SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.language.bulkFetchDefault', '16'); 0 rows inserted/updated/deleted ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A ----------- 1 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(2,1) |GRANT|ACTIVE ij> next scan_cursor; No current row ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE ij> close scan_cursor; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> -------------------------------------------------------------------------------- -- TEST 7: btree cursor scan, group fetch = 2 (scan with "<" qualifier) -- Test "less than" qualified cursor scan on a data set. -- ALL MODES - TABLE IS, "scan page lockname of form (pageno, 1) -- SERIALIZABLE - row S locks as it visits each row, held until end xact -- REPEATABLE READ - row S locks as it visits each row, held until end xact -- READ COMMITTED - row S lock on current row, released on move to next row -- READ UNCOMMITTED - no row locks. -- -- At this point the base table should look like: -- 1, 10, 'one' -- 3, 30, 'three' -- 5, 50, 'five' -- 7, 70, 'seven' -------------------------------------------------------------------------------- CALL SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.language.bulkFetchDefault','2'); 0 rows inserted/updated/deleted ij> -- RESOLVE: missing row locks -- WORKAROUND: creating an index and dropping it -- to force the statement to be recompiled create index ix1 on a(a); 0 rows inserted/updated/deleted ij> drop index ix1; 0 rows inserted/updated/deleted ij> commit; ij> get cursor scan_cursor as 'select a from a where a < 3'; ij> call SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.language.bulkFetchDefault', '16'); 0 rows inserted/updated/deleted ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A ----------- 1 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; No current row ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE ij> close scan_cursor; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> -------------------------------------------------------------------------------- -- TEST 8: btree cursor scan, group fetch = 1 (scan with equals qualifier) -- Test "equals" qualified cursor scan on a data set. -- ALL MODES - TABLE IS, "scan page lockname of form (pageno, 1) -- SERIALIZABLE - row S locks as it visits each row, held until end xact -- REPEATABLE READ - row S locks as it visits each row, held until end xact -- READ COMMITTED - row S lock on current row, released on move to next row -- READ UNCOMMITTED - no row locks. -- -- At this point the base table should look like: -- 1, 10, 'one' -- 3, 30, 'three' -- 5, 50, 'five' -- 7, 70, 'seven' -------------------------------------------------------------------------------- CALL SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.language.bulkFetchDefault','1'); 0 rows inserted/updated/deleted ij> -- RESOLVE: missing row locks -- WORKAROUND: creating an index and dropping it -- to force the statement to be recompiled create index ix1 on a(a); 0 rows inserted/updated/deleted ij> drop index ix1; 0 rows inserted/updated/deleted ij> commit; ij> get cursor scan_cursor as 'select a from a where a = 5'; ij> call SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.language.bulkFetchDefault', '16'); 0 rows inserted/updated/deleted ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A ----------- 5 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(2,1) |GRANT|ACTIVE ij> next scan_cursor; No current row ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE ij> close scan_cursor; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> -------------------------------------------------------------------------------- -- TEST 9: btree cursor scan, group fetch = 2 (scan with equals qualifier) -- Test "equals" qualified cursor scan on a data set. -- ALL MODES - TABLE IS, "scan page lockname of form (pageno, 1) -- SERIALIZABLE - row S locks as it visits each row, held until end xact -- REPEATABLE READ - row S locks as it visits each row, held until end xact -- READ COMMITTED - row S lock on current row, released on move to next row -- READ UNCOMMITTED - no row locks. -- -- At this point the base table should look like: -- 1, 10, 'one' -- 3, 30, 'three' -- 5, 50, 'five' -- 7, 70, 'seven' -------------------------------------------------------------------------------- CALL SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.language.bulkFetchDefault','2'); 0 rows inserted/updated/deleted ij> -- RESOLVE: missing row locks -- WORKAROUND: creating an index and dropping it -- to force the statement to be recompiled create index ix1 on a(a); 0 rows inserted/updated/deleted ij> drop index ix1; 0 rows inserted/updated/deleted ij> commit; ij> get cursor scan_cursor as 'select a from a where a = 5 or a = 7'; ij> call SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.language.bulkFetchDefault', '16'); 0 rows inserted/updated/deleted ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A ----------- 5 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(2,1) |GRANT|ACTIVE ij> next scan_cursor; A ----------- 7 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(3,1) |GRANT|ACTIVE ij> close scan_cursor; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> -------------------------------------------------------------------------------- -- TEST 10: btree cursor scan, group fetch = 1 (equals qualifier, no rows return) -- Test "equals" qualified cursor scan on a data set, no rows returned. -- ALL MODES - TABLE IS, "scan page lockname of form (pageno, 1) -- SERIALIZABLE - row S locks as it visits each row, held until end xact -- REPEATABLE READ - row S locks as it visits each row, held until end xact -- READ COMMITTED - row S lock on current row, released on move to next row -- READ UNCOMMITTED - no row locks. -- -- At this point the base table should look like: -- 1, 10, 'one' -- 3, 30, 'three' -- 5, 50, 'five' -- 7, 70, 'seven' -------------------------------------------------------------------------------- -- no rows expected to qualify CALL SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.language.bulkFetchDefault','1'); 0 rows inserted/updated/deleted ij> -- RESOLVE: missing row locks -- WORKAROUND: creating an index and dropping it -- to force the statement to be recompiled create index ix1 on a(a); 0 rows inserted/updated/deleted ij> drop index ix1; 0 rows inserted/updated/deleted ij> commit; ij> get cursor scan_cursor as 'select a from a where a = 42'; ij> call SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.language.bulkFetchDefault', '16'); 0 rows inserted/updated/deleted ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; No current row ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; No current row ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE ij> close scan_cursor; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> drop table a; 0 rows inserted/updated/deleted ij> -- cursor, non-unique index run drop table a; ERROR 42Y55: 'DROP TABLE' cannot be performed on 'A' because it does not exist. ij> create table a (a int, b int, c varchar(1900), index_pad varchar(700) ) ; 0 rows inserted/updated/deleted ij> insert into a values (1, 10, PADSTRING('one',1900), PADSTRING('index pad 1',700)); 1 row inserted/updated/deleted ij> insert into a values (2, 20, PADSTRING('two',1900), PADSTRING('index pad 2',700)); 1 row inserted/updated/deleted ij> insert into a values (3, 30, PADSTRING('three',1900), PADSTRING('index pad 3',700)); 1 row inserted/updated/deleted ij> insert into a values (4, 40, PADSTRING('four',1900), PADSTRING('index pad 4',700)); 1 row inserted/updated/deleted ij> insert into a values (5, 50, PADSTRING('five',1900), PADSTRING('index pad 5',700)); 1 row inserted/updated/deleted ij> insert into a values (6, 60, PADSTRING('six',1900), PADSTRING('index pad 6',700)); 1 row inserted/updated/deleted ij> insert into a values (7, 70, PADSTRING('seven',1900), PADSTRING('index pad 7',700)); 1 row inserted/updated/deleted ij> create index a_idx on a (a, index_pad) ; 0 rows inserted/updated/deleted ij> commit; ij> run resource 'readBtreeCursorLocks.subsql'; 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. -- -- Very basic single user testing of read locks on cursors on indexes. -- This ".subsql" test is -- meant to be run from another test such that it gets run under multiple -- isolation levels. This is important as they behave -- differently, depending on isolation levels. -- -- assume's caller has already done: run 'LockTableQuery.subsql'; to get -- easy access to the lock VTI. -- TEST 0: btree cursor scan, group fetch = 1 -- TEST 1: btree cursor scan, group fetch = 2 -- TEST 2: btree cursor scan, group fetch = 1 stop scan in middle of set -- TEST 3: btree cursor scan, group fetch = 4 stop scan in middle of set -- TEST 4: btree cursor scan, group fetch = 1 (scan with some deleted rows) -- TEST 5: btree cursor scan, group fetch = 2(scan with committed deleted rows) -- TEST 6: btree cursor scan, group fetch = 1 (scan with "<" qualifier) -- TEST 7: btree cursor scan, group fetch = 2 (scan with "<" qualifier) -- TEST 8: btree cursor scan, group fetch = 1 (scan with equals qualifier) -- TEST 9: btree cursor scan, group fetch = 2 (scan with equals qualifier) -- TEST 10: btree cursor scan, group fetch = 1 ("=" qualifier, no rows return) autocommit off; ij> -------------------------------------------------------------------------------- -- Assumes that calling routine has set up the following simple dataset, -- a heap, and index with following initial values: -- create table a (a int, b int, c somesortofchar, [index_pad]); -- create index a_idx on a (a) or a_idx on a (a, index_pad); -- -- 1, 10, 'one' -- 2, 20, 'two' -- 3, 30, 'three' -- 4, 40, 'four' -- 5, 50, 'five' -- 6, 60, 'six' -- 7, 70, 'seven' -------------------------------------------------------------------------------- select * from a; A |B |C |INDEX_PAD ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- 1 |10 |one &|index pad 1 & 2 |20 |two &|index pad 2 & 3 |30 |three &|index pad 3 & 4 |40 |four &|index pad 4 & 5 |50 |five &|index pad 5 & 6 |60 |six &|index pad 6 & 7 |70 |seven &|index pad 7 & ij> commit; ij> -------------------------------------------------------------------------------- -- TEST 0: btree cursor scan, group fetch = 1 -- Test full cursor scan which does no updates. -- ALL MODES - TABLE IS, "scan page lockname of form (pageno, 1) -- SERIALIZABLE - row S locks as it visits each row, held until end xact -- REPEATABLE READ - row S locks as it visits each row, held until end xact -- READ COMMITTED - row S lock on current row, released on move to next row -- READ UNCOMMITTED - no row locks. ------------------------------------------------------------------------------- CALL SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.language.bulkFetchDefault','1'); 0 rows inserted/updated/deleted ij> -- RESOLVE: missing row locks -- WORKAROUND: creating an index and dropping it -- to force the statement to be recompiled create index ix1 on a(a); 0 rows inserted/updated/deleted ij> drop index ix1; 0 rows inserted/updated/deleted ij> commit; ij> get cursor scan_cursor as 'select a from a'; ij> call SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.language.bulkFetchDefault', '16'); 0 rows inserted/updated/deleted ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A ----------- 1 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(2,1) |GRANT|ACTIVE ij> next scan_cursor; A ----------- 2 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(2,1) |GRANT|ACTIVE ij> next scan_cursor; A ----------- 3 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(2,1) |GRANT|ACTIVE ij> next scan_cursor; A ----------- 4 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(2,1) |GRANT|ACTIVE ij> next scan_cursor; A ----------- 5 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(3,1) |GRANT|ACTIVE ij> next scan_cursor; A ----------- 6 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(3,1) |GRANT|ACTIVE ij> next scan_cursor; A ----------- 7 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(3,1) |GRANT|ACTIVE ij> next scan_cursor; No current row ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE ij> close scan_cursor; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> -------------------------------------------------------------------------------- -- TEST 1: btree cursor scan, group fetch = 2 -- Test full cursor scan which does no updates. -- ALL MODES - TABLE IS, "scan page lockname of form (pageno, 1) -- SERIALIZABLE - row S locks as it visits each row, held until end xact -- REPEATABLE READ - row S locks as it visits each row, held until end xact -- READ COMMITTED - row S lock on current row, released on move to next row -- READ UNCOMMITTED - no row locks. -------------------------------------------------------------------------------- CALL SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.language.bulkFetchDefault','2'); 0 rows inserted/updated/deleted ij> -- RESOLVE: missing row locks -- WORKAROUND: creating an index and dropping it -- to force the statement to be recompiled create index ix1 on a(a); 0 rows inserted/updated/deleted ij> drop index ix1; 0 rows inserted/updated/deleted ij> commit; ij> get cursor scan_cursor as 'select a from a'; ij> call SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.language.bulkFetchDefault', '16'); 0 rows inserted/updated/deleted ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A ----------- 1 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(2,1) |GRANT|ACTIVE ij> next scan_cursor; A ----------- 2 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(2,1) |GRANT|ACTIVE ij> next scan_cursor; A ----------- 3 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(2,1) |GRANT|ACTIVE ij> next scan_cursor; A ----------- 4 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(2,1) |GRANT|ACTIVE ij> next scan_cursor; A ----------- 5 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(3,1) |GRANT|ACTIVE ij> next scan_cursor; A ----------- 6 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(3,1) |GRANT|ACTIVE ij> next scan_cursor; A ----------- 7 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; No current row ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE ij> close scan_cursor; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> -------------------------------------------------------------------------------- -- TEST 2: btree cursor scan, group fetch = 1, stop scan in middle of set -- Test full cursor scan which does no updates. -- ALL MODES - TABLE IS, "scan page lockname of form (pageno, 1) -- SERIALIZABLE - row S locks as it visits each row, held until end xact -- REPEATABLE READ - row S locks as it visits each row, held until end xact -- READ COMMITTED - row S lock on current row, released on move to next row -- READ UNCOMMITTED - no row locks. -------------------------------------------------------------------------------- CALL SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.language.bulkFetchDefault','1'); 0 rows inserted/updated/deleted ij> -- RESOLVE: missing row locks -- WORKAROUND: creating an index and dropping it -- to force the statement to be recompiled create index ix1 on a(a); 0 rows inserted/updated/deleted ij> drop index ix1; 0 rows inserted/updated/deleted ij> commit; ij> get cursor scan_cursor as 'select a from a'; ij> call SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.language.bulkFetchDefault', '16'); 0 rows inserted/updated/deleted ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A ----------- 1 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(2,1) |GRANT|ACTIVE ij> next scan_cursor; A ----------- 2 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(2,1) |GRANT|ACTIVE ij> close scan_cursor; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> -------------------------------------------------------------------------------- -- TEST 3: btree cursor scan, group fetch = 4, stop scan in middle of set -- Test full cursor scan which does no updates. -- ALL MODES - TABLE IS, "scan page lockname of form (pageno, 1) -- SERIALIZABLE - row S locks as it visits each row, held until end xact -- REPEATABLE READ - row S locks as it visits each row, held until end xact -- READ COMMITTED - row S lock on current row, released on move to next row -- READ UNCOMMITTED - no row locks. -------------------------------------------------------------------------------- CALL SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.language.bulkFetchDefault','4'); 0 rows inserted/updated/deleted ij> -- RESOLVE: missing row locks -- WORKAROUND: creating an index and dropping it -- to force the statement to be recompiled create index ix1 on a(a); 0 rows inserted/updated/deleted ij> drop index ix1; 0 rows inserted/updated/deleted ij> commit; ij> get cursor scan_cursor as 'select a from a'; ij> call SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.language.bulkFetchDefault', '16'); 0 rows inserted/updated/deleted ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A ----------- 1 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(2,1) |GRANT|ACTIVE ij> next scan_cursor; A ----------- 2 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(2,1) |GRANT|ACTIVE ij> close scan_cursor; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> -------------------------------------------------------------------------------- -- TEST 4: btree cursor scan, group fetch = 1 (scan table with some deleted rows) -- Test full cursor scan on a data set with some deleted rows (the "even" ones). -- ALL MODES - TABLE IS, "scan page lockname of form (pageno, 1) -- SERIALIZABLE - row S locks as it visits each row, held until end xact -- REPEATABLE READ - row S locks as it visits each row, held until end xact -- READ COMMITTED - row S lock on current row, released on move to next row -- READ UNCOMMITTED - no row locks. -- -- After the delete the base table should look like: -- 1, 10, 'one' -- 3, 30, 'three' -- 5, 50, 'five' -- 7, 70, 'seven' -------------------------------------------------------------------------------- delete from a where a = 2 or a = 4 or a = 6; 3 rows inserted/updated/deleted ij> commit; ij> CALL SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.language.bulkFetchDefault','1'); 0 rows inserted/updated/deleted ij> -- RESOLVE: missing row locks -- WORKAROUND: creating an index and dropping it -- to force the statement to be recompiled create index ix1 on a(a); 0 rows inserted/updated/deleted ij> drop index ix1; 0 rows inserted/updated/deleted ij> commit; ij> get cursor scan_cursor as 'select a from a'; ij> call SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.language.bulkFetchDefault', '16'); 0 rows inserted/updated/deleted ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A ----------- 1 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(2,1) |GRANT|ACTIVE ij> next scan_cursor; A ----------- 3 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(2,1) |GRANT|ACTIVE ij> next scan_cursor; A ----------- 5 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(3,1) |GRANT|ACTIVE ij> next scan_cursor; A ----------- 7 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(3,1) |GRANT|ACTIVE ij> next scan_cursor; No current row ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE ij> close scan_cursor; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> -------------------------------------------------------------------------------- -- TEST 5: btree cursor scan, group fetch = 2 (scan with committed deleted rows) -- Test full cursor scan on a data set with some deleted rows (the "even" ones). -- ALL MODES - TABLE IS, "scan page lockname of form (pageno, 1) -- SERIALIZABLE - row S locks as it visits each row, held until end xact -- REPEATABLE READ - row S locks as it visits each row, held until end xact -- READ COMMITTED - row S lock on current row, released on move to next row -- READ UNCOMMITTED - no row locks. -- -- At this point the base table should look like: -- 1, 10, 'one' -- 3, 30, 'three' -- 5, 50, 'five' -- 7, 70, 'seven' -------------------------------------------------------------------------------- CALL SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.language.bulkFetchDefault','2'); 0 rows inserted/updated/deleted ij> -- RESOLVE: missing row locks -- WORKAROUND: creating an index and dropping it -- to force the statement to be recompiled create index ix1 on a(a); 0 rows inserted/updated/deleted ij> drop index ix1; 0 rows inserted/updated/deleted ij> commit; ij> get cursor scan_cursor as 'select a from a'; ij> call SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.language.bulkFetchDefault', '16'); 0 rows inserted/updated/deleted ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A ----------- 1 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(2,1) |GRANT|ACTIVE ij> next scan_cursor; A ----------- 3 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(2,1) |GRANT|ACTIVE ij> next scan_cursor; A ----------- 5 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(3,1) |GRANT|ACTIVE ij> next scan_cursor; A ----------- 7 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(3,1) |GRANT|ACTIVE ij> next scan_cursor; No current row ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE ij> close scan_cursor; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> -------------------------------------------------------------------------------- -- TEST 6: btree cursor scan, group fetch = 1 (scan with "<" qualifier) -- Test "less than" qualified cursor scan on a data set. -- ALL MODES - TABLE IS, "scan page lockname of form (pageno, 1) -- SERIALIZABLE - row S locks as it visits each row, held until end xact -- REPEATABLE READ - row S locks as it visits each row, held until end xact -- READ COMMITTED - row S lock on current row, released on move to next row -- READ UNCOMMITTED - no row locks. -- -- At this point the base table should look like: -- 1, 10, 'one' -- 3, 30, 'three' -- 5, 50, 'five' -- 7, 70, 'seven' -------------------------------------------------------------------------------- CALL SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.language.bulkFetchDefault','1'); 0 rows inserted/updated/deleted ij> -- RESOLVE: missing row locks -- WORKAROUND: creating an index and dropping it -- to force the statement to be recompiled create index ix1 on a(a); 0 rows inserted/updated/deleted ij> drop index ix1; 0 rows inserted/updated/deleted ij> commit; ij> get cursor scan_cursor as 'select a from a where a < 3'; ij> call SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.language.bulkFetchDefault', '16'); 0 rows inserted/updated/deleted ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A ----------- 1 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(2,1) |GRANT|ACTIVE ij> next scan_cursor; No current row ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE ij> close scan_cursor; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> -------------------------------------------------------------------------------- -- TEST 7: btree cursor scan, group fetch = 2 (scan with "<" qualifier) -- Test "less than" qualified cursor scan on a data set. -- ALL MODES - TABLE IS, "scan page lockname of form (pageno, 1) -- SERIALIZABLE - row S locks as it visits each row, held until end xact -- REPEATABLE READ - row S locks as it visits each row, held until end xact -- READ COMMITTED - row S lock on current row, released on move to next row -- READ UNCOMMITTED - no row locks. -- -- At this point the base table should look like: -- 1, 10, 'one' -- 3, 30, 'three' -- 5, 50, 'five' -- 7, 70, 'seven' -------------------------------------------------------------------------------- CALL SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.language.bulkFetchDefault','2'); 0 rows inserted/updated/deleted ij> -- RESOLVE: missing row locks -- WORKAROUND: creating an index and dropping it -- to force the statement to be recompiled create index ix1 on a(a); 0 rows inserted/updated/deleted ij> drop index ix1; 0 rows inserted/updated/deleted ij> commit; ij> get cursor scan_cursor as 'select a from a where a < 3'; ij> call SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.language.bulkFetchDefault', '16'); 0 rows inserted/updated/deleted ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A ----------- 1 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; No current row ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE ij> close scan_cursor; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> -------------------------------------------------------------------------------- -- TEST 8: btree cursor scan, group fetch = 1 (scan with equals qualifier) -- Test "equals" qualified cursor scan on a data set. -- ALL MODES - TABLE IS, "scan page lockname of form (pageno, 1) -- SERIALIZABLE - row S locks as it visits each row, held until end xact -- REPEATABLE READ - row S locks as it visits each row, held until end xact -- READ COMMITTED - row S lock on current row, released on move to next row -- READ UNCOMMITTED - no row locks. -- -- At this point the base table should look like: -- 1, 10, 'one' -- 3, 30, 'three' -- 5, 50, 'five' -- 7, 70, 'seven' -------------------------------------------------------------------------------- CALL SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.language.bulkFetchDefault','1'); 0 rows inserted/updated/deleted ij> -- RESOLVE: missing row locks -- WORKAROUND: creating an index and dropping it -- to force the statement to be recompiled create index ix1 on a(a); 0 rows inserted/updated/deleted ij> drop index ix1; 0 rows inserted/updated/deleted ij> commit; ij> get cursor scan_cursor as 'select a from a where a = 5'; ij> call SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.language.bulkFetchDefault', '16'); 0 rows inserted/updated/deleted ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A ----------- 5 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(3,1) |GRANT|ACTIVE ij> next scan_cursor; No current row ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE ij> close scan_cursor; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> -------------------------------------------------------------------------------- -- TEST 9: btree cursor scan, group fetch = 2 (scan with equals qualifier) -- Test "equals" qualified cursor scan on a data set. -- ALL MODES - TABLE IS, "scan page lockname of form (pageno, 1) -- SERIALIZABLE - row S locks as it visits each row, held until end xact -- REPEATABLE READ - row S locks as it visits each row, held until end xact -- READ COMMITTED - row S lock on current row, released on move to next row -- READ UNCOMMITTED - no row locks. -- -- At this point the base table should look like: -- 1, 10, 'one' -- 3, 30, 'three' -- 5, 50, 'five' -- 7, 70, 'seven' -------------------------------------------------------------------------------- CALL SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.language.bulkFetchDefault','2'); 0 rows inserted/updated/deleted ij> -- RESOLVE: missing row locks -- WORKAROUND: creating an index and dropping it -- to force the statement to be recompiled create index ix1 on a(a); 0 rows inserted/updated/deleted ij> drop index ix1; 0 rows inserted/updated/deleted ij> commit; ij> get cursor scan_cursor as 'select a from a where a = 5 or a = 7'; ij> call SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.language.bulkFetchDefault', '16'); 0 rows inserted/updated/deleted ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A ----------- 5 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(3,1) |GRANT|ACTIVE ij> next scan_cursor; A ----------- 7 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(3,1) |GRANT|ACTIVE ij> close scan_cursor; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> -------------------------------------------------------------------------------- -- TEST 10: btree cursor scan, group fetch = 1 (equals qualifier, no rows return) -- Test "equals" qualified cursor scan on a data set, no rows returned. -- ALL MODES - TABLE IS, "scan page lockname of form (pageno, 1) -- SERIALIZABLE - row S locks as it visits each row, held until end xact -- REPEATABLE READ - row S locks as it visits each row, held until end xact -- READ COMMITTED - row S lock on current row, released on move to next row -- READ UNCOMMITTED - no row locks. -- -- At this point the base table should look like: -- 1, 10, 'one' -- 3, 30, 'three' -- 5, 50, 'five' -- 7, 70, 'seven' -------------------------------------------------------------------------------- -- no rows expected to qualify CALL SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.language.bulkFetchDefault','1'); 0 rows inserted/updated/deleted ij> -- RESOLVE: missing row locks -- WORKAROUND: creating an index and dropping it -- to force the statement to be recompiled create index ix1 on a(a); 0 rows inserted/updated/deleted ij> drop index ix1; 0 rows inserted/updated/deleted ij> commit; ij> get cursor scan_cursor as 'select a from a where a = 42'; ij> call SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.language.bulkFetchDefault', '16'); 0 rows inserted/updated/deleted ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; No current row ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; No current row ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE ij> close scan_cursor; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> drop table a; 0 rows inserted/updated/deleted ij> -- non cursor, unique index run drop table a; ERROR 42Y55: 'DROP TABLE' cannot be performed on 'A' because it does not exist. ij> create table a (a int, b int, c varchar(1900), index_pad varchar(800) ) ; 0 rows inserted/updated/deleted ij> insert into a values (1, 10, PADSTRING('one',1900), PADSTRING('index pad 1',800)); 1 row inserted/updated/deleted ij> insert into a values (2, 20, PADSTRING('two',1900), PADSTRING('index pad 2',800)); 1 row inserted/updated/deleted ij> insert into a values (3, 30, PADSTRING('three',1900), PADSTRING('index pad 3',800)); 1 row inserted/updated/deleted ij> insert into a values (4, 40, PADSTRING('four',1900), PADSTRING('index pad 4',800)); 1 row inserted/updated/deleted ij> insert into a values (5, 50, PADSTRING('five',1900), PADSTRING('index pad 5',800)); 1 row inserted/updated/deleted ij> insert into a values (6, 60, PADSTRING('six',1900), PADSTRING('index pad 6',800)); 1 row inserted/updated/deleted ij> insert into a values (7, 70, PADSTRING('seven',1900), PADSTRING('index pad 7',800)); 1 row inserted/updated/deleted ij> create unique index a_idx on a (a, index_pad) ; 0 rows inserted/updated/deleted ij> commit; ij> run resource 'readBtreeSetLocks.subsql'; 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. -- -- Basic single user testing of read locks on select "set" queries on indexes. -- -- This ".subsql" test is -- meant to be run from another test such that it gets run under multiple -- isolation levels. This is important as they behave -- differently, depending on isolation levels. -- -- assume's caller has already done: run 'LockTableQuery.subsql'; to get -- easy access to the lock VTI. -- TEST 0: btree scan -- TEST 1: btree scan, (scan table with some deleted rows) -- TEST 2: btree scan, (scan with "<" qualifier) -- TEST 3: btree scan, (scan with equals qualifier) -- TEST 4: btree scan, (equals qualifier, no rows return) autocommit off; ij> -------------------------------------------------------------------------------- -- Assumes that calling routine has set up the following simple dataset, -- a heap, and index with following initial values: -- create table a (a int, b int, c somesortofchar, [index_pad]); -- create index a_idx on a (a) or a_idx on a (a, index_pad); -- -- 1, 10, 'one' -- 2, 20, 'two' -- 3, 30, 'three' -- 4, 40, 'four' -- 5, 50, 'five' -- 6, 60, 'six' -- 7, 70, 'seven' -------------------------------------------------------------------------------- select * from a; A |B |C |INDEX_PAD ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- 1 |10 |one &|index pad 1 & 2 |20 |two &|index pad 2 & 3 |30 |three &|index pad 3 & 4 |40 |four &|index pad 4 & 5 |50 |five &|index pad 5 & 6 |60 |six &|index pad 6 & 7 |70 |seven &|index pad 7 & ij> commit; ij> -------------------------------------------------------------------------------- -- TEST 0: btree scan -- Test full scan. -- ALL MODES - TABLE IS, "scan page lockname of form (pageno, 1) -- SERIALIZABLE - row S locks as it visits each row, row/table lock -- held until end xact. Also holds one previous key lock. -- REPEATABLE READ - row S locks as it visits each row, row/table locks held -- until end of transaction. -- READ COMMITTED - instantaneous S locks requested on each row. No locks -- held after query finishes. -- READ UNCOMMITTED - no row locks. No locks held after query finishes. -------------------------------------------------------------------------------- select a from a; A ----------- 1 2 3 4 5 6 7 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> -------------------------------------------------------------------------------- -- TEST 1: btree scan, (scan table with some deleted rows) -- Test full scan on a data set with some deleted rows (the "even" ones). -- ALL MODES - TABLE IS, "scan page lockname of form (pageno, 1) -- SERIALIZABLE - row S locks as it visits each row, row/table lock -- held until end xact. Also holds one previous key lock. -- REPEATABLE READ - row S locks as it visits each row, row/table locks held -- until end of transaction. -- READ COMMITTED - instantaneous S locks requested on each row. No locks -- held after query finishes. -- READ UNCOMMITTED - no row locks. No locks held after query finishes. -- -- After the delete the base table should look like: -- 1, 10, 'one' -- 3, 30, 'three' -- 5, 50, 'five' -- 7, 70, 'seven' -------------------------------------------------------------------------------- delete from a where a = 2 or a = 4 or a = 6; 3 rows inserted/updated/deleted ij> commit; ij> -- The above delete and commit can allow post commit processing to run before -- the subsequent select is run, most likely if this run is on a table where -- there is one row per page. To get reproducible results from the subsequent -- lock calls, wait for post commit to finish before running the select. -- Without this wait "extra" locks sometimes might show up - these are locks -- on the committed deleted rows which have not been cleaned yet depending -- on timing. CALL WAIT_FOR_POST_COMMIT(); 0 rows inserted/updated/deleted ij> select a from a; A ----------- 1 3 5 7 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> -------------------------------------------------------------------------------- -- TEST 2: btree scan, (scan with "<" qualifier) -- Test "less than" qualified scan on a data set. -- ALL MODES - TABLE IS, "scan page lockname of form (pageno, 1) -- SERIALIZABLE - row S locks as it visits each row, row/table lock -- held until end xact. Also holds one previous key lock. -- REPEATABLE READ - row S locks as it visits each row, row/table locks held -- until end of transaction. -- READ COMMITTED - instantaneous S locks requested on each row. No locks -- held after query finishes. -- READ UNCOMMITTED - no row locks. No locks held after query finishes. -- -- At this point the base table should look like: -- 1, 10, 'one' -- 3, 30, 'three' -- 5, 50, 'five' -- 7, 70, 'seven' -------------------------------------------------------------------------------- select a from a where a < 3; A ----------- 1 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> -------------------------------------------------------------------------------- -- TEST 3: btree scan, (scan with equals qualifier) -- Test "equals" qualified cursor scan on a data set. -- ALL MODES - TABLE IS, "scan page lockname of form (pageno, 1) -- SERIALIZABLE - row S locks as it visits each row, row/table lock -- held until end xact. Also holds one previous key lock. -- REPEATABLE READ - row S locks as it visits each row, row/table locks held -- until end of transaction. -- READ COMMITTED - instantaneous S locks requested on each row. No locks -- held after query finishes. -- READ UNCOMMITTED - no row locks. No locks held after query finishes. -- -- At this point the base table should look like: -- 1, 10, 'one' -- 3, 30, 'three' -- 5, 50, 'five' -- 7, 70, 'seven' -------------------------------------------------------------------------------- select a from a where a = 5; A ----------- 5 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> -------------------------------------------------------------------------------- -- TEST 4: btree scan, (equals qualifier, no rows return) -- Test "equals" qualified scan on a data set, no rows returned. -- ALL MODES - TABLE IS, "scan page lockname of form (pageno, 1) -- SERIALIZABLE - row S locks as it visits each row, row/table lock -- held until end xact. Also holds one previous key lock. -- REPEATABLE READ - row S locks as it visits each row, row/table locks held -- until end of transaction. -- READ COMMITTED - instantaneous S locks requested on each row. No locks -- held after query finishes. -- READ UNCOMMITTED - no row locks. No locks held after query finishes. -- -- At this point the base table should look like: -- 1, 10, 'one' -- 3, 30, 'three' -- 5, 50, 'five' -- 7, 70, 'seven' -------------------------------------------------------------------------------- -- no rows expected to qualify select a from a where a = 42; A ----------- ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> drop table a; 0 rows inserted/updated/deleted ij> -- non cursor, non-unique index run drop table a; ERROR 42Y55: 'DROP TABLE' cannot be performed on 'A' because it does not exist. ij> create table a (a int, b int, c varchar(1900), index_pad varchar(900) ) ; 0 rows inserted/updated/deleted ij> insert into a values (1, 10, PADSTRING('one',1900), PADSTRING('index pad 1',900)); 1 row inserted/updated/deleted ij> insert into a values (2, 20, PADSTRING('two',1900), PADSTRING('index pad 2',900)); 1 row inserted/updated/deleted ij> insert into a values (3, 30, PADSTRING('three',1900), PADSTRING('index pad 3',900)); 1 row inserted/updated/deleted ij> insert into a values (4, 40, PADSTRING('four',1900), PADSTRING('index pad 4',900)); 1 row inserted/updated/deleted ij> insert into a values (5, 50, PADSTRING('five',1900), PADSTRING('index pad 5',900)); 1 row inserted/updated/deleted ij> insert into a values (6, 60, PADSTRING('six',1900), PADSTRING('index pad 6',900)); 1 row inserted/updated/deleted ij> insert into a values (7, 70, PADSTRING('seven',1900), PADSTRING('index pad 7',900)); 1 row inserted/updated/deleted ij> create index a_idx on a (a, index_pad) ; 0 rows inserted/updated/deleted ij> commit; ij> run resource 'readBtreeSetLocks.subsql'; 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. -- -- Basic single user testing of read locks on select "set" queries on indexes. -- -- This ".subsql" test is -- meant to be run from another test such that it gets run under multiple -- isolation levels. This is important as they behave -- differently, depending on isolation levels. -- -- assume's caller has already done: run 'LockTableQuery.subsql'; to get -- easy access to the lock VTI. -- TEST 0: btree scan -- TEST 1: btree scan, (scan table with some deleted rows) -- TEST 2: btree scan, (scan with "<" qualifier) -- TEST 3: btree scan, (scan with equals qualifier) -- TEST 4: btree scan, (equals qualifier, no rows return) autocommit off; ij> -------------------------------------------------------------------------------- -- Assumes that calling routine has set up the following simple dataset, -- a heap, and index with following initial values: -- create table a (a int, b int, c somesortofchar, [index_pad]); -- create index a_idx on a (a) or a_idx on a (a, index_pad); -- -- 1, 10, 'one' -- 2, 20, 'two' -- 3, 30, 'three' -- 4, 40, 'four' -- 5, 50, 'five' -- 6, 60, 'six' -- 7, 70, 'seven' -------------------------------------------------------------------------------- select * from a; A |B |C |INDEX_PAD ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- 1 |10 |one &|index pad 1 & 2 |20 |two &|index pad 2 & 3 |30 |three &|index pad 3 & 4 |40 |four &|index pad 4 & 5 |50 |five &|index pad 5 & 6 |60 |six &|index pad 6 & 7 |70 |seven &|index pad 7 & ij> commit; ij> -------------------------------------------------------------------------------- -- TEST 0: btree scan -- Test full scan. -- ALL MODES - TABLE IS, "scan page lockname of form (pageno, 1) -- SERIALIZABLE - row S locks as it visits each row, row/table lock -- held until end xact. Also holds one previous key lock. -- REPEATABLE READ - row S locks as it visits each row, row/table locks held -- until end of transaction. -- READ COMMITTED - instantaneous S locks requested on each row. No locks -- held after query finishes. -- READ UNCOMMITTED - no row locks. No locks held after query finishes. -------------------------------------------------------------------------------- select a from a; A ----------- 1 2 3 4 5 6 7 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> -------------------------------------------------------------------------------- -- TEST 1: btree scan, (scan table with some deleted rows) -- Test full scan on a data set with some deleted rows (the "even" ones). -- ALL MODES - TABLE IS, "scan page lockname of form (pageno, 1) -- SERIALIZABLE - row S locks as it visits each row, row/table lock -- held until end xact. Also holds one previous key lock. -- REPEATABLE READ - row S locks as it visits each row, row/table locks held -- until end of transaction. -- READ COMMITTED - instantaneous S locks requested on each row. No locks -- held after query finishes. -- READ UNCOMMITTED - no row locks. No locks held after query finishes. -- -- After the delete the base table should look like: -- 1, 10, 'one' -- 3, 30, 'three' -- 5, 50, 'five' -- 7, 70, 'seven' -------------------------------------------------------------------------------- delete from a where a = 2 or a = 4 or a = 6; 3 rows inserted/updated/deleted ij> commit; ij> -- The above delete and commit can allow post commit processing to run before -- the subsequent select is run, most likely if this run is on a table where -- there is one row per page. To get reproducible results from the subsequent -- lock calls, wait for post commit to finish before running the select. -- Without this wait "extra" locks sometimes might show up - these are locks -- on the committed deleted rows which have not been cleaned yet depending -- on timing. CALL WAIT_FOR_POST_COMMIT(); 0 rows inserted/updated/deleted ij> select a from a; A ----------- 1 3 5 7 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> -------------------------------------------------------------------------------- -- TEST 2: btree scan, (scan with "<" qualifier) -- Test "less than" qualified scan on a data set. -- ALL MODES - TABLE IS, "scan page lockname of form (pageno, 1) -- SERIALIZABLE - row S locks as it visits each row, row/table lock -- held until end xact. Also holds one previous key lock. -- REPEATABLE READ - row S locks as it visits each row, row/table locks held -- until end of transaction. -- READ COMMITTED - instantaneous S locks requested on each row. No locks -- held after query finishes. -- READ UNCOMMITTED - no row locks. No locks held after query finishes. -- -- At this point the base table should look like: -- 1, 10, 'one' -- 3, 30, 'three' -- 5, 50, 'five' -- 7, 70, 'seven' -------------------------------------------------------------------------------- select a from a where a < 3; A ----------- 1 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> -------------------------------------------------------------------------------- -- TEST 3: btree scan, (scan with equals qualifier) -- Test "equals" qualified cursor scan on a data set. -- ALL MODES - TABLE IS, "scan page lockname of form (pageno, 1) -- SERIALIZABLE - row S locks as it visits each row, row/table lock -- held until end xact. Also holds one previous key lock. -- REPEATABLE READ - row S locks as it visits each row, row/table locks held -- until end of transaction. -- READ COMMITTED - instantaneous S locks requested on each row. No locks -- held after query finishes. -- READ UNCOMMITTED - no row locks. No locks held after query finishes. -- -- At this point the base table should look like: -- 1, 10, 'one' -- 3, 30, 'three' -- 5, 50, 'five' -- 7, 70, 'seven' -------------------------------------------------------------------------------- select a from a where a = 5; A ----------- 5 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> -------------------------------------------------------------------------------- -- TEST 4: btree scan, (equals qualifier, no rows return) -- Test "equals" qualified scan on a data set, no rows returned. -- ALL MODES - TABLE IS, "scan page lockname of form (pageno, 1) -- SERIALIZABLE - row S locks as it visits each row, row/table lock -- held until end xact. Also holds one previous key lock. -- REPEATABLE READ - row S locks as it visits each row, row/table locks held -- until end of transaction. -- READ COMMITTED - instantaneous S locks requested on each row. No locks -- held after query finishes. -- READ UNCOMMITTED - no row locks. No locks held after query finishes. -- -- At this point the base table should look like: -- 1, 10, 'one' -- 3, 30, 'three' -- 5, 50, 'five' -- 7, 70, 'seven' -------------------------------------------------------------------------------- -- no rows expected to qualify select a from a where a = 42; A ----------- ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> drop table a; 0 rows inserted/updated/deleted ij> commit; ij> -- READ COMMITTED TEST set isolation read committed; 0 rows inserted/updated/deleted ij> commit; ij> -- run each test with rows on one page in the interesting conglomerate (heap in -- the non-index tests, and in the index in the index based tests). -- cursor, no index run drop table a; ERROR 42Y55: 'DROP TABLE' cannot be performed on 'A' because it does not exist. ij> -- to create tables of page size 4k and still keep the following tbl -- create table a (a int, b int, c varchar(1900)); create table a(a int, b int); 0 rows inserted/updated/deleted ij> alter table a add column c varchar(1900); 0 rows inserted/updated/deleted ij> insert into a values (1, 10, 'one'); 1 row inserted/updated/deleted ij> insert into a values (2, 20, 'two'); 1 row inserted/updated/deleted ij> insert into a values (3, 30, 'three'); 1 row inserted/updated/deleted ij> insert into a values (4, 40, 'four'); 1 row inserted/updated/deleted ij> insert into a values (5, 50, 'five'); 1 row inserted/updated/deleted ij> insert into a values (6, 60, 'six'); 1 row inserted/updated/deleted ij> insert into a values (7, 70, 'seven'); 1 row inserted/updated/deleted ij> commit; ij> run resource 'readCursorLocks.subsql'; 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. -- -- Very basic single user testing of read locks on cursors on heap tables. -- This ".subsql" test is -- meant to be run from another test such that it gets run under multiple -- isolation levels. This is important as they behave -- differently, depending on isolation levels. -- -- assume's caller has already done: run 'LockTableQuery.subsql'; to get -- easy access to the lock VTI. -- TEST 0: heap cursor scan, group fetch = 1 -- TEST 1: heap cursor scan, group fetch = 2 -- TEST 2: heap cursor scan, group fetch = 1, stop scan in middle of set -- TEST 3: heap cursor scan, group fetch = 4, stop scan in middle of set -- TEST 4: heap cursor scan, group fetch = 1 (scan table with some deleted rows) -- TEST 5: heap cursor scan, group fetch = 2 (scan with committed deleted rows) -- TEST 6: heap cursor scan, group fetch = 1 (scan with "<" qualifier) -- TEST 7: heap cursor scan, group fetch = 2 (scan with "<" qualifier) -- TEST 8: heap cursor scan, group fetch = 1 (scan with equals qualifier) -- TEST 9: heap cursor scan, group fetch = 2 (scan with equals qualifier) -- TEST 10: heap cursor scan, group fetch = 1 (equals qualifier, no rows return) autocommit off; ij> -------------------------------------------------------------------------------- -- Assumes that calling routine has set up the following simple dataset, -- a heap, no indexes with following initial values: -- create table (a int, b int, c somesortofchar); -- 1, 10, 'one' -- 2, 20, 'two' -- 3, 30, 'three' -- 4, 40, 'four' -- 5, 50, 'five' -- 6, 60, 'six' -- 7, 70, 'seven' -------------------------------------------------------------------------------- select * from a; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 1 |10 |one 2 |20 |two 3 |30 |three 4 |40 |four 5 |50 |five 6 |60 |six 7 |70 |seven ij> commit; ij> -------------------------------------------------------------------------------- -- TEST 0: heap cursor scan, group fetch = 1 -- Test full cursor scan which does no updates. -- SERIALIZABLE - will get table level S lock. -- REPEATABLE READ - TABLE IS, will get row S locks as it visits each row. -- READ COMMITTED - TABLE IS, will hold single S lock on current row. -- READ UNCOMMITTED - TABLE IS, no row locks. -------------------------------------------------------------------------------- CALL SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.language.bulkFetchDefault','1'); 0 rows inserted/updated/deleted ij> get cursor scan_cursor as 'select a, b, c from a'; ij> call SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.language.bulkFetchDefault', '16'); 0 rows inserted/updated/deleted ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 1 |10 |one ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,7) |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 2 |20 |two ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,8) |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 3 |30 |three ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,9) |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 4 |40 |four ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,10) |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 5 |50 |five ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,11) |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 6 |60 |six ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,12) |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 7 |70 |seven ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,13) |GRANT|ACTIVE ij> next scan_cursor; No current row ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE ij> close scan_cursor; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> -------------------------------------------------------------------------------- -- TEST 1: heap cursor scan, group fetch = 2 -- Test full cursor scan which does no updates. -- SERIALIZABLE - will get table level S lock. -- REPEATABLE READ - TABLE IS, will get row S locks as it visits each row. -- READ COMMITTED - TABLE IS, will get instantaneous locks and release -- READ UNCOMMITTED - TABLE IS, no row locks. -------------------------------------------------------------------------------- CALL SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.language.bulkFetchDefault','2'); 0 rows inserted/updated/deleted ij> -- RESOLVE: missing row locks -- WORKAROUND: creating an index and dropping it -- to force the query 'select a, b, c from a' to be recompiled create index ix1 on a(a); 0 rows inserted/updated/deleted ij> drop index ix1; 0 rows inserted/updated/deleted ij> commit; ij> get cursor scan_cursor as 'select a, b, c from a'; ij> call SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.language.bulkFetchDefault', '16'); 0 rows inserted/updated/deleted ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 1 |10 |one ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 2 |20 |two ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 3 |30 |three ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 4 |40 |four ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 5 |50 |five ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 6 |60 |six ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 7 |70 |seven ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; No current row ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE ij> close scan_cursor; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> -------------------------------------------------------------------------------- -- TEST 2: heap cursor scan, group fetch = 1, stop scan in middle of set -- Test full cursor scan which does no updates. -- SERIALIZABLE - will get table level S lock. -- REPEATABLE READ - TABLE IS, will get row S locks as it visits each row. -- READ COMMITTED - TABLE IS, will hold single S lock on current row. -- READ UNCOMMITTED - TABLE IS, no row locks. -------------------------------------------------------------------------------- CALL SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.language.bulkFetchDefault','1'); 0 rows inserted/updated/deleted ij> -- RESOLVE: missing row locks -- WORKAROUND: creating an index and dropping it -- to force the query 'select a, b, c from a' to be recompiled create index ix1 on a(a); 0 rows inserted/updated/deleted ij> drop index ix1; 0 rows inserted/updated/deleted ij> commit; ij> get cursor scan_cursor as 'select a, b, c from a'; ij> call SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.language.bulkFetchDefault', '16'); 0 rows inserted/updated/deleted ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 1 |10 |one ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,7) |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 2 |20 |two ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,8) |GRANT|ACTIVE ij> close scan_cursor; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> -------------------------------------------------------------------------------- -- TEST 3: heap cursor scan, group fetch = 4, stop scan in middle of set -- Test full cursor scan which does no updates. -- SERIALIZABLE - will get table level S lock. -- REPEATABLE READ - TABLE IS, will get row S locks as it visits each row. -- READ COMMITTED - TABLE IS, will hold single S lock on current row. -- READ UNCOMMITTED - TABLE IS, no row locks. -------------------------------------------------------------------------------- CALL SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.language.bulkFetchDefault','4'); 0 rows inserted/updated/deleted ij> -- RESOLVE: missing row locks -- WORKAROUND: creating an index and dropping it -- to force the query 'select a, b, c from a' to be recompiled create index ix1 on a(a); 0 rows inserted/updated/deleted ij> drop index ix1; 0 rows inserted/updated/deleted ij> commit; ij> get cursor scan_cursor as 'select a, b, c from a'; ij> call SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.language.bulkFetchDefault', '16'); 0 rows inserted/updated/deleted ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 1 |10 |one ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 2 |20 |two ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE ij> close scan_cursor; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> -------------------------------------------------------------------------------- -- TEST 4: heap cursor scan, group fetch = 1 (scan table with some deleted rows) -- Test full cursor scan on a data set with some deleted rows (the "even" ones). -- SERIALIZABLE - will get table level S lock. -- REPEATABLE READ - TABLE IS, will get row S locks as it visits each row -- (including deleted ones). -- READ COMMITTED - TABLE IS, will get instantaneous locks and release -- READ UNCOMMITTED - TABLE IS, no row locks. -- -- After the delete the table should look like: -- 1, 10, 'one' -- 3, 30, 'three' -- 5, 50, 'five' -- 7, 70, 'seven' -------------------------------------------------------------------------------- delete from a where a = 2 or a = 4 or a = 6; 3 rows inserted/updated/deleted ij> commit; ij> CALL SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.language.bulkFetchDefault','1'); 0 rows inserted/updated/deleted ij> -- RESOLVE: missing row locks -- WORKAROUND: creating an index and dropping it -- to force the query 'select a, b, c from a' to be recompiled create index ix1 on a(a); 0 rows inserted/updated/deleted ij> drop index ix1; 0 rows inserted/updated/deleted ij> commit; ij> get cursor scan_cursor as 'select a, b, c from a'; ij> call SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.language.bulkFetchDefault', '16'); 0 rows inserted/updated/deleted ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 1 |10 |one ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,7) |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 3 |30 |three ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,9) |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 5 |50 |five ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,11) |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 7 |70 |seven ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,13) |GRANT|ACTIVE ij> next scan_cursor; No current row ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE ij> close scan_cursor; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> -------------------------------------------------------------------------------- -- TEST 5: heap cursor scan, group fetch = 2 (scan with committed deleted rows) -- Test full cursor scan on a data set with some deleted rows (the "even" ones). -- SERIALIZABLE - will get table level S lock. -- REPEATABLE READ - TABLE IS, will get row S locks as it visits each row -- (including deleted ones). -- READ COMMITTED - TABLE IS, will get instantaneous locks and release -- READ UNCOMMITTED - TABLE IS, no row locks. -- -- At this point the table should look like: -- 1, 10, 'one' -- 3, 30, 'three' -- 5, 50, 'five' -- 7, 70, 'seven' -------------------------------------------------------------------------------- CALL SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.language.bulkFetchDefault','2'); 0 rows inserted/updated/deleted ij> -- RESOLVE: missing row locks -- WORKAROUND: creating an index and dropping it -- to force the query 'select a, b, c from a' to be recompiled create index ix1 on a(a); 0 rows inserted/updated/deleted ij> drop index ix1; 0 rows inserted/updated/deleted ij> commit; ij> get cursor scan_cursor as 'select a, b, c from a'; ij> call SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.language.bulkFetchDefault', '16'); 0 rows inserted/updated/deleted ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 1 |10 |one ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 3 |30 |three ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 5 |50 |five ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 7 |70 |seven ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; No current row ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE ij> close scan_cursor; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> -------------------------------------------------------------------------------- -- TEST 6: heap cursor scan, group fetch = 1 (scan with "<" qualifier) -- Test "less than" qualified cursor scan on a data set. -- SERIALIZABLE - will get table level S lock. -- REPEATABLE READ - TABLE IS, will get row S locks as it visits each row -- (including deleted ones). -- READ COMMITTED - TABLE IS, will get instantaneous locks and release -- READ UNCOMMITTED - TABLE IS, no row locks. -- -- At this point the table should look like: -- 1, 10, 'one' -- 3, 30, 'three' -- 5, 50, 'five' -- 7, 70, 'seven' -------------------------------------------------------------------------------- CALL SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.language.bulkFetchDefault','1'); 0 rows inserted/updated/deleted ij> get cursor scan_cursor as 'select a, b, c from a where a < 3'; ij> call SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.language.bulkFetchDefault', '16'); 0 rows inserted/updated/deleted ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 1 |10 |one ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,7) |GRANT|ACTIVE ij> next scan_cursor; No current row ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE ij> close scan_cursor; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> -------------------------------------------------------------------------------- -- TEST 7: heap cursor scan, group fetch = 2 (scan with "<" qualifier) -- Test "less than" qualified cursor scan on a data set. -- SERIALIZABLE - will get table level S lock. -- REPEATABLE READ - TABLE IS, will get row S locks as it visits each row -- (including deleted ones). -- READ COMMITTED - TABLE IS, will get instantaneous locks and release -- READ UNCOMMITTED - TABLE IS, no row locks. -- -- At this point the table should look like: -- 1, 10, 'one' -- 3, 30, 'three' -- 5, 50, 'five' -- 7, 70, 'seven' -------------------------------------------------------------------------------- CALL SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.language.bulkFetchDefault','2'); 0 rows inserted/updated/deleted ij> -- RESOLVE: missing row locks -- WORKAROUND: creating an index and dropping it -- to force the statement to be recompiled create index ix1 on a(a); 0 rows inserted/updated/deleted ij> drop index ix1; 0 rows inserted/updated/deleted ij> commit; ij> get cursor scan_cursor as 'select a, b, c from a where a < 3'; ij> call SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.language.bulkFetchDefault', '16'); 0 rows inserted/updated/deleted ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 1 |10 |one ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; No current row ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE ij> close scan_cursor; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> -------------------------------------------------------------------------------- -- TEST 8: heap cursor scan, group fetch = 1 (scan with equals qualifier) -- Test "equals" qualified cursor scan on a data set. -- SERIALIZABLE - will get table level S lock. -- REPEATABLE READ - TABLE IS, will get row S locks as it visits each row -- (including deleted ones). -- READ COMMITTED - TABLE IS, will get instantaneous locks and release -- READ UNCOMMITTED - TABLE IS, no row locks. -- -- At this point the table should look like: -- 1, 10, 'one' -- 3, 30, 'three' -- 5, 50, 'five' -- 7, 70, 'seven' -------------------------------------------------------------------------------- CALL SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.language.bulkFetchDefault','1'); 0 rows inserted/updated/deleted ij> get cursor scan_cursor as 'select a, b, c from a where a = 5'; ij> call SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.language.bulkFetchDefault', '16'); 0 rows inserted/updated/deleted ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 5 |50 |five ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,11) |GRANT|ACTIVE ij> next scan_cursor; No current row ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE ij> close scan_cursor; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> -------------------------------------------------------------------------------- -- TEST 9: heap cursor scan, group fetch = 2 (scan with equals qualifier) -- Test "equals" qualified cursor scan on a data set. -- SERIALIZABLE - will get table level S lock. -- REPEATABLE READ - TABLE IS, will get row S locks as it visits each row -- (including deleted ones). -- READ COMMITTED - TABLE IS, will get instantaneous locks and release -- READ UNCOMMITTED - TABLE IS, no row locks. -- -- At this point the table should look like: -- 1, 10, 'one' -- 3, 30, 'three' -- 5, 50, 'five' -- 7, 70, 'seven' -------------------------------------------------------------------------------- CALL SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.language.bulkFetchDefault','2'); 0 rows inserted/updated/deleted ij> get cursor scan_cursor as 'select a, b, c from a where a = 7'; ij> call SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.language.bulkFetchDefault', '16'); 0 rows inserted/updated/deleted ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 7 |70 |seven ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; No current row ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE ij> close scan_cursor; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> -------------------------------------------------------------------------------- -- TEST 10: heap cursor scan, group fetch = 1 (equals qualifier, no rows return) -- Test "equals" qualified cursor scan on a data set, no rows returned. -- SERIALIZABLE - will get table level S lock. -- REPEATABLE READ - TABLE IS, will get row S locks as it visits each row -- (including deleted ones). -- READ COMMITTED - TABLE IS, will get instantaneous locks and release -- READ UNCOMMITTED - TABLE IS, no row locks. -- -- At this point the table should look like: -- 1, 10, 'one' -- 3, 30, 'three' -- 5, 50, 'five' -- 7, 70, 'seven' -------------------------------------------------------------------------------- CALL SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.language.bulkFetchDefault','1'); 0 rows inserted/updated/deleted ij> -- RESOLVE: missing row locks -- WORKAROUND: creating an index and dropping it -- to force the statement to be recompiled create index ix1 on a(a); 0 rows inserted/updated/deleted ij> drop index ix1; 0 rows inserted/updated/deleted ij> commit; ij> get cursor scan_cursor as 'select a, b, c from a where a = 7'; ij> CALL SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.language.bulkFetchDefault','16'); 0 rows inserted/updated/deleted ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 7 |70 |seven ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,13) |GRANT|ACTIVE ij> next scan_cursor; No current row ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE ij> close scan_cursor; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> drop table a; 0 rows inserted/updated/deleted ij> -- non cursor, no index run drop table a; ERROR 42Y55: 'DROP TABLE' cannot be performed on 'A' because it does not exist. ij> -- to create tables of page size 4k and still keep the following tbl -- create table a (a int, b int, c varchar(1900)); create table a(a int, b int); 0 rows inserted/updated/deleted ij> alter table a add column c varchar(1900); 0 rows inserted/updated/deleted ij> insert into a values (1, 10, 'one'); 1 row inserted/updated/deleted ij> insert into a values (2, 20, 'two'); 1 row inserted/updated/deleted ij> insert into a values (3, 30, 'three'); 1 row inserted/updated/deleted ij> insert into a values (4, 40, 'four'); 1 row inserted/updated/deleted ij> insert into a values (5, 50, 'five'); 1 row inserted/updated/deleted ij> insert into a values (6, 60, 'six'); 1 row inserted/updated/deleted ij> insert into a values (7, 70, 'seven'); 1 row inserted/updated/deleted ij> commit; ij> run resource 'readSetLocks.subsql'; 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. -- -- Very basic single user testing of read locks in "set" queries on heap tables. -- This ".subsql" test is -- meant to be run from another test such that it gets run under multiple -- isolation levels. This is important as they behave -- differently, depending on isolation levels. -- -- assume's caller has already done: run 'LockTableQuery.subsql'; to get -- easy access to the lock VTI. -- TEST 0: heap scan. -- TEST 1: heap scan, some rows deleted. -- TEST 2: heap scan, (scan with "<" qualifier) -- TEST 3: heap scan, (scan with equals qualifier) -- TEST 4: heap scan, (equals qualifier, no rows return) autocommit off; ij> -------------------------------------------------------------------------------- -- Assumes that calling routine has set up the following simple dataset, -- a heap, no indexes with following initial values: -- create table (a int, b int, c somesortofchar); -- 1, 10, 'one' -- 2, 20, 'two' -- 3, 30, 'three' -- 4, 40, 'four' -- 5, 50, 'five' -- 6, 60, 'six' -- 7, 70, 'seven' -------------------------------------------------------------------------------- select * from a; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 1 |10 |one 2 |20 |two 3 |30 |three 4 |40 |four 5 |50 |five 6 |60 |six 7 |70 |seven ij> commit; ij> -------------------------------------------------------------------------------- -- TEST 0: heap scan. -- Test full cursor scan which does no updates. -- SERIALIZABLE - will get table level S lock, held to end of xact. -- REPEATABLE READ - TABLE IS, will get row S locks as it visits each row -- (including deleted ones). held to end of xact. -- READ COMMITTED - TABLE IS, will get instantaneous locks and release. No -- locks held when statement completes. -- READ UNCOMMITTED - TABLE IS, no row locks. No locks after statement ends. -------------------------------------------------------------------------------- select a, b, c from a; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 1 |10 |one 2 |20 |two 3 |30 |three 4 |40 |four 5 |50 |five 6 |60 |six 7 |70 |seven ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> -------------------------------------------------------------------------------- -- TEST 1: heap scan, some rows deleted. -- Test full cursor scan on a data set with some deleted rows (the "even" ones). -- SERIALIZABLE - will get table level S lock. -- REPEATABLE READ - TABLE IS, will get row S locks as it visits each row -- (including deleted ones). -- READ COMMITTED - TABLE IS, will get instantaneous locks and release -- READ UNCOMMITTED - TABLE IS, no row locks. -- SERIALIZABLE - will get table level S lock, held to end of xact. -- REPEATABLE READ - TABLE IS, will get row S locks as it visits each row -- (including deleted ones). held to end of xact. -- READ COMMITTED - TABLE IS, will get instantaneous locks and release. No -- locks held when statement completes. -- READ UNCOMMITTED - TABLE IS, no row locks. No locks after statement ends. -- -- After the delete the table should look like: -- 1, 10, 'one' -- 3, 30, 'three' -- 5, 50, 'five' -- 7, 70, 'seven' -------------------------------------------------------------------------------- delete from a where a = 2 or a = 4 or a = 6; 3 rows inserted/updated/deleted ij> commit; ij> select a, b, c from a; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 1 |10 |one 3 |30 |three 5 |50 |five 7 |70 |seven ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> -------------------------------------------------------------------------------- -- TEST 2: heap scan, (scan with "<" qualifier) -- Test "less than" qualified cursor scan on a data set. -- SERIALIZABLE - will get table level S lock, held to end of xact. -- REPEATABLE READ - TABLE IS, will get row S locks as it visits each row -- (including deleted ones). held to end of xact. -- READ COMMITTED - TABLE IS, will get instantaneous locks and release. No -- locks held when statement completes. -- READ UNCOMMITTED - TABLE IS, no row locks. No locks after statement ends. -- -- At this point the table should look like: -- 1, 10, 'one' -- 3, 30, 'three' -- 5, 50, 'five' -- 7, 70, 'seven' -------------------------------------------------------------------------------- select a, b, c from a; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 1 |10 |one 3 |30 |three 5 |50 |five 7 |70 |seven ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> -------------------------------------------------------------------------------- -- TEST 3: heap scan, (scan with equals qualifier) -- Test "equals" qualified cursor scan on a data set. -- SERIALIZABLE - will get table level S lock, held to end of xact. -- REPEATABLE READ - TABLE IS, will get row S locks as it visits each row -- (including deleted ones). held to end of xact. -- READ COMMITTED - TABLE IS, will get instantaneous locks and release. No -- locks held when statement completes. -- READ UNCOMMITTED - TABLE IS, no row locks. No locks after statement ends. -- -- At this point the table should look like: -- 1, 10, 'one' -- 3, 30, 'three' -- 5, 50, 'five' -- 7, 70, 'seven' -------------------------------------------------------------------------------- select a, b, c from a where a = 5; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 5 |50 |five ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> -------------------------------------------------------------------------------- -- TEST 4: heap scan, (equals qualifier, no rows return) -- Test "equals" qualified cursor scan on a data set, no rows returned. -- SERIALIZABLE - will get table level S lock, held to end of xact. -- REPEATABLE READ - TABLE IS, will get row S locks as it visits each row -- (including deleted ones). held to end of xact. -- READ COMMITTED - TABLE IS, will get instantaneous locks and release. No -- locks held when statement completes. -- READ UNCOMMITTED - TABLE IS, no row locks. No locks after statement ends. -- -- At this point the table should look like: -- 1, 10, 'one' -- 3, 30, 'three' -- 5, 50, 'five' -- 7, 70, 'seven' -------------------------------------------------------------------------------- select a, b, c from a where a = 7; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 7 |70 |seven ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> drop table a; 0 rows inserted/updated/deleted ij> -- cursor, unique index run drop table a; ERROR 42Y55: 'DROP TABLE' cannot be performed on 'A' because it does not exist. ij> -- to create tables of page size 4k and still keep the following tbl -- create table a (a int, b int, c varchar(1900)); create table a(a int, b int); 0 rows inserted/updated/deleted ij> alter table a add column c varchar(1900); 0 rows inserted/updated/deleted ij> insert into a values (1, 10, 'one'); 1 row inserted/updated/deleted ij> insert into a values (2, 20, 'two'); 1 row inserted/updated/deleted ij> insert into a values (3, 30, 'three'); 1 row inserted/updated/deleted ij> insert into a values (4, 40, 'four'); 1 row inserted/updated/deleted ij> insert into a values (5, 50, 'five'); 1 row inserted/updated/deleted ij> insert into a values (6, 60, 'six'); 1 row inserted/updated/deleted ij> insert into a values (7, 70, 'seven'); 1 row inserted/updated/deleted ij> create unique index a_idx on a (a); 0 rows inserted/updated/deleted ij> commit; ij> run resource 'readBtreeCursorLocks.subsql'; 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. -- -- Very basic single user testing of read locks on cursors on indexes. -- This ".subsql" test is -- meant to be run from another test such that it gets run under multiple -- isolation levels. This is important as they behave -- differently, depending on isolation levels. -- -- assume's caller has already done: run 'LockTableQuery.subsql'; to get -- easy access to the lock VTI. -- TEST 0: btree cursor scan, group fetch = 1 -- TEST 1: btree cursor scan, group fetch = 2 -- TEST 2: btree cursor scan, group fetch = 1 stop scan in middle of set -- TEST 3: btree cursor scan, group fetch = 4 stop scan in middle of set -- TEST 4: btree cursor scan, group fetch = 1 (scan with some deleted rows) -- TEST 5: btree cursor scan, group fetch = 2(scan with committed deleted rows) -- TEST 6: btree cursor scan, group fetch = 1 (scan with "<" qualifier) -- TEST 7: btree cursor scan, group fetch = 2 (scan with "<" qualifier) -- TEST 8: btree cursor scan, group fetch = 1 (scan with equals qualifier) -- TEST 9: btree cursor scan, group fetch = 2 (scan with equals qualifier) -- TEST 10: btree cursor scan, group fetch = 1 ("=" qualifier, no rows return) autocommit off; ij> -------------------------------------------------------------------------------- -- Assumes that calling routine has set up the following simple dataset, -- a heap, and index with following initial values: -- create table a (a int, b int, c somesortofchar, [index_pad]); -- create index a_idx on a (a) or a_idx on a (a, index_pad); -- -- 1, 10, 'one' -- 2, 20, 'two' -- 3, 30, 'three' -- 4, 40, 'four' -- 5, 50, 'five' -- 6, 60, 'six' -- 7, 70, 'seven' -------------------------------------------------------------------------------- select * from a; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 1 |10 |one 2 |20 |two 3 |30 |three 4 |40 |four 5 |50 |five 6 |60 |six 7 |70 |seven ij> commit; ij> -------------------------------------------------------------------------------- -- TEST 0: btree cursor scan, group fetch = 1 -- Test full cursor scan which does no updates. -- ALL MODES - TABLE IS, "scan page lockname of form (pageno, 1) -- SERIALIZABLE - row S locks as it visits each row, held until end xact -- REPEATABLE READ - row S locks as it visits each row, held until end xact -- READ COMMITTED - row S lock on current row, released on move to next row -- READ UNCOMMITTED - no row locks. ------------------------------------------------------------------------------- CALL SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.language.bulkFetchDefault','1'); 0 rows inserted/updated/deleted ij> -- RESOLVE: missing row locks -- WORKAROUND: creating an index and dropping it -- to force the statement to be recompiled create index ix1 on a(a); 0 rows inserted/updated/deleted WARNING 01504: The new index is a duplicate of an existing index: A_IDX. ij> drop index ix1; ERROR 42X65: Index 'IX1' does not exist. ij> commit; ij> get cursor scan_cursor as 'select a from a'; ij> call SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.language.bulkFetchDefault', '16'); 0 rows inserted/updated/deleted ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A ----------- 1 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,1) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,7) |GRANT|ACTIVE ij> next scan_cursor; A ----------- 2 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,1) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,8) |GRANT|ACTIVE ij> next scan_cursor; A ----------- 3 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,1) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,9) |GRANT|ACTIVE ij> next scan_cursor; A ----------- 4 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,1) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,10) |GRANT|ACTIVE ij> next scan_cursor; A ----------- 5 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,1) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,11) |GRANT|ACTIVE ij> next scan_cursor; A ----------- 6 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,1) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,12) |GRANT|ACTIVE ij> next scan_cursor; A ----------- 7 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,1) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,13) |GRANT|ACTIVE ij> next scan_cursor; No current row ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE ij> close scan_cursor; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> -------------------------------------------------------------------------------- -- TEST 1: btree cursor scan, group fetch = 2 -- Test full cursor scan which does no updates. -- ALL MODES - TABLE IS, "scan page lockname of form (pageno, 1) -- SERIALIZABLE - row S locks as it visits each row, held until end xact -- REPEATABLE READ - row S locks as it visits each row, held until end xact -- READ COMMITTED - row S lock on current row, released on move to next row -- READ UNCOMMITTED - no row locks. -------------------------------------------------------------------------------- CALL SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.language.bulkFetchDefault','2'); 0 rows inserted/updated/deleted ij> -- RESOLVE: missing row locks -- WORKAROUND: creating an index and dropping it -- to force the statement to be recompiled create index ix1 on a(a); 0 rows inserted/updated/deleted WARNING 01504: The new index is a duplicate of an existing index: A_IDX. ij> drop index ix1; ERROR 42X65: Index 'IX1' does not exist. ij> commit; ij> get cursor scan_cursor as 'select a from a'; ij> call SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.language.bulkFetchDefault', '16'); 0 rows inserted/updated/deleted ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A ----------- 1 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,1) |GRANT|ACTIVE ij> next scan_cursor; A ----------- 2 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,1) |GRANT|ACTIVE ij> next scan_cursor; A ----------- 3 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,1) |GRANT|ACTIVE ij> next scan_cursor; A ----------- 4 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,1) |GRANT|ACTIVE ij> next scan_cursor; A ----------- 5 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,1) |GRANT|ACTIVE ij> next scan_cursor; A ----------- 6 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,1) |GRANT|ACTIVE ij> next scan_cursor; A ----------- 7 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; No current row ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE ij> close scan_cursor; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> -------------------------------------------------------------------------------- -- TEST 2: btree cursor scan, group fetch = 1, stop scan in middle of set -- Test full cursor scan which does no updates. -- ALL MODES - TABLE IS, "scan page lockname of form (pageno, 1) -- SERIALIZABLE - row S locks as it visits each row, held until end xact -- REPEATABLE READ - row S locks as it visits each row, held until end xact -- READ COMMITTED - row S lock on current row, released on move to next row -- READ UNCOMMITTED - no row locks. -------------------------------------------------------------------------------- CALL SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.language.bulkFetchDefault','1'); 0 rows inserted/updated/deleted ij> -- RESOLVE: missing row locks -- WORKAROUND: creating an index and dropping it -- to force the statement to be recompiled create index ix1 on a(a); 0 rows inserted/updated/deleted WARNING 01504: The new index is a duplicate of an existing index: A_IDX. ij> drop index ix1; ERROR 42X65: Index 'IX1' does not exist. ij> commit; ij> get cursor scan_cursor as 'select a from a'; ij> call SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.language.bulkFetchDefault', '16'); 0 rows inserted/updated/deleted ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A ----------- 1 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,1) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,7) |GRANT|ACTIVE ij> next scan_cursor; A ----------- 2 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,1) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,8) |GRANT|ACTIVE ij> close scan_cursor; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> -------------------------------------------------------------------------------- -- TEST 3: btree cursor scan, group fetch = 4, stop scan in middle of set -- Test full cursor scan which does no updates. -- ALL MODES - TABLE IS, "scan page lockname of form (pageno, 1) -- SERIALIZABLE - row S locks as it visits each row, held until end xact -- REPEATABLE READ - row S locks as it visits each row, held until end xact -- READ COMMITTED - row S lock on current row, released on move to next row -- READ UNCOMMITTED - no row locks. -------------------------------------------------------------------------------- CALL SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.language.bulkFetchDefault','4'); 0 rows inserted/updated/deleted ij> -- RESOLVE: missing row locks -- WORKAROUND: creating an index and dropping it -- to force the statement to be recompiled create index ix1 on a(a); 0 rows inserted/updated/deleted WARNING 01504: The new index is a duplicate of an existing index: A_IDX. ij> drop index ix1; ERROR 42X65: Index 'IX1' does not exist. ij> commit; ij> get cursor scan_cursor as 'select a from a'; ij> call SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.language.bulkFetchDefault', '16'); 0 rows inserted/updated/deleted ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A ----------- 1 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,1) |GRANT|ACTIVE ij> next scan_cursor; A ----------- 2 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,1) |GRANT|ACTIVE ij> close scan_cursor; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> -------------------------------------------------------------------------------- -- TEST 4: btree cursor scan, group fetch = 1 (scan table with some deleted rows) -- Test full cursor scan on a data set with some deleted rows (the "even" ones). -- ALL MODES - TABLE IS, "scan page lockname of form (pageno, 1) -- SERIALIZABLE - row S locks as it visits each row, held until end xact -- REPEATABLE READ - row S locks as it visits each row, held until end xact -- READ COMMITTED - row S lock on current row, released on move to next row -- READ UNCOMMITTED - no row locks. -- -- After the delete the base table should look like: -- 1, 10, 'one' -- 3, 30, 'three' -- 5, 50, 'five' -- 7, 70, 'seven' -------------------------------------------------------------------------------- delete from a where a = 2 or a = 4 or a = 6; 3 rows inserted/updated/deleted ij> commit; ij> CALL SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.language.bulkFetchDefault','1'); 0 rows inserted/updated/deleted ij> -- RESOLVE: missing row locks -- WORKAROUND: creating an index and dropping it -- to force the statement to be recompiled create index ix1 on a(a); 0 rows inserted/updated/deleted WARNING 01504: The new index is a duplicate of an existing index: A_IDX. ij> drop index ix1; ERROR 42X65: Index 'IX1' does not exist. ij> commit; ij> get cursor scan_cursor as 'select a from a'; ij> call SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.language.bulkFetchDefault', '16'); 0 rows inserted/updated/deleted ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A ----------- 1 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,1) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,7) |GRANT|ACTIVE ij> next scan_cursor; A ----------- 3 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,1) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,9) |GRANT|ACTIVE ij> next scan_cursor; A ----------- 5 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,1) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,11) |GRANT|ACTIVE ij> next scan_cursor; A ----------- 7 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,1) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,13) |GRANT|ACTIVE ij> next scan_cursor; No current row ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE ij> close scan_cursor; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> -------------------------------------------------------------------------------- -- TEST 5: btree cursor scan, group fetch = 2 (scan with committed deleted rows) -- Test full cursor scan on a data set with some deleted rows (the "even" ones). -- ALL MODES - TABLE IS, "scan page lockname of form (pageno, 1) -- SERIALIZABLE - row S locks as it visits each row, held until end xact -- REPEATABLE READ - row S locks as it visits each row, held until end xact -- READ COMMITTED - row S lock on current row, released on move to next row -- READ UNCOMMITTED - no row locks. -- -- At this point the base table should look like: -- 1, 10, 'one' -- 3, 30, 'three' -- 5, 50, 'five' -- 7, 70, 'seven' -------------------------------------------------------------------------------- CALL SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.language.bulkFetchDefault','2'); 0 rows inserted/updated/deleted ij> -- RESOLVE: missing row locks -- WORKAROUND: creating an index and dropping it -- to force the statement to be recompiled create index ix1 on a(a); 0 rows inserted/updated/deleted WARNING 01504: The new index is a duplicate of an existing index: A_IDX. ij> drop index ix1; ERROR 42X65: Index 'IX1' does not exist. ij> commit; ij> get cursor scan_cursor as 'select a from a'; ij> call SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.language.bulkFetchDefault', '16'); 0 rows inserted/updated/deleted ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A ----------- 1 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,1) |GRANT|ACTIVE ij> next scan_cursor; A ----------- 3 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,1) |GRANT|ACTIVE ij> next scan_cursor; A ----------- 5 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,1) |GRANT|ACTIVE ij> next scan_cursor; A ----------- 7 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,1) |GRANT|ACTIVE ij> next scan_cursor; No current row ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE ij> close scan_cursor; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> -------------------------------------------------------------------------------- -- TEST 6: btree cursor scan, group fetch = 1 (scan with "<" qualifier) -- Test "less than" qualified cursor scan on a data set. -- ALL MODES - TABLE IS, "scan page lockname of form (pageno, 1) -- SERIALIZABLE - row S locks as it visits each row, held until end xact -- REPEATABLE READ - row S locks as it visits each row, held until end xact -- READ COMMITTED - row S lock on current row, released on move to next row -- READ UNCOMMITTED - no row locks. -- -- At this point the base table should look like: -- 1, 10, 'one' -- 3, 30, 'three' -- 5, 50, 'five' -- 7, 70, 'seven' -------------------------------------------------------------------------------- CALL SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.language.bulkFetchDefault','1'); 0 rows inserted/updated/deleted ij> -- RESOLVE: missing row locks -- WORKAROUND: creating an index and dropping it -- to force the statement to be recompiled create index ix1 on a(a); 0 rows inserted/updated/deleted WARNING 01504: The new index is a duplicate of an existing index: A_IDX. ij> drop index ix1; ERROR 42X65: Index 'IX1' does not exist. ij> commit; ij> get cursor scan_cursor as 'select a from a where a < 3'; ij> call SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.language.bulkFetchDefault', '16'); 0 rows inserted/updated/deleted ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A ----------- 1 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,1) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,7) |GRANT|ACTIVE ij> next scan_cursor; No current row ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE ij> close scan_cursor; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> -------------------------------------------------------------------------------- -- TEST 7: btree cursor scan, group fetch = 2 (scan with "<" qualifier) -- Test "less than" qualified cursor scan on a data set. -- ALL MODES - TABLE IS, "scan page lockname of form (pageno, 1) -- SERIALIZABLE - row S locks as it visits each row, held until end xact -- REPEATABLE READ - row S locks as it visits each row, held until end xact -- READ COMMITTED - row S lock on current row, released on move to next row -- READ UNCOMMITTED - no row locks. -- -- At this point the base table should look like: -- 1, 10, 'one' -- 3, 30, 'three' -- 5, 50, 'five' -- 7, 70, 'seven' -------------------------------------------------------------------------------- CALL SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.language.bulkFetchDefault','2'); 0 rows inserted/updated/deleted ij> -- RESOLVE: missing row locks -- WORKAROUND: creating an index and dropping it -- to force the statement to be recompiled create index ix1 on a(a); 0 rows inserted/updated/deleted WARNING 01504: The new index is a duplicate of an existing index: A_IDX. ij> drop index ix1; ERROR 42X65: Index 'IX1' does not exist. ij> commit; ij> get cursor scan_cursor as 'select a from a where a < 3'; ij> call SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.language.bulkFetchDefault', '16'); 0 rows inserted/updated/deleted ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A ----------- 1 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; No current row ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE ij> close scan_cursor; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> -------------------------------------------------------------------------------- -- TEST 8: btree cursor scan, group fetch = 1 (scan with equals qualifier) -- Test "equals" qualified cursor scan on a data set. -- ALL MODES - TABLE IS, "scan page lockname of form (pageno, 1) -- SERIALIZABLE - row S locks as it visits each row, held until end xact -- REPEATABLE READ - row S locks as it visits each row, held until end xact -- READ COMMITTED - row S lock on current row, released on move to next row -- READ UNCOMMITTED - no row locks. -- -- At this point the base table should look like: -- 1, 10, 'one' -- 3, 30, 'three' -- 5, 50, 'five' -- 7, 70, 'seven' -------------------------------------------------------------------------------- CALL SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.language.bulkFetchDefault','1'); 0 rows inserted/updated/deleted ij> -- RESOLVE: missing row locks -- WORKAROUND: creating an index and dropping it -- to force the statement to be recompiled create index ix1 on a(a); 0 rows inserted/updated/deleted WARNING 01504: The new index is a duplicate of an existing index: A_IDX. ij> drop index ix1; ERROR 42X65: Index 'IX1' does not exist. ij> commit; ij> get cursor scan_cursor as 'select a from a where a = 5'; ij> call SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.language.bulkFetchDefault', '16'); 0 rows inserted/updated/deleted ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A ----------- 5 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,1) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,11) |GRANT|ACTIVE ij> next scan_cursor; No current row ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,1) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,11) |GRANT|ACTIVE ij> close scan_cursor; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> -------------------------------------------------------------------------------- -- TEST 9: btree cursor scan, group fetch = 2 (scan with equals qualifier) -- Test "equals" qualified cursor scan on a data set. -- ALL MODES - TABLE IS, "scan page lockname of form (pageno, 1) -- SERIALIZABLE - row S locks as it visits each row, held until end xact -- REPEATABLE READ - row S locks as it visits each row, held until end xact -- READ COMMITTED - row S lock on current row, released on move to next row -- READ UNCOMMITTED - no row locks. -- -- At this point the base table should look like: -- 1, 10, 'one' -- 3, 30, 'three' -- 5, 50, 'five' -- 7, 70, 'seven' -------------------------------------------------------------------------------- CALL SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.language.bulkFetchDefault','2'); 0 rows inserted/updated/deleted ij> -- RESOLVE: missing row locks -- WORKAROUND: creating an index and dropping it -- to force the statement to be recompiled create index ix1 on a(a); 0 rows inserted/updated/deleted WARNING 01504: The new index is a duplicate of an existing index: A_IDX. ij> drop index ix1; ERROR 42X65: Index 'IX1' does not exist. ij> commit; ij> get cursor scan_cursor as 'select a from a where a = 5 or a = 7'; ij> call SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.language.bulkFetchDefault', '16'); 0 rows inserted/updated/deleted ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A ----------- 5 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,1) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,11) |GRANT|ACTIVE ij> next scan_cursor; A ----------- 7 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,1) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,13) |GRANT|ACTIVE ij> close scan_cursor; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> -------------------------------------------------------------------------------- -- TEST 10: btree cursor scan, group fetch = 1 (equals qualifier, no rows return) -- Test "equals" qualified cursor scan on a data set, no rows returned. -- ALL MODES - TABLE IS, "scan page lockname of form (pageno, 1) -- SERIALIZABLE - row S locks as it visits each row, held until end xact -- REPEATABLE READ - row S locks as it visits each row, held until end xact -- READ COMMITTED - row S lock on current row, released on move to next row -- READ UNCOMMITTED - no row locks. -- -- At this point the base table should look like: -- 1, 10, 'one' -- 3, 30, 'three' -- 5, 50, 'five' -- 7, 70, 'seven' -------------------------------------------------------------------------------- -- no rows expected to qualify CALL SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.language.bulkFetchDefault','1'); 0 rows inserted/updated/deleted ij> -- RESOLVE: missing row locks -- WORKAROUND: creating an index and dropping it -- to force the statement to be recompiled create index ix1 on a(a); 0 rows inserted/updated/deleted WARNING 01504: The new index is a duplicate of an existing index: A_IDX. ij> drop index ix1; ERROR 42X65: Index 'IX1' does not exist. ij> commit; ij> get cursor scan_cursor as 'select a from a where a = 42'; ij> call SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.language.bulkFetchDefault', '16'); 0 rows inserted/updated/deleted ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; No current row ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; No current row ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE ij> close scan_cursor; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> drop table a; 0 rows inserted/updated/deleted ij> -- cursor, non-unique index run drop table a; ERROR 42Y55: 'DROP TABLE' cannot be performed on 'A' because it does not exist. ij> -- to create tables of page size 4k and still keep the following tbl -- create table a (a int, b int, c varchar(1900)); create table a(a int, b int); 0 rows inserted/updated/deleted ij> alter table a add column c varchar(1900); 0 rows inserted/updated/deleted ij> insert into a values (1, 10, 'one'); 1 row inserted/updated/deleted ij> insert into a values (2, 20, 'two'); 1 row inserted/updated/deleted ij> insert into a values (3, 30, 'three'); 1 row inserted/updated/deleted ij> insert into a values (4, 40, 'four'); 1 row inserted/updated/deleted ij> insert into a values (5, 50, 'five'); 1 row inserted/updated/deleted ij> insert into a values (6, 60, 'six'); 1 row inserted/updated/deleted ij> insert into a values (7, 70, 'seven'); 1 row inserted/updated/deleted ij> create index a_idx on a (a); 0 rows inserted/updated/deleted ij> commit; ij> run resource 'readBtreeCursorLocks.subsql'; 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. -- -- Very basic single user testing of read locks on cursors on indexes. -- This ".subsql" test is -- meant to be run from another test such that it gets run under multiple -- isolation levels. This is important as they behave -- differently, depending on isolation levels. -- -- assume's caller has already done: run 'LockTableQuery.subsql'; to get -- easy access to the lock VTI. -- TEST 0: btree cursor scan, group fetch = 1 -- TEST 1: btree cursor scan, group fetch = 2 -- TEST 2: btree cursor scan, group fetch = 1 stop scan in middle of set -- TEST 3: btree cursor scan, group fetch = 4 stop scan in middle of set -- TEST 4: btree cursor scan, group fetch = 1 (scan with some deleted rows) -- TEST 5: btree cursor scan, group fetch = 2(scan with committed deleted rows) -- TEST 6: btree cursor scan, group fetch = 1 (scan with "<" qualifier) -- TEST 7: btree cursor scan, group fetch = 2 (scan with "<" qualifier) -- TEST 8: btree cursor scan, group fetch = 1 (scan with equals qualifier) -- TEST 9: btree cursor scan, group fetch = 2 (scan with equals qualifier) -- TEST 10: btree cursor scan, group fetch = 1 ("=" qualifier, no rows return) autocommit off; ij> -------------------------------------------------------------------------------- -- Assumes that calling routine has set up the following simple dataset, -- a heap, and index with following initial values: -- create table a (a int, b int, c somesortofchar, [index_pad]); -- create index a_idx on a (a) or a_idx on a (a, index_pad); -- -- 1, 10, 'one' -- 2, 20, 'two' -- 3, 30, 'three' -- 4, 40, 'four' -- 5, 50, 'five' -- 6, 60, 'six' -- 7, 70, 'seven' -------------------------------------------------------------------------------- select * from a; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 1 |10 |one 2 |20 |two 3 |30 |three 4 |40 |four 5 |50 |five 6 |60 |six 7 |70 |seven ij> commit; ij> -------------------------------------------------------------------------------- -- TEST 0: btree cursor scan, group fetch = 1 -- Test full cursor scan which does no updates. -- ALL MODES - TABLE IS, "scan page lockname of form (pageno, 1) -- SERIALIZABLE - row S locks as it visits each row, held until end xact -- REPEATABLE READ - row S locks as it visits each row, held until end xact -- READ COMMITTED - row S lock on current row, released on move to next row -- READ UNCOMMITTED - no row locks. ------------------------------------------------------------------------------- CALL SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.language.bulkFetchDefault','1'); 0 rows inserted/updated/deleted ij> -- RESOLVE: missing row locks -- WORKAROUND: creating an index and dropping it -- to force the statement to be recompiled create index ix1 on a(a); 0 rows inserted/updated/deleted WARNING 01504: The new index is a duplicate of an existing index: A_IDX. ij> drop index ix1; ERROR 42X65: Index 'IX1' does not exist. ij> commit; ij> get cursor scan_cursor as 'select a from a'; ij> call SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.language.bulkFetchDefault', '16'); 0 rows inserted/updated/deleted ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A ----------- 1 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,1) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,7) |GRANT|ACTIVE ij> next scan_cursor; A ----------- 2 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,1) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,8) |GRANT|ACTIVE ij> next scan_cursor; A ----------- 3 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,1) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,9) |GRANT|ACTIVE ij> next scan_cursor; A ----------- 4 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,1) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,10) |GRANT|ACTIVE ij> next scan_cursor; A ----------- 5 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,1) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,11) |GRANT|ACTIVE ij> next scan_cursor; A ----------- 6 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,1) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,12) |GRANT|ACTIVE ij> next scan_cursor; A ----------- 7 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,1) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,13) |GRANT|ACTIVE ij> next scan_cursor; No current row ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE ij> close scan_cursor; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> -------------------------------------------------------------------------------- -- TEST 1: btree cursor scan, group fetch = 2 -- Test full cursor scan which does no updates. -- ALL MODES - TABLE IS, "scan page lockname of form (pageno, 1) -- SERIALIZABLE - row S locks as it visits each row, held until end xact -- REPEATABLE READ - row S locks as it visits each row, held until end xact -- READ COMMITTED - row S lock on current row, released on move to next row -- READ UNCOMMITTED - no row locks. -------------------------------------------------------------------------------- CALL SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.language.bulkFetchDefault','2'); 0 rows inserted/updated/deleted ij> -- RESOLVE: missing row locks -- WORKAROUND: creating an index and dropping it -- to force the statement to be recompiled create index ix1 on a(a); 0 rows inserted/updated/deleted WARNING 01504: The new index is a duplicate of an existing index: A_IDX. ij> drop index ix1; ERROR 42X65: Index 'IX1' does not exist. ij> commit; ij> get cursor scan_cursor as 'select a from a'; ij> call SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.language.bulkFetchDefault', '16'); 0 rows inserted/updated/deleted ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A ----------- 1 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,1) |GRANT|ACTIVE ij> next scan_cursor; A ----------- 2 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,1) |GRANT|ACTIVE ij> next scan_cursor; A ----------- 3 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,1) |GRANT|ACTIVE ij> next scan_cursor; A ----------- 4 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,1) |GRANT|ACTIVE ij> next scan_cursor; A ----------- 5 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,1) |GRANT|ACTIVE ij> next scan_cursor; A ----------- 6 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,1) |GRANT|ACTIVE ij> next scan_cursor; A ----------- 7 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; No current row ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE ij> close scan_cursor; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> -------------------------------------------------------------------------------- -- TEST 2: btree cursor scan, group fetch = 1, stop scan in middle of set -- Test full cursor scan which does no updates. -- ALL MODES - TABLE IS, "scan page lockname of form (pageno, 1) -- SERIALIZABLE - row S locks as it visits each row, held until end xact -- REPEATABLE READ - row S locks as it visits each row, held until end xact -- READ COMMITTED - row S lock on current row, released on move to next row -- READ UNCOMMITTED - no row locks. -------------------------------------------------------------------------------- CALL SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.language.bulkFetchDefault','1'); 0 rows inserted/updated/deleted ij> -- RESOLVE: missing row locks -- WORKAROUND: creating an index and dropping it -- to force the statement to be recompiled create index ix1 on a(a); 0 rows inserted/updated/deleted WARNING 01504: The new index is a duplicate of an existing index: A_IDX. ij> drop index ix1; ERROR 42X65: Index 'IX1' does not exist. ij> commit; ij> get cursor scan_cursor as 'select a from a'; ij> call SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.language.bulkFetchDefault', '16'); 0 rows inserted/updated/deleted ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A ----------- 1 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,1) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,7) |GRANT|ACTIVE ij> next scan_cursor; A ----------- 2 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,1) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,8) |GRANT|ACTIVE ij> close scan_cursor; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> -------------------------------------------------------------------------------- -- TEST 3: btree cursor scan, group fetch = 4, stop scan in middle of set -- Test full cursor scan which does no updates. -- ALL MODES - TABLE IS, "scan page lockname of form (pageno, 1) -- SERIALIZABLE - row S locks as it visits each row, held until end xact -- REPEATABLE READ - row S locks as it visits each row, held until end xact -- READ COMMITTED - row S lock on current row, released on move to next row -- READ UNCOMMITTED - no row locks. -------------------------------------------------------------------------------- CALL SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.language.bulkFetchDefault','4'); 0 rows inserted/updated/deleted ij> -- RESOLVE: missing row locks -- WORKAROUND: creating an index and dropping it -- to force the statement to be recompiled create index ix1 on a(a); 0 rows inserted/updated/deleted WARNING 01504: The new index is a duplicate of an existing index: A_IDX. ij> drop index ix1; ERROR 42X65: Index 'IX1' does not exist. ij> commit; ij> get cursor scan_cursor as 'select a from a'; ij> call SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.language.bulkFetchDefault', '16'); 0 rows inserted/updated/deleted ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A ----------- 1 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,1) |GRANT|ACTIVE ij> next scan_cursor; A ----------- 2 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,1) |GRANT|ACTIVE ij> close scan_cursor; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> -------------------------------------------------------------------------------- -- TEST 4: btree cursor scan, group fetch = 1 (scan table with some deleted rows) -- Test full cursor scan on a data set with some deleted rows (the "even" ones). -- ALL MODES - TABLE IS, "scan page lockname of form (pageno, 1) -- SERIALIZABLE - row S locks as it visits each row, held until end xact -- REPEATABLE READ - row S locks as it visits each row, held until end xact -- READ COMMITTED - row S lock on current row, released on move to next row -- READ UNCOMMITTED - no row locks. -- -- After the delete the base table should look like: -- 1, 10, 'one' -- 3, 30, 'three' -- 5, 50, 'five' -- 7, 70, 'seven' -------------------------------------------------------------------------------- delete from a where a = 2 or a = 4 or a = 6; 3 rows inserted/updated/deleted ij> commit; ij> CALL SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.language.bulkFetchDefault','1'); 0 rows inserted/updated/deleted ij> -- RESOLVE: missing row locks -- WORKAROUND: creating an index and dropping it -- to force the statement to be recompiled create index ix1 on a(a); 0 rows inserted/updated/deleted WARNING 01504: The new index is a duplicate of an existing index: A_IDX. ij> drop index ix1; ERROR 42X65: Index 'IX1' does not exist. ij> commit; ij> get cursor scan_cursor as 'select a from a'; ij> call SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.language.bulkFetchDefault', '16'); 0 rows inserted/updated/deleted ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A ----------- 1 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,1) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,7) |GRANT|ACTIVE ij> next scan_cursor; A ----------- 3 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,1) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,9) |GRANT|ACTIVE ij> next scan_cursor; A ----------- 5 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,1) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,11) |GRANT|ACTIVE ij> next scan_cursor; A ----------- 7 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,1) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,13) |GRANT|ACTIVE ij> next scan_cursor; No current row ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE ij> close scan_cursor; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> -------------------------------------------------------------------------------- -- TEST 5: btree cursor scan, group fetch = 2 (scan with committed deleted rows) -- Test full cursor scan on a data set with some deleted rows (the "even" ones). -- ALL MODES - TABLE IS, "scan page lockname of form (pageno, 1) -- SERIALIZABLE - row S locks as it visits each row, held until end xact -- REPEATABLE READ - row S locks as it visits each row, held until end xact -- READ COMMITTED - row S lock on current row, released on move to next row -- READ UNCOMMITTED - no row locks. -- -- At this point the base table should look like: -- 1, 10, 'one' -- 3, 30, 'three' -- 5, 50, 'five' -- 7, 70, 'seven' -------------------------------------------------------------------------------- CALL SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.language.bulkFetchDefault','2'); 0 rows inserted/updated/deleted ij> -- RESOLVE: missing row locks -- WORKAROUND: creating an index and dropping it -- to force the statement to be recompiled create index ix1 on a(a); 0 rows inserted/updated/deleted WARNING 01504: The new index is a duplicate of an existing index: A_IDX. ij> drop index ix1; ERROR 42X65: Index 'IX1' does not exist. ij> commit; ij> get cursor scan_cursor as 'select a from a'; ij> call SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.language.bulkFetchDefault', '16'); 0 rows inserted/updated/deleted ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A ----------- 1 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,1) |GRANT|ACTIVE ij> next scan_cursor; A ----------- 3 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,1) |GRANT|ACTIVE ij> next scan_cursor; A ----------- 5 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,1) |GRANT|ACTIVE ij> next scan_cursor; A ----------- 7 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,1) |GRANT|ACTIVE ij> next scan_cursor; No current row ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE ij> close scan_cursor; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> -------------------------------------------------------------------------------- -- TEST 6: btree cursor scan, group fetch = 1 (scan with "<" qualifier) -- Test "less than" qualified cursor scan on a data set. -- ALL MODES - TABLE IS, "scan page lockname of form (pageno, 1) -- SERIALIZABLE - row S locks as it visits each row, held until end xact -- REPEATABLE READ - row S locks as it visits each row, held until end xact -- READ COMMITTED - row S lock on current row, released on move to next row -- READ UNCOMMITTED - no row locks. -- -- At this point the base table should look like: -- 1, 10, 'one' -- 3, 30, 'three' -- 5, 50, 'five' -- 7, 70, 'seven' -------------------------------------------------------------------------------- CALL SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.language.bulkFetchDefault','1'); 0 rows inserted/updated/deleted ij> -- RESOLVE: missing row locks -- WORKAROUND: creating an index and dropping it -- to force the statement to be recompiled create index ix1 on a(a); 0 rows inserted/updated/deleted WARNING 01504: The new index is a duplicate of an existing index: A_IDX. ij> drop index ix1; ERROR 42X65: Index 'IX1' does not exist. ij> commit; ij> get cursor scan_cursor as 'select a from a where a < 3'; ij> call SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.language.bulkFetchDefault', '16'); 0 rows inserted/updated/deleted ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A ----------- 1 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,1) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,7) |GRANT|ACTIVE ij> next scan_cursor; No current row ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE ij> close scan_cursor; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> -------------------------------------------------------------------------------- -- TEST 7: btree cursor scan, group fetch = 2 (scan with "<" qualifier) -- Test "less than" qualified cursor scan on a data set. -- ALL MODES - TABLE IS, "scan page lockname of form (pageno, 1) -- SERIALIZABLE - row S locks as it visits each row, held until end xact -- REPEATABLE READ - row S locks as it visits each row, held until end xact -- READ COMMITTED - row S lock on current row, released on move to next row -- READ UNCOMMITTED - no row locks. -- -- At this point the base table should look like: -- 1, 10, 'one' -- 3, 30, 'three' -- 5, 50, 'five' -- 7, 70, 'seven' -------------------------------------------------------------------------------- CALL SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.language.bulkFetchDefault','2'); 0 rows inserted/updated/deleted ij> -- RESOLVE: missing row locks -- WORKAROUND: creating an index and dropping it -- to force the statement to be recompiled create index ix1 on a(a); 0 rows inserted/updated/deleted WARNING 01504: The new index is a duplicate of an existing index: A_IDX. ij> drop index ix1; ERROR 42X65: Index 'IX1' does not exist. ij> commit; ij> get cursor scan_cursor as 'select a from a where a < 3'; ij> call SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.language.bulkFetchDefault', '16'); 0 rows inserted/updated/deleted ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A ----------- 1 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; No current row ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE ij> close scan_cursor; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> -------------------------------------------------------------------------------- -- TEST 8: btree cursor scan, group fetch = 1 (scan with equals qualifier) -- Test "equals" qualified cursor scan on a data set. -- ALL MODES - TABLE IS, "scan page lockname of form (pageno, 1) -- SERIALIZABLE - row S locks as it visits each row, held until end xact -- REPEATABLE READ - row S locks as it visits each row, held until end xact -- READ COMMITTED - row S lock on current row, released on move to next row -- READ UNCOMMITTED - no row locks. -- -- At this point the base table should look like: -- 1, 10, 'one' -- 3, 30, 'three' -- 5, 50, 'five' -- 7, 70, 'seven' -------------------------------------------------------------------------------- CALL SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.language.bulkFetchDefault','1'); 0 rows inserted/updated/deleted ij> -- RESOLVE: missing row locks -- WORKAROUND: creating an index and dropping it -- to force the statement to be recompiled create index ix1 on a(a); 0 rows inserted/updated/deleted WARNING 01504: The new index is a duplicate of an existing index: A_IDX. ij> drop index ix1; ERROR 42X65: Index 'IX1' does not exist. ij> commit; ij> get cursor scan_cursor as 'select a from a where a = 5'; ij> call SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.language.bulkFetchDefault', '16'); 0 rows inserted/updated/deleted ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A ----------- 5 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,1) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,11) |GRANT|ACTIVE ij> next scan_cursor; No current row ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE ij> close scan_cursor; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> -------------------------------------------------------------------------------- -- TEST 9: btree cursor scan, group fetch = 2 (scan with equals qualifier) -- Test "equals" qualified cursor scan on a data set. -- ALL MODES - TABLE IS, "scan page lockname of form (pageno, 1) -- SERIALIZABLE - row S locks as it visits each row, held until end xact -- REPEATABLE READ - row S locks as it visits each row, held until end xact -- READ COMMITTED - row S lock on current row, released on move to next row -- READ UNCOMMITTED - no row locks. -- -- At this point the base table should look like: -- 1, 10, 'one' -- 3, 30, 'three' -- 5, 50, 'five' -- 7, 70, 'seven' -------------------------------------------------------------------------------- CALL SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.language.bulkFetchDefault','2'); 0 rows inserted/updated/deleted ij> -- RESOLVE: missing row locks -- WORKAROUND: creating an index and dropping it -- to force the statement to be recompiled create index ix1 on a(a); 0 rows inserted/updated/deleted WARNING 01504: The new index is a duplicate of an existing index: A_IDX. ij> drop index ix1; ERROR 42X65: Index 'IX1' does not exist. ij> commit; ij> get cursor scan_cursor as 'select a from a where a = 5 or a = 7'; ij> call SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.language.bulkFetchDefault', '16'); 0 rows inserted/updated/deleted ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A ----------- 5 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,1) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,11) |GRANT|ACTIVE ij> next scan_cursor; A ----------- 7 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,1) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,13) |GRANT|ACTIVE ij> close scan_cursor; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> -------------------------------------------------------------------------------- -- TEST 10: btree cursor scan, group fetch = 1 (equals qualifier, no rows return) -- Test "equals" qualified cursor scan on a data set, no rows returned. -- ALL MODES - TABLE IS, "scan page lockname of form (pageno, 1) -- SERIALIZABLE - row S locks as it visits each row, held until end xact -- REPEATABLE READ - row S locks as it visits each row, held until end xact -- READ COMMITTED - row S lock on current row, released on move to next row -- READ UNCOMMITTED - no row locks. -- -- At this point the base table should look like: -- 1, 10, 'one' -- 3, 30, 'three' -- 5, 50, 'five' -- 7, 70, 'seven' -------------------------------------------------------------------------------- -- no rows expected to qualify CALL SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.language.bulkFetchDefault','1'); 0 rows inserted/updated/deleted ij> -- RESOLVE: missing row locks -- WORKAROUND: creating an index and dropping it -- to force the statement to be recompiled create index ix1 on a(a); 0 rows inserted/updated/deleted WARNING 01504: The new index is a duplicate of an existing index: A_IDX. ij> drop index ix1; ERROR 42X65: Index 'IX1' does not exist. ij> commit; ij> get cursor scan_cursor as 'select a from a where a = 42'; ij> call SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.language.bulkFetchDefault', '16'); 0 rows inserted/updated/deleted ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; No current row ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; No current row ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE ij> close scan_cursor; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> drop table a; 0 rows inserted/updated/deleted ij> -- non cursor, unique index run drop table a; ERROR 42Y55: 'DROP TABLE' cannot be performed on 'A' because it does not exist. ij> -- to create tables of page size 4k and still keep the following tbl -- create table a (a int, b int, c varchar(1900)); create table a(a int, b int); 0 rows inserted/updated/deleted ij> alter table a add column c varchar(1900); 0 rows inserted/updated/deleted ij> insert into a values (1, 10, 'one'); 1 row inserted/updated/deleted ij> insert into a values (2, 20, 'two'); 1 row inserted/updated/deleted ij> insert into a values (3, 30, 'three'); 1 row inserted/updated/deleted ij> insert into a values (4, 40, 'four'); 1 row inserted/updated/deleted ij> insert into a values (5, 50, 'five'); 1 row inserted/updated/deleted ij> insert into a values (6, 60, 'six'); 1 row inserted/updated/deleted ij> insert into a values (7, 70, 'seven'); 1 row inserted/updated/deleted ij> create unique index a_idx on a (a); 0 rows inserted/updated/deleted ij> commit; ij> run resource 'readBtreeSetLocks.subsql'; 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. -- -- Basic single user testing of read locks on select "set" queries on indexes. -- -- This ".subsql" test is -- meant to be run from another test such that it gets run under multiple -- isolation levels. This is important as they behave -- differently, depending on isolation levels. -- -- assume's caller has already done: run 'LockTableQuery.subsql'; to get -- easy access to the lock VTI. -- TEST 0: btree scan -- TEST 1: btree scan, (scan table with some deleted rows) -- TEST 2: btree scan, (scan with "<" qualifier) -- TEST 3: btree scan, (scan with equals qualifier) -- TEST 4: btree scan, (equals qualifier, no rows return) autocommit off; ij> -------------------------------------------------------------------------------- -- Assumes that calling routine has set up the following simple dataset, -- a heap, and index with following initial values: -- create table a (a int, b int, c somesortofchar, [index_pad]); -- create index a_idx on a (a) or a_idx on a (a, index_pad); -- -- 1, 10, 'one' -- 2, 20, 'two' -- 3, 30, 'three' -- 4, 40, 'four' -- 5, 50, 'five' -- 6, 60, 'six' -- 7, 70, 'seven' -------------------------------------------------------------------------------- select * from a; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 1 |10 |one 2 |20 |two 3 |30 |three 4 |40 |four 5 |50 |five 6 |60 |six 7 |70 |seven ij> commit; ij> -------------------------------------------------------------------------------- -- TEST 0: btree scan -- Test full scan. -- ALL MODES - TABLE IS, "scan page lockname of form (pageno, 1) -- SERIALIZABLE - row S locks as it visits each row, row/table lock -- held until end xact. Also holds one previous key lock. -- REPEATABLE READ - row S locks as it visits each row, row/table locks held -- until end of transaction. -- READ COMMITTED - instantaneous S locks requested on each row. No locks -- held after query finishes. -- READ UNCOMMITTED - no row locks. No locks held after query finishes. -------------------------------------------------------------------------------- select a from a; A ----------- 1 2 3 4 5 6 7 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> -------------------------------------------------------------------------------- -- TEST 1: btree scan, (scan table with some deleted rows) -- Test full scan on a data set with some deleted rows (the "even" ones). -- ALL MODES - TABLE IS, "scan page lockname of form (pageno, 1) -- SERIALIZABLE - row S locks as it visits each row, row/table lock -- held until end xact. Also holds one previous key lock. -- REPEATABLE READ - row S locks as it visits each row, row/table locks held -- until end of transaction. -- READ COMMITTED - instantaneous S locks requested on each row. No locks -- held after query finishes. -- READ UNCOMMITTED - no row locks. No locks held after query finishes. -- -- After the delete the base table should look like: -- 1, 10, 'one' -- 3, 30, 'three' -- 5, 50, 'five' -- 7, 70, 'seven' -------------------------------------------------------------------------------- delete from a where a = 2 or a = 4 or a = 6; 3 rows inserted/updated/deleted ij> commit; ij> -- The above delete and commit can allow post commit processing to run before -- the subsequent select is run, most likely if this run is on a table where -- there is one row per page. To get reproducible results from the subsequent -- lock calls, wait for post commit to finish before running the select. -- Without this wait "extra" locks sometimes might show up - these are locks -- on the committed deleted rows which have not been cleaned yet depending -- on timing. CALL WAIT_FOR_POST_COMMIT(); 0 rows inserted/updated/deleted ij> select a from a; A ----------- 1 3 5 7 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> -------------------------------------------------------------------------------- -- TEST 2: btree scan, (scan with "<" qualifier) -- Test "less than" qualified scan on a data set. -- ALL MODES - TABLE IS, "scan page lockname of form (pageno, 1) -- SERIALIZABLE - row S locks as it visits each row, row/table lock -- held until end xact. Also holds one previous key lock. -- REPEATABLE READ - row S locks as it visits each row, row/table locks held -- until end of transaction. -- READ COMMITTED - instantaneous S locks requested on each row. No locks -- held after query finishes. -- READ UNCOMMITTED - no row locks. No locks held after query finishes. -- -- At this point the base table should look like: -- 1, 10, 'one' -- 3, 30, 'three' -- 5, 50, 'five' -- 7, 70, 'seven' -------------------------------------------------------------------------------- select a from a where a < 3; A ----------- 1 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> -------------------------------------------------------------------------------- -- TEST 3: btree scan, (scan with equals qualifier) -- Test "equals" qualified cursor scan on a data set. -- ALL MODES - TABLE IS, "scan page lockname of form (pageno, 1) -- SERIALIZABLE - row S locks as it visits each row, row/table lock -- held until end xact. Also holds one previous key lock. -- REPEATABLE READ - row S locks as it visits each row, row/table locks held -- until end of transaction. -- READ COMMITTED - instantaneous S locks requested on each row. No locks -- held after query finishes. -- READ UNCOMMITTED - no row locks. No locks held after query finishes. -- -- At this point the base table should look like: -- 1, 10, 'one' -- 3, 30, 'three' -- 5, 50, 'five' -- 7, 70, 'seven' -------------------------------------------------------------------------------- select a from a where a = 5; A ----------- 5 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> -------------------------------------------------------------------------------- -- TEST 4: btree scan, (equals qualifier, no rows return) -- Test "equals" qualified scan on a data set, no rows returned. -- ALL MODES - TABLE IS, "scan page lockname of form (pageno, 1) -- SERIALIZABLE - row S locks as it visits each row, row/table lock -- held until end xact. Also holds one previous key lock. -- REPEATABLE READ - row S locks as it visits each row, row/table locks held -- until end of transaction. -- READ COMMITTED - instantaneous S locks requested on each row. No locks -- held after query finishes. -- READ UNCOMMITTED - no row locks. No locks held after query finishes. -- -- At this point the base table should look like: -- 1, 10, 'one' -- 3, 30, 'three' -- 5, 50, 'five' -- 7, 70, 'seven' -------------------------------------------------------------------------------- -- no rows expected to qualify select a from a where a = 42; A ----------- ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> drop table a; 0 rows inserted/updated/deleted ij> -- non cursor, non-unique index run drop table a; ERROR 42Y55: 'DROP TABLE' cannot be performed on 'A' because it does not exist. ij> -- to create tables of page size 4k and still keep the following tbl -- create table a (a int, b int, c varchar(1900)); create table a(a int, b int); 0 rows inserted/updated/deleted ij> alter table a add column c varchar(1900); 0 rows inserted/updated/deleted ij> insert into a values (1, 10, 'one'); 1 row inserted/updated/deleted ij> insert into a values (2, 20, 'two'); 1 row inserted/updated/deleted ij> insert into a values (3, 30, 'three'); 1 row inserted/updated/deleted ij> insert into a values (4, 40, 'four'); 1 row inserted/updated/deleted ij> insert into a values (5, 50, 'five'); 1 row inserted/updated/deleted ij> insert into a values (6, 60, 'six'); 1 row inserted/updated/deleted ij> insert into a values (7, 70, 'seven'); 1 row inserted/updated/deleted ij> create index a_idx on a (a); 0 rows inserted/updated/deleted ij> commit; ij> run resource 'readBtreeSetLocks.subsql'; 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. -- -- Basic single user testing of read locks on select "set" queries on indexes. -- -- This ".subsql" test is -- meant to be run from another test such that it gets run under multiple -- isolation levels. This is important as they behave -- differently, depending on isolation levels. -- -- assume's caller has already done: run 'LockTableQuery.subsql'; to get -- easy access to the lock VTI. -- TEST 0: btree scan -- TEST 1: btree scan, (scan table with some deleted rows) -- TEST 2: btree scan, (scan with "<" qualifier) -- TEST 3: btree scan, (scan with equals qualifier) -- TEST 4: btree scan, (equals qualifier, no rows return) autocommit off; ij> -------------------------------------------------------------------------------- -- Assumes that calling routine has set up the following simple dataset, -- a heap, and index with following initial values: -- create table a (a int, b int, c somesortofchar, [index_pad]); -- create index a_idx on a (a) or a_idx on a (a, index_pad); -- -- 1, 10, 'one' -- 2, 20, 'two' -- 3, 30, 'three' -- 4, 40, 'four' -- 5, 50, 'five' -- 6, 60, 'six' -- 7, 70, 'seven' -------------------------------------------------------------------------------- select * from a; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 1 |10 |one 2 |20 |two 3 |30 |three 4 |40 |four 5 |50 |five 6 |60 |six 7 |70 |seven ij> commit; ij> -------------------------------------------------------------------------------- -- TEST 0: btree scan -- Test full scan. -- ALL MODES - TABLE IS, "scan page lockname of form (pageno, 1) -- SERIALIZABLE - row S locks as it visits each row, row/table lock -- held until end xact. Also holds one previous key lock. -- REPEATABLE READ - row S locks as it visits each row, row/table locks held -- until end of transaction. -- READ COMMITTED - instantaneous S locks requested on each row. No locks -- held after query finishes. -- READ UNCOMMITTED - no row locks. No locks held after query finishes. -------------------------------------------------------------------------------- select a from a; A ----------- 1 2 3 4 5 6 7 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> -------------------------------------------------------------------------------- -- TEST 1: btree scan, (scan table with some deleted rows) -- Test full scan on a data set with some deleted rows (the "even" ones). -- ALL MODES - TABLE IS, "scan page lockname of form (pageno, 1) -- SERIALIZABLE - row S locks as it visits each row, row/table lock -- held until end xact. Also holds one previous key lock. -- REPEATABLE READ - row S locks as it visits each row, row/table locks held -- until end of transaction. -- READ COMMITTED - instantaneous S locks requested on each row. No locks -- held after query finishes. -- READ UNCOMMITTED - no row locks. No locks held after query finishes. -- -- After the delete the base table should look like: -- 1, 10, 'one' -- 3, 30, 'three' -- 5, 50, 'five' -- 7, 70, 'seven' -------------------------------------------------------------------------------- delete from a where a = 2 or a = 4 or a = 6; 3 rows inserted/updated/deleted ij> commit; ij> -- The above delete and commit can allow post commit processing to run before -- the subsequent select is run, most likely if this run is on a table where -- there is one row per page. To get reproducible results from the subsequent -- lock calls, wait for post commit to finish before running the select. -- Without this wait "extra" locks sometimes might show up - these are locks -- on the committed deleted rows which have not been cleaned yet depending -- on timing. CALL WAIT_FOR_POST_COMMIT(); 0 rows inserted/updated/deleted ij> select a from a; A ----------- 1 3 5 7 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> -------------------------------------------------------------------------------- -- TEST 2: btree scan, (scan with "<" qualifier) -- Test "less than" qualified scan on a data set. -- ALL MODES - TABLE IS, "scan page lockname of form (pageno, 1) -- SERIALIZABLE - row S locks as it visits each row, row/table lock -- held until end xact. Also holds one previous key lock. -- REPEATABLE READ - row S locks as it visits each row, row/table locks held -- until end of transaction. -- READ COMMITTED - instantaneous S locks requested on each row. No locks -- held after query finishes. -- READ UNCOMMITTED - no row locks. No locks held after query finishes. -- -- At this point the base table should look like: -- 1, 10, 'one' -- 3, 30, 'three' -- 5, 50, 'five' -- 7, 70, 'seven' -------------------------------------------------------------------------------- select a from a where a < 3; A ----------- 1 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> -------------------------------------------------------------------------------- -- TEST 3: btree scan, (scan with equals qualifier) -- Test "equals" qualified cursor scan on a data set. -- ALL MODES - TABLE IS, "scan page lockname of form (pageno, 1) -- SERIALIZABLE - row S locks as it visits each row, row/table lock -- held until end xact. Also holds one previous key lock. -- REPEATABLE READ - row S locks as it visits each row, row/table locks held -- until end of transaction. -- READ COMMITTED - instantaneous S locks requested on each row. No locks -- held after query finishes. -- READ UNCOMMITTED - no row locks. No locks held after query finishes. -- -- At this point the base table should look like: -- 1, 10, 'one' -- 3, 30, 'three' -- 5, 50, 'five' -- 7, 70, 'seven' -------------------------------------------------------------------------------- select a from a where a = 5; A ----------- 5 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> -------------------------------------------------------------------------------- -- TEST 4: btree scan, (equals qualifier, no rows return) -- Test "equals" qualified scan on a data set, no rows returned. -- ALL MODES - TABLE IS, "scan page lockname of form (pageno, 1) -- SERIALIZABLE - row S locks as it visits each row, row/table lock -- held until end xact. Also holds one previous key lock. -- REPEATABLE READ - row S locks as it visits each row, row/table locks held -- until end of transaction. -- READ COMMITTED - instantaneous S locks requested on each row. No locks -- held after query finishes. -- READ UNCOMMITTED - no row locks. No locks held after query finishes. -- -- At this point the base table should look like: -- 1, 10, 'one' -- 3, 30, 'three' -- 5, 50, 'five' -- 7, 70, 'seven' -------------------------------------------------------------------------------- -- no rows expected to qualify select a from a where a = 42; A ----------- ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> drop table a; 0 rows inserted/updated/deleted ij> -- run each test with rows across multiple pages in the interesting -- conglomerate (heap in the non-index tests, and in the index in the index -- based tests). -- cursor, no index run drop table a; ERROR 42Y55: 'DROP TABLE' cannot be performed on 'A' because it does not exist. ij> create table a (a int, b int, c varchar(1900)) ; 0 rows inserted/updated/deleted ij> insert into a values (1, 10, PADSTRING('one',1900)); 1 row inserted/updated/deleted ij> insert into a values (2, 20, PADSTRING('two',1900)); 1 row inserted/updated/deleted ij> insert into a values (3, 30, PADSTRING('three',1900)); 1 row inserted/updated/deleted ij> insert into a values (4, 40, PADSTRING('four',1900)); 1 row inserted/updated/deleted ij> insert into a values (5, 50, PADSTRING('five',1900)); 1 row inserted/updated/deleted ij> insert into a values (6, 60, PADSTRING('six',1900)); 1 row inserted/updated/deleted ij> insert into a values (7, 70, PADSTRING('seven',1900)); 1 row inserted/updated/deleted ij> commit; ij> run resource 'readCursorLocks.subsql'; 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. -- -- Very basic single user testing of read locks on cursors on heap tables. -- This ".subsql" test is -- meant to be run from another test such that it gets run under multiple -- isolation levels. This is important as they behave -- differently, depending on isolation levels. -- -- assume's caller has already done: run 'LockTableQuery.subsql'; to get -- easy access to the lock VTI. -- TEST 0: heap cursor scan, group fetch = 1 -- TEST 1: heap cursor scan, group fetch = 2 -- TEST 2: heap cursor scan, group fetch = 1, stop scan in middle of set -- TEST 3: heap cursor scan, group fetch = 4, stop scan in middle of set -- TEST 4: heap cursor scan, group fetch = 1 (scan table with some deleted rows) -- TEST 5: heap cursor scan, group fetch = 2 (scan with committed deleted rows) -- TEST 6: heap cursor scan, group fetch = 1 (scan with "<" qualifier) -- TEST 7: heap cursor scan, group fetch = 2 (scan with "<" qualifier) -- TEST 8: heap cursor scan, group fetch = 1 (scan with equals qualifier) -- TEST 9: heap cursor scan, group fetch = 2 (scan with equals qualifier) -- TEST 10: heap cursor scan, group fetch = 1 (equals qualifier, no rows return) autocommit off; ij> -------------------------------------------------------------------------------- -- Assumes that calling routine has set up the following simple dataset, -- a heap, no indexes with following initial values: -- create table (a int, b int, c somesortofchar); -- 1, 10, 'one' -- 2, 20, 'two' -- 3, 30, 'three' -- 4, 40, 'four' -- 5, 50, 'five' -- 6, 60, 'six' -- 7, 70, 'seven' -------------------------------------------------------------------------------- select * from a; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 1 |10 |one & 2 |20 |two & 3 |30 |three & 4 |40 |four & 5 |50 |five & 6 |60 |six & 7 |70 |seven & ij> commit; ij> -------------------------------------------------------------------------------- -- TEST 0: heap cursor scan, group fetch = 1 -- Test full cursor scan which does no updates. -- SERIALIZABLE - will get table level S lock. -- REPEATABLE READ - TABLE IS, will get row S locks as it visits each row. -- READ COMMITTED - TABLE IS, will hold single S lock on current row. -- READ UNCOMMITTED - TABLE IS, no row locks. -------------------------------------------------------------------------------- CALL SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.language.bulkFetchDefault','1'); 0 rows inserted/updated/deleted ij> get cursor scan_cursor as 'select a, b, c from a'; ij> call SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.language.bulkFetchDefault', '16'); 0 rows inserted/updated/deleted ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 1 |10 |one & ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,7) |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 2 |20 |two & ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,8) |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 3 |30 |three & ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(2,6) |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 4 |40 |four & ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(2,7) |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 5 |50 |five & ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(3,6) |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 6 |60 |six & ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(3,7) |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 7 |70 |seven & ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(4,6) |GRANT|ACTIVE ij> next scan_cursor; No current row ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE ij> close scan_cursor; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> -------------------------------------------------------------------------------- -- TEST 1: heap cursor scan, group fetch = 2 -- Test full cursor scan which does no updates. -- SERIALIZABLE - will get table level S lock. -- REPEATABLE READ - TABLE IS, will get row S locks as it visits each row. -- READ COMMITTED - TABLE IS, will get instantaneous locks and release -- READ UNCOMMITTED - TABLE IS, no row locks. -------------------------------------------------------------------------------- CALL SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.language.bulkFetchDefault','2'); 0 rows inserted/updated/deleted ij> -- RESOLVE: missing row locks -- WORKAROUND: creating an index and dropping it -- to force the query 'select a, b, c from a' to be recompiled create index ix1 on a(a); 0 rows inserted/updated/deleted ij> drop index ix1; 0 rows inserted/updated/deleted ij> commit; ij> get cursor scan_cursor as 'select a, b, c from a'; ij> call SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.language.bulkFetchDefault', '16'); 0 rows inserted/updated/deleted ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 1 |10 |one & ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 2 |20 |two & ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 3 |30 |three & ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 4 |40 |four & ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 5 |50 |five & ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 6 |60 |six & ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 7 |70 |seven & ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; No current row ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE ij> close scan_cursor; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> -------------------------------------------------------------------------------- -- TEST 2: heap cursor scan, group fetch = 1, stop scan in middle of set -- Test full cursor scan which does no updates. -- SERIALIZABLE - will get table level S lock. -- REPEATABLE READ - TABLE IS, will get row S locks as it visits each row. -- READ COMMITTED - TABLE IS, will hold single S lock on current row. -- READ UNCOMMITTED - TABLE IS, no row locks. -------------------------------------------------------------------------------- CALL SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.language.bulkFetchDefault','1'); 0 rows inserted/updated/deleted ij> -- RESOLVE: missing row locks -- WORKAROUND: creating an index and dropping it -- to force the query 'select a, b, c from a' to be recompiled create index ix1 on a(a); 0 rows inserted/updated/deleted ij> drop index ix1; 0 rows inserted/updated/deleted ij> commit; ij> get cursor scan_cursor as 'select a, b, c from a'; ij> call SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.language.bulkFetchDefault', '16'); 0 rows inserted/updated/deleted ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 1 |10 |one & ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,7) |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 2 |20 |two & ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,8) |GRANT|ACTIVE ij> close scan_cursor; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> -------------------------------------------------------------------------------- -- TEST 3: heap cursor scan, group fetch = 4, stop scan in middle of set -- Test full cursor scan which does no updates. -- SERIALIZABLE - will get table level S lock. -- REPEATABLE READ - TABLE IS, will get row S locks as it visits each row. -- READ COMMITTED - TABLE IS, will hold single S lock on current row. -- READ UNCOMMITTED - TABLE IS, no row locks. -------------------------------------------------------------------------------- CALL SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.language.bulkFetchDefault','4'); 0 rows inserted/updated/deleted ij> -- RESOLVE: missing row locks -- WORKAROUND: creating an index and dropping it -- to force the query 'select a, b, c from a' to be recompiled create index ix1 on a(a); 0 rows inserted/updated/deleted ij> drop index ix1; 0 rows inserted/updated/deleted ij> commit; ij> get cursor scan_cursor as 'select a, b, c from a'; ij> call SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.language.bulkFetchDefault', '16'); 0 rows inserted/updated/deleted ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 1 |10 |one & ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 2 |20 |two & ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE ij> close scan_cursor; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> -------------------------------------------------------------------------------- -- TEST 4: heap cursor scan, group fetch = 1 (scan table with some deleted rows) -- Test full cursor scan on a data set with some deleted rows (the "even" ones). -- SERIALIZABLE - will get table level S lock. -- REPEATABLE READ - TABLE IS, will get row S locks as it visits each row -- (including deleted ones). -- READ COMMITTED - TABLE IS, will get instantaneous locks and release -- READ UNCOMMITTED - TABLE IS, no row locks. -- -- After the delete the table should look like: -- 1, 10, 'one' -- 3, 30, 'three' -- 5, 50, 'five' -- 7, 70, 'seven' -------------------------------------------------------------------------------- delete from a where a = 2 or a = 4 or a = 6; 3 rows inserted/updated/deleted ij> commit; ij> CALL SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.language.bulkFetchDefault','1'); 0 rows inserted/updated/deleted ij> -- RESOLVE: missing row locks -- WORKAROUND: creating an index and dropping it -- to force the query 'select a, b, c from a' to be recompiled create index ix1 on a(a); 0 rows inserted/updated/deleted ij> drop index ix1; 0 rows inserted/updated/deleted ij> commit; ij> get cursor scan_cursor as 'select a, b, c from a'; ij> call SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.language.bulkFetchDefault', '16'); 0 rows inserted/updated/deleted ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 1 |10 |one & ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,7) |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 3 |30 |three & ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(2,6) |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 5 |50 |five & ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(3,6) |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 7 |70 |seven & ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(4,6) |GRANT|ACTIVE ij> next scan_cursor; No current row ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE ij> close scan_cursor; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> -------------------------------------------------------------------------------- -- TEST 5: heap cursor scan, group fetch = 2 (scan with committed deleted rows) -- Test full cursor scan on a data set with some deleted rows (the "even" ones). -- SERIALIZABLE - will get table level S lock. -- REPEATABLE READ - TABLE IS, will get row S locks as it visits each row -- (including deleted ones). -- READ COMMITTED - TABLE IS, will get instantaneous locks and release -- READ UNCOMMITTED - TABLE IS, no row locks. -- -- At this point the table should look like: -- 1, 10, 'one' -- 3, 30, 'three' -- 5, 50, 'five' -- 7, 70, 'seven' -------------------------------------------------------------------------------- CALL SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.language.bulkFetchDefault','2'); 0 rows inserted/updated/deleted ij> -- RESOLVE: missing row locks -- WORKAROUND: creating an index and dropping it -- to force the query 'select a, b, c from a' to be recompiled create index ix1 on a(a); 0 rows inserted/updated/deleted ij> drop index ix1; 0 rows inserted/updated/deleted ij> commit; ij> get cursor scan_cursor as 'select a, b, c from a'; ij> call SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.language.bulkFetchDefault', '16'); 0 rows inserted/updated/deleted ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 1 |10 |one & ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 3 |30 |three & ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 5 |50 |five & ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 7 |70 |seven & ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; No current row ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE ij> close scan_cursor; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> -------------------------------------------------------------------------------- -- TEST 6: heap cursor scan, group fetch = 1 (scan with "<" qualifier) -- Test "less than" qualified cursor scan on a data set. -- SERIALIZABLE - will get table level S lock. -- REPEATABLE READ - TABLE IS, will get row S locks as it visits each row -- (including deleted ones). -- READ COMMITTED - TABLE IS, will get instantaneous locks and release -- READ UNCOMMITTED - TABLE IS, no row locks. -- -- At this point the table should look like: -- 1, 10, 'one' -- 3, 30, 'three' -- 5, 50, 'five' -- 7, 70, 'seven' -------------------------------------------------------------------------------- CALL SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.language.bulkFetchDefault','1'); 0 rows inserted/updated/deleted ij> get cursor scan_cursor as 'select a, b, c from a where a < 3'; ij> call SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.language.bulkFetchDefault', '16'); 0 rows inserted/updated/deleted ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 1 |10 |one & ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,7) |GRANT|ACTIVE ij> next scan_cursor; No current row ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE ij> close scan_cursor; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> -------------------------------------------------------------------------------- -- TEST 7: heap cursor scan, group fetch = 2 (scan with "<" qualifier) -- Test "less than" qualified cursor scan on a data set. -- SERIALIZABLE - will get table level S lock. -- REPEATABLE READ - TABLE IS, will get row S locks as it visits each row -- (including deleted ones). -- READ COMMITTED - TABLE IS, will get instantaneous locks and release -- READ UNCOMMITTED - TABLE IS, no row locks. -- -- At this point the table should look like: -- 1, 10, 'one' -- 3, 30, 'three' -- 5, 50, 'five' -- 7, 70, 'seven' -------------------------------------------------------------------------------- CALL SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.language.bulkFetchDefault','2'); 0 rows inserted/updated/deleted ij> -- RESOLVE: missing row locks -- WORKAROUND: creating an index and dropping it -- to force the statement to be recompiled create index ix1 on a(a); 0 rows inserted/updated/deleted ij> drop index ix1; 0 rows inserted/updated/deleted ij> commit; ij> get cursor scan_cursor as 'select a, b, c from a where a < 3'; ij> call SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.language.bulkFetchDefault', '16'); 0 rows inserted/updated/deleted ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 1 |10 |one & ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; No current row ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE ij> close scan_cursor; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> -------------------------------------------------------------------------------- -- TEST 8: heap cursor scan, group fetch = 1 (scan with equals qualifier) -- Test "equals" qualified cursor scan on a data set. -- SERIALIZABLE - will get table level S lock. -- REPEATABLE READ - TABLE IS, will get row S locks as it visits each row -- (including deleted ones). -- READ COMMITTED - TABLE IS, will get instantaneous locks and release -- READ UNCOMMITTED - TABLE IS, no row locks. -- -- At this point the table should look like: -- 1, 10, 'one' -- 3, 30, 'three' -- 5, 50, 'five' -- 7, 70, 'seven' -------------------------------------------------------------------------------- CALL SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.language.bulkFetchDefault','1'); 0 rows inserted/updated/deleted ij> get cursor scan_cursor as 'select a, b, c from a where a = 5'; ij> call SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.language.bulkFetchDefault', '16'); 0 rows inserted/updated/deleted ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 5 |50 |five & ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(3,6) |GRANT|ACTIVE ij> next scan_cursor; No current row ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE ij> close scan_cursor; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> -------------------------------------------------------------------------------- -- TEST 9: heap cursor scan, group fetch = 2 (scan with equals qualifier) -- Test "equals" qualified cursor scan on a data set. -- SERIALIZABLE - will get table level S lock. -- REPEATABLE READ - TABLE IS, will get row S locks as it visits each row -- (including deleted ones). -- READ COMMITTED - TABLE IS, will get instantaneous locks and release -- READ UNCOMMITTED - TABLE IS, no row locks. -- -- At this point the table should look like: -- 1, 10, 'one' -- 3, 30, 'three' -- 5, 50, 'five' -- 7, 70, 'seven' -------------------------------------------------------------------------------- CALL SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.language.bulkFetchDefault','2'); 0 rows inserted/updated/deleted ij> get cursor scan_cursor as 'select a, b, c from a where a = 7'; ij> call SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.language.bulkFetchDefault', '16'); 0 rows inserted/updated/deleted ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 7 |70 |seven & ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; No current row ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE ij> close scan_cursor; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> -------------------------------------------------------------------------------- -- TEST 10: heap cursor scan, group fetch = 1 (equals qualifier, no rows return) -- Test "equals" qualified cursor scan on a data set, no rows returned. -- SERIALIZABLE - will get table level S lock. -- REPEATABLE READ - TABLE IS, will get row S locks as it visits each row -- (including deleted ones). -- READ COMMITTED - TABLE IS, will get instantaneous locks and release -- READ UNCOMMITTED - TABLE IS, no row locks. -- -- At this point the table should look like: -- 1, 10, 'one' -- 3, 30, 'three' -- 5, 50, 'five' -- 7, 70, 'seven' -------------------------------------------------------------------------------- CALL SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.language.bulkFetchDefault','1'); 0 rows inserted/updated/deleted ij> -- RESOLVE: missing row locks -- WORKAROUND: creating an index and dropping it -- to force the statement to be recompiled create index ix1 on a(a); 0 rows inserted/updated/deleted ij> drop index ix1; 0 rows inserted/updated/deleted ij> commit; ij> get cursor scan_cursor as 'select a, b, c from a where a = 7'; ij> CALL SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.language.bulkFetchDefault','16'); 0 rows inserted/updated/deleted ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 7 |70 |seven & ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(4,6) |GRANT|ACTIVE ij> next scan_cursor; No current row ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE ij> close scan_cursor; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> drop table a; 0 rows inserted/updated/deleted ij> -- non cursor, no index run drop table a; ERROR 42Y55: 'DROP TABLE' cannot be performed on 'A' because it does not exist. ij> create table a (a int, b int, c varchar(1900)) ; 0 rows inserted/updated/deleted ij> insert into a values (1, 10, PADSTRING('one',1900)); 1 row inserted/updated/deleted ij> insert into a values (2, 20, PADSTRING('two',1900)); 1 row inserted/updated/deleted ij> insert into a values (3, 30, PADSTRING('three',1900)); 1 row inserted/updated/deleted ij> insert into a values (4, 40, PADSTRING('four',1900)); 1 row inserted/updated/deleted ij> insert into a values (5, 50, PADSTRING('five',1900)); 1 row inserted/updated/deleted ij> insert into a values (6, 60, PADSTRING('six',1900)); 1 row inserted/updated/deleted ij> insert into a values (7, 70, PADSTRING('seven',1900)); 1 row inserted/updated/deleted ij> commit; ij> run resource 'readSetLocks.subsql'; 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. -- -- Very basic single user testing of read locks in "set" queries on heap tables. -- This ".subsql" test is -- meant to be run from another test such that it gets run under multiple -- isolation levels. This is important as they behave -- differently, depending on isolation levels. -- -- assume's caller has already done: run 'LockTableQuery.subsql'; to get -- easy access to the lock VTI. -- TEST 0: heap scan. -- TEST 1: heap scan, some rows deleted. -- TEST 2: heap scan, (scan with "<" qualifier) -- TEST 3: heap scan, (scan with equals qualifier) -- TEST 4: heap scan, (equals qualifier, no rows return) autocommit off; ij> -------------------------------------------------------------------------------- -- Assumes that calling routine has set up the following simple dataset, -- a heap, no indexes with following initial values: -- create table (a int, b int, c somesortofchar); -- 1, 10, 'one' -- 2, 20, 'two' -- 3, 30, 'three' -- 4, 40, 'four' -- 5, 50, 'five' -- 6, 60, 'six' -- 7, 70, 'seven' -------------------------------------------------------------------------------- select * from a; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 1 |10 |one & 2 |20 |two & 3 |30 |three & 4 |40 |four & 5 |50 |five & 6 |60 |six & 7 |70 |seven & ij> commit; ij> -------------------------------------------------------------------------------- -- TEST 0: heap scan. -- Test full cursor scan which does no updates. -- SERIALIZABLE - will get table level S lock, held to end of xact. -- REPEATABLE READ - TABLE IS, will get row S locks as it visits each row -- (including deleted ones). held to end of xact. -- READ COMMITTED - TABLE IS, will get instantaneous locks and release. No -- locks held when statement completes. -- READ UNCOMMITTED - TABLE IS, no row locks. No locks after statement ends. -------------------------------------------------------------------------------- select a, b, c from a; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 1 |10 |one & 2 |20 |two & 3 |30 |three & 4 |40 |four & 5 |50 |five & 6 |60 |six & 7 |70 |seven & ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> -------------------------------------------------------------------------------- -- TEST 1: heap scan, some rows deleted. -- Test full cursor scan on a data set with some deleted rows (the "even" ones). -- SERIALIZABLE - will get table level S lock. -- REPEATABLE READ - TABLE IS, will get row S locks as it visits each row -- (including deleted ones). -- READ COMMITTED - TABLE IS, will get instantaneous locks and release -- READ UNCOMMITTED - TABLE IS, no row locks. -- SERIALIZABLE - will get table level S lock, held to end of xact. -- REPEATABLE READ - TABLE IS, will get row S locks as it visits each row -- (including deleted ones). held to end of xact. -- READ COMMITTED - TABLE IS, will get instantaneous locks and release. No -- locks held when statement completes. -- READ UNCOMMITTED - TABLE IS, no row locks. No locks after statement ends. -- -- After the delete the table should look like: -- 1, 10, 'one' -- 3, 30, 'three' -- 5, 50, 'five' -- 7, 70, 'seven' -------------------------------------------------------------------------------- delete from a where a = 2 or a = 4 or a = 6; 3 rows inserted/updated/deleted ij> commit; ij> select a, b, c from a; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 1 |10 |one & 3 |30 |three & 5 |50 |five & 7 |70 |seven & ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> -------------------------------------------------------------------------------- -- TEST 2: heap scan, (scan with "<" qualifier) -- Test "less than" qualified cursor scan on a data set. -- SERIALIZABLE - will get table level S lock, held to end of xact. -- REPEATABLE READ - TABLE IS, will get row S locks as it visits each row -- (including deleted ones). held to end of xact. -- READ COMMITTED - TABLE IS, will get instantaneous locks and release. No -- locks held when statement completes. -- READ UNCOMMITTED - TABLE IS, no row locks. No locks after statement ends. -- -- At this point the table should look like: -- 1, 10, 'one' -- 3, 30, 'three' -- 5, 50, 'five' -- 7, 70, 'seven' -------------------------------------------------------------------------------- select a, b, c from a; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 1 |10 |one & 3 |30 |three & 5 |50 |five & 7 |70 |seven & ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> -------------------------------------------------------------------------------- -- TEST 3: heap scan, (scan with equals qualifier) -- Test "equals" qualified cursor scan on a data set. -- SERIALIZABLE - will get table level S lock, held to end of xact. -- REPEATABLE READ - TABLE IS, will get row S locks as it visits each row -- (including deleted ones). held to end of xact. -- READ COMMITTED - TABLE IS, will get instantaneous locks and release. No -- locks held when statement completes. -- READ UNCOMMITTED - TABLE IS, no row locks. No locks after statement ends. -- -- At this point the table should look like: -- 1, 10, 'one' -- 3, 30, 'three' -- 5, 50, 'five' -- 7, 70, 'seven' -------------------------------------------------------------------------------- select a, b, c from a where a = 5; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 5 |50 |five & ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> -------------------------------------------------------------------------------- -- TEST 4: heap scan, (equals qualifier, no rows return) -- Test "equals" qualified cursor scan on a data set, no rows returned. -- SERIALIZABLE - will get table level S lock, held to end of xact. -- REPEATABLE READ - TABLE IS, will get row S locks as it visits each row -- (including deleted ones). held to end of xact. -- READ COMMITTED - TABLE IS, will get instantaneous locks and release. No -- locks held when statement completes. -- READ UNCOMMITTED - TABLE IS, no row locks. No locks after statement ends. -- -- At this point the table should look like: -- 1, 10, 'one' -- 3, 30, 'three' -- 5, 50, 'five' -- 7, 70, 'seven' -------------------------------------------------------------------------------- select a, b, c from a where a = 7; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 7 |70 |seven & ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> drop table a; 0 rows inserted/updated/deleted ij> -- cursor, unique index run drop table a; ERROR 42Y55: 'DROP TABLE' cannot be performed on 'A' because it does not exist. ij> create table a (a int, b int, c varchar(1900), index_pad varchar(600) ) ; 0 rows inserted/updated/deleted ij> insert into a values (1, 10, PADSTRING('one',1900), PADSTRING('index pad 1',600)); 1 row inserted/updated/deleted ij> insert into a values (2, 20, PADSTRING('two',1900), PADSTRING('index pad 2',600)); 1 row inserted/updated/deleted ij> insert into a values (3, 30, PADSTRING('three',1900), PADSTRING('index pad 3',600)); 1 row inserted/updated/deleted ij> insert into a values (4, 40, PADSTRING('four',1900), PADSTRING('index pad 4',600)); 1 row inserted/updated/deleted ij> insert into a values (5, 50, PADSTRING('five',1900), PADSTRING('index pad 5',600)); 1 row inserted/updated/deleted ij> insert into a values (6, 60, PADSTRING('six',1900), PADSTRING('index pad 6',600)); 1 row inserted/updated/deleted ij> insert into a values (7, 70, PADSTRING('seven',1900), PADSTRING('index pad 7',600)); 1 row inserted/updated/deleted ij> create unique index a_idx on a (a, index_pad) ; 0 rows inserted/updated/deleted ij> commit; ij> run resource 'readBtreeCursorLocks.subsql'; 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. -- -- Very basic single user testing of read locks on cursors on indexes. -- This ".subsql" test is -- meant to be run from another test such that it gets run under multiple -- isolation levels. This is important as they behave -- differently, depending on isolation levels. -- -- assume's caller has already done: run 'LockTableQuery.subsql'; to get -- easy access to the lock VTI. -- TEST 0: btree cursor scan, group fetch = 1 -- TEST 1: btree cursor scan, group fetch = 2 -- TEST 2: btree cursor scan, group fetch = 1 stop scan in middle of set -- TEST 3: btree cursor scan, group fetch = 4 stop scan in middle of set -- TEST 4: btree cursor scan, group fetch = 1 (scan with some deleted rows) -- TEST 5: btree cursor scan, group fetch = 2(scan with committed deleted rows) -- TEST 6: btree cursor scan, group fetch = 1 (scan with "<" qualifier) -- TEST 7: btree cursor scan, group fetch = 2 (scan with "<" qualifier) -- TEST 8: btree cursor scan, group fetch = 1 (scan with equals qualifier) -- TEST 9: btree cursor scan, group fetch = 2 (scan with equals qualifier) -- TEST 10: btree cursor scan, group fetch = 1 ("=" qualifier, no rows return) autocommit off; ij> -------------------------------------------------------------------------------- -- Assumes that calling routine has set up the following simple dataset, -- a heap, and index with following initial values: -- create table a (a int, b int, c somesortofchar, [index_pad]); -- create index a_idx on a (a) or a_idx on a (a, index_pad); -- -- 1, 10, 'one' -- 2, 20, 'two' -- 3, 30, 'three' -- 4, 40, 'four' -- 5, 50, 'five' -- 6, 60, 'six' -- 7, 70, 'seven' -------------------------------------------------------------------------------- select * from a; A |B |C |INDEX_PAD ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- 1 |10 |one &|index pad 1 & 2 |20 |two &|index pad 2 & 3 |30 |three &|index pad 3 & 4 |40 |four &|index pad 4 & 5 |50 |five &|index pad 5 & 6 |60 |six &|index pad 6 & 7 |70 |seven &|index pad 7 & ij> commit; ij> -------------------------------------------------------------------------------- -- TEST 0: btree cursor scan, group fetch = 1 -- Test full cursor scan which does no updates. -- ALL MODES - TABLE IS, "scan page lockname of form (pageno, 1) -- SERIALIZABLE - row S locks as it visits each row, held until end xact -- REPEATABLE READ - row S locks as it visits each row, held until end xact -- READ COMMITTED - row S lock on current row, released on move to next row -- READ UNCOMMITTED - no row locks. ------------------------------------------------------------------------------- CALL SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.language.bulkFetchDefault','1'); 0 rows inserted/updated/deleted ij> -- RESOLVE: missing row locks -- WORKAROUND: creating an index and dropping it -- to force the statement to be recompiled create index ix1 on a(a); 0 rows inserted/updated/deleted ij> drop index ix1; 0 rows inserted/updated/deleted ij> commit; ij> get cursor scan_cursor as 'select a from a'; ij> call SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.language.bulkFetchDefault', '16'); 0 rows inserted/updated/deleted ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A ----------- 1 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(2,1) |GRANT|ACTIVE ij> next scan_cursor; A ----------- 2 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(2,1) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(2,6) |GRANT|ACTIVE ij> next scan_cursor; A ----------- 3 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(2,1) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(3,6) |GRANT|ACTIVE ij> next scan_cursor; A ----------- 4 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(2,1) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(4,6) |GRANT|ACTIVE ij> next scan_cursor; A ----------- 5 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(2,1) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(5,6) |GRANT|ACTIVE ij> next scan_cursor; A ----------- 6 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(3,1) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(6,6) |GRANT|ACTIVE ij> next scan_cursor; A ----------- 7 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(3,1) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(7,6) |GRANT|ACTIVE ij> next scan_cursor; No current row ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE ij> close scan_cursor; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> -------------------------------------------------------------------------------- -- TEST 1: btree cursor scan, group fetch = 2 -- Test full cursor scan which does no updates. -- ALL MODES - TABLE IS, "scan page lockname of form (pageno, 1) -- SERIALIZABLE - row S locks as it visits each row, held until end xact -- REPEATABLE READ - row S locks as it visits each row, held until end xact -- READ COMMITTED - row S lock on current row, released on move to next row -- READ UNCOMMITTED - no row locks. -------------------------------------------------------------------------------- CALL SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.language.bulkFetchDefault','2'); 0 rows inserted/updated/deleted ij> -- RESOLVE: missing row locks -- WORKAROUND: creating an index and dropping it -- to force the statement to be recompiled create index ix1 on a(a); 0 rows inserted/updated/deleted ij> drop index ix1; 0 rows inserted/updated/deleted ij> commit; ij> get cursor scan_cursor as 'select a from a'; ij> call SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.language.bulkFetchDefault', '16'); 0 rows inserted/updated/deleted ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A ----------- 1 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(2,1) |GRANT|ACTIVE ij> next scan_cursor; A ----------- 2 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(2,1) |GRANT|ACTIVE ij> next scan_cursor; A ----------- 3 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(2,1) |GRANT|ACTIVE ij> next scan_cursor; A ----------- 4 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(2,1) |GRANT|ACTIVE ij> next scan_cursor; A ----------- 5 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(3,1) |GRANT|ACTIVE ij> next scan_cursor; A ----------- 6 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(3,1) |GRANT|ACTIVE ij> next scan_cursor; A ----------- 7 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; No current row ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE ij> close scan_cursor; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> -------------------------------------------------------------------------------- -- TEST 2: btree cursor scan, group fetch = 1, stop scan in middle of set -- Test full cursor scan which does no updates. -- ALL MODES - TABLE IS, "scan page lockname of form (pageno, 1) -- SERIALIZABLE - row S locks as it visits each row, held until end xact -- REPEATABLE READ - row S locks as it visits each row, held until end xact -- READ COMMITTED - row S lock on current row, released on move to next row -- READ UNCOMMITTED - no row locks. -------------------------------------------------------------------------------- CALL SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.language.bulkFetchDefault','1'); 0 rows inserted/updated/deleted ij> -- RESOLVE: missing row locks -- WORKAROUND: creating an index and dropping it -- to force the statement to be recompiled create index ix1 on a(a); 0 rows inserted/updated/deleted ij> drop index ix1; 0 rows inserted/updated/deleted ij> commit; ij> get cursor scan_cursor as 'select a from a'; ij> call SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.language.bulkFetchDefault', '16'); 0 rows inserted/updated/deleted ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A ----------- 1 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(2,1) |GRANT|ACTIVE ij> next scan_cursor; A ----------- 2 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(2,1) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(2,6) |GRANT|ACTIVE ij> close scan_cursor; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> -------------------------------------------------------------------------------- -- TEST 3: btree cursor scan, group fetch = 4, stop scan in middle of set -- Test full cursor scan which does no updates. -- ALL MODES - TABLE IS, "scan page lockname of form (pageno, 1) -- SERIALIZABLE - row S locks as it visits each row, held until end xact -- REPEATABLE READ - row S locks as it visits each row, held until end xact -- READ COMMITTED - row S lock on current row, released on move to next row -- READ UNCOMMITTED - no row locks. -------------------------------------------------------------------------------- CALL SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.language.bulkFetchDefault','4'); 0 rows inserted/updated/deleted ij> -- RESOLVE: missing row locks -- WORKAROUND: creating an index and dropping it -- to force the statement to be recompiled create index ix1 on a(a); 0 rows inserted/updated/deleted ij> drop index ix1; 0 rows inserted/updated/deleted ij> commit; ij> get cursor scan_cursor as 'select a from a'; ij> call SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.language.bulkFetchDefault', '16'); 0 rows inserted/updated/deleted ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A ----------- 1 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(2,1) |GRANT|ACTIVE ij> next scan_cursor; A ----------- 2 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(2,1) |GRANT|ACTIVE ij> close scan_cursor; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> -------------------------------------------------------------------------------- -- TEST 4: btree cursor scan, group fetch = 1 (scan table with some deleted rows) -- Test full cursor scan on a data set with some deleted rows (the "even" ones). -- ALL MODES - TABLE IS, "scan page lockname of form (pageno, 1) -- SERIALIZABLE - row S locks as it visits each row, held until end xact -- REPEATABLE READ - row S locks as it visits each row, held until end xact -- READ COMMITTED - row S lock on current row, released on move to next row -- READ UNCOMMITTED - no row locks. -- -- After the delete the base table should look like: -- 1, 10, 'one' -- 3, 30, 'three' -- 5, 50, 'five' -- 7, 70, 'seven' -------------------------------------------------------------------------------- delete from a where a = 2 or a = 4 or a = 6; 3 rows inserted/updated/deleted ij> commit; ij> CALL SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.language.bulkFetchDefault','1'); 0 rows inserted/updated/deleted ij> -- RESOLVE: missing row locks -- WORKAROUND: creating an index and dropping it -- to force the statement to be recompiled create index ix1 on a(a); 0 rows inserted/updated/deleted ij> drop index ix1; 0 rows inserted/updated/deleted ij> commit; ij> get cursor scan_cursor as 'select a from a'; ij> call SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.language.bulkFetchDefault', '16'); 0 rows inserted/updated/deleted ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A ----------- 1 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(2,1) |GRANT|ACTIVE ij> next scan_cursor; A ----------- 3 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(2,1) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(3,6) |GRANT|ACTIVE ij> next scan_cursor; A ----------- 5 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(2,1) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(5,6) |GRANT|ACTIVE ij> next scan_cursor; A ----------- 7 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(3,1) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(7,6) |GRANT|ACTIVE ij> next scan_cursor; No current row ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE ij> close scan_cursor; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> -------------------------------------------------------------------------------- -- TEST 5: btree cursor scan, group fetch = 2 (scan with committed deleted rows) -- Test full cursor scan on a data set with some deleted rows (the "even" ones). -- ALL MODES - TABLE IS, "scan page lockname of form (pageno, 1) -- SERIALIZABLE - row S locks as it visits each row, held until end xact -- REPEATABLE READ - row S locks as it visits each row, held until end xact -- READ COMMITTED - row S lock on current row, released on move to next row -- READ UNCOMMITTED - no row locks. -- -- At this point the base table should look like: -- 1, 10, 'one' -- 3, 30, 'three' -- 5, 50, 'five' -- 7, 70, 'seven' -------------------------------------------------------------------------------- CALL SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.language.bulkFetchDefault','2'); 0 rows inserted/updated/deleted ij> -- RESOLVE: missing row locks -- WORKAROUND: creating an index and dropping it -- to force the statement to be recompiled create index ix1 on a(a); 0 rows inserted/updated/deleted ij> drop index ix1; 0 rows inserted/updated/deleted ij> commit; ij> get cursor scan_cursor as 'select a from a'; ij> call SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.language.bulkFetchDefault', '16'); 0 rows inserted/updated/deleted ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A ----------- 1 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(2,1) |GRANT|ACTIVE ij> next scan_cursor; A ----------- 3 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(2,1) |GRANT|ACTIVE ij> next scan_cursor; A ----------- 5 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(3,1) |GRANT|ACTIVE ij> next scan_cursor; A ----------- 7 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(3,1) |GRANT|ACTIVE ij> next scan_cursor; No current row ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE ij> close scan_cursor; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> -------------------------------------------------------------------------------- -- TEST 6: btree cursor scan, group fetch = 1 (scan with "<" qualifier) -- Test "less than" qualified cursor scan on a data set. -- ALL MODES - TABLE IS, "scan page lockname of form (pageno, 1) -- SERIALIZABLE - row S locks as it visits each row, held until end xact -- REPEATABLE READ - row S locks as it visits each row, held until end xact -- READ COMMITTED - row S lock on current row, released on move to next row -- READ UNCOMMITTED - no row locks. -- -- At this point the base table should look like: -- 1, 10, 'one' -- 3, 30, 'three' -- 5, 50, 'five' -- 7, 70, 'seven' -------------------------------------------------------------------------------- CALL SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.language.bulkFetchDefault','1'); 0 rows inserted/updated/deleted ij> -- RESOLVE: missing row locks -- WORKAROUND: creating an index and dropping it -- to force the statement to be recompiled create index ix1 on a(a); 0 rows inserted/updated/deleted ij> drop index ix1; 0 rows inserted/updated/deleted ij> commit; ij> get cursor scan_cursor as 'select a from a where a < 3'; ij> call SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.language.bulkFetchDefault', '16'); 0 rows inserted/updated/deleted ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A ----------- 1 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(2,1) |GRANT|ACTIVE ij> next scan_cursor; No current row ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE ij> close scan_cursor; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> -------------------------------------------------------------------------------- -- TEST 7: btree cursor scan, group fetch = 2 (scan with "<" qualifier) -- Test "less than" qualified cursor scan on a data set. -- ALL MODES - TABLE IS, "scan page lockname of form (pageno, 1) -- SERIALIZABLE - row S locks as it visits each row, held until end xact -- REPEATABLE READ - row S locks as it visits each row, held until end xact -- READ COMMITTED - row S lock on current row, released on move to next row -- READ UNCOMMITTED - no row locks. -- -- At this point the base table should look like: -- 1, 10, 'one' -- 3, 30, 'three' -- 5, 50, 'five' -- 7, 70, 'seven' -------------------------------------------------------------------------------- CALL SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.language.bulkFetchDefault','2'); 0 rows inserted/updated/deleted ij> -- RESOLVE: missing row locks -- WORKAROUND: creating an index and dropping it -- to force the statement to be recompiled create index ix1 on a(a); 0 rows inserted/updated/deleted ij> drop index ix1; 0 rows inserted/updated/deleted ij> commit; ij> get cursor scan_cursor as 'select a from a where a < 3'; ij> call SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.language.bulkFetchDefault', '16'); 0 rows inserted/updated/deleted ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A ----------- 1 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; No current row ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE ij> close scan_cursor; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> -------------------------------------------------------------------------------- -- TEST 8: btree cursor scan, group fetch = 1 (scan with equals qualifier) -- Test "equals" qualified cursor scan on a data set. -- ALL MODES - TABLE IS, "scan page lockname of form (pageno, 1) -- SERIALIZABLE - row S locks as it visits each row, held until end xact -- REPEATABLE READ - row S locks as it visits each row, held until end xact -- READ COMMITTED - row S lock on current row, released on move to next row -- READ UNCOMMITTED - no row locks. -- -- At this point the base table should look like: -- 1, 10, 'one' -- 3, 30, 'three' -- 5, 50, 'five' -- 7, 70, 'seven' -------------------------------------------------------------------------------- CALL SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.language.bulkFetchDefault','1'); 0 rows inserted/updated/deleted ij> -- RESOLVE: missing row locks -- WORKAROUND: creating an index and dropping it -- to force the statement to be recompiled create index ix1 on a(a); 0 rows inserted/updated/deleted ij> drop index ix1; 0 rows inserted/updated/deleted ij> commit; ij> get cursor scan_cursor as 'select a from a where a = 5'; ij> call SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.language.bulkFetchDefault', '16'); 0 rows inserted/updated/deleted ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A ----------- 5 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(2,1) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(5,6) |GRANT|ACTIVE ij> next scan_cursor; No current row ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE ij> close scan_cursor; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> -------------------------------------------------------------------------------- -- TEST 9: btree cursor scan, group fetch = 2 (scan with equals qualifier) -- Test "equals" qualified cursor scan on a data set. -- ALL MODES - TABLE IS, "scan page lockname of form (pageno, 1) -- SERIALIZABLE - row S locks as it visits each row, held until end xact -- REPEATABLE READ - row S locks as it visits each row, held until end xact -- READ COMMITTED - row S lock on current row, released on move to next row -- READ UNCOMMITTED - no row locks. -- -- At this point the base table should look like: -- 1, 10, 'one' -- 3, 30, 'three' -- 5, 50, 'five' -- 7, 70, 'seven' -------------------------------------------------------------------------------- CALL SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.language.bulkFetchDefault','2'); 0 rows inserted/updated/deleted ij> -- RESOLVE: missing row locks -- WORKAROUND: creating an index and dropping it -- to force the statement to be recompiled create index ix1 on a(a); 0 rows inserted/updated/deleted ij> drop index ix1; 0 rows inserted/updated/deleted ij> commit; ij> get cursor scan_cursor as 'select a from a where a = 5 or a = 7'; ij> call SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.language.bulkFetchDefault', '16'); 0 rows inserted/updated/deleted ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A ----------- 5 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(2,1) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(5,6) |GRANT|ACTIVE ij> next scan_cursor; A ----------- 7 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(3,1) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(7,6) |GRANT|ACTIVE ij> close scan_cursor; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> -------------------------------------------------------------------------------- -- TEST 10: btree cursor scan, group fetch = 1 (equals qualifier, no rows return) -- Test "equals" qualified cursor scan on a data set, no rows returned. -- ALL MODES - TABLE IS, "scan page lockname of form (pageno, 1) -- SERIALIZABLE - row S locks as it visits each row, held until end xact -- REPEATABLE READ - row S locks as it visits each row, held until end xact -- READ COMMITTED - row S lock on current row, released on move to next row -- READ UNCOMMITTED - no row locks. -- -- At this point the base table should look like: -- 1, 10, 'one' -- 3, 30, 'three' -- 5, 50, 'five' -- 7, 70, 'seven' -------------------------------------------------------------------------------- -- no rows expected to qualify CALL SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.language.bulkFetchDefault','1'); 0 rows inserted/updated/deleted ij> -- RESOLVE: missing row locks -- WORKAROUND: creating an index and dropping it -- to force the statement to be recompiled create index ix1 on a(a); 0 rows inserted/updated/deleted ij> drop index ix1; 0 rows inserted/updated/deleted ij> commit; ij> get cursor scan_cursor as 'select a from a where a = 42'; ij> call SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.language.bulkFetchDefault', '16'); 0 rows inserted/updated/deleted ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; No current row ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; No current row ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE ij> close scan_cursor; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> drop table a; 0 rows inserted/updated/deleted ij> -- cursor, non-unique index run drop table a; ERROR 42Y55: 'DROP TABLE' cannot be performed on 'A' because it does not exist. ij> create table a (a int, b int, c varchar(1900), index_pad varchar(700) ) ; 0 rows inserted/updated/deleted ij> insert into a values (1, 10, PADSTRING('one',1900), PADSTRING('index pad 1',700)); 1 row inserted/updated/deleted ij> insert into a values (2, 20, PADSTRING('two',1900), PADSTRING('index pad 2',700)); 1 row inserted/updated/deleted ij> insert into a values (3, 30, PADSTRING('three',1900), PADSTRING('index pad 3',700)); 1 row inserted/updated/deleted ij> insert into a values (4, 40, PADSTRING('four',1900), PADSTRING('index pad 4',700)); 1 row inserted/updated/deleted ij> insert into a values (5, 50, PADSTRING('five',1900), PADSTRING('index pad 5',700)); 1 row inserted/updated/deleted ij> insert into a values (6, 60, PADSTRING('six',1900), PADSTRING('index pad 6',700)); 1 row inserted/updated/deleted ij> insert into a values (7, 70, PADSTRING('seven',1900), PADSTRING('index pad 7',700)); 1 row inserted/updated/deleted ij> create index a_idx on a (a, index_pad) ; 0 rows inserted/updated/deleted ij> commit; ij> run resource 'readBtreeCursorLocks.subsql'; 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. -- -- Very basic single user testing of read locks on cursors on indexes. -- This ".subsql" test is -- meant to be run from another test such that it gets run under multiple -- isolation levels. This is important as they behave -- differently, depending on isolation levels. -- -- assume's caller has already done: run 'LockTableQuery.subsql'; to get -- easy access to the lock VTI. -- TEST 0: btree cursor scan, group fetch = 1 -- TEST 1: btree cursor scan, group fetch = 2 -- TEST 2: btree cursor scan, group fetch = 1 stop scan in middle of set -- TEST 3: btree cursor scan, group fetch = 4 stop scan in middle of set -- TEST 4: btree cursor scan, group fetch = 1 (scan with some deleted rows) -- TEST 5: btree cursor scan, group fetch = 2(scan with committed deleted rows) -- TEST 6: btree cursor scan, group fetch = 1 (scan with "<" qualifier) -- TEST 7: btree cursor scan, group fetch = 2 (scan with "<" qualifier) -- TEST 8: btree cursor scan, group fetch = 1 (scan with equals qualifier) -- TEST 9: btree cursor scan, group fetch = 2 (scan with equals qualifier) -- TEST 10: btree cursor scan, group fetch = 1 ("=" qualifier, no rows return) autocommit off; ij> -------------------------------------------------------------------------------- -- Assumes that calling routine has set up the following simple dataset, -- a heap, and index with following initial values: -- create table a (a int, b int, c somesortofchar, [index_pad]); -- create index a_idx on a (a) or a_idx on a (a, index_pad); -- -- 1, 10, 'one' -- 2, 20, 'two' -- 3, 30, 'three' -- 4, 40, 'four' -- 5, 50, 'five' -- 6, 60, 'six' -- 7, 70, 'seven' -------------------------------------------------------------------------------- select * from a; A |B |C |INDEX_PAD ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- 1 |10 |one &|index pad 1 & 2 |20 |two &|index pad 2 & 3 |30 |three &|index pad 3 & 4 |40 |four &|index pad 4 & 5 |50 |five &|index pad 5 & 6 |60 |six &|index pad 6 & 7 |70 |seven &|index pad 7 & ij> commit; ij> -------------------------------------------------------------------------------- -- TEST 0: btree cursor scan, group fetch = 1 -- Test full cursor scan which does no updates. -- ALL MODES - TABLE IS, "scan page lockname of form (pageno, 1) -- SERIALIZABLE - row S locks as it visits each row, held until end xact -- REPEATABLE READ - row S locks as it visits each row, held until end xact -- READ COMMITTED - row S lock on current row, released on move to next row -- READ UNCOMMITTED - no row locks. ------------------------------------------------------------------------------- CALL SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.language.bulkFetchDefault','1'); 0 rows inserted/updated/deleted ij> -- RESOLVE: missing row locks -- WORKAROUND: creating an index and dropping it -- to force the statement to be recompiled create index ix1 on a(a); 0 rows inserted/updated/deleted ij> drop index ix1; 0 rows inserted/updated/deleted ij> commit; ij> get cursor scan_cursor as 'select a from a'; ij> call SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.language.bulkFetchDefault', '16'); 0 rows inserted/updated/deleted ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A ----------- 1 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(2,1) |GRANT|ACTIVE ij> next scan_cursor; A ----------- 2 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(2,1) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(2,6) |GRANT|ACTIVE ij> next scan_cursor; A ----------- 3 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(2,1) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(3,6) |GRANT|ACTIVE ij> next scan_cursor; A ----------- 4 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(2,1) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(4,6) |GRANT|ACTIVE ij> next scan_cursor; A ----------- 5 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(3,1) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(5,6) |GRANT|ACTIVE ij> next scan_cursor; A ----------- 6 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(3,1) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(6,6) |GRANT|ACTIVE ij> next scan_cursor; A ----------- 7 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(3,1) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(7,6) |GRANT|ACTIVE ij> next scan_cursor; No current row ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE ij> close scan_cursor; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> -------------------------------------------------------------------------------- -- TEST 1: btree cursor scan, group fetch = 2 -- Test full cursor scan which does no updates. -- ALL MODES - TABLE IS, "scan page lockname of form (pageno, 1) -- SERIALIZABLE - row S locks as it visits each row, held until end xact -- REPEATABLE READ - row S locks as it visits each row, held until end xact -- READ COMMITTED - row S lock on current row, released on move to next row -- READ UNCOMMITTED - no row locks. -------------------------------------------------------------------------------- CALL SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.language.bulkFetchDefault','2'); 0 rows inserted/updated/deleted ij> -- RESOLVE: missing row locks -- WORKAROUND: creating an index and dropping it -- to force the statement to be recompiled create index ix1 on a(a); 0 rows inserted/updated/deleted ij> drop index ix1; 0 rows inserted/updated/deleted ij> commit; ij> get cursor scan_cursor as 'select a from a'; ij> call SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.language.bulkFetchDefault', '16'); 0 rows inserted/updated/deleted ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A ----------- 1 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(2,1) |GRANT|ACTIVE ij> next scan_cursor; A ----------- 2 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(2,1) |GRANT|ACTIVE ij> next scan_cursor; A ----------- 3 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(2,1) |GRANT|ACTIVE ij> next scan_cursor; A ----------- 4 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(2,1) |GRANT|ACTIVE ij> next scan_cursor; A ----------- 5 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(3,1) |GRANT|ACTIVE ij> next scan_cursor; A ----------- 6 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(3,1) |GRANT|ACTIVE ij> next scan_cursor; A ----------- 7 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; No current row ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE ij> close scan_cursor; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> -------------------------------------------------------------------------------- -- TEST 2: btree cursor scan, group fetch = 1, stop scan in middle of set -- Test full cursor scan which does no updates. -- ALL MODES - TABLE IS, "scan page lockname of form (pageno, 1) -- SERIALIZABLE - row S locks as it visits each row, held until end xact -- REPEATABLE READ - row S locks as it visits each row, held until end xact -- READ COMMITTED - row S lock on current row, released on move to next row -- READ UNCOMMITTED - no row locks. -------------------------------------------------------------------------------- CALL SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.language.bulkFetchDefault','1'); 0 rows inserted/updated/deleted ij> -- RESOLVE: missing row locks -- WORKAROUND: creating an index and dropping it -- to force the statement to be recompiled create index ix1 on a(a); 0 rows inserted/updated/deleted ij> drop index ix1; 0 rows inserted/updated/deleted ij> commit; ij> get cursor scan_cursor as 'select a from a'; ij> call SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.language.bulkFetchDefault', '16'); 0 rows inserted/updated/deleted ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A ----------- 1 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(2,1) |GRANT|ACTIVE ij> next scan_cursor; A ----------- 2 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(2,1) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(2,6) |GRANT|ACTIVE ij> close scan_cursor; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> -------------------------------------------------------------------------------- -- TEST 3: btree cursor scan, group fetch = 4, stop scan in middle of set -- Test full cursor scan which does no updates. -- ALL MODES - TABLE IS, "scan page lockname of form (pageno, 1) -- SERIALIZABLE - row S locks as it visits each row, held until end xact -- REPEATABLE READ - row S locks as it visits each row, held until end xact -- READ COMMITTED - row S lock on current row, released on move to next row -- READ UNCOMMITTED - no row locks. -------------------------------------------------------------------------------- CALL SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.language.bulkFetchDefault','4'); 0 rows inserted/updated/deleted ij> -- RESOLVE: missing row locks -- WORKAROUND: creating an index and dropping it -- to force the statement to be recompiled create index ix1 on a(a); 0 rows inserted/updated/deleted ij> drop index ix1; 0 rows inserted/updated/deleted ij> commit; ij> get cursor scan_cursor as 'select a from a'; ij> call SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.language.bulkFetchDefault', '16'); 0 rows inserted/updated/deleted ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A ----------- 1 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(2,1) |GRANT|ACTIVE ij> next scan_cursor; A ----------- 2 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(2,1) |GRANT|ACTIVE ij> close scan_cursor; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> -------------------------------------------------------------------------------- -- TEST 4: btree cursor scan, group fetch = 1 (scan table with some deleted rows) -- Test full cursor scan on a data set with some deleted rows (the "even" ones). -- ALL MODES - TABLE IS, "scan page lockname of form (pageno, 1) -- SERIALIZABLE - row S locks as it visits each row, held until end xact -- REPEATABLE READ - row S locks as it visits each row, held until end xact -- READ COMMITTED - row S lock on current row, released on move to next row -- READ UNCOMMITTED - no row locks. -- -- After the delete the base table should look like: -- 1, 10, 'one' -- 3, 30, 'three' -- 5, 50, 'five' -- 7, 70, 'seven' -------------------------------------------------------------------------------- delete from a where a = 2 or a = 4 or a = 6; 3 rows inserted/updated/deleted ij> commit; ij> CALL SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.language.bulkFetchDefault','1'); 0 rows inserted/updated/deleted ij> -- RESOLVE: missing row locks -- WORKAROUND: creating an index and dropping it -- to force the statement to be recompiled create index ix1 on a(a); 0 rows inserted/updated/deleted ij> drop index ix1; 0 rows inserted/updated/deleted ij> commit; ij> get cursor scan_cursor as 'select a from a'; ij> call SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.language.bulkFetchDefault', '16'); 0 rows inserted/updated/deleted ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A ----------- 1 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(2,1) |GRANT|ACTIVE ij> next scan_cursor; A ----------- 3 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(2,1) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(3,6) |GRANT|ACTIVE ij> next scan_cursor; A ----------- 5 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(3,1) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(5,6) |GRANT|ACTIVE ij> next scan_cursor; A ----------- 7 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(3,1) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(7,6) |GRANT|ACTIVE ij> next scan_cursor; No current row ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE ij> close scan_cursor; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> -------------------------------------------------------------------------------- -- TEST 5: btree cursor scan, group fetch = 2 (scan with committed deleted rows) -- Test full cursor scan on a data set with some deleted rows (the "even" ones). -- ALL MODES - TABLE IS, "scan page lockname of form (pageno, 1) -- SERIALIZABLE - row S locks as it visits each row, held until end xact -- REPEATABLE READ - row S locks as it visits each row, held until end xact -- READ COMMITTED - row S lock on current row, released on move to next row -- READ UNCOMMITTED - no row locks. -- -- At this point the base table should look like: -- 1, 10, 'one' -- 3, 30, 'three' -- 5, 50, 'five' -- 7, 70, 'seven' -------------------------------------------------------------------------------- CALL SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.language.bulkFetchDefault','2'); 0 rows inserted/updated/deleted ij> -- RESOLVE: missing row locks -- WORKAROUND: creating an index and dropping it -- to force the statement to be recompiled create index ix1 on a(a); 0 rows inserted/updated/deleted ij> drop index ix1; 0 rows inserted/updated/deleted ij> commit; ij> get cursor scan_cursor as 'select a from a'; ij> call SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.language.bulkFetchDefault', '16'); 0 rows inserted/updated/deleted ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A ----------- 1 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(2,1) |GRANT|ACTIVE ij> next scan_cursor; A ----------- 3 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(2,1) |GRANT|ACTIVE ij> next scan_cursor; A ----------- 5 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(3,1) |GRANT|ACTIVE ij> next scan_cursor; A ----------- 7 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(3,1) |GRANT|ACTIVE ij> next scan_cursor; No current row ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE ij> close scan_cursor; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> -------------------------------------------------------------------------------- -- TEST 6: btree cursor scan, group fetch = 1 (scan with "<" qualifier) -- Test "less than" qualified cursor scan on a data set. -- ALL MODES - TABLE IS, "scan page lockname of form (pageno, 1) -- SERIALIZABLE - row S locks as it visits each row, held until end xact -- REPEATABLE READ - row S locks as it visits each row, held until end xact -- READ COMMITTED - row S lock on current row, released on move to next row -- READ UNCOMMITTED - no row locks. -- -- At this point the base table should look like: -- 1, 10, 'one' -- 3, 30, 'three' -- 5, 50, 'five' -- 7, 70, 'seven' -------------------------------------------------------------------------------- CALL SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.language.bulkFetchDefault','1'); 0 rows inserted/updated/deleted ij> -- RESOLVE: missing row locks -- WORKAROUND: creating an index and dropping it -- to force the statement to be recompiled create index ix1 on a(a); 0 rows inserted/updated/deleted ij> drop index ix1; 0 rows inserted/updated/deleted ij> commit; ij> get cursor scan_cursor as 'select a from a where a < 3'; ij> call SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.language.bulkFetchDefault', '16'); 0 rows inserted/updated/deleted ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A ----------- 1 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(2,1) |GRANT|ACTIVE ij> next scan_cursor; No current row ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE ij> close scan_cursor; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> -------------------------------------------------------------------------------- -- TEST 7: btree cursor scan, group fetch = 2 (scan with "<" qualifier) -- Test "less than" qualified cursor scan on a data set. -- ALL MODES - TABLE IS, "scan page lockname of form (pageno, 1) -- SERIALIZABLE - row S locks as it visits each row, held until end xact -- REPEATABLE READ - row S locks as it visits each row, held until end xact -- READ COMMITTED - row S lock on current row, released on move to next row -- READ UNCOMMITTED - no row locks. -- -- At this point the base table should look like: -- 1, 10, 'one' -- 3, 30, 'three' -- 5, 50, 'five' -- 7, 70, 'seven' -------------------------------------------------------------------------------- CALL SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.language.bulkFetchDefault','2'); 0 rows inserted/updated/deleted ij> -- RESOLVE: missing row locks -- WORKAROUND: creating an index and dropping it -- to force the statement to be recompiled create index ix1 on a(a); 0 rows inserted/updated/deleted ij> drop index ix1; 0 rows inserted/updated/deleted ij> commit; ij> get cursor scan_cursor as 'select a from a where a < 3'; ij> call SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.language.bulkFetchDefault', '16'); 0 rows inserted/updated/deleted ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A ----------- 1 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; No current row ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE ij> close scan_cursor; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> -------------------------------------------------------------------------------- -- TEST 8: btree cursor scan, group fetch = 1 (scan with equals qualifier) -- Test "equals" qualified cursor scan on a data set. -- ALL MODES - TABLE IS, "scan page lockname of form (pageno, 1) -- SERIALIZABLE - row S locks as it visits each row, held until end xact -- REPEATABLE READ - row S locks as it visits each row, held until end xact -- READ COMMITTED - row S lock on current row, released on move to next row -- READ UNCOMMITTED - no row locks. -- -- At this point the base table should look like: -- 1, 10, 'one' -- 3, 30, 'three' -- 5, 50, 'five' -- 7, 70, 'seven' -------------------------------------------------------------------------------- CALL SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.language.bulkFetchDefault','1'); 0 rows inserted/updated/deleted ij> -- RESOLVE: missing row locks -- WORKAROUND: creating an index and dropping it -- to force the statement to be recompiled create index ix1 on a(a); 0 rows inserted/updated/deleted ij> drop index ix1; 0 rows inserted/updated/deleted ij> commit; ij> get cursor scan_cursor as 'select a from a where a = 5'; ij> call SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.language.bulkFetchDefault', '16'); 0 rows inserted/updated/deleted ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A ----------- 5 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(3,1) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(5,6) |GRANT|ACTIVE ij> next scan_cursor; No current row ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE ij> close scan_cursor; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> -------------------------------------------------------------------------------- -- TEST 9: btree cursor scan, group fetch = 2 (scan with equals qualifier) -- Test "equals" qualified cursor scan on a data set. -- ALL MODES - TABLE IS, "scan page lockname of form (pageno, 1) -- SERIALIZABLE - row S locks as it visits each row, held until end xact -- REPEATABLE READ - row S locks as it visits each row, held until end xact -- READ COMMITTED - row S lock on current row, released on move to next row -- READ UNCOMMITTED - no row locks. -- -- At this point the base table should look like: -- 1, 10, 'one' -- 3, 30, 'three' -- 5, 50, 'five' -- 7, 70, 'seven' -------------------------------------------------------------------------------- CALL SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.language.bulkFetchDefault','2'); 0 rows inserted/updated/deleted ij> -- RESOLVE: missing row locks -- WORKAROUND: creating an index and dropping it -- to force the statement to be recompiled create index ix1 on a(a); 0 rows inserted/updated/deleted ij> drop index ix1; 0 rows inserted/updated/deleted ij> commit; ij> get cursor scan_cursor as 'select a from a where a = 5 or a = 7'; ij> call SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.language.bulkFetchDefault', '16'); 0 rows inserted/updated/deleted ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A ----------- 5 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(3,1) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(5,6) |GRANT|ACTIVE ij> next scan_cursor; A ----------- 7 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(3,1) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(7,6) |GRANT|ACTIVE ij> close scan_cursor; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> -------------------------------------------------------------------------------- -- TEST 10: btree cursor scan, group fetch = 1 (equals qualifier, no rows return) -- Test "equals" qualified cursor scan on a data set, no rows returned. -- ALL MODES - TABLE IS, "scan page lockname of form (pageno, 1) -- SERIALIZABLE - row S locks as it visits each row, held until end xact -- REPEATABLE READ - row S locks as it visits each row, held until end xact -- READ COMMITTED - row S lock on current row, released on move to next row -- READ UNCOMMITTED - no row locks. -- -- At this point the base table should look like: -- 1, 10, 'one' -- 3, 30, 'three' -- 5, 50, 'five' -- 7, 70, 'seven' -------------------------------------------------------------------------------- -- no rows expected to qualify CALL SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.language.bulkFetchDefault','1'); 0 rows inserted/updated/deleted ij> -- RESOLVE: missing row locks -- WORKAROUND: creating an index and dropping it -- to force the statement to be recompiled create index ix1 on a(a); 0 rows inserted/updated/deleted ij> drop index ix1; 0 rows inserted/updated/deleted ij> commit; ij> get cursor scan_cursor as 'select a from a where a = 42'; ij> call SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.language.bulkFetchDefault', '16'); 0 rows inserted/updated/deleted ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; No current row ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; No current row ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE ij> close scan_cursor; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> drop table a; 0 rows inserted/updated/deleted ij> -- non cursor, unique index run drop table a; ERROR 42Y55: 'DROP TABLE' cannot be performed on 'A' because it does not exist. ij> create table a (a int, b int, c varchar(1900), index_pad varchar(800) ) ; 0 rows inserted/updated/deleted ij> insert into a values (1, 10, PADSTRING('one',1900), PADSTRING('index pad 1',800)); 1 row inserted/updated/deleted ij> insert into a values (2, 20, PADSTRING('two',1900), PADSTRING('index pad 2',800)); 1 row inserted/updated/deleted ij> insert into a values (3, 30, PADSTRING('three',1900), PADSTRING('index pad 3',800)); 1 row inserted/updated/deleted ij> insert into a values (4, 40, PADSTRING('four',1900), PADSTRING('index pad 4',800)); 1 row inserted/updated/deleted ij> insert into a values (5, 50, PADSTRING('five',1900), PADSTRING('index pad 5',800)); 1 row inserted/updated/deleted ij> insert into a values (6, 60, PADSTRING('six',1900), PADSTRING('index pad 6',800)); 1 row inserted/updated/deleted ij> insert into a values (7, 70, PADSTRING('seven',1900), PADSTRING('index pad 7',800)); 1 row inserted/updated/deleted ij> create unique index a_idx on a (a, index_pad) ; 0 rows inserted/updated/deleted ij> commit; ij> run resource 'readBtreeSetLocks.subsql'; 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. -- -- Basic single user testing of read locks on select "set" queries on indexes. -- -- This ".subsql" test is -- meant to be run from another test such that it gets run under multiple -- isolation levels. This is important as they behave -- differently, depending on isolation levels. -- -- assume's caller has already done: run 'LockTableQuery.subsql'; to get -- easy access to the lock VTI. -- TEST 0: btree scan -- TEST 1: btree scan, (scan table with some deleted rows) -- TEST 2: btree scan, (scan with "<" qualifier) -- TEST 3: btree scan, (scan with equals qualifier) -- TEST 4: btree scan, (equals qualifier, no rows return) autocommit off; ij> -------------------------------------------------------------------------------- -- Assumes that calling routine has set up the following simple dataset, -- a heap, and index with following initial values: -- create table a (a int, b int, c somesortofchar, [index_pad]); -- create index a_idx on a (a) or a_idx on a (a, index_pad); -- -- 1, 10, 'one' -- 2, 20, 'two' -- 3, 30, 'three' -- 4, 40, 'four' -- 5, 50, 'five' -- 6, 60, 'six' -- 7, 70, 'seven' -------------------------------------------------------------------------------- select * from a; A |B |C |INDEX_PAD ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- 1 |10 |one &|index pad 1 & 2 |20 |two &|index pad 2 & 3 |30 |three &|index pad 3 & 4 |40 |four &|index pad 4 & 5 |50 |five &|index pad 5 & 6 |60 |six &|index pad 6 & 7 |70 |seven &|index pad 7 & ij> commit; ij> -------------------------------------------------------------------------------- -- TEST 0: btree scan -- Test full scan. -- ALL MODES - TABLE IS, "scan page lockname of form (pageno, 1) -- SERIALIZABLE - row S locks as it visits each row, row/table lock -- held until end xact. Also holds one previous key lock. -- REPEATABLE READ - row S locks as it visits each row, row/table locks held -- until end of transaction. -- READ COMMITTED - instantaneous S locks requested on each row. No locks -- held after query finishes. -- READ UNCOMMITTED - no row locks. No locks held after query finishes. -------------------------------------------------------------------------------- select a from a; A ----------- 1 2 3 4 5 6 7 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> -------------------------------------------------------------------------------- -- TEST 1: btree scan, (scan table with some deleted rows) -- Test full scan on a data set with some deleted rows (the "even" ones). -- ALL MODES - TABLE IS, "scan page lockname of form (pageno, 1) -- SERIALIZABLE - row S locks as it visits each row, row/table lock -- held until end xact. Also holds one previous key lock. -- REPEATABLE READ - row S locks as it visits each row, row/table locks held -- until end of transaction. -- READ COMMITTED - instantaneous S locks requested on each row. No locks -- held after query finishes. -- READ UNCOMMITTED - no row locks. No locks held after query finishes. -- -- After the delete the base table should look like: -- 1, 10, 'one' -- 3, 30, 'three' -- 5, 50, 'five' -- 7, 70, 'seven' -------------------------------------------------------------------------------- delete from a where a = 2 or a = 4 or a = 6; 3 rows inserted/updated/deleted ij> commit; ij> -- The above delete and commit can allow post commit processing to run before -- the subsequent select is run, most likely if this run is on a table where -- there is one row per page. To get reproducible results from the subsequent -- lock calls, wait for post commit to finish before running the select. -- Without this wait "extra" locks sometimes might show up - these are locks -- on the committed deleted rows which have not been cleaned yet depending -- on timing. CALL WAIT_FOR_POST_COMMIT(); 0 rows inserted/updated/deleted ij> select a from a; A ----------- 1 3 5 7 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> -------------------------------------------------------------------------------- -- TEST 2: btree scan, (scan with "<" qualifier) -- Test "less than" qualified scan on a data set. -- ALL MODES - TABLE IS, "scan page lockname of form (pageno, 1) -- SERIALIZABLE - row S locks as it visits each row, row/table lock -- held until end xact. Also holds one previous key lock. -- REPEATABLE READ - row S locks as it visits each row, row/table locks held -- until end of transaction. -- READ COMMITTED - instantaneous S locks requested on each row. No locks -- held after query finishes. -- READ UNCOMMITTED - no row locks. No locks held after query finishes. -- -- At this point the base table should look like: -- 1, 10, 'one' -- 3, 30, 'three' -- 5, 50, 'five' -- 7, 70, 'seven' -------------------------------------------------------------------------------- select a from a where a < 3; A ----------- 1 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> -------------------------------------------------------------------------------- -- TEST 3: btree scan, (scan with equals qualifier) -- Test "equals" qualified cursor scan on a data set. -- ALL MODES - TABLE IS, "scan page lockname of form (pageno, 1) -- SERIALIZABLE - row S locks as it visits each row, row/table lock -- held until end xact. Also holds one previous key lock. -- REPEATABLE READ - row S locks as it visits each row, row/table locks held -- until end of transaction. -- READ COMMITTED - instantaneous S locks requested on each row. No locks -- held after query finishes. -- READ UNCOMMITTED - no row locks. No locks held after query finishes. -- -- At this point the base table should look like: -- 1, 10, 'one' -- 3, 30, 'three' -- 5, 50, 'five' -- 7, 70, 'seven' -------------------------------------------------------------------------------- select a from a where a = 5; A ----------- 5 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> -------------------------------------------------------------------------------- -- TEST 4: btree scan, (equals qualifier, no rows return) -- Test "equals" qualified scan on a data set, no rows returned. -- ALL MODES - TABLE IS, "scan page lockname of form (pageno, 1) -- SERIALIZABLE - row S locks as it visits each row, row/table lock -- held until end xact. Also holds one previous key lock. -- REPEATABLE READ - row S locks as it visits each row, row/table locks held -- until end of transaction. -- READ COMMITTED - instantaneous S locks requested on each row. No locks -- held after query finishes. -- READ UNCOMMITTED - no row locks. No locks held after query finishes. -- -- At this point the base table should look like: -- 1, 10, 'one' -- 3, 30, 'three' -- 5, 50, 'five' -- 7, 70, 'seven' -------------------------------------------------------------------------------- -- no rows expected to qualify select a from a where a = 42; A ----------- ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> drop table a; 0 rows inserted/updated/deleted ij> -- non cursor, non-unique index run drop table a; ERROR 42Y55: 'DROP TABLE' cannot be performed on 'A' because it does not exist. ij> create table a (a int, b int, c varchar(1900), index_pad varchar(900) ) ; 0 rows inserted/updated/deleted ij> insert into a values (1, 10, PADSTRING('one',1900), PADSTRING('index pad 1',900)); 1 row inserted/updated/deleted ij> insert into a values (2, 20, PADSTRING('two',1900), PADSTRING('index pad 2',900)); 1 row inserted/updated/deleted ij> insert into a values (3, 30, PADSTRING('three',1900), PADSTRING('index pad 3',900)); 1 row inserted/updated/deleted ij> insert into a values (4, 40, PADSTRING('four',1900), PADSTRING('index pad 4',900)); 1 row inserted/updated/deleted ij> insert into a values (5, 50, PADSTRING('five',1900), PADSTRING('index pad 5',900)); 1 row inserted/updated/deleted ij> insert into a values (6, 60, PADSTRING('six',1900), PADSTRING('index pad 6',900)); 1 row inserted/updated/deleted ij> insert into a values (7, 70, PADSTRING('seven',1900), PADSTRING('index pad 7',900)); 1 row inserted/updated/deleted ij> create index a_idx on a (a, index_pad) ; 0 rows inserted/updated/deleted ij> commit; ij> run resource 'readBtreeSetLocks.subsql'; 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. -- -- Basic single user testing of read locks on select "set" queries on indexes. -- -- This ".subsql" test is -- meant to be run from another test such that it gets run under multiple -- isolation levels. This is important as they behave -- differently, depending on isolation levels. -- -- assume's caller has already done: run 'LockTableQuery.subsql'; to get -- easy access to the lock VTI. -- TEST 0: btree scan -- TEST 1: btree scan, (scan table with some deleted rows) -- TEST 2: btree scan, (scan with "<" qualifier) -- TEST 3: btree scan, (scan with equals qualifier) -- TEST 4: btree scan, (equals qualifier, no rows return) autocommit off; ij> -------------------------------------------------------------------------------- -- Assumes that calling routine has set up the following simple dataset, -- a heap, and index with following initial values: -- create table a (a int, b int, c somesortofchar, [index_pad]); -- create index a_idx on a (a) or a_idx on a (a, index_pad); -- -- 1, 10, 'one' -- 2, 20, 'two' -- 3, 30, 'three' -- 4, 40, 'four' -- 5, 50, 'five' -- 6, 60, 'six' -- 7, 70, 'seven' -------------------------------------------------------------------------------- select * from a; A |B |C |INDEX_PAD ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- 1 |10 |one &|index pad 1 & 2 |20 |two &|index pad 2 & 3 |30 |three &|index pad 3 & 4 |40 |four &|index pad 4 & 5 |50 |five &|index pad 5 & 6 |60 |six &|index pad 6 & 7 |70 |seven &|index pad 7 & ij> commit; ij> -------------------------------------------------------------------------------- -- TEST 0: btree scan -- Test full scan. -- ALL MODES - TABLE IS, "scan page lockname of form (pageno, 1) -- SERIALIZABLE - row S locks as it visits each row, row/table lock -- held until end xact. Also holds one previous key lock. -- REPEATABLE READ - row S locks as it visits each row, row/table locks held -- until end of transaction. -- READ COMMITTED - instantaneous S locks requested on each row. No locks -- held after query finishes. -- READ UNCOMMITTED - no row locks. No locks held after query finishes. -------------------------------------------------------------------------------- select a from a; A ----------- 1 2 3 4 5 6 7 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> -------------------------------------------------------------------------------- -- TEST 1: btree scan, (scan table with some deleted rows) -- Test full scan on a data set with some deleted rows (the "even" ones). -- ALL MODES - TABLE IS, "scan page lockname of form (pageno, 1) -- SERIALIZABLE - row S locks as it visits each row, row/table lock -- held until end xact. Also holds one previous key lock. -- REPEATABLE READ - row S locks as it visits each row, row/table locks held -- until end of transaction. -- READ COMMITTED - instantaneous S locks requested on each row. No locks -- held after query finishes. -- READ UNCOMMITTED - no row locks. No locks held after query finishes. -- -- After the delete the base table should look like: -- 1, 10, 'one' -- 3, 30, 'three' -- 5, 50, 'five' -- 7, 70, 'seven' -------------------------------------------------------------------------------- delete from a where a = 2 or a = 4 or a = 6; 3 rows inserted/updated/deleted ij> commit; ij> -- The above delete and commit can allow post commit processing to run before -- the subsequent select is run, most likely if this run is on a table where -- there is one row per page. To get reproducible results from the subsequent -- lock calls, wait for post commit to finish before running the select. -- Without this wait "extra" locks sometimes might show up - these are locks -- on the committed deleted rows which have not been cleaned yet depending -- on timing. CALL WAIT_FOR_POST_COMMIT(); 0 rows inserted/updated/deleted ij> select a from a; A ----------- 1 3 5 7 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> -------------------------------------------------------------------------------- -- TEST 2: btree scan, (scan with "<" qualifier) -- Test "less than" qualified scan on a data set. -- ALL MODES - TABLE IS, "scan page lockname of form (pageno, 1) -- SERIALIZABLE - row S locks as it visits each row, row/table lock -- held until end xact. Also holds one previous key lock. -- REPEATABLE READ - row S locks as it visits each row, row/table locks held -- until end of transaction. -- READ COMMITTED - instantaneous S locks requested on each row. No locks -- held after query finishes. -- READ UNCOMMITTED - no row locks. No locks held after query finishes. -- -- At this point the base table should look like: -- 1, 10, 'one' -- 3, 30, 'three' -- 5, 50, 'five' -- 7, 70, 'seven' -------------------------------------------------------------------------------- select a from a where a < 3; A ----------- 1 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> -------------------------------------------------------------------------------- -- TEST 3: btree scan, (scan with equals qualifier) -- Test "equals" qualified cursor scan on a data set. -- ALL MODES - TABLE IS, "scan page lockname of form (pageno, 1) -- SERIALIZABLE - row S locks as it visits each row, row/table lock -- held until end xact. Also holds one previous key lock. -- REPEATABLE READ - row S locks as it visits each row, row/table locks held -- until end of transaction. -- READ COMMITTED - instantaneous S locks requested on each row. No locks -- held after query finishes. -- READ UNCOMMITTED - no row locks. No locks held after query finishes. -- -- At this point the base table should look like: -- 1, 10, 'one' -- 3, 30, 'three' -- 5, 50, 'five' -- 7, 70, 'seven' -------------------------------------------------------------------------------- select a from a where a = 5; A ----------- 5 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> -------------------------------------------------------------------------------- -- TEST 4: btree scan, (equals qualifier, no rows return) -- Test "equals" qualified scan on a data set, no rows returned. -- ALL MODES - TABLE IS, "scan page lockname of form (pageno, 1) -- SERIALIZABLE - row S locks as it visits each row, row/table lock -- held until end xact. Also holds one previous key lock. -- REPEATABLE READ - row S locks as it visits each row, row/table locks held -- until end of transaction. -- READ COMMITTED - instantaneous S locks requested on each row. No locks -- held after query finishes. -- READ UNCOMMITTED - no row locks. No locks held after query finishes. -- -- At this point the base table should look like: -- 1, 10, 'one' -- 3, 30, 'three' -- 5, 50, 'five' -- 7, 70, 'seven' -------------------------------------------------------------------------------- -- no rows expected to qualify select a from a where a = 42; A ----------- ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> drop table a; 0 rows inserted/updated/deleted ij> commit; ij> -- REPEATABLE READ TEST set current isolation RS; 0 rows inserted/updated/deleted ij> commit; ij> -- run each test with rows on one page in the interesting conglomerate (heap in -- the non-index tests, and in the index in the index based tests). -- cursor, no index run drop table a; ERROR 42Y55: 'DROP TABLE' cannot be performed on 'A' because it does not exist. ij> -- to create tables of page size 4k and still keep the following tbl -- create table a (a int, b int, c varchar(1900)); create table a(a int, b int); 0 rows inserted/updated/deleted ij> alter table a add column c varchar(1900); 0 rows inserted/updated/deleted ij> insert into a values (1, 10, 'one'); 1 row inserted/updated/deleted ij> insert into a values (2, 20, 'two'); 1 row inserted/updated/deleted ij> insert into a values (3, 30, 'three'); 1 row inserted/updated/deleted ij> insert into a values (4, 40, 'four'); 1 row inserted/updated/deleted ij> insert into a values (5, 50, 'five'); 1 row inserted/updated/deleted ij> insert into a values (6, 60, 'six'); 1 row inserted/updated/deleted ij> insert into a values (7, 70, 'seven'); 1 row inserted/updated/deleted ij> commit; ij> run resource 'readCursorLocks.subsql'; 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. -- -- Very basic single user testing of read locks on cursors on heap tables. -- This ".subsql" test is -- meant to be run from another test such that it gets run under multiple -- isolation levels. This is important as they behave -- differently, depending on isolation levels. -- -- assume's caller has already done: run 'LockTableQuery.subsql'; to get -- easy access to the lock VTI. -- TEST 0: heap cursor scan, group fetch = 1 -- TEST 1: heap cursor scan, group fetch = 2 -- TEST 2: heap cursor scan, group fetch = 1, stop scan in middle of set -- TEST 3: heap cursor scan, group fetch = 4, stop scan in middle of set -- TEST 4: heap cursor scan, group fetch = 1 (scan table with some deleted rows) -- TEST 5: heap cursor scan, group fetch = 2 (scan with committed deleted rows) -- TEST 6: heap cursor scan, group fetch = 1 (scan with "<" qualifier) -- TEST 7: heap cursor scan, group fetch = 2 (scan with "<" qualifier) -- TEST 8: heap cursor scan, group fetch = 1 (scan with equals qualifier) -- TEST 9: heap cursor scan, group fetch = 2 (scan with equals qualifier) -- TEST 10: heap cursor scan, group fetch = 1 (equals qualifier, no rows return) autocommit off; ij> -------------------------------------------------------------------------------- -- Assumes that calling routine has set up the following simple dataset, -- a heap, no indexes with following initial values: -- create table (a int, b int, c somesortofchar); -- 1, 10, 'one' -- 2, 20, 'two' -- 3, 30, 'three' -- 4, 40, 'four' -- 5, 50, 'five' -- 6, 60, 'six' -- 7, 70, 'seven' -------------------------------------------------------------------------------- select * from a; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 1 |10 |one 2 |20 |two 3 |30 |three 4 |40 |four 5 |50 |five 6 |60 |six 7 |70 |seven ij> commit; ij> -------------------------------------------------------------------------------- -- TEST 0: heap cursor scan, group fetch = 1 -- Test full cursor scan which does no updates. -- SERIALIZABLE - will get table level S lock. -- REPEATABLE READ - TABLE IS, will get row S locks as it visits each row. -- READ COMMITTED - TABLE IS, will hold single S lock on current row. -- READ UNCOMMITTED - TABLE IS, no row locks. -------------------------------------------------------------------------------- CALL SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.language.bulkFetchDefault','1'); 0 rows inserted/updated/deleted ij> get cursor scan_cursor as 'select a, b, c from a'; ij> call SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.language.bulkFetchDefault', '16'); 0 rows inserted/updated/deleted ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 1 |10 |one ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,7) |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 2 |20 |two ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,8) |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 3 |30 |three ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,8) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,9) |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 4 |40 |four ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,10) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,8) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,9) |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 5 |50 |five ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,10) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,11) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,8) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,9) |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 6 |60 |six ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,10) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,11) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,12) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,8) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,9) |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 7 |70 |seven ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,10) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,11) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,12) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,13) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,8) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,9) |GRANT|ACTIVE ij> next scan_cursor; No current row ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,10) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,11) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,12) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,13) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,8) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,9) |GRANT|ACTIVE ij> close scan_cursor; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,10) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,11) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,12) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,13) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,8) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,9) |GRANT|ACTIVE ij> commit; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> -------------------------------------------------------------------------------- -- TEST 1: heap cursor scan, group fetch = 2 -- Test full cursor scan which does no updates. -- SERIALIZABLE - will get table level S lock. -- REPEATABLE READ - TABLE IS, will get row S locks as it visits each row. -- READ COMMITTED - TABLE IS, will get instantaneous locks and release -- READ UNCOMMITTED - TABLE IS, no row locks. -------------------------------------------------------------------------------- CALL SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.language.bulkFetchDefault','2'); 0 rows inserted/updated/deleted ij> -- RESOLVE: missing row locks -- WORKAROUND: creating an index and dropping it -- to force the query 'select a, b, c from a' to be recompiled create index ix1 on a(a); 0 rows inserted/updated/deleted ij> drop index ix1; 0 rows inserted/updated/deleted ij> commit; ij> get cursor scan_cursor as 'select a, b, c from a'; ij> call SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.language.bulkFetchDefault', '16'); 0 rows inserted/updated/deleted ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 1 |10 |one ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,8) |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 2 |20 |two ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,8) |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 3 |30 |three ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,10) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,8) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,9) |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 4 |40 |four ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,10) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,8) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,9) |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 5 |50 |five ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,10) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,11) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,12) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,8) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,9) |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 6 |60 |six ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,10) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,11) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,12) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,8) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,9) |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 7 |70 |seven ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,10) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,11) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,12) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,13) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,8) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,9) |GRANT|ACTIVE ij> next scan_cursor; No current row ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,10) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,11) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,12) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,13) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,8) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,9) |GRANT|ACTIVE ij> close scan_cursor; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,10) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,11) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,12) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,13) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,8) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,9) |GRANT|ACTIVE ij> commit; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> -------------------------------------------------------------------------------- -- TEST 2: heap cursor scan, group fetch = 1, stop scan in middle of set -- Test full cursor scan which does no updates. -- SERIALIZABLE - will get table level S lock. -- REPEATABLE READ - TABLE IS, will get row S locks as it visits each row. -- READ COMMITTED - TABLE IS, will hold single S lock on current row. -- READ UNCOMMITTED - TABLE IS, no row locks. -------------------------------------------------------------------------------- CALL SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.language.bulkFetchDefault','1'); 0 rows inserted/updated/deleted ij> -- RESOLVE: missing row locks -- WORKAROUND: creating an index and dropping it -- to force the query 'select a, b, c from a' to be recompiled create index ix1 on a(a); 0 rows inserted/updated/deleted ij> drop index ix1; 0 rows inserted/updated/deleted ij> commit; ij> get cursor scan_cursor as 'select a, b, c from a'; ij> call SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.language.bulkFetchDefault', '16'); 0 rows inserted/updated/deleted ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 1 |10 |one ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,7) |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 2 |20 |two ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,8) |GRANT|ACTIVE ij> close scan_cursor; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,8) |GRANT|ACTIVE ij> commit; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> -------------------------------------------------------------------------------- -- TEST 3: heap cursor scan, group fetch = 4, stop scan in middle of set -- Test full cursor scan which does no updates. -- SERIALIZABLE - will get table level S lock. -- REPEATABLE READ - TABLE IS, will get row S locks as it visits each row. -- READ COMMITTED - TABLE IS, will hold single S lock on current row. -- READ UNCOMMITTED - TABLE IS, no row locks. -------------------------------------------------------------------------------- CALL SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.language.bulkFetchDefault','4'); 0 rows inserted/updated/deleted ij> -- RESOLVE: missing row locks -- WORKAROUND: creating an index and dropping it -- to force the query 'select a, b, c from a' to be recompiled create index ix1 on a(a); 0 rows inserted/updated/deleted ij> drop index ix1; 0 rows inserted/updated/deleted ij> commit; ij> get cursor scan_cursor as 'select a, b, c from a'; ij> call SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.language.bulkFetchDefault', '16'); 0 rows inserted/updated/deleted ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 1 |10 |one ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,10) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,8) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,9) |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 2 |20 |two ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,10) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,8) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,9) |GRANT|ACTIVE ij> close scan_cursor; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,10) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,8) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,9) |GRANT|ACTIVE ij> commit; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> -------------------------------------------------------------------------------- -- TEST 4: heap cursor scan, group fetch = 1 (scan table with some deleted rows) -- Test full cursor scan on a data set with some deleted rows (the "even" ones). -- SERIALIZABLE - will get table level S lock. -- REPEATABLE READ - TABLE IS, will get row S locks as it visits each row -- (including deleted ones). -- READ COMMITTED - TABLE IS, will get instantaneous locks and release -- READ UNCOMMITTED - TABLE IS, no row locks. -- -- After the delete the table should look like: -- 1, 10, 'one' -- 3, 30, 'three' -- 5, 50, 'five' -- 7, 70, 'seven' -------------------------------------------------------------------------------- delete from a where a = 2 or a = 4 or a = 6; 3 rows inserted/updated/deleted ij> commit; ij> CALL SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.language.bulkFetchDefault','1'); 0 rows inserted/updated/deleted ij> -- RESOLVE: missing row locks -- WORKAROUND: creating an index and dropping it -- to force the query 'select a, b, c from a' to be recompiled create index ix1 on a(a); 0 rows inserted/updated/deleted ij> drop index ix1; 0 rows inserted/updated/deleted ij> commit; ij> get cursor scan_cursor as 'select a, b, c from a'; ij> call SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.language.bulkFetchDefault', '16'); 0 rows inserted/updated/deleted ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 1 |10 |one ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,7) |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 3 |30 |three ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,9) |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 5 |50 |five ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,11) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,9) |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 7 |70 |seven ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,11) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,13) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,9) |GRANT|ACTIVE ij> next scan_cursor; No current row ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,11) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,13) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,9) |GRANT|ACTIVE ij> close scan_cursor; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,11) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,13) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,9) |GRANT|ACTIVE ij> commit; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> -------------------------------------------------------------------------------- -- TEST 5: heap cursor scan, group fetch = 2 (scan with committed deleted rows) -- Test full cursor scan on a data set with some deleted rows (the "even" ones). -- SERIALIZABLE - will get table level S lock. -- REPEATABLE READ - TABLE IS, will get row S locks as it visits each row -- (including deleted ones). -- READ COMMITTED - TABLE IS, will get instantaneous locks and release -- READ UNCOMMITTED - TABLE IS, no row locks. -- -- At this point the table should look like: -- 1, 10, 'one' -- 3, 30, 'three' -- 5, 50, 'five' -- 7, 70, 'seven' -------------------------------------------------------------------------------- CALL SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.language.bulkFetchDefault','2'); 0 rows inserted/updated/deleted ij> -- RESOLVE: missing row locks -- WORKAROUND: creating an index and dropping it -- to force the query 'select a, b, c from a' to be recompiled create index ix1 on a(a); 0 rows inserted/updated/deleted ij> drop index ix1; 0 rows inserted/updated/deleted ij> commit; ij> get cursor scan_cursor as 'select a, b, c from a'; ij> call SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.language.bulkFetchDefault', '16'); 0 rows inserted/updated/deleted ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 1 |10 |one ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,9) |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 3 |30 |three ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,9) |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 5 |50 |five ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,11) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,13) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,9) |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 7 |70 |seven ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,11) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,13) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,9) |GRANT|ACTIVE ij> next scan_cursor; No current row ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,11) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,13) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,9) |GRANT|ACTIVE ij> close scan_cursor; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,11) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,13) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,9) |GRANT|ACTIVE ij> commit; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> -------------------------------------------------------------------------------- -- TEST 6: heap cursor scan, group fetch = 1 (scan with "<" qualifier) -- Test "less than" qualified cursor scan on a data set. -- SERIALIZABLE - will get table level S lock. -- REPEATABLE READ - TABLE IS, will get row S locks as it visits each row -- (including deleted ones). -- READ COMMITTED - TABLE IS, will get instantaneous locks and release -- READ UNCOMMITTED - TABLE IS, no row locks. -- -- At this point the table should look like: -- 1, 10, 'one' -- 3, 30, 'three' -- 5, 50, 'five' -- 7, 70, 'seven' -------------------------------------------------------------------------------- CALL SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.language.bulkFetchDefault','1'); 0 rows inserted/updated/deleted ij> get cursor scan_cursor as 'select a, b, c from a where a < 3'; ij> call SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.language.bulkFetchDefault', '16'); 0 rows inserted/updated/deleted ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 1 |10 |one ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,7) |GRANT|ACTIVE ij> next scan_cursor; No current row ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,7) |GRANT|ACTIVE ij> close scan_cursor; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,7) |GRANT|ACTIVE ij> commit; ij> -------------------------------------------------------------------------------- -- TEST 7: heap cursor scan, group fetch = 2 (scan with "<" qualifier) -- Test "less than" qualified cursor scan on a data set. -- SERIALIZABLE - will get table level S lock. -- REPEATABLE READ - TABLE IS, will get row S locks as it visits each row -- (including deleted ones). -- READ COMMITTED - TABLE IS, will get instantaneous locks and release -- READ UNCOMMITTED - TABLE IS, no row locks. -- -- At this point the table should look like: -- 1, 10, 'one' -- 3, 30, 'three' -- 5, 50, 'five' -- 7, 70, 'seven' -------------------------------------------------------------------------------- CALL SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.language.bulkFetchDefault','2'); 0 rows inserted/updated/deleted ij> -- RESOLVE: missing row locks -- WORKAROUND: creating an index and dropping it -- to force the statement to be recompiled create index ix1 on a(a); 0 rows inserted/updated/deleted ij> drop index ix1; 0 rows inserted/updated/deleted ij> commit; ij> get cursor scan_cursor as 'select a, b, c from a where a < 3'; ij> call SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.language.bulkFetchDefault', '16'); 0 rows inserted/updated/deleted ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 1 |10 |one ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,7) |GRANT|ACTIVE ij> next scan_cursor; No current row ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,7) |GRANT|ACTIVE ij> close scan_cursor; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,7) |GRANT|ACTIVE ij> commit; ij> -------------------------------------------------------------------------------- -- TEST 8: heap cursor scan, group fetch = 1 (scan with equals qualifier) -- Test "equals" qualified cursor scan on a data set. -- SERIALIZABLE - will get table level S lock. -- REPEATABLE READ - TABLE IS, will get row S locks as it visits each row -- (including deleted ones). -- READ COMMITTED - TABLE IS, will get instantaneous locks and release -- READ UNCOMMITTED - TABLE IS, no row locks. -- -- At this point the table should look like: -- 1, 10, 'one' -- 3, 30, 'three' -- 5, 50, 'five' -- 7, 70, 'seven' -------------------------------------------------------------------------------- CALL SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.language.bulkFetchDefault','1'); 0 rows inserted/updated/deleted ij> get cursor scan_cursor as 'select a, b, c from a where a = 5'; ij> call SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.language.bulkFetchDefault', '16'); 0 rows inserted/updated/deleted ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 5 |50 |five ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,11) |GRANT|ACTIVE ij> next scan_cursor; No current row ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,11) |GRANT|ACTIVE ij> close scan_cursor; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,11) |GRANT|ACTIVE ij> commit; ij> -------------------------------------------------------------------------------- -- TEST 9: heap cursor scan, group fetch = 2 (scan with equals qualifier) -- Test "equals" qualified cursor scan on a data set. -- SERIALIZABLE - will get table level S lock. -- REPEATABLE READ - TABLE IS, will get row S locks as it visits each row -- (including deleted ones). -- READ COMMITTED - TABLE IS, will get instantaneous locks and release -- READ UNCOMMITTED - TABLE IS, no row locks. -- -- At this point the table should look like: -- 1, 10, 'one' -- 3, 30, 'three' -- 5, 50, 'five' -- 7, 70, 'seven' -------------------------------------------------------------------------------- CALL SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.language.bulkFetchDefault','2'); 0 rows inserted/updated/deleted ij> get cursor scan_cursor as 'select a, b, c from a where a = 7'; ij> call SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.language.bulkFetchDefault', '16'); 0 rows inserted/updated/deleted ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 7 |70 |seven ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,13) |GRANT|ACTIVE ij> next scan_cursor; No current row ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,13) |GRANT|ACTIVE ij> close scan_cursor; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,13) |GRANT|ACTIVE ij> commit; ij> -------------------------------------------------------------------------------- -- TEST 10: heap cursor scan, group fetch = 1 (equals qualifier, no rows return) -- Test "equals" qualified cursor scan on a data set, no rows returned. -- SERIALIZABLE - will get table level S lock. -- REPEATABLE READ - TABLE IS, will get row S locks as it visits each row -- (including deleted ones). -- READ COMMITTED - TABLE IS, will get instantaneous locks and release -- READ UNCOMMITTED - TABLE IS, no row locks. -- -- At this point the table should look like: -- 1, 10, 'one' -- 3, 30, 'three' -- 5, 50, 'five' -- 7, 70, 'seven' -------------------------------------------------------------------------------- CALL SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.language.bulkFetchDefault','1'); 0 rows inserted/updated/deleted ij> -- RESOLVE: missing row locks -- WORKAROUND: creating an index and dropping it -- to force the statement to be recompiled create index ix1 on a(a); 0 rows inserted/updated/deleted ij> drop index ix1; 0 rows inserted/updated/deleted ij> commit; ij> get cursor scan_cursor as 'select a, b, c from a where a = 7'; ij> CALL SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.language.bulkFetchDefault','16'); 0 rows inserted/updated/deleted ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 7 |70 |seven ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,13) |GRANT|ACTIVE ij> next scan_cursor; No current row ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,13) |GRANT|ACTIVE ij> close scan_cursor; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,13) |GRANT|ACTIVE ij> commit; ij> drop table a; 0 rows inserted/updated/deleted ij> -- non cursor, no index run drop table a; ERROR 42Y55: 'DROP TABLE' cannot be performed on 'A' because it does not exist. ij> -- to create tables of page size 4k and still keep the following tbl -- create table a (a int, b int, c varchar(1900)); create table a(a int, b int); 0 rows inserted/updated/deleted ij> alter table a add column c varchar(1900); 0 rows inserted/updated/deleted ij> insert into a values (1, 10, 'one'); 1 row inserted/updated/deleted ij> insert into a values (2, 20, 'two'); 1 row inserted/updated/deleted ij> insert into a values (3, 30, 'three'); 1 row inserted/updated/deleted ij> insert into a values (4, 40, 'four'); 1 row inserted/updated/deleted ij> insert into a values (5, 50, 'five'); 1 row inserted/updated/deleted ij> insert into a values (6, 60, 'six'); 1 row inserted/updated/deleted ij> insert into a values (7, 70, 'seven'); 1 row inserted/updated/deleted ij> commit; ij> run resource 'readSetLocks.subsql'; 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. -- -- Very basic single user testing of read locks in "set" queries on heap tables. -- This ".subsql" test is -- meant to be run from another test such that it gets run under multiple -- isolation levels. This is important as they behave -- differently, depending on isolation levels. -- -- assume's caller has already done: run 'LockTableQuery.subsql'; to get -- easy access to the lock VTI. -- TEST 0: heap scan. -- TEST 1: heap scan, some rows deleted. -- TEST 2: heap scan, (scan with "<" qualifier) -- TEST 3: heap scan, (scan with equals qualifier) -- TEST 4: heap scan, (equals qualifier, no rows return) autocommit off; ij> -------------------------------------------------------------------------------- -- Assumes that calling routine has set up the following simple dataset, -- a heap, no indexes with following initial values: -- create table (a int, b int, c somesortofchar); -- 1, 10, 'one' -- 2, 20, 'two' -- 3, 30, 'three' -- 4, 40, 'four' -- 5, 50, 'five' -- 6, 60, 'six' -- 7, 70, 'seven' -------------------------------------------------------------------------------- select * from a; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 1 |10 |one 2 |20 |two 3 |30 |three 4 |40 |four 5 |50 |five 6 |60 |six 7 |70 |seven ij> commit; ij> -------------------------------------------------------------------------------- -- TEST 0: heap scan. -- Test full cursor scan which does no updates. -- SERIALIZABLE - will get table level S lock, held to end of xact. -- REPEATABLE READ - TABLE IS, will get row S locks as it visits each row -- (including deleted ones). held to end of xact. -- READ COMMITTED - TABLE IS, will get instantaneous locks and release. No -- locks held when statement completes. -- READ UNCOMMITTED - TABLE IS, no row locks. No locks after statement ends. -------------------------------------------------------------------------------- select a, b, c from a; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 1 |10 |one 2 |20 |two 3 |30 |three 4 |40 |four 5 |50 |five 6 |60 |six 7 |70 |seven ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,10) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,11) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,12) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,13) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,8) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,9) |GRANT|ACTIVE ij> commit; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> -------------------------------------------------------------------------------- -- TEST 1: heap scan, some rows deleted. -- Test full cursor scan on a data set with some deleted rows (the "even" ones). -- SERIALIZABLE - will get table level S lock. -- REPEATABLE READ - TABLE IS, will get row S locks as it visits each row -- (including deleted ones). -- READ COMMITTED - TABLE IS, will get instantaneous locks and release -- READ UNCOMMITTED - TABLE IS, no row locks. -- SERIALIZABLE - will get table level S lock, held to end of xact. -- REPEATABLE READ - TABLE IS, will get row S locks as it visits each row -- (including deleted ones). held to end of xact. -- READ COMMITTED - TABLE IS, will get instantaneous locks and release. No -- locks held when statement completes. -- READ UNCOMMITTED - TABLE IS, no row locks. No locks after statement ends. -- -- After the delete the table should look like: -- 1, 10, 'one' -- 3, 30, 'three' -- 5, 50, 'five' -- 7, 70, 'seven' -------------------------------------------------------------------------------- delete from a where a = 2 or a = 4 or a = 6; 3 rows inserted/updated/deleted ij> commit; ij> select a, b, c from a; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 1 |10 |one 3 |30 |three 5 |50 |five 7 |70 |seven ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,11) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,13) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,9) |GRANT|ACTIVE ij> commit; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> -------------------------------------------------------------------------------- -- TEST 2: heap scan, (scan with "<" qualifier) -- Test "less than" qualified cursor scan on a data set. -- SERIALIZABLE - will get table level S lock, held to end of xact. -- REPEATABLE READ - TABLE IS, will get row S locks as it visits each row -- (including deleted ones). held to end of xact. -- READ COMMITTED - TABLE IS, will get instantaneous locks and release. No -- locks held when statement completes. -- READ UNCOMMITTED - TABLE IS, no row locks. No locks after statement ends. -- -- At this point the table should look like: -- 1, 10, 'one' -- 3, 30, 'three' -- 5, 50, 'five' -- 7, 70, 'seven' -------------------------------------------------------------------------------- select a, b, c from a; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 1 |10 |one 3 |30 |three 5 |50 |five 7 |70 |seven ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,11) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,13) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,9) |GRANT|ACTIVE ij> commit; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> -------------------------------------------------------------------------------- -- TEST 3: heap scan, (scan with equals qualifier) -- Test "equals" qualified cursor scan on a data set. -- SERIALIZABLE - will get table level S lock, held to end of xact. -- REPEATABLE READ - TABLE IS, will get row S locks as it visits each row -- (including deleted ones). held to end of xact. -- READ COMMITTED - TABLE IS, will get instantaneous locks and release. No -- locks held when statement completes. -- READ UNCOMMITTED - TABLE IS, no row locks. No locks after statement ends. -- -- At this point the table should look like: -- 1, 10, 'one' -- 3, 30, 'three' -- 5, 50, 'five' -- 7, 70, 'seven' -------------------------------------------------------------------------------- select a, b, c from a where a = 5; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 5 |50 |five ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,11) |GRANT|ACTIVE ij> commit; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> -------------------------------------------------------------------------------- -- TEST 4: heap scan, (equals qualifier, no rows return) -- Test "equals" qualified cursor scan on a data set, no rows returned. -- SERIALIZABLE - will get table level S lock, held to end of xact. -- REPEATABLE READ - TABLE IS, will get row S locks as it visits each row -- (including deleted ones). held to end of xact. -- READ COMMITTED - TABLE IS, will get instantaneous locks and release. No -- locks held when statement completes. -- READ UNCOMMITTED - TABLE IS, no row locks. No locks after statement ends. -- -- At this point the table should look like: -- 1, 10, 'one' -- 3, 30, 'three' -- 5, 50, 'five' -- 7, 70, 'seven' -------------------------------------------------------------------------------- select a, b, c from a where a = 7; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 7 |70 |seven ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,13) |GRANT|ACTIVE ij> commit; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> drop table a; 0 rows inserted/updated/deleted ij> -- cursor, unique index run drop table a; ERROR 42Y55: 'DROP TABLE' cannot be performed on 'A' because it does not exist. ij> -- to create tables of page size 4k and still keep the following tbl -- create table a (a int, b int, c varchar(1900)); create table a(a int, b int); 0 rows inserted/updated/deleted ij> alter table a add column c varchar(1900); 0 rows inserted/updated/deleted ij> insert into a values (1, 10, 'one'); 1 row inserted/updated/deleted ij> insert into a values (2, 20, 'two'); 1 row inserted/updated/deleted ij> insert into a values (3, 30, 'three'); 1 row inserted/updated/deleted ij> insert into a values (4, 40, 'four'); 1 row inserted/updated/deleted ij> insert into a values (5, 50, 'five'); 1 row inserted/updated/deleted ij> insert into a values (6, 60, 'six'); 1 row inserted/updated/deleted ij> insert into a values (7, 70, 'seven'); 1 row inserted/updated/deleted ij> create unique index a_idx on a (a); 0 rows inserted/updated/deleted ij> commit; ij> run resource 'readBtreeCursorLocks.subsql'; 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. -- -- Very basic single user testing of read locks on cursors on indexes. -- This ".subsql" test is -- meant to be run from another test such that it gets run under multiple -- isolation levels. This is important as they behave -- differently, depending on isolation levels. -- -- assume's caller has already done: run 'LockTableQuery.subsql'; to get -- easy access to the lock VTI. -- TEST 0: btree cursor scan, group fetch = 1 -- TEST 1: btree cursor scan, group fetch = 2 -- TEST 2: btree cursor scan, group fetch = 1 stop scan in middle of set -- TEST 3: btree cursor scan, group fetch = 4 stop scan in middle of set -- TEST 4: btree cursor scan, group fetch = 1 (scan with some deleted rows) -- TEST 5: btree cursor scan, group fetch = 2(scan with committed deleted rows) -- TEST 6: btree cursor scan, group fetch = 1 (scan with "<" qualifier) -- TEST 7: btree cursor scan, group fetch = 2 (scan with "<" qualifier) -- TEST 8: btree cursor scan, group fetch = 1 (scan with equals qualifier) -- TEST 9: btree cursor scan, group fetch = 2 (scan with equals qualifier) -- TEST 10: btree cursor scan, group fetch = 1 ("=" qualifier, no rows return) autocommit off; ij> -------------------------------------------------------------------------------- -- Assumes that calling routine has set up the following simple dataset, -- a heap, and index with following initial values: -- create table a (a int, b int, c somesortofchar, [index_pad]); -- create index a_idx on a (a) or a_idx on a (a, index_pad); -- -- 1, 10, 'one' -- 2, 20, 'two' -- 3, 30, 'three' -- 4, 40, 'four' -- 5, 50, 'five' -- 6, 60, 'six' -- 7, 70, 'seven' -------------------------------------------------------------------------------- select * from a; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 1 |10 |one 2 |20 |two 3 |30 |three 4 |40 |four 5 |50 |five 6 |60 |six 7 |70 |seven ij> commit; ij> -------------------------------------------------------------------------------- -- TEST 0: btree cursor scan, group fetch = 1 -- Test full cursor scan which does no updates. -- ALL MODES - TABLE IS, "scan page lockname of form (pageno, 1) -- SERIALIZABLE - row S locks as it visits each row, held until end xact -- REPEATABLE READ - row S locks as it visits each row, held until end xact -- READ COMMITTED - row S lock on current row, released on move to next row -- READ UNCOMMITTED - no row locks. ------------------------------------------------------------------------------- CALL SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.language.bulkFetchDefault','1'); 0 rows inserted/updated/deleted ij> -- RESOLVE: missing row locks -- WORKAROUND: creating an index and dropping it -- to force the statement to be recompiled create index ix1 on a(a); 0 rows inserted/updated/deleted WARNING 01504: The new index is a duplicate of an existing index: A_IDX. ij> drop index ix1; ERROR 42X65: Index 'IX1' does not exist. ij> commit; ij> get cursor scan_cursor as 'select a from a'; ij> call SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.language.bulkFetchDefault', '16'); 0 rows inserted/updated/deleted ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A ----------- 1 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,1) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,7) |GRANT|ACTIVE ij> next scan_cursor; A ----------- 2 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,1) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,8) |GRANT|ACTIVE ij> next scan_cursor; A ----------- 3 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,1) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,8) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,9) |GRANT|ACTIVE ij> next scan_cursor; A ----------- 4 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,1) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,10) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,8) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,9) |GRANT|ACTIVE ij> next scan_cursor; A ----------- 5 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,1) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,10) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,11) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,8) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,9) |GRANT|ACTIVE ij> next scan_cursor; A ----------- 6 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,1) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,10) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,11) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,12) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,8) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,9) |GRANT|ACTIVE ij> next scan_cursor; A ----------- 7 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,1) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,10) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,11) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,12) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,13) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,8) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,9) |GRANT|ACTIVE ij> next scan_cursor; No current row ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,10) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,11) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,12) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,13) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,8) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,9) |GRANT|ACTIVE ij> close scan_cursor; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,10) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,11) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,12) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,13) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,8) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,9) |GRANT|ACTIVE ij> commit; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> -------------------------------------------------------------------------------- -- TEST 1: btree cursor scan, group fetch = 2 -- Test full cursor scan which does no updates. -- ALL MODES - TABLE IS, "scan page lockname of form (pageno, 1) -- SERIALIZABLE - row S locks as it visits each row, held until end xact -- REPEATABLE READ - row S locks as it visits each row, held until end xact -- READ COMMITTED - row S lock on current row, released on move to next row -- READ UNCOMMITTED - no row locks. -------------------------------------------------------------------------------- CALL SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.language.bulkFetchDefault','2'); 0 rows inserted/updated/deleted ij> -- RESOLVE: missing row locks -- WORKAROUND: creating an index and dropping it -- to force the statement to be recompiled create index ix1 on a(a); 0 rows inserted/updated/deleted WARNING 01504: The new index is a duplicate of an existing index: A_IDX. ij> drop index ix1; ERROR 42X65: Index 'IX1' does not exist. ij> commit; ij> get cursor scan_cursor as 'select a from a'; ij> call SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.language.bulkFetchDefault', '16'); 0 rows inserted/updated/deleted ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A ----------- 1 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,1) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,8) |GRANT|ACTIVE ij> next scan_cursor; A ----------- 2 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,1) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,8) |GRANT|ACTIVE ij> next scan_cursor; A ----------- 3 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,1) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,10) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,8) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,9) |GRANT|ACTIVE ij> next scan_cursor; A ----------- 4 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,1) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,10) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,8) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,9) |GRANT|ACTIVE ij> next scan_cursor; A ----------- 5 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,1) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,10) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,11) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,12) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,8) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,9) |GRANT|ACTIVE ij> next scan_cursor; A ----------- 6 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,1) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,10) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,11) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,12) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,8) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,9) |GRANT|ACTIVE ij> next scan_cursor; A ----------- 7 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,10) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,11) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,12) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,13) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,8) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,9) |GRANT|ACTIVE ij> next scan_cursor; No current row ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,10) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,11) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,12) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,13) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,8) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,9) |GRANT|ACTIVE ij> close scan_cursor; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,10) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,11) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,12) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,13) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,8) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,9) |GRANT|ACTIVE ij> commit; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> -------------------------------------------------------------------------------- -- TEST 2: btree cursor scan, group fetch = 1, stop scan in middle of set -- Test full cursor scan which does no updates. -- ALL MODES - TABLE IS, "scan page lockname of form (pageno, 1) -- SERIALIZABLE - row S locks as it visits each row, held until end xact -- REPEATABLE READ - row S locks as it visits each row, held until end xact -- READ COMMITTED - row S lock on current row, released on move to next row -- READ UNCOMMITTED - no row locks. -------------------------------------------------------------------------------- CALL SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.language.bulkFetchDefault','1'); 0 rows inserted/updated/deleted ij> -- RESOLVE: missing row locks -- WORKAROUND: creating an index and dropping it -- to force the statement to be recompiled create index ix1 on a(a); 0 rows inserted/updated/deleted WARNING 01504: The new index is a duplicate of an existing index: A_IDX. ij> drop index ix1; ERROR 42X65: Index 'IX1' does not exist. ij> commit; ij> get cursor scan_cursor as 'select a from a'; ij> call SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.language.bulkFetchDefault', '16'); 0 rows inserted/updated/deleted ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A ----------- 1 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,1) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,7) |GRANT|ACTIVE ij> next scan_cursor; A ----------- 2 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,1) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,8) |GRANT|ACTIVE ij> close scan_cursor; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,8) |GRANT|ACTIVE ij> commit; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> -------------------------------------------------------------------------------- -- TEST 3: btree cursor scan, group fetch = 4, stop scan in middle of set -- Test full cursor scan which does no updates. -- ALL MODES - TABLE IS, "scan page lockname of form (pageno, 1) -- SERIALIZABLE - row S locks as it visits each row, held until end xact -- REPEATABLE READ - row S locks as it visits each row, held until end xact -- READ COMMITTED - row S lock on current row, released on move to next row -- READ UNCOMMITTED - no row locks. -------------------------------------------------------------------------------- CALL SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.language.bulkFetchDefault','4'); 0 rows inserted/updated/deleted ij> -- RESOLVE: missing row locks -- WORKAROUND: creating an index and dropping it -- to force the statement to be recompiled create index ix1 on a(a); 0 rows inserted/updated/deleted WARNING 01504: The new index is a duplicate of an existing index: A_IDX. ij> drop index ix1; ERROR 42X65: Index 'IX1' does not exist. ij> commit; ij> get cursor scan_cursor as 'select a from a'; ij> call SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.language.bulkFetchDefault', '16'); 0 rows inserted/updated/deleted ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A ----------- 1 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,1) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,10) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,8) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,9) |GRANT|ACTIVE ij> next scan_cursor; A ----------- 2 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,1) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,10) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,8) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,9) |GRANT|ACTIVE ij> close scan_cursor; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,10) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,8) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,9) |GRANT|ACTIVE ij> commit; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> -------------------------------------------------------------------------------- -- TEST 4: btree cursor scan, group fetch = 1 (scan table with some deleted rows) -- Test full cursor scan on a data set with some deleted rows (the "even" ones). -- ALL MODES - TABLE IS, "scan page lockname of form (pageno, 1) -- SERIALIZABLE - row S locks as it visits each row, held until end xact -- REPEATABLE READ - row S locks as it visits each row, held until end xact -- READ COMMITTED - row S lock on current row, released on move to next row -- READ UNCOMMITTED - no row locks. -- -- After the delete the base table should look like: -- 1, 10, 'one' -- 3, 30, 'three' -- 5, 50, 'five' -- 7, 70, 'seven' -------------------------------------------------------------------------------- delete from a where a = 2 or a = 4 or a = 6; 3 rows inserted/updated/deleted ij> commit; ij> CALL SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.language.bulkFetchDefault','1'); 0 rows inserted/updated/deleted ij> -- RESOLVE: missing row locks -- WORKAROUND: creating an index and dropping it -- to force the statement to be recompiled create index ix1 on a(a); 0 rows inserted/updated/deleted WARNING 01504: The new index is a duplicate of an existing index: A_IDX. ij> drop index ix1; ERROR 42X65: Index 'IX1' does not exist. ij> commit; ij> get cursor scan_cursor as 'select a from a'; ij> call SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.language.bulkFetchDefault', '16'); 0 rows inserted/updated/deleted ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A ----------- 1 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,1) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,7) |GRANT|ACTIVE ij> next scan_cursor; A ----------- 3 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,1) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,9) |GRANT|ACTIVE ij> next scan_cursor; A ----------- 5 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,1) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,11) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,9) |GRANT|ACTIVE ij> next scan_cursor; A ----------- 7 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,1) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,11) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,13) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,9) |GRANT|ACTIVE ij> next scan_cursor; No current row ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,11) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,13) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,9) |GRANT|ACTIVE ij> close scan_cursor; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,11) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,13) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,9) |GRANT|ACTIVE ij> commit; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> -------------------------------------------------------------------------------- -- TEST 5: btree cursor scan, group fetch = 2 (scan with committed deleted rows) -- Test full cursor scan on a data set with some deleted rows (the "even" ones). -- ALL MODES - TABLE IS, "scan page lockname of form (pageno, 1) -- SERIALIZABLE - row S locks as it visits each row, held until end xact -- REPEATABLE READ - row S locks as it visits each row, held until end xact -- READ COMMITTED - row S lock on current row, released on move to next row -- READ UNCOMMITTED - no row locks. -- -- At this point the base table should look like: -- 1, 10, 'one' -- 3, 30, 'three' -- 5, 50, 'five' -- 7, 70, 'seven' -------------------------------------------------------------------------------- CALL SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.language.bulkFetchDefault','2'); 0 rows inserted/updated/deleted ij> -- RESOLVE: missing row locks -- WORKAROUND: creating an index and dropping it -- to force the statement to be recompiled create index ix1 on a(a); 0 rows inserted/updated/deleted WARNING 01504: The new index is a duplicate of an existing index: A_IDX. ij> drop index ix1; ERROR 42X65: Index 'IX1' does not exist. ij> commit; ij> get cursor scan_cursor as 'select a from a'; ij> call SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.language.bulkFetchDefault', '16'); 0 rows inserted/updated/deleted ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A ----------- 1 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,1) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,9) |GRANT|ACTIVE ij> next scan_cursor; A ----------- 3 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,1) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,9) |GRANT|ACTIVE ij> next scan_cursor; A ----------- 5 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,1) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,11) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,13) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,9) |GRANT|ACTIVE ij> next scan_cursor; A ----------- 7 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,1) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,11) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,13) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,9) |GRANT|ACTIVE ij> next scan_cursor; No current row ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,11) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,13) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,9) |GRANT|ACTIVE ij> close scan_cursor; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,11) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,13) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,9) |GRANT|ACTIVE ij> commit; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> -------------------------------------------------------------------------------- -- TEST 6: btree cursor scan, group fetch = 1 (scan with "<" qualifier) -- Test "less than" qualified cursor scan on a data set. -- ALL MODES - TABLE IS, "scan page lockname of form (pageno, 1) -- SERIALIZABLE - row S locks as it visits each row, held until end xact -- REPEATABLE READ - row S locks as it visits each row, held until end xact -- READ COMMITTED - row S lock on current row, released on move to next row -- READ UNCOMMITTED - no row locks. -- -- At this point the base table should look like: -- 1, 10, 'one' -- 3, 30, 'three' -- 5, 50, 'five' -- 7, 70, 'seven' -------------------------------------------------------------------------------- CALL SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.language.bulkFetchDefault','1'); 0 rows inserted/updated/deleted ij> -- RESOLVE: missing row locks -- WORKAROUND: creating an index and dropping it -- to force the statement to be recompiled create index ix1 on a(a); 0 rows inserted/updated/deleted WARNING 01504: The new index is a duplicate of an existing index: A_IDX. ij> drop index ix1; ERROR 42X65: Index 'IX1' does not exist. ij> commit; ij> get cursor scan_cursor as 'select a from a where a < 3'; ij> call SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.language.bulkFetchDefault', '16'); 0 rows inserted/updated/deleted ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A ----------- 1 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,1) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,7) |GRANT|ACTIVE ij> next scan_cursor; No current row ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,7) |GRANT|ACTIVE ij> close scan_cursor; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,7) |GRANT|ACTIVE ij> commit; ij> -------------------------------------------------------------------------------- -- TEST 7: btree cursor scan, group fetch = 2 (scan with "<" qualifier) -- Test "less than" qualified cursor scan on a data set. -- ALL MODES - TABLE IS, "scan page lockname of form (pageno, 1) -- SERIALIZABLE - row S locks as it visits each row, held until end xact -- REPEATABLE READ - row S locks as it visits each row, held until end xact -- READ COMMITTED - row S lock on current row, released on move to next row -- READ UNCOMMITTED - no row locks. -- -- At this point the base table should look like: -- 1, 10, 'one' -- 3, 30, 'three' -- 5, 50, 'five' -- 7, 70, 'seven' -------------------------------------------------------------------------------- CALL SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.language.bulkFetchDefault','2'); 0 rows inserted/updated/deleted ij> -- RESOLVE: missing row locks -- WORKAROUND: creating an index and dropping it -- to force the statement to be recompiled create index ix1 on a(a); 0 rows inserted/updated/deleted WARNING 01504: The new index is a duplicate of an existing index: A_IDX. ij> drop index ix1; ERROR 42X65: Index 'IX1' does not exist. ij> commit; ij> get cursor scan_cursor as 'select a from a where a < 3'; ij> call SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.language.bulkFetchDefault', '16'); 0 rows inserted/updated/deleted ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A ----------- 1 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,7) |GRANT|ACTIVE ij> next scan_cursor; No current row ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,7) |GRANT|ACTIVE ij> close scan_cursor; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,7) |GRANT|ACTIVE ij> commit; ij> -------------------------------------------------------------------------------- -- TEST 8: btree cursor scan, group fetch = 1 (scan with equals qualifier) -- Test "equals" qualified cursor scan on a data set. -- ALL MODES - TABLE IS, "scan page lockname of form (pageno, 1) -- SERIALIZABLE - row S locks as it visits each row, held until end xact -- REPEATABLE READ - row S locks as it visits each row, held until end xact -- READ COMMITTED - row S lock on current row, released on move to next row -- READ UNCOMMITTED - no row locks. -- -- At this point the base table should look like: -- 1, 10, 'one' -- 3, 30, 'three' -- 5, 50, 'five' -- 7, 70, 'seven' -------------------------------------------------------------------------------- CALL SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.language.bulkFetchDefault','1'); 0 rows inserted/updated/deleted ij> -- RESOLVE: missing row locks -- WORKAROUND: creating an index and dropping it -- to force the statement to be recompiled create index ix1 on a(a); 0 rows inserted/updated/deleted WARNING 01504: The new index is a duplicate of an existing index: A_IDX. ij> drop index ix1; ERROR 42X65: Index 'IX1' does not exist. ij> commit; ij> get cursor scan_cursor as 'select a from a where a = 5'; ij> call SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.language.bulkFetchDefault', '16'); 0 rows inserted/updated/deleted ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A ----------- 5 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,1) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,11) |GRANT|ACTIVE ij> next scan_cursor; No current row ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,1) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,11) |GRANT|ACTIVE ij> close scan_cursor; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,11) |GRANT|ACTIVE ij> commit; ij> -------------------------------------------------------------------------------- -- TEST 9: btree cursor scan, group fetch = 2 (scan with equals qualifier) -- Test "equals" qualified cursor scan on a data set. -- ALL MODES - TABLE IS, "scan page lockname of form (pageno, 1) -- SERIALIZABLE - row S locks as it visits each row, held until end xact -- REPEATABLE READ - row S locks as it visits each row, held until end xact -- READ COMMITTED - row S lock on current row, released on move to next row -- READ UNCOMMITTED - no row locks. -- -- At this point the base table should look like: -- 1, 10, 'one' -- 3, 30, 'three' -- 5, 50, 'five' -- 7, 70, 'seven' -------------------------------------------------------------------------------- CALL SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.language.bulkFetchDefault','2'); 0 rows inserted/updated/deleted ij> -- RESOLVE: missing row locks -- WORKAROUND: creating an index and dropping it -- to force the statement to be recompiled create index ix1 on a(a); 0 rows inserted/updated/deleted WARNING 01504: The new index is a duplicate of an existing index: A_IDX. ij> drop index ix1; ERROR 42X65: Index 'IX1' does not exist. ij> commit; ij> get cursor scan_cursor as 'select a from a where a = 5 or a = 7'; ij> call SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.language.bulkFetchDefault', '16'); 0 rows inserted/updated/deleted ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A ----------- 5 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,1) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,11) |GRANT|ACTIVE ij> next scan_cursor; A ----------- 7 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,1) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,11) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,13) |GRANT|ACTIVE ij> close scan_cursor; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,11) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,13) |GRANT|ACTIVE ij> commit; ij> -------------------------------------------------------------------------------- -- TEST 10: btree cursor scan, group fetch = 1 (equals qualifier, no rows return) -- Test "equals" qualified cursor scan on a data set, no rows returned. -- ALL MODES - TABLE IS, "scan page lockname of form (pageno, 1) -- SERIALIZABLE - row S locks as it visits each row, held until end xact -- REPEATABLE READ - row S locks as it visits each row, held until end xact -- READ COMMITTED - row S lock on current row, released on move to next row -- READ UNCOMMITTED - no row locks. -- -- At this point the base table should look like: -- 1, 10, 'one' -- 3, 30, 'three' -- 5, 50, 'five' -- 7, 70, 'seven' -------------------------------------------------------------------------------- -- no rows expected to qualify CALL SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.language.bulkFetchDefault','1'); 0 rows inserted/updated/deleted ij> -- RESOLVE: missing row locks -- WORKAROUND: creating an index and dropping it -- to force the statement to be recompiled create index ix1 on a(a); 0 rows inserted/updated/deleted WARNING 01504: The new index is a duplicate of an existing index: A_IDX. ij> drop index ix1; ERROR 42X65: Index 'IX1' does not exist. ij> commit; ij> get cursor scan_cursor as 'select a from a where a = 42'; ij> call SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.language.bulkFetchDefault', '16'); 0 rows inserted/updated/deleted ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; No current row ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; No current row ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE ij> close scan_cursor; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE ij> commit; ij> drop table a; 0 rows inserted/updated/deleted ij> -- cursor, non-unique index run drop table a; ERROR 42Y55: 'DROP TABLE' cannot be performed on 'A' because it does not exist. ij> -- to create tables of page size 4k and still keep the following tbl -- create table a (a int, b int, c varchar(1900)); create table a(a int, b int); 0 rows inserted/updated/deleted ij> alter table a add column c varchar(1900); 0 rows inserted/updated/deleted ij> insert into a values (1, 10, 'one'); 1 row inserted/updated/deleted ij> insert into a values (2, 20, 'two'); 1 row inserted/updated/deleted ij> insert into a values (3, 30, 'three'); 1 row inserted/updated/deleted ij> insert into a values (4, 40, 'four'); 1 row inserted/updated/deleted ij> insert into a values (5, 50, 'five'); 1 row inserted/updated/deleted ij> insert into a values (6, 60, 'six'); 1 row inserted/updated/deleted ij> insert into a values (7, 70, 'seven'); 1 row inserted/updated/deleted ij> create index a_idx on a (a); 0 rows inserted/updated/deleted ij> commit; ij> run resource 'readBtreeCursorLocks.subsql'; 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. -- -- Very basic single user testing of read locks on cursors on indexes. -- This ".subsql" test is -- meant to be run from another test such that it gets run under multiple -- isolation levels. This is important as they behave -- differently, depending on isolation levels. -- -- assume's caller has already done: run 'LockTableQuery.subsql'; to get -- easy access to the lock VTI. -- TEST 0: btree cursor scan, group fetch = 1 -- TEST 1: btree cursor scan, group fetch = 2 -- TEST 2: btree cursor scan, group fetch = 1 stop scan in middle of set -- TEST 3: btree cursor scan, group fetch = 4 stop scan in middle of set -- TEST 4: btree cursor scan, group fetch = 1 (scan with some deleted rows) -- TEST 5: btree cursor scan, group fetch = 2(scan with committed deleted rows) -- TEST 6: btree cursor scan, group fetch = 1 (scan with "<" qualifier) -- TEST 7: btree cursor scan, group fetch = 2 (scan with "<" qualifier) -- TEST 8: btree cursor scan, group fetch = 1 (scan with equals qualifier) -- TEST 9: btree cursor scan, group fetch = 2 (scan with equals qualifier) -- TEST 10: btree cursor scan, group fetch = 1 ("=" qualifier, no rows return) autocommit off; ij> -------------------------------------------------------------------------------- -- Assumes that calling routine has set up the following simple dataset, -- a heap, and index with following initial values: -- create table a (a int, b int, c somesortofchar, [index_pad]); -- create index a_idx on a (a) or a_idx on a (a, index_pad); -- -- 1, 10, 'one' -- 2, 20, 'two' -- 3, 30, 'three' -- 4, 40, 'four' -- 5, 50, 'five' -- 6, 60, 'six' -- 7, 70, 'seven' -------------------------------------------------------------------------------- select * from a; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 1 |10 |one 2 |20 |two 3 |30 |three 4 |40 |four 5 |50 |five 6 |60 |six 7 |70 |seven ij> commit; ij> -------------------------------------------------------------------------------- -- TEST 0: btree cursor scan, group fetch = 1 -- Test full cursor scan which does no updates. -- ALL MODES - TABLE IS, "scan page lockname of form (pageno, 1) -- SERIALIZABLE - row S locks as it visits each row, held until end xact -- REPEATABLE READ - row S locks as it visits each row, held until end xact -- READ COMMITTED - row S lock on current row, released on move to next row -- READ UNCOMMITTED - no row locks. ------------------------------------------------------------------------------- CALL SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.language.bulkFetchDefault','1'); 0 rows inserted/updated/deleted ij> -- RESOLVE: missing row locks -- WORKAROUND: creating an index and dropping it -- to force the statement to be recompiled create index ix1 on a(a); 0 rows inserted/updated/deleted WARNING 01504: The new index is a duplicate of an existing index: A_IDX. ij> drop index ix1; ERROR 42X65: Index 'IX1' does not exist. ij> commit; ij> get cursor scan_cursor as 'select a from a'; ij> call SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.language.bulkFetchDefault', '16'); 0 rows inserted/updated/deleted ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A ----------- 1 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,1) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,7) |GRANT|ACTIVE ij> next scan_cursor; A ----------- 2 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,1) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,8) |GRANT|ACTIVE ij> next scan_cursor; A ----------- 3 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,1) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,8) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,9) |GRANT|ACTIVE ij> next scan_cursor; A ----------- 4 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,1) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,10) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,8) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,9) |GRANT|ACTIVE ij> next scan_cursor; A ----------- 5 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,1) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,10) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,11) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,8) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,9) |GRANT|ACTIVE ij> next scan_cursor; A ----------- 6 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,1) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,10) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,11) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,12) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,8) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,9) |GRANT|ACTIVE ij> next scan_cursor; A ----------- 7 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,1) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,10) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,11) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,12) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,13) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,8) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,9) |GRANT|ACTIVE ij> next scan_cursor; No current row ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,10) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,11) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,12) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,13) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,8) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,9) |GRANT|ACTIVE ij> close scan_cursor; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,10) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,11) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,12) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,13) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,8) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,9) |GRANT|ACTIVE ij> commit; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> -------------------------------------------------------------------------------- -- TEST 1: btree cursor scan, group fetch = 2 -- Test full cursor scan which does no updates. -- ALL MODES - TABLE IS, "scan page lockname of form (pageno, 1) -- SERIALIZABLE - row S locks as it visits each row, held until end xact -- REPEATABLE READ - row S locks as it visits each row, held until end xact -- READ COMMITTED - row S lock on current row, released on move to next row -- READ UNCOMMITTED - no row locks. -------------------------------------------------------------------------------- CALL SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.language.bulkFetchDefault','2'); 0 rows inserted/updated/deleted ij> -- RESOLVE: missing row locks -- WORKAROUND: creating an index and dropping it -- to force the statement to be recompiled create index ix1 on a(a); 0 rows inserted/updated/deleted WARNING 01504: The new index is a duplicate of an existing index: A_IDX. ij> drop index ix1; ERROR 42X65: Index 'IX1' does not exist. ij> commit; ij> get cursor scan_cursor as 'select a from a'; ij> call SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.language.bulkFetchDefault', '16'); 0 rows inserted/updated/deleted ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A ----------- 1 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,1) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,8) |GRANT|ACTIVE ij> next scan_cursor; A ----------- 2 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,1) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,8) |GRANT|ACTIVE ij> next scan_cursor; A ----------- 3 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,1) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,10) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,8) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,9) |GRANT|ACTIVE ij> next scan_cursor; A ----------- 4 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,1) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,10) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,8) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,9) |GRANT|ACTIVE ij> next scan_cursor; A ----------- 5 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,1) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,10) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,11) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,12) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,8) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,9) |GRANT|ACTIVE ij> next scan_cursor; A ----------- 6 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,1) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,10) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,11) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,12) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,8) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,9) |GRANT|ACTIVE ij> next scan_cursor; A ----------- 7 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,10) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,11) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,12) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,13) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,8) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,9) |GRANT|ACTIVE ij> next scan_cursor; No current row ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,10) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,11) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,12) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,13) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,8) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,9) |GRANT|ACTIVE ij> close scan_cursor; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,10) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,11) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,12) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,13) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,8) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,9) |GRANT|ACTIVE ij> commit; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> -------------------------------------------------------------------------------- -- TEST 2: btree cursor scan, group fetch = 1, stop scan in middle of set -- Test full cursor scan which does no updates. -- ALL MODES - TABLE IS, "scan page lockname of form (pageno, 1) -- SERIALIZABLE - row S locks as it visits each row, held until end xact -- REPEATABLE READ - row S locks as it visits each row, held until end xact -- READ COMMITTED - row S lock on current row, released on move to next row -- READ UNCOMMITTED - no row locks. -------------------------------------------------------------------------------- CALL SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.language.bulkFetchDefault','1'); 0 rows inserted/updated/deleted ij> -- RESOLVE: missing row locks -- WORKAROUND: creating an index and dropping it -- to force the statement to be recompiled create index ix1 on a(a); 0 rows inserted/updated/deleted WARNING 01504: The new index is a duplicate of an existing index: A_IDX. ij> drop index ix1; ERROR 42X65: Index 'IX1' does not exist. ij> commit; ij> get cursor scan_cursor as 'select a from a'; ij> call SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.language.bulkFetchDefault', '16'); 0 rows inserted/updated/deleted ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A ----------- 1 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,1) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,7) |GRANT|ACTIVE ij> next scan_cursor; A ----------- 2 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,1) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,8) |GRANT|ACTIVE ij> close scan_cursor; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,8) |GRANT|ACTIVE ij> commit; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> -------------------------------------------------------------------------------- -- TEST 3: btree cursor scan, group fetch = 4, stop scan in middle of set -- Test full cursor scan which does no updates. -- ALL MODES - TABLE IS, "scan page lockname of form (pageno, 1) -- SERIALIZABLE - row S locks as it visits each row, held until end xact -- REPEATABLE READ - row S locks as it visits each row, held until end xact -- READ COMMITTED - row S lock on current row, released on move to next row -- READ UNCOMMITTED - no row locks. -------------------------------------------------------------------------------- CALL SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.language.bulkFetchDefault','4'); 0 rows inserted/updated/deleted ij> -- RESOLVE: missing row locks -- WORKAROUND: creating an index and dropping it -- to force the statement to be recompiled create index ix1 on a(a); 0 rows inserted/updated/deleted WARNING 01504: The new index is a duplicate of an existing index: A_IDX. ij> drop index ix1; ERROR 42X65: Index 'IX1' does not exist. ij> commit; ij> get cursor scan_cursor as 'select a from a'; ij> call SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.language.bulkFetchDefault', '16'); 0 rows inserted/updated/deleted ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A ----------- 1 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,1) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,10) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,8) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,9) |GRANT|ACTIVE ij> next scan_cursor; A ----------- 2 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,1) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,10) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,8) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,9) |GRANT|ACTIVE ij> close scan_cursor; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,10) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,8) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,9) |GRANT|ACTIVE ij> commit; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> -------------------------------------------------------------------------------- -- TEST 4: btree cursor scan, group fetch = 1 (scan table with some deleted rows) -- Test full cursor scan on a data set with some deleted rows (the "even" ones). -- ALL MODES - TABLE IS, "scan page lockname of form (pageno, 1) -- SERIALIZABLE - row S locks as it visits each row, held until end xact -- REPEATABLE READ - row S locks as it visits each row, held until end xact -- READ COMMITTED - row S lock on current row, released on move to next row -- READ UNCOMMITTED - no row locks. -- -- After the delete the base table should look like: -- 1, 10, 'one' -- 3, 30, 'three' -- 5, 50, 'five' -- 7, 70, 'seven' -------------------------------------------------------------------------------- delete from a where a = 2 or a = 4 or a = 6; 3 rows inserted/updated/deleted ij> commit; ij> CALL SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.language.bulkFetchDefault','1'); 0 rows inserted/updated/deleted ij> -- RESOLVE: missing row locks -- WORKAROUND: creating an index and dropping it -- to force the statement to be recompiled create index ix1 on a(a); 0 rows inserted/updated/deleted WARNING 01504: The new index is a duplicate of an existing index: A_IDX. ij> drop index ix1; ERROR 42X65: Index 'IX1' does not exist. ij> commit; ij> get cursor scan_cursor as 'select a from a'; ij> call SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.language.bulkFetchDefault', '16'); 0 rows inserted/updated/deleted ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A ----------- 1 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,1) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,7) |GRANT|ACTIVE ij> next scan_cursor; A ----------- 3 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,1) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,9) |GRANT|ACTIVE ij> next scan_cursor; A ----------- 5 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,1) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,11) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,9) |GRANT|ACTIVE ij> next scan_cursor; A ----------- 7 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,1) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,11) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,13) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,9) |GRANT|ACTIVE ij> next scan_cursor; No current row ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,11) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,13) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,9) |GRANT|ACTIVE ij> close scan_cursor; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,11) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,13) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,9) |GRANT|ACTIVE ij> commit; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> -------------------------------------------------------------------------------- -- TEST 5: btree cursor scan, group fetch = 2 (scan with committed deleted rows) -- Test full cursor scan on a data set with some deleted rows (the "even" ones). -- ALL MODES - TABLE IS, "scan page lockname of form (pageno, 1) -- SERIALIZABLE - row S locks as it visits each row, held until end xact -- REPEATABLE READ - row S locks as it visits each row, held until end xact -- READ COMMITTED - row S lock on current row, released on move to next row -- READ UNCOMMITTED - no row locks. -- -- At this point the base table should look like: -- 1, 10, 'one' -- 3, 30, 'three' -- 5, 50, 'five' -- 7, 70, 'seven' -------------------------------------------------------------------------------- CALL SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.language.bulkFetchDefault','2'); 0 rows inserted/updated/deleted ij> -- RESOLVE: missing row locks -- WORKAROUND: creating an index and dropping it -- to force the statement to be recompiled create index ix1 on a(a); 0 rows inserted/updated/deleted WARNING 01504: The new index is a duplicate of an existing index: A_IDX. ij> drop index ix1; ERROR 42X65: Index 'IX1' does not exist. ij> commit; ij> get cursor scan_cursor as 'select a from a'; ij> call SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.language.bulkFetchDefault', '16'); 0 rows inserted/updated/deleted ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A ----------- 1 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,1) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,9) |GRANT|ACTIVE ij> next scan_cursor; A ----------- 3 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,1) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,9) |GRANT|ACTIVE ij> next scan_cursor; A ----------- 5 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,1) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,11) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,13) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,9) |GRANT|ACTIVE ij> next scan_cursor; A ----------- 7 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,1) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,11) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,13) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,9) |GRANT|ACTIVE ij> next scan_cursor; No current row ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,11) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,13) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,9) |GRANT|ACTIVE ij> close scan_cursor; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,11) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,13) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,9) |GRANT|ACTIVE ij> commit; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> -------------------------------------------------------------------------------- -- TEST 6: btree cursor scan, group fetch = 1 (scan with "<" qualifier) -- Test "less than" qualified cursor scan on a data set. -- ALL MODES - TABLE IS, "scan page lockname of form (pageno, 1) -- SERIALIZABLE - row S locks as it visits each row, held until end xact -- REPEATABLE READ - row S locks as it visits each row, held until end xact -- READ COMMITTED - row S lock on current row, released on move to next row -- READ UNCOMMITTED - no row locks. -- -- At this point the base table should look like: -- 1, 10, 'one' -- 3, 30, 'three' -- 5, 50, 'five' -- 7, 70, 'seven' -------------------------------------------------------------------------------- CALL SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.language.bulkFetchDefault','1'); 0 rows inserted/updated/deleted ij> -- RESOLVE: missing row locks -- WORKAROUND: creating an index and dropping it -- to force the statement to be recompiled create index ix1 on a(a); 0 rows inserted/updated/deleted WARNING 01504: The new index is a duplicate of an existing index: A_IDX. ij> drop index ix1; ERROR 42X65: Index 'IX1' does not exist. ij> commit; ij> get cursor scan_cursor as 'select a from a where a < 3'; ij> call SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.language.bulkFetchDefault', '16'); 0 rows inserted/updated/deleted ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A ----------- 1 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,1) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,7) |GRANT|ACTIVE ij> next scan_cursor; No current row ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,7) |GRANT|ACTIVE ij> close scan_cursor; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,7) |GRANT|ACTIVE ij> commit; ij> -------------------------------------------------------------------------------- -- TEST 7: btree cursor scan, group fetch = 2 (scan with "<" qualifier) -- Test "less than" qualified cursor scan on a data set. -- ALL MODES - TABLE IS, "scan page lockname of form (pageno, 1) -- SERIALIZABLE - row S locks as it visits each row, held until end xact -- REPEATABLE READ - row S locks as it visits each row, held until end xact -- READ COMMITTED - row S lock on current row, released on move to next row -- READ UNCOMMITTED - no row locks. -- -- At this point the base table should look like: -- 1, 10, 'one' -- 3, 30, 'three' -- 5, 50, 'five' -- 7, 70, 'seven' -------------------------------------------------------------------------------- CALL SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.language.bulkFetchDefault','2'); 0 rows inserted/updated/deleted ij> -- RESOLVE: missing row locks -- WORKAROUND: creating an index and dropping it -- to force the statement to be recompiled create index ix1 on a(a); 0 rows inserted/updated/deleted WARNING 01504: The new index is a duplicate of an existing index: A_IDX. ij> drop index ix1; ERROR 42X65: Index 'IX1' does not exist. ij> commit; ij> get cursor scan_cursor as 'select a from a where a < 3'; ij> call SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.language.bulkFetchDefault', '16'); 0 rows inserted/updated/deleted ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A ----------- 1 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,7) |GRANT|ACTIVE ij> next scan_cursor; No current row ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,7) |GRANT|ACTIVE ij> close scan_cursor; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,7) |GRANT|ACTIVE ij> commit; ij> -------------------------------------------------------------------------------- -- TEST 8: btree cursor scan, group fetch = 1 (scan with equals qualifier) -- Test "equals" qualified cursor scan on a data set. -- ALL MODES - TABLE IS, "scan page lockname of form (pageno, 1) -- SERIALIZABLE - row S locks as it visits each row, held until end xact -- REPEATABLE READ - row S locks as it visits each row, held until end xact -- READ COMMITTED - row S lock on current row, released on move to next row -- READ UNCOMMITTED - no row locks. -- -- At this point the base table should look like: -- 1, 10, 'one' -- 3, 30, 'three' -- 5, 50, 'five' -- 7, 70, 'seven' -------------------------------------------------------------------------------- CALL SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.language.bulkFetchDefault','1'); 0 rows inserted/updated/deleted ij> -- RESOLVE: missing row locks -- WORKAROUND: creating an index and dropping it -- to force the statement to be recompiled create index ix1 on a(a); 0 rows inserted/updated/deleted WARNING 01504: The new index is a duplicate of an existing index: A_IDX. ij> drop index ix1; ERROR 42X65: Index 'IX1' does not exist. ij> commit; ij> get cursor scan_cursor as 'select a from a where a = 5'; ij> call SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.language.bulkFetchDefault', '16'); 0 rows inserted/updated/deleted ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A ----------- 5 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,1) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,11) |GRANT|ACTIVE ij> next scan_cursor; No current row ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,11) |GRANT|ACTIVE ij> close scan_cursor; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,11) |GRANT|ACTIVE ij> commit; ij> -------------------------------------------------------------------------------- -- TEST 9: btree cursor scan, group fetch = 2 (scan with equals qualifier) -- Test "equals" qualified cursor scan on a data set. -- ALL MODES - TABLE IS, "scan page lockname of form (pageno, 1) -- SERIALIZABLE - row S locks as it visits each row, held until end xact -- REPEATABLE READ - row S locks as it visits each row, held until end xact -- READ COMMITTED - row S lock on current row, released on move to next row -- READ UNCOMMITTED - no row locks. -- -- At this point the base table should look like: -- 1, 10, 'one' -- 3, 30, 'three' -- 5, 50, 'five' -- 7, 70, 'seven' -------------------------------------------------------------------------------- CALL SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.language.bulkFetchDefault','2'); 0 rows inserted/updated/deleted ij> -- RESOLVE: missing row locks -- WORKAROUND: creating an index and dropping it -- to force the statement to be recompiled create index ix1 on a(a); 0 rows inserted/updated/deleted WARNING 01504: The new index is a duplicate of an existing index: A_IDX. ij> drop index ix1; ERROR 42X65: Index 'IX1' does not exist. ij> commit; ij> get cursor scan_cursor as 'select a from a where a = 5 or a = 7'; ij> call SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.language.bulkFetchDefault', '16'); 0 rows inserted/updated/deleted ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A ----------- 5 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,1) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,11) |GRANT|ACTIVE ij> next scan_cursor; A ----------- 7 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,1) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,11) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,13) |GRANT|ACTIVE ij> close scan_cursor; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,11) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,13) |GRANT|ACTIVE ij> commit; ij> -------------------------------------------------------------------------------- -- TEST 10: btree cursor scan, group fetch = 1 (equals qualifier, no rows return) -- Test "equals" qualified cursor scan on a data set, no rows returned. -- ALL MODES - TABLE IS, "scan page lockname of form (pageno, 1) -- SERIALIZABLE - row S locks as it visits each row, held until end xact -- REPEATABLE READ - row S locks as it visits each row, held until end xact -- READ COMMITTED - row S lock on current row, released on move to next row -- READ UNCOMMITTED - no row locks. -- -- At this point the base table should look like: -- 1, 10, 'one' -- 3, 30, 'three' -- 5, 50, 'five' -- 7, 70, 'seven' -------------------------------------------------------------------------------- -- no rows expected to qualify CALL SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.language.bulkFetchDefault','1'); 0 rows inserted/updated/deleted ij> -- RESOLVE: missing row locks -- WORKAROUND: creating an index and dropping it -- to force the statement to be recompiled create index ix1 on a(a); 0 rows inserted/updated/deleted WARNING 01504: The new index is a duplicate of an existing index: A_IDX. ij> drop index ix1; ERROR 42X65: Index 'IX1' does not exist. ij> commit; ij> get cursor scan_cursor as 'select a from a where a = 42'; ij> call SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.language.bulkFetchDefault', '16'); 0 rows inserted/updated/deleted ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; No current row ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; No current row ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE ij> close scan_cursor; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE ij> commit; ij> drop table a; 0 rows inserted/updated/deleted ij> -- non cursor, unique index run drop table a; ERROR 42Y55: 'DROP TABLE' cannot be performed on 'A' because it does not exist. ij> -- to create tables of page size 4k and still keep the following tbl -- create table a (a int, b int, c varchar(1900)); create table a(a int, b int); 0 rows inserted/updated/deleted ij> alter table a add column c varchar(1900); 0 rows inserted/updated/deleted ij> insert into a values (1, 10, 'one'); 1 row inserted/updated/deleted ij> insert into a values (2, 20, 'two'); 1 row inserted/updated/deleted ij> insert into a values (3, 30, 'three'); 1 row inserted/updated/deleted ij> insert into a values (4, 40, 'four'); 1 row inserted/updated/deleted ij> insert into a values (5, 50, 'five'); 1 row inserted/updated/deleted ij> insert into a values (6, 60, 'six'); 1 row inserted/updated/deleted ij> insert into a values (7, 70, 'seven'); 1 row inserted/updated/deleted ij> create unique index a_idx on a (a); 0 rows inserted/updated/deleted ij> commit; ij> run resource 'readBtreeSetLocks.subsql'; 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. -- -- Basic single user testing of read locks on select "set" queries on indexes. -- -- This ".subsql" test is -- meant to be run from another test such that it gets run under multiple -- isolation levels. This is important as they behave -- differently, depending on isolation levels. -- -- assume's caller has already done: run 'LockTableQuery.subsql'; to get -- easy access to the lock VTI. -- TEST 0: btree scan -- TEST 1: btree scan, (scan table with some deleted rows) -- TEST 2: btree scan, (scan with "<" qualifier) -- TEST 3: btree scan, (scan with equals qualifier) -- TEST 4: btree scan, (equals qualifier, no rows return) autocommit off; ij> -------------------------------------------------------------------------------- -- Assumes that calling routine has set up the following simple dataset, -- a heap, and index with following initial values: -- create table a (a int, b int, c somesortofchar, [index_pad]); -- create index a_idx on a (a) or a_idx on a (a, index_pad); -- -- 1, 10, 'one' -- 2, 20, 'two' -- 3, 30, 'three' -- 4, 40, 'four' -- 5, 50, 'five' -- 6, 60, 'six' -- 7, 70, 'seven' -------------------------------------------------------------------------------- select * from a; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 1 |10 |one 2 |20 |two 3 |30 |three 4 |40 |four 5 |50 |five 6 |60 |six 7 |70 |seven ij> commit; ij> -------------------------------------------------------------------------------- -- TEST 0: btree scan -- Test full scan. -- ALL MODES - TABLE IS, "scan page lockname of form (pageno, 1) -- SERIALIZABLE - row S locks as it visits each row, row/table lock -- held until end xact. Also holds one previous key lock. -- REPEATABLE READ - row S locks as it visits each row, row/table locks held -- until end of transaction. -- READ COMMITTED - instantaneous S locks requested on each row. No locks -- held after query finishes. -- READ UNCOMMITTED - no row locks. No locks held after query finishes. -------------------------------------------------------------------------------- select a from a; A ----------- 1 2 3 4 5 6 7 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,10) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,11) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,12) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,13) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,8) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,9) |GRANT|ACTIVE ij> commit; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> -------------------------------------------------------------------------------- -- TEST 1: btree scan, (scan table with some deleted rows) -- Test full scan on a data set with some deleted rows (the "even" ones). -- ALL MODES - TABLE IS, "scan page lockname of form (pageno, 1) -- SERIALIZABLE - row S locks as it visits each row, row/table lock -- held until end xact. Also holds one previous key lock. -- REPEATABLE READ - row S locks as it visits each row, row/table locks held -- until end of transaction. -- READ COMMITTED - instantaneous S locks requested on each row. No locks -- held after query finishes. -- READ UNCOMMITTED - no row locks. No locks held after query finishes. -- -- After the delete the base table should look like: -- 1, 10, 'one' -- 3, 30, 'three' -- 5, 50, 'five' -- 7, 70, 'seven' -------------------------------------------------------------------------------- delete from a where a = 2 or a = 4 or a = 6; 3 rows inserted/updated/deleted ij> commit; ij> -- The above delete and commit can allow post commit processing to run before -- the subsequent select is run, most likely if this run is on a table where -- there is one row per page. To get reproducible results from the subsequent -- lock calls, wait for post commit to finish before running the select. -- Without this wait "extra" locks sometimes might show up - these are locks -- on the committed deleted rows which have not been cleaned yet depending -- on timing. CALL WAIT_FOR_POST_COMMIT(); 0 rows inserted/updated/deleted ij> select a from a; A ----------- 1 3 5 7 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,11) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,13) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,9) |GRANT|ACTIVE ij> commit; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> -------------------------------------------------------------------------------- -- TEST 2: btree scan, (scan with "<" qualifier) -- Test "less than" qualified scan on a data set. -- ALL MODES - TABLE IS, "scan page lockname of form (pageno, 1) -- SERIALIZABLE - row S locks as it visits each row, row/table lock -- held until end xact. Also holds one previous key lock. -- REPEATABLE READ - row S locks as it visits each row, row/table locks held -- until end of transaction. -- READ COMMITTED - instantaneous S locks requested on each row. No locks -- held after query finishes. -- READ UNCOMMITTED - no row locks. No locks held after query finishes. -- -- At this point the base table should look like: -- 1, 10, 'one' -- 3, 30, 'three' -- 5, 50, 'five' -- 7, 70, 'seven' -------------------------------------------------------------------------------- select a from a where a < 3; A ----------- 1 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,7) |GRANT|ACTIVE ij> commit; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> -------------------------------------------------------------------------------- -- TEST 3: btree scan, (scan with equals qualifier) -- Test "equals" qualified cursor scan on a data set. -- ALL MODES - TABLE IS, "scan page lockname of form (pageno, 1) -- SERIALIZABLE - row S locks as it visits each row, row/table lock -- held until end xact. Also holds one previous key lock. -- REPEATABLE READ - row S locks as it visits each row, row/table locks held -- until end of transaction. -- READ COMMITTED - instantaneous S locks requested on each row. No locks -- held after query finishes. -- READ UNCOMMITTED - no row locks. No locks held after query finishes. -- -- At this point the base table should look like: -- 1, 10, 'one' -- 3, 30, 'three' -- 5, 50, 'five' -- 7, 70, 'seven' -------------------------------------------------------------------------------- select a from a where a = 5; A ----------- 5 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,11) |GRANT|ACTIVE ij> commit; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> -------------------------------------------------------------------------------- -- TEST 4: btree scan, (equals qualifier, no rows return) -- Test "equals" qualified scan on a data set, no rows returned. -- ALL MODES - TABLE IS, "scan page lockname of form (pageno, 1) -- SERIALIZABLE - row S locks as it visits each row, row/table lock -- held until end xact. Also holds one previous key lock. -- REPEATABLE READ - row S locks as it visits each row, row/table locks held -- until end of transaction. -- READ COMMITTED - instantaneous S locks requested on each row. No locks -- held after query finishes. -- READ UNCOMMITTED - no row locks. No locks held after query finishes. -- -- At this point the base table should look like: -- 1, 10, 'one' -- 3, 30, 'three' -- 5, 50, 'five' -- 7, 70, 'seven' -------------------------------------------------------------------------------- -- no rows expected to qualify select a from a where a = 42; A ----------- ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE ij> commit; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> drop table a; 0 rows inserted/updated/deleted ij> -- non cursor, non-unique index run drop table a; ERROR 42Y55: 'DROP TABLE' cannot be performed on 'A' because it does not exist. ij> -- to create tables of page size 4k and still keep the following tbl -- create table a (a int, b int, c varchar(1900)); create table a(a int, b int); 0 rows inserted/updated/deleted ij> alter table a add column c varchar(1900); 0 rows inserted/updated/deleted ij> insert into a values (1, 10, 'one'); 1 row inserted/updated/deleted ij> insert into a values (2, 20, 'two'); 1 row inserted/updated/deleted ij> insert into a values (3, 30, 'three'); 1 row inserted/updated/deleted ij> insert into a values (4, 40, 'four'); 1 row inserted/updated/deleted ij> insert into a values (5, 50, 'five'); 1 row inserted/updated/deleted ij> insert into a values (6, 60, 'six'); 1 row inserted/updated/deleted ij> insert into a values (7, 70, 'seven'); 1 row inserted/updated/deleted ij> create index a_idx on a (a); 0 rows inserted/updated/deleted ij> commit; ij> run resource 'readBtreeSetLocks.subsql'; 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. -- -- Basic single user testing of read locks on select "set" queries on indexes. -- -- This ".subsql" test is -- meant to be run from another test such that it gets run under multiple -- isolation levels. This is important as they behave -- differently, depending on isolation levels. -- -- assume's caller has already done: run 'LockTableQuery.subsql'; to get -- easy access to the lock VTI. -- TEST 0: btree scan -- TEST 1: btree scan, (scan table with some deleted rows) -- TEST 2: btree scan, (scan with "<" qualifier) -- TEST 3: btree scan, (scan with equals qualifier) -- TEST 4: btree scan, (equals qualifier, no rows return) autocommit off; ij> -------------------------------------------------------------------------------- -- Assumes that calling routine has set up the following simple dataset, -- a heap, and index with following initial values: -- create table a (a int, b int, c somesortofchar, [index_pad]); -- create index a_idx on a (a) or a_idx on a (a, index_pad); -- -- 1, 10, 'one' -- 2, 20, 'two' -- 3, 30, 'three' -- 4, 40, 'four' -- 5, 50, 'five' -- 6, 60, 'six' -- 7, 70, 'seven' -------------------------------------------------------------------------------- select * from a; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 1 |10 |one 2 |20 |two 3 |30 |three 4 |40 |four 5 |50 |five 6 |60 |six 7 |70 |seven ij> commit; ij> -------------------------------------------------------------------------------- -- TEST 0: btree scan -- Test full scan. -- ALL MODES - TABLE IS, "scan page lockname of form (pageno, 1) -- SERIALIZABLE - row S locks as it visits each row, row/table lock -- held until end xact. Also holds one previous key lock. -- REPEATABLE READ - row S locks as it visits each row, row/table locks held -- until end of transaction. -- READ COMMITTED - instantaneous S locks requested on each row. No locks -- held after query finishes. -- READ UNCOMMITTED - no row locks. No locks held after query finishes. -------------------------------------------------------------------------------- select a from a; A ----------- 1 2 3 4 5 6 7 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,10) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,11) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,12) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,13) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,8) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,9) |GRANT|ACTIVE ij> commit; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> -------------------------------------------------------------------------------- -- TEST 1: btree scan, (scan table with some deleted rows) -- Test full scan on a data set with some deleted rows (the "even" ones). -- ALL MODES - TABLE IS, "scan page lockname of form (pageno, 1) -- SERIALIZABLE - row S locks as it visits each row, row/table lock -- held until end xact. Also holds one previous key lock. -- REPEATABLE READ - row S locks as it visits each row, row/table locks held -- until end of transaction. -- READ COMMITTED - instantaneous S locks requested on each row. No locks -- held after query finishes. -- READ UNCOMMITTED - no row locks. No locks held after query finishes. -- -- After the delete the base table should look like: -- 1, 10, 'one' -- 3, 30, 'three' -- 5, 50, 'five' -- 7, 70, 'seven' -------------------------------------------------------------------------------- delete from a where a = 2 or a = 4 or a = 6; 3 rows inserted/updated/deleted ij> commit; ij> -- The above delete and commit can allow post commit processing to run before -- the subsequent select is run, most likely if this run is on a table where -- there is one row per page. To get reproducible results from the subsequent -- lock calls, wait for post commit to finish before running the select. -- Without this wait "extra" locks sometimes might show up - these are locks -- on the committed deleted rows which have not been cleaned yet depending -- on timing. CALL WAIT_FOR_POST_COMMIT(); 0 rows inserted/updated/deleted ij> select a from a; A ----------- 1 3 5 7 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,11) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,13) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,9) |GRANT|ACTIVE ij> commit; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> -------------------------------------------------------------------------------- -- TEST 2: btree scan, (scan with "<" qualifier) -- Test "less than" qualified scan on a data set. -- ALL MODES - TABLE IS, "scan page lockname of form (pageno, 1) -- SERIALIZABLE - row S locks as it visits each row, row/table lock -- held until end xact. Also holds one previous key lock. -- REPEATABLE READ - row S locks as it visits each row, row/table locks held -- until end of transaction. -- READ COMMITTED - instantaneous S locks requested on each row. No locks -- held after query finishes. -- READ UNCOMMITTED - no row locks. No locks held after query finishes. -- -- At this point the base table should look like: -- 1, 10, 'one' -- 3, 30, 'three' -- 5, 50, 'five' -- 7, 70, 'seven' -------------------------------------------------------------------------------- select a from a where a < 3; A ----------- 1 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,7) |GRANT|ACTIVE ij> commit; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> -------------------------------------------------------------------------------- -- TEST 3: btree scan, (scan with equals qualifier) -- Test "equals" qualified cursor scan on a data set. -- ALL MODES - TABLE IS, "scan page lockname of form (pageno, 1) -- SERIALIZABLE - row S locks as it visits each row, row/table lock -- held until end xact. Also holds one previous key lock. -- REPEATABLE READ - row S locks as it visits each row, row/table locks held -- until end of transaction. -- READ COMMITTED - instantaneous S locks requested on each row. No locks -- held after query finishes. -- READ UNCOMMITTED - no row locks. No locks held after query finishes. -- -- At this point the base table should look like: -- 1, 10, 'one' -- 3, 30, 'three' -- 5, 50, 'five' -- 7, 70, 'seven' -------------------------------------------------------------------------------- select a from a where a = 5; A ----------- 5 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,11) |GRANT|ACTIVE ij> commit; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> -------------------------------------------------------------------------------- -- TEST 4: btree scan, (equals qualifier, no rows return) -- Test "equals" qualified scan on a data set, no rows returned. -- ALL MODES - TABLE IS, "scan page lockname of form (pageno, 1) -- SERIALIZABLE - row S locks as it visits each row, row/table lock -- held until end xact. Also holds one previous key lock. -- REPEATABLE READ - row S locks as it visits each row, row/table locks held -- until end of transaction. -- READ COMMITTED - instantaneous S locks requested on each row. No locks -- held after query finishes. -- READ UNCOMMITTED - no row locks. No locks held after query finishes. -- -- At this point the base table should look like: -- 1, 10, 'one' -- 3, 30, 'three' -- 5, 50, 'five' -- 7, 70, 'seven' -------------------------------------------------------------------------------- -- no rows expected to qualify select a from a where a = 42; A ----------- ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE ij> commit; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> drop table a; 0 rows inserted/updated/deleted ij> -- run each test with rows across multiple pages in the interesting -- conglomerate (heap in the non-index tests, and in the index in the index -- based tests). -- cursor, no index run drop table a; ERROR 42Y55: 'DROP TABLE' cannot be performed on 'A' because it does not exist. ij> -- to create tables of page size 4k and still keep the following tbl -- create table a (a int, b int, c varchar(1900)); create table a(a int, b int); 0 rows inserted/updated/deleted ij> alter table a add column c varchar(1900); 0 rows inserted/updated/deleted ij> insert into a values (1, 10, PADSTRING('one', 1900)); 1 row inserted/updated/deleted ij> insert into a values (2, 20, PADSTRING('two', 1900)); 1 row inserted/updated/deleted ij> insert into a values (3, 30, PADSTRING('three', 1900)); 1 row inserted/updated/deleted ij> insert into a values (4, 40, PADSTRING('four', 1900)); 1 row inserted/updated/deleted ij> insert into a values (5, 50, PADSTRING('five', 1900)); 1 row inserted/updated/deleted ij> insert into a values (6, 60, PADSTRING('six', 1900)); 1 row inserted/updated/deleted ij> insert into a values (7, 70, PADSTRING('seven', 1900)); 1 row inserted/updated/deleted ij> commit; ij> run resource 'readCursorLocks.subsql'; 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. -- -- Very basic single user testing of read locks on cursors on heap tables. -- This ".subsql" test is -- meant to be run from another test such that it gets run under multiple -- isolation levels. This is important as they behave -- differently, depending on isolation levels. -- -- assume's caller has already done: run 'LockTableQuery.subsql'; to get -- easy access to the lock VTI. -- TEST 0: heap cursor scan, group fetch = 1 -- TEST 1: heap cursor scan, group fetch = 2 -- TEST 2: heap cursor scan, group fetch = 1, stop scan in middle of set -- TEST 3: heap cursor scan, group fetch = 4, stop scan in middle of set -- TEST 4: heap cursor scan, group fetch = 1 (scan table with some deleted rows) -- TEST 5: heap cursor scan, group fetch = 2 (scan with committed deleted rows) -- TEST 6: heap cursor scan, group fetch = 1 (scan with "<" qualifier) -- TEST 7: heap cursor scan, group fetch = 2 (scan with "<" qualifier) -- TEST 8: heap cursor scan, group fetch = 1 (scan with equals qualifier) -- TEST 9: heap cursor scan, group fetch = 2 (scan with equals qualifier) -- TEST 10: heap cursor scan, group fetch = 1 (equals qualifier, no rows return) autocommit off; ij> -------------------------------------------------------------------------------- -- Assumes that calling routine has set up the following simple dataset, -- a heap, no indexes with following initial values: -- create table (a int, b int, c somesortofchar); -- 1, 10, 'one' -- 2, 20, 'two' -- 3, 30, 'three' -- 4, 40, 'four' -- 5, 50, 'five' -- 6, 60, 'six' -- 7, 70, 'seven' -------------------------------------------------------------------------------- select * from a; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 1 |10 |one & 2 |20 |two & 3 |30 |three & 4 |40 |four & 5 |50 |five & 6 |60 |six & 7 |70 |seven & ij> commit; ij> -------------------------------------------------------------------------------- -- TEST 0: heap cursor scan, group fetch = 1 -- Test full cursor scan which does no updates. -- SERIALIZABLE - will get table level S lock. -- REPEATABLE READ - TABLE IS, will get row S locks as it visits each row. -- READ COMMITTED - TABLE IS, will hold single S lock on current row. -- READ UNCOMMITTED - TABLE IS, no row locks. -------------------------------------------------------------------------------- CALL SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.language.bulkFetchDefault','1'); 0 rows inserted/updated/deleted ij> get cursor scan_cursor as 'select a, b, c from a'; ij> call SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.language.bulkFetchDefault', '16'); 0 rows inserted/updated/deleted ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 1 |10 |one & ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,7) |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 2 |20 |two & ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,8) |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 3 |30 |three & ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,8) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(2,6) |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 4 |40 |four & ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,8) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(2,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(2,7) |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 5 |50 |five & ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,8) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(2,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(2,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(3,6) |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 6 |60 |six & ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,8) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(2,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(2,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(3,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(3,7) |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 7 |70 |seven & ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,8) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(2,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(2,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(3,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(3,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(4,6) |GRANT|ACTIVE ij> next scan_cursor; No current row ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,8) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(2,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(2,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(3,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(3,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(4,6) |GRANT|ACTIVE ij> close scan_cursor; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,8) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(2,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(2,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(3,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(3,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(4,6) |GRANT|ACTIVE ij> commit; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> -------------------------------------------------------------------------------- -- TEST 1: heap cursor scan, group fetch = 2 -- Test full cursor scan which does no updates. -- SERIALIZABLE - will get table level S lock. -- REPEATABLE READ - TABLE IS, will get row S locks as it visits each row. -- READ COMMITTED - TABLE IS, will get instantaneous locks and release -- READ UNCOMMITTED - TABLE IS, no row locks. -------------------------------------------------------------------------------- CALL SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.language.bulkFetchDefault','2'); 0 rows inserted/updated/deleted ij> -- RESOLVE: missing row locks -- WORKAROUND: creating an index and dropping it -- to force the query 'select a, b, c from a' to be recompiled create index ix1 on a(a); 0 rows inserted/updated/deleted ij> drop index ix1; 0 rows inserted/updated/deleted ij> commit; ij> get cursor scan_cursor as 'select a, b, c from a'; ij> call SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.language.bulkFetchDefault', '16'); 0 rows inserted/updated/deleted ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 1 |10 |one & ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,8) |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 2 |20 |two & ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,8) |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 3 |30 |three & ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,8) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(2,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(2,7) |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 4 |40 |four & ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,8) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(2,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(2,7) |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 5 |50 |five & ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,8) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(2,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(2,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(3,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(3,7) |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 6 |60 |six & ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,8) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(2,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(2,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(3,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(3,7) |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 7 |70 |seven & ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,8) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(2,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(2,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(3,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(3,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(4,6) |GRANT|ACTIVE ij> next scan_cursor; No current row ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,8) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(2,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(2,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(3,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(3,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(4,6) |GRANT|ACTIVE ij> close scan_cursor; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,8) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(2,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(2,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(3,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(3,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(4,6) |GRANT|ACTIVE ij> commit; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> -------------------------------------------------------------------------------- -- TEST 2: heap cursor scan, group fetch = 1, stop scan in middle of set -- Test full cursor scan which does no updates. -- SERIALIZABLE - will get table level S lock. -- REPEATABLE READ - TABLE IS, will get row S locks as it visits each row. -- READ COMMITTED - TABLE IS, will hold single S lock on current row. -- READ UNCOMMITTED - TABLE IS, no row locks. -------------------------------------------------------------------------------- CALL SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.language.bulkFetchDefault','1'); 0 rows inserted/updated/deleted ij> -- RESOLVE: missing row locks -- WORKAROUND: creating an index and dropping it -- to force the query 'select a, b, c from a' to be recompiled create index ix1 on a(a); 0 rows inserted/updated/deleted ij> drop index ix1; 0 rows inserted/updated/deleted ij> commit; ij> get cursor scan_cursor as 'select a, b, c from a'; ij> call SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.language.bulkFetchDefault', '16'); 0 rows inserted/updated/deleted ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 1 |10 |one & ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,7) |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 2 |20 |two & ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,8) |GRANT|ACTIVE ij> close scan_cursor; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,8) |GRANT|ACTIVE ij> commit; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> -------------------------------------------------------------------------------- -- TEST 3: heap cursor scan, group fetch = 4, stop scan in middle of set -- Test full cursor scan which does no updates. -- SERIALIZABLE - will get table level S lock. -- REPEATABLE READ - TABLE IS, will get row S locks as it visits each row. -- READ COMMITTED - TABLE IS, will hold single S lock on current row. -- READ UNCOMMITTED - TABLE IS, no row locks. -------------------------------------------------------------------------------- CALL SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.language.bulkFetchDefault','4'); 0 rows inserted/updated/deleted ij> -- RESOLVE: missing row locks -- WORKAROUND: creating an index and dropping it -- to force the query 'select a, b, c from a' to be recompiled create index ix1 on a(a); 0 rows inserted/updated/deleted ij> drop index ix1; 0 rows inserted/updated/deleted ij> commit; ij> get cursor scan_cursor as 'select a, b, c from a'; ij> call SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.language.bulkFetchDefault', '16'); 0 rows inserted/updated/deleted ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 1 |10 |one & ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,8) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(2,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(2,7) |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 2 |20 |two & ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,8) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(2,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(2,7) |GRANT|ACTIVE ij> close scan_cursor; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,8) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(2,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(2,7) |GRANT|ACTIVE ij> commit; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> -------------------------------------------------------------------------------- -- TEST 4: heap cursor scan, group fetch = 1 (scan table with some deleted rows) -- Test full cursor scan on a data set with some deleted rows (the "even" ones). -- SERIALIZABLE - will get table level S lock. -- REPEATABLE READ - TABLE IS, will get row S locks as it visits each row -- (including deleted ones). -- READ COMMITTED - TABLE IS, will get instantaneous locks and release -- READ UNCOMMITTED - TABLE IS, no row locks. -- -- After the delete the table should look like: -- 1, 10, 'one' -- 3, 30, 'three' -- 5, 50, 'five' -- 7, 70, 'seven' -------------------------------------------------------------------------------- delete from a where a = 2 or a = 4 or a = 6; 3 rows inserted/updated/deleted ij> commit; ij> CALL SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.language.bulkFetchDefault','1'); 0 rows inserted/updated/deleted ij> -- RESOLVE: missing row locks -- WORKAROUND: creating an index and dropping it -- to force the query 'select a, b, c from a' to be recompiled create index ix1 on a(a); 0 rows inserted/updated/deleted ij> drop index ix1; 0 rows inserted/updated/deleted ij> commit; ij> get cursor scan_cursor as 'select a, b, c from a'; ij> call SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.language.bulkFetchDefault', '16'); 0 rows inserted/updated/deleted ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 1 |10 |one & ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,7) |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 3 |30 |three & ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(2,6) |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 5 |50 |five & ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(2,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(3,6) |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 7 |70 |seven & ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(2,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(3,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(4,6) |GRANT|ACTIVE ij> next scan_cursor; No current row ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(2,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(3,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(4,6) |GRANT|ACTIVE ij> close scan_cursor; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(2,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(3,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(4,6) |GRANT|ACTIVE ij> commit; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> -------------------------------------------------------------------------------- -- TEST 5: heap cursor scan, group fetch = 2 (scan with committed deleted rows) -- Test full cursor scan on a data set with some deleted rows (the "even" ones). -- SERIALIZABLE - will get table level S lock. -- REPEATABLE READ - TABLE IS, will get row S locks as it visits each row -- (including deleted ones). -- READ COMMITTED - TABLE IS, will get instantaneous locks and release -- READ UNCOMMITTED - TABLE IS, no row locks. -- -- At this point the table should look like: -- 1, 10, 'one' -- 3, 30, 'three' -- 5, 50, 'five' -- 7, 70, 'seven' -------------------------------------------------------------------------------- CALL SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.language.bulkFetchDefault','2'); 0 rows inserted/updated/deleted ij> -- RESOLVE: missing row locks -- WORKAROUND: creating an index and dropping it -- to force the query 'select a, b, c from a' to be recompiled create index ix1 on a(a); 0 rows inserted/updated/deleted ij> drop index ix1; 0 rows inserted/updated/deleted ij> commit; ij> get cursor scan_cursor as 'select a, b, c from a'; ij> call SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.language.bulkFetchDefault', '16'); 0 rows inserted/updated/deleted ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 1 |10 |one & ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(2,6) |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 3 |30 |three & ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(2,6) |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 5 |50 |five & ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(2,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(3,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(4,6) |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 7 |70 |seven & ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(2,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(3,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(4,6) |GRANT|ACTIVE ij> next scan_cursor; No current row ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(2,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(3,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(4,6) |GRANT|ACTIVE ij> close scan_cursor; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(2,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(3,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(4,6) |GRANT|ACTIVE ij> commit; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> -------------------------------------------------------------------------------- -- TEST 6: heap cursor scan, group fetch = 1 (scan with "<" qualifier) -- Test "less than" qualified cursor scan on a data set. -- SERIALIZABLE - will get table level S lock. -- REPEATABLE READ - TABLE IS, will get row S locks as it visits each row -- (including deleted ones). -- READ COMMITTED - TABLE IS, will get instantaneous locks and release -- READ UNCOMMITTED - TABLE IS, no row locks. -- -- At this point the table should look like: -- 1, 10, 'one' -- 3, 30, 'three' -- 5, 50, 'five' -- 7, 70, 'seven' -------------------------------------------------------------------------------- CALL SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.language.bulkFetchDefault','1'); 0 rows inserted/updated/deleted ij> get cursor scan_cursor as 'select a, b, c from a where a < 3'; ij> call SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.language.bulkFetchDefault', '16'); 0 rows inserted/updated/deleted ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 1 |10 |one & ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,7) |GRANT|ACTIVE ij> next scan_cursor; No current row ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,7) |GRANT|ACTIVE ij> close scan_cursor; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,7) |GRANT|ACTIVE ij> commit; ij> -------------------------------------------------------------------------------- -- TEST 7: heap cursor scan, group fetch = 2 (scan with "<" qualifier) -- Test "less than" qualified cursor scan on a data set. -- SERIALIZABLE - will get table level S lock. -- REPEATABLE READ - TABLE IS, will get row S locks as it visits each row -- (including deleted ones). -- READ COMMITTED - TABLE IS, will get instantaneous locks and release -- READ UNCOMMITTED - TABLE IS, no row locks. -- -- At this point the table should look like: -- 1, 10, 'one' -- 3, 30, 'three' -- 5, 50, 'five' -- 7, 70, 'seven' -------------------------------------------------------------------------------- CALL SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.language.bulkFetchDefault','2'); 0 rows inserted/updated/deleted ij> -- RESOLVE: missing row locks -- WORKAROUND: creating an index and dropping it -- to force the statement to be recompiled create index ix1 on a(a); 0 rows inserted/updated/deleted ij> drop index ix1; 0 rows inserted/updated/deleted ij> commit; ij> get cursor scan_cursor as 'select a, b, c from a where a < 3'; ij> call SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.language.bulkFetchDefault', '16'); 0 rows inserted/updated/deleted ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 1 |10 |one & ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,7) |GRANT|ACTIVE ij> next scan_cursor; No current row ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,7) |GRANT|ACTIVE ij> close scan_cursor; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,7) |GRANT|ACTIVE ij> commit; ij> -------------------------------------------------------------------------------- -- TEST 8: heap cursor scan, group fetch = 1 (scan with equals qualifier) -- Test "equals" qualified cursor scan on a data set. -- SERIALIZABLE - will get table level S lock. -- REPEATABLE READ - TABLE IS, will get row S locks as it visits each row -- (including deleted ones). -- READ COMMITTED - TABLE IS, will get instantaneous locks and release -- READ UNCOMMITTED - TABLE IS, no row locks. -- -- At this point the table should look like: -- 1, 10, 'one' -- 3, 30, 'three' -- 5, 50, 'five' -- 7, 70, 'seven' -------------------------------------------------------------------------------- CALL SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.language.bulkFetchDefault','1'); 0 rows inserted/updated/deleted ij> get cursor scan_cursor as 'select a, b, c from a where a = 5'; ij> call SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.language.bulkFetchDefault', '16'); 0 rows inserted/updated/deleted ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 5 |50 |five & ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(3,6) |GRANT|ACTIVE ij> next scan_cursor; No current row ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(3,6) |GRANT|ACTIVE ij> close scan_cursor; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(3,6) |GRANT|ACTIVE ij> commit; ij> -------------------------------------------------------------------------------- -- TEST 9: heap cursor scan, group fetch = 2 (scan with equals qualifier) -- Test "equals" qualified cursor scan on a data set. -- SERIALIZABLE - will get table level S lock. -- REPEATABLE READ - TABLE IS, will get row S locks as it visits each row -- (including deleted ones). -- READ COMMITTED - TABLE IS, will get instantaneous locks and release -- READ UNCOMMITTED - TABLE IS, no row locks. -- -- At this point the table should look like: -- 1, 10, 'one' -- 3, 30, 'three' -- 5, 50, 'five' -- 7, 70, 'seven' -------------------------------------------------------------------------------- CALL SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.language.bulkFetchDefault','2'); 0 rows inserted/updated/deleted ij> get cursor scan_cursor as 'select a, b, c from a where a = 7'; ij> call SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.language.bulkFetchDefault', '16'); 0 rows inserted/updated/deleted ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 7 |70 |seven & ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(4,6) |GRANT|ACTIVE ij> next scan_cursor; No current row ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(4,6) |GRANT|ACTIVE ij> close scan_cursor; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(4,6) |GRANT|ACTIVE ij> commit; ij> -------------------------------------------------------------------------------- -- TEST 10: heap cursor scan, group fetch = 1 (equals qualifier, no rows return) -- Test "equals" qualified cursor scan on a data set, no rows returned. -- SERIALIZABLE - will get table level S lock. -- REPEATABLE READ - TABLE IS, will get row S locks as it visits each row -- (including deleted ones). -- READ COMMITTED - TABLE IS, will get instantaneous locks and release -- READ UNCOMMITTED - TABLE IS, no row locks. -- -- At this point the table should look like: -- 1, 10, 'one' -- 3, 30, 'three' -- 5, 50, 'five' -- 7, 70, 'seven' -------------------------------------------------------------------------------- CALL SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.language.bulkFetchDefault','1'); 0 rows inserted/updated/deleted ij> -- RESOLVE: missing row locks -- WORKAROUND: creating an index and dropping it -- to force the statement to be recompiled create index ix1 on a(a); 0 rows inserted/updated/deleted ij> drop index ix1; 0 rows inserted/updated/deleted ij> commit; ij> get cursor scan_cursor as 'select a, b, c from a where a = 7'; ij> CALL SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.language.bulkFetchDefault','16'); 0 rows inserted/updated/deleted ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 7 |70 |seven & ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(4,6) |GRANT|ACTIVE ij> next scan_cursor; No current row ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(4,6) |GRANT|ACTIVE ij> close scan_cursor; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(4,6) |GRANT|ACTIVE ij> commit; ij> drop table a; 0 rows inserted/updated/deleted ij> -- non cursor, no index run drop table a; ERROR 42Y55: 'DROP TABLE' cannot be performed on 'A' because it does not exist. ij> -- to create tables of page size 4k and still keep the following tbl -- create table a (a int, b int, c varchar(1900)); create table a(a int, b int); 0 rows inserted/updated/deleted ij> alter table a add column c varchar(1900); 0 rows inserted/updated/deleted ij> insert into a values (1, 10, PADSTRING('one', 1900)); 1 row inserted/updated/deleted ij> insert into a values (2, 20, PADSTRING('two', 1900)); 1 row inserted/updated/deleted ij> insert into a values (3, 30, PADSTRING('three', 1900)); 1 row inserted/updated/deleted ij> insert into a values (4, 40, PADSTRING('four', 1900)); 1 row inserted/updated/deleted ij> insert into a values (5, 50, PADSTRING('five', 1900)); 1 row inserted/updated/deleted ij> insert into a values (6, 60, PADSTRING('six', 1900)); 1 row inserted/updated/deleted ij> insert into a values (7, 70, PADSTRING('seven', 1900)); 1 row inserted/updated/deleted ij> commit; ij> run resource 'readSetLocks.subsql'; 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. -- -- Very basic single user testing of read locks in "set" queries on heap tables. -- This ".subsql" test is -- meant to be run from another test such that it gets run under multiple -- isolation levels. This is important as they behave -- differently, depending on isolation levels. -- -- assume's caller has already done: run 'LockTableQuery.subsql'; to get -- easy access to the lock VTI. -- TEST 0: heap scan. -- TEST 1: heap scan, some rows deleted. -- TEST 2: heap scan, (scan with "<" qualifier) -- TEST 3: heap scan, (scan with equals qualifier) -- TEST 4: heap scan, (equals qualifier, no rows return) autocommit off; ij> -------------------------------------------------------------------------------- -- Assumes that calling routine has set up the following simple dataset, -- a heap, no indexes with following initial values: -- create table (a int, b int, c somesortofchar); -- 1, 10, 'one' -- 2, 20, 'two' -- 3, 30, 'three' -- 4, 40, 'four' -- 5, 50, 'five' -- 6, 60, 'six' -- 7, 70, 'seven' -------------------------------------------------------------------------------- select * from a; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 1 |10 |one & 2 |20 |two & 3 |30 |three & 4 |40 |four & 5 |50 |five & 6 |60 |six & 7 |70 |seven & ij> commit; ij> -------------------------------------------------------------------------------- -- TEST 0: heap scan. -- Test full cursor scan which does no updates. -- SERIALIZABLE - will get table level S lock, held to end of xact. -- REPEATABLE READ - TABLE IS, will get row S locks as it visits each row -- (including deleted ones). held to end of xact. -- READ COMMITTED - TABLE IS, will get instantaneous locks and release. No -- locks held when statement completes. -- READ UNCOMMITTED - TABLE IS, no row locks. No locks after statement ends. -------------------------------------------------------------------------------- select a, b, c from a; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 1 |10 |one & 2 |20 |two & 3 |30 |three & 4 |40 |four & 5 |50 |five & 6 |60 |six & 7 |70 |seven & ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,8) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(2,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(2,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(3,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(3,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(4,6) |GRANT|ACTIVE ij> commit; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> -------------------------------------------------------------------------------- -- TEST 1: heap scan, some rows deleted. -- Test full cursor scan on a data set with some deleted rows (the "even" ones). -- SERIALIZABLE - will get table level S lock. -- REPEATABLE READ - TABLE IS, will get row S locks as it visits each row -- (including deleted ones). -- READ COMMITTED - TABLE IS, will get instantaneous locks and release -- READ UNCOMMITTED - TABLE IS, no row locks. -- SERIALIZABLE - will get table level S lock, held to end of xact. -- REPEATABLE READ - TABLE IS, will get row S locks as it visits each row -- (including deleted ones). held to end of xact. -- READ COMMITTED - TABLE IS, will get instantaneous locks and release. No -- locks held when statement completes. -- READ UNCOMMITTED - TABLE IS, no row locks. No locks after statement ends. -- -- After the delete the table should look like: -- 1, 10, 'one' -- 3, 30, 'three' -- 5, 50, 'five' -- 7, 70, 'seven' -------------------------------------------------------------------------------- delete from a where a = 2 or a = 4 or a = 6; 3 rows inserted/updated/deleted ij> commit; ij> select a, b, c from a; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 1 |10 |one & 3 |30 |three & 5 |50 |five & 7 |70 |seven & ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(2,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(3,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(4,6) |GRANT|ACTIVE ij> commit; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> -------------------------------------------------------------------------------- -- TEST 2: heap scan, (scan with "<" qualifier) -- Test "less than" qualified cursor scan on a data set. -- SERIALIZABLE - will get table level S lock, held to end of xact. -- REPEATABLE READ - TABLE IS, will get row S locks as it visits each row -- (including deleted ones). held to end of xact. -- READ COMMITTED - TABLE IS, will get instantaneous locks and release. No -- locks held when statement completes. -- READ UNCOMMITTED - TABLE IS, no row locks. No locks after statement ends. -- -- At this point the table should look like: -- 1, 10, 'one' -- 3, 30, 'three' -- 5, 50, 'five' -- 7, 70, 'seven' -------------------------------------------------------------------------------- select a, b, c from a; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 1 |10 |one & 3 |30 |three & 5 |50 |five & 7 |70 |seven & ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(2,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(3,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(4,6) |GRANT|ACTIVE ij> commit; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> -------------------------------------------------------------------------------- -- TEST 3: heap scan, (scan with equals qualifier) -- Test "equals" qualified cursor scan on a data set. -- SERIALIZABLE - will get table level S lock, held to end of xact. -- REPEATABLE READ - TABLE IS, will get row S locks as it visits each row -- (including deleted ones). held to end of xact. -- READ COMMITTED - TABLE IS, will get instantaneous locks and release. No -- locks held when statement completes. -- READ UNCOMMITTED - TABLE IS, no row locks. No locks after statement ends. -- -- At this point the table should look like: -- 1, 10, 'one' -- 3, 30, 'three' -- 5, 50, 'five' -- 7, 70, 'seven' -------------------------------------------------------------------------------- select a, b, c from a where a = 5; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 5 |50 |five & ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(3,6) |GRANT|ACTIVE ij> commit; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> -------------------------------------------------------------------------------- -- TEST 4: heap scan, (equals qualifier, no rows return) -- Test "equals" qualified cursor scan on a data set, no rows returned. -- SERIALIZABLE - will get table level S lock, held to end of xact. -- REPEATABLE READ - TABLE IS, will get row S locks as it visits each row -- (including deleted ones). held to end of xact. -- READ COMMITTED - TABLE IS, will get instantaneous locks and release. No -- locks held when statement completes. -- READ UNCOMMITTED - TABLE IS, no row locks. No locks after statement ends. -- -- At this point the table should look like: -- 1, 10, 'one' -- 3, 30, 'three' -- 5, 50, 'five' -- 7, 70, 'seven' -------------------------------------------------------------------------------- select a, b, c from a where a = 7; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 7 |70 |seven & ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(4,6) |GRANT|ACTIVE ij> commit; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> drop table a; 0 rows inserted/updated/deleted ij> -- cursor, unique index run drop table a; ERROR 42Y55: 'DROP TABLE' cannot be performed on 'A' because it does not exist. ij> create table a (a int, b int, c varchar(1900), index_pad varchar(600) ) ; 0 rows inserted/updated/deleted ij> insert into a values (1, 10, PADSTRING('one', 1900), PADSTRING('index pad 1',600)); 1 row inserted/updated/deleted ij> insert into a values (2, 20, PADSTRING('two', 1900), PADSTRING('index pad 2',600)); 1 row inserted/updated/deleted ij> insert into a values (3, 30, PADSTRING('three', 1900), PADSTRING('index pad 3',600)); 1 row inserted/updated/deleted ij> insert into a values (4, 40, PADSTRING('four', 1900), PADSTRING('index pad 4',600)); 1 row inserted/updated/deleted ij> insert into a values (5, 50, PADSTRING('five', 1900), PADSTRING('index pad 5',600)); 1 row inserted/updated/deleted ij> insert into a values (6, 60, PADSTRING('six', 1900), PADSTRING('index pad 6',600)); 1 row inserted/updated/deleted ij> insert into a values (7, 70, PADSTRING('seven', 1900), PADSTRING('index pad 7',600)); 1 row inserted/updated/deleted ij> create unique index a_idx on a (a, index_pad) ; 0 rows inserted/updated/deleted ij> commit; ij> run resource 'readBtreeCursorLocks.subsql'; 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. -- -- Very basic single user testing of read locks on cursors on indexes. -- This ".subsql" test is -- meant to be run from another test such that it gets run under multiple -- isolation levels. This is important as they behave -- differently, depending on isolation levels. -- -- assume's caller has already done: run 'LockTableQuery.subsql'; to get -- easy access to the lock VTI. -- TEST 0: btree cursor scan, group fetch = 1 -- TEST 1: btree cursor scan, group fetch = 2 -- TEST 2: btree cursor scan, group fetch = 1 stop scan in middle of set -- TEST 3: btree cursor scan, group fetch = 4 stop scan in middle of set -- TEST 4: btree cursor scan, group fetch = 1 (scan with some deleted rows) -- TEST 5: btree cursor scan, group fetch = 2(scan with committed deleted rows) -- TEST 6: btree cursor scan, group fetch = 1 (scan with "<" qualifier) -- TEST 7: btree cursor scan, group fetch = 2 (scan with "<" qualifier) -- TEST 8: btree cursor scan, group fetch = 1 (scan with equals qualifier) -- TEST 9: btree cursor scan, group fetch = 2 (scan with equals qualifier) -- TEST 10: btree cursor scan, group fetch = 1 ("=" qualifier, no rows return) autocommit off; ij> -------------------------------------------------------------------------------- -- Assumes that calling routine has set up the following simple dataset, -- a heap, and index with following initial values: -- create table a (a int, b int, c somesortofchar, [index_pad]); -- create index a_idx on a (a) or a_idx on a (a, index_pad); -- -- 1, 10, 'one' -- 2, 20, 'two' -- 3, 30, 'three' -- 4, 40, 'four' -- 5, 50, 'five' -- 6, 60, 'six' -- 7, 70, 'seven' -------------------------------------------------------------------------------- select * from a; A |B |C |INDEX_PAD ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- 1 |10 |one &|index pad 1 & 2 |20 |two &|index pad 2 & 3 |30 |three &|index pad 3 & 4 |40 |four &|index pad 4 & 5 |50 |five &|index pad 5 & 6 |60 |six &|index pad 6 & 7 |70 |seven &|index pad 7 & ij> commit; ij> -------------------------------------------------------------------------------- -- TEST 0: btree cursor scan, group fetch = 1 -- Test full cursor scan which does no updates. -- ALL MODES - TABLE IS, "scan page lockname of form (pageno, 1) -- SERIALIZABLE - row S locks as it visits each row, held until end xact -- REPEATABLE READ - row S locks as it visits each row, held until end xact -- READ COMMITTED - row S lock on current row, released on move to next row -- READ UNCOMMITTED - no row locks. ------------------------------------------------------------------------------- CALL SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.language.bulkFetchDefault','1'); 0 rows inserted/updated/deleted ij> -- RESOLVE: missing row locks -- WORKAROUND: creating an index and dropping it -- to force the statement to be recompiled create index ix1 on a(a); 0 rows inserted/updated/deleted ij> drop index ix1; 0 rows inserted/updated/deleted ij> commit; ij> get cursor scan_cursor as 'select a from a'; ij> call SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.language.bulkFetchDefault', '16'); 0 rows inserted/updated/deleted ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A ----------- 1 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(2,1) |GRANT|ACTIVE ij> next scan_cursor; A ----------- 2 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(2,1) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(2,6) |GRANT|ACTIVE ij> next scan_cursor; A ----------- 3 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(2,1) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(2,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(3,6) |GRANT|ACTIVE ij> next scan_cursor; A ----------- 4 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(2,1) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(2,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(3,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(4,6) |GRANT|ACTIVE ij> next scan_cursor; A ----------- 5 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(2,1) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(2,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(3,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(4,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(5,6) |GRANT|ACTIVE ij> next scan_cursor; A ----------- 6 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(2,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(3,1) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(3,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(4,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(5,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(6,6) |GRANT|ACTIVE ij> next scan_cursor; A ----------- 7 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(2,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(3,1) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(3,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(4,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(5,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(6,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(7,6) |GRANT|ACTIVE ij> next scan_cursor; No current row ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(2,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(3,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(4,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(5,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(6,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(7,6) |GRANT|ACTIVE ij> close scan_cursor; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(2,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(3,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(4,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(5,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(6,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(7,6) |GRANT|ACTIVE ij> commit; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> -------------------------------------------------------------------------------- -- TEST 1: btree cursor scan, group fetch = 2 -- Test full cursor scan which does no updates. -- ALL MODES - TABLE IS, "scan page lockname of form (pageno, 1) -- SERIALIZABLE - row S locks as it visits each row, held until end xact -- REPEATABLE READ - row S locks as it visits each row, held until end xact -- READ COMMITTED - row S lock on current row, released on move to next row -- READ UNCOMMITTED - no row locks. -------------------------------------------------------------------------------- CALL SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.language.bulkFetchDefault','2'); 0 rows inserted/updated/deleted ij> -- RESOLVE: missing row locks -- WORKAROUND: creating an index and dropping it -- to force the statement to be recompiled create index ix1 on a(a); 0 rows inserted/updated/deleted ij> drop index ix1; 0 rows inserted/updated/deleted ij> commit; ij> get cursor scan_cursor as 'select a from a'; ij> call SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.language.bulkFetchDefault', '16'); 0 rows inserted/updated/deleted ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A ----------- 1 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(2,1) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(2,6) |GRANT|ACTIVE ij> next scan_cursor; A ----------- 2 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(2,1) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(2,6) |GRANT|ACTIVE ij> next scan_cursor; A ----------- 3 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(2,1) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(2,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(3,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(4,6) |GRANT|ACTIVE ij> next scan_cursor; A ----------- 4 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(2,1) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(2,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(3,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(4,6) |GRANT|ACTIVE ij> next scan_cursor; A ----------- 5 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(2,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(3,1) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(3,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(4,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(5,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(6,6) |GRANT|ACTIVE ij> next scan_cursor; A ----------- 6 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(2,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(3,1) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(3,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(4,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(5,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(6,6) |GRANT|ACTIVE ij> next scan_cursor; A ----------- 7 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(2,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(3,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(4,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(5,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(6,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(7,6) |GRANT|ACTIVE ij> next scan_cursor; No current row ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(2,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(3,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(4,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(5,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(6,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(7,6) |GRANT|ACTIVE ij> close scan_cursor; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(2,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(3,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(4,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(5,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(6,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(7,6) |GRANT|ACTIVE ij> commit; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> -------------------------------------------------------------------------------- -- TEST 2: btree cursor scan, group fetch = 1, stop scan in middle of set -- Test full cursor scan which does no updates. -- ALL MODES - TABLE IS, "scan page lockname of form (pageno, 1) -- SERIALIZABLE - row S locks as it visits each row, held until end xact -- REPEATABLE READ - row S locks as it visits each row, held until end xact -- READ COMMITTED - row S lock on current row, released on move to next row -- READ UNCOMMITTED - no row locks. -------------------------------------------------------------------------------- CALL SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.language.bulkFetchDefault','1'); 0 rows inserted/updated/deleted ij> -- RESOLVE: missing row locks -- WORKAROUND: creating an index and dropping it -- to force the statement to be recompiled create index ix1 on a(a); 0 rows inserted/updated/deleted ij> drop index ix1; 0 rows inserted/updated/deleted ij> commit; ij> get cursor scan_cursor as 'select a from a'; ij> call SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.language.bulkFetchDefault', '16'); 0 rows inserted/updated/deleted ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A ----------- 1 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(2,1) |GRANT|ACTIVE ij> next scan_cursor; A ----------- 2 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(2,1) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(2,6) |GRANT|ACTIVE ij> close scan_cursor; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(2,6) |GRANT|ACTIVE ij> commit; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> -------------------------------------------------------------------------------- -- TEST 3: btree cursor scan, group fetch = 4, stop scan in middle of set -- Test full cursor scan which does no updates. -- ALL MODES - TABLE IS, "scan page lockname of form (pageno, 1) -- SERIALIZABLE - row S locks as it visits each row, held until end xact -- REPEATABLE READ - row S locks as it visits each row, held until end xact -- READ COMMITTED - row S lock on current row, released on move to next row -- READ UNCOMMITTED - no row locks. -------------------------------------------------------------------------------- CALL SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.language.bulkFetchDefault','4'); 0 rows inserted/updated/deleted ij> -- RESOLVE: missing row locks -- WORKAROUND: creating an index and dropping it -- to force the statement to be recompiled create index ix1 on a(a); 0 rows inserted/updated/deleted ij> drop index ix1; 0 rows inserted/updated/deleted ij> commit; ij> get cursor scan_cursor as 'select a from a'; ij> call SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.language.bulkFetchDefault', '16'); 0 rows inserted/updated/deleted ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A ----------- 1 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(2,1) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(2,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(3,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(4,6) |GRANT|ACTIVE ij> next scan_cursor; A ----------- 2 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(2,1) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(2,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(3,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(4,6) |GRANT|ACTIVE ij> close scan_cursor; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(2,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(3,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(4,6) |GRANT|ACTIVE ij> commit; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> -------------------------------------------------------------------------------- -- TEST 4: btree cursor scan, group fetch = 1 (scan table with some deleted rows) -- Test full cursor scan on a data set with some deleted rows (the "even" ones). -- ALL MODES - TABLE IS, "scan page lockname of form (pageno, 1) -- SERIALIZABLE - row S locks as it visits each row, held until end xact -- REPEATABLE READ - row S locks as it visits each row, held until end xact -- READ COMMITTED - row S lock on current row, released on move to next row -- READ UNCOMMITTED - no row locks. -- -- After the delete the base table should look like: -- 1, 10, 'one' -- 3, 30, 'three' -- 5, 50, 'five' -- 7, 70, 'seven' -------------------------------------------------------------------------------- delete from a where a = 2 or a = 4 or a = 6; 3 rows inserted/updated/deleted ij> commit; ij> CALL SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.language.bulkFetchDefault','1'); 0 rows inserted/updated/deleted ij> -- RESOLVE: missing row locks -- WORKAROUND: creating an index and dropping it -- to force the statement to be recompiled create index ix1 on a(a); 0 rows inserted/updated/deleted ij> drop index ix1; 0 rows inserted/updated/deleted ij> commit; ij> get cursor scan_cursor as 'select a from a'; ij> call SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.language.bulkFetchDefault', '16'); 0 rows inserted/updated/deleted ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A ----------- 1 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(2,1) |GRANT|ACTIVE ij> next scan_cursor; A ----------- 3 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(2,1) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(3,6) |GRANT|ACTIVE ij> next scan_cursor; A ----------- 5 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(2,1) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(3,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(5,6) |GRANT|ACTIVE ij> next scan_cursor; A ----------- 7 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(3,1) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(3,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(5,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(7,6) |GRANT|ACTIVE ij> next scan_cursor; No current row ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(3,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(5,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(7,6) |GRANT|ACTIVE ij> close scan_cursor; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(3,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(5,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(7,6) |GRANT|ACTIVE ij> commit; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> -------------------------------------------------------------------------------- -- TEST 5: btree cursor scan, group fetch = 2 (scan with committed deleted rows) -- Test full cursor scan on a data set with some deleted rows (the "even" ones). -- ALL MODES - TABLE IS, "scan page lockname of form (pageno, 1) -- SERIALIZABLE - row S locks as it visits each row, held until end xact -- REPEATABLE READ - row S locks as it visits each row, held until end xact -- READ COMMITTED - row S lock on current row, released on move to next row -- READ UNCOMMITTED - no row locks. -- -- At this point the base table should look like: -- 1, 10, 'one' -- 3, 30, 'three' -- 5, 50, 'five' -- 7, 70, 'seven' -------------------------------------------------------------------------------- CALL SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.language.bulkFetchDefault','2'); 0 rows inserted/updated/deleted ij> -- RESOLVE: missing row locks -- WORKAROUND: creating an index and dropping it -- to force the statement to be recompiled create index ix1 on a(a); 0 rows inserted/updated/deleted ij> drop index ix1; 0 rows inserted/updated/deleted ij> commit; ij> get cursor scan_cursor as 'select a from a'; ij> call SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.language.bulkFetchDefault', '16'); 0 rows inserted/updated/deleted ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A ----------- 1 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(2,1) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(3,6) |GRANT|ACTIVE ij> next scan_cursor; A ----------- 3 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(2,1) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(3,6) |GRANT|ACTIVE ij> next scan_cursor; A ----------- 5 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(3,1) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(3,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(5,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(7,6) |GRANT|ACTIVE ij> next scan_cursor; A ----------- 7 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(3,1) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(3,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(5,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(7,6) |GRANT|ACTIVE ij> next scan_cursor; No current row ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(3,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(5,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(7,6) |GRANT|ACTIVE ij> close scan_cursor; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(3,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(5,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(7,6) |GRANT|ACTIVE ij> commit; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> -------------------------------------------------------------------------------- -- TEST 6: btree cursor scan, group fetch = 1 (scan with "<" qualifier) -- Test "less than" qualified cursor scan on a data set. -- ALL MODES - TABLE IS, "scan page lockname of form (pageno, 1) -- SERIALIZABLE - row S locks as it visits each row, held until end xact -- REPEATABLE READ - row S locks as it visits each row, held until end xact -- READ COMMITTED - row S lock on current row, released on move to next row -- READ UNCOMMITTED - no row locks. -- -- At this point the base table should look like: -- 1, 10, 'one' -- 3, 30, 'three' -- 5, 50, 'five' -- 7, 70, 'seven' -------------------------------------------------------------------------------- CALL SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.language.bulkFetchDefault','1'); 0 rows inserted/updated/deleted ij> -- RESOLVE: missing row locks -- WORKAROUND: creating an index and dropping it -- to force the statement to be recompiled create index ix1 on a(a); 0 rows inserted/updated/deleted ij> drop index ix1; 0 rows inserted/updated/deleted ij> commit; ij> get cursor scan_cursor as 'select a from a where a < 3'; ij> call SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.language.bulkFetchDefault', '16'); 0 rows inserted/updated/deleted ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A ----------- 1 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(2,1) |GRANT|ACTIVE ij> next scan_cursor; No current row ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,7) |GRANT|ACTIVE ij> close scan_cursor; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,7) |GRANT|ACTIVE ij> commit; ij> -------------------------------------------------------------------------------- -- TEST 7: btree cursor scan, group fetch = 2 (scan with "<" qualifier) -- Test "less than" qualified cursor scan on a data set. -- ALL MODES - TABLE IS, "scan page lockname of form (pageno, 1) -- SERIALIZABLE - row S locks as it visits each row, held until end xact -- REPEATABLE READ - row S locks as it visits each row, held until end xact -- READ COMMITTED - row S lock on current row, released on move to next row -- READ UNCOMMITTED - no row locks. -- -- At this point the base table should look like: -- 1, 10, 'one' -- 3, 30, 'three' -- 5, 50, 'five' -- 7, 70, 'seven' -------------------------------------------------------------------------------- CALL SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.language.bulkFetchDefault','2'); 0 rows inserted/updated/deleted ij> -- RESOLVE: missing row locks -- WORKAROUND: creating an index and dropping it -- to force the statement to be recompiled create index ix1 on a(a); 0 rows inserted/updated/deleted ij> drop index ix1; 0 rows inserted/updated/deleted ij> commit; ij> get cursor scan_cursor as 'select a from a where a < 3'; ij> call SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.language.bulkFetchDefault', '16'); 0 rows inserted/updated/deleted ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A ----------- 1 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,7) |GRANT|ACTIVE ij> next scan_cursor; No current row ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,7) |GRANT|ACTIVE ij> close scan_cursor; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,7) |GRANT|ACTIVE ij> commit; ij> -------------------------------------------------------------------------------- -- TEST 8: btree cursor scan, group fetch = 1 (scan with equals qualifier) -- Test "equals" qualified cursor scan on a data set. -- ALL MODES - TABLE IS, "scan page lockname of form (pageno, 1) -- SERIALIZABLE - row S locks as it visits each row, held until end xact -- REPEATABLE READ - row S locks as it visits each row, held until end xact -- READ COMMITTED - row S lock on current row, released on move to next row -- READ UNCOMMITTED - no row locks. -- -- At this point the base table should look like: -- 1, 10, 'one' -- 3, 30, 'three' -- 5, 50, 'five' -- 7, 70, 'seven' -------------------------------------------------------------------------------- CALL SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.language.bulkFetchDefault','1'); 0 rows inserted/updated/deleted ij> -- RESOLVE: missing row locks -- WORKAROUND: creating an index and dropping it -- to force the statement to be recompiled create index ix1 on a(a); 0 rows inserted/updated/deleted ij> drop index ix1; 0 rows inserted/updated/deleted ij> commit; ij> get cursor scan_cursor as 'select a from a where a = 5'; ij> call SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.language.bulkFetchDefault', '16'); 0 rows inserted/updated/deleted ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A ----------- 5 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(2,1) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(5,6) |GRANT|ACTIVE ij> next scan_cursor; No current row ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(5,6) |GRANT|ACTIVE ij> close scan_cursor; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(5,6) |GRANT|ACTIVE ij> commit; ij> -------------------------------------------------------------------------------- -- TEST 9: btree cursor scan, group fetch = 2 (scan with equals qualifier) -- Test "equals" qualified cursor scan on a data set. -- ALL MODES - TABLE IS, "scan page lockname of form (pageno, 1) -- SERIALIZABLE - row S locks as it visits each row, held until end xact -- REPEATABLE READ - row S locks as it visits each row, held until end xact -- READ COMMITTED - row S lock on current row, released on move to next row -- READ UNCOMMITTED - no row locks. -- -- At this point the base table should look like: -- 1, 10, 'one' -- 3, 30, 'three' -- 5, 50, 'five' -- 7, 70, 'seven' -------------------------------------------------------------------------------- CALL SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.language.bulkFetchDefault','2'); 0 rows inserted/updated/deleted ij> -- RESOLVE: missing row locks -- WORKAROUND: creating an index and dropping it -- to force the statement to be recompiled create index ix1 on a(a); 0 rows inserted/updated/deleted ij> drop index ix1; 0 rows inserted/updated/deleted ij> commit; ij> get cursor scan_cursor as 'select a from a where a = 5 or a = 7'; ij> call SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.language.bulkFetchDefault', '16'); 0 rows inserted/updated/deleted ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A ----------- 5 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(2,1) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(5,6) |GRANT|ACTIVE ij> next scan_cursor; A ----------- 7 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(3,1) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(5,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(7,6) |GRANT|ACTIVE ij> close scan_cursor; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(5,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(7,6) |GRANT|ACTIVE ij> commit; ij> -------------------------------------------------------------------------------- -- TEST 10: btree cursor scan, group fetch = 1 (equals qualifier, no rows return) -- Test "equals" qualified cursor scan on a data set, no rows returned. -- ALL MODES - TABLE IS, "scan page lockname of form (pageno, 1) -- SERIALIZABLE - row S locks as it visits each row, held until end xact -- REPEATABLE READ - row S locks as it visits each row, held until end xact -- READ COMMITTED - row S lock on current row, released on move to next row -- READ UNCOMMITTED - no row locks. -- -- At this point the base table should look like: -- 1, 10, 'one' -- 3, 30, 'three' -- 5, 50, 'five' -- 7, 70, 'seven' -------------------------------------------------------------------------------- -- no rows expected to qualify CALL SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.language.bulkFetchDefault','1'); 0 rows inserted/updated/deleted ij> -- RESOLVE: missing row locks -- WORKAROUND: creating an index and dropping it -- to force the statement to be recompiled create index ix1 on a(a); 0 rows inserted/updated/deleted ij> drop index ix1; 0 rows inserted/updated/deleted ij> commit; ij> get cursor scan_cursor as 'select a from a where a = 42'; ij> call SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.language.bulkFetchDefault', '16'); 0 rows inserted/updated/deleted ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; No current row ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; No current row ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE ij> close scan_cursor; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE ij> commit; ij> drop table a; 0 rows inserted/updated/deleted ij> -- cursor, non-unique index run drop table a; ERROR 42Y55: 'DROP TABLE' cannot be performed on 'A' because it does not exist. ij> create table a (a int, b int, c varchar(1900), index_pad varchar(700) ) ; 0 rows inserted/updated/deleted ij> insert into a values (1, 10, PADSTRING('one',1900), PADSTRING('index pad 1',700)); 1 row inserted/updated/deleted ij> insert into a values (2, 20, PADSTRING('two',1900), PADSTRING('index pad 2',700)); 1 row inserted/updated/deleted ij> insert into a values (3, 30, PADSTRING('three',1900), PADSTRING('index pad 3',700)); 1 row inserted/updated/deleted ij> insert into a values (4, 40, PADSTRING('four',1900), PADSTRING('index pad 4',700)); 1 row inserted/updated/deleted ij> insert into a values (5, 50, PADSTRING('five',1900), PADSTRING('index pad 5',700)); 1 row inserted/updated/deleted ij> insert into a values (6, 60, PADSTRING('six',1900), PADSTRING('index pad 6',700)); 1 row inserted/updated/deleted ij> insert into a values (7, 70, PADSTRING('seven',1900), PADSTRING('index pad 7',700)); 1 row inserted/updated/deleted ij> create index a_idx on a (a, index_pad) ; 0 rows inserted/updated/deleted ij> commit; ij> run resource 'readBtreeCursorLocks.subsql'; 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. -- -- Very basic single user testing of read locks on cursors on indexes. -- This ".subsql" test is -- meant to be run from another test such that it gets run under multiple -- isolation levels. This is important as they behave -- differently, depending on isolation levels. -- -- assume's caller has already done: run 'LockTableQuery.subsql'; to get -- easy access to the lock VTI. -- TEST 0: btree cursor scan, group fetch = 1 -- TEST 1: btree cursor scan, group fetch = 2 -- TEST 2: btree cursor scan, group fetch = 1 stop scan in middle of set -- TEST 3: btree cursor scan, group fetch = 4 stop scan in middle of set -- TEST 4: btree cursor scan, group fetch = 1 (scan with some deleted rows) -- TEST 5: btree cursor scan, group fetch = 2(scan with committed deleted rows) -- TEST 6: btree cursor scan, group fetch = 1 (scan with "<" qualifier) -- TEST 7: btree cursor scan, group fetch = 2 (scan with "<" qualifier) -- TEST 8: btree cursor scan, group fetch = 1 (scan with equals qualifier) -- TEST 9: btree cursor scan, group fetch = 2 (scan with equals qualifier) -- TEST 10: btree cursor scan, group fetch = 1 ("=" qualifier, no rows return) autocommit off; ij> -------------------------------------------------------------------------------- -- Assumes that calling routine has set up the following simple dataset, -- a heap, and index with following initial values: -- create table a (a int, b int, c somesortofchar, [index_pad]); -- create index a_idx on a (a) or a_idx on a (a, index_pad); -- -- 1, 10, 'one' -- 2, 20, 'two' -- 3, 30, 'three' -- 4, 40, 'four' -- 5, 50, 'five' -- 6, 60, 'six' -- 7, 70, 'seven' -------------------------------------------------------------------------------- select * from a; A |B |C |INDEX_PAD ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- 1 |10 |one &|index pad 1 & 2 |20 |two &|index pad 2 & 3 |30 |three &|index pad 3 & 4 |40 |four &|index pad 4 & 5 |50 |five &|index pad 5 & 6 |60 |six &|index pad 6 & 7 |70 |seven &|index pad 7 & ij> commit; ij> -------------------------------------------------------------------------------- -- TEST 0: btree cursor scan, group fetch = 1 -- Test full cursor scan which does no updates. -- ALL MODES - TABLE IS, "scan page lockname of form (pageno, 1) -- SERIALIZABLE - row S locks as it visits each row, held until end xact -- REPEATABLE READ - row S locks as it visits each row, held until end xact -- READ COMMITTED - row S lock on current row, released on move to next row -- READ UNCOMMITTED - no row locks. ------------------------------------------------------------------------------- CALL SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.language.bulkFetchDefault','1'); 0 rows inserted/updated/deleted ij> -- RESOLVE: missing row locks -- WORKAROUND: creating an index and dropping it -- to force the statement to be recompiled create index ix1 on a(a); 0 rows inserted/updated/deleted ij> drop index ix1; 0 rows inserted/updated/deleted ij> commit; ij> get cursor scan_cursor as 'select a from a'; ij> call SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.language.bulkFetchDefault', '16'); 0 rows inserted/updated/deleted ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A ----------- 1 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(2,1) |GRANT|ACTIVE ij> next scan_cursor; A ----------- 2 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(2,1) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(2,6) |GRANT|ACTIVE ij> next scan_cursor; A ----------- 3 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(2,1) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(2,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(3,6) |GRANT|ACTIVE ij> next scan_cursor; A ----------- 4 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(2,1) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(2,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(3,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(4,6) |GRANT|ACTIVE ij> next scan_cursor; A ----------- 5 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(2,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(3,1) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(3,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(4,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(5,6) |GRANT|ACTIVE ij> next scan_cursor; A ----------- 6 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(2,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(3,1) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(3,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(4,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(5,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(6,6) |GRANT|ACTIVE ij> next scan_cursor; A ----------- 7 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(2,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(3,1) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(3,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(4,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(5,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(6,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(7,6) |GRANT|ACTIVE ij> next scan_cursor; No current row ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(2,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(3,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(4,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(5,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(6,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(7,6) |GRANT|ACTIVE ij> close scan_cursor; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(2,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(3,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(4,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(5,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(6,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(7,6) |GRANT|ACTIVE ij> commit; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> -------------------------------------------------------------------------------- -- TEST 1: btree cursor scan, group fetch = 2 -- Test full cursor scan which does no updates. -- ALL MODES - TABLE IS, "scan page lockname of form (pageno, 1) -- SERIALIZABLE - row S locks as it visits each row, held until end xact -- REPEATABLE READ - row S locks as it visits each row, held until end xact -- READ COMMITTED - row S lock on current row, released on move to next row -- READ UNCOMMITTED - no row locks. -------------------------------------------------------------------------------- CALL SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.language.bulkFetchDefault','2'); 0 rows inserted/updated/deleted ij> -- RESOLVE: missing row locks -- WORKAROUND: creating an index and dropping it -- to force the statement to be recompiled create index ix1 on a(a); 0 rows inserted/updated/deleted ij> drop index ix1; 0 rows inserted/updated/deleted ij> commit; ij> get cursor scan_cursor as 'select a from a'; ij> call SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.language.bulkFetchDefault', '16'); 0 rows inserted/updated/deleted ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A ----------- 1 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(2,1) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(2,6) |GRANT|ACTIVE ij> next scan_cursor; A ----------- 2 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(2,1) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(2,6) |GRANT|ACTIVE ij> next scan_cursor; A ----------- 3 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(2,1) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(2,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(3,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(4,6) |GRANT|ACTIVE ij> next scan_cursor; A ----------- 4 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(2,1) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(2,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(3,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(4,6) |GRANT|ACTIVE ij> next scan_cursor; A ----------- 5 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(2,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(3,1) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(3,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(4,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(5,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(6,6) |GRANT|ACTIVE ij> next scan_cursor; A ----------- 6 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(2,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(3,1) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(3,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(4,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(5,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(6,6) |GRANT|ACTIVE ij> next scan_cursor; A ----------- 7 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(2,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(3,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(4,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(5,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(6,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(7,6) |GRANT|ACTIVE ij> next scan_cursor; No current row ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(2,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(3,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(4,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(5,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(6,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(7,6) |GRANT|ACTIVE ij> close scan_cursor; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(2,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(3,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(4,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(5,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(6,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(7,6) |GRANT|ACTIVE ij> commit; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> -------------------------------------------------------------------------------- -- TEST 2: btree cursor scan, group fetch = 1, stop scan in middle of set -- Test full cursor scan which does no updates. -- ALL MODES - TABLE IS, "scan page lockname of form (pageno, 1) -- SERIALIZABLE - row S locks as it visits each row, held until end xact -- REPEATABLE READ - row S locks as it visits each row, held until end xact -- READ COMMITTED - row S lock on current row, released on move to next row -- READ UNCOMMITTED - no row locks. -------------------------------------------------------------------------------- CALL SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.language.bulkFetchDefault','1'); 0 rows inserted/updated/deleted ij> -- RESOLVE: missing row locks -- WORKAROUND: creating an index and dropping it -- to force the statement to be recompiled create index ix1 on a(a); 0 rows inserted/updated/deleted ij> drop index ix1; 0 rows inserted/updated/deleted ij> commit; ij> get cursor scan_cursor as 'select a from a'; ij> call SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.language.bulkFetchDefault', '16'); 0 rows inserted/updated/deleted ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A ----------- 1 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(2,1) |GRANT|ACTIVE ij> next scan_cursor; A ----------- 2 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(2,1) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(2,6) |GRANT|ACTIVE ij> close scan_cursor; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(2,6) |GRANT|ACTIVE ij> commit; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> -------------------------------------------------------------------------------- -- TEST 3: btree cursor scan, group fetch = 4, stop scan in middle of set -- Test full cursor scan which does no updates. -- ALL MODES - TABLE IS, "scan page lockname of form (pageno, 1) -- SERIALIZABLE - row S locks as it visits each row, held until end xact -- REPEATABLE READ - row S locks as it visits each row, held until end xact -- READ COMMITTED - row S lock on current row, released on move to next row -- READ UNCOMMITTED - no row locks. -------------------------------------------------------------------------------- CALL SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.language.bulkFetchDefault','4'); 0 rows inserted/updated/deleted ij> -- RESOLVE: missing row locks -- WORKAROUND: creating an index and dropping it -- to force the statement to be recompiled create index ix1 on a(a); 0 rows inserted/updated/deleted ij> drop index ix1; 0 rows inserted/updated/deleted ij> commit; ij> get cursor scan_cursor as 'select a from a'; ij> call SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.language.bulkFetchDefault', '16'); 0 rows inserted/updated/deleted ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A ----------- 1 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(2,1) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(2,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(3,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(4,6) |GRANT|ACTIVE ij> next scan_cursor; A ----------- 2 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(2,1) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(2,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(3,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(4,6) |GRANT|ACTIVE ij> close scan_cursor; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(2,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(3,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(4,6) |GRANT|ACTIVE ij> commit; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> -------------------------------------------------------------------------------- -- TEST 4: btree cursor scan, group fetch = 1 (scan table with some deleted rows) -- Test full cursor scan on a data set with some deleted rows (the "even" ones). -- ALL MODES - TABLE IS, "scan page lockname of form (pageno, 1) -- SERIALIZABLE - row S locks as it visits each row, held until end xact -- REPEATABLE READ - row S locks as it visits each row, held until end xact -- READ COMMITTED - row S lock on current row, released on move to next row -- READ UNCOMMITTED - no row locks. -- -- After the delete the base table should look like: -- 1, 10, 'one' -- 3, 30, 'three' -- 5, 50, 'five' -- 7, 70, 'seven' -------------------------------------------------------------------------------- delete from a where a = 2 or a = 4 or a = 6; 3 rows inserted/updated/deleted ij> commit; ij> CALL SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.language.bulkFetchDefault','1'); 0 rows inserted/updated/deleted ij> -- RESOLVE: missing row locks -- WORKAROUND: creating an index and dropping it -- to force the statement to be recompiled create index ix1 on a(a); 0 rows inserted/updated/deleted ij> drop index ix1; 0 rows inserted/updated/deleted ij> commit; ij> get cursor scan_cursor as 'select a from a'; ij> call SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.language.bulkFetchDefault', '16'); 0 rows inserted/updated/deleted ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A ----------- 1 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(2,1) |GRANT|ACTIVE ij> next scan_cursor; A ----------- 3 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(2,1) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(3,6) |GRANT|ACTIVE ij> next scan_cursor; A ----------- 5 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(3,1) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(3,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(5,6) |GRANT|ACTIVE ij> next scan_cursor; A ----------- 7 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(3,1) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(3,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(5,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(7,6) |GRANT|ACTIVE ij> next scan_cursor; No current row ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(3,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(5,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(7,6) |GRANT|ACTIVE ij> close scan_cursor; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(3,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(5,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(7,6) |GRANT|ACTIVE ij> commit; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> -------------------------------------------------------------------------------- -- TEST 5: btree cursor scan, group fetch = 2 (scan with committed deleted rows) -- Test full cursor scan on a data set with some deleted rows (the "even" ones). -- ALL MODES - TABLE IS, "scan page lockname of form (pageno, 1) -- SERIALIZABLE - row S locks as it visits each row, held until end xact -- REPEATABLE READ - row S locks as it visits each row, held until end xact -- READ COMMITTED - row S lock on current row, released on move to next row -- READ UNCOMMITTED - no row locks. -- -- At this point the base table should look like: -- 1, 10, 'one' -- 3, 30, 'three' -- 5, 50, 'five' -- 7, 70, 'seven' -------------------------------------------------------------------------------- CALL SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.language.bulkFetchDefault','2'); 0 rows inserted/updated/deleted ij> -- RESOLVE: missing row locks -- WORKAROUND: creating an index and dropping it -- to force the statement to be recompiled create index ix1 on a(a); 0 rows inserted/updated/deleted ij> drop index ix1; 0 rows inserted/updated/deleted ij> commit; ij> get cursor scan_cursor as 'select a from a'; ij> call SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.language.bulkFetchDefault', '16'); 0 rows inserted/updated/deleted ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A ----------- 1 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(2,1) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(3,6) |GRANT|ACTIVE ij> next scan_cursor; A ----------- 3 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(2,1) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(3,6) |GRANT|ACTIVE ij> next scan_cursor; A ----------- 5 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(3,1) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(3,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(5,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(7,6) |GRANT|ACTIVE ij> next scan_cursor; A ----------- 7 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(3,1) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(3,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(5,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(7,6) |GRANT|ACTIVE ij> next scan_cursor; No current row ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(3,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(5,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(7,6) |GRANT|ACTIVE ij> close scan_cursor; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(3,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(5,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(7,6) |GRANT|ACTIVE ij> commit; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> -------------------------------------------------------------------------------- -- TEST 6: btree cursor scan, group fetch = 1 (scan with "<" qualifier) -- Test "less than" qualified cursor scan on a data set. -- ALL MODES - TABLE IS, "scan page lockname of form (pageno, 1) -- SERIALIZABLE - row S locks as it visits each row, held until end xact -- REPEATABLE READ - row S locks as it visits each row, held until end xact -- READ COMMITTED - row S lock on current row, released on move to next row -- READ UNCOMMITTED - no row locks. -- -- At this point the base table should look like: -- 1, 10, 'one' -- 3, 30, 'three' -- 5, 50, 'five' -- 7, 70, 'seven' -------------------------------------------------------------------------------- CALL SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.language.bulkFetchDefault','1'); 0 rows inserted/updated/deleted ij> -- RESOLVE: missing row locks -- WORKAROUND: creating an index and dropping it -- to force the statement to be recompiled create index ix1 on a(a); 0 rows inserted/updated/deleted ij> drop index ix1; 0 rows inserted/updated/deleted ij> commit; ij> get cursor scan_cursor as 'select a from a where a < 3'; ij> call SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.language.bulkFetchDefault', '16'); 0 rows inserted/updated/deleted ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A ----------- 1 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(2,1) |GRANT|ACTIVE ij> next scan_cursor; No current row ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,7) |GRANT|ACTIVE ij> close scan_cursor; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,7) |GRANT|ACTIVE ij> commit; ij> -------------------------------------------------------------------------------- -- TEST 7: btree cursor scan, group fetch = 2 (scan with "<" qualifier) -- Test "less than" qualified cursor scan on a data set. -- ALL MODES - TABLE IS, "scan page lockname of form (pageno, 1) -- SERIALIZABLE - row S locks as it visits each row, held until end xact -- REPEATABLE READ - row S locks as it visits each row, held until end xact -- READ COMMITTED - row S lock on current row, released on move to next row -- READ UNCOMMITTED - no row locks. -- -- At this point the base table should look like: -- 1, 10, 'one' -- 3, 30, 'three' -- 5, 50, 'five' -- 7, 70, 'seven' -------------------------------------------------------------------------------- CALL SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.language.bulkFetchDefault','2'); 0 rows inserted/updated/deleted ij> -- RESOLVE: missing row locks -- WORKAROUND: creating an index and dropping it -- to force the statement to be recompiled create index ix1 on a(a); 0 rows inserted/updated/deleted ij> drop index ix1; 0 rows inserted/updated/deleted ij> commit; ij> get cursor scan_cursor as 'select a from a where a < 3'; ij> call SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.language.bulkFetchDefault', '16'); 0 rows inserted/updated/deleted ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A ----------- 1 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,7) |GRANT|ACTIVE ij> next scan_cursor; No current row ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,7) |GRANT|ACTIVE ij> close scan_cursor; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,7) |GRANT|ACTIVE ij> commit; ij> -------------------------------------------------------------------------------- -- TEST 8: btree cursor scan, group fetch = 1 (scan with equals qualifier) -- Test "equals" qualified cursor scan on a data set. -- ALL MODES - TABLE IS, "scan page lockname of form (pageno, 1) -- SERIALIZABLE - row S locks as it visits each row, held until end xact -- REPEATABLE READ - row S locks as it visits each row, held until end xact -- READ COMMITTED - row S lock on current row, released on move to next row -- READ UNCOMMITTED - no row locks. -- -- At this point the base table should look like: -- 1, 10, 'one' -- 3, 30, 'three' -- 5, 50, 'five' -- 7, 70, 'seven' -------------------------------------------------------------------------------- CALL SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.language.bulkFetchDefault','1'); 0 rows inserted/updated/deleted ij> -- RESOLVE: missing row locks -- WORKAROUND: creating an index and dropping it -- to force the statement to be recompiled create index ix1 on a(a); 0 rows inserted/updated/deleted ij> drop index ix1; 0 rows inserted/updated/deleted ij> commit; ij> get cursor scan_cursor as 'select a from a where a = 5'; ij> call SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.language.bulkFetchDefault', '16'); 0 rows inserted/updated/deleted ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A ----------- 5 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(3,1) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(5,6) |GRANT|ACTIVE ij> next scan_cursor; No current row ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(5,6) |GRANT|ACTIVE ij> close scan_cursor; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(5,6) |GRANT|ACTIVE ij> commit; ij> -------------------------------------------------------------------------------- -- TEST 9: btree cursor scan, group fetch = 2 (scan with equals qualifier) -- Test "equals" qualified cursor scan on a data set. -- ALL MODES - TABLE IS, "scan page lockname of form (pageno, 1) -- SERIALIZABLE - row S locks as it visits each row, held until end xact -- REPEATABLE READ - row S locks as it visits each row, held until end xact -- READ COMMITTED - row S lock on current row, released on move to next row -- READ UNCOMMITTED - no row locks. -- -- At this point the base table should look like: -- 1, 10, 'one' -- 3, 30, 'three' -- 5, 50, 'five' -- 7, 70, 'seven' -------------------------------------------------------------------------------- CALL SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.language.bulkFetchDefault','2'); 0 rows inserted/updated/deleted ij> -- RESOLVE: missing row locks -- WORKAROUND: creating an index and dropping it -- to force the statement to be recompiled create index ix1 on a(a); 0 rows inserted/updated/deleted ij> drop index ix1; 0 rows inserted/updated/deleted ij> commit; ij> get cursor scan_cursor as 'select a from a where a = 5 or a = 7'; ij> call SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.language.bulkFetchDefault', '16'); 0 rows inserted/updated/deleted ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A ----------- 5 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(3,1) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(5,6) |GRANT|ACTIVE ij> next scan_cursor; A ----------- 7 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(3,1) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(5,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(7,6) |GRANT|ACTIVE ij> close scan_cursor; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(5,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(7,6) |GRANT|ACTIVE ij> commit; ij> -------------------------------------------------------------------------------- -- TEST 10: btree cursor scan, group fetch = 1 (equals qualifier, no rows return) -- Test "equals" qualified cursor scan on a data set, no rows returned. -- ALL MODES - TABLE IS, "scan page lockname of form (pageno, 1) -- SERIALIZABLE - row S locks as it visits each row, held until end xact -- REPEATABLE READ - row S locks as it visits each row, held until end xact -- READ COMMITTED - row S lock on current row, released on move to next row -- READ UNCOMMITTED - no row locks. -- -- At this point the base table should look like: -- 1, 10, 'one' -- 3, 30, 'three' -- 5, 50, 'five' -- 7, 70, 'seven' -------------------------------------------------------------------------------- -- no rows expected to qualify CALL SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.language.bulkFetchDefault','1'); 0 rows inserted/updated/deleted ij> -- RESOLVE: missing row locks -- WORKAROUND: creating an index and dropping it -- to force the statement to be recompiled create index ix1 on a(a); 0 rows inserted/updated/deleted ij> drop index ix1; 0 rows inserted/updated/deleted ij> commit; ij> get cursor scan_cursor as 'select a from a where a = 42'; ij> call SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.language.bulkFetchDefault', '16'); 0 rows inserted/updated/deleted ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; No current row ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; No current row ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE ij> close scan_cursor; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE ij> commit; ij> drop table a; 0 rows inserted/updated/deleted ij> -- non cursor, unique index run drop table a; ERROR 42Y55: 'DROP TABLE' cannot be performed on 'A' because it does not exist. ij> create table a (a int, b int, c varchar(1900), index_pad varchar(800) ) ; 0 rows inserted/updated/deleted ij> insert into a values (1, 10, PADSTRING('one',1900), PADSTRING('index pad 1',800)); 1 row inserted/updated/deleted ij> insert into a values (2, 20, PADSTRING('two',1900), PADSTRING('index pad 2',800)); 1 row inserted/updated/deleted ij> insert into a values (3, 30, PADSTRING('three',1900), PADSTRING('index pad 3',800)); 1 row inserted/updated/deleted ij> insert into a values (4, 40, PADSTRING('four',1900), PADSTRING('index pad 4',800)); 1 row inserted/updated/deleted ij> insert into a values (5, 50, PADSTRING('five',1900), PADSTRING('index pad 5',800)); 1 row inserted/updated/deleted ij> insert into a values (6, 60, PADSTRING('six',1900), PADSTRING('index pad 6',800)); 1 row inserted/updated/deleted ij> insert into a values (7, 70, PADSTRING('seven',1900), PADSTRING('index pad 7',800)); 1 row inserted/updated/deleted ij> create unique index a_idx on a (a, index_pad) ; 0 rows inserted/updated/deleted ij> commit; ij> run resource 'readBtreeSetLocks.subsql'; 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. -- -- Basic single user testing of read locks on select "set" queries on indexes. -- -- This ".subsql" test is -- meant to be run from another test such that it gets run under multiple -- isolation levels. This is important as they behave -- differently, depending on isolation levels. -- -- assume's caller has already done: run 'LockTableQuery.subsql'; to get -- easy access to the lock VTI. -- TEST 0: btree scan -- TEST 1: btree scan, (scan table with some deleted rows) -- TEST 2: btree scan, (scan with "<" qualifier) -- TEST 3: btree scan, (scan with equals qualifier) -- TEST 4: btree scan, (equals qualifier, no rows return) autocommit off; ij> -------------------------------------------------------------------------------- -- Assumes that calling routine has set up the following simple dataset, -- a heap, and index with following initial values: -- create table a (a int, b int, c somesortofchar, [index_pad]); -- create index a_idx on a (a) or a_idx on a (a, index_pad); -- -- 1, 10, 'one' -- 2, 20, 'two' -- 3, 30, 'three' -- 4, 40, 'four' -- 5, 50, 'five' -- 6, 60, 'six' -- 7, 70, 'seven' -------------------------------------------------------------------------------- select * from a; A |B |C |INDEX_PAD ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- 1 |10 |one &|index pad 1 & 2 |20 |two &|index pad 2 & 3 |30 |three &|index pad 3 & 4 |40 |four &|index pad 4 & 5 |50 |five &|index pad 5 & 6 |60 |six &|index pad 6 & 7 |70 |seven &|index pad 7 & ij> commit; ij> -------------------------------------------------------------------------------- -- TEST 0: btree scan -- Test full scan. -- ALL MODES - TABLE IS, "scan page lockname of form (pageno, 1) -- SERIALIZABLE - row S locks as it visits each row, row/table lock -- held until end xact. Also holds one previous key lock. -- REPEATABLE READ - row S locks as it visits each row, row/table locks held -- until end of transaction. -- READ COMMITTED - instantaneous S locks requested on each row. No locks -- held after query finishes. -- READ UNCOMMITTED - no row locks. No locks held after query finishes. -------------------------------------------------------------------------------- select a from a; A ----------- 1 2 3 4 5 6 7 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(2,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(3,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(4,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(5,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(6,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(7,6) |GRANT|ACTIVE ij> commit; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> -------------------------------------------------------------------------------- -- TEST 1: btree scan, (scan table with some deleted rows) -- Test full scan on a data set with some deleted rows (the "even" ones). -- ALL MODES - TABLE IS, "scan page lockname of form (pageno, 1) -- SERIALIZABLE - row S locks as it visits each row, row/table lock -- held until end xact. Also holds one previous key lock. -- REPEATABLE READ - row S locks as it visits each row, row/table locks held -- until end of transaction. -- READ COMMITTED - instantaneous S locks requested on each row. No locks -- held after query finishes. -- READ UNCOMMITTED - no row locks. No locks held after query finishes. -- -- After the delete the base table should look like: -- 1, 10, 'one' -- 3, 30, 'three' -- 5, 50, 'five' -- 7, 70, 'seven' -------------------------------------------------------------------------------- delete from a where a = 2 or a = 4 or a = 6; 3 rows inserted/updated/deleted ij> commit; ij> -- The above delete and commit can allow post commit processing to run before -- the subsequent select is run, most likely if this run is on a table where -- there is one row per page. To get reproducible results from the subsequent -- lock calls, wait for post commit to finish before running the select. -- Without this wait "extra" locks sometimes might show up - these are locks -- on the committed deleted rows which have not been cleaned yet depending -- on timing. CALL WAIT_FOR_POST_COMMIT(); 0 rows inserted/updated/deleted ij> select a from a; A ----------- 1 3 5 7 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(3,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(5,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(7,6) |GRANT|ACTIVE ij> commit; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> -------------------------------------------------------------------------------- -- TEST 2: btree scan, (scan with "<" qualifier) -- Test "less than" qualified scan on a data set. -- ALL MODES - TABLE IS, "scan page lockname of form (pageno, 1) -- SERIALIZABLE - row S locks as it visits each row, row/table lock -- held until end xact. Also holds one previous key lock. -- REPEATABLE READ - row S locks as it visits each row, row/table locks held -- until end of transaction. -- READ COMMITTED - instantaneous S locks requested on each row. No locks -- held after query finishes. -- READ UNCOMMITTED - no row locks. No locks held after query finishes. -- -- At this point the base table should look like: -- 1, 10, 'one' -- 3, 30, 'three' -- 5, 50, 'five' -- 7, 70, 'seven' -------------------------------------------------------------------------------- select a from a where a < 3; A ----------- 1 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,7) |GRANT|ACTIVE ij> commit; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> -------------------------------------------------------------------------------- -- TEST 3: btree scan, (scan with equals qualifier) -- Test "equals" qualified cursor scan on a data set. -- ALL MODES - TABLE IS, "scan page lockname of form (pageno, 1) -- SERIALIZABLE - row S locks as it visits each row, row/table lock -- held until end xact. Also holds one previous key lock. -- REPEATABLE READ - row S locks as it visits each row, row/table locks held -- until end of transaction. -- READ COMMITTED - instantaneous S locks requested on each row. No locks -- held after query finishes. -- READ UNCOMMITTED - no row locks. No locks held after query finishes. -- -- At this point the base table should look like: -- 1, 10, 'one' -- 3, 30, 'three' -- 5, 50, 'five' -- 7, 70, 'seven' -------------------------------------------------------------------------------- select a from a where a = 5; A ----------- 5 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(5,6) |GRANT|ACTIVE ij> commit; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> -------------------------------------------------------------------------------- -- TEST 4: btree scan, (equals qualifier, no rows return) -- Test "equals" qualified scan on a data set, no rows returned. -- ALL MODES - TABLE IS, "scan page lockname of form (pageno, 1) -- SERIALIZABLE - row S locks as it visits each row, row/table lock -- held until end xact. Also holds one previous key lock. -- REPEATABLE READ - row S locks as it visits each row, row/table locks held -- until end of transaction. -- READ COMMITTED - instantaneous S locks requested on each row. No locks -- held after query finishes. -- READ UNCOMMITTED - no row locks. No locks held after query finishes. -- -- At this point the base table should look like: -- 1, 10, 'one' -- 3, 30, 'three' -- 5, 50, 'five' -- 7, 70, 'seven' -------------------------------------------------------------------------------- -- no rows expected to qualify select a from a where a = 42; A ----------- ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE ij> commit; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> drop table a; 0 rows inserted/updated/deleted ij> -- non cursor, non-unique index run drop table a; ERROR 42Y55: 'DROP TABLE' cannot be performed on 'A' because it does not exist. ij> create table a (a int, b int, c varchar(1900), index_pad varchar(900) ) ; 0 rows inserted/updated/deleted ij> insert into a values (1, 10, PADSTRING('one',1900), PADSTRING('index pad 1',900)); 1 row inserted/updated/deleted ij> insert into a values (2, 20, PADSTRING('two',1900), PADSTRING('index pad 2',900)); 1 row inserted/updated/deleted ij> insert into a values (3, 30, PADSTRING('three',1900), PADSTRING('index pad 3',900)); 1 row inserted/updated/deleted ij> insert into a values (4, 40, PADSTRING('four',1900), PADSTRING('index pad 4',900)); 1 row inserted/updated/deleted ij> insert into a values (5, 50, PADSTRING('five',1900), PADSTRING('index pad 5',900)); 1 row inserted/updated/deleted ij> insert into a values (6, 60, PADSTRING('six',1900), PADSTRING('index pad 6',900)); 1 row inserted/updated/deleted ij> insert into a values (7, 70, PADSTRING('seven',1900), PADSTRING('index pad 7',900)); 1 row inserted/updated/deleted ij> create index a_idx on a (a, index_pad) ; 0 rows inserted/updated/deleted ij> commit; ij> run resource 'readBtreeSetLocks.subsql'; 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. -- -- Basic single user testing of read locks on select "set" queries on indexes. -- -- This ".subsql" test is -- meant to be run from another test such that it gets run under multiple -- isolation levels. This is important as they behave -- differently, depending on isolation levels. -- -- assume's caller has already done: run 'LockTableQuery.subsql'; to get -- easy access to the lock VTI. -- TEST 0: btree scan -- TEST 1: btree scan, (scan table with some deleted rows) -- TEST 2: btree scan, (scan with "<" qualifier) -- TEST 3: btree scan, (scan with equals qualifier) -- TEST 4: btree scan, (equals qualifier, no rows return) autocommit off; ij> -------------------------------------------------------------------------------- -- Assumes that calling routine has set up the following simple dataset, -- a heap, and index with following initial values: -- create table a (a int, b int, c somesortofchar, [index_pad]); -- create index a_idx on a (a) or a_idx on a (a, index_pad); -- -- 1, 10, 'one' -- 2, 20, 'two' -- 3, 30, 'three' -- 4, 40, 'four' -- 5, 50, 'five' -- 6, 60, 'six' -- 7, 70, 'seven' -------------------------------------------------------------------------------- select * from a; A |B |C |INDEX_PAD ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- 1 |10 |one &|index pad 1 & 2 |20 |two &|index pad 2 & 3 |30 |three &|index pad 3 & 4 |40 |four &|index pad 4 & 5 |50 |five &|index pad 5 & 6 |60 |six &|index pad 6 & 7 |70 |seven &|index pad 7 & ij> commit; ij> -------------------------------------------------------------------------------- -- TEST 0: btree scan -- Test full scan. -- ALL MODES - TABLE IS, "scan page lockname of form (pageno, 1) -- SERIALIZABLE - row S locks as it visits each row, row/table lock -- held until end xact. Also holds one previous key lock. -- REPEATABLE READ - row S locks as it visits each row, row/table locks held -- until end of transaction. -- READ COMMITTED - instantaneous S locks requested on each row. No locks -- held after query finishes. -- READ UNCOMMITTED - no row locks. No locks held after query finishes. -------------------------------------------------------------------------------- select a from a; A ----------- 1 2 3 4 5 6 7 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(2,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(3,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(4,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(5,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(6,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(7,6) |GRANT|ACTIVE ij> commit; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> -------------------------------------------------------------------------------- -- TEST 1: btree scan, (scan table with some deleted rows) -- Test full scan on a data set with some deleted rows (the "even" ones). -- ALL MODES - TABLE IS, "scan page lockname of form (pageno, 1) -- SERIALIZABLE - row S locks as it visits each row, row/table lock -- held until end xact. Also holds one previous key lock. -- REPEATABLE READ - row S locks as it visits each row, row/table locks held -- until end of transaction. -- READ COMMITTED - instantaneous S locks requested on each row. No locks -- held after query finishes. -- READ UNCOMMITTED - no row locks. No locks held after query finishes. -- -- After the delete the base table should look like: -- 1, 10, 'one' -- 3, 30, 'three' -- 5, 50, 'five' -- 7, 70, 'seven' -------------------------------------------------------------------------------- delete from a where a = 2 or a = 4 or a = 6; 3 rows inserted/updated/deleted ij> commit; ij> -- The above delete and commit can allow post commit processing to run before -- the subsequent select is run, most likely if this run is on a table where -- there is one row per page. To get reproducible results from the subsequent -- lock calls, wait for post commit to finish before running the select. -- Without this wait "extra" locks sometimes might show up - these are locks -- on the committed deleted rows which have not been cleaned yet depending -- on timing. CALL WAIT_FOR_POST_COMMIT(); 0 rows inserted/updated/deleted ij> select a from a; A ----------- 1 3 5 7 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(3,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(5,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(7,6) |GRANT|ACTIVE ij> commit; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> -------------------------------------------------------------------------------- -- TEST 2: btree scan, (scan with "<" qualifier) -- Test "less than" qualified scan on a data set. -- ALL MODES - TABLE IS, "scan page lockname of form (pageno, 1) -- SERIALIZABLE - row S locks as it visits each row, row/table lock -- held until end xact. Also holds one previous key lock. -- REPEATABLE READ - row S locks as it visits each row, row/table locks held -- until end of transaction. -- READ COMMITTED - instantaneous S locks requested on each row. No locks -- held after query finishes. -- READ UNCOMMITTED - no row locks. No locks held after query finishes. -- -- At this point the base table should look like: -- 1, 10, 'one' -- 3, 30, 'three' -- 5, 50, 'five' -- 7, 70, 'seven' -------------------------------------------------------------------------------- select a from a where a < 3; A ----------- 1 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,7) |GRANT|ACTIVE ij> commit; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> -------------------------------------------------------------------------------- -- TEST 3: btree scan, (scan with equals qualifier) -- Test "equals" qualified cursor scan on a data set. -- ALL MODES - TABLE IS, "scan page lockname of form (pageno, 1) -- SERIALIZABLE - row S locks as it visits each row, row/table lock -- held until end xact. Also holds one previous key lock. -- REPEATABLE READ - row S locks as it visits each row, row/table locks held -- until end of transaction. -- READ COMMITTED - instantaneous S locks requested on each row. No locks -- held after query finishes. -- READ UNCOMMITTED - no row locks. No locks held after query finishes. -- -- At this point the base table should look like: -- 1, 10, 'one' -- 3, 30, 'three' -- 5, 50, 'five' -- 7, 70, 'seven' -------------------------------------------------------------------------------- select a from a where a = 5; A ----------- 5 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(5,6) |GRANT|ACTIVE ij> commit; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> -------------------------------------------------------------------------------- -- TEST 4: btree scan, (equals qualifier, no rows return) -- Test "equals" qualified scan on a data set, no rows returned. -- ALL MODES - TABLE IS, "scan page lockname of form (pageno, 1) -- SERIALIZABLE - row S locks as it visits each row, row/table lock -- held until end xact. Also holds one previous key lock. -- REPEATABLE READ - row S locks as it visits each row, row/table locks held -- until end of transaction. -- READ COMMITTED - instantaneous S locks requested on each row. No locks -- held after query finishes. -- READ UNCOMMITTED - no row locks. No locks held after query finishes. -- -- At this point the base table should look like: -- 1, 10, 'one' -- 3, 30, 'three' -- 5, 50, 'five' -- 7, 70, 'seven' -------------------------------------------------------------------------------- -- no rows expected to qualify select a from a where a = 42; A ----------- ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE ij> commit; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> drop table a; 0 rows inserted/updated/deleted ij> commit; ij> -- SERIALIZABLE TEST set isolation serializable; 0 rows inserted/updated/deleted ij> commit; ij> -- run each test with rows on one page in the interesting conglomerate (heap in -- the non-index tests, and in the index in the index based tests). -- cursor, no index run drop table a; ERROR 42Y55: 'DROP TABLE' cannot be performed on 'A' because it does not exist. ij> -- to create tables of page size 4k and still keep the following tbl -- create table a (a int, b int, c varchar(1900)); create table a(a int, b int); 0 rows inserted/updated/deleted ij> alter table a add column c varchar(1900); 0 rows inserted/updated/deleted ij> insert into a values (1, 10, 'one'); 1 row inserted/updated/deleted ij> insert into a values (2, 20, 'two'); 1 row inserted/updated/deleted ij> insert into a values (3, 30, 'three'); 1 row inserted/updated/deleted ij> insert into a values (4, 40, 'four'); 1 row inserted/updated/deleted ij> insert into a values (5, 50, 'five'); 1 row inserted/updated/deleted ij> insert into a values (6, 60, 'six'); 1 row inserted/updated/deleted ij> insert into a values (7, 70, 'seven'); 1 row inserted/updated/deleted ij> commit; ij> run resource 'readCursorLocks.subsql'; 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. -- -- Very basic single user testing of read locks on cursors on heap tables. -- This ".subsql" test is -- meant to be run from another test such that it gets run under multiple -- isolation levels. This is important as they behave -- differently, depending on isolation levels. -- -- assume's caller has already done: run 'LockTableQuery.subsql'; to get -- easy access to the lock VTI. -- TEST 0: heap cursor scan, group fetch = 1 -- TEST 1: heap cursor scan, group fetch = 2 -- TEST 2: heap cursor scan, group fetch = 1, stop scan in middle of set -- TEST 3: heap cursor scan, group fetch = 4, stop scan in middle of set -- TEST 4: heap cursor scan, group fetch = 1 (scan table with some deleted rows) -- TEST 5: heap cursor scan, group fetch = 2 (scan with committed deleted rows) -- TEST 6: heap cursor scan, group fetch = 1 (scan with "<" qualifier) -- TEST 7: heap cursor scan, group fetch = 2 (scan with "<" qualifier) -- TEST 8: heap cursor scan, group fetch = 1 (scan with equals qualifier) -- TEST 9: heap cursor scan, group fetch = 2 (scan with equals qualifier) -- TEST 10: heap cursor scan, group fetch = 1 (equals qualifier, no rows return) autocommit off; ij> -------------------------------------------------------------------------------- -- Assumes that calling routine has set up the following simple dataset, -- a heap, no indexes with following initial values: -- create table (a int, b int, c somesortofchar); -- 1, 10, 'one' -- 2, 20, 'two' -- 3, 30, 'three' -- 4, 40, 'four' -- 5, 50, 'five' -- 6, 60, 'six' -- 7, 70, 'seven' -------------------------------------------------------------------------------- select * from a; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 1 |10 |one 2 |20 |two 3 |30 |three 4 |40 |four 5 |50 |five 6 |60 |six 7 |70 |seven ij> commit; ij> -------------------------------------------------------------------------------- -- TEST 0: heap cursor scan, group fetch = 1 -- Test full cursor scan which does no updates. -- SERIALIZABLE - will get table level S lock. -- REPEATABLE READ - TABLE IS, will get row S locks as it visits each row. -- READ COMMITTED - TABLE IS, will hold single S lock on current row. -- READ UNCOMMITTED - TABLE IS, no row locks. -------------------------------------------------------------------------------- CALL SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.language.bulkFetchDefault','1'); 0 rows inserted/updated/deleted ij> get cursor scan_cursor as 'select a, b, c from a'; ij> call SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.language.bulkFetchDefault', '16'); 0 rows inserted/updated/deleted ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |S |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 1 |10 |one ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |S |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 2 |20 |two ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |S |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 3 |30 |three ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |S |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 4 |40 |four ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |S |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 5 |50 |five ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |S |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 6 |60 |six ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |S |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 7 |70 |seven ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |S |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; No current row ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |S |A |Tablelock |GRANT|ACTIVE ij> close scan_cursor; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |S |A |Tablelock |GRANT|ACTIVE ij> commit; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> -------------------------------------------------------------------------------- -- TEST 1: heap cursor scan, group fetch = 2 -- Test full cursor scan which does no updates. -- SERIALIZABLE - will get table level S lock. -- REPEATABLE READ - TABLE IS, will get row S locks as it visits each row. -- READ COMMITTED - TABLE IS, will get instantaneous locks and release -- READ UNCOMMITTED - TABLE IS, no row locks. -------------------------------------------------------------------------------- CALL SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.language.bulkFetchDefault','2'); 0 rows inserted/updated/deleted ij> -- RESOLVE: missing row locks -- WORKAROUND: creating an index and dropping it -- to force the query 'select a, b, c from a' to be recompiled create index ix1 on a(a); 0 rows inserted/updated/deleted ij> drop index ix1; 0 rows inserted/updated/deleted ij> commit; ij> get cursor scan_cursor as 'select a, b, c from a'; ij> call SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.language.bulkFetchDefault', '16'); 0 rows inserted/updated/deleted ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |S |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 1 |10 |one ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |S |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 2 |20 |two ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |S |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 3 |30 |three ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |S |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 4 |40 |four ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |S |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 5 |50 |five ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |S |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 6 |60 |six ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |S |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 7 |70 |seven ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |S |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; No current row ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |S |A |Tablelock |GRANT|ACTIVE ij> close scan_cursor; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |S |A |Tablelock |GRANT|ACTIVE ij> commit; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> -------------------------------------------------------------------------------- -- TEST 2: heap cursor scan, group fetch = 1, stop scan in middle of set -- Test full cursor scan which does no updates. -- SERIALIZABLE - will get table level S lock. -- REPEATABLE READ - TABLE IS, will get row S locks as it visits each row. -- READ COMMITTED - TABLE IS, will hold single S lock on current row. -- READ UNCOMMITTED - TABLE IS, no row locks. -------------------------------------------------------------------------------- CALL SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.language.bulkFetchDefault','1'); 0 rows inserted/updated/deleted ij> -- RESOLVE: missing row locks -- WORKAROUND: creating an index and dropping it -- to force the query 'select a, b, c from a' to be recompiled create index ix1 on a(a); 0 rows inserted/updated/deleted ij> drop index ix1; 0 rows inserted/updated/deleted ij> commit; ij> get cursor scan_cursor as 'select a, b, c from a'; ij> call SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.language.bulkFetchDefault', '16'); 0 rows inserted/updated/deleted ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |S |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 1 |10 |one ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |S |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 2 |20 |two ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |S |A |Tablelock |GRANT|ACTIVE ij> close scan_cursor; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |S |A |Tablelock |GRANT|ACTIVE ij> commit; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> -------------------------------------------------------------------------------- -- TEST 3: heap cursor scan, group fetch = 4, stop scan in middle of set -- Test full cursor scan which does no updates. -- SERIALIZABLE - will get table level S lock. -- REPEATABLE READ - TABLE IS, will get row S locks as it visits each row. -- READ COMMITTED - TABLE IS, will hold single S lock on current row. -- READ UNCOMMITTED - TABLE IS, no row locks. -------------------------------------------------------------------------------- CALL SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.language.bulkFetchDefault','4'); 0 rows inserted/updated/deleted ij> -- RESOLVE: missing row locks -- WORKAROUND: creating an index and dropping it -- to force the query 'select a, b, c from a' to be recompiled create index ix1 on a(a); 0 rows inserted/updated/deleted ij> drop index ix1; 0 rows inserted/updated/deleted ij> commit; ij> get cursor scan_cursor as 'select a, b, c from a'; ij> call SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.language.bulkFetchDefault', '16'); 0 rows inserted/updated/deleted ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |S |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 1 |10 |one ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |S |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 2 |20 |two ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |S |A |Tablelock |GRANT|ACTIVE ij> close scan_cursor; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |S |A |Tablelock |GRANT|ACTIVE ij> commit; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> -------------------------------------------------------------------------------- -- TEST 4: heap cursor scan, group fetch = 1 (scan table with some deleted rows) -- Test full cursor scan on a data set with some deleted rows (the "even" ones). -- SERIALIZABLE - will get table level S lock. -- REPEATABLE READ - TABLE IS, will get row S locks as it visits each row -- (including deleted ones). -- READ COMMITTED - TABLE IS, will get instantaneous locks and release -- READ UNCOMMITTED - TABLE IS, no row locks. -- -- After the delete the table should look like: -- 1, 10, 'one' -- 3, 30, 'three' -- 5, 50, 'five' -- 7, 70, 'seven' -------------------------------------------------------------------------------- delete from a where a = 2 or a = 4 or a = 6; 3 rows inserted/updated/deleted ij> commit; ij> CALL SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.language.bulkFetchDefault','1'); 0 rows inserted/updated/deleted ij> -- RESOLVE: missing row locks -- WORKAROUND: creating an index and dropping it -- to force the query 'select a, b, c from a' to be recompiled create index ix1 on a(a); 0 rows inserted/updated/deleted ij> drop index ix1; 0 rows inserted/updated/deleted ij> commit; ij> get cursor scan_cursor as 'select a, b, c from a'; ij> call SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.language.bulkFetchDefault', '16'); 0 rows inserted/updated/deleted ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |S |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 1 |10 |one ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |S |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 3 |30 |three ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |S |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 5 |50 |five ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |S |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 7 |70 |seven ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |S |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; No current row ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |S |A |Tablelock |GRANT|ACTIVE ij> close scan_cursor; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |S |A |Tablelock |GRANT|ACTIVE ij> commit; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> -------------------------------------------------------------------------------- -- TEST 5: heap cursor scan, group fetch = 2 (scan with committed deleted rows) -- Test full cursor scan on a data set with some deleted rows (the "even" ones). -- SERIALIZABLE - will get table level S lock. -- REPEATABLE READ - TABLE IS, will get row S locks as it visits each row -- (including deleted ones). -- READ COMMITTED - TABLE IS, will get instantaneous locks and release -- READ UNCOMMITTED - TABLE IS, no row locks. -- -- At this point the table should look like: -- 1, 10, 'one' -- 3, 30, 'three' -- 5, 50, 'five' -- 7, 70, 'seven' -------------------------------------------------------------------------------- CALL SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.language.bulkFetchDefault','2'); 0 rows inserted/updated/deleted ij> -- RESOLVE: missing row locks -- WORKAROUND: creating an index and dropping it -- to force the query 'select a, b, c from a' to be recompiled create index ix1 on a(a); 0 rows inserted/updated/deleted ij> drop index ix1; 0 rows inserted/updated/deleted ij> commit; ij> get cursor scan_cursor as 'select a, b, c from a'; ij> call SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.language.bulkFetchDefault', '16'); 0 rows inserted/updated/deleted ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |S |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 1 |10 |one ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |S |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 3 |30 |three ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |S |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 5 |50 |five ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |S |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 7 |70 |seven ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |S |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; No current row ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |S |A |Tablelock |GRANT|ACTIVE ij> close scan_cursor; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |S |A |Tablelock |GRANT|ACTIVE ij> commit; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> -------------------------------------------------------------------------------- -- TEST 6: heap cursor scan, group fetch = 1 (scan with "<" qualifier) -- Test "less than" qualified cursor scan on a data set. -- SERIALIZABLE - will get table level S lock. -- REPEATABLE READ - TABLE IS, will get row S locks as it visits each row -- (including deleted ones). -- READ COMMITTED - TABLE IS, will get instantaneous locks and release -- READ UNCOMMITTED - TABLE IS, no row locks. -- -- At this point the table should look like: -- 1, 10, 'one' -- 3, 30, 'three' -- 5, 50, 'five' -- 7, 70, 'seven' -------------------------------------------------------------------------------- CALL SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.language.bulkFetchDefault','1'); 0 rows inserted/updated/deleted ij> get cursor scan_cursor as 'select a, b, c from a where a < 3'; ij> call SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.language.bulkFetchDefault', '16'); 0 rows inserted/updated/deleted ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |S |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 1 |10 |one ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |S |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; No current row ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |S |A |Tablelock |GRANT|ACTIVE ij> close scan_cursor; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |S |A |Tablelock |GRANT|ACTIVE ij> commit; ij> -------------------------------------------------------------------------------- -- TEST 7: heap cursor scan, group fetch = 2 (scan with "<" qualifier) -- Test "less than" qualified cursor scan on a data set. -- SERIALIZABLE - will get table level S lock. -- REPEATABLE READ - TABLE IS, will get row S locks as it visits each row -- (including deleted ones). -- READ COMMITTED - TABLE IS, will get instantaneous locks and release -- READ UNCOMMITTED - TABLE IS, no row locks. -- -- At this point the table should look like: -- 1, 10, 'one' -- 3, 30, 'three' -- 5, 50, 'five' -- 7, 70, 'seven' -------------------------------------------------------------------------------- CALL SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.language.bulkFetchDefault','2'); 0 rows inserted/updated/deleted ij> -- RESOLVE: missing row locks -- WORKAROUND: creating an index and dropping it -- to force the statement to be recompiled create index ix1 on a(a); 0 rows inserted/updated/deleted ij> drop index ix1; 0 rows inserted/updated/deleted ij> commit; ij> get cursor scan_cursor as 'select a, b, c from a where a < 3'; ij> call SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.language.bulkFetchDefault', '16'); 0 rows inserted/updated/deleted ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |S |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 1 |10 |one ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |S |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; No current row ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |S |A |Tablelock |GRANT|ACTIVE ij> close scan_cursor; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |S |A |Tablelock |GRANT|ACTIVE ij> commit; ij> -------------------------------------------------------------------------------- -- TEST 8: heap cursor scan, group fetch = 1 (scan with equals qualifier) -- Test "equals" qualified cursor scan on a data set. -- SERIALIZABLE - will get table level S lock. -- REPEATABLE READ - TABLE IS, will get row S locks as it visits each row -- (including deleted ones). -- READ COMMITTED - TABLE IS, will get instantaneous locks and release -- READ UNCOMMITTED - TABLE IS, no row locks. -- -- At this point the table should look like: -- 1, 10, 'one' -- 3, 30, 'three' -- 5, 50, 'five' -- 7, 70, 'seven' -------------------------------------------------------------------------------- CALL SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.language.bulkFetchDefault','1'); 0 rows inserted/updated/deleted ij> get cursor scan_cursor as 'select a, b, c from a where a = 5'; ij> call SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.language.bulkFetchDefault', '16'); 0 rows inserted/updated/deleted ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |S |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 5 |50 |five ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |S |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; No current row ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |S |A |Tablelock |GRANT|ACTIVE ij> close scan_cursor; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |S |A |Tablelock |GRANT|ACTIVE ij> commit; ij> -------------------------------------------------------------------------------- -- TEST 9: heap cursor scan, group fetch = 2 (scan with equals qualifier) -- Test "equals" qualified cursor scan on a data set. -- SERIALIZABLE - will get table level S lock. -- REPEATABLE READ - TABLE IS, will get row S locks as it visits each row -- (including deleted ones). -- READ COMMITTED - TABLE IS, will get instantaneous locks and release -- READ UNCOMMITTED - TABLE IS, no row locks. -- -- At this point the table should look like: -- 1, 10, 'one' -- 3, 30, 'three' -- 5, 50, 'five' -- 7, 70, 'seven' -------------------------------------------------------------------------------- CALL SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.language.bulkFetchDefault','2'); 0 rows inserted/updated/deleted ij> get cursor scan_cursor as 'select a, b, c from a where a = 7'; ij> call SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.language.bulkFetchDefault', '16'); 0 rows inserted/updated/deleted ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |S |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 7 |70 |seven ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |S |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; No current row ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |S |A |Tablelock |GRANT|ACTIVE ij> close scan_cursor; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |S |A |Tablelock |GRANT|ACTIVE ij> commit; ij> -------------------------------------------------------------------------------- -- TEST 10: heap cursor scan, group fetch = 1 (equals qualifier, no rows return) -- Test "equals" qualified cursor scan on a data set, no rows returned. -- SERIALIZABLE - will get table level S lock. -- REPEATABLE READ - TABLE IS, will get row S locks as it visits each row -- (including deleted ones). -- READ COMMITTED - TABLE IS, will get instantaneous locks and release -- READ UNCOMMITTED - TABLE IS, no row locks. -- -- At this point the table should look like: -- 1, 10, 'one' -- 3, 30, 'three' -- 5, 50, 'five' -- 7, 70, 'seven' -------------------------------------------------------------------------------- CALL SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.language.bulkFetchDefault','1'); 0 rows inserted/updated/deleted ij> -- RESOLVE: missing row locks -- WORKAROUND: creating an index and dropping it -- to force the statement to be recompiled create index ix1 on a(a); 0 rows inserted/updated/deleted ij> drop index ix1; 0 rows inserted/updated/deleted ij> commit; ij> get cursor scan_cursor as 'select a, b, c from a where a = 7'; ij> CALL SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.language.bulkFetchDefault','16'); 0 rows inserted/updated/deleted ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |S |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 7 |70 |seven ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |S |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; No current row ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |S |A |Tablelock |GRANT|ACTIVE ij> close scan_cursor; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |S |A |Tablelock |GRANT|ACTIVE ij> commit; ij> drop table a; 0 rows inserted/updated/deleted ij> -- non cursor, no index run drop table a; ERROR 42Y55: 'DROP TABLE' cannot be performed on 'A' because it does not exist. ij> -- to create tables of page size 4k and still keep the following tbl -- create table a (a int, b int, c varchar(1900)); create table a(a int, b int); 0 rows inserted/updated/deleted ij> alter table a add column c varchar(1900); 0 rows inserted/updated/deleted ij> insert into a values (1, 10, 'one'); 1 row inserted/updated/deleted ij> insert into a values (2, 20, 'two'); 1 row inserted/updated/deleted ij> insert into a values (3, 30, 'three'); 1 row inserted/updated/deleted ij> insert into a values (4, 40, 'four'); 1 row inserted/updated/deleted ij> insert into a values (5, 50, 'five'); 1 row inserted/updated/deleted ij> insert into a values (6, 60, 'six'); 1 row inserted/updated/deleted ij> insert into a values (7, 70, 'seven'); 1 row inserted/updated/deleted ij> commit; ij> run resource 'readSetLocks.subsql'; 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. -- -- Very basic single user testing of read locks in "set" queries on heap tables. -- This ".subsql" test is -- meant to be run from another test such that it gets run under multiple -- isolation levels. This is important as they behave -- differently, depending on isolation levels. -- -- assume's caller has already done: run 'LockTableQuery.subsql'; to get -- easy access to the lock VTI. -- TEST 0: heap scan. -- TEST 1: heap scan, some rows deleted. -- TEST 2: heap scan, (scan with "<" qualifier) -- TEST 3: heap scan, (scan with equals qualifier) -- TEST 4: heap scan, (equals qualifier, no rows return) autocommit off; ij> -------------------------------------------------------------------------------- -- Assumes that calling routine has set up the following simple dataset, -- a heap, no indexes with following initial values: -- create table (a int, b int, c somesortofchar); -- 1, 10, 'one' -- 2, 20, 'two' -- 3, 30, 'three' -- 4, 40, 'four' -- 5, 50, 'five' -- 6, 60, 'six' -- 7, 70, 'seven' -------------------------------------------------------------------------------- select * from a; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 1 |10 |one 2 |20 |two 3 |30 |three 4 |40 |four 5 |50 |five 6 |60 |six 7 |70 |seven ij> commit; ij> -------------------------------------------------------------------------------- -- TEST 0: heap scan. -- Test full cursor scan which does no updates. -- SERIALIZABLE - will get table level S lock, held to end of xact. -- REPEATABLE READ - TABLE IS, will get row S locks as it visits each row -- (including deleted ones). held to end of xact. -- READ COMMITTED - TABLE IS, will get instantaneous locks and release. No -- locks held when statement completes. -- READ UNCOMMITTED - TABLE IS, no row locks. No locks after statement ends. -------------------------------------------------------------------------------- select a, b, c from a; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 1 |10 |one 2 |20 |two 3 |30 |three 4 |40 |four 5 |50 |five 6 |60 |six 7 |70 |seven ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |S |A |Tablelock |GRANT|ACTIVE ij> commit; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> -------------------------------------------------------------------------------- -- TEST 1: heap scan, some rows deleted. -- Test full cursor scan on a data set with some deleted rows (the "even" ones). -- SERIALIZABLE - will get table level S lock. -- REPEATABLE READ - TABLE IS, will get row S locks as it visits each row -- (including deleted ones). -- READ COMMITTED - TABLE IS, will get instantaneous locks and release -- READ UNCOMMITTED - TABLE IS, no row locks. -- SERIALIZABLE - will get table level S lock, held to end of xact. -- REPEATABLE READ - TABLE IS, will get row S locks as it visits each row -- (including deleted ones). held to end of xact. -- READ COMMITTED - TABLE IS, will get instantaneous locks and release. No -- locks held when statement completes. -- READ UNCOMMITTED - TABLE IS, no row locks. No locks after statement ends. -- -- After the delete the table should look like: -- 1, 10, 'one' -- 3, 30, 'three' -- 5, 50, 'five' -- 7, 70, 'seven' -------------------------------------------------------------------------------- delete from a where a = 2 or a = 4 or a = 6; 3 rows inserted/updated/deleted ij> commit; ij> select a, b, c from a; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 1 |10 |one 3 |30 |three 5 |50 |five 7 |70 |seven ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |S |A |Tablelock |GRANT|ACTIVE ij> commit; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> -------------------------------------------------------------------------------- -- TEST 2: heap scan, (scan with "<" qualifier) -- Test "less than" qualified cursor scan on a data set. -- SERIALIZABLE - will get table level S lock, held to end of xact. -- REPEATABLE READ - TABLE IS, will get row S locks as it visits each row -- (including deleted ones). held to end of xact. -- READ COMMITTED - TABLE IS, will get instantaneous locks and release. No -- locks held when statement completes. -- READ UNCOMMITTED - TABLE IS, no row locks. No locks after statement ends. -- -- At this point the table should look like: -- 1, 10, 'one' -- 3, 30, 'three' -- 5, 50, 'five' -- 7, 70, 'seven' -------------------------------------------------------------------------------- select a, b, c from a; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 1 |10 |one 3 |30 |three 5 |50 |five 7 |70 |seven ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |S |A |Tablelock |GRANT|ACTIVE ij> commit; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> -------------------------------------------------------------------------------- -- TEST 3: heap scan, (scan with equals qualifier) -- Test "equals" qualified cursor scan on a data set. -- SERIALIZABLE - will get table level S lock, held to end of xact. -- REPEATABLE READ - TABLE IS, will get row S locks as it visits each row -- (including deleted ones). held to end of xact. -- READ COMMITTED - TABLE IS, will get instantaneous locks and release. No -- locks held when statement completes. -- READ UNCOMMITTED - TABLE IS, no row locks. No locks after statement ends. -- -- At this point the table should look like: -- 1, 10, 'one' -- 3, 30, 'three' -- 5, 50, 'five' -- 7, 70, 'seven' -------------------------------------------------------------------------------- select a, b, c from a where a = 5; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 5 |50 |five ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |S |A |Tablelock |GRANT|ACTIVE ij> commit; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> -------------------------------------------------------------------------------- -- TEST 4: heap scan, (equals qualifier, no rows return) -- Test "equals" qualified cursor scan on a data set, no rows returned. -- SERIALIZABLE - will get table level S lock, held to end of xact. -- REPEATABLE READ - TABLE IS, will get row S locks as it visits each row -- (including deleted ones). held to end of xact. -- READ COMMITTED - TABLE IS, will get instantaneous locks and release. No -- locks held when statement completes. -- READ UNCOMMITTED - TABLE IS, no row locks. No locks after statement ends. -- -- At this point the table should look like: -- 1, 10, 'one' -- 3, 30, 'three' -- 5, 50, 'five' -- 7, 70, 'seven' -------------------------------------------------------------------------------- select a, b, c from a where a = 7; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 7 |70 |seven ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |S |A |Tablelock |GRANT|ACTIVE ij> commit; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> drop table a; 0 rows inserted/updated/deleted ij> -- cursor, unique index run drop table a; ERROR 42Y55: 'DROP TABLE' cannot be performed on 'A' because it does not exist. ij> -- to create tables of page size 4k and still keep the following tbl -- create table a (a int, b int, c varchar(1900)); create table a(a int, b int); 0 rows inserted/updated/deleted ij> alter table a add column c varchar(1900); 0 rows inserted/updated/deleted ij> insert into a values (1, 10, 'one'); 1 row inserted/updated/deleted ij> insert into a values (2, 20, 'two'); 1 row inserted/updated/deleted ij> insert into a values (3, 30, 'three'); 1 row inserted/updated/deleted ij> insert into a values (4, 40, 'four'); 1 row inserted/updated/deleted ij> insert into a values (5, 50, 'five'); 1 row inserted/updated/deleted ij> insert into a values (6, 60, 'six'); 1 row inserted/updated/deleted ij> insert into a values (7, 70, 'seven'); 1 row inserted/updated/deleted ij> create unique index a_idx on a (a); 0 rows inserted/updated/deleted ij> commit; ij> run resource 'readBtreeCursorLocks.subsql'; 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. -- -- Very basic single user testing of read locks on cursors on indexes. -- This ".subsql" test is -- meant to be run from another test such that it gets run under multiple -- isolation levels. This is important as they behave -- differently, depending on isolation levels. -- -- assume's caller has already done: run 'LockTableQuery.subsql'; to get -- easy access to the lock VTI. -- TEST 0: btree cursor scan, group fetch = 1 -- TEST 1: btree cursor scan, group fetch = 2 -- TEST 2: btree cursor scan, group fetch = 1 stop scan in middle of set -- TEST 3: btree cursor scan, group fetch = 4 stop scan in middle of set -- TEST 4: btree cursor scan, group fetch = 1 (scan with some deleted rows) -- TEST 5: btree cursor scan, group fetch = 2(scan with committed deleted rows) -- TEST 6: btree cursor scan, group fetch = 1 (scan with "<" qualifier) -- TEST 7: btree cursor scan, group fetch = 2 (scan with "<" qualifier) -- TEST 8: btree cursor scan, group fetch = 1 (scan with equals qualifier) -- TEST 9: btree cursor scan, group fetch = 2 (scan with equals qualifier) -- TEST 10: btree cursor scan, group fetch = 1 ("=" qualifier, no rows return) autocommit off; ij> -------------------------------------------------------------------------------- -- Assumes that calling routine has set up the following simple dataset, -- a heap, and index with following initial values: -- create table a (a int, b int, c somesortofchar, [index_pad]); -- create index a_idx on a (a) or a_idx on a (a, index_pad); -- -- 1, 10, 'one' -- 2, 20, 'two' -- 3, 30, 'three' -- 4, 40, 'four' -- 5, 50, 'five' -- 6, 60, 'six' -- 7, 70, 'seven' -------------------------------------------------------------------------------- select * from a; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 1 |10 |one 2 |20 |two 3 |30 |three 4 |40 |four 5 |50 |five 6 |60 |six 7 |70 |seven ij> commit; ij> -------------------------------------------------------------------------------- -- TEST 0: btree cursor scan, group fetch = 1 -- Test full cursor scan which does no updates. -- ALL MODES - TABLE IS, "scan page lockname of form (pageno, 1) -- SERIALIZABLE - row S locks as it visits each row, held until end xact -- REPEATABLE READ - row S locks as it visits each row, held until end xact -- READ COMMITTED - row S lock on current row, released on move to next row -- READ UNCOMMITTED - no row locks. ------------------------------------------------------------------------------- CALL SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.language.bulkFetchDefault','1'); 0 rows inserted/updated/deleted ij> -- RESOLVE: missing row locks -- WORKAROUND: creating an index and dropping it -- to force the statement to be recompiled create index ix1 on a(a); 0 rows inserted/updated/deleted WARNING 01504: The new index is a duplicate of an existing index: A_IDX. ij> drop index ix1; ERROR 42X65: Index 'IX1' does not exist. ij> commit; ij> get cursor scan_cursor as 'select a from a'; ij> call SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.language.bulkFetchDefault', '16'); 0 rows inserted/updated/deleted ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |S |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A ----------- 1 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |S |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A ----------- 2 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |S |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A ----------- 3 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |S |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A ----------- 4 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |S |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A ----------- 5 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |S |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A ----------- 6 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |S |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A ----------- 7 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |S |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; No current row ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |S |A |Tablelock |GRANT|ACTIVE ij> close scan_cursor; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |S |A |Tablelock |GRANT|ACTIVE ij> commit; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> -------------------------------------------------------------------------------- -- TEST 1: btree cursor scan, group fetch = 2 -- Test full cursor scan which does no updates. -- ALL MODES - TABLE IS, "scan page lockname of form (pageno, 1) -- SERIALIZABLE - row S locks as it visits each row, held until end xact -- REPEATABLE READ - row S locks as it visits each row, held until end xact -- READ COMMITTED - row S lock on current row, released on move to next row -- READ UNCOMMITTED - no row locks. -------------------------------------------------------------------------------- CALL SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.language.bulkFetchDefault','2'); 0 rows inserted/updated/deleted ij> -- RESOLVE: missing row locks -- WORKAROUND: creating an index and dropping it -- to force the statement to be recompiled create index ix1 on a(a); 0 rows inserted/updated/deleted WARNING 01504: The new index is a duplicate of an existing index: A_IDX. ij> drop index ix1; ERROR 42X65: Index 'IX1' does not exist. ij> commit; ij> get cursor scan_cursor as 'select a from a'; ij> call SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.language.bulkFetchDefault', '16'); 0 rows inserted/updated/deleted ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |S |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A ----------- 1 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |S |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A ----------- 2 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |S |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A ----------- 3 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |S |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A ----------- 4 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |S |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A ----------- 5 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |S |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A ----------- 6 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |S |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A ----------- 7 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |S |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; No current row ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |S |A |Tablelock |GRANT|ACTIVE ij> close scan_cursor; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |S |A |Tablelock |GRANT|ACTIVE ij> commit; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> -------------------------------------------------------------------------------- -- TEST 2: btree cursor scan, group fetch = 1, stop scan in middle of set -- Test full cursor scan which does no updates. -- ALL MODES - TABLE IS, "scan page lockname of form (pageno, 1) -- SERIALIZABLE - row S locks as it visits each row, held until end xact -- REPEATABLE READ - row S locks as it visits each row, held until end xact -- READ COMMITTED - row S lock on current row, released on move to next row -- READ UNCOMMITTED - no row locks. -------------------------------------------------------------------------------- CALL SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.language.bulkFetchDefault','1'); 0 rows inserted/updated/deleted ij> -- RESOLVE: missing row locks -- WORKAROUND: creating an index and dropping it -- to force the statement to be recompiled create index ix1 on a(a); 0 rows inserted/updated/deleted WARNING 01504: The new index is a duplicate of an existing index: A_IDX. ij> drop index ix1; ERROR 42X65: Index 'IX1' does not exist. ij> commit; ij> get cursor scan_cursor as 'select a from a'; ij> call SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.language.bulkFetchDefault', '16'); 0 rows inserted/updated/deleted ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |S |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A ----------- 1 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |S |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A ----------- 2 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |S |A |Tablelock |GRANT|ACTIVE ij> close scan_cursor; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |S |A |Tablelock |GRANT|ACTIVE ij> commit; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> -------------------------------------------------------------------------------- -- TEST 3: btree cursor scan, group fetch = 4, stop scan in middle of set -- Test full cursor scan which does no updates. -- ALL MODES - TABLE IS, "scan page lockname of form (pageno, 1) -- SERIALIZABLE - row S locks as it visits each row, held until end xact -- REPEATABLE READ - row S locks as it visits each row, held until end xact -- READ COMMITTED - row S lock on current row, released on move to next row -- READ UNCOMMITTED - no row locks. -------------------------------------------------------------------------------- CALL SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.language.bulkFetchDefault','4'); 0 rows inserted/updated/deleted ij> -- RESOLVE: missing row locks -- WORKAROUND: creating an index and dropping it -- to force the statement to be recompiled create index ix1 on a(a); 0 rows inserted/updated/deleted WARNING 01504: The new index is a duplicate of an existing index: A_IDX. ij> drop index ix1; ERROR 42X65: Index 'IX1' does not exist. ij> commit; ij> get cursor scan_cursor as 'select a from a'; ij> call SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.language.bulkFetchDefault', '16'); 0 rows inserted/updated/deleted ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |S |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A ----------- 1 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |S |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A ----------- 2 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |S |A |Tablelock |GRANT|ACTIVE ij> close scan_cursor; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |S |A |Tablelock |GRANT|ACTIVE ij> commit; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> -------------------------------------------------------------------------------- -- TEST 4: btree cursor scan, group fetch = 1 (scan table with some deleted rows) -- Test full cursor scan on a data set with some deleted rows (the "even" ones). -- ALL MODES - TABLE IS, "scan page lockname of form (pageno, 1) -- SERIALIZABLE - row S locks as it visits each row, held until end xact -- REPEATABLE READ - row S locks as it visits each row, held until end xact -- READ COMMITTED - row S lock on current row, released on move to next row -- READ UNCOMMITTED - no row locks. -- -- After the delete the base table should look like: -- 1, 10, 'one' -- 3, 30, 'three' -- 5, 50, 'five' -- 7, 70, 'seven' -------------------------------------------------------------------------------- delete from a where a = 2 or a = 4 or a = 6; 3 rows inserted/updated/deleted ij> commit; ij> CALL SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.language.bulkFetchDefault','1'); 0 rows inserted/updated/deleted ij> -- RESOLVE: missing row locks -- WORKAROUND: creating an index and dropping it -- to force the statement to be recompiled create index ix1 on a(a); 0 rows inserted/updated/deleted WARNING 01504: The new index is a duplicate of an existing index: A_IDX. ij> drop index ix1; ERROR 42X65: Index 'IX1' does not exist. ij> commit; ij> get cursor scan_cursor as 'select a from a'; ij> call SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.language.bulkFetchDefault', '16'); 0 rows inserted/updated/deleted ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |S |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A ----------- 1 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |S |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A ----------- 3 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |S |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A ----------- 5 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |S |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A ----------- 7 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |S |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; No current row ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |S |A |Tablelock |GRANT|ACTIVE ij> close scan_cursor; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |S |A |Tablelock |GRANT|ACTIVE ij> commit; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> -------------------------------------------------------------------------------- -- TEST 5: btree cursor scan, group fetch = 2 (scan with committed deleted rows) -- Test full cursor scan on a data set with some deleted rows (the "even" ones). -- ALL MODES - TABLE IS, "scan page lockname of form (pageno, 1) -- SERIALIZABLE - row S locks as it visits each row, held until end xact -- REPEATABLE READ - row S locks as it visits each row, held until end xact -- READ COMMITTED - row S lock on current row, released on move to next row -- READ UNCOMMITTED - no row locks. -- -- At this point the base table should look like: -- 1, 10, 'one' -- 3, 30, 'three' -- 5, 50, 'five' -- 7, 70, 'seven' -------------------------------------------------------------------------------- CALL SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.language.bulkFetchDefault','2'); 0 rows inserted/updated/deleted ij> -- RESOLVE: missing row locks -- WORKAROUND: creating an index and dropping it -- to force the statement to be recompiled create index ix1 on a(a); 0 rows inserted/updated/deleted WARNING 01504: The new index is a duplicate of an existing index: A_IDX. ij> drop index ix1; ERROR 42X65: Index 'IX1' does not exist. ij> commit; ij> get cursor scan_cursor as 'select a from a'; ij> call SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.language.bulkFetchDefault', '16'); 0 rows inserted/updated/deleted ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |S |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A ----------- 1 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |S |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A ----------- 3 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |S |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A ----------- 5 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |S |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A ----------- 7 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |S |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; No current row ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |S |A |Tablelock |GRANT|ACTIVE ij> close scan_cursor; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |S |A |Tablelock |GRANT|ACTIVE ij> commit; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> -------------------------------------------------------------------------------- -- TEST 6: btree cursor scan, group fetch = 1 (scan with "<" qualifier) -- Test "less than" qualified cursor scan on a data set. -- ALL MODES - TABLE IS, "scan page lockname of form (pageno, 1) -- SERIALIZABLE - row S locks as it visits each row, held until end xact -- REPEATABLE READ - row S locks as it visits each row, held until end xact -- READ COMMITTED - row S lock on current row, released on move to next row -- READ UNCOMMITTED - no row locks. -- -- At this point the base table should look like: -- 1, 10, 'one' -- 3, 30, 'three' -- 5, 50, 'five' -- 7, 70, 'seven' -------------------------------------------------------------------------------- CALL SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.language.bulkFetchDefault','1'); 0 rows inserted/updated/deleted ij> -- RESOLVE: missing row locks -- WORKAROUND: creating an index and dropping it -- to force the statement to be recompiled create index ix1 on a(a); 0 rows inserted/updated/deleted WARNING 01504: The new index is a duplicate of an existing index: A_IDX. ij> drop index ix1; ERROR 42X65: Index 'IX1' does not exist. ij> commit; ij> get cursor scan_cursor as 'select a from a where a < 3'; ij> call SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.language.bulkFetchDefault', '16'); 0 rows inserted/updated/deleted ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A ----------- 1 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,1) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,3) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,7) |GRANT|ACTIVE ij> next scan_cursor; No current row ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,3) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,8) |GRANT|ACTIVE ij> close scan_cursor; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,3) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,8) |GRANT|ACTIVE ij> commit; ij> -------------------------------------------------------------------------------- -- TEST 7: btree cursor scan, group fetch = 2 (scan with "<" qualifier) -- Test "less than" qualified cursor scan on a data set. -- ALL MODES - TABLE IS, "scan page lockname of form (pageno, 1) -- SERIALIZABLE - row S locks as it visits each row, held until end xact -- REPEATABLE READ - row S locks as it visits each row, held until end xact -- READ COMMITTED - row S lock on current row, released on move to next row -- READ UNCOMMITTED - no row locks. -- -- At this point the base table should look like: -- 1, 10, 'one' -- 3, 30, 'three' -- 5, 50, 'five' -- 7, 70, 'seven' -------------------------------------------------------------------------------- CALL SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.language.bulkFetchDefault','2'); 0 rows inserted/updated/deleted ij> -- RESOLVE: missing row locks -- WORKAROUND: creating an index and dropping it -- to force the statement to be recompiled create index ix1 on a(a); 0 rows inserted/updated/deleted WARNING 01504: The new index is a duplicate of an existing index: A_IDX. ij> drop index ix1; ERROR 42X65: Index 'IX1' does not exist. ij> commit; ij> get cursor scan_cursor as 'select a from a where a < 3'; ij> call SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.language.bulkFetchDefault', '16'); 0 rows inserted/updated/deleted ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A ----------- 1 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,3) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,8) |GRANT|ACTIVE ij> next scan_cursor; No current row ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,3) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,8) |GRANT|ACTIVE ij> close scan_cursor; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,3) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,8) |GRANT|ACTIVE ij> commit; ij> -------------------------------------------------------------------------------- -- TEST 8: btree cursor scan, group fetch = 1 (scan with equals qualifier) -- Test "equals" qualified cursor scan on a data set. -- ALL MODES - TABLE IS, "scan page lockname of form (pageno, 1) -- SERIALIZABLE - row S locks as it visits each row, held until end xact -- REPEATABLE READ - row S locks as it visits each row, held until end xact -- READ COMMITTED - row S lock on current row, released on move to next row -- READ UNCOMMITTED - no row locks. -- -- At this point the base table should look like: -- 1, 10, 'one' -- 3, 30, 'three' -- 5, 50, 'five' -- 7, 70, 'seven' -------------------------------------------------------------------------------- CALL SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.language.bulkFetchDefault','1'); 0 rows inserted/updated/deleted ij> -- RESOLVE: missing row locks -- WORKAROUND: creating an index and dropping it -- to force the statement to be recompiled create index ix1 on a(a); 0 rows inserted/updated/deleted WARNING 01504: The new index is a duplicate of an existing index: A_IDX. ij> drop index ix1; ERROR 42X65: Index 'IX1' does not exist. ij> commit; ij> get cursor scan_cursor as 'select a from a where a = 5'; ij> call SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.language.bulkFetchDefault', '16'); 0 rows inserted/updated/deleted ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A ----------- 5 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,1) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,11) |GRANT|ACTIVE ij> next scan_cursor; No current row ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,1) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,11) |GRANT|ACTIVE ij> close scan_cursor; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,11) |GRANT|ACTIVE ij> commit; ij> -------------------------------------------------------------------------------- -- TEST 9: btree cursor scan, group fetch = 2 (scan with equals qualifier) -- Test "equals" qualified cursor scan on a data set. -- ALL MODES - TABLE IS, "scan page lockname of form (pageno, 1) -- SERIALIZABLE - row S locks as it visits each row, held until end xact -- REPEATABLE READ - row S locks as it visits each row, held until end xact -- READ COMMITTED - row S lock on current row, released on move to next row -- READ UNCOMMITTED - no row locks. -- -- At this point the base table should look like: -- 1, 10, 'one' -- 3, 30, 'three' -- 5, 50, 'five' -- 7, 70, 'seven' -------------------------------------------------------------------------------- CALL SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.language.bulkFetchDefault','2'); 0 rows inserted/updated/deleted ij> -- RESOLVE: missing row locks -- WORKAROUND: creating an index and dropping it -- to force the statement to be recompiled create index ix1 on a(a); 0 rows inserted/updated/deleted WARNING 01504: The new index is a duplicate of an existing index: A_IDX. ij> drop index ix1; ERROR 42X65: Index 'IX1' does not exist. ij> commit; ij> get cursor scan_cursor as 'select a from a where a = 5 or a = 7'; ij> call SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.language.bulkFetchDefault', '16'); 0 rows inserted/updated/deleted ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A ----------- 5 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,1) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,11) |GRANT|ACTIVE ij> next scan_cursor; A ----------- 7 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,1) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,11) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,13) |GRANT|ACTIVE ij> close scan_cursor; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,11) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,13) |GRANT|ACTIVE ij> commit; ij> -------------------------------------------------------------------------------- -- TEST 10: btree cursor scan, group fetch = 1 (equals qualifier, no rows return) -- Test "equals" qualified cursor scan on a data set, no rows returned. -- ALL MODES - TABLE IS, "scan page lockname of form (pageno, 1) -- SERIALIZABLE - row S locks as it visits each row, held until end xact -- REPEATABLE READ - row S locks as it visits each row, held until end xact -- READ COMMITTED - row S lock on current row, released on move to next row -- READ UNCOMMITTED - no row locks. -- -- At this point the base table should look like: -- 1, 10, 'one' -- 3, 30, 'three' -- 5, 50, 'five' -- 7, 70, 'seven' -------------------------------------------------------------------------------- -- no rows expected to qualify CALL SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.language.bulkFetchDefault','1'); 0 rows inserted/updated/deleted ij> -- RESOLVE: missing row locks -- WORKAROUND: creating an index and dropping it -- to force the statement to be recompiled create index ix1 on a(a); 0 rows inserted/updated/deleted WARNING 01504: The new index is a duplicate of an existing index: A_IDX. ij> drop index ix1; ERROR 42X65: Index 'IX1' does not exist. ij> commit; ij> get cursor scan_cursor as 'select a from a where a = 42'; ij> call SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.language.bulkFetchDefault', '16'); 0 rows inserted/updated/deleted ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; No current row ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,13) |GRANT|ACTIVE ij> next scan_cursor; No current row ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,13) |GRANT|ACTIVE ij> close scan_cursor; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,13) |GRANT|ACTIVE ij> commit; ij> drop table a; 0 rows inserted/updated/deleted ij> -- cursor, non-unique index run drop table a; ERROR 42Y55: 'DROP TABLE' cannot be performed on 'A' because it does not exist. ij> -- to create tables of page size 4k and still keep the following tbl -- create table a (a int, b int, c varchar(1900)); create table a(a int, b int); 0 rows inserted/updated/deleted ij> alter table a add column c varchar(1900); 0 rows inserted/updated/deleted ij> insert into a values (1, 10, 'one'); 1 row inserted/updated/deleted ij> insert into a values (2, 20, 'two'); 1 row inserted/updated/deleted ij> insert into a values (3, 30, 'three'); 1 row inserted/updated/deleted ij> insert into a values (4, 40, 'four'); 1 row inserted/updated/deleted ij> insert into a values (5, 50, 'five'); 1 row inserted/updated/deleted ij> insert into a values (6, 60, 'six'); 1 row inserted/updated/deleted ij> insert into a values (7, 70, 'seven'); 1 row inserted/updated/deleted ij> create index a_idx on a (a); 0 rows inserted/updated/deleted ij> commit; ij> run resource 'readBtreeCursorLocks.subsql'; 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. -- -- Very basic single user testing of read locks on cursors on indexes. -- This ".subsql" test is -- meant to be run from another test such that it gets run under multiple -- isolation levels. This is important as they behave -- differently, depending on isolation levels. -- -- assume's caller has already done: run 'LockTableQuery.subsql'; to get -- easy access to the lock VTI. -- TEST 0: btree cursor scan, group fetch = 1 -- TEST 1: btree cursor scan, group fetch = 2 -- TEST 2: btree cursor scan, group fetch = 1 stop scan in middle of set -- TEST 3: btree cursor scan, group fetch = 4 stop scan in middle of set -- TEST 4: btree cursor scan, group fetch = 1 (scan with some deleted rows) -- TEST 5: btree cursor scan, group fetch = 2(scan with committed deleted rows) -- TEST 6: btree cursor scan, group fetch = 1 (scan with "<" qualifier) -- TEST 7: btree cursor scan, group fetch = 2 (scan with "<" qualifier) -- TEST 8: btree cursor scan, group fetch = 1 (scan with equals qualifier) -- TEST 9: btree cursor scan, group fetch = 2 (scan with equals qualifier) -- TEST 10: btree cursor scan, group fetch = 1 ("=" qualifier, no rows return) autocommit off; ij> -------------------------------------------------------------------------------- -- Assumes that calling routine has set up the following simple dataset, -- a heap, and index with following initial values: -- create table a (a int, b int, c somesortofchar, [index_pad]); -- create index a_idx on a (a) or a_idx on a (a, index_pad); -- -- 1, 10, 'one' -- 2, 20, 'two' -- 3, 30, 'three' -- 4, 40, 'four' -- 5, 50, 'five' -- 6, 60, 'six' -- 7, 70, 'seven' -------------------------------------------------------------------------------- select * from a; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 1 |10 |one 2 |20 |two 3 |30 |three 4 |40 |four 5 |50 |five 6 |60 |six 7 |70 |seven ij> commit; ij> -------------------------------------------------------------------------------- -- TEST 0: btree cursor scan, group fetch = 1 -- Test full cursor scan which does no updates. -- ALL MODES - TABLE IS, "scan page lockname of form (pageno, 1) -- SERIALIZABLE - row S locks as it visits each row, held until end xact -- REPEATABLE READ - row S locks as it visits each row, held until end xact -- READ COMMITTED - row S lock on current row, released on move to next row -- READ UNCOMMITTED - no row locks. ------------------------------------------------------------------------------- CALL SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.language.bulkFetchDefault','1'); 0 rows inserted/updated/deleted ij> -- RESOLVE: missing row locks -- WORKAROUND: creating an index and dropping it -- to force the statement to be recompiled create index ix1 on a(a); 0 rows inserted/updated/deleted WARNING 01504: The new index is a duplicate of an existing index: A_IDX. ij> drop index ix1; ERROR 42X65: Index 'IX1' does not exist. ij> commit; ij> get cursor scan_cursor as 'select a from a'; ij> call SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.language.bulkFetchDefault', '16'); 0 rows inserted/updated/deleted ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |S |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A ----------- 1 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |S |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A ----------- 2 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |S |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A ----------- 3 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |S |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A ----------- 4 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |S |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A ----------- 5 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |S |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A ----------- 6 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |S |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A ----------- 7 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |S |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; No current row ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |S |A |Tablelock |GRANT|ACTIVE ij> close scan_cursor; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |S |A |Tablelock |GRANT|ACTIVE ij> commit; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> -------------------------------------------------------------------------------- -- TEST 1: btree cursor scan, group fetch = 2 -- Test full cursor scan which does no updates. -- ALL MODES - TABLE IS, "scan page lockname of form (pageno, 1) -- SERIALIZABLE - row S locks as it visits each row, held until end xact -- REPEATABLE READ - row S locks as it visits each row, held until end xact -- READ COMMITTED - row S lock on current row, released on move to next row -- READ UNCOMMITTED - no row locks. -------------------------------------------------------------------------------- CALL SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.language.bulkFetchDefault','2'); 0 rows inserted/updated/deleted ij> -- RESOLVE: missing row locks -- WORKAROUND: creating an index and dropping it -- to force the statement to be recompiled create index ix1 on a(a); 0 rows inserted/updated/deleted WARNING 01504: The new index is a duplicate of an existing index: A_IDX. ij> drop index ix1; ERROR 42X65: Index 'IX1' does not exist. ij> commit; ij> get cursor scan_cursor as 'select a from a'; ij> call SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.language.bulkFetchDefault', '16'); 0 rows inserted/updated/deleted ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |S |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A ----------- 1 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |S |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A ----------- 2 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |S |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A ----------- 3 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |S |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A ----------- 4 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |S |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A ----------- 5 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |S |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A ----------- 6 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |S |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A ----------- 7 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |S |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; No current row ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |S |A |Tablelock |GRANT|ACTIVE ij> close scan_cursor; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |S |A |Tablelock |GRANT|ACTIVE ij> commit; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> -------------------------------------------------------------------------------- -- TEST 2: btree cursor scan, group fetch = 1, stop scan in middle of set -- Test full cursor scan which does no updates. -- ALL MODES - TABLE IS, "scan page lockname of form (pageno, 1) -- SERIALIZABLE - row S locks as it visits each row, held until end xact -- REPEATABLE READ - row S locks as it visits each row, held until end xact -- READ COMMITTED - row S lock on current row, released on move to next row -- READ UNCOMMITTED - no row locks. -------------------------------------------------------------------------------- CALL SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.language.bulkFetchDefault','1'); 0 rows inserted/updated/deleted ij> -- RESOLVE: missing row locks -- WORKAROUND: creating an index and dropping it -- to force the statement to be recompiled create index ix1 on a(a); 0 rows inserted/updated/deleted WARNING 01504: The new index is a duplicate of an existing index: A_IDX. ij> drop index ix1; ERROR 42X65: Index 'IX1' does not exist. ij> commit; ij> get cursor scan_cursor as 'select a from a'; ij> call SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.language.bulkFetchDefault', '16'); 0 rows inserted/updated/deleted ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |S |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A ----------- 1 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |S |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A ----------- 2 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |S |A |Tablelock |GRANT|ACTIVE ij> close scan_cursor; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |S |A |Tablelock |GRANT|ACTIVE ij> commit; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> -------------------------------------------------------------------------------- -- TEST 3: btree cursor scan, group fetch = 4, stop scan in middle of set -- Test full cursor scan which does no updates. -- ALL MODES - TABLE IS, "scan page lockname of form (pageno, 1) -- SERIALIZABLE - row S locks as it visits each row, held until end xact -- REPEATABLE READ - row S locks as it visits each row, held until end xact -- READ COMMITTED - row S lock on current row, released on move to next row -- READ UNCOMMITTED - no row locks. -------------------------------------------------------------------------------- CALL SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.language.bulkFetchDefault','4'); 0 rows inserted/updated/deleted ij> -- RESOLVE: missing row locks -- WORKAROUND: creating an index and dropping it -- to force the statement to be recompiled create index ix1 on a(a); 0 rows inserted/updated/deleted WARNING 01504: The new index is a duplicate of an existing index: A_IDX. ij> drop index ix1; ERROR 42X65: Index 'IX1' does not exist. ij> commit; ij> get cursor scan_cursor as 'select a from a'; ij> call SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.language.bulkFetchDefault', '16'); 0 rows inserted/updated/deleted ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |S |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A ----------- 1 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |S |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A ----------- 2 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |S |A |Tablelock |GRANT|ACTIVE ij> close scan_cursor; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |S |A |Tablelock |GRANT|ACTIVE ij> commit; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> -------------------------------------------------------------------------------- -- TEST 4: btree cursor scan, group fetch = 1 (scan table with some deleted rows) -- Test full cursor scan on a data set with some deleted rows (the "even" ones). -- ALL MODES - TABLE IS, "scan page lockname of form (pageno, 1) -- SERIALIZABLE - row S locks as it visits each row, held until end xact -- REPEATABLE READ - row S locks as it visits each row, held until end xact -- READ COMMITTED - row S lock on current row, released on move to next row -- READ UNCOMMITTED - no row locks. -- -- After the delete the base table should look like: -- 1, 10, 'one' -- 3, 30, 'three' -- 5, 50, 'five' -- 7, 70, 'seven' -------------------------------------------------------------------------------- delete from a where a = 2 or a = 4 or a = 6; 3 rows inserted/updated/deleted ij> commit; ij> CALL SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.language.bulkFetchDefault','1'); 0 rows inserted/updated/deleted ij> -- RESOLVE: missing row locks -- WORKAROUND: creating an index and dropping it -- to force the statement to be recompiled create index ix1 on a(a); 0 rows inserted/updated/deleted WARNING 01504: The new index is a duplicate of an existing index: A_IDX. ij> drop index ix1; ERROR 42X65: Index 'IX1' does not exist. ij> commit; ij> get cursor scan_cursor as 'select a from a'; ij> call SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.language.bulkFetchDefault', '16'); 0 rows inserted/updated/deleted ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |S |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A ----------- 1 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |S |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A ----------- 3 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |S |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A ----------- 5 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |S |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A ----------- 7 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |S |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; No current row ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |S |A |Tablelock |GRANT|ACTIVE ij> close scan_cursor; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |S |A |Tablelock |GRANT|ACTIVE ij> commit; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> -------------------------------------------------------------------------------- -- TEST 5: btree cursor scan, group fetch = 2 (scan with committed deleted rows) -- Test full cursor scan on a data set with some deleted rows (the "even" ones). -- ALL MODES - TABLE IS, "scan page lockname of form (pageno, 1) -- SERIALIZABLE - row S locks as it visits each row, held until end xact -- REPEATABLE READ - row S locks as it visits each row, held until end xact -- READ COMMITTED - row S lock on current row, released on move to next row -- READ UNCOMMITTED - no row locks. -- -- At this point the base table should look like: -- 1, 10, 'one' -- 3, 30, 'three' -- 5, 50, 'five' -- 7, 70, 'seven' -------------------------------------------------------------------------------- CALL SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.language.bulkFetchDefault','2'); 0 rows inserted/updated/deleted ij> -- RESOLVE: missing row locks -- WORKAROUND: creating an index and dropping it -- to force the statement to be recompiled create index ix1 on a(a); 0 rows inserted/updated/deleted WARNING 01504: The new index is a duplicate of an existing index: A_IDX. ij> drop index ix1; ERROR 42X65: Index 'IX1' does not exist. ij> commit; ij> get cursor scan_cursor as 'select a from a'; ij> call SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.language.bulkFetchDefault', '16'); 0 rows inserted/updated/deleted ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |S |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A ----------- 1 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |S |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A ----------- 3 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |S |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A ----------- 5 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |S |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A ----------- 7 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |S |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; No current row ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |S |A |Tablelock |GRANT|ACTIVE ij> close scan_cursor; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |S |A |Tablelock |GRANT|ACTIVE ij> commit; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> -------------------------------------------------------------------------------- -- TEST 6: btree cursor scan, group fetch = 1 (scan with "<" qualifier) -- Test "less than" qualified cursor scan on a data set. -- ALL MODES - TABLE IS, "scan page lockname of form (pageno, 1) -- SERIALIZABLE - row S locks as it visits each row, held until end xact -- REPEATABLE READ - row S locks as it visits each row, held until end xact -- READ COMMITTED - row S lock on current row, released on move to next row -- READ UNCOMMITTED - no row locks. -- -- At this point the base table should look like: -- 1, 10, 'one' -- 3, 30, 'three' -- 5, 50, 'five' -- 7, 70, 'seven' -------------------------------------------------------------------------------- CALL SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.language.bulkFetchDefault','1'); 0 rows inserted/updated/deleted ij> -- RESOLVE: missing row locks -- WORKAROUND: creating an index and dropping it -- to force the statement to be recompiled create index ix1 on a(a); 0 rows inserted/updated/deleted WARNING 01504: The new index is a duplicate of an existing index: A_IDX. ij> drop index ix1; ERROR 42X65: Index 'IX1' does not exist. ij> commit; ij> get cursor scan_cursor as 'select a from a where a < 3'; ij> call SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.language.bulkFetchDefault', '16'); 0 rows inserted/updated/deleted ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A ----------- 1 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,1) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,3) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,7) |GRANT|ACTIVE ij> next scan_cursor; No current row ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,3) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,8) |GRANT|ACTIVE ij> close scan_cursor; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,3) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,8) |GRANT|ACTIVE ij> commit; ij> -------------------------------------------------------------------------------- -- TEST 7: btree cursor scan, group fetch = 2 (scan with "<" qualifier) -- Test "less than" qualified cursor scan on a data set. -- ALL MODES - TABLE IS, "scan page lockname of form (pageno, 1) -- SERIALIZABLE - row S locks as it visits each row, held until end xact -- REPEATABLE READ - row S locks as it visits each row, held until end xact -- READ COMMITTED - row S lock on current row, released on move to next row -- READ UNCOMMITTED - no row locks. -- -- At this point the base table should look like: -- 1, 10, 'one' -- 3, 30, 'three' -- 5, 50, 'five' -- 7, 70, 'seven' -------------------------------------------------------------------------------- CALL SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.language.bulkFetchDefault','2'); 0 rows inserted/updated/deleted ij> -- RESOLVE: missing row locks -- WORKAROUND: creating an index and dropping it -- to force the statement to be recompiled create index ix1 on a(a); 0 rows inserted/updated/deleted WARNING 01504: The new index is a duplicate of an existing index: A_IDX. ij> drop index ix1; ERROR 42X65: Index 'IX1' does not exist. ij> commit; ij> get cursor scan_cursor as 'select a from a where a < 3'; ij> call SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.language.bulkFetchDefault', '16'); 0 rows inserted/updated/deleted ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A ----------- 1 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,3) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,8) |GRANT|ACTIVE ij> next scan_cursor; No current row ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,3) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,8) |GRANT|ACTIVE ij> close scan_cursor; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,3) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,8) |GRANT|ACTIVE ij> commit; ij> -------------------------------------------------------------------------------- -- TEST 8: btree cursor scan, group fetch = 1 (scan with equals qualifier) -- Test "equals" qualified cursor scan on a data set. -- ALL MODES - TABLE IS, "scan page lockname of form (pageno, 1) -- SERIALIZABLE - row S locks as it visits each row, held until end xact -- REPEATABLE READ - row S locks as it visits each row, held until end xact -- READ COMMITTED - row S lock on current row, released on move to next row -- READ UNCOMMITTED - no row locks. -- -- At this point the base table should look like: -- 1, 10, 'one' -- 3, 30, 'three' -- 5, 50, 'five' -- 7, 70, 'seven' -------------------------------------------------------------------------------- CALL SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.language.bulkFetchDefault','1'); 0 rows inserted/updated/deleted ij> -- RESOLVE: missing row locks -- WORKAROUND: creating an index and dropping it -- to force the statement to be recompiled create index ix1 on a(a); 0 rows inserted/updated/deleted WARNING 01504: The new index is a duplicate of an existing index: A_IDX. ij> drop index ix1; ERROR 42X65: Index 'IX1' does not exist. ij> commit; ij> get cursor scan_cursor as 'select a from a where a = 5'; ij> call SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.language.bulkFetchDefault', '16'); 0 rows inserted/updated/deleted ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A ----------- 5 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,1) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,10) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,11) |GRANT|ACTIVE ij> next scan_cursor; No current row ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,10) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,11) |GRANT|ACTIVE ij> close scan_cursor; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,10) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,11) |GRANT|ACTIVE ij> commit; ij> -------------------------------------------------------------------------------- -- TEST 9: btree cursor scan, group fetch = 2 (scan with equals qualifier) -- Test "equals" qualified cursor scan on a data set. -- ALL MODES - TABLE IS, "scan page lockname of form (pageno, 1) -- SERIALIZABLE - row S locks as it visits each row, held until end xact -- REPEATABLE READ - row S locks as it visits each row, held until end xact -- READ COMMITTED - row S lock on current row, released on move to next row -- READ UNCOMMITTED - no row locks. -- -- At this point the base table should look like: -- 1, 10, 'one' -- 3, 30, 'three' -- 5, 50, 'five' -- 7, 70, 'seven' -------------------------------------------------------------------------------- CALL SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.language.bulkFetchDefault','2'); 0 rows inserted/updated/deleted ij> -- RESOLVE: missing row locks -- WORKAROUND: creating an index and dropping it -- to force the statement to be recompiled create index ix1 on a(a); 0 rows inserted/updated/deleted WARNING 01504: The new index is a duplicate of an existing index: A_IDX. ij> drop index ix1; ERROR 42X65: Index 'IX1' does not exist. ij> commit; ij> get cursor scan_cursor as 'select a from a where a = 5 or a = 7'; ij> call SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.language.bulkFetchDefault', '16'); 0 rows inserted/updated/deleted ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A ----------- 5 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,1) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,10) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,11) |GRANT|ACTIVE ij> next scan_cursor; A ----------- 7 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,1) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,10) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,11) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,12) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,13) |GRANT|ACTIVE ij> close scan_cursor; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,10) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,11) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,12) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,13) |GRANT|ACTIVE ij> commit; ij> -------------------------------------------------------------------------------- -- TEST 10: btree cursor scan, group fetch = 1 (equals qualifier, no rows return) -- Test "equals" qualified cursor scan on a data set, no rows returned. -- ALL MODES - TABLE IS, "scan page lockname of form (pageno, 1) -- SERIALIZABLE - row S locks as it visits each row, held until end xact -- REPEATABLE READ - row S locks as it visits each row, held until end xact -- READ COMMITTED - row S lock on current row, released on move to next row -- READ UNCOMMITTED - no row locks. -- -- At this point the base table should look like: -- 1, 10, 'one' -- 3, 30, 'three' -- 5, 50, 'five' -- 7, 70, 'seven' -------------------------------------------------------------------------------- -- no rows expected to qualify CALL SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.language.bulkFetchDefault','1'); 0 rows inserted/updated/deleted ij> -- RESOLVE: missing row locks -- WORKAROUND: creating an index and dropping it -- to force the statement to be recompiled create index ix1 on a(a); 0 rows inserted/updated/deleted WARNING 01504: The new index is a duplicate of an existing index: A_IDX. ij> drop index ix1; ERROR 42X65: Index 'IX1' does not exist. ij> commit; ij> get cursor scan_cursor as 'select a from a where a = 42'; ij> call SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.language.bulkFetchDefault', '16'); 0 rows inserted/updated/deleted ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; No current row ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,13) |GRANT|ACTIVE ij> next scan_cursor; No current row ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,13) |GRANT|ACTIVE ij> close scan_cursor; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,13) |GRANT|ACTIVE ij> commit; ij> drop table a; 0 rows inserted/updated/deleted ij> -- non cursor, unique index run drop table a; ERROR 42Y55: 'DROP TABLE' cannot be performed on 'A' because it does not exist. ij> -- to create tables of page size 4k and still keep the following tbl -- create table a (a int, b int, c varchar(1900)); create table a(a int, b int); 0 rows inserted/updated/deleted ij> alter table a add column c varchar(1900); 0 rows inserted/updated/deleted ij> insert into a values (1, 10, 'one'); 1 row inserted/updated/deleted ij> insert into a values (2, 20, 'two'); 1 row inserted/updated/deleted ij> insert into a values (3, 30, 'three'); 1 row inserted/updated/deleted ij> insert into a values (4, 40, 'four'); 1 row inserted/updated/deleted ij> insert into a values (5, 50, 'five'); 1 row inserted/updated/deleted ij> insert into a values (6, 60, 'six'); 1 row inserted/updated/deleted ij> insert into a values (7, 70, 'seven'); 1 row inserted/updated/deleted ij> create unique index a_idx on a (a); 0 rows inserted/updated/deleted ij> commit; ij> run resource 'readBtreeSetLocks.subsql'; 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. -- -- Basic single user testing of read locks on select "set" queries on indexes. -- -- This ".subsql" test is -- meant to be run from another test such that it gets run under multiple -- isolation levels. This is important as they behave -- differently, depending on isolation levels. -- -- assume's caller has already done: run 'LockTableQuery.subsql'; to get -- easy access to the lock VTI. -- TEST 0: btree scan -- TEST 1: btree scan, (scan table with some deleted rows) -- TEST 2: btree scan, (scan with "<" qualifier) -- TEST 3: btree scan, (scan with equals qualifier) -- TEST 4: btree scan, (equals qualifier, no rows return) autocommit off; ij> -------------------------------------------------------------------------------- -- Assumes that calling routine has set up the following simple dataset, -- a heap, and index with following initial values: -- create table a (a int, b int, c somesortofchar, [index_pad]); -- create index a_idx on a (a) or a_idx on a (a, index_pad); -- -- 1, 10, 'one' -- 2, 20, 'two' -- 3, 30, 'three' -- 4, 40, 'four' -- 5, 50, 'five' -- 6, 60, 'six' -- 7, 70, 'seven' -------------------------------------------------------------------------------- select * from a; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 1 |10 |one 2 |20 |two 3 |30 |three 4 |40 |four 5 |50 |five 6 |60 |six 7 |70 |seven ij> commit; ij> -------------------------------------------------------------------------------- -- TEST 0: btree scan -- Test full scan. -- ALL MODES - TABLE IS, "scan page lockname of form (pageno, 1) -- SERIALIZABLE - row S locks as it visits each row, row/table lock -- held until end xact. Also holds one previous key lock. -- REPEATABLE READ - row S locks as it visits each row, row/table locks held -- until end of transaction. -- READ COMMITTED - instantaneous S locks requested on each row. No locks -- held after query finishes. -- READ UNCOMMITTED - no row locks. No locks held after query finishes. -------------------------------------------------------------------------------- select a from a; A ----------- 1 2 3 4 5 6 7 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |S |A |Tablelock |GRANT|ACTIVE ij> commit; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> -------------------------------------------------------------------------------- -- TEST 1: btree scan, (scan table with some deleted rows) -- Test full scan on a data set with some deleted rows (the "even" ones). -- ALL MODES - TABLE IS, "scan page lockname of form (pageno, 1) -- SERIALIZABLE - row S locks as it visits each row, row/table lock -- held until end xact. Also holds one previous key lock. -- REPEATABLE READ - row S locks as it visits each row, row/table locks held -- until end of transaction. -- READ COMMITTED - instantaneous S locks requested on each row. No locks -- held after query finishes. -- READ UNCOMMITTED - no row locks. No locks held after query finishes. -- -- After the delete the base table should look like: -- 1, 10, 'one' -- 3, 30, 'three' -- 5, 50, 'five' -- 7, 70, 'seven' -------------------------------------------------------------------------------- delete from a where a = 2 or a = 4 or a = 6; 3 rows inserted/updated/deleted ij> commit; ij> -- The above delete and commit can allow post commit processing to run before -- the subsequent select is run, most likely if this run is on a table where -- there is one row per page. To get reproducible results from the subsequent -- lock calls, wait for post commit to finish before running the select. -- Without this wait "extra" locks sometimes might show up - these are locks -- on the committed deleted rows which have not been cleaned yet depending -- on timing. CALL WAIT_FOR_POST_COMMIT(); 0 rows inserted/updated/deleted ij> select a from a; A ----------- 1 3 5 7 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |S |A |Tablelock |GRANT|ACTIVE ij> commit; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> -------------------------------------------------------------------------------- -- TEST 2: btree scan, (scan with "<" qualifier) -- Test "less than" qualified scan on a data set. -- ALL MODES - TABLE IS, "scan page lockname of form (pageno, 1) -- SERIALIZABLE - row S locks as it visits each row, row/table lock -- held until end xact. Also holds one previous key lock. -- REPEATABLE READ - row S locks as it visits each row, row/table locks held -- until end of transaction. -- READ COMMITTED - instantaneous S locks requested on each row. No locks -- held after query finishes. -- READ UNCOMMITTED - no row locks. No locks held after query finishes. -- -- At this point the base table should look like: -- 1, 10, 'one' -- 3, 30, 'three' -- 5, 50, 'five' -- 7, 70, 'seven' -------------------------------------------------------------------------------- select a from a where a < 3; A ----------- 1 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,3) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,8) |GRANT|ACTIVE ij> commit; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> -------------------------------------------------------------------------------- -- TEST 3: btree scan, (scan with equals qualifier) -- Test "equals" qualified cursor scan on a data set. -- ALL MODES - TABLE IS, "scan page lockname of form (pageno, 1) -- SERIALIZABLE - row S locks as it visits each row, row/table lock -- held until end xact. Also holds one previous key lock. -- REPEATABLE READ - row S locks as it visits each row, row/table locks held -- until end of transaction. -- READ COMMITTED - instantaneous S locks requested on each row. No locks -- held after query finishes. -- READ UNCOMMITTED - no row locks. No locks held after query finishes. -- -- At this point the base table should look like: -- 1, 10, 'one' -- 3, 30, 'three' -- 5, 50, 'five' -- 7, 70, 'seven' -------------------------------------------------------------------------------- select a from a where a = 5; A ----------- 5 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,11) |GRANT|ACTIVE ij> commit; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> -------------------------------------------------------------------------------- -- TEST 4: btree scan, (equals qualifier, no rows return) -- Test "equals" qualified scan on a data set, no rows returned. -- ALL MODES - TABLE IS, "scan page lockname of form (pageno, 1) -- SERIALIZABLE - row S locks as it visits each row, row/table lock -- held until end xact. Also holds one previous key lock. -- REPEATABLE READ - row S locks as it visits each row, row/table locks held -- until end of transaction. -- READ COMMITTED - instantaneous S locks requested on each row. No locks -- held after query finishes. -- READ UNCOMMITTED - no row locks. No locks held after query finishes. -- -- At this point the base table should look like: -- 1, 10, 'one' -- 3, 30, 'three' -- 5, 50, 'five' -- 7, 70, 'seven' -------------------------------------------------------------------------------- -- no rows expected to qualify select a from a where a = 42; A ----------- ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,13) |GRANT|ACTIVE ij> commit; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> drop table a; 0 rows inserted/updated/deleted ij> -- non cursor, non-unique index run drop table a; ERROR 42Y55: 'DROP TABLE' cannot be performed on 'A' because it does not exist. ij> -- to create tables of page size 4k and still keep the following tbl -- create table a (a int, b int, c varchar(1900)); create table a(a int, b int); 0 rows inserted/updated/deleted ij> alter table a add column c varchar(1900); 0 rows inserted/updated/deleted ij> insert into a values (1, 10, 'one'); 1 row inserted/updated/deleted ij> insert into a values (2, 20, 'two'); 1 row inserted/updated/deleted ij> insert into a values (3, 30, 'three'); 1 row inserted/updated/deleted ij> insert into a values (4, 40, 'four'); 1 row inserted/updated/deleted ij> insert into a values (5, 50, 'five'); 1 row inserted/updated/deleted ij> insert into a values (6, 60, 'six'); 1 row inserted/updated/deleted ij> insert into a values (7, 70, 'seven'); 1 row inserted/updated/deleted ij> create index a_idx on a (a); 0 rows inserted/updated/deleted ij> commit; ij> run resource 'readBtreeSetLocks.subsql'; 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. -- -- Basic single user testing of read locks on select "set" queries on indexes. -- -- This ".subsql" test is -- meant to be run from another test such that it gets run under multiple -- isolation levels. This is important as they behave -- differently, depending on isolation levels. -- -- assume's caller has already done: run 'LockTableQuery.subsql'; to get -- easy access to the lock VTI. -- TEST 0: btree scan -- TEST 1: btree scan, (scan table with some deleted rows) -- TEST 2: btree scan, (scan with "<" qualifier) -- TEST 3: btree scan, (scan with equals qualifier) -- TEST 4: btree scan, (equals qualifier, no rows return) autocommit off; ij> -------------------------------------------------------------------------------- -- Assumes that calling routine has set up the following simple dataset, -- a heap, and index with following initial values: -- create table a (a int, b int, c somesortofchar, [index_pad]); -- create index a_idx on a (a) or a_idx on a (a, index_pad); -- -- 1, 10, 'one' -- 2, 20, 'two' -- 3, 30, 'three' -- 4, 40, 'four' -- 5, 50, 'five' -- 6, 60, 'six' -- 7, 70, 'seven' -------------------------------------------------------------------------------- select * from a; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 1 |10 |one 2 |20 |two 3 |30 |three 4 |40 |four 5 |50 |five 6 |60 |six 7 |70 |seven ij> commit; ij> -------------------------------------------------------------------------------- -- TEST 0: btree scan -- Test full scan. -- ALL MODES - TABLE IS, "scan page lockname of form (pageno, 1) -- SERIALIZABLE - row S locks as it visits each row, row/table lock -- held until end xact. Also holds one previous key lock. -- REPEATABLE READ - row S locks as it visits each row, row/table locks held -- until end of transaction. -- READ COMMITTED - instantaneous S locks requested on each row. No locks -- held after query finishes. -- READ UNCOMMITTED - no row locks. No locks held after query finishes. -------------------------------------------------------------------------------- select a from a; A ----------- 1 2 3 4 5 6 7 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |S |A |Tablelock |GRANT|ACTIVE ij> commit; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> -------------------------------------------------------------------------------- -- TEST 1: btree scan, (scan table with some deleted rows) -- Test full scan on a data set with some deleted rows (the "even" ones). -- ALL MODES - TABLE IS, "scan page lockname of form (pageno, 1) -- SERIALIZABLE - row S locks as it visits each row, row/table lock -- held until end xact. Also holds one previous key lock. -- REPEATABLE READ - row S locks as it visits each row, row/table locks held -- until end of transaction. -- READ COMMITTED - instantaneous S locks requested on each row. No locks -- held after query finishes. -- READ UNCOMMITTED - no row locks. No locks held after query finishes. -- -- After the delete the base table should look like: -- 1, 10, 'one' -- 3, 30, 'three' -- 5, 50, 'five' -- 7, 70, 'seven' -------------------------------------------------------------------------------- delete from a where a = 2 or a = 4 or a = 6; 3 rows inserted/updated/deleted ij> commit; ij> -- The above delete and commit can allow post commit processing to run before -- the subsequent select is run, most likely if this run is on a table where -- there is one row per page. To get reproducible results from the subsequent -- lock calls, wait for post commit to finish before running the select. -- Without this wait "extra" locks sometimes might show up - these are locks -- on the committed deleted rows which have not been cleaned yet depending -- on timing. CALL WAIT_FOR_POST_COMMIT(); 0 rows inserted/updated/deleted ij> select a from a; A ----------- 1 3 5 7 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |S |A |Tablelock |GRANT|ACTIVE ij> commit; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> -------------------------------------------------------------------------------- -- TEST 2: btree scan, (scan with "<" qualifier) -- Test "less than" qualified scan on a data set. -- ALL MODES - TABLE IS, "scan page lockname of form (pageno, 1) -- SERIALIZABLE - row S locks as it visits each row, row/table lock -- held until end xact. Also holds one previous key lock. -- REPEATABLE READ - row S locks as it visits each row, row/table locks held -- until end of transaction. -- READ COMMITTED - instantaneous S locks requested on each row. No locks -- held after query finishes. -- READ UNCOMMITTED - no row locks. No locks held after query finishes. -- -- At this point the base table should look like: -- 1, 10, 'one' -- 3, 30, 'three' -- 5, 50, 'five' -- 7, 70, 'seven' -------------------------------------------------------------------------------- select a from a where a < 3; A ----------- 1 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,3) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,8) |GRANT|ACTIVE ij> commit; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> -------------------------------------------------------------------------------- -- TEST 3: btree scan, (scan with equals qualifier) -- Test "equals" qualified cursor scan on a data set. -- ALL MODES - TABLE IS, "scan page lockname of form (pageno, 1) -- SERIALIZABLE - row S locks as it visits each row, row/table lock -- held until end xact. Also holds one previous key lock. -- REPEATABLE READ - row S locks as it visits each row, row/table locks held -- until end of transaction. -- READ COMMITTED - instantaneous S locks requested on each row. No locks -- held after query finishes. -- READ UNCOMMITTED - no row locks. No locks held after query finishes. -- -- At this point the base table should look like: -- 1, 10, 'one' -- 3, 30, 'three' -- 5, 50, 'five' -- 7, 70, 'seven' -------------------------------------------------------------------------------- select a from a where a = 5; A ----------- 5 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,10) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,11) |GRANT|ACTIVE ij> commit; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> -------------------------------------------------------------------------------- -- TEST 4: btree scan, (equals qualifier, no rows return) -- Test "equals" qualified scan on a data set, no rows returned. -- ALL MODES - TABLE IS, "scan page lockname of form (pageno, 1) -- SERIALIZABLE - row S locks as it visits each row, row/table lock -- held until end xact. Also holds one previous key lock. -- REPEATABLE READ - row S locks as it visits each row, row/table locks held -- until end of transaction. -- READ COMMITTED - instantaneous S locks requested on each row. No locks -- held after query finishes. -- READ UNCOMMITTED - no row locks. No locks held after query finishes. -- -- At this point the base table should look like: -- 1, 10, 'one' -- 3, 30, 'three' -- 5, 50, 'five' -- 7, 70, 'seven' -------------------------------------------------------------------------------- -- no rows expected to qualify select a from a where a = 42; A ----------- ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,13) |GRANT|ACTIVE ij> commit; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> drop table a; 0 rows inserted/updated/deleted ij> -- run each test with rows across multiple pages in the interesting -- conglomerate (heap in the non-index tests, and in the index in the index -- based tests). -- cursor, no index run drop table a; ERROR 42Y55: 'DROP TABLE' cannot be performed on 'A' because it does not exist. ij> -- to create tables of page size 4k and still keep the following tbl -- create table a (a int, b int, c varchar(1900)); create table a(a int, b int); 0 rows inserted/updated/deleted ij> alter table a add column c varchar(1900); 0 rows inserted/updated/deleted ij> insert into a values (1, 10, PADSTRING('one', 1900)); 1 row inserted/updated/deleted ij> insert into a values (2, 20, PADSTRING('two', 1900)); 1 row inserted/updated/deleted ij> insert into a values (3, 30, PADSTRING('three', 1900)); 1 row inserted/updated/deleted ij> insert into a values (4, 40, PADSTRING('four', 1900)); 1 row inserted/updated/deleted ij> insert into a values (5, 50, PADSTRING('five', 1900)); 1 row inserted/updated/deleted ij> insert into a values (6, 60, PADSTRING('six', 1900)); 1 row inserted/updated/deleted ij> insert into a values (7, 70, PADSTRING('seven', 1900)); 1 row inserted/updated/deleted ij> commit; ij> run resource 'readCursorLocks.subsql'; 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. -- -- Very basic single user testing of read locks on cursors on heap tables. -- This ".subsql" test is -- meant to be run from another test such that it gets run under multiple -- isolation levels. This is important as they behave -- differently, depending on isolation levels. -- -- assume's caller has already done: run 'LockTableQuery.subsql'; to get -- easy access to the lock VTI. -- TEST 0: heap cursor scan, group fetch = 1 -- TEST 1: heap cursor scan, group fetch = 2 -- TEST 2: heap cursor scan, group fetch = 1, stop scan in middle of set -- TEST 3: heap cursor scan, group fetch = 4, stop scan in middle of set -- TEST 4: heap cursor scan, group fetch = 1 (scan table with some deleted rows) -- TEST 5: heap cursor scan, group fetch = 2 (scan with committed deleted rows) -- TEST 6: heap cursor scan, group fetch = 1 (scan with "<" qualifier) -- TEST 7: heap cursor scan, group fetch = 2 (scan with "<" qualifier) -- TEST 8: heap cursor scan, group fetch = 1 (scan with equals qualifier) -- TEST 9: heap cursor scan, group fetch = 2 (scan with equals qualifier) -- TEST 10: heap cursor scan, group fetch = 1 (equals qualifier, no rows return) autocommit off; ij> -------------------------------------------------------------------------------- -- Assumes that calling routine has set up the following simple dataset, -- a heap, no indexes with following initial values: -- create table (a int, b int, c somesortofchar); -- 1, 10, 'one' -- 2, 20, 'two' -- 3, 30, 'three' -- 4, 40, 'four' -- 5, 50, 'five' -- 6, 60, 'six' -- 7, 70, 'seven' -------------------------------------------------------------------------------- select * from a; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 1 |10 |one & 2 |20 |two & 3 |30 |three & 4 |40 |four & 5 |50 |five & 6 |60 |six & 7 |70 |seven & ij> commit; ij> -------------------------------------------------------------------------------- -- TEST 0: heap cursor scan, group fetch = 1 -- Test full cursor scan which does no updates. -- SERIALIZABLE - will get table level S lock. -- REPEATABLE READ - TABLE IS, will get row S locks as it visits each row. -- READ COMMITTED - TABLE IS, will hold single S lock on current row. -- READ UNCOMMITTED - TABLE IS, no row locks. -------------------------------------------------------------------------------- CALL SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.language.bulkFetchDefault','1'); 0 rows inserted/updated/deleted ij> get cursor scan_cursor as 'select a, b, c from a'; ij> call SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.language.bulkFetchDefault', '16'); 0 rows inserted/updated/deleted ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |S |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 1 |10 |one & ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |S |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 2 |20 |two & ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |S |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 3 |30 |three & ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |S |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 4 |40 |four & ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |S |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 5 |50 |five & ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |S |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 6 |60 |six & ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |S |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 7 |70 |seven & ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |S |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; No current row ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |S |A |Tablelock |GRANT|ACTIVE ij> close scan_cursor; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |S |A |Tablelock |GRANT|ACTIVE ij> commit; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> -------------------------------------------------------------------------------- -- TEST 1: heap cursor scan, group fetch = 2 -- Test full cursor scan which does no updates. -- SERIALIZABLE - will get table level S lock. -- REPEATABLE READ - TABLE IS, will get row S locks as it visits each row. -- READ COMMITTED - TABLE IS, will get instantaneous locks and release -- READ UNCOMMITTED - TABLE IS, no row locks. -------------------------------------------------------------------------------- CALL SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.language.bulkFetchDefault','2'); 0 rows inserted/updated/deleted ij> -- RESOLVE: missing row locks -- WORKAROUND: creating an index and dropping it -- to force the query 'select a, b, c from a' to be recompiled create index ix1 on a(a); 0 rows inserted/updated/deleted ij> drop index ix1; 0 rows inserted/updated/deleted ij> commit; ij> get cursor scan_cursor as 'select a, b, c from a'; ij> call SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.language.bulkFetchDefault', '16'); 0 rows inserted/updated/deleted ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |S |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 1 |10 |one & ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |S |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 2 |20 |two & ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |S |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 3 |30 |three & ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |S |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 4 |40 |four & ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |S |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 5 |50 |five & ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |S |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 6 |60 |six & ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |S |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 7 |70 |seven & ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |S |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; No current row ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |S |A |Tablelock |GRANT|ACTIVE ij> close scan_cursor; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |S |A |Tablelock |GRANT|ACTIVE ij> commit; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> -------------------------------------------------------------------------------- -- TEST 2: heap cursor scan, group fetch = 1, stop scan in middle of set -- Test full cursor scan which does no updates. -- SERIALIZABLE - will get table level S lock. -- REPEATABLE READ - TABLE IS, will get row S locks as it visits each row. -- READ COMMITTED - TABLE IS, will hold single S lock on current row. -- READ UNCOMMITTED - TABLE IS, no row locks. -------------------------------------------------------------------------------- CALL SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.language.bulkFetchDefault','1'); 0 rows inserted/updated/deleted ij> -- RESOLVE: missing row locks -- WORKAROUND: creating an index and dropping it -- to force the query 'select a, b, c from a' to be recompiled create index ix1 on a(a); 0 rows inserted/updated/deleted ij> drop index ix1; 0 rows inserted/updated/deleted ij> commit; ij> get cursor scan_cursor as 'select a, b, c from a'; ij> call SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.language.bulkFetchDefault', '16'); 0 rows inserted/updated/deleted ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |S |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 1 |10 |one & ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |S |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 2 |20 |two & ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |S |A |Tablelock |GRANT|ACTIVE ij> close scan_cursor; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |S |A |Tablelock |GRANT|ACTIVE ij> commit; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> -------------------------------------------------------------------------------- -- TEST 3: heap cursor scan, group fetch = 4, stop scan in middle of set -- Test full cursor scan which does no updates. -- SERIALIZABLE - will get table level S lock. -- REPEATABLE READ - TABLE IS, will get row S locks as it visits each row. -- READ COMMITTED - TABLE IS, will hold single S lock on current row. -- READ UNCOMMITTED - TABLE IS, no row locks. -------------------------------------------------------------------------------- CALL SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.language.bulkFetchDefault','4'); 0 rows inserted/updated/deleted ij> -- RESOLVE: missing row locks -- WORKAROUND: creating an index and dropping it -- to force the query 'select a, b, c from a' to be recompiled create index ix1 on a(a); 0 rows inserted/updated/deleted ij> drop index ix1; 0 rows inserted/updated/deleted ij> commit; ij> get cursor scan_cursor as 'select a, b, c from a'; ij> call SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.language.bulkFetchDefault', '16'); 0 rows inserted/updated/deleted ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |S |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 1 |10 |one & ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |S |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 2 |20 |two & ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |S |A |Tablelock |GRANT|ACTIVE ij> close scan_cursor; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |S |A |Tablelock |GRANT|ACTIVE ij> commit; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> -------------------------------------------------------------------------------- -- TEST 4: heap cursor scan, group fetch = 1 (scan table with some deleted rows) -- Test full cursor scan on a data set with some deleted rows (the "even" ones). -- SERIALIZABLE - will get table level S lock. -- REPEATABLE READ - TABLE IS, will get row S locks as it visits each row -- (including deleted ones). -- READ COMMITTED - TABLE IS, will get instantaneous locks and release -- READ UNCOMMITTED - TABLE IS, no row locks. -- -- After the delete the table should look like: -- 1, 10, 'one' -- 3, 30, 'three' -- 5, 50, 'five' -- 7, 70, 'seven' -------------------------------------------------------------------------------- delete from a where a = 2 or a = 4 or a = 6; 3 rows inserted/updated/deleted ij> commit; ij> CALL SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.language.bulkFetchDefault','1'); 0 rows inserted/updated/deleted ij> -- RESOLVE: missing row locks -- WORKAROUND: creating an index and dropping it -- to force the query 'select a, b, c from a' to be recompiled create index ix1 on a(a); 0 rows inserted/updated/deleted ij> drop index ix1; 0 rows inserted/updated/deleted ij> commit; ij> get cursor scan_cursor as 'select a, b, c from a'; ij> call SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.language.bulkFetchDefault', '16'); 0 rows inserted/updated/deleted ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |S |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 1 |10 |one & ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |S |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 3 |30 |three & ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |S |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 5 |50 |five & ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |S |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 7 |70 |seven & ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |S |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; No current row ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |S |A |Tablelock |GRANT|ACTIVE ij> close scan_cursor; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |S |A |Tablelock |GRANT|ACTIVE ij> commit; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> -------------------------------------------------------------------------------- -- TEST 5: heap cursor scan, group fetch = 2 (scan with committed deleted rows) -- Test full cursor scan on a data set with some deleted rows (the "even" ones). -- SERIALIZABLE - will get table level S lock. -- REPEATABLE READ - TABLE IS, will get row S locks as it visits each row -- (including deleted ones). -- READ COMMITTED - TABLE IS, will get instantaneous locks and release -- READ UNCOMMITTED - TABLE IS, no row locks. -- -- At this point the table should look like: -- 1, 10, 'one' -- 3, 30, 'three' -- 5, 50, 'five' -- 7, 70, 'seven' -------------------------------------------------------------------------------- CALL SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.language.bulkFetchDefault','2'); 0 rows inserted/updated/deleted ij> -- RESOLVE: missing row locks -- WORKAROUND: creating an index and dropping it -- to force the query 'select a, b, c from a' to be recompiled create index ix1 on a(a); 0 rows inserted/updated/deleted ij> drop index ix1; 0 rows inserted/updated/deleted ij> commit; ij> get cursor scan_cursor as 'select a, b, c from a'; ij> call SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.language.bulkFetchDefault', '16'); 0 rows inserted/updated/deleted ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |S |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 1 |10 |one & ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |S |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 3 |30 |three & ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |S |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 5 |50 |five & ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |S |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 7 |70 |seven & ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |S |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; No current row ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |S |A |Tablelock |GRANT|ACTIVE ij> close scan_cursor; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |S |A |Tablelock |GRANT|ACTIVE ij> commit; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> -------------------------------------------------------------------------------- -- TEST 6: heap cursor scan, group fetch = 1 (scan with "<" qualifier) -- Test "less than" qualified cursor scan on a data set. -- SERIALIZABLE - will get table level S lock. -- REPEATABLE READ - TABLE IS, will get row S locks as it visits each row -- (including deleted ones). -- READ COMMITTED - TABLE IS, will get instantaneous locks and release -- READ UNCOMMITTED - TABLE IS, no row locks. -- -- At this point the table should look like: -- 1, 10, 'one' -- 3, 30, 'three' -- 5, 50, 'five' -- 7, 70, 'seven' -------------------------------------------------------------------------------- CALL SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.language.bulkFetchDefault','1'); 0 rows inserted/updated/deleted ij> get cursor scan_cursor as 'select a, b, c from a where a < 3'; ij> call SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.language.bulkFetchDefault', '16'); 0 rows inserted/updated/deleted ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |S |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 1 |10 |one & ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |S |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; No current row ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |S |A |Tablelock |GRANT|ACTIVE ij> close scan_cursor; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |S |A |Tablelock |GRANT|ACTIVE ij> commit; ij> -------------------------------------------------------------------------------- -- TEST 7: heap cursor scan, group fetch = 2 (scan with "<" qualifier) -- Test "less than" qualified cursor scan on a data set. -- SERIALIZABLE - will get table level S lock. -- REPEATABLE READ - TABLE IS, will get row S locks as it visits each row -- (including deleted ones). -- READ COMMITTED - TABLE IS, will get instantaneous locks and release -- READ UNCOMMITTED - TABLE IS, no row locks. -- -- At this point the table should look like: -- 1, 10, 'one' -- 3, 30, 'three' -- 5, 50, 'five' -- 7, 70, 'seven' -------------------------------------------------------------------------------- CALL SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.language.bulkFetchDefault','2'); 0 rows inserted/updated/deleted ij> -- RESOLVE: missing row locks -- WORKAROUND: creating an index and dropping it -- to force the statement to be recompiled create index ix1 on a(a); 0 rows inserted/updated/deleted ij> drop index ix1; 0 rows inserted/updated/deleted ij> commit; ij> get cursor scan_cursor as 'select a, b, c from a where a < 3'; ij> call SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.language.bulkFetchDefault', '16'); 0 rows inserted/updated/deleted ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |S |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 1 |10 |one & ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |S |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; No current row ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |S |A |Tablelock |GRANT|ACTIVE ij> close scan_cursor; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |S |A |Tablelock |GRANT|ACTIVE ij> commit; ij> -------------------------------------------------------------------------------- -- TEST 8: heap cursor scan, group fetch = 1 (scan with equals qualifier) -- Test "equals" qualified cursor scan on a data set. -- SERIALIZABLE - will get table level S lock. -- REPEATABLE READ - TABLE IS, will get row S locks as it visits each row -- (including deleted ones). -- READ COMMITTED - TABLE IS, will get instantaneous locks and release -- READ UNCOMMITTED - TABLE IS, no row locks. -- -- At this point the table should look like: -- 1, 10, 'one' -- 3, 30, 'three' -- 5, 50, 'five' -- 7, 70, 'seven' -------------------------------------------------------------------------------- CALL SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.language.bulkFetchDefault','1'); 0 rows inserted/updated/deleted ij> get cursor scan_cursor as 'select a, b, c from a where a = 5'; ij> call SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.language.bulkFetchDefault', '16'); 0 rows inserted/updated/deleted ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |S |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 5 |50 |five & ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |S |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; No current row ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |S |A |Tablelock |GRANT|ACTIVE ij> close scan_cursor; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |S |A |Tablelock |GRANT|ACTIVE ij> commit; ij> -------------------------------------------------------------------------------- -- TEST 9: heap cursor scan, group fetch = 2 (scan with equals qualifier) -- Test "equals" qualified cursor scan on a data set. -- SERIALIZABLE - will get table level S lock. -- REPEATABLE READ - TABLE IS, will get row S locks as it visits each row -- (including deleted ones). -- READ COMMITTED - TABLE IS, will get instantaneous locks and release -- READ UNCOMMITTED - TABLE IS, no row locks. -- -- At this point the table should look like: -- 1, 10, 'one' -- 3, 30, 'three' -- 5, 50, 'five' -- 7, 70, 'seven' -------------------------------------------------------------------------------- CALL SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.language.bulkFetchDefault','2'); 0 rows inserted/updated/deleted ij> get cursor scan_cursor as 'select a, b, c from a where a = 7'; ij> call SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.language.bulkFetchDefault', '16'); 0 rows inserted/updated/deleted ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |S |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 7 |70 |seven & ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |S |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; No current row ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |S |A |Tablelock |GRANT|ACTIVE ij> close scan_cursor; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |S |A |Tablelock |GRANT|ACTIVE ij> commit; ij> -------------------------------------------------------------------------------- -- TEST 10: heap cursor scan, group fetch = 1 (equals qualifier, no rows return) -- Test "equals" qualified cursor scan on a data set, no rows returned. -- SERIALIZABLE - will get table level S lock. -- REPEATABLE READ - TABLE IS, will get row S locks as it visits each row -- (including deleted ones). -- READ COMMITTED - TABLE IS, will get instantaneous locks and release -- READ UNCOMMITTED - TABLE IS, no row locks. -- -- At this point the table should look like: -- 1, 10, 'one' -- 3, 30, 'three' -- 5, 50, 'five' -- 7, 70, 'seven' -------------------------------------------------------------------------------- CALL SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.language.bulkFetchDefault','1'); 0 rows inserted/updated/deleted ij> -- RESOLVE: missing row locks -- WORKAROUND: creating an index and dropping it -- to force the statement to be recompiled create index ix1 on a(a); 0 rows inserted/updated/deleted ij> drop index ix1; 0 rows inserted/updated/deleted ij> commit; ij> get cursor scan_cursor as 'select a, b, c from a where a = 7'; ij> CALL SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.language.bulkFetchDefault','16'); 0 rows inserted/updated/deleted ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |S |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 7 |70 |seven & ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |S |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; No current row ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |S |A |Tablelock |GRANT|ACTIVE ij> close scan_cursor; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |S |A |Tablelock |GRANT|ACTIVE ij> commit; ij> drop table a; 0 rows inserted/updated/deleted ij> -- non cursor, no index run drop table a; ERROR 42Y55: 'DROP TABLE' cannot be performed on 'A' because it does not exist. ij> -- to create tables of page size 4k and still keep the following tbl -- create table a (a int, b int, c varchar(1900)); create table a(a int, b int); 0 rows inserted/updated/deleted ij> alter table a add column c varchar(1900); 0 rows inserted/updated/deleted ij> insert into a values (1, 10, PADSTRING('one', 1900)); 1 row inserted/updated/deleted ij> insert into a values (2, 20, PADSTRING('two', 1900)); 1 row inserted/updated/deleted ij> insert into a values (3, 30, PADSTRING('three', 1900)); 1 row inserted/updated/deleted ij> insert into a values (4, 40, PADSTRING('four', 1900)); 1 row inserted/updated/deleted ij> insert into a values (5, 50, PADSTRING('five', 1900)); 1 row inserted/updated/deleted ij> insert into a values (6, 60, PADSTRING('six', 1900)); 1 row inserted/updated/deleted ij> insert into a values (7, 70, PADSTRING('seven', 1900)); 1 row inserted/updated/deleted ij> commit; ij> run resource 'readSetLocks.subsql'; 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. -- -- Very basic single user testing of read locks in "set" queries on heap tables. -- This ".subsql" test is -- meant to be run from another test such that it gets run under multiple -- isolation levels. This is important as they behave -- differently, depending on isolation levels. -- -- assume's caller has already done: run 'LockTableQuery.subsql'; to get -- easy access to the lock VTI. -- TEST 0: heap scan. -- TEST 1: heap scan, some rows deleted. -- TEST 2: heap scan, (scan with "<" qualifier) -- TEST 3: heap scan, (scan with equals qualifier) -- TEST 4: heap scan, (equals qualifier, no rows return) autocommit off; ij> -------------------------------------------------------------------------------- -- Assumes that calling routine has set up the following simple dataset, -- a heap, no indexes with following initial values: -- create table (a int, b int, c somesortofchar); -- 1, 10, 'one' -- 2, 20, 'two' -- 3, 30, 'three' -- 4, 40, 'four' -- 5, 50, 'five' -- 6, 60, 'six' -- 7, 70, 'seven' -------------------------------------------------------------------------------- select * from a; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 1 |10 |one & 2 |20 |two & 3 |30 |three & 4 |40 |four & 5 |50 |five & 6 |60 |six & 7 |70 |seven & ij> commit; ij> -------------------------------------------------------------------------------- -- TEST 0: heap scan. -- Test full cursor scan which does no updates. -- SERIALIZABLE - will get table level S lock, held to end of xact. -- REPEATABLE READ - TABLE IS, will get row S locks as it visits each row -- (including deleted ones). held to end of xact. -- READ COMMITTED - TABLE IS, will get instantaneous locks and release. No -- locks held when statement completes. -- READ UNCOMMITTED - TABLE IS, no row locks. No locks after statement ends. -------------------------------------------------------------------------------- select a, b, c from a; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 1 |10 |one & 2 |20 |two & 3 |30 |three & 4 |40 |four & 5 |50 |five & 6 |60 |six & 7 |70 |seven & ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |S |A |Tablelock |GRANT|ACTIVE ij> commit; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> -------------------------------------------------------------------------------- -- TEST 1: heap scan, some rows deleted. -- Test full cursor scan on a data set with some deleted rows (the "even" ones). -- SERIALIZABLE - will get table level S lock. -- REPEATABLE READ - TABLE IS, will get row S locks as it visits each row -- (including deleted ones). -- READ COMMITTED - TABLE IS, will get instantaneous locks and release -- READ UNCOMMITTED - TABLE IS, no row locks. -- SERIALIZABLE - will get table level S lock, held to end of xact. -- REPEATABLE READ - TABLE IS, will get row S locks as it visits each row -- (including deleted ones). held to end of xact. -- READ COMMITTED - TABLE IS, will get instantaneous locks and release. No -- locks held when statement completes. -- READ UNCOMMITTED - TABLE IS, no row locks. No locks after statement ends. -- -- After the delete the table should look like: -- 1, 10, 'one' -- 3, 30, 'three' -- 5, 50, 'five' -- 7, 70, 'seven' -------------------------------------------------------------------------------- delete from a where a = 2 or a = 4 or a = 6; 3 rows inserted/updated/deleted ij> commit; ij> select a, b, c from a; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 1 |10 |one & 3 |30 |three & 5 |50 |five & 7 |70 |seven & ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |S |A |Tablelock |GRANT|ACTIVE ij> commit; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> -------------------------------------------------------------------------------- -- TEST 2: heap scan, (scan with "<" qualifier) -- Test "less than" qualified cursor scan on a data set. -- SERIALIZABLE - will get table level S lock, held to end of xact. -- REPEATABLE READ - TABLE IS, will get row S locks as it visits each row -- (including deleted ones). held to end of xact. -- READ COMMITTED - TABLE IS, will get instantaneous locks and release. No -- locks held when statement completes. -- READ UNCOMMITTED - TABLE IS, no row locks. No locks after statement ends. -- -- At this point the table should look like: -- 1, 10, 'one' -- 3, 30, 'three' -- 5, 50, 'five' -- 7, 70, 'seven' -------------------------------------------------------------------------------- select a, b, c from a; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 1 |10 |one & 3 |30 |three & 5 |50 |five & 7 |70 |seven & ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |S |A |Tablelock |GRANT|ACTIVE ij> commit; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> -------------------------------------------------------------------------------- -- TEST 3: heap scan, (scan with equals qualifier) -- Test "equals" qualified cursor scan on a data set. -- SERIALIZABLE - will get table level S lock, held to end of xact. -- REPEATABLE READ - TABLE IS, will get row S locks as it visits each row -- (including deleted ones). held to end of xact. -- READ COMMITTED - TABLE IS, will get instantaneous locks and release. No -- locks held when statement completes. -- READ UNCOMMITTED - TABLE IS, no row locks. No locks after statement ends. -- -- At this point the table should look like: -- 1, 10, 'one' -- 3, 30, 'three' -- 5, 50, 'five' -- 7, 70, 'seven' -------------------------------------------------------------------------------- select a, b, c from a where a = 5; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 5 |50 |five & ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |S |A |Tablelock |GRANT|ACTIVE ij> commit; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> -------------------------------------------------------------------------------- -- TEST 4: heap scan, (equals qualifier, no rows return) -- Test "equals" qualified cursor scan on a data set, no rows returned. -- SERIALIZABLE - will get table level S lock, held to end of xact. -- REPEATABLE READ - TABLE IS, will get row S locks as it visits each row -- (including deleted ones). held to end of xact. -- READ COMMITTED - TABLE IS, will get instantaneous locks and release. No -- locks held when statement completes. -- READ UNCOMMITTED - TABLE IS, no row locks. No locks after statement ends. -- -- At this point the table should look like: -- 1, 10, 'one' -- 3, 30, 'three' -- 5, 50, 'five' -- 7, 70, 'seven' -------------------------------------------------------------------------------- select a, b, c from a where a = 7; A |B |C -------------------------------------------------------------------------------------------------------------------------------------------------------- 7 |70 |seven & ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |S |A |Tablelock |GRANT|ACTIVE ij> commit; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> drop table a; 0 rows inserted/updated/deleted ij> -- cursor, unique index run drop table a; ERROR 42Y55: 'DROP TABLE' cannot be performed on 'A' because it does not exist. ij> create table a (a int, b int, c varchar(1900), index_pad varchar(600) ) ; 0 rows inserted/updated/deleted ij> insert into a values (1, 10, PADSTRING('one', 1900), PADSTRING('index pad 1',600)); 1 row inserted/updated/deleted ij> insert into a values (2, 20, PADSTRING('two', 1900), PADSTRING('index pad 2',600)); 1 row inserted/updated/deleted ij> insert into a values (3, 30, PADSTRING('three', 1900), PADSTRING('index pad 3',600)); 1 row inserted/updated/deleted ij> insert into a values (4, 40, PADSTRING('four', 1900), PADSTRING('index pad 4',600)); 1 row inserted/updated/deleted ij> insert into a values (5, 50, PADSTRING('five', 1900), PADSTRING('index pad 5',600)); 1 row inserted/updated/deleted ij> insert into a values (6, 60, PADSTRING('six', 1900), PADSTRING('index pad 6',600)); 1 row inserted/updated/deleted ij> insert into a values (7, 70, PADSTRING('seven', 1900), PADSTRING('index pad 7',600)); 1 row inserted/updated/deleted ij> create unique index a_idx on a (a, index_pad) ; 0 rows inserted/updated/deleted ij> commit; ij> run resource 'readBtreeCursorLocks.subsql'; 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. -- -- Very basic single user testing of read locks on cursors on indexes. -- This ".subsql" test is -- meant to be run from another test such that it gets run under multiple -- isolation levels. This is important as they behave -- differently, depending on isolation levels. -- -- assume's caller has already done: run 'LockTableQuery.subsql'; to get -- easy access to the lock VTI. -- TEST 0: btree cursor scan, group fetch = 1 -- TEST 1: btree cursor scan, group fetch = 2 -- TEST 2: btree cursor scan, group fetch = 1 stop scan in middle of set -- TEST 3: btree cursor scan, group fetch = 4 stop scan in middle of set -- TEST 4: btree cursor scan, group fetch = 1 (scan with some deleted rows) -- TEST 5: btree cursor scan, group fetch = 2(scan with committed deleted rows) -- TEST 6: btree cursor scan, group fetch = 1 (scan with "<" qualifier) -- TEST 7: btree cursor scan, group fetch = 2 (scan with "<" qualifier) -- TEST 8: btree cursor scan, group fetch = 1 (scan with equals qualifier) -- TEST 9: btree cursor scan, group fetch = 2 (scan with equals qualifier) -- TEST 10: btree cursor scan, group fetch = 1 ("=" qualifier, no rows return) autocommit off; ij> -------------------------------------------------------------------------------- -- Assumes that calling routine has set up the following simple dataset, -- a heap, and index with following initial values: -- create table a (a int, b int, c somesortofchar, [index_pad]); -- create index a_idx on a (a) or a_idx on a (a, index_pad); -- -- 1, 10, 'one' -- 2, 20, 'two' -- 3, 30, 'three' -- 4, 40, 'four' -- 5, 50, 'five' -- 6, 60, 'six' -- 7, 70, 'seven' -------------------------------------------------------------------------------- select * from a; A |B |C |INDEX_PAD ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- 1 |10 |one &|index pad 1 & 2 |20 |two &|index pad 2 & 3 |30 |three &|index pad 3 & 4 |40 |four &|index pad 4 & 5 |50 |five &|index pad 5 & 6 |60 |six &|index pad 6 & 7 |70 |seven &|index pad 7 & ij> commit; ij> -------------------------------------------------------------------------------- -- TEST 0: btree cursor scan, group fetch = 1 -- Test full cursor scan which does no updates. -- ALL MODES - TABLE IS, "scan page lockname of form (pageno, 1) -- SERIALIZABLE - row S locks as it visits each row, held until end xact -- REPEATABLE READ - row S locks as it visits each row, held until end xact -- READ COMMITTED - row S lock on current row, released on move to next row -- READ UNCOMMITTED - no row locks. ------------------------------------------------------------------------------- CALL SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.language.bulkFetchDefault','1'); 0 rows inserted/updated/deleted ij> -- RESOLVE: missing row locks -- WORKAROUND: creating an index and dropping it -- to force the statement to be recompiled create index ix1 on a(a); 0 rows inserted/updated/deleted ij> drop index ix1; 0 rows inserted/updated/deleted ij> commit; ij> get cursor scan_cursor as 'select a from a'; ij> call SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.language.bulkFetchDefault', '16'); 0 rows inserted/updated/deleted ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |S |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A ----------- 1 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |S |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A ----------- 2 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |S |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A ----------- 3 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |S |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A ----------- 4 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |S |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A ----------- 5 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |S |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A ----------- 6 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |S |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A ----------- 7 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |S |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; No current row ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |S |A |Tablelock |GRANT|ACTIVE ij> close scan_cursor; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |S |A |Tablelock |GRANT|ACTIVE ij> commit; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> -------------------------------------------------------------------------------- -- TEST 1: btree cursor scan, group fetch = 2 -- Test full cursor scan which does no updates. -- ALL MODES - TABLE IS, "scan page lockname of form (pageno, 1) -- SERIALIZABLE - row S locks as it visits each row, held until end xact -- REPEATABLE READ - row S locks as it visits each row, held until end xact -- READ COMMITTED - row S lock on current row, released on move to next row -- READ UNCOMMITTED - no row locks. -------------------------------------------------------------------------------- CALL SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.language.bulkFetchDefault','2'); 0 rows inserted/updated/deleted ij> -- RESOLVE: missing row locks -- WORKAROUND: creating an index and dropping it -- to force the statement to be recompiled create index ix1 on a(a); 0 rows inserted/updated/deleted ij> drop index ix1; 0 rows inserted/updated/deleted ij> commit; ij> get cursor scan_cursor as 'select a from a'; ij> call SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.language.bulkFetchDefault', '16'); 0 rows inserted/updated/deleted ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |S |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A ----------- 1 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |S |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A ----------- 2 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |S |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A ----------- 3 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |S |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A ----------- 4 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |S |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A ----------- 5 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |S |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A ----------- 6 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |S |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A ----------- 7 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |S |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; No current row ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |S |A |Tablelock |GRANT|ACTIVE ij> close scan_cursor; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |S |A |Tablelock |GRANT|ACTIVE ij> commit; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> -------------------------------------------------------------------------------- -- TEST 2: btree cursor scan, group fetch = 1, stop scan in middle of set -- Test full cursor scan which does no updates. -- ALL MODES - TABLE IS, "scan page lockname of form (pageno, 1) -- SERIALIZABLE - row S locks as it visits each row, held until end xact -- REPEATABLE READ - row S locks as it visits each row, held until end xact -- READ COMMITTED - row S lock on current row, released on move to next row -- READ UNCOMMITTED - no row locks. -------------------------------------------------------------------------------- CALL SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.language.bulkFetchDefault','1'); 0 rows inserted/updated/deleted ij> -- RESOLVE: missing row locks -- WORKAROUND: creating an index and dropping it -- to force the statement to be recompiled create index ix1 on a(a); 0 rows inserted/updated/deleted ij> drop index ix1; 0 rows inserted/updated/deleted ij> commit; ij> get cursor scan_cursor as 'select a from a'; ij> call SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.language.bulkFetchDefault', '16'); 0 rows inserted/updated/deleted ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |S |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A ----------- 1 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |S |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A ----------- 2 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |S |A |Tablelock |GRANT|ACTIVE ij> close scan_cursor; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |S |A |Tablelock |GRANT|ACTIVE ij> commit; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> -------------------------------------------------------------------------------- -- TEST 3: btree cursor scan, group fetch = 4, stop scan in middle of set -- Test full cursor scan which does no updates. -- ALL MODES - TABLE IS, "scan page lockname of form (pageno, 1) -- SERIALIZABLE - row S locks as it visits each row, held until end xact -- REPEATABLE READ - row S locks as it visits each row, held until end xact -- READ COMMITTED - row S lock on current row, released on move to next row -- READ UNCOMMITTED - no row locks. -------------------------------------------------------------------------------- CALL SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.language.bulkFetchDefault','4'); 0 rows inserted/updated/deleted ij> -- RESOLVE: missing row locks -- WORKAROUND: creating an index and dropping it -- to force the statement to be recompiled create index ix1 on a(a); 0 rows inserted/updated/deleted ij> drop index ix1; 0 rows inserted/updated/deleted ij> commit; ij> get cursor scan_cursor as 'select a from a'; ij> call SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.language.bulkFetchDefault', '16'); 0 rows inserted/updated/deleted ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |S |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A ----------- 1 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |S |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A ----------- 2 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |S |A |Tablelock |GRANT|ACTIVE ij> close scan_cursor; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |S |A |Tablelock |GRANT|ACTIVE ij> commit; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> -------------------------------------------------------------------------------- -- TEST 4: btree cursor scan, group fetch = 1 (scan table with some deleted rows) -- Test full cursor scan on a data set with some deleted rows (the "even" ones). -- ALL MODES - TABLE IS, "scan page lockname of form (pageno, 1) -- SERIALIZABLE - row S locks as it visits each row, held until end xact -- REPEATABLE READ - row S locks as it visits each row, held until end xact -- READ COMMITTED - row S lock on current row, released on move to next row -- READ UNCOMMITTED - no row locks. -- -- After the delete the base table should look like: -- 1, 10, 'one' -- 3, 30, 'three' -- 5, 50, 'five' -- 7, 70, 'seven' -------------------------------------------------------------------------------- delete from a where a = 2 or a = 4 or a = 6; 3 rows inserted/updated/deleted ij> commit; ij> CALL SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.language.bulkFetchDefault','1'); 0 rows inserted/updated/deleted ij> -- RESOLVE: missing row locks -- WORKAROUND: creating an index and dropping it -- to force the statement to be recompiled create index ix1 on a(a); 0 rows inserted/updated/deleted ij> drop index ix1; 0 rows inserted/updated/deleted ij> commit; ij> get cursor scan_cursor as 'select a from a'; ij> call SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.language.bulkFetchDefault', '16'); 0 rows inserted/updated/deleted ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |S |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A ----------- 1 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |S |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A ----------- 3 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |S |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A ----------- 5 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |S |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A ----------- 7 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |S |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; No current row ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |S |A |Tablelock |GRANT|ACTIVE ij> close scan_cursor; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |S |A |Tablelock |GRANT|ACTIVE ij> commit; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> -------------------------------------------------------------------------------- -- TEST 5: btree cursor scan, group fetch = 2 (scan with committed deleted rows) -- Test full cursor scan on a data set with some deleted rows (the "even" ones). -- ALL MODES - TABLE IS, "scan page lockname of form (pageno, 1) -- SERIALIZABLE - row S locks as it visits each row, held until end xact -- REPEATABLE READ - row S locks as it visits each row, held until end xact -- READ COMMITTED - row S lock on current row, released on move to next row -- READ UNCOMMITTED - no row locks. -- -- At this point the base table should look like: -- 1, 10, 'one' -- 3, 30, 'three' -- 5, 50, 'five' -- 7, 70, 'seven' -------------------------------------------------------------------------------- CALL SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.language.bulkFetchDefault','2'); 0 rows inserted/updated/deleted ij> -- RESOLVE: missing row locks -- WORKAROUND: creating an index and dropping it -- to force the statement to be recompiled create index ix1 on a(a); 0 rows inserted/updated/deleted ij> drop index ix1; 0 rows inserted/updated/deleted ij> commit; ij> get cursor scan_cursor as 'select a from a'; ij> call SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.language.bulkFetchDefault', '16'); 0 rows inserted/updated/deleted ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |S |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A ----------- 1 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |S |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A ----------- 3 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |S |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A ----------- 5 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |S |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A ----------- 7 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |S |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; No current row ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |S |A |Tablelock |GRANT|ACTIVE ij> close scan_cursor; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |S |A |Tablelock |GRANT|ACTIVE ij> commit; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> -------------------------------------------------------------------------------- -- TEST 6: btree cursor scan, group fetch = 1 (scan with "<" qualifier) -- Test "less than" qualified cursor scan on a data set. -- ALL MODES - TABLE IS, "scan page lockname of form (pageno, 1) -- SERIALIZABLE - row S locks as it visits each row, held until end xact -- REPEATABLE READ - row S locks as it visits each row, held until end xact -- READ COMMITTED - row S lock on current row, released on move to next row -- READ UNCOMMITTED - no row locks. -- -- At this point the base table should look like: -- 1, 10, 'one' -- 3, 30, 'three' -- 5, 50, 'five' -- 7, 70, 'seven' -------------------------------------------------------------------------------- CALL SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.language.bulkFetchDefault','1'); 0 rows inserted/updated/deleted ij> -- RESOLVE: missing row locks -- WORKAROUND: creating an index and dropping it -- to force the statement to be recompiled create index ix1 on a(a); 0 rows inserted/updated/deleted ij> drop index ix1; 0 rows inserted/updated/deleted ij> commit; ij> get cursor scan_cursor as 'select a from a where a < 3'; ij> call SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.language.bulkFetchDefault', '16'); 0 rows inserted/updated/deleted ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A ----------- 1 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,3) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(2,1) |GRANT|ACTIVE ij> next scan_cursor; No current row ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,3) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(2,6) |GRANT|ACTIVE ij> close scan_cursor; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,3) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(2,6) |GRANT|ACTIVE ij> commit; ij> -------------------------------------------------------------------------------- -- TEST 7: btree cursor scan, group fetch = 2 (scan with "<" qualifier) -- Test "less than" qualified cursor scan on a data set. -- ALL MODES - TABLE IS, "scan page lockname of form (pageno, 1) -- SERIALIZABLE - row S locks as it visits each row, held until end xact -- REPEATABLE READ - row S locks as it visits each row, held until end xact -- READ COMMITTED - row S lock on current row, released on move to next row -- READ UNCOMMITTED - no row locks. -- -- At this point the base table should look like: -- 1, 10, 'one' -- 3, 30, 'three' -- 5, 50, 'five' -- 7, 70, 'seven' -------------------------------------------------------------------------------- CALL SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.language.bulkFetchDefault','2'); 0 rows inserted/updated/deleted ij> -- RESOLVE: missing row locks -- WORKAROUND: creating an index and dropping it -- to force the statement to be recompiled create index ix1 on a(a); 0 rows inserted/updated/deleted ij> drop index ix1; 0 rows inserted/updated/deleted ij> commit; ij> get cursor scan_cursor as 'select a from a where a < 3'; ij> call SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.language.bulkFetchDefault', '16'); 0 rows inserted/updated/deleted ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A ----------- 1 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,3) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(2,6) |GRANT|ACTIVE ij> next scan_cursor; No current row ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,3) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(2,6) |GRANT|ACTIVE ij> close scan_cursor; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,3) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(2,6) |GRANT|ACTIVE ij> commit; ij> -------------------------------------------------------------------------------- -- TEST 8: btree cursor scan, group fetch = 1 (scan with equals qualifier) -- Test "equals" qualified cursor scan on a data set. -- ALL MODES - TABLE IS, "scan page lockname of form (pageno, 1) -- SERIALIZABLE - row S locks as it visits each row, held until end xact -- REPEATABLE READ - row S locks as it visits each row, held until end xact -- READ COMMITTED - row S lock on current row, released on move to next row -- READ UNCOMMITTED - no row locks. -- -- At this point the base table should look like: -- 1, 10, 'one' -- 3, 30, 'three' -- 5, 50, 'five' -- 7, 70, 'seven' -------------------------------------------------------------------------------- CALL SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.language.bulkFetchDefault','1'); 0 rows inserted/updated/deleted ij> -- RESOLVE: missing row locks -- WORKAROUND: creating an index and dropping it -- to force the statement to be recompiled create index ix1 on a(a); 0 rows inserted/updated/deleted ij> drop index ix1; 0 rows inserted/updated/deleted ij> commit; ij> get cursor scan_cursor as 'select a from a where a = 5'; ij> call SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.language.bulkFetchDefault', '16'); 0 rows inserted/updated/deleted ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A ----------- 5 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(2,1) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(4,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(5,6) |GRANT|ACTIVE ij> next scan_cursor; No current row ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(4,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(5,6) |GRANT|ACTIVE ij> close scan_cursor; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(4,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(5,6) |GRANT|ACTIVE ij> commit; ij> -------------------------------------------------------------------------------- -- TEST 9: btree cursor scan, group fetch = 2 (scan with equals qualifier) -- Test "equals" qualified cursor scan on a data set. -- ALL MODES - TABLE IS, "scan page lockname of form (pageno, 1) -- SERIALIZABLE - row S locks as it visits each row, held until end xact -- REPEATABLE READ - row S locks as it visits each row, held until end xact -- READ COMMITTED - row S lock on current row, released on move to next row -- READ UNCOMMITTED - no row locks. -- -- At this point the base table should look like: -- 1, 10, 'one' -- 3, 30, 'three' -- 5, 50, 'five' -- 7, 70, 'seven' -------------------------------------------------------------------------------- CALL SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.language.bulkFetchDefault','2'); 0 rows inserted/updated/deleted ij> -- RESOLVE: missing row locks -- WORKAROUND: creating an index and dropping it -- to force the statement to be recompiled create index ix1 on a(a); 0 rows inserted/updated/deleted ij> drop index ix1; 0 rows inserted/updated/deleted ij> commit; ij> get cursor scan_cursor as 'select a from a where a = 5 or a = 7'; ij> call SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.language.bulkFetchDefault', '16'); 0 rows inserted/updated/deleted ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A ----------- 5 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(2,1) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(4,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(5,6) |GRANT|ACTIVE ij> next scan_cursor; A ----------- 7 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(3,1) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(4,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(5,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(6,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(7,6) |GRANT|ACTIVE ij> close scan_cursor; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(4,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(5,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(6,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(7,6) |GRANT|ACTIVE ij> commit; ij> -------------------------------------------------------------------------------- -- TEST 10: btree cursor scan, group fetch = 1 (equals qualifier, no rows return) -- Test "equals" qualified cursor scan on a data set, no rows returned. -- ALL MODES - TABLE IS, "scan page lockname of form (pageno, 1) -- SERIALIZABLE - row S locks as it visits each row, held until end xact -- REPEATABLE READ - row S locks as it visits each row, held until end xact -- READ COMMITTED - row S lock on current row, released on move to next row -- READ UNCOMMITTED - no row locks. -- -- At this point the base table should look like: -- 1, 10, 'one' -- 3, 30, 'three' -- 5, 50, 'five' -- 7, 70, 'seven' -------------------------------------------------------------------------------- -- no rows expected to qualify CALL SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.language.bulkFetchDefault','1'); 0 rows inserted/updated/deleted ij> -- RESOLVE: missing row locks -- WORKAROUND: creating an index and dropping it -- to force the statement to be recompiled create index ix1 on a(a); 0 rows inserted/updated/deleted ij> drop index ix1; 0 rows inserted/updated/deleted ij> commit; ij> get cursor scan_cursor as 'select a from a where a = 42'; ij> call SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.language.bulkFetchDefault', '16'); 0 rows inserted/updated/deleted ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; No current row ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(7,6) |GRANT|ACTIVE ij> next scan_cursor; No current row ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(7,6) |GRANT|ACTIVE ij> close scan_cursor; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(7,6) |GRANT|ACTIVE ij> commit; ij> drop table a; 0 rows inserted/updated/deleted ij> -- cursor, non-unique index run drop table a; ERROR 42Y55: 'DROP TABLE' cannot be performed on 'A' because it does not exist. ij> create table a (a int, b int, c varchar(1900), index_pad varchar(700) ) ; 0 rows inserted/updated/deleted ij> insert into a values (1, 10, PADSTRING('one',1900), PADSTRING('index pad 1',700)); 1 row inserted/updated/deleted ij> insert into a values (2, 20, PADSTRING('two',1900), PADSTRING('index pad 2',700)); 1 row inserted/updated/deleted ij> insert into a values (3, 30, PADSTRING('three',1900), PADSTRING('index pad 3',700)); 1 row inserted/updated/deleted ij> insert into a values (4, 40, PADSTRING('four',1900), PADSTRING('index pad 4',700)); 1 row inserted/updated/deleted ij> insert into a values (5, 50, PADSTRING('five',1900), PADSTRING('index pad 5',700)); 1 row inserted/updated/deleted ij> insert into a values (6, 60, PADSTRING('six',1900), PADSTRING('index pad 6',700)); 1 row inserted/updated/deleted ij> insert into a values (7, 70, PADSTRING('seven',1900), PADSTRING('index pad 7',700)); 1 row inserted/updated/deleted ij> create index a_idx on a (a, index_pad) ; 0 rows inserted/updated/deleted ij> commit; ij> run resource 'readBtreeCursorLocks.subsql'; 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. -- -- Very basic single user testing of read locks on cursors on indexes. -- This ".subsql" test is -- meant to be run from another test such that it gets run under multiple -- isolation levels. This is important as they behave -- differently, depending on isolation levels. -- -- assume's caller has already done: run 'LockTableQuery.subsql'; to get -- easy access to the lock VTI. -- TEST 0: btree cursor scan, group fetch = 1 -- TEST 1: btree cursor scan, group fetch = 2 -- TEST 2: btree cursor scan, group fetch = 1 stop scan in middle of set -- TEST 3: btree cursor scan, group fetch = 4 stop scan in middle of set -- TEST 4: btree cursor scan, group fetch = 1 (scan with some deleted rows) -- TEST 5: btree cursor scan, group fetch = 2(scan with committed deleted rows) -- TEST 6: btree cursor scan, group fetch = 1 (scan with "<" qualifier) -- TEST 7: btree cursor scan, group fetch = 2 (scan with "<" qualifier) -- TEST 8: btree cursor scan, group fetch = 1 (scan with equals qualifier) -- TEST 9: btree cursor scan, group fetch = 2 (scan with equals qualifier) -- TEST 10: btree cursor scan, group fetch = 1 ("=" qualifier, no rows return) autocommit off; ij> -------------------------------------------------------------------------------- -- Assumes that calling routine has set up the following simple dataset, -- a heap, and index with following initial values: -- create table a (a int, b int, c somesortofchar, [index_pad]); -- create index a_idx on a (a) or a_idx on a (a, index_pad); -- -- 1, 10, 'one' -- 2, 20, 'two' -- 3, 30, 'three' -- 4, 40, 'four' -- 5, 50, 'five' -- 6, 60, 'six' -- 7, 70, 'seven' -------------------------------------------------------------------------------- select * from a; A |B |C |INDEX_PAD ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- 1 |10 |one &|index pad 1 & 2 |20 |two &|index pad 2 & 3 |30 |three &|index pad 3 & 4 |40 |four &|index pad 4 & 5 |50 |five &|index pad 5 & 6 |60 |six &|index pad 6 & 7 |70 |seven &|index pad 7 & ij> commit; ij> -------------------------------------------------------------------------------- -- TEST 0: btree cursor scan, group fetch = 1 -- Test full cursor scan which does no updates. -- ALL MODES - TABLE IS, "scan page lockname of form (pageno, 1) -- SERIALIZABLE - row S locks as it visits each row, held until end xact -- REPEATABLE READ - row S locks as it visits each row, held until end xact -- READ COMMITTED - row S lock on current row, released on move to next row -- READ UNCOMMITTED - no row locks. ------------------------------------------------------------------------------- CALL SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.language.bulkFetchDefault','1'); 0 rows inserted/updated/deleted ij> -- RESOLVE: missing row locks -- WORKAROUND: creating an index and dropping it -- to force the statement to be recompiled create index ix1 on a(a); 0 rows inserted/updated/deleted ij> drop index ix1; 0 rows inserted/updated/deleted ij> commit; ij> get cursor scan_cursor as 'select a from a'; ij> call SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.language.bulkFetchDefault', '16'); 0 rows inserted/updated/deleted ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |S |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A ----------- 1 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |S |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A ----------- 2 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |S |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A ----------- 3 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |S |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A ----------- 4 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |S |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A ----------- 5 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |S |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A ----------- 6 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |S |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A ----------- 7 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |S |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; No current row ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |S |A |Tablelock |GRANT|ACTIVE ij> close scan_cursor; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |S |A |Tablelock |GRANT|ACTIVE ij> commit; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> -------------------------------------------------------------------------------- -- TEST 1: btree cursor scan, group fetch = 2 -- Test full cursor scan which does no updates. -- ALL MODES - TABLE IS, "scan page lockname of form (pageno, 1) -- SERIALIZABLE - row S locks as it visits each row, held until end xact -- REPEATABLE READ - row S locks as it visits each row, held until end xact -- READ COMMITTED - row S lock on current row, released on move to next row -- READ UNCOMMITTED - no row locks. -------------------------------------------------------------------------------- CALL SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.language.bulkFetchDefault','2'); 0 rows inserted/updated/deleted ij> -- RESOLVE: missing row locks -- WORKAROUND: creating an index and dropping it -- to force the statement to be recompiled create index ix1 on a(a); 0 rows inserted/updated/deleted ij> drop index ix1; 0 rows inserted/updated/deleted ij> commit; ij> get cursor scan_cursor as 'select a from a'; ij> call SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.language.bulkFetchDefault', '16'); 0 rows inserted/updated/deleted ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |S |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A ----------- 1 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |S |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A ----------- 2 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |S |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A ----------- 3 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |S |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A ----------- 4 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |S |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A ----------- 5 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |S |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A ----------- 6 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |S |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A ----------- 7 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |S |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; No current row ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |S |A |Tablelock |GRANT|ACTIVE ij> close scan_cursor; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |S |A |Tablelock |GRANT|ACTIVE ij> commit; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> -------------------------------------------------------------------------------- -- TEST 2: btree cursor scan, group fetch = 1, stop scan in middle of set -- Test full cursor scan which does no updates. -- ALL MODES - TABLE IS, "scan page lockname of form (pageno, 1) -- SERIALIZABLE - row S locks as it visits each row, held until end xact -- REPEATABLE READ - row S locks as it visits each row, held until end xact -- READ COMMITTED - row S lock on current row, released on move to next row -- READ UNCOMMITTED - no row locks. -------------------------------------------------------------------------------- CALL SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.language.bulkFetchDefault','1'); 0 rows inserted/updated/deleted ij> -- RESOLVE: missing row locks -- WORKAROUND: creating an index and dropping it -- to force the statement to be recompiled create index ix1 on a(a); 0 rows inserted/updated/deleted ij> drop index ix1; 0 rows inserted/updated/deleted ij> commit; ij> get cursor scan_cursor as 'select a from a'; ij> call SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.language.bulkFetchDefault', '16'); 0 rows inserted/updated/deleted ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |S |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A ----------- 1 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |S |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A ----------- 2 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |S |A |Tablelock |GRANT|ACTIVE ij> close scan_cursor; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |S |A |Tablelock |GRANT|ACTIVE ij> commit; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> -------------------------------------------------------------------------------- -- TEST 3: btree cursor scan, group fetch = 4, stop scan in middle of set -- Test full cursor scan which does no updates. -- ALL MODES - TABLE IS, "scan page lockname of form (pageno, 1) -- SERIALIZABLE - row S locks as it visits each row, held until end xact -- REPEATABLE READ - row S locks as it visits each row, held until end xact -- READ COMMITTED - row S lock on current row, released on move to next row -- READ UNCOMMITTED - no row locks. -------------------------------------------------------------------------------- CALL SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.language.bulkFetchDefault','4'); 0 rows inserted/updated/deleted ij> -- RESOLVE: missing row locks -- WORKAROUND: creating an index and dropping it -- to force the statement to be recompiled create index ix1 on a(a); 0 rows inserted/updated/deleted ij> drop index ix1; 0 rows inserted/updated/deleted ij> commit; ij> get cursor scan_cursor as 'select a from a'; ij> call SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.language.bulkFetchDefault', '16'); 0 rows inserted/updated/deleted ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |S |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A ----------- 1 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |S |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A ----------- 2 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |S |A |Tablelock |GRANT|ACTIVE ij> close scan_cursor; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |S |A |Tablelock |GRANT|ACTIVE ij> commit; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> -------------------------------------------------------------------------------- -- TEST 4: btree cursor scan, group fetch = 1 (scan table with some deleted rows) -- Test full cursor scan on a data set with some deleted rows (the "even" ones). -- ALL MODES - TABLE IS, "scan page lockname of form (pageno, 1) -- SERIALIZABLE - row S locks as it visits each row, held until end xact -- REPEATABLE READ - row S locks as it visits each row, held until end xact -- READ COMMITTED - row S lock on current row, released on move to next row -- READ UNCOMMITTED - no row locks. -- -- After the delete the base table should look like: -- 1, 10, 'one' -- 3, 30, 'three' -- 5, 50, 'five' -- 7, 70, 'seven' -------------------------------------------------------------------------------- delete from a where a = 2 or a = 4 or a = 6; 3 rows inserted/updated/deleted ij> commit; ij> CALL SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.language.bulkFetchDefault','1'); 0 rows inserted/updated/deleted ij> -- RESOLVE: missing row locks -- WORKAROUND: creating an index and dropping it -- to force the statement to be recompiled create index ix1 on a(a); 0 rows inserted/updated/deleted ij> drop index ix1; 0 rows inserted/updated/deleted ij> commit; ij> get cursor scan_cursor as 'select a from a'; ij> call SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.language.bulkFetchDefault', '16'); 0 rows inserted/updated/deleted ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |S |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A ----------- 1 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |S |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A ----------- 3 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |S |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A ----------- 5 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |S |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A ----------- 7 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |S |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; No current row ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |S |A |Tablelock |GRANT|ACTIVE ij> close scan_cursor; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |S |A |Tablelock |GRANT|ACTIVE ij> commit; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> -------------------------------------------------------------------------------- -- TEST 5: btree cursor scan, group fetch = 2 (scan with committed deleted rows) -- Test full cursor scan on a data set with some deleted rows (the "even" ones). -- ALL MODES - TABLE IS, "scan page lockname of form (pageno, 1) -- SERIALIZABLE - row S locks as it visits each row, held until end xact -- REPEATABLE READ - row S locks as it visits each row, held until end xact -- READ COMMITTED - row S lock on current row, released on move to next row -- READ UNCOMMITTED - no row locks. -- -- At this point the base table should look like: -- 1, 10, 'one' -- 3, 30, 'three' -- 5, 50, 'five' -- 7, 70, 'seven' -------------------------------------------------------------------------------- CALL SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.language.bulkFetchDefault','2'); 0 rows inserted/updated/deleted ij> -- RESOLVE: missing row locks -- WORKAROUND: creating an index and dropping it -- to force the statement to be recompiled create index ix1 on a(a); 0 rows inserted/updated/deleted ij> drop index ix1; 0 rows inserted/updated/deleted ij> commit; ij> get cursor scan_cursor as 'select a from a'; ij> call SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.language.bulkFetchDefault', '16'); 0 rows inserted/updated/deleted ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |S |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A ----------- 1 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |S |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A ----------- 3 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |S |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A ----------- 5 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |S |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A ----------- 7 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |S |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; No current row ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |S |A |Tablelock |GRANT|ACTIVE ij> close scan_cursor; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |S |A |Tablelock |GRANT|ACTIVE ij> commit; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> -------------------------------------------------------------------------------- -- TEST 6: btree cursor scan, group fetch = 1 (scan with "<" qualifier) -- Test "less than" qualified cursor scan on a data set. -- ALL MODES - TABLE IS, "scan page lockname of form (pageno, 1) -- SERIALIZABLE - row S locks as it visits each row, held until end xact -- REPEATABLE READ - row S locks as it visits each row, held until end xact -- READ COMMITTED - row S lock on current row, released on move to next row -- READ UNCOMMITTED - no row locks. -- -- At this point the base table should look like: -- 1, 10, 'one' -- 3, 30, 'three' -- 5, 50, 'five' -- 7, 70, 'seven' -------------------------------------------------------------------------------- CALL SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.language.bulkFetchDefault','1'); 0 rows inserted/updated/deleted ij> -- RESOLVE: missing row locks -- WORKAROUND: creating an index and dropping it -- to force the statement to be recompiled create index ix1 on a(a); 0 rows inserted/updated/deleted ij> drop index ix1; 0 rows inserted/updated/deleted ij> commit; ij> get cursor scan_cursor as 'select a from a where a < 3'; ij> call SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.language.bulkFetchDefault', '16'); 0 rows inserted/updated/deleted ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A ----------- 1 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,3) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(2,1) |GRANT|ACTIVE ij> next scan_cursor; No current row ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,3) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(2,6) |GRANT|ACTIVE ij> close scan_cursor; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,3) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(2,6) |GRANT|ACTIVE ij> commit; ij> -------------------------------------------------------------------------------- -- TEST 7: btree cursor scan, group fetch = 2 (scan with "<" qualifier) -- Test "less than" qualified cursor scan on a data set. -- ALL MODES - TABLE IS, "scan page lockname of form (pageno, 1) -- SERIALIZABLE - row S locks as it visits each row, held until end xact -- REPEATABLE READ - row S locks as it visits each row, held until end xact -- READ COMMITTED - row S lock on current row, released on move to next row -- READ UNCOMMITTED - no row locks. -- -- At this point the base table should look like: -- 1, 10, 'one' -- 3, 30, 'three' -- 5, 50, 'five' -- 7, 70, 'seven' -------------------------------------------------------------------------------- CALL SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.language.bulkFetchDefault','2'); 0 rows inserted/updated/deleted ij> -- RESOLVE: missing row locks -- WORKAROUND: creating an index and dropping it -- to force the statement to be recompiled create index ix1 on a(a); 0 rows inserted/updated/deleted ij> drop index ix1; 0 rows inserted/updated/deleted ij> commit; ij> get cursor scan_cursor as 'select a from a where a < 3'; ij> call SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.language.bulkFetchDefault', '16'); 0 rows inserted/updated/deleted ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A ----------- 1 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,3) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(2,6) |GRANT|ACTIVE ij> next scan_cursor; No current row ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,3) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(2,6) |GRANT|ACTIVE ij> close scan_cursor; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,3) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(2,6) |GRANT|ACTIVE ij> commit; ij> -------------------------------------------------------------------------------- -- TEST 8: btree cursor scan, group fetch = 1 (scan with equals qualifier) -- Test "equals" qualified cursor scan on a data set. -- ALL MODES - TABLE IS, "scan page lockname of form (pageno, 1) -- SERIALIZABLE - row S locks as it visits each row, held until end xact -- REPEATABLE READ - row S locks as it visits each row, held until end xact -- READ COMMITTED - row S lock on current row, released on move to next row -- READ UNCOMMITTED - no row locks. -- -- At this point the base table should look like: -- 1, 10, 'one' -- 3, 30, 'three' -- 5, 50, 'five' -- 7, 70, 'seven' -------------------------------------------------------------------------------- CALL SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.language.bulkFetchDefault','1'); 0 rows inserted/updated/deleted ij> -- RESOLVE: missing row locks -- WORKAROUND: creating an index and dropping it -- to force the statement to be recompiled create index ix1 on a(a); 0 rows inserted/updated/deleted ij> drop index ix1; 0 rows inserted/updated/deleted ij> commit; ij> get cursor scan_cursor as 'select a from a where a = 5'; ij> call SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.language.bulkFetchDefault', '16'); 0 rows inserted/updated/deleted ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A ----------- 5 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(3,1) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(4,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(5,6) |GRANT|ACTIVE ij> next scan_cursor; No current row ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(4,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(5,6) |GRANT|ACTIVE ij> close scan_cursor; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(4,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(5,6) |GRANT|ACTIVE ij> commit; ij> -------------------------------------------------------------------------------- -- TEST 9: btree cursor scan, group fetch = 2 (scan with equals qualifier) -- Test "equals" qualified cursor scan on a data set. -- ALL MODES - TABLE IS, "scan page lockname of form (pageno, 1) -- SERIALIZABLE - row S locks as it visits each row, held until end xact -- REPEATABLE READ - row S locks as it visits each row, held until end xact -- READ COMMITTED - row S lock on current row, released on move to next row -- READ UNCOMMITTED - no row locks. -- -- At this point the base table should look like: -- 1, 10, 'one' -- 3, 30, 'three' -- 5, 50, 'five' -- 7, 70, 'seven' -------------------------------------------------------------------------------- CALL SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.language.bulkFetchDefault','2'); 0 rows inserted/updated/deleted ij> -- RESOLVE: missing row locks -- WORKAROUND: creating an index and dropping it -- to force the statement to be recompiled create index ix1 on a(a); 0 rows inserted/updated/deleted ij> drop index ix1; 0 rows inserted/updated/deleted ij> commit; ij> get cursor scan_cursor as 'select a from a where a = 5 or a = 7'; ij> call SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.language.bulkFetchDefault', '16'); 0 rows inserted/updated/deleted ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; A ----------- 5 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(3,1) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(4,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(5,6) |GRANT|ACTIVE ij> next scan_cursor; A ----------- 7 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(3,1) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(4,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(5,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(6,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(7,6) |GRANT|ACTIVE ij> close scan_cursor; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(4,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(5,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(6,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(7,6) |GRANT|ACTIVE ij> commit; ij> -------------------------------------------------------------------------------- -- TEST 10: btree cursor scan, group fetch = 1 (equals qualifier, no rows return) -- Test "equals" qualified cursor scan on a data set, no rows returned. -- ALL MODES - TABLE IS, "scan page lockname of form (pageno, 1) -- SERIALIZABLE - row S locks as it visits each row, held until end xact -- REPEATABLE READ - row S locks as it visits each row, held until end xact -- READ COMMITTED - row S lock on current row, released on move to next row -- READ UNCOMMITTED - no row locks. -- -- At this point the base table should look like: -- 1, 10, 'one' -- 3, 30, 'three' -- 5, 50, 'five' -- 7, 70, 'seven' -------------------------------------------------------------------------------- -- no rows expected to qualify CALL SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.language.bulkFetchDefault','1'); 0 rows inserted/updated/deleted ij> -- RESOLVE: missing row locks -- WORKAROUND: creating an index and dropping it -- to force the statement to be recompiled create index ix1 on a(a); 0 rows inserted/updated/deleted ij> drop index ix1; 0 rows inserted/updated/deleted ij> commit; ij> get cursor scan_cursor as 'select a from a where a = 42'; ij> call SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.language.bulkFetchDefault', '16'); 0 rows inserted/updated/deleted ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE ij> next scan_cursor; No current row ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(7,6) |GRANT|ACTIVE ij> next scan_cursor; No current row ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(7,6) |GRANT|ACTIVE ij> close scan_cursor; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(7,6) |GRANT|ACTIVE ij> commit; ij> drop table a; 0 rows inserted/updated/deleted ij> -- non cursor, unique index run drop table a; ERROR 42Y55: 'DROP TABLE' cannot be performed on 'A' because it does not exist. ij> create table a (a int, b int, c varchar(1900), index_pad varchar(800) ) ; 0 rows inserted/updated/deleted ij> insert into a values (1, 10, PADSTRING('one',1900), PADSTRING('index pad 1',800)); 1 row inserted/updated/deleted ij> insert into a values (2, 20, PADSTRING('two',1900), PADSTRING('index pad 2',800)); 1 row inserted/updated/deleted ij> insert into a values (3, 30, PADSTRING('three',1900), PADSTRING('index pad 3',800)); 1 row inserted/updated/deleted ij> insert into a values (4, 40, PADSTRING('four',1900), PADSTRING('index pad 4',800)); 1 row inserted/updated/deleted ij> insert into a values (5, 50, PADSTRING('five',1900), PADSTRING('index pad 5',800)); 1 row inserted/updated/deleted ij> insert into a values (6, 60, PADSTRING('six',1900), PADSTRING('index pad 6',800)); 1 row inserted/updated/deleted ij> insert into a values (7, 70, PADSTRING('seven',1900), PADSTRING('index pad 7',800)); 1 row inserted/updated/deleted ij> create unique index a_idx on a (a, index_pad) ; 0 rows inserted/updated/deleted ij> commit; ij> run resource 'readBtreeSetLocks.subsql'; 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. -- -- Basic single user testing of read locks on select "set" queries on indexes. -- -- This ".subsql" test is -- meant to be run from another test such that it gets run under multiple -- isolation levels. This is important as they behave -- differently, depending on isolation levels. -- -- assume's caller has already done: run 'LockTableQuery.subsql'; to get -- easy access to the lock VTI. -- TEST 0: btree scan -- TEST 1: btree scan, (scan table with some deleted rows) -- TEST 2: btree scan, (scan with "<" qualifier) -- TEST 3: btree scan, (scan with equals qualifier) -- TEST 4: btree scan, (equals qualifier, no rows return) autocommit off; ij> -------------------------------------------------------------------------------- -- Assumes that calling routine has set up the following simple dataset, -- a heap, and index with following initial values: -- create table a (a int, b int, c somesortofchar, [index_pad]); -- create index a_idx on a (a) or a_idx on a (a, index_pad); -- -- 1, 10, 'one' -- 2, 20, 'two' -- 3, 30, 'three' -- 4, 40, 'four' -- 5, 50, 'five' -- 6, 60, 'six' -- 7, 70, 'seven' -------------------------------------------------------------------------------- select * from a; A |B |C |INDEX_PAD ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- 1 |10 |one &|index pad 1 & 2 |20 |two &|index pad 2 & 3 |30 |three &|index pad 3 & 4 |40 |four &|index pad 4 & 5 |50 |five &|index pad 5 & 6 |60 |six &|index pad 6 & 7 |70 |seven &|index pad 7 & ij> commit; ij> -------------------------------------------------------------------------------- -- TEST 0: btree scan -- Test full scan. -- ALL MODES - TABLE IS, "scan page lockname of form (pageno, 1) -- SERIALIZABLE - row S locks as it visits each row, row/table lock -- held until end xact. Also holds one previous key lock. -- REPEATABLE READ - row S locks as it visits each row, row/table locks held -- until end of transaction. -- READ COMMITTED - instantaneous S locks requested on each row. No locks -- held after query finishes. -- READ UNCOMMITTED - no row locks. No locks held after query finishes. -------------------------------------------------------------------------------- select a from a; A ----------- 1 2 3 4 5 6 7 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |S |A |Tablelock |GRANT|ACTIVE ij> commit; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> -------------------------------------------------------------------------------- -- TEST 1: btree scan, (scan table with some deleted rows) -- Test full scan on a data set with some deleted rows (the "even" ones). -- ALL MODES - TABLE IS, "scan page lockname of form (pageno, 1) -- SERIALIZABLE - row S locks as it visits each row, row/table lock -- held until end xact. Also holds one previous key lock. -- REPEATABLE READ - row S locks as it visits each row, row/table locks held -- until end of transaction. -- READ COMMITTED - instantaneous S locks requested on each row. No locks -- held after query finishes. -- READ UNCOMMITTED - no row locks. No locks held after query finishes. -- -- After the delete the base table should look like: -- 1, 10, 'one' -- 3, 30, 'three' -- 5, 50, 'five' -- 7, 70, 'seven' -------------------------------------------------------------------------------- delete from a where a = 2 or a = 4 or a = 6; 3 rows inserted/updated/deleted ij> commit; ij> -- The above delete and commit can allow post commit processing to run before -- the subsequent select is run, most likely if this run is on a table where -- there is one row per page. To get reproducible results from the subsequent -- lock calls, wait for post commit to finish before running the select. -- Without this wait "extra" locks sometimes might show up - these are locks -- on the committed deleted rows which have not been cleaned yet depending -- on timing. CALL WAIT_FOR_POST_COMMIT(); 0 rows inserted/updated/deleted ij> select a from a; A ----------- 1 3 5 7 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |S |A |Tablelock |GRANT|ACTIVE ij> commit; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> -------------------------------------------------------------------------------- -- TEST 2: btree scan, (scan with "<" qualifier) -- Test "less than" qualified scan on a data set. -- ALL MODES - TABLE IS, "scan page lockname of form (pageno, 1) -- SERIALIZABLE - row S locks as it visits each row, row/table lock -- held until end xact. Also holds one previous key lock. -- REPEATABLE READ - row S locks as it visits each row, row/table locks held -- until end of transaction. -- READ COMMITTED - instantaneous S locks requested on each row. No locks -- held after query finishes. -- READ UNCOMMITTED - no row locks. No locks held after query finishes. -- -- At this point the base table should look like: -- 1, 10, 'one' -- 3, 30, 'three' -- 5, 50, 'five' -- 7, 70, 'seven' -------------------------------------------------------------------------------- select a from a where a < 3; A ----------- 1 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,3) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(2,6) |GRANT|ACTIVE ij> commit; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> -------------------------------------------------------------------------------- -- TEST 3: btree scan, (scan with equals qualifier) -- Test "equals" qualified cursor scan on a data set. -- ALL MODES - TABLE IS, "scan page lockname of form (pageno, 1) -- SERIALIZABLE - row S locks as it visits each row, row/table lock -- held until end xact. Also holds one previous key lock. -- REPEATABLE READ - row S locks as it visits each row, row/table locks held -- until end of transaction. -- READ COMMITTED - instantaneous S locks requested on each row. No locks -- held after query finishes. -- READ UNCOMMITTED - no row locks. No locks held after query finishes. -- -- At this point the base table should look like: -- 1, 10, 'one' -- 3, 30, 'three' -- 5, 50, 'five' -- 7, 70, 'seven' -------------------------------------------------------------------------------- select a from a where a = 5; A ----------- 5 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(4,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(5,6) |GRANT|ACTIVE ij> commit; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> -------------------------------------------------------------------------------- -- TEST 4: btree scan, (equals qualifier, no rows return) -- Test "equals" qualified scan on a data set, no rows returned. -- ALL MODES - TABLE IS, "scan page lockname of form (pageno, 1) -- SERIALIZABLE - row S locks as it visits each row, row/table lock -- held until end xact. Also holds one previous key lock. -- REPEATABLE READ - row S locks as it visits each row, row/table locks held -- until end of transaction. -- READ COMMITTED - instantaneous S locks requested on each row. No locks -- held after query finishes. -- READ UNCOMMITTED - no row locks. No locks held after query finishes. -- -- At this point the base table should look like: -- 1, 10, 'one' -- 3, 30, 'three' -- 5, 50, 'five' -- 7, 70, 'seven' -------------------------------------------------------------------------------- -- no rows expected to qualify select a from a where a = 42; A ----------- ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(7,6) |GRANT|ACTIVE ij> commit; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> drop table a; 0 rows inserted/updated/deleted ij> -- non cursor, non-unique index run drop table a; ERROR 42Y55: 'DROP TABLE' cannot be performed on 'A' because it does not exist. ij> create table a (a int, b int, c varchar(1900), index_pad varchar(900) ) ; 0 rows inserted/updated/deleted ij> insert into a values (1, 10, PADSTRING('one',1900), PADSTRING('index pad 1',900)); 1 row inserted/updated/deleted ij> insert into a values (2, 20, PADSTRING('two',1900), PADSTRING('index pad 2',900)); 1 row inserted/updated/deleted ij> insert into a values (3, 30, PADSTRING('three',1900), PADSTRING('index pad 3',900)); 1 row inserted/updated/deleted ij> insert into a values (4, 40, PADSTRING('four',1900), PADSTRING('index pad 4',900)); 1 row inserted/updated/deleted ij> insert into a values (5, 50, PADSTRING('five',1900), PADSTRING('index pad 5',900)); 1 row inserted/updated/deleted ij> insert into a values (6, 60, PADSTRING('six',1900), PADSTRING('index pad 6',900)); 1 row inserted/updated/deleted ij> insert into a values (7, 70, PADSTRING('seven',1900), PADSTRING('index pad 7',900)); 1 row inserted/updated/deleted ij> create index a_idx on a (a, index_pad) ; 0 rows inserted/updated/deleted ij> commit; ij> run resource 'readBtreeSetLocks.subsql'; 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. -- -- Basic single user testing of read locks on select "set" queries on indexes. -- -- This ".subsql" test is -- meant to be run from another test such that it gets run under multiple -- isolation levels. This is important as they behave -- differently, depending on isolation levels. -- -- assume's caller has already done: run 'LockTableQuery.subsql'; to get -- easy access to the lock VTI. -- TEST 0: btree scan -- TEST 1: btree scan, (scan table with some deleted rows) -- TEST 2: btree scan, (scan with "<" qualifier) -- TEST 3: btree scan, (scan with equals qualifier) -- TEST 4: btree scan, (equals qualifier, no rows return) autocommit off; ij> -------------------------------------------------------------------------------- -- Assumes that calling routine has set up the following simple dataset, -- a heap, and index with following initial values: -- create table a (a int, b int, c somesortofchar, [index_pad]); -- create index a_idx on a (a) or a_idx on a (a, index_pad); -- -- 1, 10, 'one' -- 2, 20, 'two' -- 3, 30, 'three' -- 4, 40, 'four' -- 5, 50, 'five' -- 6, 60, 'six' -- 7, 70, 'seven' -------------------------------------------------------------------------------- select * from a; A |B |C |INDEX_PAD ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- 1 |10 |one &|index pad 1 & 2 |20 |two &|index pad 2 & 3 |30 |three &|index pad 3 & 4 |40 |four &|index pad 4 & 5 |50 |five &|index pad 5 & 6 |60 |six &|index pad 6 & 7 |70 |seven &|index pad 7 & ij> commit; ij> -------------------------------------------------------------------------------- -- TEST 0: btree scan -- Test full scan. -- ALL MODES - TABLE IS, "scan page lockname of form (pageno, 1) -- SERIALIZABLE - row S locks as it visits each row, row/table lock -- held until end xact. Also holds one previous key lock. -- REPEATABLE READ - row S locks as it visits each row, row/table locks held -- until end of transaction. -- READ COMMITTED - instantaneous S locks requested on each row. No locks -- held after query finishes. -- READ UNCOMMITTED - no row locks. No locks held after query finishes. -------------------------------------------------------------------------------- select a from a; A ----------- 1 2 3 4 5 6 7 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |S |A |Tablelock |GRANT|ACTIVE ij> commit; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> -------------------------------------------------------------------------------- -- TEST 1: btree scan, (scan table with some deleted rows) -- Test full scan on a data set with some deleted rows (the "even" ones). -- ALL MODES - TABLE IS, "scan page lockname of form (pageno, 1) -- SERIALIZABLE - row S locks as it visits each row, row/table lock -- held until end xact. Also holds one previous key lock. -- REPEATABLE READ - row S locks as it visits each row, row/table locks held -- until end of transaction. -- READ COMMITTED - instantaneous S locks requested on each row. No locks -- held after query finishes. -- READ UNCOMMITTED - no row locks. No locks held after query finishes. -- -- After the delete the base table should look like: -- 1, 10, 'one' -- 3, 30, 'three' -- 5, 50, 'five' -- 7, 70, 'seven' -------------------------------------------------------------------------------- delete from a where a = 2 or a = 4 or a = 6; 3 rows inserted/updated/deleted ij> commit; ij> -- The above delete and commit can allow post commit processing to run before -- the subsequent select is run, most likely if this run is on a table where -- there is one row per page. To get reproducible results from the subsequent -- lock calls, wait for post commit to finish before running the select. -- Without this wait "extra" locks sometimes might show up - these are locks -- on the committed deleted rows which have not been cleaned yet depending -- on timing. CALL WAIT_FOR_POST_COMMIT(); 0 rows inserted/updated/deleted ij> select a from a; A ----------- 1 3 5 7 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |S |A |Tablelock |GRANT|ACTIVE ij> commit; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> -------------------------------------------------------------------------------- -- TEST 2: btree scan, (scan with "<" qualifier) -- Test "less than" qualified scan on a data set. -- ALL MODES - TABLE IS, "scan page lockname of form (pageno, 1) -- SERIALIZABLE - row S locks as it visits each row, row/table lock -- held until end xact. Also holds one previous key lock. -- REPEATABLE READ - row S locks as it visits each row, row/table locks held -- until end of transaction. -- READ COMMITTED - instantaneous S locks requested on each row. No locks -- held after query finishes. -- READ UNCOMMITTED - no row locks. No locks held after query finishes. -- -- At this point the base table should look like: -- 1, 10, 'one' -- 3, 30, 'three' -- 5, 50, 'five' -- 7, 70, 'seven' -------------------------------------------------------------------------------- select a from a where a < 3; A ----------- 1 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,3) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(1,7) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(2,6) |GRANT|ACTIVE ij> commit; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> -------------------------------------------------------------------------------- -- TEST 3: btree scan, (scan with equals qualifier) -- Test "equals" qualified cursor scan on a data set. -- ALL MODES - TABLE IS, "scan page lockname of form (pageno, 1) -- SERIALIZABLE - row S locks as it visits each row, row/table lock -- held until end xact. Also holds one previous key lock. -- REPEATABLE READ - row S locks as it visits each row, row/table locks held -- until end of transaction. -- READ COMMITTED - instantaneous S locks requested on each row. No locks -- held after query finishes. -- READ UNCOMMITTED - no row locks. No locks held after query finishes. -- -- At this point the base table should look like: -- 1, 10, 'one' -- 3, 30, 'three' -- 5, 50, 'five' -- 7, 70, 'seven' -------------------------------------------------------------------------------- select a from a where a = 5; A ----------- 5 ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(4,6) |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(5,6) |GRANT|ACTIVE ij> commit; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> -------------------------------------------------------------------------------- -- TEST 4: btree scan, (equals qualifier, no rows return) -- Test "equals" qualified scan on a data set, no rows returned. -- ALL MODES - TABLE IS, "scan page lockname of form (pageno, 1) -- SERIALIZABLE - row S locks as it visits each row, row/table lock -- held until end xact. Also holds one previous key lock. -- REPEATABLE READ - row S locks as it visits each row, row/table locks held -- until end of transaction. -- READ COMMITTED - instantaneous S locks requested on each row. No locks -- held after query finishes. -- READ UNCOMMITTED - no row locks. No locks held after query finishes. -- -- At this point the base table should look like: -- 1, 10, 'one' -- 3, 30, 'three' -- 5, 50, 'five' -- 7, 70, 'seven' -------------------------------------------------------------------------------- -- no rows expected to qualify select a from a where a = 42; A ----------- ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- APP |UserTran|TABLE |1 |IS |A |Tablelock |GRANT|ACTIVE APP |UserTran|ROW |1 |S |A |(7,6) |GRANT|ACTIVE ij> commit; ij> select * from lock_table order by tabname, type desc, mode, cnt, lockname; USERNAME|TRANTYPE|TYPE |CNT |MODE|TABNAME |LOCKNAME |STATE|STATUS --------------------------------------------------------------------------- ij> commit; ij> drop table a; 0 rows inserted/updated/deleted ij> commit; ij> exit;