/*
 * 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.
 */
/*
 * Description  : This test case is to verify the fix for issue782
 * https://code.google.com/p/asterixdb/issues/detail?id=782
 * Expected Res : SUCCESS
 * Date         : 2nd Jun 2014
 */

drop  dataverse tpch if exists;
create  dataverse tpch;

use tpch;


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

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

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

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;

create  dataset SelectedNation(NationType) primary key n_nationkey;

select element {'nation_key':nation.n_nationkey,'name':nation.n_name,'aggregates':(
        select element {'order_date':orderdate,'sum_price':sum}
        from  Orders as orders,
              Customer as customer
        where ((orders.o_custkey = customer.c_custkey) and (customer.c_nationkey = nation.n_nationkey))
        group by orders.o_orderdate as orderdate
        with  sum as tpch.coll_sum((
              select element o.o_totalprice
              from  orders as o
          ))
        order by sum
        limit 3
    )}
from  Nation as nation,
      SelectedNation as sn
where (nation.n_nationkey = sn.n_nationkey)
;
