# These are queries that test correlated subqueries, and are taken from the
# Hibernate test suite. See this issue:
#   https://github.com/cockroachdb/cockroach/issues/26658

# ------------------------------------------------------------------------------
# Query #1
#   org.hibernate.userguide.collections.UnidirectionalMapTest testLifecycle
# ------------------------------------------------------------------------------
exec-ddl
create table Person (
  id int8 not null,
  primary key (id)
)
----
TABLE person
 ├── id int not null
 └── INDEX primary
      └── id int not null

exec-ddl
create table Phone (
  id int8 not null,
  "number" varchar(255),
  since timestamp,
  type int4,
  primary key (id)
)
----
TABLE phone
 ├── id int not null
 ├── number string
 ├── since timestamp
 ├── type int
 └── INDEX primary
      └── id int not null

exec-ddl
create table phone_register (
  phone_id int8 not null,
  person_id int8 not null,
  primary key (phone_id, person_id),
  foreign key (person_id) references Phone (id),
  foreign key (phone_id) references Person (id),
  unique (person_id)
)
----
TABLE phone_register
 ├── phone_id int not null
 ├── person_id int not null
 ├── INDEX primary
 │    ├── phone_id int not null
 │    └── person_id int not null
 ├── INDEX secondary
 │    ├── person_id int not null
 │    └── phone_id int not null (storing)
 ├── FOREIGN KEY (phone_id) REFERENCES t.public.person (id)
 └── FOREIGN KEY (person_id) REFERENCES t.public.phone (id)

opt
select
  phoneregis0_.phone_id as phone_id1_2_0_,
  phoneregis0_.person_id as person_i2_2_0_,
  (
    select a10.since
    from Phone a10
    where a10.id=phoneregis0_.person_id
  ) as formula159_0_,
  unidirecti1_.id as id1_1_1_,
  unidirecti1_."number" as number2_1_1_,
  unidirecti1_.since as since3_1_1_,
  unidirecti1_.type as type4_1_1_
from
  phone_register phoneregis0_
inner join Phone unidirecti1_
  on phoneregis0_.person_id=unidirecti1_.id
where phoneregis0_.phone_id=1;
----
project
 ├── columns: phone_id1_2_0_:1(int!null) person_i2_2_0_:2(int!null) formula159_0_:11(timestamp) id1_1_1_:3(int!null) number2_1_1_:4(string) since3_1_1_:5(timestamp) type4_1_1_:6(int)
 ├── key: (3)
 ├── fd: ()-->(1), (3)-->(4-6), (2)==(3), (3)==(2), (2)-->(11)
 ├── inner-join (lookup phone)
 │    ├── columns: phone_id:1(int!null) person_id:2(int!null) unidirecti1_.id:3(int!null) unidirecti1_.number:4(string) unidirecti1_.since:5(timestamp) unidirecti1_.type:6(int) a10.id:7(int!null) a10.since:9(timestamp)
 │    ├── key columns: [2] = [7]
 │    ├── key: (7)
 │    ├── fd: ()-->(1), (3)-->(4-6), (2)==(3,7), (3)==(2,7), (7)-->(9), (7)==(2,3)
 │    ├── inner-join (lookup phone)
 │    │    ├── columns: phone_id:1(int!null) person_id:2(int!null) unidirecti1_.id:3(int!null) unidirecti1_.number:4(string) unidirecti1_.since:5(timestamp) unidirecti1_.type:6(int)
 │    │    ├── key columns: [2] = [3]
 │    │    ├── key: (3)
 │    │    ├── fd: ()-->(1), (3)-->(4-6), (2)==(3), (3)==(2)
 │    │    ├── scan phoneregis0_
 │    │    │    ├── columns: phone_id:1(int!null) person_id:2(int!null)
 │    │    │    ├── constraint: /1/2: [/1 - /1]
 │    │    │    ├── key: (2)
 │    │    │    └── fd: ()-->(1)
 │    │    └── filters (true)
 │    └── filters (true)
 └── projections
      └── variable: a10.since [type=timestamp, outer=(9)]

exec-ddl
drop table Person, Phone, phone_register;
----

# ------------------------------------------------------------------------------
# Query #2
#   org.hibernate.userguide.criteria.CriteriaTest:
#
#   test_criteria_from_fetch_example
#   test_criteria_from_join_example
#   test_criteria_from_multiple_root_example
# ------------------------------------------------------------------------------
exec-ddl
create table Person (
   id int8 not null,
    address varchar(255),
    createdOn timestamp,
    name varchar(255),
    nickName varchar(255),
    version int4 not null,
    primary key (id)
)
----
TABLE person
 ├── id int not null
 ├── address string
 ├── createdon timestamp
 ├── name string
 ├── nickname string
 ├── version int not null
 └── INDEX primary
      └── id int not null

exec-ddl
create table Person_addresses (
   Person_id int8 not null,
    addresses varchar(255),
    addresses_KEY varchar(255) not null,
    primary key (Person_id, addresses_KEY)
)
----
TABLE person_addresses
 ├── person_id int not null
 ├── addresses string
 ├── addresses_key string not null
 └── INDEX primary
      ├── person_id int not null
      └── addresses_key string not null

exec-ddl
create table Phone (
   id int8 not null,
    phone_number varchar(255),
    phone_type varchar(255),
    person_id int8,
    order_id int4,
    primary key (id)
)
----
TABLE phone
 ├── id int not null
 ├── phone_number string
 ├── phone_type string
 ├── person_id int
 ├── order_id int
 └── INDEX primary
      └── id int not null

exec-ddl
create table phone_call (
   id int8 not null,
    duration int4 not null,
    call_timestamp timestamp,
    phone_id int8,
    primary key (id)
)
----
TABLE phone_call
 ├── id int not null
 ├── duration int not null
 ├── call_timestamp timestamp
 ├── phone_id int
 └── INDEX primary
      └── id int not null

exec-ddl
create table Partner (
   id int8 not null,
    name varchar(255),
    version int4 not null,
    primary key (id)
)
----
TABLE partner
 ├── id int not null
 ├── name string
 ├── version int not null
 └── INDEX primary
      └── id int not null

opt
select
    phone0_.id as id1_6_0_,
    person1_.id as id1_4_1_,
    phone0_.phone_number as phone_nu2_6_0_,
    phone0_.person_id as person_i4_6_0_,
    phone0_.phone_type as phone_ty3_6_0_,
    addresses2_.Person_id as Person_i1_5_0__,
    addresses2_.addresses as addresse2_5_0__,
    addresses2_.addresses_KEY as addresse3_0__,
    person1_.address as address2_4_1_,
    person1_.createdOn as createdO3_4_1_,
    person1_.name as name4_4_1_,
    person1_.nickName as nickName5_4_1_,
    person1_.version as version6_4_1_,
    addresses2_.Person_id as Person_i1_5_0__,
    addresses2_.addresses as addresse2_5_0__,
    addresses2_.addresses_KEY as addresse3_0__
from
    Phone phone0_
inner join
    Person person1_
        on phone0_.person_id=person1_.id
inner join
    Person_addresses addresses2_
        on person1_.id=addresses2_.Person_id
where
    exists (
        select
            calls3_.id
        from
            phone_call calls3_
        where
            phone0_.id=calls3_.phone_id
    )
----
inner-join
 ├── columns: id1_6_0_:1(int!null) id1_4_1_:6(int!null) phone_nu2_6_0_:2(string) person_i4_6_0_:4(int!null) phone_ty3_6_0_:3(string) person_i1_5_0__:12(int!null) addresse2_5_0__:13(string) addresse3_0__:14(string!null) address2_4_1_:7(string) createdo3_4_1_:8(timestamp) name4_4_1_:9(string) nickname5_4_1_:10(string) version6_4_1_:11(int!null) person_i1_5_0__:12(int!null) addresse2_5_0__:13(string) addresse3_0__:14(string!null)
 ├── key: (1,14)
 ├── fd: (1)-->(2-4), (6)-->(7-11), (4)==(6,12), (6)==(4,12), (12,14)-->(13), (12)==(4,6)
 ├── semi-join
 │    ├── columns: phone0_.id:1(int!null) phone_number:2(string) phone_type:3(string) phone0_.person_id:4(int)
 │    ├── key: (1)
 │    ├── fd: (1)-->(2-4)
 │    ├── scan phone0_
 │    │    ├── columns: phone0_.id:1(int!null) phone_number:2(string) phone_type:3(string) phone0_.person_id:4(int)
 │    │    ├── key: (1)
 │    │    └── fd: (1)-->(2-4)
 │    ├── scan calls3_
 │    │    ├── columns: calls3_.id:15(int!null) phone_id:18(int)
 │    │    ├── key: (15)
 │    │    └── fd: (15)-->(18)
 │    └── filters
 │         └── phone0_.id = phone_id [type=bool, outer=(1,18), constraints=(/1: (/NULL - ]; /18: (/NULL - ]), fd=(1)==(18), (18)==(1)]
 ├── inner-join (merge)
 │    ├── columns: person1_.id:6(int!null) address:7(string) createdon:8(timestamp) name:9(string) nickname:10(string) version:11(int!null) addresses2_.person_id:12(int!null) addresses:13(string) addresses_key:14(string!null)
 │    ├── left ordering: +6
 │    ├── right ordering: +12
 │    ├── key: (12,14)
 │    ├── fd: (6)-->(7-11), (12,14)-->(13), (6)==(12), (12)==(6)
 │    ├── scan person1_
 │    │    ├── columns: person1_.id:6(int!null) address:7(string) createdon:8(timestamp) name:9(string) nickname:10(string) version:11(int!null)
 │    │    ├── key: (6)
 │    │    ├── fd: (6)-->(7-11)
 │    │    └── ordering: +6
 │    ├── scan addresses2_
 │    │    ├── columns: addresses2_.person_id:12(int!null) addresses:13(string) addresses_key:14(string!null)
 │    │    ├── key: (12,14)
 │    │    ├── fd: (12,14)-->(13)
 │    │    └── ordering: +12
 │    └── filters (true)
 └── filters
      └── phone0_.person_id = person1_.id [type=bool, outer=(4,6), constraints=(/4: (/NULL - ]; /6: (/NULL - ]), fd=(4)==(6), (6)==(4)]

opt
select
    phone0_.id as id1_6_,
    phone0_.phone_number as phone_nu2_6_,
    phone0_.person_id as person_i4_6_,
    phone0_.phone_type as phone_ty3_6_
from
    Phone phone0_
inner join
    Person person1_
        on phone0_.person_id=person1_.id
inner join
    Person_addresses addresses2_
        on person1_.id=addresses2_.Person_id
where
    exists (
        select
            calls3_.id
        from
            phone_call calls3_
        where
            phone0_.id=calls3_.phone_id
    )
----
project
 ├── columns: id1_6_:1(int!null) phone_nu2_6_:2(string) person_i4_6_:4(int!null) phone_ty3_6_:3(string)
 ├── fd: (1)-->(2-4)
 └── inner-join
      ├── columns: phone0_.id:1(int!null) phone_number:2(string) phone_type:3(string) phone0_.person_id:4(int!null) person1_.id:6(int!null) addresses2_.person_id:12(int!null)
      ├── fd: (1)-->(2-4), (4)==(6,12), (6)==(4,12), (12)==(4,6)
      ├── semi-join
      │    ├── columns: phone0_.id:1(int!null) phone_number:2(string) phone_type:3(string) phone0_.person_id:4(int)
      │    ├── key: (1)
      │    ├── fd: (1)-->(2-4)
      │    ├── scan phone0_
      │    │    ├── columns: phone0_.id:1(int!null) phone_number:2(string) phone_type:3(string) phone0_.person_id:4(int)
      │    │    ├── key: (1)
      │    │    └── fd: (1)-->(2-4)
      │    ├── scan calls3_
      │    │    ├── columns: calls3_.id:15(int!null) phone_id:18(int)
      │    │    ├── key: (15)
      │    │    └── fd: (15)-->(18)
      │    └── filters
      │         └── phone0_.id = phone_id [type=bool, outer=(1,18), constraints=(/1: (/NULL - ]; /18: (/NULL - ]), fd=(1)==(18), (18)==(1)]
      ├── inner-join (merge)
      │    ├── columns: person1_.id:6(int!null) addresses2_.person_id:12(int!null)
      │    ├── left ordering: +6
      │    ├── right ordering: +12
      │    ├── fd: (6)==(12), (12)==(6)
      │    ├── scan person1_
      │    │    ├── columns: person1_.id:6(int!null)
      │    │    ├── key: (6)
      │    │    └── ordering: +6
      │    ├── scan addresses2_
      │    │    ├── columns: addresses2_.person_id:12(int!null)
      │    │    └── ordering: +12
      │    └── filters (true)
      └── filters
           └── phone0_.person_id = person1_.id [type=bool, outer=(4,6), constraints=(/4: (/NULL - ]; /6: (/NULL - ]), fd=(4)==(6), (6)==(4)]

opt
select
    person0_.id as id1_4_0_,
    partner1_.id as id1_2_1_,
    person0_.address as address2_4_0_,
    person0_.createdOn as createdO3_4_0_,
    person0_.name as name4_4_0_,
    person0_.nickName as nickName5_4_0_,
    person0_.version as version6_4_0_,
    partner1_.name as name2_2_1_,
    partner1_.version as version3_2_1_
from
    Person person0_ cross
join
    Partner partner1_
where
    person0_.address=$1
    and (
        exists (
            select
                phones2_.id
            from
                Phone phones2_
            where
                person0_.id=phones2_.person_id
        )
    )
    and (
        partner1_.name like $2
    )
    and partner1_.version=0
----
inner-join
 ├── columns: id1_4_0_:1(int!null) id1_2_1_:7(int!null) address2_4_0_:2(string!null) createdo3_4_0_:3(timestamp) name4_4_0_:4(string) nickname5_4_0_:5(string) version6_4_0_:6(int!null) name2_2_1_:8(string!null) version3_2_1_:9(int!null)
 ├── has-placeholder
 ├── key: (1,7)
 ├── fd: ()-->(9), (1)-->(2-6), (7)-->(8)
 ├── semi-join
 │    ├── columns: person0_.id:1(int!null) address:2(string!null) createdon:3(timestamp) person0_.name:4(string) nickname:5(string) person0_.version:6(int!null)
 │    ├── has-placeholder
 │    ├── key: (1)
 │    ├── fd: (1)-->(2-6)
 │    ├── select
 │    │    ├── columns: person0_.id:1(int!null) address:2(string!null) createdon:3(timestamp) person0_.name:4(string) nickname:5(string) person0_.version:6(int!null)
 │    │    ├── has-placeholder
 │    │    ├── key: (1)
 │    │    ├── fd: (1)-->(2-6)
 │    │    ├── scan person0_
 │    │    │    ├── columns: person0_.id:1(int!null) address:2(string) createdon:3(timestamp) person0_.name:4(string) nickname:5(string) person0_.version:6(int!null)
 │    │    │    ├── key: (1)
 │    │    │    └── fd: (1)-->(2-6)
 │    │    └── filters
 │    │         └── address = $1 [type=bool, outer=(2), constraints=(/2: (/NULL - ])]
 │    ├── scan phones2_
 │    │    ├── columns: phones2_.id:10(int!null) person_id:13(int)
 │    │    ├── key: (10)
 │    │    └── fd: (10)-->(13)
 │    └── filters
 │         └── person0_.id = person_id [type=bool, outer=(1,13), constraints=(/1: (/NULL - ]; /13: (/NULL - ]), fd=(1)==(13), (13)==(1)]
 ├── select
 │    ├── columns: partner1_.id:7(int!null) partner1_.name:8(string!null) partner1_.version:9(int!null)
 │    ├── has-placeholder
 │    ├── key: (7)
 │    ├── fd: ()-->(9), (7)-->(8)
 │    ├── scan partner1_
 │    │    ├── columns: partner1_.id:7(int!null) partner1_.name:8(string) partner1_.version:9(int!null)
 │    │    ├── key: (7)
 │    │    └── fd: (7)-->(8,9)
 │    └── filters
 │         ├── partner1_.name LIKE $2 [type=bool, outer=(8), constraints=(/8: (/NULL - ])]
 │         └── partner1_.version = 0 [type=bool, outer=(9), constraints=(/9: [/0 - /0]; tight), fd=()-->(9)]
 └── filters (true)

exec-ddl
drop table Person, Person_addresses, Phone, phone_call, Partner;
----

