Nested Outer Joins
-----------------
Example:

drop table a, b, c;
create table a(x int primary key);
insert into a values(0), (1);
create table b(x int primary key);
insert into b values(0);
create table c(x int primary key);
select * from a left outer join b on a.x = b.x inner join c on b.x = c.x;
select * from a left outer join b on a.x = b.x left outer join c on b.x = c.x;
select * from a left outer join (b inner join c on b.x = c.x) on a.x = b.x;
select a.x, b_x, c_x from a left outer join (select b.x b_x, c.x c_x from b inner join c on b.x = c.x) on a.x = b_x;

drop table test;
create table test(id int primary key);
insert into test values(0), (1), (2);
select * from test a left outer join (test b inner join test c on b.id = c.id - 2) on a.id = b.id + 1;
select a.id, b_id, c_id from test a left outer join (select b.id b_id, c.id c_id from test b inner join test c on b.id = c.id - 2) on a.id = b_id + 1;

create table a(x int);
create table b(x int);
create table c(x int, y int);
insert into a values(1);
insert into a values(2);
insert into b values(3);
insert into c values(1, 3);
insert into c values(4, 5);
select * from a left outer join (b left outer join c on b.x = c.y) on a.x = c.x;
explain select * from a left outer join (b left outer join c on b.x = c.y) on a.x = c.x;
drop table a;
drop table b;
drop table c;

The following doesn't work correctly:
TableFilter,
    private void mapAndAddFilter(Expression on) throws SQLException {
        on.mapColumns(this, 0);
        if (join == null || on.isEverything(ExpressionVisitor.RESOLVED)) {
            addFilterCondition(on, true);
            on.createIndexConditions(session, this);
        }
        if (join != null) {
            join.mapAndAddFilter(on);
        }
    }


drop table base;
drop table a;
drop table b;
create table a( pk integer, val varchar(255) );
create table b( pk integer, val varchar(255) );
create table base( pk integer, deleted integer );
insert into base values ( 1,  0 );
insert into base values ( 2,  1 );
insert into base values ( 3,  0 );
insert into a values  ( 1, 'a' );
insert into b values ( 2, 'a' );
insert into b values ( 3, 'a' );

select a.pk, a_base.pk, b.pk, b_base.pk from a inner join base a_base
on a.pk = a_base.pk left outer join
( b inner join base b_base on b.pk = b_base.pk and b_base.deleted = 0 ) ;
-- H2:
-- 1    1   2   null
-- 1    1   3   3
-- PostgreSQL: ERROR: syntax error at end of input 42601/0
-- MySQL: You have an error in your SQL syntax;
--       check the manual that corresponds to your MySQL server version
--       for the right syntax to use near '' at line 3
-- Derby: Syntax error: Encountered "<EOF>" at line 3, column 71. 42X01/30000
-- HSQLDB: Unexpected token B, requires SELECT in statement

select a.pk, a_base.pk, b.pk, b_base.pk  from a inner join base a_base
on a.pk = a_base.pk left outer join
( b inner join base b_base on b.pk = b_base.pk and b_base.deleted = 0 )
on a.pk = b.pk;
-- H2, MySQL, PostgreSQL, Derby:
-- 1    1   null    null
-- HSQLDB: Unexpected token B, requires SELECT in statement

select a.pk, a_base.pk, b.pk, b_base.pk  from a inner join base a_base
on a.pk = a_base.pk left outer join
( b inner join base b_base on b.pk = b_base.pk and b_base.deleted = 0 )
on 1=1;
-- H2:
-- 1    1   2   null
-- 1    1   3   3
-- PostgreSQL, MySQL, Derby:
-- 1    1   3   3
-- HSQLDB: Unexpected token B, requires SELECT in statement

select a.pk, a_base.pk, b_pk, b_base_pk  from a inner join base a_base
on a.pk = a_base.pk left outer join
( select b.pk b_pk, b_base.pk b_base_pk from b inner join base b_base on b.pk = b_base.pk and b_base.deleted = 0 ) x
on 1=1;
-- PostgreSQL, MySQL, Derby, H2:
-- 1    1   3   3

Auto Upgrade
-----------------
file conversion should be done automatically when the new engine connects.

auto-upgrade application:
check if new version is available
(option: digital signature)
if yes download new version
(option: http, https, ftp)
backup database to SQL script
(option: list of databases, use recovery mechanism)
install new version

ftp client
task to download new version from another HTTP / HTTPS / FTP server
multi-task


Direct Lookup
-----------------
drop table test;
create table test(id int, version int, idx int);
@LOOP 1000 insert into test values(1, 1, ?);
@LOOP 1000 insert into test values(1, 2, ?);
@LOOP 1000 insert into test values(2, 1, ?);
create index idx_test on test(id, version, idx);
@LOOP 1000 select max(id)+1 from test;
@LOOP 1000 select max(idx)+1 from test where id=1 and version=2;
@LOOP 1000 select max(id)+1 from test;
@LOOP 1000 select max(idx)+1 from test where id=1 and version=2;
@LOOP 1000 select max(id)+1 from test;
@LOOP 1000 select max(idx)+1 from test where id=1 and version=2;
-- should be direct query


Update Multiple Tables with Merge
-----------------
drop table statisticlog;
create table statisticlog(id int primary key, datatext varchar, moment int);
@LOOP 20000 insert into statisticlog values(?, ?, ?);
merge into statisticlog(id, datatext) key(id)
select id, 'data1' from statisticlog order by moment limit 5;
select * from statisticlog where id < 10;
UPDATE statisticlog SET datatext = 'data2'
WHERE id IN (SELECT id FROM statisticlog ORDER BY moment LIMIT 5);
select * from statisticlog where id < 10;

Auto-Reconnect
-----------------
Implemented:
- auto_server includes auto_reconnect
- works with server mode
- works with auto_server mode
- keep temporary linked tables, variables on client
- statements
- prepared statements
- small result sets (up to fetch size)
- throws an error when autocommit is false
- an error is thrown when the connection is lost
    while looping over large result sets (larger than fetch size)
Not implemented / not tested:
- batch updates
- ignored in embedded mode
- keep temporary tables (including data) on client
- keep identity, getGeneratedKeys on client
- throw error when in cluster mode

Support Model
-----------------
Check JBoss and Spring support models
http://wiki.bonita.ow2.org/xwiki/bin/view/Main/BullOffer
- starting 2500 euros / year
- unlimited support requests
- 2 named contacts
- optional half days of technical aid by remote services

Durability
-----------------
Improve documentation.
You can't make a system that will not lose data, you can only make
a system that knows the last save point of 100% integrity. There are
too many variables and too much randomness on a cold hard power failure.
