blob: 6139ef7efeaee800a178896d69a955cdd456be35 [file] [log] [blame]
--
-- Licensed to the Apache Software Foundation (ASF) under one or more
-- contributor license agreements. See the NOTICE file distributed with
-- this work for additional information regarding copyright ownership.
-- The ASF licenses this file to You under the Apache License, Version 2.0
-- (the "License"); you may not use this file except in compliance with
-- the License. You may obtain a copy of the License at
--
-- http://www.apache.org/licenses/LICENSE-2.0
--
-- Unless required by applicable law or agreed to in writing, software
-- distributed under the License is distributed on an "AS IS" BASIS,
-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-- See the License for the specific language governing permissions and
-- limitations under the License.
--
-- test 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;