# ------------------------------------------------------------------------------
# Query #3
#   org.hibernate.userguide.envers.DefaultAuditTest test
# ------------------------------------------------------------------------------
exec-ddl
create table Customer_AUD (
   id int8 not null,
    REV int4 not null,
    REVTYPE int2,
    created_on timestamp,
    firstName varchar(255),
    lastName varchar(255),
    primary key (id, REV)
)
----
TABLE customer_aud
 ├── id int not null
 ├── rev int not null
 ├── revtype int
 ├── created_on timestamp
 ├── firstname string
 ├── lastname string
 └── INDEX primary
      ├── id int not null
      └── rev int not null

opt
select
    defaultaud0_.id as id1_1_,
    defaultaud0_.REV as REV2_1_,
    defaultaud0_.REVTYPE as REVTYPE3_1_,
    defaultaud0_.created_on as created_4_1_,
    defaultaud0_.firstName as firstNam5_1_,
    defaultaud0_.lastName as lastName6_1_
from
    Customer_AUD defaultaud0_
where
    defaultaud0_.REV=(
        select
            max(defaultaud1_.REV)
        from
            Customer_AUD defaultaud1_
        where
            defaultaud1_.REV<=$1
            and defaultaud0_.id=defaultaud1_.id
    )
    and defaultaud0_.REVTYPE<>$2
----
project
 ├── columns: id1_1_:1(int!null) rev2_1_:2(int!null) revtype3_1_:3(int) created_4_1_:4(timestamp) firstnam5_1_:5(string) lastname6_1_:6(string)
 ├── has-placeholder
 ├── key: (1,2)
 ├── fd: (1,2)-->(3-6)
 └── select
      ├── columns: defaultaud0_.id:1(int!null) defaultaud0_.rev:2(int!null) defaultaud0_.revtype:3(int) defaultaud0_.created_on:4(timestamp) defaultaud0_.firstname:5(string) defaultaud0_.lastname:6(string) max:13(int!null)
      ├── has-placeholder
      ├── key: (1,2)
      ├── fd: (1,2)-->(3-6,13), (2)==(13), (13)==(2)
      ├── group-by
      │    ├── columns: defaultaud0_.id:1(int!null) defaultaud0_.rev:2(int!null) defaultaud0_.revtype:3(int) defaultaud0_.created_on:4(timestamp) defaultaud0_.firstname:5(string) defaultaud0_.lastname:6(string) max:13(int)
      │    ├── grouping columns: defaultaud0_.id:1(int!null) defaultaud0_.rev:2(int!null)
      │    ├── has-placeholder
      │    ├── key: (1,2)
      │    ├── fd: (1,2)-->(3-6,13)
      │    ├── inner-join (merge)
      │    │    ├── columns: defaultaud0_.id:1(int!null) defaultaud0_.rev:2(int!null) defaultaud0_.revtype:3(int!null) defaultaud0_.created_on:4(timestamp) defaultaud0_.firstname:5(string) defaultaud0_.lastname:6(string) defaultaud1_.id:7(int!null) defaultaud1_.rev:8(int!null)
      │    │    ├── left ordering: +1
      │    │    ├── right ordering: +7
      │    │    ├── has-placeholder
      │    │    ├── key: (2,7,8)
      │    │    ├── fd: (1,2)-->(3-6), (1)==(7), (7)==(1)
      │    │    ├── select
      │    │    │    ├── columns: defaultaud0_.id:1(int!null) defaultaud0_.rev:2(int!null) defaultaud0_.revtype:3(int!null) defaultaud0_.created_on:4(timestamp) defaultaud0_.firstname:5(string) defaultaud0_.lastname:6(string)
      │    │    │    ├── has-placeholder
      │    │    │    ├── key: (1,2)
      │    │    │    ├── fd: (1,2)-->(3-6)
      │    │    │    ├── ordering: +1
      │    │    │    ├── scan defaultaud0_
      │    │    │    │    ├── columns: defaultaud0_.id:1(int!null) defaultaud0_.rev:2(int!null) defaultaud0_.revtype:3(int) defaultaud0_.created_on:4(timestamp) defaultaud0_.firstname:5(string) defaultaud0_.lastname:6(string)
      │    │    │    │    ├── key: (1,2)
      │    │    │    │    ├── fd: (1,2)-->(3-6)
      │    │    │    │    └── ordering: +1
      │    │    │    └── filters
      │    │    │         └── defaultaud0_.revtype != $2 [type=bool, outer=(3), constraints=(/3: (/NULL - ])]
      │    │    ├── select
      │    │    │    ├── columns: defaultaud1_.id:7(int!null) defaultaud1_.rev:8(int!null)
      │    │    │    ├── has-placeholder
      │    │    │    ├── key: (7,8)
      │    │    │    ├── ordering: +7
      │    │    │    ├── scan defaultaud1_
      │    │    │    │    ├── columns: defaultaud1_.id:7(int!null) defaultaud1_.rev:8(int!null)
      │    │    │    │    ├── key: (7,8)
      │    │    │    │    └── ordering: +7
      │    │    │    └── filters
      │    │    │         └── defaultaud1_.rev <= $1 [type=bool, outer=(8), constraints=(/8: (/NULL - ])]
      │    │    └── filters (true)
      │    └── aggregations
      │         ├── max [type=int, outer=(8)]
      │         │    └── variable: defaultaud1_.rev [type=int]
      │         ├── const-agg [type=int, outer=(3)]
      │         │    └── variable: defaultaud0_.revtype [type=int]
      │         ├── const-agg [type=timestamp, outer=(4)]
      │         │    └── variable: defaultaud0_.created_on [type=timestamp]
      │         ├── const-agg [type=string, outer=(5)]
      │         │    └── variable: defaultaud0_.firstname [type=string]
      │         └── const-agg [type=string, outer=(6)]
      │              └── variable: defaultaud0_.lastname [type=string]
      └── filters
           └── defaultaud0_.rev = max [type=bool, outer=(2,13), constraints=(/2: (/NULL - ]; /13: (/NULL - ]), fd=(2)==(13), (13)==(2)]

exec-ddl
drop table Customer_AUD;
----

# ------------------------------------------------------------------------------
# Query #4
#   org.hibernate.userguide.envers.QueryAuditTest test
# ------------------------------------------------------------------------------
exec-ddl
create table Customer_AUD (
   id int8 not null,
    REV int4 not null,
    REVTYPE int2,
    REVEND int4,
    created_on timestamp,
    firstName varchar(255),
    lastName varchar(255),
    address_id int8,
    primary key (id, REV)
)
----
TABLE customer_aud
 ├── id int not null
 ├── rev int not null
 ├── revtype int
 ├── revend int
 ├── created_on timestamp
 ├── firstname string
 ├── lastname string
 ├── address_id int
 └── INDEX primary
      ├── id int not null
      └── rev int not null

opt
select
    queryaudit0_.id as id1_3_,
    queryaudit0_.REV as REV2_3_,
    queryaudit0_.REVTYPE as REVTYPE3_3_,
    queryaudit0_.REVEND as REVEND4_3_,
    queryaudit0_.created_on as created_5_3_,
    queryaudit0_.firstName as firstNam6_3_,
    queryaudit0_.lastName as lastName7_3_,
    queryaudit0_.address_id as address_8_3_
from
    Customer_AUD queryaudit0_
where
    queryaudit0_.REVTYPE<>$1
    and queryaudit0_.REV=(
        select
            max(queryaudit1_.REV)
        from
            Customer_AUD queryaudit1_
        where
            queryaudit1_.id=queryaudit0_.id
    )
order by
    queryaudit0_.REV asc
----
sort
 ├── columns: id1_3_:1(int!null) rev2_3_:2(int!null) revtype3_3_:3(int) revend4_3_:4(int) created_5_3_:5(timestamp) firstnam6_3_:6(string) lastname7_3_:7(string) address_8_3_:8(int)
 ├── has-placeholder
 ├── key: (1,2)
 ├── fd: (1,2)-->(3-8)
 ├── ordering: +2
 └── project
      ├── columns: queryaudit0_.id:1(int!null) queryaudit0_.rev:2(int!null) queryaudit0_.revtype:3(int) queryaudit0_.revend:4(int) queryaudit0_.created_on:5(timestamp) queryaudit0_.firstname:6(string) queryaudit0_.lastname:7(string) queryaudit0_.address_id:8(int)
      ├── has-placeholder
      ├── key: (1,2)
      ├── fd: (1,2)-->(3-8)
      └── select
           ├── columns: queryaudit0_.id:1(int!null) queryaudit0_.rev:2(int!null) queryaudit0_.revtype:3(int) queryaudit0_.revend:4(int) queryaudit0_.created_on:5(timestamp) queryaudit0_.firstname:6(string) queryaudit0_.lastname:7(string) queryaudit0_.address_id:8(int) max:17(int!null)
           ├── has-placeholder
           ├── key: (1,2)
           ├── fd: (1,2)-->(3-8,17), (2)==(17), (17)==(2)
           ├── group-by
           │    ├── columns: queryaudit0_.id:1(int!null) queryaudit0_.rev:2(int!null) queryaudit0_.revtype:3(int) queryaudit0_.revend:4(int) queryaudit0_.created_on:5(timestamp) queryaudit0_.firstname:6(string) queryaudit0_.lastname:7(string) queryaudit0_.address_id:8(int) max:17(int)
           │    ├── grouping columns: queryaudit0_.id:1(int!null) queryaudit0_.rev:2(int!null)
           │    ├── has-placeholder
           │    ├── key: (1,2)
           │    ├── fd: (1,2)-->(3-8,17)
           │    ├── inner-join (merge)
           │    │    ├── columns: queryaudit0_.id:1(int!null) queryaudit0_.rev:2(int!null) queryaudit0_.revtype:3(int!null) queryaudit0_.revend:4(int) queryaudit0_.created_on:5(timestamp) queryaudit0_.firstname:6(string) queryaudit0_.lastname:7(string) queryaudit0_.address_id:8(int) queryaudit1_.id:9(int!null) queryaudit1_.rev:10(int!null)
           │    │    ├── left ordering: +1
           │    │    ├── right ordering: +9
           │    │    ├── has-placeholder
           │    │    ├── key: (2,9,10)
           │    │    ├── fd: (1,2)-->(3-8), (1)==(9), (9)==(1)
           │    │    ├── select
           │    │    │    ├── columns: queryaudit0_.id:1(int!null) queryaudit0_.rev:2(int!null) queryaudit0_.revtype:3(int!null) queryaudit0_.revend:4(int) queryaudit0_.created_on:5(timestamp) queryaudit0_.firstname:6(string) queryaudit0_.lastname:7(string) queryaudit0_.address_id:8(int)
           │    │    │    ├── has-placeholder
           │    │    │    ├── key: (1,2)
           │    │    │    ├── fd: (1,2)-->(3-8)
           │    │    │    ├── ordering: +1
           │    │    │    ├── scan queryaudit0_
           │    │    │    │    ├── columns: queryaudit0_.id:1(int!null) queryaudit0_.rev:2(int!null) queryaudit0_.revtype:3(int) queryaudit0_.revend:4(int) queryaudit0_.created_on:5(timestamp) queryaudit0_.firstname:6(string) queryaudit0_.lastname:7(string) queryaudit0_.address_id:8(int)
           │    │    │    │    ├── key: (1,2)
           │    │    │    │    ├── fd: (1,2)-->(3-8)
           │    │    │    │    └── ordering: +1
           │    │    │    └── filters
           │    │    │         └── queryaudit0_.revtype != $1 [type=bool, outer=(3), constraints=(/3: (/NULL - ])]
           │    │    ├── scan queryaudit1_
           │    │    │    ├── columns: queryaudit1_.id:9(int!null) queryaudit1_.rev:10(int!null)
           │    │    │    ├── key: (9,10)
           │    │    │    └── ordering: +9
           │    │    └── filters (true)
           │    └── aggregations
           │         ├── max [type=int, outer=(10)]
           │         │    └── variable: queryaudit1_.rev [type=int]
           │         ├── const-agg [type=int, outer=(3)]
           │         │    └── variable: queryaudit0_.revtype [type=int]
           │         ├── const-agg [type=int, outer=(4)]
           │         │    └── variable: queryaudit0_.revend [type=int]
           │         ├── const-agg [type=timestamp, outer=(5)]
           │         │    └── variable: queryaudit0_.created_on [type=timestamp]
           │         ├── const-agg [type=string, outer=(6)]
           │         │    └── variable: queryaudit0_.firstname [type=string]
           │         ├── const-agg [type=string, outer=(7)]
           │         │    └── variable: queryaudit0_.lastname [type=string]
           │         └── const-agg [type=int, outer=(8)]
           │              └── variable: queryaudit0_.address_id [type=int]
           └── filters
                └── queryaudit0_.rev = max [type=bool, outer=(2,17), constraints=(/2: (/NULL - ]; /17: (/NULL - ]), fd=(2)==(17), (17)==(2)]

exec-ddl
drop table Customer_AUD;
----

# ------------------------------------------------------------------------------
# Query #5
#   org.hibernate.userguide.hql.HQLTest
#     test_hql_all_subquery_comparison_qualifier_example
#     test_hql_collection_expressions_example_1
#     test_hql_collection_expressions_example_10
#     test_hql_collection_expressions_example_2
#     test_hql_collection_expressions_example_3
#     test_hql_collection_expressions_example_4
#     test_hql_collection_expressions_example_5
#     test_hql_collection_expressions_example_6
#     test_hql_collection_expressions_example_8
#     test_hql_collection_expressions_example_9
#     test_hql_collection_index_operator_example_3
#     test_hql_empty_collection_predicate_example_1
#     test_hql_empty_collection_predicate_example_2
#     test_hql_group_by_example_4
#     test_hql_member_of_collection_predicate_example_1
#     test_hql_member_of_collection_predicate_example_2
#   org.hibernate.jpa.test.criteria.enumcollection.EnumIsMemberTest
#     testQueryEnumCollection
# ------------------------------------------------------------------------------
exec-ddl
create table Phone (
   id int8 not null,
    phone_number varchar(255),
    phone_type varchar(255),
    person_id int8,
    order_id int4,
    primary key (id)
)
----
TABLE phone
 ├── id int not null
 ├── phone_number string
 ├── phone_type string
 ├── person_id int
 ├── order_id int
 └── INDEX primary
      └── id int not null

exec-ddl
create table phone_call (
   id int8 not null,
    duration int4 not null,
    call_timestamp timestamp,
    phone_id int8,
    primary key (id)
)
----
TABLE phone_call
 ├── id int not null
 ├── duration int not null
 ├── call_timestamp timestamp
 ├── phone_id int
 └── INDEX primary
      └── id int not null

exec-ddl
create table Person (
   id int8 not null,
    address varchar(255),
    createdOn timestamp,
    name varchar(255),
    nickName varchar(255),
    version int4 not null,
    primary key (id)
)
----
TABLE person
 ├── id int not null
 ├── address string
 ├── createdon timestamp
 ├── name string
 ├── nickname string
 ├── version int not null
 └── INDEX primary
      └── id int not null

exec-ddl
create table Phone_repairTimestamps (
   Phone_id int8 not null,
   repairTimestamps timestamp
)
----
TABLE phone_repairtimestamps
 ├── phone_id int not null
 ├── repairtimestamps timestamp
 ├── rowid int not null (hidden)
 └── INDEX primary
      └── rowid int not null (hidden)

exec-ddl
create table Person_addresses (
    Person_id int8 not null,
    addresses varchar(255),
    addresses_KEY varchar(255) not null,
    primary key (Person_id, addresses_KEY)
)
----
TABLE person_addresses
 ├── person_id int not null
 ├── addresses string
 ├── addresses_key string not null
 └── INDEX primary
      ├── person_id int not null
      └── addresses_key string not null

opt
select
    distinct person2_.id as id1_2_,
    person2_.address as address2_2_,
    person2_.createdOn as createdO3_2_,
    person2_.name as name4_2_,
    person2_.nickName as nickName5_2_,
    person2_.version as version6_2_
from
    Phone phone0_
inner join
    phone_call calls1_
        on phone0_.id=calls1_.phone_id
inner join
    Person person2_
        on phone0_.person_id=person2_.id
where
    50>all (
        select
            call3_.duration
        from
            phone_call call3_
        where
            call3_.phone_id=phone0_.id
    )
