/*
 * 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 tpch if exists;
create  database tpch;

use tpch;


create type tpch.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 tpch.LineIDType as
 closed {
  l_orderkey : int32,
  l_partkey : int32,
  l_suppkey : int32
}

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

create  table LineID(LineIDType) primary key l_orderkey on group1;

create  index idx_LineID_partkey  on LineID (l_partkey) type btree;

create  index idx_LineID_suppkey  on LineID (l_suppkey) type btree;

insert into LineID
select element {'l_orderkey':l.l_orderkey,'l_partkey':l.l_partkey,'l_suppkey':l.l_partkey}
from  LineItems_q1 as l
;
