/*
 * 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     : Drop empty secondary index.
 * Expected Result : Success
 * Date            : 8th Feb 2013
 *
 */

drop  dataverse test if exists;
create  dataverse test;

use test;


create type test.Name as
{
  first : string,
  last : string
}

create type test.Person as
{
  name : Name
}

create type test.TestType as
{
  id : int32,
  name : string,
  locn : point,
  zip : string,
  person : Person
}

create  dataset t1(TestType) primary key id;

create  index rtree_index_point  on t1 (locn) type rtree;

create  index rtree_index_point_open  on t1 (open_locn:point) type rtree enforced;

create  index keyWD_indx  on t1 (name) type keyword;

create  index keyWD_indx_open  on t1 (nickname:string) type keyword enforced;

create  index secndIndx  on t1 (zip) type btree;

create  index nested  on t1 (person.name.first) type btree;

create  index secndIndx_open  on t1 (address:string) type btree enforced;

drop index t1.rtree_index_point;
drop index t1.rtree_index_point_open;
drop index t1.keyWD_indx;
drop index t1.keyWD_indx_open;
drop index t1.secndIndx;
drop index t1.nested;
drop index t1.secndIndx_open;