----
distinct-on
 ├── columns: id1_2_:10(int!null) address2_2_:11(string) createdo3_2_:12(timestamp) name4_2_:13(string) nickname5_2_:14(string) version6_2_:15(int)
 ├── grouping columns: person2_.id:10(int!null)
 ├── key: (10)
 ├── fd: (10)-->(11-15)
 ├── inner-join
 │    ├── columns: phone0_.id:1(int!null) person_id:4(int!null) calls1_.phone_id:9(int!null) person2_.id:10(int!null) address:11(string) createdon:12(timestamp) name:13(string) nickname:14(string) version:15(int!null)
 │    ├── fd: (1)-->(4), (1)==(9), (9)==(1), (10)-->(11-15), (4)==(10), (10)==(4)
 │    ├── inner-join
 │    │    ├── columns: phone0_.id:1(int!null) person_id:4(int) calls1_.phone_id:9(int!null)
 │    │    ├── fd: (1)-->(4), (1)==(9), (9)==(1)
 │    │    ├── anti-join
 │    │    │    ├── columns: phone0_.id:1(int!null) person_id:4(int)
 │    │    │    ├── key: (1)
 │    │    │    ├── fd: (1)-->(4)
 │    │    │    ├── scan phone0_
 │    │    │    │    ├── columns: phone0_.id:1(int!null) person_id:4(int)
 │    │    │    │    ├── key: (1)
 │    │    │    │    └── fd: (1)-->(4)
 │    │    │    ├── select
 │    │    │    │    ├── columns: call3_.duration:17(int!null) call3_.phone_id:19(int)
 │    │    │    │    ├── scan call3_
 │    │    │    │    │    └── columns: call3_.duration:17(int!null) call3_.phone_id:19(int)
 │    │    │    │    └── filters
 │    │    │    │         └── (call3_.duration >= 50) IS NOT false [type=bool, outer=(17)]
 │    │    │    └── filters
 │    │    │         └── call3_.phone_id = phone0_.id [type=bool, outer=(1,19), constraints=(/1: (/NULL - ]; /19: (/NULL - ]), fd=(1)==(19), (19)==(1)]
 │    │    ├── scan calls1_
 │    │    │    └── columns: calls1_.phone_id:9(int)
 │    │    └── filters
 │    │         └── phone0_.id = calls1_.phone_id [type=bool, outer=(1,9), constraints=(/1: (/NULL - ]; /9: (/NULL - ]), fd=(1)==(9), (9)==(1)]
 │    ├── scan person2_
 │    │    ├── columns: person2_.id:10(int!null) address:11(string) createdon:12(timestamp) name:13(string) nickname:14(string) version:15(int!null)
 │    │    ├── key: (10)
 │    │    └── fd: (10)-->(11-15)
 │    └── filters
 │         └── person_id = person2_.id [type=bool, outer=(4,10), constraints=(/4: (/NULL - ]; /10: (/NULL - ]), fd=(4)==(10), (10)==(4)]
 └── aggregations
      ├── const-agg [type=string, outer=(11)]
      │    └── variable: address [type=string]
      ├── const-agg [type=timestamp, outer=(12)]
      │    └── variable: createdon [type=timestamp]
      ├── const-agg [type=string, outer=(13)]
      │    └── variable: name [type=string]
      ├── const-agg [type=string, outer=(14)]
      │    └── variable: nickname [type=string]
      └── const-agg [type=int, outer=(15)]
           └── variable: version [type=int]

opt
select
    phone0_.id as id1_4_,
    phone0_.phone_number as phone_nu2_4_,
    phone0_.person_id as person_i4_4_,
    phone0_.phone_type as phone_ty3_4_
from
    Phone phone0_
where
    (
        select
            max(calls1_.id)
        from
            phone_call calls1_
        where
            phone0_.id=calls1_.phone_id
    )=$1
----
project
 ├── columns: id1_4_:1(int!null) phone_nu2_4_:2(string) person_i4_4_:4(int) phone_ty3_4_:3(string)
 ├── has-placeholder
 ├── key: (1)
 ├── fd: (1)-->(2-4)
 └── select
      ├── columns: phone0_.id:1(int!null) phone_number:2(string) phone_type:3(string) person_id:4(int) max:10(int!null)
      ├── has-placeholder
      ├── key: (1)
      ├── fd: (1)-->(2-4,10)
      ├── group-by
      │    ├── columns: phone0_.id:1(int!null) phone_number:2(string) phone_type:3(string) person_id:4(int) max:10(int)
      │    ├── grouping columns: phone0_.id:1(int!null)
      │    ├── key: (1)
      │    ├── fd: (1)-->(2-4,10)
      │    ├── inner-join
      │    │    ├── columns: phone0_.id:1(int!null) phone_number:2(string) phone_type:3(string) person_id:4(int) calls1_.id:6(int!null) phone_id:9(int!null)
      │    │    ├── key: (6)
      │    │    ├── fd: (1)-->(2-4), (6)-->(9), (1)==(9), (9)==(1)
      │    │    ├── scan phone0_
      │    │    │    ├── columns: phone0_.id:1(int!null) phone_number:2(string) phone_type:3(string) person_id:4(int)
      │    │    │    ├── key: (1)
      │    │    │    └── fd: (1)-->(2-4)
      │    │    ├── scan calls1_
      │    │    │    ├── columns: calls1_.id:6(int!null) phone_id:9(int)
      │    │    │    ├── key: (6)
      │    │    │    └── fd: (6)-->(9)
      │    │    └── filters
      │    │         └── phone0_.id = phone_id [type=bool, outer=(1,9), constraints=(/1: (/NULL - ]; /9: (/NULL - ]), fd=(1)==(9), (9)==(1)]
      │    └── aggregations
      │         ├── max [type=int, outer=(6)]
      │         │    └── variable: calls1_.id [type=int]
      │         ├── const-agg [type=string, outer=(2)]
      │         │    └── variable: phone_number [type=string]
      │         ├── const-agg [type=string, outer=(3)]
      │         │    └── variable: phone_type [type=string]
      │         └── const-agg [type=int, outer=(4)]
      │              └── variable: person_id [type=int]
      └── filters
           └── max = $1 [type=bool, outer=(10), constraints=(/10: (/NULL - ])]

opt
select
    person0_.id as id1_2_,
    person0_.address as address2_2_,
    person0_.createdOn as createdO3_2_,
    person0_.name as name4_2_,
    person0_.nickName as nickName5_2_,
    person0_.version as version6_2_
from
    Person person0_
where
    (
        select
            count(phones1_.person_id)
        from
            Phone phones1_
        where
            person0_.id=phones1_.person_id
    )=2
----
project
 ├── columns: id1_2_:1(int!null) address2_2_:2(string) createdo3_2_:3(timestamp) name4_2_:4(string) nickname5_2_:5(string) version6_2_:6(int)
 ├── key: (1)
 ├── fd: (1)-->(2-6)
 └── select
      ├── columns: person0_.id:1(int!null) address:2(string) createdon:3(timestamp) name:4(string) nickname:5(string) version:6(int) count:12(int!null)
      ├── key: (1)
      ├── fd: ()-->(12), (1)-->(2-6)
      ├── group-by
      │    ├── columns: person0_.id:1(int!null) address:2(string) createdon:3(timestamp) name:4(string) nickname:5(string) version:6(int) count:12(int)
      │    ├── grouping columns: person0_.id:1(int!null)
      │    ├── key: (1)
      │    ├── fd: (1)-->(2-6,12)
      │    ├── left-join
      │    │    ├── columns: person0_.id:1(int!null) address:2(string) createdon:3(timestamp) name:4(string) nickname:5(string) version:6(int!null) person_id:10(int)
      │    │    ├── fd: (1)-->(2-6)
      │    │    ├── scan person0_
      │    │    │    ├── columns: person0_.id:1(int!null) address:2(string) createdon:3(timestamp) name:4(string) nickname:5(string) version:6(int!null)
      │    │    │    ├── key: (1)
      │    │    │    └── fd: (1)-->(2-6)
      │    │    ├── scan phones1_
      │    │    │    └── columns: person_id:10(int)
      │    │    └── filters
      │    │         └── person0_.id = person_id [type=bool, outer=(1,10), constraints=(/1: (/NULL - ]; /10: (/NULL - ]), fd=(1)==(10), (10)==(1)]
      │    └── aggregations
      │         ├── count [type=int, outer=(10)]
      │         │    └── variable: person_id [type=int]
      │         ├── const-agg [type=string, outer=(2)]
      │         │    └── variable: address [type=string]
      │         ├── const-agg [type=timestamp, outer=(3)]
      │         │    └── variable: createdon [type=timestamp]
      │         ├── const-agg [type=string, outer=(4)]
      │         │    └── variable: name [type=string]
      │         ├── const-agg [type=string, outer=(5)]
      │         │    └── variable: nickname [type=string]
      │         └── const-agg [type=int, outer=(6)]
      │              └── variable: version [type=int]
      └── filters
           └── count = 2 [type=bool, outer=(12), constraints=(/12: [/2 - /2]; tight), fd=()-->(12)]

opt
select
    phone0_.id as id1_4_,
    phone0_.phone_number as phone_nu2_4_,
    phone0_.person_id as person_i4_4_,
    phone0_.phone_type as phone_ty3_4_
from
    Phone phone0_
where
    (
        select
            min(calls1_.id)
        from
            phone_call calls1_
        where
            phone0_.id=calls1_.phone_id
    )=$1
----
project
 ├── columns: id1_4_:1(int!null) phone_nu2_4_:2(string) person_i4_4_:4(int) phone_ty3_4_:3(string)
 ├── has-placeholder
 ├── key: (1)
 ├── fd: (1)-->(2-4)
 └── select
      ├── columns: phone0_.id:1(int!null) phone_number:2(string) phone_type:3(string) person_id:4(int) min:10(int!null)
      ├── has-placeholder
      ├── key: (1)
      ├── fd: (1)-->(2-4,10)
      ├── group-by
      │    ├── columns: phone0_.id:1(int!null) phone_number:2(string) phone_type:3(string) person_id:4(int) min:10(int)
      │    ├── grouping columns: phone0_.id:1(int!null)
      │    ├── key: (1)
      │    ├── fd: (1)-->(2-4,10)
      │    ├── inner-join
      │    │    ├── columns: phone0_.id:1(int!null) phone_number:2(string) phone_type:3(string) person_id:4(int) calls1_.id:6(int!null) phone_id:9(int!null)
      │    │    ├── key: (6)
      │    │    ├── fd: (1)-->(2-4), (6)-->(9), (1)==(9), (9)==(1)
      │    │    ├── scan phone0_
      │    │    │    ├── columns: phone0_.id:1(int!null) phone_number:2(string) phone_type:3(string) person_id:4(int)
      │    │    │    ├── key: (1)
      │    │    │    └── fd: (1)-->(2-4)
      │    │    ├── scan calls1_
      │    │    │    ├── columns: calls1_.id:6(int!null) phone_id:9(int)
      │    │    │    ├── key: (6)
      │    │    │    └── fd: (6)-->(9)
      │    │    └── filters
      │    │         └── phone0_.id = phone_id [type=bool, outer=(1,9), constraints=(/1: (/NULL - ]; /9: (/NULL - ]), fd=(1)==(9), (9)==(1)]
      │    └── aggregations
      │         ├── min [type=int, outer=(6)]
      │         │    └── variable: calls1_.id [type=int]
      │         ├── const-agg [type=string, outer=(2)]
      │         │    └── variable: phone_number [type=string]
      │         ├── const-agg [type=string, outer=(3)]
      │         │    └── variable: phone_type [type=string]
      │         └── const-agg [type=int, outer=(4)]
      │              └── variable: person_id [type=int]
      └── filters
           └── min = $1 [type=bool, outer=(10), constraints=(/10: (/NULL - ])]

opt
select
    person0_.id as id1_2_,
    person0_.address as address2_2_,
    person0_.createdOn as createdO3_2_,
    person0_.name as name4_2_,
    person0_.nickName as nickName5_2_,
    person0_.version as version6_2_
from
    Person person0_
where
    (
        select
            max(phones1_.order_id)
        from
            Phone phones1_
        where
            person0_.id=phones1_.person_id
    )=0
----
project
 ├── columns: id1_2_:1(int!null) address2_2_:2(string) createdo3_2_:3(timestamp) name4_2_:4(string) nickname5_2_:5(string) version6_2_:6(int)
 ├── key: (1)
 ├── fd: (1)-->(2-6)
 └── select
      ├── columns: person0_.id:1(int!null) address:2(string) createdon:3(timestamp) name:4(string) nickname:5(string) version:6(int) max:12(int!null)
      ├── key: (1)
      ├── fd: ()-->(12), (1)-->(2-6)
      ├── group-by
      │    ├── columns: person0_.id:1(int!null) address:2(string) createdon:3(timestamp) name:4(string) nickname:5(string) version:6(int) max:12(int)
      │    ├── grouping columns: person0_.id:1(int!null)
      │    ├── key: (1)
      │    ├── fd: (1)-->(2-6,12)
      │    ├── inner-join
      │    │    ├── columns: person0_.id:1(int!null) address:2(string) createdon:3(timestamp) name:4(string) nickname:5(string) version:6(int!null) person_id:10(int!null) order_id:11(int!null)
      │    │    ├── fd: (1)-->(2-6), (1)==(10), (10)==(1)
      │    │    ├── scan person0_
      │    │    │    ├── columns: person0_.id:1(int!null) address:2(string) createdon:3(timestamp) name:4(string) nickname:5(string) version:6(int!null)
      │    │    │    ├── key: (1)
      │    │    │    └── fd: (1)-->(2-6)
      │    │    ├── select
      │    │    │    ├── columns: person_id:10(int) order_id:11(int!null)
      │    │    │    ├── scan phones1_
      │    │    │    │    └── columns: person_id:10(int) order_id:11(int)
      │    │    │    └── filters
      │    │    │         └── order_id IS NOT NULL [type=bool, outer=(11), constraints=(/11: (/NULL - ]; tight)]
      │    │    └── filters
      │    │         └── person0_.id = person_id [type=bool, outer=(1,10), constraints=(/1: (/NULL - ]; /10: (/NULL - ]), fd=(1)==(10), (10)==(1)]
      │    └── aggregations
      │         ├── max [type=int, outer=(11)]
      │         │    └── variable: order_id [type=int]
      │         ├── const-agg [type=string, outer=(2)]
      │         │    └── variable: address [type=string]
      │         ├── const-agg [type=timestamp, outer=(3)]
      │         │    └── variable: createdon [type=timestamp]
      │         ├── const-agg [type=string, outer=(4)]
      │         │    └── variable: name [type=string]
      │         ├── const-agg [type=string, outer=(5)]
      │         │    └── variable: nickname [type=string]
      │         └── const-agg [type=int, outer=(6)]
      │              └── variable: version [type=int]
      └── filters
           └── max = 0 [type=bool, outer=(12), constraints=(/12: [/0 - /0]; tight), fd=()-->(12)]

opt
select
    person0_.id as id1_2_,
    person0_.address as address2_2_,
    person0_.createdOn as createdO3_2_,
    person0_.name as name4_2_,
    person0_.nickName as nickName5_2_,
    person0_.version as version6_2_
from
    Person person0_
where
    $1::int in (
        select
            phones1_.id
        from
            Phone phones1_
        where
            person0_.id=phones1_.person_id
    )
----
semi-join
 ├── columns: id1_2_:1(int!null) address2_2_:2(string) createdo3_2_:3(timestamp) name4_2_:4(string) nickname5_2_:5(string) version6_2_:6(int!null)
 ├── has-placeholder
 ├── key: (1)
 ├── fd: (1)-->(2-6)
 ├── scan person0_
 │    ├── columns: person0_.id:1(int!null) address:2(string) createdon:3(timestamp) name:4(string) nickname:5(string) version:6(int!null)
 │    ├── key: (1)
 │    └── fd: (1)-->(2-6)
 ├── select
 │    ├── columns: phones1_.id:7(int!null) person_id:10(int)
 │    ├── has-placeholder
 │    ├── key: (7)
 │    ├── fd: (7)-->(10)
 │    ├── scan phones1_
 │    │    ├── columns: phones1_.id:7(int!null) person_id:10(int)
 │    │    ├── key: (7)
 │    │    └── fd: (7)-->(10)
 │    └── filters
 │         └── phones1_.id = $1::INT8 [type=bool, outer=(7), constraints=(/7: (/NULL - ])]
 └── filters
      └── person0_.id = person_id [type=bool, outer=(1,10), constraints=(/1: (/NULL - ]; /10: (/NULL - ]), fd=(1)==(10), (10)==(1)]

opt
select
    person0_.id as id1_2_,
    person0_.address as address2_2_,
    person0_.createdOn as createdO3_2_,
    person0_.name as name4_2_,
    person0_.nickName as nickName5_2_,
    person0_.version as version6_2_
from
    Person person0_
