/*
 * 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.
 */
use dataverse demo1112;

declare type CustomerType as open {
  cid: int32, 
  name: string,
  age: int32?,
  address: AddressType?,
  lastorder: {
    oid: int32,
    total: float
  }
}

declare type AddressType as open {
  number: int32, 
  street: string,
  city: string
}


declare type OrderType as open {
  oid: int32,
  cid: int32,
  orderstatus: string,
  orderpriority: string,
  clerk: string,
  total: float
}

declare nodegroup group1 on asterix_nc1, asterix_nc2;

declare dataset Customers(CustomerType) 
  primary key cid on group1;
declare dataset Orders(OrderType)
  primary key oid on group1;

write output to asterix_nc1:"/tmp/split01.adm";

let $os := for $o in dataset('Orders') return $o
for $o1 in $os
for $o2 in $os
where $o1.cid = $o2.cid
return { "o1": $o1.oid, "o2": $o2.oid, "cid": $o1.cid }
