| -- |
| -- Licensed to the Apache Software Foundation (ASF) under one or more |
| -- contributor license agreements. See the NOTICE file distributed with |
| -- this work for additional information regarding copyright ownership. |
| -- The ASF licenses this file to You under the Apache License, Version 2.0 |
| -- (the "License"); you may not use this file except in compliance with |
| -- the License. You may obtain a copy of the License at |
| -- |
| -- http://www.apache.org/licenses/LICENSE-2.0 |
| -- |
| -- Unless required by applicable law or agreed to in writing, software |
| -- distributed under the License is distributed on an "AS IS" BASIS, |
| -- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| -- See the License for the specific language governing permissions and |
| -- limitations under the License. |
| -- |
| -- test various aggregate optimizations |
| set isolation to rr; |
| -- by default, holdability of ResultSet objects created using this Connection object is true. Following will set it to false for this connection. |
| NoHoldForConnection; |
| |
| -- create and populate tables |
| create table t1(c1 int, c2 char(200)); |
| insert into t1 (c1) values 10, 9, 10, 9, 8, 7, 6, 1, 3; |
| update t1 set c2 = CHAR(c1); |
| |
| -- distinct min -> min, distinct max -> max |
| call SYSCS_UTIL.SYSCS_SET_RUNTIMESTATISTICS(1); |
| maximumdisplaywidth 7000; |
| |
| select min(distinct c1), max(distinct(c1)) from t1; |
| values SYSCS_UTIL.SYSCS_GET_RUNTIMESTATISTICS(); |
| |
| select min(distinct c1), max(distinct(c1)) from t1 group by c1; |
| values SYSCS_UTIL.SYSCS_GET_RUNTIMESTATISTICS(); |
| |
| -- min optimization |
| create index i1 on t1(c1); |
| -- min column is 1st column in index |
| select min(c1) from t1; |
| values SYSCS_UTIL.SYSCS_GET_RUNTIMESTATISTICS(); |
| create index i2 on t1(c2, c1); |
| -- equality predicates on all key columns preceding min column |
| select min(c1) from t1 where c2 = '10'; |
| values SYSCS_UTIL.SYSCS_GET_RUNTIMESTATISTICS(); |
| |
| -- equality predicates on all key columns preceding min column, |
| -- not a unique index |
| select min(c2) from t1 where c1 = 1; |
| values SYSCS_UTIL.SYSCS_GET_RUNTIMESTATISTICS(); |
| delete from t1; |
| drop index i1; |
| create unique index i1 on t1(c1); |
| insert into t1 values (1, '1'), (2, '2'); |
| -- equality predicates on all key columns preceding min column, |
| -- a unique index |
| select min(c2) from t1 where c1 = 1; |
| values SYSCS_UTIL.SYSCS_GET_RUNTIMESTATISTICS(); |
| |
| -- group by ordered on grouping columns |
| create table t2(c1 int, c2 int, c3 int, c4 int); |
| create index t2_i1 on t2(c1); |
| create index t2_i2 on t2(c1, c2); |
| -- empty table |
| select c1, sum(c2) from t2 group by c1; |
| values SYSCS_UTIL.SYSCS_GET_RUNTIMESTATISTICS(); |
| |
| -- 1 row table |
| insert into t2 values (1, 1, 1, 1); |
| select c1, sum(c2) from t2 group by c1; |
| values SYSCS_UTIL.SYSCS_GET_RUNTIMESTATISTICS(); |
| -- multiple rows, 1 group |
| insert into t2 values (1, 2, 2, 2), (1, -1, -1, -1); |
| select c1, sum(c2) from t2 group by c1; |
| values SYSCS_UTIL.SYSCS_GET_RUNTIMESTATISTICS(); |
| -- multiple rows, multiple groups |
| insert into t2 values (2, 3, 2, 2), (2, 3, -1, -1); |
| select c1, sum(c2) from t2 group by c1; |
| values SYSCS_UTIL.SYSCS_GET_RUNTIMESTATISTICS(); |
| -- ordered, but in reverse order |
| select c2, c1, sum(c3) from t2 group by c2, c1; |
| values SYSCS_UTIL.SYSCS_GET_RUNTIMESTATISTICS(); |
| |
| -- clean up |
| drop table t1; |
| drop table t2; |
| |
| |
| -- |
| -- max optimization: the optimization is to call the store |
| -- with a special request for the last row in an index. so |
| -- we cannot deal with any predicates |
| -- |
| set isolation read committed; |
| create table x (x int, y int); |
| create index ix on x(x); |
| create index ixy on x(x,y); |
| insert into x values (3,3),(7,7),(2,2),(666,6),(1,1); |
| |
| select max(x) from x; |
| values SYSCS_UTIL.SYSCS_GET_RUNTIMESTATISTICS(); |
| |
| select max(x) from x; |
| values SYSCS_UTIL.SYSCS_GET_RUNTIMESTATISTICS(); |
| |
| -- cannot use max opt |
| select max(x) from x; |
| values SYSCS_UTIL.SYSCS_GET_RUNTIMESTATISTICS(); |
| |
| select max(x) from x where x < 99; |
| values SYSCS_UTIL.SYSCS_GET_RUNTIMESTATISTICS(); |
| |
| select max(x) from x where x = 7; |
| values SYSCS_UTIL.SYSCS_GET_RUNTIMESTATISTICS(); |
| |
| select max(x) from x where y = 7; |
| values SYSCS_UTIL.SYSCS_GET_RUNTIMESTATISTICS(); |
| |
| select max(x) from x where y = 7; |
| values SYSCS_UTIL.SYSCS_GET_RUNTIMESTATISTICS(); |
| |
| select max(y) from x where y = 7; |
| values SYSCS_UTIL.SYSCS_GET_RUNTIMESTATISTICS(); |
| |
| select max(x) from x group by x; |
| values SYSCS_UTIL.SYSCS_GET_RUNTIMESTATISTICS(); |
| |
| -- could do max optimization on this, but we don't |
| -- really know much about qualifications |
| select max(x) from x where x > 99; |
| values SYSCS_UTIL.SYSCS_GET_RUNTIMESTATISTICS(); |
| |
| |
| autocommit off; |
| |
| prepare p as 'select max(x) from x'; |
| execute p; |
| values SYSCS_UTIL.SYSCS_GET_RUNTIMESTATISTICS(); |
| insert into x values (99999,99999); |
| execute p; |
| rollback; |
| execute p; |
| delete from x; |
| execute p; |
| rollback; |
| |
| -- since max uses some funky store interface, lets |
| -- check locking |
| connect 'wombat' as conn2; |
| set isolation to rr; |
| |
| -- by default, holdability of ResultSet objects created using this Connection object is true. Following will set it to false for this connection. |
| NoHoldForConnection; |
| autocommit off; |
| insert into x values (99999,null); |
| |
| set connection connection0; |
| -- should deadlock |
| select max(x) from x; |
| |
| set connection conn2; |
| commit; |
| insert into x values (99980,null); |
| |
| set connection connection0; |
| -- ok - should not block on previous key (lock held by conn2 on 99980) |
| select max(x) from x; |
| |
| set connection conn2; |
| delete from x where x = 99980; |
| delete from x where x = 99999; |
| commit; |
| |
| set connection connection0; |
| -- ok |
| select max(x) from x; |
| |
| set connection conn2; |
| insert into x values (-1,null); |
| |
| set connection connection0; |
| -- does not deadlock in current implementation, as it handles cases where |
| -- the last row is deleted, but the maximum values is somewhere on the last |
| -- page. |
| select max(x) from x; |
| |
| set connection conn2; |
| insert into x values (100000,null); |
| commit; |
| |
| set connection connection0; |
| -- ok |
| select max(x) from x; |
| |
| set connection connection0; |
| rollback; |
| disconnect; |
| |
| set connection conn2; |
| rollback; |
| disconnect; |
| |
| |
| -- check case where all rows are deleted off the last page of index, store |
| -- will fault over to doing full table scan, rather than max optimization. |
| |
| connect 'wombat' as conn1; |
| set isolation to rr; |
| |
| -- by default, holdability of ResultSet objects created using this Connection object is true. Following will set it to false for this connection. |
| NoHoldForConnection; |
| autocommit off; |
| drop table x; |
| create table x (a bigint, b int); |
| |
| -- insert enough rows so that there are multiple pages in the index. |
| insert into x values (1, 1); |
| insert into x (select a + 1, b from x); |
| insert into x (select a + 2, b from x); |
| insert into x (select a + 4, b from x); |
| insert into x (select a + 8, b from x); |
| insert into x (select a + 16, b from x); |
| insert into x (select a + 32, b from x); |
| insert into x (select a + 64, b from x); |
| insert into x (select a + 128, b from x); |
| insert into x (select a + 256, b from x); |
| create index x_idx on x (a); |
| commit; |
| |
| connect 'wombat' as conn2; |
| set isolation to rr; |
| |
| -- by default, holdability of ResultSet objects created using this Connection object is true. Following will set it to false for this connection. |
| NoHoldForConnection; |
| autocommit off; |
| commit; |
| |
| set connection conn1; |
| -- get lock on first row of table |
| insert into x values (0, 0); |
| |
| set connection conn2; |
| -- delete all the rows from the last page in the index, but don't commit or |
| -- else post commit will remove the page from the index. |
| delete from x where a > 4; |
| |
| -- lock timeout in current implementation - to be fixed when row level locked |
| -- backward scan exists. |
| -- |
| -- this one deadlocks because we have not done a complete implementation |
| -- of backward scan for max on btree. If the last page in the table is |
| -- all deletes, then instead of doing a backward scan we fault over |
| -- to the un-optimized max code which does a forward scan from the |
| -- beginnning of the table. |
| select max(a) from x; |
| |
| -- cleanup |
| set connection conn1; |
| rollback; |
| disconnect; |
| set connection conn2; |
| drop table x; |
| commit; |
| -- test a table with null values to be sure we do the right thing on optimization |
| call SYSCS_UTIL.SYSCS_SET_RUNTIMESTATISTICS(1); |
| create table t1(a int, b int); |
| insert into t1 values (null, null); |
| insert into t1 values (10, 10), (9, 9), (10, 10), (9, 9), (8, 8), (7, 7), (6, 6), |
| (1,1), (3,3); |
| create index aindex on t1(a); |
| create index bindex on t1(b desc); |
| select min(a) from t1; |
| values SYSCS_UTIL.SYSCS_GET_RUNTIMESTATISTICS(); |
| -- min of b should use max optimization whether b in nullable or not because NULLS are sorted high |
| select min(b) from t1; |
| values SYSCS_UTIL.SYSCS_GET_RUNTIMESTATISTICS(); |
| select max(a) from t1; |
| values SYSCS_UTIL.SYSCS_GET_RUNTIMESTATISTICS(); |
| select max(b) from t1; |
| values SYSCS_UTIL.SYSCS_GET_RUNTIMESTATISTICS(); |
| create table t2 (a int not null, b int not null); |
| insert into t2 select a, b from t1 where a is not null and b is not null; |
| create index bindex2 on t2(b desc); |
| -- min of b should use max optimization since b is nullable or not because NULLS are sorted high |
| select min(b) from t2; |
| values SYSCS_UTIL.SYSCS_GET_RUNTIMESTATISTICS(); |
| drop table t1; |
| drop table t2; |