where
    $1::int=some (
        select
            phones1_.id
        from
            Phone phones1_
        where
            person0_.id=phones1_.person_id
    )
----
semi-join
 ├── columns: id1_2_:1(int!null) address2_2_:2(string) createdo3_2_:3(timestamp) name4_2_:4(string) nickname5_2_:5(string) version6_2_:6(int!null)
 ├── has-placeholder
 ├── key: (1)
 ├── fd: (1)-->(2-6)
 ├── scan person0_
 │    ├── columns: person0_.id:1(int!null) address:2(string) createdon:3(timestamp) name:4(string) nickname:5(string) version:6(int!null)
 │    ├── key: (1)
 │    └── fd: (1)-->(2-6)
 ├── select
 │    ├── columns: phones1_.id:7(int!null) person_id:10(int)
 │    ├── has-placeholder
 │    ├── key: (7)
 │    ├── fd: (7)-->(10)
 │    ├── scan phones1_
 │    │    ├── columns: phones1_.id:7(int!null) person_id:10(int)
 │    │    ├── key: (7)
 │    │    └── fd: (7)-->(10)
 │    └── filters
 │         └── phones1_.id = $1::INT8 [type=bool, outer=(7), constraints=(/7: (/NULL - ])]
 └── filters
      └── person0_.id = person_id [type=bool, outer=(1,10), constraints=(/1: (/NULL - ]; /10: (/NULL - ]), fd=(1)==(10), (10)==(1)]

opt
select
    person0_.id as id1_2_,
    person0_.address as address2_2_,
    person0_.createdOn as createdO3_2_,
    person0_.name as name4_2_,
    person0_.nickName as nickName5_2_,
    person0_.version as version6_2_
from
    Person person0_
where
    exists (
        select
            phones1_.id
        from
            Phone phones1_
        where
            person0_.id=phones1_.person_id
    )
----
semi-join
 ├── columns: id1_2_:1(int!null) address2_2_:2(string) createdo3_2_:3(timestamp) name4_2_:4(string) nickname5_2_:5(string) version6_2_:6(int!null)
 ├── key: (1)
 ├── fd: (1)-->(2-6)
 ├── scan person0_
 │    ├── columns: person0_.id:1(int!null) address:2(string) createdon:3(timestamp) name:4(string) nickname:5(string) version:6(int!null)
 │    ├── key: (1)
 │    └── fd: (1)-->(2-6)
 ├── scan phones1_
 │    ├── columns: phones1_.id:7(int!null) person_id:10(int)
 │    ├── key: (7)
 │    └── fd: (7)-->(10)
 └── filters
      └── person0_.id = person_id [type=bool, outer=(1,10), constraints=(/1: (/NULL - ]; /10: (/NULL - ]), fd=(1)==(10), (10)==(1)]

opt
select
    phone0_.id as id1_4_,
    phone0_.phone_number as phone_nu2_4_,
    phone0_.person_id as person_i4_4_,
    phone0_.phone_type as phone_ty3_4_
from
    Phone phone0_
where
    $1::date>all (
        select
            repairtime1_.repairTimestamps
        from
            Phone_repairTimestamps repairtime1_
        where
            phone0_.id=repairtime1_.Phone_id
    )
----
anti-join
 ├── columns: id1_4_:1(int!null) phone_nu2_4_:2(string) person_i4_4_:4(int) phone_ty3_4_:3(string)
 ├── has-placeholder
 ├── key: (1)
 ├── fd: (1)-->(2-4)
 ├── scan phone0_
 │    ├── columns: id:1(int!null) phone_number:2(string) phone_type:3(string) person_id:4(int)
 │    ├── key: (1)
 │    └── fd: (1)-->(2-4)
 ├── select
 │    ├── columns: phone_id:6(int!null) repairtimestamps:7(timestamp)
 │    ├── has-placeholder
 │    ├── scan repairtime1_
 │    │    └── columns: phone_id:6(int!null) repairtimestamps:7(timestamp)
 │    └── filters
 │         └── (repairtimestamps >= $1::DATE) IS NOT false [type=bool, outer=(7)]
 └── filters
      └── id = phone_id [type=bool, outer=(1,6), constraints=(/1: (/NULL - ]; /6: (/NULL - ]), fd=(1)==(6), (6)==(1)]

opt
select
    person0_.id as id1_2_,
    person0_.address as address2_2_,
    person0_.createdOn as createdO3_2_,
    person0_.name as name4_2_,
    person0_.nickName as nickName5_2_,
    person0_.version as version6_2_
from
    Person person0_
where
    1 in (
        select
            phones1_.order_id
        from
            Phone phones1_
        where
            person0_.id=phones1_.person_id
    )
----
semi-join (merge)
 ├── columns: id1_2_:1(int!null) address2_2_:2(string) createdo3_2_:3(timestamp) name4_2_:4(string) nickname5_2_:5(string) version6_2_:6(int!null)
 ├── left ordering: +1
 ├── right ordering: +10
 ├── key: (1)
 ├── fd: (1)-->(2-6)
 ├── scan person0_
 │    ├── columns: person0_.id:1(int!null) address:2(string) createdon:3(timestamp) name:4(string) nickname:5(string) version:6(int!null)
 │    ├── key: (1)
 │    ├── fd: (1)-->(2-6)
 │    └── ordering: +1
 ├── sort
 │    ├── columns: person_id:10(int) order_id:11(int!null)
 │    ├── fd: ()-->(11)
 │    ├── ordering: +10 opt(11) [actual: +10]
 │    └── select
 │         ├── columns: person_id:10(int) order_id:11(int!null)
 │         ├── fd: ()-->(11)
 │         ├── scan phones1_
 │         │    └── columns: person_id:10(int) order_id:11(int)
 │         └── filters
 │              └── order_id = 1 [type=bool, outer=(11), constraints=(/11: [/1 - /1]; tight), fd=()-->(11)]
 └── filters (true)

opt
select
    person0_.id as id1_2_,
    person0_.address as address2_2_,
    person0_.createdOn as createdO3_2_,
    person0_.name as name4_2_,
    person0_.nickName as nickName5_2_,
    person0_.version as version6_2_
from
    Person person0_ cross
join
    Phone phones2_
where
    person0_.id=phones2_.person_id
    and phones2_.order_id = (
        select
            max(phones1_.order_id)
        from
            Phone phones1_
        where
            person0_.id=phones1_.person_id
    )
    and phones2_.phone_type='LAND_LINE'
----
project
 ├── columns: id1_2_:1(int) address2_2_:2(string) createdo3_2_:3(timestamp) name4_2_:4(string) nickname5_2_:5(string) version6_2_:6(int)
 ├── fd: (1)-->(2-6)
 └── select
      ├── columns: person0_.id:1(int) address:2(string) createdon:3(timestamp) name:4(string) nickname:5(string) version:6(int) phones2_.id:7(int!null) phones2_.order_id:11(int!null) max:17(int!null)
      ├── key: (7)
      ├── fd: (1)-->(2-6), (7)-->(1-6,11,17), (11)==(17), (17)==(11)
      ├── group-by
      │    ├── columns: person0_.id:1(int) address:2(string) createdon:3(timestamp) name:4(string) nickname:5(string) version:6(int) phones2_.id:7(int!null) phones2_.order_id:11(int) max:17(int)
      │    ├── grouping columns: phones2_.id:7(int!null)
      │    ├── key: (7)
      │    ├── fd: (1)-->(2-6), (7)-->(1-6,11,17)
      │    ├── inner-join
      │    │    ├── columns: person0_.id:1(int!null) address:2(string) createdon:3(timestamp) name:4(string) nickname:5(string) version:6(int!null) phones2_.id:7(int!null) phones2_.phone_type:9(string!null) phones2_.person_id:10(int!null) phones2_.order_id:11(int) phones1_.person_id:15(int!null) phones1_.order_id:16(int!null)
      │    │    ├── fd: ()-->(9), (1)-->(2-6), (7)-->(10,11), (1)==(10,15), (10)==(1,15), (15)==(1,10)
      │    │    ├── select
      │    │    │    ├── columns: phones1_.person_id:15(int) phones1_.order_id:16(int!null)
      │    │    │    ├── scan phones1_
      │    │    │    │    └── columns: phones1_.person_id:15(int) phones1_.order_id:16(int)
      │    │    │    └── filters
      │    │    │         └── phones1_.order_id IS NOT NULL [type=bool, outer=(16), constraints=(/16: (/NULL - ]; tight)]
      │    │    ├── inner-join (lookup person)
      │    │    │    ├── columns: person0_.id:1(int!null) address:2(string) createdon:3(timestamp) name:4(string) nickname:5(string) version:6(int!null) phones2_.id:7(int!null) phones2_.phone_type:9(string!null) phones2_.person_id:10(int!null) phones2_.order_id:11(int)
      │    │    │    ├── key columns: [10] = [1]
      │    │    │    ├── key: (7)
      │    │    │    ├── fd: ()-->(9), (1)-->(2-6), (7)-->(10,11), (1)==(10), (10)==(1)
      │    │    │    ├── select
      │    │    │    │    ├── columns: phones2_.id:7(int!null) phones2_.phone_type:9(string!null) phones2_.person_id:10(int) phones2_.order_id:11(int)
      │    │    │    │    ├── key: (7)
      │    │    │    │    ├── fd: ()-->(9), (7)-->(10,11)
      │    │    │    │    ├── scan phones2_
      │    │    │    │    │    ├── columns: phones2_.id:7(int!null) phones2_.phone_type:9(string) phones2_.person_id:10(int) phones2_.order_id:11(int)
      │    │    │    │    │    ├── key: (7)
      │    │    │    │    │    └── fd: (7)-->(9-11)
      │    │    │    │    └── filters
      │    │    │    │         └── phones2_.phone_type = 'LAND_LINE' [type=bool, outer=(9), constraints=(/9: [/'LAND_LINE' - /'LAND_LINE']; tight), fd=()-->(9)]
      │    │    │    └── filters (true)
      │    │    └── filters
      │    │         └── person0_.id = phones1_.person_id [type=bool, outer=(1,15), constraints=(/1: (/NULL - ]; /15: (/NULL - ]), fd=(1)==(15), (15)==(1)]
      │    └── aggregations
      │         ├── max [type=int, outer=(16)]
      │         │    └── variable: phones1_.order_id [type=int]
      │         ├── const-agg [type=int, outer=(11)]
      │         │    └── variable: phones2_.order_id [type=int]
      │         ├── const-agg [type=string, outer=(2)]
      │         │    └── variable: address [type=string]
      │         ├── const-agg [type=timestamp, outer=(3)]
      │         │    └── variable: createdon [type=timestamp]
      │         ├── const-agg [type=string, outer=(4)]
      │         │    └── variable: name [type=string]
      │         ├── const-agg [type=string, outer=(5)]
      │         │    └── variable: nickname [type=string]
      │         ├── const-agg [type=int, outer=(6)]
      │         │    └── variable: version [type=int]
      │         └── const-agg [type=int, outer=(1)]
      │              └── variable: person0_.id [type=int]
      └── filters
           └── phones2_.order_id = max [type=bool, outer=(11,17), constraints=(/11: (/NULL - ]; /17: (/NULL - ]), fd=(11)==(17), (17)==(11)]

opt
select
    person0_.id as id1_2_,
    person0_.address as address2_2_,
    person0_.createdOn as createdO3_2_,
    person0_.name as name4_2_,
    person0_.nickName as nickName5_2_,
    person0_.version as version6_2_
from
    Person person0_
where
    not (exists (select
        phones1_.id
    from
        Phone phones1_
    where
        person0_.id=phones1_.person_id))
----
anti-join
 ├── columns: id1_2_:1(int!null) address2_2_:2(string) createdo3_2_:3(timestamp) name4_2_:4(string) nickname5_2_:5(string) version6_2_:6(int!null)
 ├── key: (1)
 ├── fd: (1)-->(2-6)
 ├── scan person0_
 │    ├── columns: person0_.id:1(int!null) address:2(string) createdon:3(timestamp) name:4(string) nickname:5(string) version:6(int!null)
 │    ├── key: (1)
 │    └── fd: (1)-->(2-6)
 ├── scan phones1_
 │    ├── columns: phones1_.id:7(int!null) person_id:10(int)
 │    ├── key: (7)
 │    └── fd: (7)-->(10)
 └── filters
      └── person0_.id = person_id [type=bool, outer=(1,10), constraints=(/1: (/NULL - ]; /10: (/NULL - ]), fd=(1)==(10), (10)==(1)]

opt
select
    person0_.id as id1_2_,
    person0_.address as address2_2_,
    person0_.createdOn as createdO3_2_,
    person0_.name as name4_2_,
    person0_.nickName as nickName5_2_,
    person0_.version as version6_2_
from
    Person person0_
where
    exists (
        select
            phones1_.id
        from
            Phone phones1_
        where
            person0_.id=phones1_.person_id
    )
----
semi-join
 ├── columns: id1_2_:1(int!null) address2_2_:2(string) createdo3_2_:3(timestamp) name4_2_:4(string) nickname5_2_:5(string) version6_2_:6(int!null)
 ├── key: (1)
 ├── fd: (1)-->(2-6)
 ├── scan person0_
 │    ├── columns: person0_.id:1(int!null) address:2(string) createdon:3(timestamp) name:4(string) nickname:5(string) version:6(int!null)
 │    ├── key: (1)
 │    └── fd: (1)-->(2-6)
 ├── scan phones1_
 │    ├── columns: phones1_.id:7(int!null) person_id:10(int)
 │    ├── key: (7)
 │    └── fd: (7)-->(10)
 └── filters
      └── person0_.id = person_id [type=bool, outer=(1,10), constraints=(/1: (/NULL - ]; /10: (/NULL - ]), fd=(1)==(10), (10)==(1)]

opt
select
    phone0_.id as id1_4_,
    phone0_.phone_number as phone_nu2_4_,
    phone0_.person_id as person_i4_4_,
    phone0_.phone_type as phone_ty3_4_
from
    Phone phone0_
where
    not (exists (select
        calls1_.id
    from
        phone_call calls1_
    where
        phone0_.id=calls1_.phone_id))
----
anti-join
 ├── columns: id1_4_:1(int!null) phone_nu2_4_:2(string) person_i4_4_:4(int) phone_ty3_4_:3(string)
 ├── key: (1)
 ├── fd: (1)-->(2-4)
 ├── scan phone0_
 │    ├── columns: phone0_.id:1(int!null) phone_number:2(string) phone_type:3(string) person_id:4(int)
 │    ├── key: (1)
 │    └── fd: (1)-->(2-4)
 ├── scan calls1_
 │    ├── columns: calls1_.id:6(int!null) phone_id:9(int)
 │    ├── key: (6)
 │    └── fd: (6)-->(9)
 └── filters
      └── phone0_.id = phone_id [type=bool, outer=(1,9), constraints=(/1: (/NULL - ]; /9: (/NULL - ]), fd=(1)==(9), (9)==(1)]

opt
select
    person0_.id as id1_2_,
    person0_.address as address2_2_,
    person0_.createdOn as createdO3_2_,
    person0_.name as name4_2_,
    person0_.nickName as nickName5_2_,
    person0_.version as version6_2_
from
    Person person0_
where
    'Home address' in (
        select
            addresses1_.addresses
        from
            Person_addresses addresses1_
        where
            person0_.id=addresses1_.Person_id
    )
----
semi-join (merge)
 ├── columns: id1_2_:1(int!null) address2_2_:2(string) createdo3_2_:3(timestamp) name4_2_:4(string) nickname5_2_:5(string) version6_2_:6(int!null)
 ├── left ordering: +1
 ├── right ordering: +7
 ├── key: (1)
 ├── fd: (1)-->(2-6)
 ├── scan person0_
 │    ├── columns: id:1(int!null) address:2(string) createdon:3(timestamp) name:4(string) nickname:5(string) version:6(int!null)
 │    ├── key: (1)
 │    ├── fd: (1)-->(2-6)
 │    └── ordering: +1
 ├── select
 │    ├── columns: person_id:7(int!null) addresses:8(string!null)
 │    ├── fd: ()-->(8)
 │    ├── ordering: +7 opt(8) [actual: +7]
 │    ├── scan addresses1_
 │    │    ├── columns: person_id:7(int!null) addresses:8(string)
 │    │    └── ordering: +7 opt(8) [actual: +7]
 │    └── filters
 │         └── addresses = 'Home address' [type=bool, outer=(8), constraints=(/8: [/'Home address' - /'Home address']; tight), fd=()-->(8)]
 └── filters (true)

