/*
 * 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 from issue786
 * https://code.google.com/p/asterixdb/issues/detail?id=786
 * Expected Res : SUCCESS
 * Date         : 10th Oct. 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  collection Orders(OrderType) primary key o_orderkey;

create  collection Supplier(SupplierType) primary key s_suppkey;

create  collection Region(RegionType) primary key r_regionkey;

create  collection Nation(NationType) primary key n_nationkey;

create  collection Customer(CustomerType) primary key c_custkey;

create  collection SelectedNation(NationType) primary key n_nationkey;

