/*
 * 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  : Testing get-record-fields under different queries.
* Expected Res : Success
* Date         : 04 Jun 2015
*/

use TinySocial;


load  dataset FacebookUsers using localfs ((`path`=`asterix_nc1://data/tinysocial/fbu.adm`),(`format`=`adm`));

load  dataset FacebookMessages using localfs ((`path`=`asterix_nc1://data/tinysocial/fbm.adm`),(`format`=`adm`));

load  dataset TwitterUsers using localfs ((`path`=`asterix_nc1://data/tinysocial/twu.adm`),(`format`=`adm`));

load  dataset TweetMessages using localfs ((`path`=`asterix_nc1://data/tinysocial/twm.adm`),(`format`=`adm`));

insert into TwitterUsersAlternate
select element {'screen-name':r.`screen-name`,'lang':r.lang,'friends_count':r.friends_count,'statuses_count':r.statuses_count}
from  TwitterUsers as r
;
insert into TweetMessagesAlternate
select element {'tweetid':r.tweetid,'sender-location':r.`sender-location`,'send-time':r.`send-time`,'message-text':r.`message-text`,'referred-topics':r.`referred-topics`}
from  TweetMessages as r
;
insert into FacebookUsersAlternate
select element {'id':r.id,'alias':r.alias,'name':r.name,'friend-ids':r.`friend-ids`,'user-since':r.`user-since`}
from  FacebookUsers as r
;
insert into FacebookMessagesAlternate
select element {'message-id':r.`message-id`,'author-id':r.`author-id`,'in-response-to':r.`in-response-to`,'sender-location':r.`sender-location`,'message':r.message}
from  FacebookMessages as r
;