opt
select
    person0_.id as id1_2_,
    person0_.address as address2_2_,
    person0_.createdOn as createdO3_2_,
    person0_.name as name4_2_,
    person0_.nickName as nickName5_2_,
    person0_.version as version6_2_
from
    Person person0_
where
    'Home address' not in  (
        select
            addresses1_.addresses
        from
            Person_addresses addresses1_
        where
            person0_.id=addresses1_.Person_id
    )
----
anti-join (merge)
 ├── columns: id1_2_:1(int!null) address2_2_:2(string) createdo3_2_:3(timestamp) name4_2_:4(string) nickname5_2_:5(string) version6_2_:6(int!null)
 ├── left ordering: +1
 ├── right ordering: +7
 ├── key: (1)
 ├── fd: (1)-->(2-6)
 ├── scan person0_
 │    ├── columns: id:1(int!null) address:2(string) createdon:3(timestamp) name:4(string) nickname:5(string) version:6(int!null)
 │    ├── key: (1)
 │    ├── fd: (1)-->(2-6)
 │    └── ordering: +1
 ├── select
 │    ├── columns: person_id:7(int!null) addresses:8(string)
 │    ├── ordering: +7
 │    ├── scan addresses1_
 │    │    ├── columns: person_id:7(int!null) addresses:8(string)
 │    │    └── ordering: +7
 │    └── filters
 │         └── (addresses = 'Home address') IS NOT false [type=bool, outer=(8)]
 └── filters (true)

exec-ddl
drop table Phone, phone_call, Person, Phone_repairTimestamps, Person_addresses;
----

# ------------------------------------------------------------------------------
# Query #6
# ------------------------------------------------------------------------------
exec-ddl
create table EMPLOYEE (
   id int8 not null,
    email varchar(255),
    currentProject_id int8,
    primary key (id)
)
----
TABLE employee
 ├── id int not null
 ├── email string
 ├── currentproject_id int
 └── INDEX primary
      └── id int not null

exec-ddl
create table Employee_phones (
   Employee_id int8 not null,
    phone_number varchar(255)
)
----
TABLE employee_phones
 ├── employee_id int not null
 ├── phone_number string
 ├── rowid int not null (hidden)
 └── INDEX primary
      └── rowid int not null (hidden)

opt
select
    componenti0_.id as id1_0_,
    componenti0_.email as email2_0_,
    componenti0_.currentProject_id as currentP3_0_
from
    EMPLOYEE componenti0_
where
    (
        select
            count(phones1_.Employee_id)
        from
            Employee_phones phones1_
        where
            componenti0_.id=phones1_.Employee_id
    )=1
----
project
 ├── columns: id1_0_:1(int!null) email2_0_:2(string) currentp3_0_:3(int)
 ├── key: (1)
 ├── fd: (1)-->(2,3)
 └── select
      ├── columns: id:1(int!null) email:2(string) currentproject_id:3(int) count:7(int!null)
      ├── key: (1)
      ├── fd: ()-->(7), (1)-->(2,3)
      ├── group-by
      │    ├── columns: id:1(int!null) email:2(string) currentproject_id:3(int) count:7(int)
      │    ├── grouping columns: id:1(int!null)
      │    ├── key: (1)
      │    ├── fd: (1)-->(2,3,7)
      │    ├── left-join
      │    │    ├── columns: id:1(int!null) email:2(string) currentproject_id:3(int) employee_id:4(int)
      │    │    ├── fd: (1)-->(2,3)
      │    │    ├── scan componenti0_
      │    │    │    ├── columns: id:1(int!null) email:2(string) currentproject_id:3(int)
      │    │    │    ├── key: (1)
      │    │    │    └── fd: (1)-->(2,3)
      │    │    ├── scan phones1_
      │    │    │    └── columns: employee_id:4(int!null)
      │    │    └── filters
      │    │         └── id = employee_id [type=bool, outer=(1,4), constraints=(/1: (/NULL - ]; /4: (/NULL - ]), fd=(1)==(4), (4)==(1)]
      │    └── aggregations
      │         ├── count [type=int, outer=(4)]
      │         │    └── variable: employee_id [type=int]
      │         ├── const-agg [type=string, outer=(2)]
      │         │    └── variable: email [type=string]
      │         └── const-agg [type=int, outer=(3)]
      │              └── variable: currentproject_id [type=int]
      └── filters
           └── count = 1 [type=bool, outer=(7), constraints=(/7: [/1 - /1]; tight), fd=()-->(7)]

exec-ddl
drop table EMPLOYEE, Employee_phones;
----

# ------------------------------------------------------------------------------
# Query #7
# ------------------------------------------------------------------------------
exec-ddl
create table Company (
   id int8 not null,
    location_id int8,
    primary key (id)
)
----
TABLE company
 ├── id int not null
 ├── location_id int
 └── INDEX primary
      └── id int not null

exec-ddl
create table Company_Employee (
   Company_id int8 not null,
    employees_id int8 not null,
    primary key (Company_id, employees_id)
)
----
TABLE company_employee
 ├── company_id int not null
 ├── employees_id int not null
 └── INDEX primary
      ├── company_id int not null
      └── employees_id int not null

exec-ddl
create table Employee (
   id int8 not null,
    primary key (id)
)
----
TABLE employee
 ├── id int not null
 └── INDEX primary
      └── id int not null

exec-ddl
create table Manager (
   id int8 not null,
    primary key (id)
)
----
TABLE manager
 ├── id int not null
 └── INDEX primary
      └── id int not null

exec-ddl
create table Location (
   id int8 not null,
    address varchar(255),
    zip int4 not null,
    primary key (id)
)
----
TABLE location
 ├── id int not null
 ├── address string
 ├── zip int not null
 └── INDEX primary
      └── id int not null

opt
select
    company0_.id as id1_0_0_,
    location3_.id as id1_8_1_,
    company0_.location_id as location2_0_0_,
    location3_.address as address2_8_1_,
    location3_.zip as zip3_8_1_
from
    Company company0_
left outer join
    Location location3_
        on company0_.location_id=location3_.id
where
    not (exists (select
        employee2_.id
    from
        Company_Employee employees1_,
        ( select
            id,
            0 as clazz_
        from
            Employee
        union
        all select
            id,
            1 as clazz_
        from
            Manager ) employee2_
    where
        company0_.id=employees1_.Company_id
        and employees1_.employees_id=employee2_.id))
----
left-join
 ├── columns: id1_0_0_:1(int!null) id1_8_1_:3(int) location2_0_0_:2(int) address2_8_1_:4(string) zip3_8_1_:5(int)
 ├── key: (1,3)
 ├── fd: (1)-->(2), (3)-->(4,5)
 ├── anti-join
 │    ├── columns: company0_.id:1(int!null) location_id:2(int)
 │    ├── key: (1)
 │    ├── fd: (1)-->(2)
 │    ├── scan company0_
 │    │    ├── columns: company0_.id:1(int!null) location_id:2(int)
 │    │    ├── key: (1)
 │    │    └── fd: (1)-->(2)
 │    ├── inner-join
 │    │    ├── columns: company_id:6(int!null) employees_id:7(int!null) id:12(int!null) clazz_:13(int!null)
 │    │    ├── fd: (7)==(12), (12)==(7)
 │    │    ├── union-all
 │    │    │    ├── columns: id:12(int!null) clazz_:13(int!null)
 │    │    │    ├── left columns: employee.id:8(int) clazz_:9(int)
 │    │    │    ├── right columns: manager.id:10(int) clazz_:11(int)
 │    │    │    ├── project
 │    │    │    │    ├── columns: clazz_:9(int!null) employee.id:8(int!null)
 │    │    │    │    ├── key: (8)
 │    │    │    │    ├── fd: ()-->(9)
 │    │    │    │    ├── scan employee
 │    │    │    │    │    ├── columns: employee.id:8(int!null)
 │    │    │    │    │    └── key: (8)
 │    │    │    │    └── projections
 │    │    │    │         └── const: 0 [type=int]
 │    │    │    └── project
 │    │    │         ├── columns: clazz_:11(int!null) manager.id:10(int!null)
 │    │    │         ├── key: (10)
 │    │    │         ├── fd: ()-->(11)
 │    │    │         ├── scan manager
 │    │    │         │    ├── columns: manager.id:10(int!null)
 │    │    │         │    └── key: (10)
 │    │    │         └── projections
 │    │    │              └── const: 1 [type=int]
 │    │    ├── scan employees1_
 │    │    │    ├── columns: company_id:6(int!null) employees_id:7(int!null)
 │    │    │    └── key: (6,7)
 │    │    └── filters
 │    │         └── employees_id = id [type=bool, outer=(7,12), constraints=(/7: (/NULL - ]; /12: (/NULL - ]), fd=(7)==(12), (12)==(7)]
 │    └── filters
 │         └── company0_.id = company_id [type=bool, outer=(1,6), constraints=(/1: (/NULL - ]; /6: (/NULL - ]), fd=(1)==(6), (6)==(1)]
 ├── scan location3_
 │    ├── columns: location3_.id:3(int!null) address:4(string) zip:5(int!null)
 │    ├── key: (3)
 │    └── fd: (3)-->(4,5)
 └── filters
      └── location_id = location3_.id [type=bool, outer=(2,3), constraints=(/2: (/NULL - ]; /3: (/NULL - ]), fd=(2)==(3), (3)==(2)]

exec-ddl
drop table Company, Company_Employee, Employee, Manager, Location;
----

# ------------------------------------------------------------------------------
# Query #8
#   org.hibernate.test.annotations.indexcoll.IndexedCollectionTest
#   testMapKeyOnManyToMany
# ------------------------------------------------------------------------------
exec-ddl
create table News (
   news_id int4 not null,
    detail varchar(255),
    title varchar(255),
    primary key (news_id)
)
----
TABLE news
 ├── news_id int not null
 ├── detail string
 ├── title string
 └── INDEX primary
      └── news_id int not null

exec-ddl
create table Newspaper (
   id int4 not null,
    name varchar(255),
    primary key (id)
)
----
TABLE newspaper
 ├── id int not null
 ├── name string
 └── INDEX primary
      └── id int not null

exec-ddl
create table Newspaper_News (
   Newspaper_id int4 not null,
    news_news_id int4 not null,
    primary key (Newspaper_id, news_news_id)
)
----
TABLE newspaper_news
 ├── newspaper_id int not null
 ├── news_news_id int not null
 └── INDEX primary
      ├── newspaper_id int not null
      └── news_news_id int not null

opt
select
    news0_.Newspaper_id as Newspape1_23_0_,
    news0_.news_news_id as news_new2_23_0_,
    (select
        a0.title
    from
        News a0
    where
        a0.news_id=news0_.news_news_id) as formula140_0_,
    news1_.news_id as news_id1_21_1_,
    news1_.detail as detail2_21_1_,
    news1_.title as title3_21_1_
from
    Newspaper_News news0_
inner join
    News news1_
        on news0_.news_news_id=news1_.news_id
where
    news0_.Newspaper_id=1
----
project
 ├── columns: newspape1_23_0_:1(int!null) news_new2_23_0_:2(int!null) formula140_0_:9(string) news_id1_21_1_:3(int!null) detail2_21_1_:4(string) title3_21_1_:5(string)
 ├── fd: ()-->(1), (3)-->(4,5), (2)==(3), (3)==(2)
 ├── left-join (lookup news)
 │    ├── columns: newspaper_id:1(int!null) news_news_id:2(int!null) news1_.news_id:3(int!null) news1_.detail:4(string) news1_.title:5(string) a0.news_id:6(int) a0.title:8(string)
 │    ├── key columns: [2] = [6]
 │    ├── key: (3,6)
 │    ├── fd: ()-->(1), (3)-->(4,5), (2)==(3), (3)==(2), (6)-->(8)
 │    ├── inner-join (lookup news)
 │    │    ├── columns: newspaper_id:1(int!null) news_news_id:2(int!null) news1_.news_id:3(int!null) news1_.detail:4(string) news1_.title:5(string)
 │    │    ├── key columns: [2] = [3]
 │    │    ├── key: (3)
 │    │    ├── fd: ()-->(1), (3)-->(4,5), (2)==(3), (3)==(2)
 │    │    ├── scan news0_
 │    │    │    ├── columns: newspaper_id:1(int!null) news_news_id:2(int!null)
 │    │    │    ├── constraint: /1/2: [/1 - /1]
 │    │    │    ├── key: (2)
 │    │    │    └── fd: ()-->(1)
 │    │    └── filters (true)
 │    └── filters (true)
 └── projections
      └── variable: a0.title [type=string, outer=(8)]

exec-ddl
drop table News, Newspaper, Newspaper_News;
----

# ------------------------------------------------------------------------------
# Query #9
#   org.hibernate.test.annotations.indexcoll.MapKeyTest testMapKeyOnEmbeddedId
# ------------------------------------------------------------------------------
exec-ddl
create table GenerationGroup (
   id int4 not null,
    age varchar(255),
    culture varchar(255),
    description varchar(255),
    primary key (id)
)
----
TABLE generationgroup
 ├── id int not null
 ├── age string
 ├── culture string
 ├── description string
 └── INDEX primary
      └── id int not null

exec-ddl
create table GenerationUser (
   id int4 not null,
    primary key (id)
)
----
TABLE generationuser
 ├── id int not null
 └── INDEX primary
      └── id int not null

exec-ddl
create table GenerationUser_GenerationGroup (
   GenerationUser_id int4 not null,
    ref_id int4 not null,
    primary key (GenerationUser_id, ref_id)
)
----
TABLE generationuser_generationgroup
 ├── generationuser_id int not null
 ├── ref_id int not null
 └── INDEX primary
      ├── generationuser_id int not null
      └── ref_id int not null

opt
SELECT ref0_.generationuser_id AS generati1_2_0_
      ,ref0_.ref_id AS ref_id2_2_0_
      ,(SELECT a13.age
        FROM generationgroup AS a13
        WHERE a13.id = ref0_.ref_id) AS formula131_0_
      ,(SELECT a15.culture
        FROM generationgroup AS a15
        WHERE a15.id = ref0_.ref_id) AS formula132_0_
      ,(SELECT a13.description
        FROM generationgroup AS a13
        WHERE a13.id = ref0_.ref_id) AS formula133_0_
      ,generation1_.id AS id1_0_1_
      ,generation1_.age AS age2_0_1_
      ,generation1_.culture AS culture3_0_1_
      ,generation1_.description AS descript4_0_1_
FROM generationuser_generationgroup AS ref0_
INNER JOIN generationgroup AS generation1_
  ON ref0_.ref_id = generation1_.id
WHERE ref0_.generationuser_id = 1;
----
project
 ├── columns: generati1_2_0_:1(int!null) ref_id2_2_0_:2(int!null) formula131_0_:19(string) formula132_0_:20(string) formula133_0_:21(string) id1_0_1_:3(int!null) age2_0_1_:4(string) culture3_0_1_:5(string) descript4_0_1_:6(string)
 ├── fd: ()-->(1), (3)-->(4-6), (2)==(3), (3)==(2)
 ├── left-join (lookup generationgroup)
 │    ├── columns: generationuser_id:1(int!null) ref_id:2(int!null) generation1_.id:3(int!null) generation1_.age:4(string) generation1_.culture:5(string) generation1_.description:6(string) a13.id:7(int) a13.age:8(string) a15.id:11(int) a15.culture:13(string) a13.id:15(int) a13.description:18(string)
 │    ├── key columns: [2] = [15]
 │    ├── key: (3,7,11,15)
 │    ├── fd: ()-->(1), (3)-->(4-6), (2)==(3), (3)==(2), (7)-->(8), (11)-->(13), (15)-->(18)
 │    ├── left-join (lookup generationgroup)
 │    │    ├── columns: generationuser_id:1(int!null) ref_id:2(int!null) generation1_.id:3(int!null) generation1_.age:4(string) generation1_.culture:5(string) generation1_.description:6(string) a13.id:7(int) a13.age:8(string) a15.id:11(int) a15.culture:13(string)
 │    │    ├── key columns: [2] = [11]
 │    │    ├── key: (3,7,11)
 │    │    ├── fd: ()-->(1), (3)-->(4-6), (2)==(3), (3)==(2), (7)-->(8), (11)-->(13)
 │    │    ├── left-join (lookup generationgroup)
 │    │    │    ├── columns: generationuser_id:1(int!null) ref_id:2(int!null) generation1_.id:3(int!null) generation1_.age:4(string) generation1_.culture:5(string) generation1_.description:6(string) a13.id:7(int) a13.age:8(string)
 │    │    │    ├── key columns: [2] = [7]
 │    │    │    ├── key: (3,7)
 │    │    │    ├── fd: ()-->(1), (3)-->(4-6), (2)==(3), (3)==(2), (7)-->(8)
 │    │    │    ├── inner-join (lookup generationgroup)
 │    │    │    │    ├── columns: generationuser_id:1(int!null) ref_id:2(int!null) generation1_.id:3(int!null) generation1_.age:4(string) generation1_.culture:5(string) generation1_.description:6(string)
 │    │    │    │    ├── key columns: [2] = [3]
 │    │    │    │    ├── key: (3)
 │    │    │    │    ├── fd: ()-->(1), (3)-->(4-6), (2)==(3), (3)==(2)
 │    │    │    │    ├── scan ref0_
 │    │    │    │    │    ├── columns: generationuser_id:1(int!null) ref_id:2(int!null)
 │    │    │    │    │    ├── constraint: /1/2: [/1 - /1]
 │    │    │    │    │    ├── key: (2)
 │    │    │    │    │    └── fd: ()-->(1)
 │    │    │    │    └── filters (true)
 │    │    │    └── filters (true)
 │    │    └── filters (true)
 │    └── filters (true)
 └── projections
      ├── variable: a13.age [type=string, outer=(8)]
      ├── variable: a15.culture [type=string, outer=(13)]
      └── variable: a13.description [type=string, outer=(18)]

