/*
* Copyright © 2014 Cask Data, Inc.
*
* Licensed 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 co.cask.cdap.explore.service;
import co.cask.cdap.api.dataset.DatasetDefinition;
import co.cask.cdap.api.dataset.DatasetProperties;
import co.cask.cdap.explore.service.datasets.ExtensiveSchemaTableDefinition;
import co.cask.cdap.proto.ColumnDesc;
import co.cask.cdap.proto.Id;
import co.cask.cdap.proto.QueryResult;
import co.cask.cdap.proto.TableInfo;
import co.cask.cdap.test.SlowTests;
import co.cask.tephra.Transaction;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.Lists;
import org.junit.AfterClass;
import org.junit.Assert;
import org.junit.BeforeClass;
import org.junit.ClassRule;
import org.junit.Test;
import org.junit.experimental.categories.Category;
import org.junit.rules.TemporaryFolder;
/**
* Painfully test a wide combination of types in a schema of a record scannable.
*/
@Category(SlowTests.class)
public class ExploreExtensiveSchemaTableTestRun extends BaseHiveExploreServiceTest {
@ClassRule
public static TemporaryFolder tmpFolder = new TemporaryFolder();
private static final Id.DatasetModule extensiveSchema = Id.DatasetModule.from(NAMESPACE_ID, "extensiveSchema");
@BeforeClass
public static void start() throws Exception {
initialize(tmpFolder);
datasetFramework.addModule(extensiveSchema, new ExtensiveSchemaTableDefinition.ExtensiveSchemaTableModule());
// Performing admin operations to create dataset instance
datasetFramework.addInstance("ExtensiveSchemaTable", MY_TABLE, DatasetProperties.EMPTY);
// Accessing dataset instance to perform data operations
ExtensiveSchemaTableDefinition.ExtensiveSchemaTable table =
datasetFramework.getDataset(MY_TABLE, DatasetDefinition.NO_ARGUMENTS, null);
Assert.assertNotNull(table);
Transaction tx1 = transactionManager.startShort(100);
table.startTx(tx1);
ExtensiveSchemaTableDefinition.ExtensiveSchema value1 =
new ExtensiveSchemaTableDefinition.ExtensiveSchema(
"foo", 1, 1.23f, 2.45d, (long) 1000, (byte) 100, true, (short) 8, new int[] { 10, 11 },
new float[] { 1.67f, 2.89f }, new double[] { 10.56d, 8.78d }, new long [] { 101, 201 },
new byte[] { 106, 110 }, new boolean[] { true, false }, new short[] { 50, 51 }, new String[] { "foo", "bar" },
ImmutableList.of(10, 20), ImmutableList.of(10.45f, 20.98f), ImmutableList.of(10.99d, 20.90d),
ImmutableList.of((long) 654, (long) 2897), ImmutableList.of((byte) 22, (byte) 23), ImmutableList.of(true, true),
ImmutableList.of((short) 76, (short) 39), ImmutableList.of("foo2", "bar2"), ImmutableMap.of("foo3", 51),
ImmutableMap.of(3.55f, 51.98d), ImmutableMap.of((long) 890, (byte) 45), ImmutableMap.of(true, (short) 27),
new ExtensiveSchemaTableDefinition.Value("foo", 2),
new ExtensiveSchemaTableDefinition.Value[] {
new ExtensiveSchemaTableDefinition.Value("bar", 3), new ExtensiveSchemaTableDefinition.Value("foobar", 4)
}, ImmutableList.of(new ExtensiveSchemaTableDefinition.Value("foobar2", 3)),
ImmutableMap.of("key", new ExtensiveSchemaTableDefinition.Value("foobar3", 9)));
value1.setExt(value1);
table.put("1", value1);
Assert.assertTrue(table.commitTx());
transactionManager.canCommit(tx1, table.getTxChanges());
transactionManager.commit(tx1);
table.postTxCommit();
Transaction tx2 = transactionManager.startShort(100);
table.startTx(tx2);
}
@AfterClass
public static void stop() throws Exception {
datasetFramework.deleteInstance(MY_TABLE);
datasetFramework.deleteModule(extensiveSchema);
}
@Test
public void testExtensiveSchema() throws Exception {
runCommand(NAMESPACE_ID, "show tables",
true,
Lists.newArrayList(new ColumnDesc("tab_name", "STRING", 1, "from deserializer")),
Lists.newArrayList(new QueryResult(Lists.<Object>newArrayList(MY_TABLE_NAME))));
runCommand(NAMESPACE_ID, "describe " + MY_TABLE_NAME,
true,
Lists.newArrayList(
new ColumnDesc("col_name", "STRING", 1, "from deserializer"),
new ColumnDesc("data_type", "STRING", 2, "from deserializer"),
new ColumnDesc("comment", "STRING", 3, "from deserializer")
),
Lists.newArrayList(
new QueryResult(Lists.<Object>newArrayList("s", "string", "from deserializer")),
new QueryResult(Lists.<Object>newArrayList("i", "int", "from deserializer")),
new QueryResult(Lists.<Object>newArrayList("f", "float", "from deserializer")),
new QueryResult(Lists.<Object>newArrayList("d", "double", "from deserializer")),
new QueryResult(Lists.<Object>newArrayList("l", "bigint", "from deserializer")),
new QueryResult(Lists.<Object>newArrayList("b", "tinyint", "from deserializer")),
new QueryResult(Lists.<Object>newArrayList("bo", "boolean", "from deserializer")),
new QueryResult(Lists.<Object>newArrayList("sh", "smallint", "from deserializer")),
// note: hive removes upper cases
// Arrays
new QueryResult(Lists.<Object>newArrayList("iarr", "array<int>", "from deserializer")),
new QueryResult(Lists.<Object>newArrayList("farr", "array<float>", "from deserializer")),
new QueryResult(Lists.<Object>newArrayList("darr", "array<double>", "from deserializer")),
new QueryResult(Lists.<Object>newArrayList("larr", "array<bigint>", "from deserializer")),
new QueryResult(Lists.<Object>newArrayList("barr", "binary", "from deserializer")),
new QueryResult(Lists.<Object>newArrayList("boarr", "array<boolean>", "from deserializer")),
new QueryResult(Lists.<Object>newArrayList("sharr", "array<smallint>", "from deserializer")),
new QueryResult(Lists.<Object>newArrayList("sarr", "array<string>", "from deserializer")),
// Lists
new QueryResult(Lists.<Object>newArrayList("ilist", "array<int>", "from deserializer")),
new QueryResult(Lists.<Object>newArrayList("flist", "array<float>", "from deserializer")),
new QueryResult(Lists.<Object>newArrayList("dlist", "array<double>", "from deserializer")),
new QueryResult(Lists.<Object>newArrayList("llist", "array<bigint>", "from deserializer")),
// Note: list<byte> becomes array<tinyint>, whereas byte[] becomes binary...
new QueryResult(Lists.<Object>newArrayList("blist", "array<tinyint>", "from deserializer")),
new QueryResult(Lists.<Object>newArrayList("bolist", "array<boolean>", "from deserializer")),
new QueryResult(Lists.<Object>newArrayList("shlist", "array<smallint>", "from deserializer")),
new QueryResult(Lists.<Object>newArrayList("slist", "array<string>", "from deserializer")),
// Maps
new QueryResult(Lists.<Object>newArrayList("stoimap", "map<string,int>", "from deserializer")),
new QueryResult(Lists.<Object>newArrayList("ftodmap", "map<float,double>", "from deserializer")),
new QueryResult(Lists.<Object>newArrayList("ltobmap", "map<bigint,tinyint>", "from deserializer")),
new QueryResult(Lists.<Object>newArrayList("botoshmap", "map<boolean,smallint>", "from deserializer")),
// Custom type
new QueryResult(Lists.<Object>newArrayList("v", "struct<s:string,i:int>", "from deserializer")),
new QueryResult(Lists.<Object>newArrayList("varr", "array<struct<s:string,i:int>>",
"from deserializer")),
new QueryResult(Lists.<Object>newArrayList("vlist", "array<struct<s:string,i:int>>",
"from deserializer")),
new QueryResult(Lists.<Object>newArrayList("stovmap", "map<string,struct<s:string,i:int>>",
"from deserializer"))
)
);
runCommand(NAMESPACE_ID, "select * from " + MY_TABLE_NAME,
true,
Lists.newArrayList(new ColumnDesc(MY_TABLE_NAME + ".s", "STRING", 1, null),
new ColumnDesc(MY_TABLE_NAME + ".i", "INT", 2, null),
new ColumnDesc(MY_TABLE_NAME + ".f", "FLOAT", 3, null),
new ColumnDesc(MY_TABLE_NAME + ".d", "DOUBLE", 4, null),
new ColumnDesc(MY_TABLE_NAME + ".l", "BIGINT", 5, null),
new ColumnDesc(MY_TABLE_NAME + ".b", "TINYINT", 6, null),
new ColumnDesc(MY_TABLE_NAME + ".bo", "BOOLEAN", 7, null),
new ColumnDesc(MY_TABLE_NAME + ".sh", "SMALLINT", 8, null),
// Arrays
new ColumnDesc(MY_TABLE_NAME + ".iarr", "array<int>", 9, null),
new ColumnDesc(MY_TABLE_NAME + ".farr", "array<float>", 10, null),
new ColumnDesc(MY_TABLE_NAME + ".darr", "array<double>", 11, null),
new ColumnDesc(MY_TABLE_NAME + ".larr", "array<bigint>", 12, null),
new ColumnDesc(MY_TABLE_NAME + ".barr", "BINARY", 13, null),
new ColumnDesc(MY_TABLE_NAME + ".boarr", "array<boolean>", 14, null),
new ColumnDesc(MY_TABLE_NAME + ".sharr", "array<smallint>", 15, null),
new ColumnDesc(MY_TABLE_NAME + ".sarr", "array<string>", 16, null),
// Lists
new ColumnDesc(MY_TABLE_NAME + ".ilist", "array<int>", 17, null),
new ColumnDesc(MY_TABLE_NAME + ".flist", "array<float>", 18, null),
new ColumnDesc(MY_TABLE_NAME + ".dlist", "array<double>", 19, null),
new ColumnDesc(MY_TABLE_NAME + ".llist", "array<bigint>", 20, null),
new ColumnDesc(MY_TABLE_NAME + ".blist", "array<tinyint>", 21, null),
new ColumnDesc(MY_TABLE_NAME + ".bolist", "array<boolean>", 22, null),
new ColumnDesc(MY_TABLE_NAME + ".shlist", "array<smallint>", 23, null),
new ColumnDesc(MY_TABLE_NAME + ".slist", "array<string>", 24, null),
// Maps
new ColumnDesc(MY_TABLE_NAME + ".stoimap", "map<string,int>", 25, null),
new ColumnDesc(MY_TABLE_NAME + ".ftodmap", "map<float,double>", 26, null),
new ColumnDesc(MY_TABLE_NAME + ".ltobmap", "map<bigint,tinyint>", 27, null),
new ColumnDesc(MY_TABLE_NAME + ".botoshmap",
"map<boolean,smallint>", 28, null),
// Custom type
new ColumnDesc(MY_TABLE_NAME + ".v", "struct<s:string,i:int>", 29, null),
new ColumnDesc(MY_TABLE_NAME + ".varr", "array<struct<s:string,i:int>>",
30, null),
new ColumnDesc(MY_TABLE_NAME + ".vlist", "array<struct<s:string,i:int>>",
31, null),
new ColumnDesc(MY_TABLE_NAME + ".stovmap",
"map<string,struct<s:string,i:int>>", 32, null)
),
Lists.newArrayList(
new QueryResult(Lists.<Object>newArrayList(
// scalars
"foo", 1, 1.23, 2.45, (long) 1000, (byte) 100, true, (short) 8,
// arrays
"[10,11]",
"[1.67,2.89]",
"[10.56,8.78]",
"[101,201]",
new byte[] { 106, 110 },
"[true,false]",
"[50,51]",
"[\"foo\",\"bar\"]",
// lists
"[10,20]",
"[10.45,20.98]",
"[10.99,20.9]",
"[654,2897]",
new byte[] { 22, 23 },
"[true,true]",
"[76,39]",
"[\"foo2\",\"bar2\"]",
// maps
"{\"foo3\":51}", "{3.55:51.98}", "{890:45}",
"{true:27}", "{\"s\":\"foo\",\"i\":2}", "[{\"s\":\"bar\",\"i\":3},{\"s\":\"foobar\",\"i\":4}]",
"[{\"s\":\"foobar2\",\"i\":3}]", "{\"key\":{\"s\":\"foobar3\",\"i\":9}}"
)))
);
// Make sure the whole schema has been persisted in the metastore, and with the right order
Assert.assertEquals(ImmutableList.of(new TableInfo.ColumnInfo("s", "string", null),
new TableInfo.ColumnInfo("i", "int", null),
new TableInfo.ColumnInfo("f", "float", null),
new TableInfo.ColumnInfo("d", "double", null),
new TableInfo.ColumnInfo("l", "bigint", null),
new TableInfo.ColumnInfo("b", "tinyint", null),
new TableInfo.ColumnInfo("bo", "boolean", null),
new TableInfo.ColumnInfo("sh", "smallint", null),
// Arrays
new TableInfo.ColumnInfo("iarr", "array<int>", null),
new TableInfo.ColumnInfo("farr", "array<float>", null),
new TableInfo.ColumnInfo("darr", "array<double>", null),
new TableInfo.ColumnInfo("larr", "array<bigint>", null),
new TableInfo.ColumnInfo("barr", "binary", null),
new TableInfo.ColumnInfo("boarr", "array<boolean>", null),
new TableInfo.ColumnInfo("sharr", "array<smallint>", null),
new TableInfo.ColumnInfo("sarr", "array<string>", null),
// Lists
new TableInfo.ColumnInfo("ilist", "array<int>", null),
new TableInfo.ColumnInfo("flist", "array<float>", null),
new TableInfo.ColumnInfo("dlist", "array<double>", null),
new TableInfo.ColumnInfo("llist", "array<bigint>", null),
new TableInfo.ColumnInfo("blist", "array<tinyint>", null),
new TableInfo.ColumnInfo("bolist", "array<boolean>", null),
new TableInfo.ColumnInfo("shlist", "array<smallint>", null),
new TableInfo.ColumnInfo("slist", "array<string>", null),
// Maps
new TableInfo.ColumnInfo("stoimap", "map<string,int>", null),
new TableInfo.ColumnInfo("ftodmap", "map<float,double>", null),
new TableInfo.ColumnInfo("ltobmap", "map<bigint,tinyint>", null),
new TableInfo.ColumnInfo("botoshmap", "map<boolean,smallint>", null),
// Custom type
new TableInfo.ColumnInfo("v", "struct<s:string,i:int>", null),
new TableInfo.ColumnInfo("varr", "array<struct<s:string,i:int>>", null),
new TableInfo.ColumnInfo("vlist", "array<struct<s:string,i:int>>", null),
new TableInfo.ColumnInfo("stovmap", "map<string,struct<s:string,i:int>>", null)
),
exploreService.getTableInfo(NAMESPACE_ID.getId(), MY_TABLE_NAME).getSchema());
}
}