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

drop  database q5_local_supplier if exists;
create  database q5_local_supplier;

use q5_local_supplier;


create type q5_local_supplier.LineItemType as
 closed {
  l_orderkey : int32,
  l_partkey : int32,
  l_suppkey : int32,
  l_linenumber : int32,
  l_quantity : double,
  l_extendedprice : double,
  l_discount : double,
  l_tax : double,
  l_returnflag : string,
  l_linestatus : string,
  l_shipdate : string,
  l_commitdate : string,
  l_receiptdate : string,
  l_shipinstruct : string,
  l_shipmode : string,
  l_comment : string
}

create type q5_local_supplier.OrderType as
 closed {
  o_orderkey : int32,
  o_custkey : int32,
  o_orderstatus : string,
  o_totalprice : double,
  o_orderdate : string,
  o_orderpriority : string,
  o_clerk : string,
  o_shippriority : int32,
  o_comment : string
}

create type q5_local_supplier.CustomerType as
 closed {
  c_custkey : int32,
  c_name : string,
  c_address : string,
  c_nationkey : int32,
  c_phone : string,
  c_acctbal : double,
  c_mktsegment : string,
  c_comment : string
}

create type q5_local_supplier.SupplierType as
 closed {
  s_suppkey : int32,
  s_name : string,
  s_address : string,
  s_nationkey : int32,
  s_phone : string,
  s_acctbal : double,
  s_comment : string
}

create type q5_local_supplier.NationType as
 closed {
  n_nationkey : int32,
  n_name : string,
  n_regionkey : int32,
  n_comment : string
}

create type q5_local_supplier.RegionType as
 closed {
  r_regionkey : int32,
  r_name : string,
  r_comment : string
}

create  nodegroup group1 if not exists  on
    asterix_nc1,
    asterix_nc2
;
create  table LineItems(LineItemType) primary key l_orderkey,l_linenumber on group1;

create  table Orders(OrderType) primary key o_orderkey on group1;

create  table Customers(CustomerType) primary key c_custkey on group1;

create  table Suppliers(SupplierType) primary key s_suppkey on group1;

create  table Nations(NationType) primary key n_nationkey on group1;

create  table Regions(RegionType) primary key r_regionkey on group1;

write output to asterix_nc1:"/tmp/q5_local_supplier.adm"
select element {'n_name':n_name,'revenue':revenue}
from  Customers as c,
      (
    select element {'n_name':l1.n_name,'l_extendedprice':l1.l_extendedprice,'l_discount':l1.l_discount,'s_nationkey':l1.s_nationkey,'o_custkey':o.o_custkey}
    from  Orders as o,
          (
        select element {'n_name':s1.n_name,'l_extendedprice':l.l_extendedprice,'l_discount':l.l_discount,'l_orderkey':l.l_orderkey,'s_nationkey':s1.s_nationkey}
        from  LineItems as l,
              (
            select element {'n_name':n1.n_name,'s_suppkey':s.s_suppkey,'s_nationkey':s.s_nationkey}
            from  Suppliers as s,
                  (
                select element {'n_name':n.n_name,'n_nationkey':n.n_nationkey}
                from  Nations as n,
                      Regions as r
                where ((n.n_regionkey = r.r_regionkey) and (r.r_name = 'ASIA'))
            ) as n1
            where (s.s_nationkey = n1.n_nationkey)
        ) as s1
        where (l.l_suppkey = s1.s_suppkey)
    ) as l1
    where ((l1.l_orderkey = o.o_orderkey) and (o.o_orderdate >= '1994-01-01') and (o.o_orderdate < '1995-01-01'))
) as o1
where ((c.c_nationkey = o1.s_nationkey) and (c.c_custkey = o1.o_custkey))
/* +hash */
group by o1.n_name as n_name
with  revenue as q5_local_supplier.coll_sum((
      select element (i.l_extendedprice * (1 - i.l_discount))
      from  o1 as i
  ))
order by revenue desc
;
