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

use q09_group_by;


create type q09_group_by.LineItemType as
 closed {
  l_orderkey : int32,
  l_partkey : int32,
  l_suppkey : int32,
  l_linenumber : int32,
  l_quantity : int32,
  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 q09_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 q09_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 q09_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 q09_group_by.NationType as
 closed {
  n_nationkey : int32,
  n_name : string,
  n_regionkey : int32,
  n_comment : string
}

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

create type q09_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 type q09_group_by.PartSuppType as
 closed {
  ps_partkey : int32,
  ps_suppkey : int32,
  ps_availqty : int32,
  ps_supplycost : double,
  ps_comment : string
}

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

create  dataset Orders(OrderType) primary key o_orderkey;

create  dataset Supplier(SupplierType) primary key s_suppkey;

create  dataset Region(RegionType) primary key r_regionkey;

create  dataset Nation(NationType) primary key n_nationkey;

create  dataset Part(PartType) primary key p_partkey;

create  dataset Partsupp(PartSuppType) primary key ps_partkey,ps_suppkey;

create  dataset Customer(CustomerType) primary key c_custkey;

select element {'l_extendedprice':l2.l_extendedprice,'l_discount':l2.l_discount,'l_quantity':l2.l_quantity,'l_orderkey':l2.l_orderkey,'n_name':l2.n_name,'ps_supplycost':l2.ps_supplycost}
from  Part as p,
      (
    select element {'l_extendedprice':l1.l_extendedprice,'l_discount':l1.l_discount,'l_quantity':l1.l_quantity,'l_partkey':l1.l_partkey,'l_orderkey':l1.l_orderkey,'n_name':l1.n_name,'ps_supplycost':ps.ps_supplycost}
    from  Partsupp as ps,
          (
        select element {'l_suppkey':l.l_suppkey,'l_extendedprice':l.l_extendedprice,'l_discount':l.l_discount,'l_quantity':l.l_quantity,'l_partkey':l.l_partkey,'l_orderkey':l.l_orderkey,'n_name':s1.n_name}
        from  (
            select element {'s_suppkey':s.s_suppkey,'n_name':n.n_name}
            from  Supplier as s,
                  Nation as n
            where (n.n_nationkey = s.s_nationkey)
        ) as s1,
              LineItem as l
        where (s1.s_suppkey = l.l_suppkey)
    ) as l1
    where ((ps.ps_suppkey = l1.l_suppkey) and (ps.ps_partkey = l1.l_partkey))
) as l2
where (q09_group_by.contains(p.p_name,'green') and (p.p_partkey = l2.l_partkey))
;