exec-ddl
drop table GenerationGroup, GenerationUser, GenerationUser_GenerationGroup;
----

# ------------------------------------------------------------------------------
# Query #10
#   org.hibernate.test.bidi.AuctionTest2 testLazy
# ------------------------------------------------------------------------------
exec-ddl
create table TAuction2 (
   id int8 not null,
    description varchar(255),
    endDatetime timestamp,
    successfulBid int8,
    primary key (id)
)
----
TABLE tauction2
 ├── id int not null
 ├── description string
 ├── enddatetime timestamp
 ├── successfulbid int
 └── INDEX primary
      └── id int not null

exec-ddl
create table TBid2 (
   id int8 not null,
    amount numeric(31, 19),
    createdDatetime timestamp,
    auctionId int8,
    primary key (id)
)
----
TABLE tbid2
 ├── id int not null
 ├── amount decimal
 ├── createddatetime timestamp
 ├── auctionid int
 └── INDEX primary
      └── id int not null

opt
select
    bids0_.auctionId as auctionI4_1_0_,
    bids0_.id as id1_1_0_,
    bids0_.id as id1_1_1_,
    bids0_.amount as amount2_1_1_,
    bids0_.createdDatetime as createdD3_1_1_,
    bids0_.auctionId as auctionI4_1_1_,
    exists(select
        a.id
    from
        TAuction2 a
    where
        a.successfulBid=bids0_.id) as formula41_1_
from
    TBid2 bids0_
where
    bids0_.auctionId=$1
----
project
 ├── columns: auctioni4_1_0_:4(int) id1_1_0_:1(int!null) id1_1_1_:1(int!null) amount2_1_1_:2(decimal) createdd3_1_1_:3(timestamp) auctioni4_1_1_:4(int) formula41_1_:9(bool)
 ├── has-placeholder
 ├── key: (1)
 ├── fd: (1)-->(2-4,9)
 ├── group-by
 │    ├── columns: bids0_.id:1(int!null) amount:2(decimal) createddatetime:3(timestamp) auctionid:4(int) true_agg:11(bool)
 │    ├── grouping columns: bids0_.id:1(int!null)
 │    ├── has-placeholder
 │    ├── key: (1)
 │    ├── fd: (1)-->(2-4,11)
 │    ├── right-join
 │    │    ├── columns: bids0_.id:1(int!null) amount:2(decimal) createddatetime:3(timestamp) auctionid:4(int!null) successfulbid:8(int) true:10(bool)
 │    │    ├── has-placeholder
 │    │    ├── fd: (1)-->(2-4), ()~~>(10)
 │    │    ├── project
 │    │    │    ├── columns: true:10(bool!null) successfulbid:8(int)
 │    │    │    ├── fd: ()-->(10)
 │    │    │    ├── scan a
 │    │    │    │    └── columns: successfulbid:8(int)
 │    │    │    └── projections
 │    │    │         └── true [type=bool]
 │    │    ├── select
 │    │    │    ├── columns: bids0_.id:1(int!null) amount:2(decimal) createddatetime:3(timestamp) auctionid:4(int!null)
 │    │    │    ├── has-placeholder
 │    │    │    ├── key: (1)
 │    │    │    ├── fd: (1)-->(2-4)
 │    │    │    ├── scan bids0_
 │    │    │    │    ├── columns: bids0_.id:1(int!null) amount:2(decimal) createddatetime:3(timestamp) auctionid:4(int)
 │    │    │    │    ├── key: (1)
 │    │    │    │    └── fd: (1)-->(2-4)
 │    │    │    └── filters
 │    │    │         └── auctionid = $1 [type=bool, outer=(4), constraints=(/4: (/NULL - ])]
 │    │    └── filters
 │    │         └── successfulbid = bids0_.id [type=bool, outer=(1,8), constraints=(/1: (/NULL - ]; /8: (/NULL - ]), fd=(1)==(8), (8)==(1)]
 │    └── aggregations
 │         ├── const-not-null-agg [type=bool, outer=(10)]
 │         │    └── variable: true [type=bool]
 │         ├── const-agg [type=decimal, outer=(2)]
 │         │    └── variable: amount [type=decimal]
 │         ├── const-agg [type=timestamp, outer=(3)]
 │         │    └── variable: createddatetime [type=timestamp]
 │         └── const-agg [type=int, outer=(4)]
 │              └── variable: auctionid [type=int]
 └── projections
      └── true_agg IS NOT NULL [type=bool, outer=(11)]

exec-ddl
drop table TAuction2, TBid2;
----

# ------------------------------------------------------------------------------
# Query #11
#   org.hibernate.test.cid.CompositeIdTest
# ------------------------------------------------------------------------------
exec-ddl
CREATE TABLE customer (
  customerid VARCHAR(10) NOT NULL,
  name VARCHAR(100) NOT NULL,
  address VARCHAR(200) NOT NULL,
  PRIMARY KEY (customerid)
);
----
TABLE customer
 ├── customerid string not null
 ├── name string not null
 ├── address string not null
 └── INDEX primary
      └── customerid string not null

exec-ddl
CREATE TABLE customerorder (
  customerid VARCHAR(10) NOT NULL,
  ordernumber INT4 NOT NULL,
  orderdate DATE NOT NULL,
  PRIMARY KEY (customerid, ordernumber)
);
----
TABLE customerorder
 ├── customerid string not null
 ├── ordernumber int not null
 ├── orderdate date not null
 └── INDEX primary
      ├── customerid string not null
      └── ordernumber int not null

exec-ddl
CREATE TABLE lineitem (
  customerid VARCHAR(10) NOT NULL,
  ordernumber INT4 NOT NULL,
  productid VARCHAR(10) NOT NULL,
  quantity INT4,
  PRIMARY KEY (customerid, ordernumber, productid)
);
----
TABLE lineitem
 ├── customerid string not null
 ├── ordernumber int not null
 ├── productid string not null
 ├── quantity int
 └── INDEX primary
      ├── customerid string not null
      ├── ordernumber int not null
      └── productid string not null

exec-ddl
CREATE TABLE product (
  productid VARCHAR(10) NOT NULL,
  description VARCHAR(200) NOT NULL,
  cost NUMERIC(19,2),
  numberavailable INT4,
  PRIMARY KEY (productid)
);
----
TABLE product
 ├── productid string not null
 ├── description string not null
 ├── cost decimal
 ├── numberavailable int
 └── INDEX primary
      └── productid string not null

opt
SELECT
  order0_.customerid AS customer1_1_0_,
  order0_.ordernumber AS ordernum2_1_0_,
  order0_.orderdate AS orderdat3_1_0_,
  (
    SELECT
      sum(li.quantity * p.cost)
    FROM
      lineitem AS li, product AS p
    WHERE
      li.productid = p.productid
      AND li.customerid = order0_.customerid
      AND li.ordernumber = order0_.ordernumber
  )
    AS formula101_0_,
  lineitems1_.customerid AS customer1_2_1_,
  lineitems1_.ordernumber AS ordernum2_2_1_,
  lineitems1_.productid AS producti3_2_1_,
  lineitems1_.customerid AS customer1_2_2_,
  lineitems1_.ordernumber AS ordernum2_2_2_,
  lineitems1_.productid AS producti3_2_2_,
  lineitems1_.quantity AS quantity4_2_2_
FROM
  customerorder AS order0_
  LEFT JOIN lineitem AS lineitems1_
  ON
    order0_.customerid = lineitems1_.customerid
    AND order0_.ordernumber = lineitems1_.ordernumber
WHERE
  order0_.customerid = 'c111' AND order0_.ordernumber = 0;
----
project
 ├── columns: customer1_1_0_:1(string) ordernum2_1_0_:2(int) orderdat3_1_0_:3(date) formula101_0_:18(decimal) customer1_2_1_:4(string) ordernum2_2_1_:5(int) producti3_2_1_:6(string) customer1_2_2_:4(string) ordernum2_2_2_:5(int) producti3_2_2_:6(string) quantity4_2_2_:7(int)
 ├── key: (6)
 ├── fd: ()-->(1-3), (6)-->(4,5,7,18), ()~~>(4,5)
 ├── group-by
 │    ├── columns: order0_.customerid:1(string) order0_.ordernumber:2(int) orderdate:3(date) lineitems1_.customerid:4(string) lineitems1_.ordernumber:5(int) lineitems1_.productid:6(string) lineitems1_.quantity:7(int) sum:17(decimal)
 │    ├── grouping columns: lineitems1_.productid:6(string)
 │    ├── key: (6)
 │    ├── fd: ()-->(1-3), (6)-->(1-5,7,17), ()~~>(4,5)
 │    ├── right-join
 │    │    ├── columns: order0_.customerid:1(string!null) order0_.ordernumber:2(int!null) orderdate:3(date!null) lineitems1_.customerid:4(string) lineitems1_.ordernumber:5(int) lineitems1_.productid:6(string) lineitems1_.quantity:7(int) li.customerid:8(string) li.ordernumber:9(int) column16:16(decimal)
 │    │    ├── fd: ()-->(1-3), (6)-->(4,5,7), ()~~>(4,5)
 │    │    ├── project
 │    │    │    ├── columns: column16:16(decimal) li.customerid:8(string!null) li.ordernumber:9(int!null)
 │    │    │    ├── inner-join
 │    │    │    │    ├── columns: li.customerid:8(string!null) li.ordernumber:9(int!null) li.productid:10(string!null) li.quantity:11(int) p.productid:12(string!null) cost:14(decimal)
 │    │    │    │    ├── key: (8,9,12)
 │    │    │    │    ├── fd: (8-10)-->(11), (12)-->(14), (10)==(12), (12)==(10)
 │    │    │    │    ├── scan li
 │    │    │    │    │    ├── columns: li.customerid:8(string!null) li.ordernumber:9(int!null) li.productid:10(string!null) li.quantity:11(int)
 │    │    │    │    │    ├── key: (8-10)
 │    │    │    │    │    └── fd: (8-10)-->(11)
 │    │    │    │    ├── scan p
 │    │    │    │    │    ├── columns: p.productid:12(string!null) cost:14(decimal)
 │    │    │    │    │    ├── key: (12)
 │    │    │    │    │    └── fd: (12)-->(14)
 │    │    │    │    └── filters
 │    │    │    │         └── li.productid = p.productid [type=bool, outer=(10,12), constraints=(/10: (/NULL - ]; /12: (/NULL - ]), fd=(10)==(12), (12)==(10)]
 │    │    │    └── projections
 │    │    │         └── li.quantity * cost [type=decimal, outer=(11,14)]
 │    │    ├── left-join (merge)
 │    │    │    ├── columns: order0_.customerid:1(string!null) order0_.ordernumber:2(int!null) orderdate:3(date!null) lineitems1_.customerid:4(string) lineitems1_.ordernumber:5(int) lineitems1_.productid:6(string) lineitems1_.quantity:7(int)
 │    │    │    ├── left ordering: +1,+2
 │    │    │    ├── right ordering: +4,+5
 │    │    │    ├── key: (6)
 │    │    │    ├── fd: ()-->(1-3), (6)-->(4,5,7), ()~~>(4,5)
 │    │    │    ├── scan order0_
 │    │    │    │    ├── columns: order0_.customerid:1(string!null) order0_.ordernumber:2(int!null) orderdate:3(date!null)
 │    │    │    │    ├── constraint: /1/2: [/'c111'/0 - /'c111'/0]
 │    │    │    │    ├── cardinality: [0 - 1]
 │    │    │    │    ├── key: ()
 │    │    │    │    └── fd: ()-->(1-3)
 │    │    │    ├── scan lineitems1_
 │    │    │    │    ├── columns: lineitems1_.customerid:4(string!null) lineitems1_.ordernumber:5(int!null) lineitems1_.productid:6(string!null) lineitems1_.quantity:7(int)
 │    │    │    │    ├── constraint: /4/5/6: [/'c111'/0 - /'c111'/0]
 │    │    │    │    ├── key: (6)
 │    │    │    │    └── fd: ()-->(4,5), (6)-->(7)
 │    │    │    └── filters (true)
 │    │    └── filters
 │    │         ├── li.customerid = order0_.customerid [type=bool, outer=(1,8), constraints=(/1: (/NULL - ]; /8: (/NULL - ]), fd=(1)==(8), (8)==(1)]
 │    │         └── li.ordernumber = order0_.ordernumber [type=bool, outer=(2,9), constraints=(/2: (/NULL - ]; /9: (/NULL - ]), fd=(2)==(9), (9)==(2)]
 │    └── aggregations
 │         ├── sum [type=decimal, outer=(16)]
 │         │    └── variable: column16 [type=decimal]
 │         ├── const-agg [type=string, outer=(1)]
 │         │    └── variable: order0_.customerid [type=string]
 │         ├── const-agg [type=int, outer=(2)]
 │         │    └── variable: order0_.ordernumber [type=int]
 │         ├── const-agg [type=date, outer=(3)]
 │         │    └── variable: orderdate [type=date]
 │         ├── const-agg [type=string, outer=(4)]
 │         │    └── variable: lineitems1_.customerid [type=string]
 │         ├── const-agg [type=int, outer=(5)]
 │         │    └── variable: lineitems1_.ordernumber [type=int]
 │         └── const-agg [type=int, outer=(7)]
 │              └── variable: lineitems1_.quantity [type=int]
 └── projections
      └── variable: sum [type=decimal, outer=(17)]

opt
SELECT
  customer0_.customerid AS customer1_0_0_,
  orders1_.customerid AS customer1_1_1_,
  orders1_.ordernumber AS ordernum2_1_1_,
  lineitems2_.customerid AS customer1_2_2_,
  lineitems2_.ordernumber AS ordernum2_2_2_,
  lineitems2_.productid AS producti3_2_2_,
  product3_.productid AS producti1_3_3_,
  customer0_.name AS name2_0_0_,
  customer0_.address AS address3_0_0_,
  orders1_.orderdate AS orderdat3_1_1_,
  (
    SELECT
      sum(li.quantity * p.cost)
    FROM
      lineitem AS li, product AS p
    WHERE
      li.productid = p.productid
      AND li.customerid = orders1_.customerid
      AND li.ordernumber = orders1_.ordernumber
  )
    AS formula103_1_,
  orders1_.customerid AS customer1_1_0__,
  orders1_.ordernumber AS ordernum2_1_0__,
  orders1_.ordernumber AS ordernum2_0__,
  lineitems2_.quantity AS quantity4_2_2_,
  lineitems2_.customerid AS customer1_2_1__,
  lineitems2_.ordernumber AS ordernum2_2_1__,
  lineitems2_.productid AS producti3_2_1__,
  product3_.description AS descript2_3_3_,
  product3_.cost AS cost3_3_3_,
  product3_.numberavailable AS numberav4_3_3_,
  (
    SELECT
      sum(li.quantity)
    FROM
      lineitem AS li
    WHERE
      li.productid = product3_.productid
  )
    AS formula104_3_
FROM
  customer AS customer0_
  LEFT JOIN customerorder AS orders1_
  ON customer0_.customerid = orders1_.customerid
  LEFT JOIN lineitem AS lineitems2_
  ON
    orders1_.customerid = lineitems2_.customerid
    AND orders1_.ordernumber = lineitems2_.ordernumber
  LEFT JOIN product AS product3_ ON lineitems2_.productid = product3_.productid;
