/*
 * 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  dataverse q08_group_by if exists;
create  dataverse q08_group_by;

use q08_group_by;


create type q08_group_by.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 q08_group_by.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 q08_group_by.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 q08_group_by.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 q08_group_by.NationType as
 closed {
  n_nationkey : int32,
  n_name : string,
  n_regionkey : int32,
  n_comment : string
}

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

create type q08_group_by.PartType as
 closed {
  p_partkey : int32,
  p_name : string,
  p_mfgr : string,
  p_brand : string,
  p_type : string,
  p_size : int32,
  p_container : string,
  p_retailprice : double,
  p_comment : string
}

create  dataset LineItem(LineItemType) primary key l_orderkey,l_linenumber;

create  dataset Orders(OrderType) primary key o_orderkey;

create  dataset Customer(CustomerType) primary key c_custkey;

create  dataset Supplier(SupplierType) primary key s_suppkey;

create  dataset Nation(NationType) primary key n_nationkey;

create  dataset Region(RegionType) primary key r_regionkey;

create  dataset Part(PartType) primary key p_partkey;

select element {'o_orderdate':lnrcop.o_orderdate,'l_discount':lnrcop.l_discount,'l_extendedprice':lnrcop.l_extendedprice,'l_suppkey':lnrcop.l_suppkey,'s_nationkey':s.s_nationkey}
from  Supplier as s,
      (
    select element {'o_orderdate':lnrco.o_orderdate,'l_discount':lnrco.l_discount,'l_extendedprice':lnrco.l_extendedprice,'l_suppkey':lnrco.l_suppkey}
    from  (
        select element {'o_orderdate':nrco.o_orderdate,'l_partkey':l.l_partkey,'l_discount':l.l_discount,'l_extendedprice':l.l_extendedprice,'l_suppkey':l.l_suppkey}
        from  LineItem as l,
              (
            select element {'o_orderdate':o.o_orderdate,'o_orderkey':o.o_orderkey}
            from  Orders as o,
                  (
                select element {'c_custkey':c.c_custkey}
                from  Customer as c,
                      (
                    select element {'n_nationkey':n1.n_nationkey}
                    from  Nation as n1,
                          Region as r1
                    where ((n1.n_regionkey = r1.r_regionkey) and (r1.r_name = 'AMERICA'))
                ) as nr
                where (c.c_nationkey = nr.n_nationkey)
            ) as nrc
            where (nrc.c_custkey = o.o_custkey)
        ) as nrco
        where ((l.l_orderkey = nrco.o_orderkey) and (nrco.o_orderdate >= '1995-01-01') and (nrco.o_orderdate <= '1996-12-31'))
    ) as lnrco,
          Part as p
    where ((p.p_partkey = lnrco.l_partkey) and (p.p_type = 'ECONOMY ANODIZED STEEL'))
) as lnrcop
where (s.s_suppkey = lnrcop.l_suppkey)
;
