blob: 07f2146991cd54d41c345942dd3c1312ed63402d [file] [log] [blame]
/*
* 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.drill.exec.vector.complex.writer;
import org.apache.drill.test.BaseTestQuery;
import org.apache.drill.test.TestBuilder;
import org.junit.BeforeClass;
import org.junit.Ignore;
import org.junit.Test;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.io.PrintWriter;
import java.nio.file.Files;
import java.nio.file.Path;
import static org.apache.drill.test.TestBuilder.listOf;
import static org.apache.drill.test.TestBuilder.mapOf;
public class TestComplexTypeReader extends BaseTestQuery {
@BeforeClass
public static void init() throws Exception {
testNoResult("alter session set `exec.enable_union_type` = true");
}
@Test
// Repeated map (map) -> json.
public void testX() throws Exception{
test("select convert_to(z[0], 'JSON') from cp.`jsoninput/input2.json`;");
}
@Test
//map -> json.
public void testX2() throws Exception{
test("select convert_to(x, 'JSON') from cp.`jsoninput/input2.json`;");
}
@Test
//Map (mapfield) -> json.
public void testX3() throws Exception{
test("select convert_to(tbl.x.y, 'JSON') from cp.`jsoninput/input2.json` tbl;");
}
@Test
//float value -> json
public void testX4() throws Exception{
test("select convert_to(`float`, 'JSON') from cp.`jsoninput/input2.json`;");
}
@Test
//integer value -> json
public void testX5() throws Exception{
test("select convert_to(`integer`, 'JSON') from cp.`jsoninput/input2.json`;");
}
@Test
// repeated map -> json.
public void testX6() throws Exception{
test("select convert_to(z, 'JSON') from cp.`jsoninput/input2.json`;");
}
@Test
//repeated list (Repeated BigInt) -> json
public void testX7() throws Exception{
test("select convert_to(rl[1], 'JSON') from cp.`jsoninput/input2.json`;");
}
@Test
//repeated list (Repeated BigInt) -> json
public void testX8() throws Exception{
test("select convert_to(rl[0][1], 'JSON') from cp.`jsoninput/input2.json`;");
}
@Test
//repeated list -> json
public void testX9() throws Exception{
test("select convert_to(rl, 'JSON') from cp.`jsoninput/input2.json`;");
}
@Test
public void testY() throws Exception{
test("select z[0] from cp.`jsoninput/input2.json`;");
}
@Test
public void testY2() throws Exception{
test("select x from cp.`jsoninput/input2.json`;");
}
@Test
public void testY3() throws Exception{
test("select tbl.x.y from cp.`jsoninput/input2.json` tbl;");
}
@Test
public void testY6() throws Exception{
test("select z from cp.`jsoninput/input2.json`;");
}
@Test
//repeated list (Repeated BigInt)
public void testZ() throws Exception{
test("select rl[1] from cp.`jsoninput/input2.json`;");
}
@Test
//repeated list (Repeated BigInt ( BigInt) ) )
public void testZ1() throws Exception{
test("select rl[0][1] from cp.`jsoninput/input2.json`;");
}
@Test
//repeated list (Repeated BigInt ( BigInt) ) ). The first index is out of boundary
public void testZ2() throws Exception{
test("select rl[1000][1] from cp.`jsoninput/input2.json`;");
}
@Test
//repeated list (Repeated BigInt ( BigInt) ) ). The second index is out of boundary
public void testZ3() throws Exception{
test("select rl[0][1000] from cp.`jsoninput/input2.json`;");
}
@Test
//repeated list. The repeated list is asked for twice, hence requires copying (evaluation in ProjectRecordBatch)
public void testZ4() throws Exception{
test("select rl, rl from cp.`jsoninput/input2.json`;");
}
@Test
//repeated map --> Json. It will go beyond the buffer of size 256 allocated in setup.
public void testA0() throws Exception{
test(" select convert_to(types, 'JSON') from cp.`jsoninput/vvtypes.json`;");
}
@Test
//repeated map (map) --> Json.
public void testA1() throws Exception{
test(" select convert_to(types[1], 'JSON') from cp.`jsoninput/vvtypes.json`;");
}
@Test
//repeated map (map (repeated map) ) --> Json.
public void testA2() throws Exception{
test(" select convert_to(types[1].minor, 'JSON') from cp.`jsoninput/vvtypes.json`;");
}
@Test
//repeated map (map( repeated map (map (varchar)))) --> Json.
public void testA3() throws Exception{
test(" select convert_to(types[1].minor[0].valueHolder, 'JSON') from cp.`jsoninput/vvtypes.json`;");
}
@Test
//Two complex type functions in SELECT clause : repeated map (map) --> Json,
public void testA4() throws Exception{
test(" select convert_to(types[1], 'JSON'), convert_to(modes[2], 'JSON') from cp.`jsoninput/vvtypes.json`;");
}
@Test
//repeated map (map) .
public void testB1() throws Exception{
test(" select types[1] from cp.`jsoninput/vvtypes.json`;");
}
@Test
//repeated map (map (repeated map) ).
public void testB2() throws Exception{
test(" select types[1].minor from cp.`jsoninput/vvtypes.json`;");
}
@Test
//repeated map (map( repeated map (map (varchar)))).
public void testB3() throws Exception{
test(" select types[1].minor[0].valueholder from cp.`jsoninput/vvtypes.json`;");
}
@Test // DRILL-1250
//repeated scalar values evaluation.
public void test_repeatedList() throws Exception{
test("select l, l from cp.`jsoninput/input2.json`;");
}
@Test
public void testKeyValueGen() throws Exception {
test("select kvgen(x) from cp.`jsoninput/input2.json`");
test("select kvgen(bigintegercol), kvgen(float8col) from cp.`jsoninput/input3.json`");
}
@Test
// Functions tests kvgen functionality where the 'value' part of the map is complex
public void testKVGenWithComplexValues() throws Exception {
// test where 'value' is a list of integers
test("select kvgen(a) from cp.`jsoninput/kvgen_complex_input.json`");
// test where 'value' is a repeated list of floats
test("select kvgen(c) from cp.`jsoninput/kvgen_complex_input.json`");
// test where 'value' is a map
test("select kvgen(e) from cp.`jsoninput/kvgen_complex_input.json`");
// test where 'value' is a repeated list of maps
test("select kvgen(i) from cp.`jsoninput/kvgen_complex_input.json`");
// test where 'value' is a map that contains a list
test("select kvgen(m) from cp.`jsoninput/kvgen_complex_input.json`");
// test where 'value' is a map that contains a map
test("select kvgen(p) from cp.`jsoninput/kvgen_complex_input.json`");
}
@Test
// Test SplitUpComplexExpressions rule which splits complex expression into multiple projects
public void testComplexAndSimpleColumnSelection() throws Exception {
test("select t.a.b, kvgen(t.a.c) from cp.`jsoninput/input4.json` t");
}
@Test
public void testKVGenWithNullableInput() throws Exception {
// Contents of the generated file:
/*
{"foo": {"obj":1, "bar":10}}
{"foo": {"obj":2, "bar":20}}
{"foo": null}
{"foo": {"obj": null, "bar": 30}}
*/
try (BufferedWriter writer = new BufferedWriter(new FileWriter(
new File(dirTestWatcher.getRootDir(), "input_nested.json")))) {
String[] fieldValue = {"{\"obj\":1, \"bar\":10}", "{\"obj\":2, \"bar\":20}", null, "{\"obj\": null, \"bar\": 30}"};
for (String value : fieldValue) {
String entry = String.format("{\"foo\": %s}\n", value);
writer.write(entry);
}
}
testBuilder()
.sqlQuery("select kvgen(foo) kv from dfs.`input_nested.json`")
.unOrdered()
.baselineColumns("kv")
.baselineValues(listOf(mapOf("key", "obj", "value", 1L), mapOf("key", "bar", "value", 10L)))
.baselineValues(listOf(mapOf("key", "obj", "value", 2L), mapOf("key", "bar", "value", 20L)))
.baselineValues(listOf())
.baselineValues(listOf(mapOf("key", "bar", "value", 30L)))
.go();
}
@Test
@Ignore( "until flattening code creates correct ListVector (DRILL-4045)" )
public void testNestedFlatten() throws Exception {
test("select flatten(rl) from cp.`jsoninput/input2.json`");
}
@Test //DRILL-2872.
public void testRepeatedJson() throws Exception {
testBuilder()
.sqlQuery("select cast(convert_to(interests, 'JSON') as varchar(0)) as interests from cp.`complex_student.json`")
.unOrdered()
.jsonBaselineFile("DRILL-2872-result.json")
.go();
}
@Test // DRILL-4410
// ListVector allocation
public void test_array() throws Exception{
long numRecords = 100000;
final String file1 = "arrays1.json";
final String file2 = "arrays2.json";
final Path path1 = dirTestWatcher.getRootDir().toPath().resolve(file1);
final Path path2 = dirTestWatcher.getRootDir().toPath().resolve(file2);
Files.createFile(path1);
Files.createFile(path2);
final String arrayString = "[ \"abcdef\", \"ghijkl\", \"mnopqr\", \"stuvwx\", \"yz1234\", \"567890\" ] ";
try(PrintWriter out = new PrintWriter(new BufferedWriter(new FileWriter(path1.toFile(), true)))) {
for (long i = 0; i < numRecords; i++) {
out.println("{ \"id\" : " + i + ", \"array\" : " + arrayString + "}");
}
}catch (IOException e) {
throw e;
}
try(PrintWriter out = new PrintWriter(new BufferedWriter(new FileWriter(path2.toFile(), true)))) {
for (long i = 0; i < numRecords; i++) {
out.println("{ \"id\" : " + i + ", \"array\" : " + arrayString + "}");
}
}catch (IOException e) {
throw e;
}
TestBuilder testBuilder = testBuilder()
.sqlQuery("select * from dfs.`%s` `arrays1` INNER JOIN dfs.`%s` `arrays2` ON "
+ "(`arrays1`.id = `arrays2`.id)", file1, file2)
.unOrdered()
.baselineColumns("id", "id0", "array", "array0");
for (long i = 0; i < numRecords; i++) {
testBuilder.baselineValues(i, i, listOf("abcdef", "ghijkl", "mnopqr", "stuvwx", "yz1234", "567890"),
listOf("abcdef", "ghijkl", "mnopqr", "stuvwx", "yz1234", "567890"));
}
testBuilder.go();
}
@Test
public void testNonExistentFieldConverting() throws Exception {
testBuilder()
.sqlQuery("select employee_id, convert_to(`complex_field`, 'JSON') as complex_field from cp.`employee.json` " +
"where employee_id = 1")
.unOrdered()
.baselineColumns("employee_id", "complex_field")
.baselineValues(1L, null)
.build()
.run();
}
}