----
project
 ├── columns: customer1_0_0_:1(string!null) customer1_1_1_:4(string) ordernum2_1_1_:5(int) customer1_2_2_:7(string) ordernum2_2_2_:8(int) producti3_2_2_:9(string) producti1_3_3_:11(string) name2_0_0_:2(string) address3_0_0_:3(string) orderdat3_1_1_:6(date) formula103_1_:30(decimal) customer1_1_0__:4(string) ordernum2_1_0__:5(int) ordernum2_0__:5(int) quantity4_2_2_:10(int) customer1_2_1__:7(string) ordernum2_2_1__:8(int) producti3_2_1__:9(string) descript2_3_3_:12(string) cost3_3_3_:13(decimal) numberav4_3_3_:14(int) formula104_3_:31(decimal)
 ├── key: (1,4,5,7-9,11)
 ├── fd: (1)-->(2,3), (4,5)-->(6), (7-9)-->(10), (11)-->(12-14), (1,4,5,7-9,11)-->(2,3,6,10,12-14,30,31)
 ├── group-by
 │    ├── columns: customer0_.customerid:1(string!null) name:2(string) address:3(string) orders1_.customerid:4(string) orders1_.ordernumber:5(int) orderdate:6(date) lineitems2_.customerid:7(string) lineitems2_.ordernumber:8(int) lineitems2_.productid:9(string) lineitems2_.quantity:10(int) product3_.productid:11(string) product3_.description:12(string) product3_.cost:13(decimal) product3_.numberavailable:14(int) sum:24(decimal) sum:29(decimal)
 │    ├── grouping columns: customer0_.customerid:1(string!null) orders1_.customerid:4(string) orders1_.ordernumber:5(int) lineitems2_.customerid:7(string) lineitems2_.ordernumber:8(int) lineitems2_.productid:9(string) product3_.productid:11(string)
 │    ├── key: (1,4,5,7-9,11)
 │    ├── fd: (1)-->(2,3), (4,5)-->(6), (7-9)-->(10), (11)-->(12-14), (1,4,5,7-9,11)-->(2,3,6,10,12-14,24,29)
 │    ├── left-join
 │    │    ├── columns: customer0_.customerid:1(string!null) name:2(string) address:3(string) orders1_.customerid:4(string) orders1_.ordernumber:5(int) orderdate:6(date) lineitems2_.customerid:7(string) lineitems2_.ordernumber:8(int) lineitems2_.productid:9(string) lineitems2_.quantity:10(int) product3_.productid:11(string) product3_.description:12(string) product3_.cost:13(decimal) product3_.numberavailable:14(int) sum:24(decimal) li.productid:27(string) li.quantity:28(int)
 │    │    ├── fd: (1)-->(2,3), (4,5)-->(6), (7-9)-->(10), (11)-->(12-14), (1,4,5,7-9,11)-->(2,3,6,10,12-14,24)
 │    │    ├── group-by
 │    │    │    ├── columns: customer0_.customerid:1(string!null) name:2(string) address:3(string) orders1_.customerid:4(string) orders1_.ordernumber:5(int) orderdate:6(date) lineitems2_.customerid:7(string) lineitems2_.ordernumber:8(int) lineitems2_.productid:9(string) lineitems2_.quantity:10(int) product3_.productid:11(string) product3_.description:12(string) product3_.cost:13(decimal) product3_.numberavailable:14(int) sum:24(decimal)
 │    │    │    ├── grouping columns: customer0_.customerid:1(string!null) orders1_.customerid:4(string) orders1_.ordernumber:5(int) lineitems2_.customerid:7(string) lineitems2_.ordernumber:8(int) lineitems2_.productid:9(string) product3_.productid:11(string)
 │    │    │    ├── key: (1,4,5,7-9,11)
 │    │    │    ├── fd: (1)-->(2,3), (4,5)-->(6), (7-9)-->(10), (11)-->(12-14), (1,4,5,7-9,11)-->(2,3,6,10,12-14,24)
 │    │    │    ├── left-join
 │    │    │    │    ├── columns: customer0_.customerid:1(string!null) name:2(string!null) address:3(string!null) orders1_.customerid:4(string) orders1_.ordernumber:5(int) orderdate:6(date) lineitems2_.customerid:7(string) lineitems2_.ordernumber:8(int) lineitems2_.productid:9(string) lineitems2_.quantity:10(int) product3_.productid:11(string) product3_.description:12(string) product3_.cost:13(decimal) product3_.numberavailable:14(int) li.customerid:15(string) li.ordernumber:16(int) column23:23(decimal)
 │    │    │    │    ├── fd: (1)-->(2,3), (4,5)-->(6), (7-9)-->(10), (11)-->(12-14)
 │    │    │    │    ├── left-join
 │    │    │    │    │    ├── columns: customer0_.customerid:1(string!null) name:2(string!null) address:3(string!null) orders1_.customerid:4(string) orders1_.ordernumber:5(int) orderdate:6(date) lineitems2_.customerid:7(string) lineitems2_.ordernumber:8(int) lineitems2_.productid:9(string) lineitems2_.quantity:10(int) product3_.productid:11(string) product3_.description:12(string) product3_.cost:13(decimal) product3_.numberavailable:14(int)
 │    │    │    │    │    ├── key: (1,4,5,7-9,11)
 │    │    │    │    │    ├── fd: (1)-->(2,3), (4,5)-->(6), (7-9)-->(10), (11)-->(12-14)
 │    │    │    │    │    ├── left-join
 │    │    │    │    │    │    ├── columns: customer0_.customerid:1(string!null) name:2(string!null) address:3(string!null) orders1_.customerid:4(string) orders1_.ordernumber:5(int) orderdate:6(date) lineitems2_.customerid:7(string) lineitems2_.ordernumber:8(int) lineitems2_.productid:9(string) lineitems2_.quantity:10(int)
 │    │    │    │    │    │    ├── key: (1,4,5,7-9)
 │    │    │    │    │    │    ├── fd: (1)-->(2,3), (4,5)-->(6), (7-9)-->(10)
 │    │    │    │    │    │    ├── left-join (merge)
 │    │    │    │    │    │    │    ├── columns: customer0_.customerid:1(string!null) name:2(string!null) address:3(string!null) orders1_.customerid:4(string) orders1_.ordernumber:5(int) orderdate:6(date)
 │    │    │    │    │    │    │    ├── left ordering: +1
 │    │    │    │    │    │    │    ├── right ordering: +4
 │    │    │    │    │    │    │    ├── key: (1,4,5)
 │    │    │    │    │    │    │    ├── fd: (1)-->(2,3), (4,5)-->(6)
 │    │    │    │    │    │    │    ├── scan customer0_
 │    │    │    │    │    │    │    │    ├── columns: customer0_.customerid:1(string!null) name:2(string!null) address:3(string!null)
 │    │    │    │    │    │    │    │    ├── key: (1)
 │    │    │    │    │    │    │    │    ├── fd: (1)-->(2,3)
 │    │    │    │    │    │    │    │    └── ordering: +1
 │    │    │    │    │    │    │    ├── scan orders1_
 │    │    │    │    │    │    │    │    ├── columns: orders1_.customerid:4(string!null) orders1_.ordernumber:5(int!null) orderdate:6(date!null)
 │    │    │    │    │    │    │    │    ├── key: (4,5)
 │    │    │    │    │    │    │    │    ├── fd: (4,5)-->(6)
 │    │    │    │    │    │    │    │    └── ordering: +4
 │    │    │    │    │    │    │    └── filters (true)
 │    │    │    │    │    │    ├── scan lineitems2_
 │    │    │    │    │    │    │    ├── columns: lineitems2_.customerid:7(string!null) lineitems2_.ordernumber:8(int!null) lineitems2_.productid:9(string!null) lineitems2_.quantity:10(int)
 │    │    │    │    │    │    │    ├── key: (7-9)
 │    │    │    │    │    │    │    └── fd: (7-9)-->(10)
 │    │    │    │    │    │    └── filters
 │    │    │    │    │    │         ├── orders1_.customerid = lineitems2_.customerid [type=bool, outer=(4,7), constraints=(/4: (/NULL - ]; /7: (/NULL - ]), fd=(4)==(7), (7)==(4)]
 │    │    │    │    │    │         └── orders1_.ordernumber = lineitems2_.ordernumber [type=bool, outer=(5,8), constraints=(/5: (/NULL - ]; /8: (/NULL - ]), fd=(5)==(8), (8)==(5)]
 │    │    │    │    │    ├── scan product3_
 │    │    │    │    │    │    ├── columns: product3_.productid:11(string!null) product3_.description:12(string!null) product3_.cost:13(decimal) product3_.numberavailable:14(int)
 │    │    │    │    │    │    ├── key: (11)
 │    │    │    │    │    │    └── fd: (11)-->(12-14)
 │    │    │    │    │    └── filters
 │    │    │    │    │         └── lineitems2_.productid = product3_.productid [type=bool, outer=(9,11), constraints=(/9: (/NULL - ]; /11: (/NULL - ]), fd=(9)==(11), (11)==(9)]
 │    │    │    │    ├── project
 │    │    │    │    │    ├── columns: column23:23(decimal) li.customerid:15(string!null) li.ordernumber:16(int!null)
 │    │    │    │    │    ├── inner-join
 │    │    │    │    │    │    ├── columns: li.customerid:15(string!null) li.ordernumber:16(int!null) li.productid:17(string!null) li.quantity:18(int) p.productid:19(string!null) p.cost:21(decimal)
 │    │    │    │    │    │    ├── key: (15,16,19)
 │    │    │    │    │    │    ├── fd: (15-17)-->(18), (19)-->(21), (17)==(19), (19)==(17)
 │    │    │    │    │    │    ├── scan li
 │    │    │    │    │    │    │    ├── columns: li.customerid:15(string!null) li.ordernumber:16(int!null) li.productid:17(string!null) li.quantity:18(int)
 │    │    │    │    │    │    │    ├── key: (15-17)
 │    │    │    │    │    │    │    └── fd: (15-17)-->(18)
 │    │    │    │    │    │    ├── scan p
 │    │    │    │    │    │    │    ├── columns: p.productid:19(string!null) p.cost:21(decimal)
 │    │    │    │    │    │    │    ├── key: (19)
 │    │    │    │    │    │    │    └── fd: (19)-->(21)
 │    │    │    │    │    │    └── filters
 │    │    │    │    │    │         └── li.productid = p.productid [type=bool, outer=(17,19), constraints=(/17: (/NULL - ]; /19: (/NULL - ]), fd=(17)==(19), (19)==(17)]
 │    │    │    │    │    └── projections
 │    │    │    │    │         └── li.quantity * p.cost [type=decimal, outer=(18,21)]
 │    │    │    │    └── filters
 │    │    │    │         ├── li.customerid = orders1_.customerid [type=bool, outer=(4,15), constraints=(/4: (/NULL - ]; /15: (/NULL - ]), fd=(4)==(15), (15)==(4)]
 │    │    │    │         └── li.ordernumber = orders1_.ordernumber [type=bool, outer=(5,16), constraints=(/5: (/NULL - ]; /16: (/NULL - ]), fd=(5)==(16), (16)==(5)]
 │    │    │    └── aggregations
 │    │    │         ├── sum [type=decimal, outer=(23)]
 │    │    │         │    └── variable: column23 [type=decimal]
 │    │    │         ├── const-agg [type=string, outer=(2)]
 │    │    │         │    └── variable: name [type=string]
 │    │    │         ├── const-agg [type=string, outer=(3)]
 │    │    │         │    └── variable: address [type=string]
 │    │    │         ├── const-agg [type=date, outer=(6)]
 │    │    │         │    └── variable: orderdate [type=date]
 │    │    │         ├── const-agg [type=int, outer=(10)]
 │    │    │         │    └── variable: lineitems2_.quantity [type=int]
 │    │    │         ├── const-agg [type=string, outer=(12)]
 │    │    │         │    └── variable: product3_.description [type=string]
 │    │    │         ├── const-agg [type=decimal, outer=(13)]
 │    │    │         │    └── variable: product3_.cost [type=decimal]
 │    │    │         └── const-agg [type=int, outer=(14)]
 │    │    │              └── variable: product3_.numberavailable [type=int]
 │    │    ├── scan li
 │    │    │    └── columns: li.productid:27(string!null) li.quantity:28(int)
 │    │    └── filters
 │    │         └── li.productid = product3_.productid [type=bool, outer=(11,27), constraints=(/11: (/NULL - ]; /27: (/NULL - ]), fd=(11)==(27), (27)==(11)]
 │    └── aggregations
 │         ├── sum [type=decimal, outer=(28)]
 │         │    └── variable: li.quantity [type=int]
 │         ├── const-agg [type=string, outer=(2)]
 │         │    └── variable: name [type=string]
 │         ├── const-agg [type=string, outer=(3)]
 │         │    └── variable: address [type=string]
 │         ├── const-agg [type=date, outer=(6)]
 │         │    └── variable: orderdate [type=date]
 │         ├── const-agg [type=int, outer=(10)]
 │         │    └── variable: lineitems2_.quantity [type=int]
 │         ├── const-agg [type=string, outer=(12)]
 │         │    └── variable: product3_.description [type=string]
 │         ├── const-agg [type=decimal, outer=(13)]
 │         │    └── variable: product3_.cost [type=decimal]
 │         ├── const-agg [type=int, outer=(14)]
 │         │    └── variable: product3_.numberavailable [type=int]
 │         └── const-agg [type=decimal, outer=(24)]
 │              └── variable: sum [type=decimal]
 └── projections
      ├── variable: sum [type=decimal, outer=(24)]
      └── variable: sum [type=decimal, outer=(29)]

opt
SELECT
  order0_.customerid AS customer1_1_0_,
  order0_.ordernumber AS ordernum2_1_0_,
  order0_.orderdate AS orderdat3_1_0_,
  (
    SELECT
      sum(li.quantity * p.cost)
    FROM
      lineitem AS li, product AS p
    WHERE
      li.productid = p.productid
      AND li.customerid = order0_.customerid
      AND li.ordernumber = order0_.ordernumber
  )
    AS formula105_0_,
  lineitems1_.customerid AS customer1_2_1_,
  lineitems1_.ordernumber AS ordernum2_2_1_,
  lineitems1_.productid AS producti3_2_1_,
  lineitems1_.customerid AS customer1_2_2_,
  lineitems1_.ordernumber AS ordernum2_2_2_,
  lineitems1_.productid AS producti3_2_2_,
  lineitems1_.quantity AS quantity4_2_2_
FROM
  customerorder AS order0_
  LEFT JOIN lineitem AS lineitems1_
  ON
    order0_.customerid = lineitems1_.customerid
    AND order0_.ordernumber = lineitems1_.ordernumber
WHERE
  order0_.customerid = 'c111' AND order0_.ordernumber = 0;
