/*
* 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.
*/
package org.apache.pig.test;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import org.apache.pig.ResourceSchema;
import org.apache.pig.SortColInfo;
import org.apache.pig.SortInfo;
import org.apache.pig.ResourceSchema.ResourceFieldSchema;
import org.apache.pig.backend.executionengine.ExecException;
import org.apache.pig.data.DataType;
import org.apache.pig.impl.logicalLayer.FrontendException;
import org.apache.pig.impl.logicalLayer.schema.Schema;
import org.apache.pig.impl.logicalLayer.schema.SchemaMergeException;
import org.apache.pig.test.utils.TypeCheckingTestUtil;
import org.junit.Test;
public class TestResourceSchema {
/**
* Test that ResourceSchema is correctly created given a
* pig.Schema and vice versa
*/
@Test
public void testResourceFlatSchemaCreation()
throws ExecException, SchemaMergeException, FrontendException {
String [] aliases ={"f1", "f2"};
byte[] types = {DataType.CHARARRAY, DataType.INTEGER};
Schema origSchema = TypeCheckingTestUtil.genFlatSchema(
aliases,types);
ResourceSchema rsSchema = new ResourceSchema(origSchema);
assertEquals("num fields", aliases.length, rsSchema.getFields().length);
ResourceSchema.ResourceFieldSchema[] fields = rsSchema.getFields();
for (int i=0; i<fields.length; i++) {
assertEquals(fields[i].getName(), aliases[i]);
assertEquals(fields[i].getType(), types[i]);
}
Schema genSchema = Schema.getPigSchema(rsSchema);
assertTrue("generated schema equals original",
Schema.equals(genSchema, origSchema, true, false));
}
/**
* Test that ResourceSchema is correctly created given a
* pig.Schema and vice versa
*/
@Test
public void testResourceFlatSchemaCreation2()
throws ExecException, SchemaMergeException, FrontendException {
String [] aliases ={"f1", "f2"};
byte[] types = {DataType.CHARARRAY, DataType.INTEGER};
Schema origSchema = new Schema(
new Schema.FieldSchema("t1",
new Schema(
new Schema.FieldSchema("t0",
TypeCheckingTestUtil.genFlatSchema(
aliases,types),
DataType.TUPLE)), DataType.BAG));
ResourceSchema rsSchema = new ResourceSchema(origSchema);
Schema genSchema = Schema.getPigSchema(rsSchema);
assertTrue("generated schema equals original",
Schema.equals(genSchema, origSchema, true, false));
}
/**
* Test that ResourceSchema is correctly with SortInfo
*/
@Test
public void testResourceFlatSchemaCreationWithSortInfo()
throws ExecException, SchemaMergeException, FrontendException {
String [] aliases ={"f1", "f2"};
byte[] types = {DataType.CHARARRAY, DataType.INTEGER};
Schema origSchema = new Schema(
new Schema.FieldSchema("t1",
new Schema(
new Schema.FieldSchema("t0",
TypeCheckingTestUtil.genFlatSchema(
aliases,types),
DataType.TUPLE)), DataType.BAG));
List<SortColInfo> colList = new ArrayList<SortColInfo>();
SortColInfo col1 = new SortColInfo("f1", 0, SortColInfo.Order.ASCENDING);
SortColInfo col2 = new SortColInfo("f1", 1, SortColInfo.Order.DESCENDING);
colList.add(col1);
colList.add(col2);
SortInfo sortInfo = new SortInfo(colList);
ResourceSchema rsSchema = new ResourceSchema(origSchema, sortInfo);
Schema genSchema = Schema.getPigSchema(rsSchema);
assertTrue("generated schema equals original",
Schema.equals(genSchema, origSchema, true, false));
assertTrue(rsSchema.getSortKeys()[0]==0);
assertTrue(rsSchema.getSortKeys()[1]==1);
assertTrue(rsSchema.getSortKeyOrders()[0]==ResourceSchema.Order.ASCENDING);
assertTrue(rsSchema.getSortKeyOrders()[1]==ResourceSchema.Order.DESCENDING);
}
/**
* Test that Pig Schema is correctly created given a
* ResourceSchema and vice versa. Test also that
* TwoLevelAccess flag is set for Pig Schema when needed.
* @throws IOException
*/
@Test
public void testToPigSchemaWithTwoLevelAccess() throws IOException {
ResourceFieldSchema[] level0 =
new ResourceFieldSchema[] {
new ResourceFieldSchema()
.setName("fld0").setType(DataType.CHARARRAY),
new ResourceFieldSchema()
.setName("fld1").setType(DataType.DOUBLE),
new ResourceFieldSchema()
.setName("fld2").setType(DataType.INTEGER)
};
ResourceSchema rSchema0 = new ResourceSchema()
.setFields(level0);
ResourceFieldSchema[] level1 =
new ResourceFieldSchema[] {
new ResourceFieldSchema()
.setName("t1").setType(DataType.TUPLE)
.setSchema(rSchema0)
};
ResourceSchema rSchema1 = new ResourceSchema()
.setFields(level1);
ResourceFieldSchema[] level2 =
new ResourceFieldSchema[] {
new ResourceFieldSchema()
.setName("t2").setType(DataType.BAG)
.setSchema(rSchema1)
};
ResourceSchema origSchema = new ResourceSchema()
.setFields(level2);
Schema pSchema = Schema.getPigSchema(origSchema);
assertTrue(CheckTwoLevelAccess(pSchema));
assertTrue(ResourceSchema.equals(origSchema, new ResourceSchema(pSchema)));
}
private boolean CheckTwoLevelAccess(Schema s) {
if (s == null) return false;
for (Schema.FieldSchema fs : s.getFields()) {
if (fs.type == DataType.BAG
&& fs.schema != null
&& fs.schema.isTwoLevelAccessRequired()) {
return true;
}
if (CheckTwoLevelAccess(fs.schema)) return true;
}
return false;
}
/**
* Test invalid Resource Schema: multiple fields for a bag
* @throws IOException
*/
@Test(expected=FrontendException.class)
public void testToPigSchemaWithInvalidSchema() throws IOException {
ResourceFieldSchema[] level0 = new ResourceFieldSchema[] {
new ResourceFieldSchema()
.setName("fld0").setType(DataType.CHARARRAY),
new ResourceFieldSchema()
.setName("fld1").setType(DataType.DOUBLE),
new ResourceFieldSchema()
.setName("fld2").setType(DataType.INTEGER)
};
ResourceSchema rSchema0 = new ResourceSchema()
.setFields(level0);
ResourceFieldSchema[] level2 = new ResourceFieldSchema[] {
new ResourceFieldSchema()
.setName("t2").setType(DataType.BAG).setSchema(rSchema0)
};
}
/**
* Test invalid Resource Schema: bag without tuple field
* @throws IOException
*/
@Test(expected=FrontendException.class)
public void testToPigSchemaWithInvalidSchema2() throws IOException {
ResourceFieldSchema[] level0 = new ResourceFieldSchema[] {
new ResourceFieldSchema()
.setName("fld0").setType(DataType.CHARARRAY)
};
ResourceSchema rSchema0 = new ResourceSchema()
.setFields(level0);
ResourceFieldSchema[] level2 = new ResourceFieldSchema[] {
new ResourceFieldSchema()
.setName("t2").setType(DataType.BAG).setSchema(rSchema0)
};
}
/**
* Test one-level Pig Schema: multiple fields for a bag
*/
@Test
public void testResourceSchemaWithInvalidPigSchema()
throws FrontendException {
String [] aliases ={"f1", "f2"};
byte[] types = {DataType.CHARARRAY, DataType.INTEGER};
Schema level0 = TypeCheckingTestUtil.genFlatSchema(
aliases,types);
Schema.FieldSchema fld0 =
new Schema.FieldSchema("f0", level0, DataType.BAG);
Schema level1 = new Schema(fld0);
Schema genSchema = Schema.getPigSchema(new ResourceSchema(level1));
assertTrue(CheckTwoLevelAccess(genSchema));
}
/**
* Test one-level Pig Schema: bag without tuple field
*/
@Test
public void testResourceSchemaWithInvalidPigSchema2()
throws FrontendException {
String [] aliases ={"f1"};
byte[] types = {DataType.INTEGER};
Schema level0 = TypeCheckingTestUtil.genFlatSchema(
aliases,types);
Schema.FieldSchema fld0 =
new Schema.FieldSchema("f0", level0, DataType.BAG);
Schema level1 = new Schema(fld0);
Schema genSchema = Schema.getPigSchema(new ResourceSchema(level1));
assertTrue(CheckTwoLevelAccess(genSchema));
}
}