| -- |
| -- 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; |
| |
| -------------------------------------------------------------------------------- |
| -- 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; |
| commit; |
| |
| -------------------------------------------------------------------------------- |
| -- 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'); |
| get cursor scan_cursor as |
| 'select a, b, c from a'; |
| call SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.language.bulkFetchDefault', '16'); |
| |
| select * from lock_table order by tabname, type desc, mode, cnt, lockname; |
| |
| next scan_cursor; |
| select * from lock_table order by tabname, type desc, mode, cnt, lockname; |
| |
| next scan_cursor; |
| select * from lock_table order by tabname, type desc, mode, cnt, lockname; |
| |
| next scan_cursor; |
| select * from lock_table order by tabname, type desc, mode, cnt, lockname; |
| |
| next scan_cursor; |
| select * from lock_table order by tabname, type desc, mode, cnt, lockname; |
| |
| next scan_cursor; |
| select * from lock_table order by tabname, type desc, mode, cnt, lockname; |
| |
| next scan_cursor; |
| select * from lock_table order by tabname, type desc, mode, cnt, lockname; |
| |
| next scan_cursor; |
| select * from lock_table order by tabname, type desc, mode, cnt, lockname; |
| |
| next scan_cursor; |
| select * from lock_table order by tabname, type desc, mode, cnt, lockname; |
| |
| close scan_cursor; |
| select * from lock_table order by tabname, type desc, mode, cnt, lockname; |
| |
| commit; |
| select * from lock_table order by tabname, type desc, mode, cnt, lockname; |
| commit; |
| |
| -------------------------------------------------------------------------------- |
| -- 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'); |
| |
| -- 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); |
| drop index ix1; |
| commit; |
| |
| get cursor scan_cursor as |
| 'select a, b, c from a'; |
| call SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.language.bulkFetchDefault', '16'); |
| |
| select * from lock_table order by tabname, type desc, mode, cnt, lockname; |
| |
| next scan_cursor; |
| select * from lock_table order by tabname, type desc, mode, cnt, lockname; |
| |
| next scan_cursor; |
| select * from lock_table order by tabname, type desc, mode, cnt, lockname; |
| |
| next scan_cursor; |
| select * from lock_table order by tabname, type desc, mode, cnt, lockname; |
| |
| next scan_cursor; |
| select * from lock_table order by tabname, type desc, mode, cnt, lockname; |
| |
| next scan_cursor; |
| select * from lock_table order by tabname, type desc, mode, cnt, lockname; |
| |
| next scan_cursor; |
| select * from lock_table order by tabname, type desc, mode, cnt, lockname; |
| |
| next scan_cursor; |
| select * from lock_table order by tabname, type desc, mode, cnt, lockname; |
| |
| next scan_cursor; |
| select * from lock_table order by tabname, type desc, mode, cnt, lockname; |
| |
| close scan_cursor; |
| select * from lock_table order by tabname, type desc, mode, cnt, lockname; |
| |
| commit; |
| select * from lock_table order by tabname, type desc, mode, cnt, lockname; |
| commit; |
| |
| -------------------------------------------------------------------------------- |
| -- 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'); |
| |
| -- 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); |
| drop index ix1; |
| commit; |
| |
| get cursor scan_cursor as |
| 'select a, b, c from a'; |
| call SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.language.bulkFetchDefault', '16'); |
| |
| select * from lock_table order by tabname, type desc, mode, cnt, lockname; |
| |
| next scan_cursor; |
| select * from lock_table order by tabname, type desc, mode, cnt, lockname; |
| |
| next scan_cursor; |
| select * from lock_table order by tabname, type desc, mode, cnt, lockname; |
| |
| close scan_cursor; |
| select * from lock_table order by tabname, type desc, mode, cnt, lockname; |
| |
| commit; |
| |
| select * from lock_table order by tabname, type desc, mode, cnt, lockname; |
| commit; |
| |
| -------------------------------------------------------------------------------- |
| -- 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'); |
| |
| -- 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); |
| drop index ix1; |
| commit; |
| |
| get cursor scan_cursor as |
| 'select a, b, c from a'; |
| call SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.language.bulkFetchDefault', '16'); |
| |
| select * from lock_table order by tabname, type desc, mode, cnt, lockname; |
| |
| next scan_cursor; |
| select * from lock_table order by tabname, type desc, mode, cnt, lockname; |
| |
| next scan_cursor; |
| select * from lock_table order by tabname, type desc, mode, cnt, lockname; |
| |
| close scan_cursor; |
| select * from lock_table order by tabname, type desc, mode, cnt, lockname; |
| |
| commit; |
| |
| select * from lock_table order by tabname, type desc, mode, cnt, lockname; |
| commit; |
| |
| -------------------------------------------------------------------------------- |
| -- 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; |
| commit; |
| |
| -- 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(); |
| |
| CALL SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.language.bulkFetchDefault','1'); |
| |
| -- 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); |
| drop index ix1; |
| commit; |
| |
| get cursor scan_cursor as |
| 'select a, b, c from a'; |
| call SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.language.bulkFetchDefault', '16'); |
| |
| select * from lock_table order by tabname, type desc, mode, cnt, lockname; |
| |
| next scan_cursor; |
| select * from lock_table order by tabname, type desc, mode, cnt, lockname; |
| |
| next scan_cursor; |
| select * from lock_table order by tabname, type desc, mode, cnt, lockname; |
| |
| next scan_cursor; |
| select * from lock_table order by tabname, type desc, mode, cnt, lockname; |
| |
| next scan_cursor; |
| select * from lock_table order by tabname, type desc, mode, cnt, lockname; |
| |
| next scan_cursor; |
| select * from lock_table order by tabname, type desc, mode, cnt, lockname; |
| |
| close scan_cursor; |
| select * from lock_table order by tabname, type desc, mode, cnt, lockname; |
| |
| commit; |
| select * from lock_table order by tabname, type desc, mode, cnt, lockname; |
| commit; |
| |
| -------------------------------------------------------------------------------- |
| -- 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'); |
| |
| -- 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); |
| drop index ix1; |
| commit; |
| |
| get cursor scan_cursor as |
| 'select a, b, c from a'; |
| call SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.language.bulkFetchDefault', '16'); |
| |
| select * from lock_table order by tabname, type desc, mode, cnt, lockname; |
| |
| next scan_cursor; |
| select * from lock_table order by tabname, type desc, mode, cnt, lockname; |
| |
| next scan_cursor; |
| select * from lock_table order by tabname, type desc, mode, cnt, lockname; |
| |
| next scan_cursor; |
| select * from lock_table order by tabname, type desc, mode, cnt, lockname; |
| |
| next scan_cursor; |
| select * from lock_table order by tabname, type desc, mode, cnt, lockname; |
| |
| next scan_cursor; |
| select * from lock_table order by tabname, type desc, mode, cnt, lockname; |
| |
| close scan_cursor; |
| select * from lock_table order by tabname, type desc, mode, cnt, lockname; |
| |
| commit; |
| select * from lock_table order by tabname, type desc, mode, cnt, lockname; |
| commit; |
| |
| -------------------------------------------------------------------------------- |
| -- 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'); |
| get cursor scan_cursor as |
| 'select a, b, c from a where a < 3'; |
| call SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.language.bulkFetchDefault', '16'); |
| |
| select * from lock_table order by tabname, type desc, mode, cnt, lockname; |
| |
| next scan_cursor; |
| select * from lock_table order by tabname, type desc, mode, cnt, lockname; |
| |
| next scan_cursor; |
| select * from lock_table order by tabname, type desc, mode, cnt, lockname; |
| |
| close scan_cursor; |
| select * from lock_table order by tabname, type desc, mode, cnt, lockname; |
| |
| commit; |
| |
| -------------------------------------------------------------------------------- |
| -- 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'); |
| |
| -- RESOLVE: missing row locks |
| -- WORKAROUND: creating an index and dropping it |
| -- to force the statement to be recompiled |
| create index ix1 on a(a); |
| drop index ix1; |
| commit; |
| |
| get cursor scan_cursor as |
| 'select a, b, c from a where a < 3'; |
| call SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.language.bulkFetchDefault', '16'); |
| |
| select * from lock_table order by tabname, type desc, mode, cnt, lockname; |
| |
| next scan_cursor; |
| select * from lock_table order by tabname, type desc, mode, cnt, lockname; |
| |
| next scan_cursor; |
| select * from lock_table order by tabname, type desc, mode, cnt, lockname; |
| |
| close scan_cursor; |
| select * from lock_table order by tabname, type desc, mode, cnt, lockname; |
| |
| commit; |
| |
| -------------------------------------------------------------------------------- |
| -- 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'); |
| get cursor scan_cursor as |
| 'select a, b, c from a where a = 5'; |
| call SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.language.bulkFetchDefault', '16'); |
| |
| select * from lock_table order by tabname, type desc, mode, cnt, lockname; |
| |
| next scan_cursor; |
| select * from lock_table order by tabname, type desc, mode, cnt, lockname; |
| |
| next scan_cursor; |
| select * from lock_table order by tabname, type desc, mode, cnt, lockname; |
| |
| close scan_cursor; |
| select * from lock_table order by tabname, type desc, mode, cnt, lockname; |
| |
| commit; |
| |
| -------------------------------------------------------------------------------- |
| -- 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'); |
| get cursor scan_cursor as |
| 'select a, b, c from a where a = 7'; |
| call SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.language.bulkFetchDefault', '16'); |
| |
| select * from lock_table order by tabname, type desc, mode, cnt, lockname; |
| |
| next scan_cursor; |
| select * from lock_table order by tabname, type desc, mode, cnt, lockname; |
| |
| next scan_cursor; |
| select * from lock_table order by tabname, type desc, mode, cnt, lockname; |
| |
| close scan_cursor; |
| select * from lock_table order by tabname, type desc, mode, cnt, lockname; |
| |
| commit; |
| |
| -------------------------------------------------------------------------------- |
| -- 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'); |
| |
| -- RESOLVE: missing row locks |
| -- WORKAROUND: creating an index and dropping it |
| -- to force the statement to be recompiled |
| create index ix1 on a(a); |
| drop index ix1; |
| commit; |
| |
| get cursor scan_cursor as |
| 'select a, b, c from a where a = 7'; |
| CALL SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.language.bulkFetchDefault','16'); |
| |
| select * from lock_table order by tabname, type desc, mode, cnt, lockname; |
| |
| next scan_cursor; |
| select * from lock_table order by tabname, type desc, mode, cnt, lockname; |
| |
| next scan_cursor; |
| select * from lock_table order by tabname, type desc, mode, cnt, lockname; |
| |
| close scan_cursor; |
| select * from lock_table order by tabname, type desc, mode, cnt, lockname; |
| |
| commit; |
| |
| drop table a; |