----
project
 ├── columns: customer1_1_0_:1(string) ordernum2_1_0_:2(int) orderdat3_1_0_:3(date) formula105_0_:18(decimal) customer1_2_1_:4(string) ordernum2_2_1_:5(int) producti3_2_1_:6(string) customer1_2_2_:4(string) ordernum2_2_2_:5(int) producti3_2_2_:6(string) quantity4_2_2_:7(int)
 ├── key: (6)
 ├── fd: ()-->(1-3), (6)-->(4,5,7,18), ()~~>(4,5)
 ├── group-by
 │    ├── columns: order0_.customerid:1(string) order0_.ordernumber:2(int) orderdate:3(date) lineitems1_.customerid:4(string) lineitems1_.ordernumber:5(int) lineitems1_.productid:6(string) lineitems1_.quantity:7(int) sum:17(decimal)
 │    ├── grouping columns: lineitems1_.productid:6(string)
 │    ├── key: (6)
 │    ├── fd: ()-->(1-3), (6)-->(1-5,7,17), ()~~>(4,5)
 │    ├── right-join
 │    │    ├── columns: order0_.customerid:1(string!null) order0_.ordernumber:2(int!null) orderdate:3(date!null) lineitems1_.customerid:4(string) lineitems1_.ordernumber:5(int) lineitems1_.productid:6(string) lineitems1_.quantity:7(int) li.customerid:8(string) li.ordernumber:9(int) column16:16(decimal)
 │    │    ├── fd: ()-->(1-3), (6)-->(4,5,7), ()~~>(4,5)
 │    │    ├── project
 │    │    │    ├── columns: column16:16(decimal) li.customerid:8(string!null) li.ordernumber:9(int!null)
 │    │    │    ├── inner-join
 │    │    │    │    ├── columns: li.customerid:8(string!null) li.ordernumber:9(int!null) li.productid:10(string!null) li.quantity:11(int) p.productid:12(string!null) cost:14(decimal)
 │    │    │    │    ├── key: (8,9,12)
 │    │    │    │    ├── fd: (8-10)-->(11), (12)-->(14), (10)==(12), (12)==(10)
 │    │    │    │    ├── scan li
 │    │    │    │    │    ├── columns: li.customerid:8(string!null) li.ordernumber:9(int!null) li.productid:10(string!null) li.quantity:11(int)
 │    │    │    │    │    ├── key: (8-10)
 │    │    │    │    │    └── fd: (8-10)-->(11)
 │    │    │    │    ├── scan p
 │    │    │    │    │    ├── columns: p.productid:12(string!null) cost:14(decimal)
 │    │    │    │    │    ├── key: (12)
 │    │    │    │    │    └── fd: (12)-->(14)
 │    │    │    │    └── filters
 │    │    │    │         └── li.productid = p.productid [type=bool, outer=(10,12), constraints=(/10: (/NULL - ]; /12: (/NULL - ]), fd=(10)==(12), (12)==(10)]
 │    │    │    └── projections
 │    │    │         └── li.quantity * cost [type=decimal, outer=(11,14)]
 │    │    ├── left-join (merge)
 │    │    │    ├── columns: order0_.customerid:1(string!null) order0_.ordernumber:2(int!null) orderdate:3(date!null) lineitems1_.customerid:4(string) lineitems1_.ordernumber:5(int) lineitems1_.productid:6(string) lineitems1_.quantity:7(int)
 │    │    │    ├── left ordering: +1,+2
 │    │    │    ├── right ordering: +4,+5
 │    │    │    ├── key: (6)
 │    │    │    ├── fd: ()-->(1-3), (6)-->(4,5,7), ()~~>(4,5)
 │    │    │    ├── scan order0_
 │    │    │    │    ├── columns: order0_.customerid:1(string!null) order0_.ordernumber:2(int!null) orderdate:3(date!null)
 │    │    │    │    ├── constraint: /1/2: [/'c111'/0 - /'c111'/0]
 │    │    │    │    ├── cardinality: [0 - 1]
 │    │    │    │    ├── key: ()
 │    │    │    │    └── fd: ()-->(1-3)
 │    │    │    ├── scan lineitems1_
 │    │    │    │    ├── columns: lineitems1_.customerid:4(string!null) lineitems1_.ordernumber:5(int!null) lineitems1_.productid:6(string!null) lineitems1_.quantity:7(int)
 │    │    │    │    ├── constraint: /4/5/6: [/'c111'/0 - /'c111'/0]
 │    │    │    │    ├── key: (6)
 │    │    │    │    └── fd: ()-->(4,5), (6)-->(7)
 │    │    │    └── filters (true)
 │    │    └── filters
 │    │         ├── li.customerid = order0_.customerid [type=bool, outer=(1,8), constraints=(/1: (/NULL - ]; /8: (/NULL - ]), fd=(1)==(8), (8)==(1)]
 │    │         └── li.ordernumber = order0_.ordernumber [type=bool, outer=(2,9), constraints=(/2: (/NULL - ]; /9: (/NULL - ]), fd=(2)==(9), (9)==(2)]
 │    └── aggregations
 │         ├── sum [type=decimal, outer=(16)]
 │         │    └── variable: column16 [type=decimal]
 │         ├── const-agg [type=string, outer=(1)]
 │         │    └── variable: order0_.customerid [type=string]
 │         ├── const-agg [type=int, outer=(2)]
 │         │    └── variable: order0_.ordernumber [type=int]
 │         ├── const-agg [type=date, outer=(3)]
 │         │    └── variable: orderdate [type=date]
 │         ├── const-agg [type=string, outer=(4)]
 │         │    └── variable: lineitems1_.customerid [type=string]
 │         ├── const-agg [type=int, outer=(5)]
 │         │    └── variable: lineitems1_.ordernumber [type=int]
 │         └── const-agg [type=int, outer=(7)]
 │              └── variable: lineitems1_.quantity [type=int]
 └── projections
      └── variable: sum [type=decimal, outer=(17)]

opt
SELECT
  order0_.customerid AS customer1_10_,
  order0_.ordernumber AS ordernum2_10_,
  order0_.orderdate AS orderdat3_10_,
  (
    SELECT
      sum(li.quantity * p.cost)
    FROM
      lineitem AS li, product AS p
    WHERE
      li.productid = p.productid
      AND li.customerid = order0_.customerid
      AND li.ordernumber = order0_.ordernumber
  )
    AS formula273_
FROM
  customerorder AS order0_;
----
project
 ├── columns: customer1_10_:1(string!null) ordernum2_10_:2(int!null) orderdat3_10_:3(date) formula273_:14(decimal)
 ├── key: (1,2)
 ├── fd: (1,2)-->(3,14)
 ├── group-by
 │    ├── columns: order0_.customerid:1(string!null) order0_.ordernumber:2(int!null) orderdate:3(date) sum:13(decimal)
 │    ├── grouping columns: order0_.customerid:1(string!null) order0_.ordernumber:2(int!null)
 │    ├── key: (1,2)
 │    ├── fd: (1,2)-->(3,13)
 │    ├── left-join
 │    │    ├── columns: order0_.customerid:1(string!null) order0_.ordernumber:2(int!null) orderdate:3(date!null) li.customerid:4(string) li.ordernumber:5(int) column12:12(decimal)
 │    │    ├── fd: (1,2)-->(3)
 │    │    ├── scan order0_
 │    │    │    ├── columns: order0_.customerid:1(string!null) order0_.ordernumber:2(int!null) orderdate:3(date!null)
 │    │    │    ├── key: (1,2)
 │    │    │    └── fd: (1,2)-->(3)
 │    │    ├── project
 │    │    │    ├── columns: column12:12(decimal) li.customerid:4(string!null) li.ordernumber:5(int!null)
 │    │    │    ├── inner-join
 │    │    │    │    ├── columns: li.customerid:4(string!null) li.ordernumber:5(int!null) li.productid:6(string!null) quantity:7(int) p.productid:8(string!null) cost:10(decimal)
 │    │    │    │    ├── key: (4,5,8)
 │    │    │    │    ├── fd: (4-6)-->(7), (8)-->(10), (6)==(8), (8)==(6)
 │    │    │    │    ├── scan li
 │    │    │    │    │    ├── columns: li.customerid:4(string!null) li.ordernumber:5(int!null) li.productid:6(string!null) quantity:7(int)
 │    │    │    │    │    ├── key: (4-6)
 │    │    │    │    │    └── fd: (4-6)-->(7)
 │    │    │    │    ├── scan p
 │    │    │    │    │    ├── columns: p.productid:8(string!null) cost:10(decimal)
 │    │    │    │    │    ├── key: (8)
 │    │    │    │    │    └── fd: (8)-->(10)
 │    │    │    │    └── filters
 │    │    │    │         └── li.productid = p.productid [type=bool, outer=(6,8), constraints=(/6: (/NULL - ]; /8: (/NULL - ]), fd=(6)==(8), (8)==(6)]
 │    │    │    └── projections
 │    │    │         └── quantity * cost [type=decimal, outer=(7,10)]
 │    │    └── filters
 │    │         ├── li.customerid = order0_.customerid [type=bool, outer=(1,4), constraints=(/1: (/NULL - ]; /4: (/NULL - ]), fd=(1)==(4), (4)==(1)]
 │    │         └── li.ordernumber = order0_.ordernumber [type=bool, outer=(2,5), constraints=(/2: (/NULL - ]; /5: (/NULL - ]), fd=(2)==(5), (5)==(2)]
 │    └── aggregations
 │         ├── sum [type=decimal, outer=(12)]
 │         │    └── variable: column12 [type=decimal]
 │         └── const-agg [type=date, outer=(3)]
 │              └── variable: orderdate [type=date]
 └── projections
      └── variable: sum [type=decimal, outer=(13)]

exec-ddl
drop table customer, customerorder, lineitem, product
----

# ------------------------------------------------------------------------------
# Query #12
#   org.hibernate.test.criteria.CriteriaQueryTest
# ------------------------------------------------------------------------------
exec-ddl
CREATE TABLE student (
  studentid INT8 NOT NULL,
  name VARCHAR(255) NOT NULL,
  address_city VARCHAR(255),
  address_state VARCHAR(255),
  preferredcoursecode VARCHAR(255),
  PRIMARY KEY (studentid)
);
----
TABLE student
 ├── studentid int not null
 ├── name string not null
 ├── address_city string
 ├── address_state string
 ├── preferredcoursecode string
 └── INDEX primary
      └── studentid int not null

exec-ddl
CREATE TABLE enrolment (
  studentid INT8 NOT NULL,
  coursecode VARCHAR(255) NOT NULL,
  semester INT2 NOT NULL,
  year INT2 NOT NULL,
  PRIMARY KEY (studentid, coursecode)
);
----
TABLE enrolment
 ├── studentid int not null
 ├── coursecode string not null
 ├── semester int not null
 ├── year int not null
 └── INDEX primary
      ├── studentid int not null
      └── coursecode string not null

opt
SELECT
  this_.studentid AS studenti1_26_0_,
  this_.name AS name2_26_0_,
  this_.address_city AS address_3_26_0_,
  this_.address_state AS address_4_26_0_,
  this_.preferredcoursecode AS preferre5_26_0_
FROM
  student AS this_
WHERE
  EXISTS(
    SELECT
      enrolment_.studentid AS y0_
    FROM
      enrolment AS enrolment_
    WHERE
      enrolment_.year
      = (
          SELECT
            max(maxstudentenrolment_.year) AS y0_
          FROM
            enrolment AS maxstudentenrolment_
          WHERE
            this_.preferredcoursecode = maxstudentenrolment_.coursecode
        )
  );
----
group-by
 ├── columns: studenti1_26_0_:1(int!null) name2_26_0_:2(string) address_3_26_0_:3(string) address_4_26_0_:4(string) preferre5_26_0_:5(string)
 ├── grouping columns: this_.studentid:1(int!null)
 ├── key: (1)
 ├── fd: (1)-->(2-5)
 ├── select
 │    ├── columns: this_.studentid:1(int!null) name:2(string) address_city:3(string) address_state:4(string) preferredcoursecode:5(string) enrolment_.studentid:6(int!null) enrolment_.coursecode:7(string!null) enrolment_.year:9(int!null) max:14(int!null)
 │    ├── key: (1,6,7)
 │    ├── fd: (1)-->(2-5), (6,7)-->(9), (1,6,7)-->(2-5,9,14), (9)==(14), (14)==(9)
 │    ├── group-by
 │    │    ├── columns: this_.studentid:1(int!null) name:2(string) address_city:3(string) address_state:4(string) preferredcoursecode:5(string) enrolment_.studentid:6(int!null) enrolment_.coursecode:7(string!null) enrolment_.year:9(int) max:14(int)
 │    │    ├── grouping columns: this_.studentid:1(int!null) enrolment_.studentid:6(int!null) enrolment_.coursecode:7(string!null)
 │    │    ├── key: (1,6,7)
 │    │    ├── fd: (1)-->(2-5), (6,7)-->(9), (1,6,7)-->(2-5,9,14)
 │    │    ├── inner-join
 │    │    │    ├── columns: this_.studentid:1(int!null) name:2(string!null) address_city:3(string) address_state:4(string) preferredcoursecode:5(string!null) enrolment_.studentid:6(int!null) enrolment_.coursecode:7(string!null) enrolment_.year:9(int!null) maxstudentenrolment_.coursecode:11(string!null) maxstudentenrolment_.year:13(int!null)
 │    │    │    ├── fd: (1)-->(2-5), (6,7)-->(9), (5)==(11), (11)==(5)
 │    │    │    ├── inner-join
 │    │    │    │    ├── columns: this_.studentid:1(int!null) name:2(string!null) address_city:3(string) address_state:4(string) preferredcoursecode:5(string!null) maxstudentenrolment_.coursecode:11(string!null) maxstudentenrolment_.year:13(int!null)
 │    │    │    │    ├── fd: (1)-->(2-5), (5)==(11), (11)==(5)
 │    │    │    │    ├── scan maxstudentenrolment_
 │    │    │    │    │    └── columns: maxstudentenrolment_.coursecode:11(string!null) maxstudentenrolment_.year:13(int!null)
 │    │    │    │    ├── scan this_
 │    │    │    │    │    ├── columns: this_.studentid:1(int!null) name:2(string!null) address_city:3(string) address_state:4(string) preferredcoursecode:5(string)
 │    │    │    │    │    ├── key: (1)
 │    │    │    │    │    └── fd: (1)-->(2-5)
 │    │    │    │    └── filters
 │    │    │    │         └── preferredcoursecode = maxstudentenrolment_.coursecode [type=bool, outer=(5,11), constraints=(/5: (/NULL - ]; /11: (/NULL - ]), fd=(5)==(11), (11)==(5)]
 │    │    │    ├── scan enrolment_
 │    │    │    │    ├── columns: enrolment_.studentid:6(int!null) enrolment_.coursecode:7(string!null) enrolment_.year:9(int!null)
 │    │    │    │    ├── key: (6,7)
 │    │    │    │    └── fd: (6,7)-->(9)
 │    │    │    └── filters (true)
 │    │    └── aggregations
 │    │         ├── max [type=int, outer=(13)]
 │    │         │    └── variable: maxstudentenrolment_.year [type=int]
 │    │         ├── const-agg [type=int, outer=(9)]
 │    │         │    └── variable: enrolment_.year [type=int]
 │    │         ├── const-agg [type=string, outer=(2)]
 │    │         │    └── variable: name [type=string]
 │    │         ├── const-agg [type=string, outer=(3)]
 │    │         │    └── variable: address_city [type=string]
 │    │         ├── const-agg [type=string, outer=(4)]
 │    │         │    └── variable: address_state [type=string]
 │    │         └── const-agg [type=string, outer=(5)]
 │    │              └── variable: preferredcoursecode [type=string]
 │    └── filters
 │         └── enrolment_.year = max [type=bool, outer=(9,14), constraints=(/9: (/NULL - ]; /14: (/NULL - ]), fd=(9)==(14), (14)==(9)]
 └── aggregations
      ├── const-agg [type=string, outer=(2)]
      │    └── variable: name [type=string]
      ├── const-agg [type=string, outer=(3)]
      │    └── variable: address_city [type=string]
      ├── const-agg [type=string, outer=(4)]
      │    └── variable: address_state [type=string]
      └── const-agg [type=string, outer=(5)]
           └── variable: preferredcoursecode [type=string]

exec-ddl
drop table student, enrolment
----

# ------------------------------------------------------------------------------
# Query #13
#   org.hibernate.test.subselectfetch.SubselectFetchWithFormulaTest
#   TODO(andyk): Need to decorrelate LeftJoin -> Project complex.
# ------------------------------------------------------------------------------
exec-ddl
CREATE TABLE t_name (id INT4 NOT NULL, c_name VARCHAR(255), PRIMARY KEY (id));
----
TABLE t_name
 ├── id int not null
 ├── c_name string
 └── INDEX primary
      └── id int not null

opt
SELECT
  this_.id AS id1_0_0_,
  this_.c_name AS c_name2_0_0_,
  (SELECT length(this_.c_name) FROM t_name WHERE this_.id = t_name.id)
    AS formula0_0_
FROM
  t_name AS this_;
----
project
 ├── columns: id1_0_0_:1(int!null) c_name2_0_0_:2(string) formula0_0_:6(int)
 ├── key: (1)
 ├── fd: (1)-->(2), (2)-->(6)
 ├── inner-join (merge)
 │    ├── columns: this_.id:1(int!null) this_.c_name:2(string) t_name.id:3(int!null)
 │    ├── left ordering: +1
 │    ├── right ordering: +3
 │    ├── key: (3)
 │    ├── fd: (1)-->(2), (1)==(3), (3)==(1)
 │    ├── scan this_
 │    │    ├── columns: this_.id:1(int!null) this_.c_name:2(string)
 │    │    ├── key: (1)
 │    │    ├── fd: (1)-->(2)
 │    │    └── ordering: +1
 │    ├── scan t_name
 │    │    ├── columns: t_name.id:3(int!null)
 │    │    ├── key: (3)
 │    │    └── ordering: +3
 │    └── filters (true)
 └── projections
      └── length(this_.c_name) [type=int, outer=(2)]

exec-ddl
drop table t_name
----
