blob: c83850e914f902ce0398a364dc0839fcfa694272 [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;
import org.apache.commons.io.FileUtils;
import org.apache.drill.categories.SqlTest;
import org.apache.drill.categories.UnlikelyTest;
import org.apache.drill.common.exceptions.UserException;
import org.apache.drill.common.exceptions.UserRemoteException;
import org.apache.drill.common.types.TypeProtos;
import org.apache.drill.exec.record.metadata.ColumnMetadata;
import org.apache.drill.exec.record.metadata.TupleMetadata;
import org.apache.drill.exec.record.metadata.schema.PathSchemaProvider;
import org.apache.drill.exec.record.metadata.schema.SchemaContainer;
import org.apache.drill.exec.record.metadata.schema.SchemaProvider;
import org.apache.drill.test.ClusterFixture;
import org.apache.drill.test.ClusterFixtureBuilder;
import org.apache.drill.test.ClusterTest;
import org.apache.hadoop.fs.Path;
import org.joda.time.LocalDate;
import org.junit.BeforeClass;
import org.junit.Rule;
import org.junit.Test;
import org.junit.experimental.categories.Category;
import org.junit.rules.ExpectedException;
import java.io.File;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.Arrays;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.Map;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
@Category({SqlTest.class, UnlikelyTest.class})
public class TestSchemaCommands extends ClusterTest {
@Rule
public ExpectedException thrown = ExpectedException.none();
@BeforeClass
public static void setup() throws Exception {
ClusterFixtureBuilder builder = ClusterFixture.builder(dirTestWatcher);
startCluster(builder);
}
@Test
public void testCreateWithoutSchema() throws Exception {
thrown.expect(UserException.class);
thrown.expectMessage("PARSE ERROR: Lexical error");
run("create schema for");
}
@Test
public void testCreateWithForAndPath() throws Exception {
thrown.expect(UserException.class);
thrown.expectMessage("PARSE ERROR: Encountered \"path\"");
run("create schema ( col1 int, col2 int) for table tbl path '/tmp/schema.file'");
}
@Test
public void testCreateWithPathAndOrReplace() throws Exception {
thrown.expect(UserException.class);
thrown.expectMessage("PARSE ERROR: <OR REPLACE> cannot be used with <PATH> property");
run("create or replace schema (col1 int, col2 int) path '/tmp/schema.file'");
}
@Test
public void testCreateForMissingTable() throws Exception {
String table = "dfs.tmp.tbl";
thrown.expect(UserException.class);
thrown.expectMessage("VALIDATION ERROR: Table [tbl] was not found");
run("create schema (col1 int, col2 int) for table %s", table);
}
@Test
public void testCreateForTemporaryTable() throws Exception {
String table = "temp_create";
try {
run("create temporary table %s as select 'a' as c from (values(1))", table);
thrown.expect(UserException.class);
thrown.expectMessage(String.format("VALIDATION ERROR: Indicated table [%s] is temporary table", table));
run("create schema (col1 int, col2 int) for table %s", table);
} finally {
run("drop table if exists %s", table);
}
}
@Test
public void testCreateForImmutableSchema() throws Exception {
String table = "sys.version";
thrown.expect(UserException.class);
thrown.expectMessage("VALIDATION ERROR: Unable to create or drop objects. Schema [sys] is immutable");
run("create schema (col1 int, col2 int) for table %s", table);
}
@Test
public void testMissingDirectory() throws Exception {
File tmpDir = dirTestWatcher.getTmpDir();
Path schema = new Path(Paths.get(tmpDir.getPath(), "missing_parent_directory", "file.schema").toFile().getPath());
thrown.expect(UserException.class);
thrown.expectMessage(String.format("RESOURCE ERROR: Parent path for schema file [%s] does not exist", schema.toUri().getPath()));
run("create schema (col1 int, col2 int) path '%s'", schema.toUri().getPath());
}
@Test
public void testTableAsFile() throws Exception {
File tmpDir = dirTestWatcher.getDfsTestTmpDir();
String table = "test_table_as_file.json";
File tablePath = new File(tmpDir, table);
assertTrue(tablePath.createNewFile());
thrown.expect(UserException.class);
thrown.expectMessage(String.format("RESOURCE ERROR: Indicated table [%s] must be a directory",
String.format("dfs.tmp.%s", table)));
try {
run("create schema (col1 int, col2 int) for table %s.`%s`", "dfs.tmp", table);
} finally {
FileUtils.deleteQuietly(tablePath);
}
}
@Test
public void testCreateSimpleForPathWithExistingSchema() throws Exception {
File tmpDir = dirTestWatcher.getTmpDir();
File schema = new File(tmpDir, "simple_for_path.schema");
assertTrue(schema.createNewFile());
thrown.expect(UserException.class);
thrown.expectMessage(String.format("VALIDATION ERROR: Schema already exists for [%s]", schema.getPath()));
try {
run("create schema (col1 int, col2 int) path '%s'", schema.getPath());
} finally {
FileUtils.deleteQuietly(schema);
}
}
@Test
public void testCreateSimpleForTableWithExistingSchema() throws Exception {
String table = "dfs.tmp.table_for_simple_existing_schema";
try {
run("create table %s as select 'a' as c from (values(1))", table);
testBuilder()
.sqlQuery("create schema (c varchar not null) for table %s", table)
.unOrdered()
.baselineColumns("ok", "summary")
.baselineValues(true, String.format("Created schema for [%s]", table))
.go();
thrown.expect(UserRemoteException.class);
thrown.expectMessage(String.format("VALIDATION ERROR: Schema already exists for [%s]", table));
run("create schema (c varchar not null) for table %s", table);
} finally {
run("drop table if exists %s", table);
}
}
@Test
public void testSuccessfulCreateForPath() throws Exception {
File tmpDir = dirTestWatcher.getTmpDir();
File schemaFile = new File(tmpDir, "schema_for_successful_create_for_path.schema");
assertFalse(schemaFile.exists());
try {
testBuilder()
.sqlQuery("create schema (i int not null, v varchar) path '%s'", schemaFile.getPath())
.unOrdered()
.baselineColumns("ok", "summary")
.baselineValues(true, String.format("Created schema for [%s]", schemaFile.getPath()))
.go();
SchemaProvider schemaProvider = new PathSchemaProvider(new Path(schemaFile.getPath()));
assertTrue(schemaProvider.exists());
SchemaContainer schemaContainer = schemaProvider.read();
assertNull(schemaContainer.getTable());
assertNotNull(schemaContainer.getSchema());
TupleMetadata schema = schemaContainer.getSchema();
ColumnMetadata intColumn = schema.metadata("i");
assertFalse(intColumn.isNullable());
assertEquals(TypeProtos.MinorType.INT, intColumn.type());
ColumnMetadata varcharColumn = schema.metadata("v");
assertTrue(varcharColumn.isNullable());
assertEquals(TypeProtos.MinorType.VARCHAR, varcharColumn.type());
} finally {
FileUtils.deleteQuietly(schemaFile);
}
}
@Test
public void testSuccessfulCreateOrReplaceForTable() throws Exception {
String tableName = "table_for_successful_create_or_replace_for_table";
String table = String.format("dfs.tmp.%s", tableName);
try {
run("create table %s as select 'a' as c from (values(1))", table);
File schemaPath = Paths.get(dirTestWatcher.getDfsTestTmpDir().getPath(),
tableName, SchemaProvider.DEFAULT_SCHEMA_NAME).toFile();
assertFalse(schemaPath.exists());
testBuilder()
.sqlQuery("create schema (c varchar not null) for table %s", table)
.unOrdered()
.baselineColumns("ok", "summary")
.baselineValues(true, String.format("Created schema for [%s]", table))
.go();
SchemaProvider schemaProvider = new PathSchemaProvider(new Path(schemaPath.getPath()));
assertTrue(schemaProvider.exists());
SchemaContainer schemaContainer = schemaProvider.read();
assertNotNull(schemaContainer.getTable());
assertEquals(String.format("dfs.tmp.`%s`", tableName), schemaContainer.getTable());
assertNotNull(schemaContainer.getSchema());
ColumnMetadata column = schemaContainer.getSchema().metadata("c");
assertFalse(column.isNullable());
assertEquals(TypeProtos.MinorType.VARCHAR, column.type());
testBuilder()
.sqlQuery("create or replace schema (c varchar) for table %s", table)
.unOrdered()
.baselineColumns("ok", "summary")
.baselineValues(true, String.format("Created schema for [%s]", table))
.go();
assertTrue(schemaProvider.exists());
SchemaContainer updatedSchemaContainer = schemaProvider.read();
assertNotNull(updatedSchemaContainer.getTable());
assertEquals(String.format("dfs.tmp.`%s`", tableName), updatedSchemaContainer.getTable());
assertNotNull(updatedSchemaContainer.getSchema());
ColumnMetadata updatedColumn = updatedSchemaContainer.getSchema().metadata("c");
assertTrue(updatedColumn.isNullable());
assertEquals(TypeProtos.MinorType.VARCHAR, updatedColumn.type());
} finally {
run("drop table if exists %s", table);
}
}
@Test
public void testCreateWithSchemaProperties() throws Exception {
File tmpDir = dirTestWatcher.getTmpDir();
File schemaFile = new File(tmpDir, "schema_for_create_with_properties.schema");
assertFalse(schemaFile.exists());
try {
testBuilder()
.sqlQuery("create schema (i int not null) path '%s' " +
"properties ('k1' = 'v1', 'k2' = 'v2', 'k3' = 'v3')", schemaFile.getPath())
.unOrdered()
.baselineColumns("ok", "summary")
.baselineValues(true, String.format("Created schema for [%s]", schemaFile.getPath()))
.go();
SchemaProvider schemaProvider = new PathSchemaProvider(new Path(schemaFile.getPath()));
assertTrue(schemaProvider.exists());
SchemaContainer schemaContainer = schemaProvider.read();
assertNull(schemaContainer.getTable());
TupleMetadata schema = schemaContainer.getSchema();
assertNotNull(schema);
Map<String, String> properties = new LinkedHashMap<>();
properties.put("k1", "v1");
properties.put("k2", "v2");
properties.put("k3", "v3");
assertEquals(properties.size(), schema.properties().size());
assertEquals(properties, schema.properties());
} finally {
FileUtils.deleteQuietly(schemaFile);
}
}
@Test
public void testCreateWithoutSchemaProperties() throws Exception {
File tmpDir = dirTestWatcher.getTmpDir();
File schemaFile = new File(tmpDir, "schema_for_create_without_properties.schema");
assertFalse(schemaFile.exists());
try {
testBuilder()
.sqlQuery("create schema (i int not null) path '%s'", schemaFile.getPath())
.unOrdered()
.baselineColumns("ok", "summary")
.baselineValues(true, String.format("Created schema for [%s]", schemaFile.getPath()))
.go();
SchemaProvider schemaProvider = new PathSchemaProvider(new Path(schemaFile.getPath()));
assertTrue(schemaProvider.exists());
SchemaContainer schemaContainer = schemaProvider.read();
assertNull(schemaContainer.getTable());
TupleMetadata schema = schemaContainer.getSchema();
assertNotNull(schema);
assertNotNull(schema.properties());
assertEquals(0, schema.properties().size());
} finally {
FileUtils.deleteQuietly(schemaFile);
}
}
@Test
public void testCreateWithVariousColumnProperties() throws Exception {
File tmpDir = dirTestWatcher.getTmpDir();
File schemaFile = new File(tmpDir, "schema_for_create_with_various_column_properties.schema");
assertFalse(schemaFile.exists());
try {
testBuilder()
.sqlQuery("create schema ( " +
"a int not null default '10', " +
"b date format 'yyyy-MM-dd' default '2017-01-31', " +
"c varchar properties {'k1' = 'v1', 'k2' = 'v2'}) " +
"path '%s'",
schemaFile.getPath())
.unOrdered()
.baselineColumns("ok", "summary")
.baselineValues(true, String.format("Created schema for [%s]", schemaFile.getPath()))
.go();
SchemaProvider schemaProvider = new PathSchemaProvider(new Path(schemaFile.getPath()));
assertTrue(schemaProvider.exists());
SchemaContainer schemaContainer = schemaProvider.read();
assertNull(schemaContainer.getTable());
TupleMetadata schema = schemaContainer.getSchema();
assertNotNull(schema);
assertEquals(3, schema.size());
ColumnMetadata a = schema.metadata("a");
assertTrue(a.decodeDefaultValue() instanceof Integer);
assertEquals(10, a.decodeDefaultValue());
assertEquals("10", a.defaultValue());
ColumnMetadata b = schema.metadata("b");
assertTrue(b.decodeDefaultValue() instanceof LocalDate);
assertEquals("yyyy-MM-dd", b.format());
assertEquals(LocalDate.parse("2017-01-31"), b.decodeDefaultValue());
assertEquals("2017-01-31", b.defaultValue());
ColumnMetadata c = schema.metadata("c");
Map<String, String> properties = new LinkedHashMap<>();
properties.put("k1", "v1");
properties.put("k2", "v2");
assertEquals(properties, c.properties());
assertEquals(0, schema.properties().size());
} finally {
FileUtils.deleteQuietly(schemaFile);
}
}
@Test
public void testCreateWithoutColumns() throws Exception {
File tmpDir = dirTestWatcher.getTmpDir();
File schemaFile = new File(tmpDir, "schema_for_create_without_columns.schema");
assertFalse(schemaFile.exists());
try {
testBuilder()
.sqlQuery("create schema () " +
"path '%s' " +
"properties ('prop' = 'val')",
schemaFile.getPath())
.unOrdered()
.baselineColumns("ok", "summary")
.baselineValues(true, String.format("Created schema for [%s]", schemaFile.getPath()))
.go();
SchemaProvider schemaProvider = new PathSchemaProvider(new Path(schemaFile.getPath()));
assertTrue(schemaProvider.exists());
SchemaContainer schemaContainer = schemaProvider.read();
assertNull(schemaContainer.getTable());
TupleMetadata schema = schemaContainer.getSchema();
assertNotNull(schema);
assertTrue(schema.isEmpty());
assertEquals("val", schema.property("prop"));
} finally {
FileUtils.deleteQuietly(schemaFile);
}
}
@Test
public void testCreateUsingLoadFromMissingFile() throws Exception {
thrown.expect(UserException.class);
thrown.expectMessage("RESOURCE ERROR: File with raw schema [path/to/file] does not exist");
run("create schema load 'path/to/file' for table dfs.tmp.t");
}
@Test
public void testCreateUsingLoad() throws Exception {
File tmpDir = dirTestWatcher.getTmpDir();
File rawSchema = new File(tmpDir, "raw.schema");
File schemaFile = new File(tmpDir, "schema_for_create_using_load.schema");
try {
Files.write(rawSchema.toPath(), Arrays.asList(
"i int,",
"v varchar"
));
assertTrue(rawSchema.exists());
testBuilder()
.sqlQuery("create schema load '%s' path '%s' properties ('k1'='v1', 'k2' = 'v2')",
rawSchema.getPath(), schemaFile.getPath())
.unOrdered()
.baselineColumns("ok", "summary")
.baselineValues(true, String.format("Created schema for [%s]", schemaFile.getPath()))
.go();
SchemaProvider schemaProvider = new PathSchemaProvider(new Path(schemaFile.getPath()));
assertTrue(schemaFile.exists());
SchemaContainer schemaContainer = schemaProvider.read();
assertNull(schemaContainer.getTable());
TupleMetadata schema = schemaContainer.getSchema();
assertNotNull(schema);
assertEquals(2, schema.size());
assertEquals(TypeProtos.MinorType.INT, schema.metadata("i").type());
assertEquals(TypeProtos.MinorType.VARCHAR, schema.metadata("v").type());
assertEquals(2, schema.properties().size());
} finally {
FileUtils.deleteQuietly(rawSchema);
FileUtils.deleteQuietly(schemaFile);
}
}
@Test
public void testCreateUsingLoadEmptyFile() throws Exception {
File tmpDir = dirTestWatcher.getTmpDir();
File rawSchema = new File(tmpDir, "raw_empty.schema");
File schemaFile = new File(tmpDir, "schema_for_create_using_load_empty_file.schema");
try {
assertTrue(rawSchema.createNewFile());
testBuilder()
.sqlQuery("create schema load '%s' path '%s' properties ('k1'='v1', 'k2' = 'v2')",
rawSchema.getPath(), schemaFile.getPath())
.unOrdered()
.baselineColumns("ok", "summary")
.baselineValues(true, String.format("Created schema for [%s]", schemaFile.getPath()))
.go();
SchemaProvider schemaProvider = new PathSchemaProvider(new Path(schemaFile.getPath()));
assertTrue(schemaFile.exists());
SchemaContainer schemaContainer = schemaProvider.read();
assertNull(schemaContainer.getTable());
TupleMetadata schema = schemaContainer.getSchema();
assertNotNull(schema);
assertEquals(0, schema.size());
assertEquals(2, schema.properties().size());
} finally {
FileUtils.deleteQuietly(rawSchema);
FileUtils.deleteQuietly(schemaFile);
}
}
@Test
public void testDropWithoutTable() throws Exception {
thrown.expect(UserException.class);
thrown.expectMessage("PARSE ERROR: Encountered \"<EOF>\"");
run("drop schema");
}
@Test
public void testDropForMissingTable() throws Exception {
thrown.expect(UserException.class);
thrown.expectMessage("VALIDATION ERROR: Table [t] was not found");
run("drop schema for table dfs.t");
}
@Test
public void testDropForTemporaryTable() throws Exception {
String table = "temp_drop";
try {
run("create temporary table %s as select 'a' as c from (values(1))", table);
thrown.expect(UserException.class);
thrown.expectMessage(String.format("VALIDATION ERROR: Indicated table [%s] is temporary table", table));
run("drop schema for table %s", table);
} finally {
run("drop table if exists %s", table);
}
}
@Test
public void testDropForImmutableSchema() throws Exception {
String table = "sys.version";
thrown.expect(UserException.class);
thrown.expectMessage("VALIDATION ERROR: Unable to create or drop objects. Schema [sys] is immutable");
run("drop schema for table %s", table);
}
@Test
public void testDropForMissingSchema() throws Exception {
String table = "dfs.tmp.table_with_missing_schema";
try {
run("create table %s as select 'a' as c from (values(1))", table);
thrown.expect(UserException.class);
thrown.expectMessage(String.format("VALIDATION ERROR: Schema [%s] " +
"does not exist in table [%s] root directory", SchemaProvider.DEFAULT_SCHEMA_NAME, table));
run("drop schema for table %s", table);
} finally {
run("drop table if exists %s", table);
}
}
@Test
public void testDropForMissingSchemaIfExists() throws Exception {
String table = "dfs.tmp.table_with_missing_schema_if_exists";
try {
run("create table %s as select 'a' as c from (values(1))", table);
testBuilder()
.sqlQuery("drop schema if exists for table %s", table)
.unOrdered()
.baselineColumns("ok", "summary")
.baselineValues(false, String.format("Schema [%s] does not exist in table [%s] root directory",
SchemaProvider.DEFAULT_SCHEMA_NAME, table))
.go();
} finally {
run("drop table if exists %s", table);
}
}
@Test
public void testSuccessfulDrop() throws Exception {
String tableName = "table_for_successful_drop";
String table = String.format("dfs.tmp.%s", tableName);
try {
run("create table %s as select 'a' as c from (values(1))", table);
File schemaPath = Paths.get(dirTestWatcher.getDfsTestTmpDir().getPath(),
tableName, SchemaProvider.DEFAULT_SCHEMA_NAME).toFile();
assertFalse(schemaPath.exists());
testBuilder()
.sqlQuery("create schema (c varchar not null) for table %s", table)
.unOrdered()
.baselineColumns("ok", "summary")
.baselineValues(true, String.format("Created schema for [%s]", table))
.go();
assertTrue(schemaPath.exists());
testBuilder()
.sqlQuery("drop schema for table %s", table)
.unOrdered()
.baselineColumns("ok", "summary")
.baselineValues(true, String.format("Dropped schema for table [%s]", table))
.go();
assertFalse(schemaPath.exists());
} finally {
run("drop table if exists %s", table);
}
}
@Test
public void testDescribeForMissingTable() throws Exception {
thrown.expect(UserException.class);
thrown.expectMessage("VALIDATION ERROR: Table [t] was not found");
run("describe schema for table dfs.t");
}
@Test
public void testDescribeForMissingSchema() throws Exception {
String table = "dfs.tmp.table_describe_with_missing_schema";
try {
run("create table %s as select 'a' as c from (values(1))", table);
testBuilder()
.sqlQuery("describe schema for table %s", table)
.unOrdered()
.baselineColumns("ok", "summary")
.baselineValues(false, String.format("Schema for table [%s] is absent", table))
.go();
} finally {
run("drop table if exists %s", table);
}
}
@Test
public void testDescribeDefault() throws Exception {
String tableName = "table_describe_default";
String table = String.format("dfs.tmp.%s", tableName);
try {
run("create table %s as select 'a' as c from (values(1))", table);
run("create schema (col int) for table %s", table);
File schemaFile = Paths.get(dirTestWatcher.getDfsTestTmpDir().getPath(),
tableName, SchemaProvider.DEFAULT_SCHEMA_NAME).toFile();
SchemaProvider schemaProvider = new PathSchemaProvider(new Path(schemaFile.getPath()));
SchemaContainer schemaContainer = schemaProvider.read();
String schema = PathSchemaProvider.WRITER.writeValueAsString(schemaContainer);
testBuilder()
.sqlQuery("describe schema for table %s", table)
.unOrdered()
.baselineColumns("schema")
.baselineValues(schema)
.go();
} finally {
run("drop table if exists %s", table);
}
}
@Test
public void testDescribeJson() throws Exception {
String tableName = "table_describe_json";
String table = String.format("dfs.tmp.%s", tableName);
try {
run("create table %s as select 'a' as c from (values(1))", table);
run("create schema (col int) for table %s", table);
File schemaFile = Paths.get(dirTestWatcher.getDfsTestTmpDir().getPath(),
tableName, SchemaProvider.DEFAULT_SCHEMA_NAME).toFile();
SchemaProvider schemaProvider = new PathSchemaProvider(new Path(schemaFile.getPath()));
SchemaContainer schemaContainer = schemaProvider.read();
String schema = PathSchemaProvider.WRITER.writeValueAsString(schemaContainer);
testBuilder()
.sqlQuery("describe schema for table %s as json", table)
.unOrdered()
.baselineColumns("schema")
.baselineValues(schema)
.go();
} finally {
run("drop table if exists %s", table);
}
}
@Test
public void testDescribeStatement() throws Exception {
String tableName = "table_describe_statement";
String table = String.format("dfs.tmp.%s", tableName);
try {
run("create table %s as select 'a' as c from (values(1))", table);
String statement = "CREATE OR REPLACE SCHEMA \n"
+ "(\n"
+ "`col1` DATE FORMAT 'yyyy-MM-dd' DEFAULT '-1', \n"
+ "`col2` INT NOT NULL FORMAT 'yyyy-MM-dd' PROPERTIES { 'drill.strict' = 'true', 'some_column_prop' = 'some_column_val' }\n"
+ ") \n"
+ "FOR TABLE dfs.tmp.`table_describe_statement` \n"
+ "PROPERTIES (\n"
+ "'drill.strict' = 'false', \n"
+ "'some_schema_prop' = 'some_schema_val'\n"
+ ")";
run(statement);
testBuilder()
.sqlQuery("describe schema for table %s as statement", table)
.unOrdered()
.baselineColumns("schema")
.baselineValues(statement)
.go();
} finally {
run("drop table if exists %s", table);
}
}
@Test
public void testDescribeWithoutColumns() throws Exception {
String tableName = "table_describe_statement_without_columns";
String table = String.format("dfs.tmp.%s", tableName);
try {
run("create table %s as select 'a' as c from (values(1))", table);
String statement = "CREATE OR REPLACE SCHEMA \n"
+ "() \n"
+ "FOR TABLE dfs.tmp.`table_describe_statement_without_columns` \n"
+ "PROPERTIES (\n"
+ "'drill.strict' = 'false', \n"
+ "'some_schema_prop' = 'some_schema_val'\n"
+ ")";
run(statement);
testBuilder()
.sqlQuery("describe schema for table %s as statement", table)
.unOrdered()
.baselineColumns("schema")
.baselineValues(statement)
.go();
} finally {
run("drop table if exists %s", table);
}
}
@Test
public void testAlterAddAbsentKeywords() throws Exception {
thrown.expect(UserException.class);
thrown.expectMessage("PARSE ERROR");
run("alter schema for table abc add");
}
@Test
public void testAlterAddAbsentSchemaForTable() throws Exception {
String tableName = "table_alter_schema_add_absent_schema";
String table = String.format("dfs.tmp.%s", tableName);
try {
run("create table %s as select 'a' as c from (values(1))", table);
thrown.expect(UserException.class);
thrown.expectMessage("RESOURCE ERROR: Schema does not exist");
run("alter schema for table %s add columns (col int)", table);
} finally {
run("drop table if exists %s", table);
}
}
@Test
public void testAlterAddAbsentSchemaPath() throws Exception {
thrown.expect(UserException.class);
thrown.expectMessage("RESOURCE ERROR: Schema does not exist");
run("alter schema path '%s' add columns (col int)",
new File(dirTestWatcher.getTmpDir(), "absent.schema").getPath());
}
@Test
public void testAlterAddDuplicateColumn() throws Exception {
File tmpDir = dirTestWatcher.getTmpDir();
File schemaFile = new File(tmpDir, "schema_for_duplicate_column.schema");
assertFalse(schemaFile.exists());
try {
run("create schema (col int) path '%s'", schemaFile.getPath());
thrown.expect(UserException.class);
thrown.expectMessage("VALIDATION ERROR");
run("alter schema path '%s' add columns (col varchar)", schemaFile.getPath());
} finally {
FileUtils.deleteQuietly(schemaFile);
}
}
@Test
public void testAlterAddDuplicateProperty() throws Exception {
File tmpDir = dirTestWatcher.getTmpDir();
File schemaFile = new File(tmpDir, "schema_for_duplicate_property.schema");
assertFalse(schemaFile.exists());
try {
run("create schema (col int) path '%s' properties ('prop' = 'a')", schemaFile.getPath());
thrown.expect(UserException.class);
thrown.expectMessage("VALIDATION ERROR");
run("alter schema path '%s' add properties ('prop' = 'b')", schemaFile.getPath());
} finally {
FileUtils.deleteQuietly(schemaFile);
}
}
@Test
public void testAlterAddColumns() throws Exception {
File tmpDir = dirTestWatcher.getTmpDir();
File schemaFile = new File(tmpDir, "alter_schema_add_columns.schema");
assertFalse(schemaFile.exists());
try {
run("create schema (col1 int) path '%s' properties ('prop1' = 'a')", schemaFile.getPath());
testBuilder()
.sqlQuery("alter schema path '%s' add " +
"columns (col2 varchar) ", schemaFile.getPath())
.unOrdered()
.baselineColumns("ok", "summary")
.baselineValues(true, String.format("Schema for [%s] was updated", schemaFile.getPath()))
.go();
SchemaProvider schemaProvider = new PathSchemaProvider(new Path(schemaFile.getPath()));
TupleMetadata schema = schemaProvider.read().getSchema();
assertEquals(2, schema.size());
assertEquals("col1", schema.fullName(0));
assertEquals("col2", schema.fullName(1));
assertEquals(1, schema.properties().size());
} finally {
FileUtils.deleteQuietly(schemaFile);
}
}
@Test
public void testAlterAddProperties() throws Exception {
File tmpDir = dirTestWatcher.getTmpDir();
File schemaFile = new File(tmpDir, "alter_schema_add_properties.schema");
assertFalse(schemaFile.exists());
try {
run("create schema (col1 int) path '%s' properties ('prop1' = 'a')", schemaFile.getPath());
testBuilder()
.sqlQuery("alter schema path '%s' add " +
"properties ('prop2' = 'b', 'prop3' = 'c')", schemaFile.getPath())
.unOrdered()
.baselineColumns("ok", "summary")
.baselineValues(true, String.format("Schema for [%s] was updated", schemaFile.getPath()))
.go();
SchemaProvider schemaProvider = new PathSchemaProvider(new Path(schemaFile.getPath()));
TupleMetadata schema = schemaProvider.read().getSchema();
assertEquals(1, schema.size());
Map<String, String> expectedProperties = new HashMap<>();
expectedProperties.put("prop1", "a");
expectedProperties.put("prop2", "b");
expectedProperties.put("prop3", "c");
assertEquals(expectedProperties, schema.properties());
} finally {
FileUtils.deleteQuietly(schemaFile);
}
}
@Test
public void testAlterAddSuccess() throws Exception {
File tmpDir = dirTestWatcher.getTmpDir();
File schemaFile = new File(tmpDir, "alter_schema_add_success.schema");
assertFalse(schemaFile.exists());
try {
run("create schema (col1 int) path '%s' properties ('prop1' = 'a')", schemaFile.getPath());
testBuilder()
.sqlQuery("alter schema path '%s' add " +
"columns (col2 varchar, col3 boolean) " +
"properties ('prop2' = 'b', 'prop3' = 'c')", schemaFile.getPath())
.unOrdered()
.baselineColumns("ok", "summary")
.baselineValues(true, String.format("Schema for [%s] was updated", schemaFile.getPath()))
.go();
SchemaProvider schemaProvider = new PathSchemaProvider(new Path(schemaFile.getPath()));
TupleMetadata schema = schemaProvider.read().getSchema();
assertEquals(3, schema.size());
assertEquals("col1", schema.fullName(0));
assertEquals("col2", schema.fullName(1));
assertEquals("col3", schema.fullName(2));
Map<String, String> expectedProperties = new HashMap<>();
expectedProperties.put("prop1", "a");
expectedProperties.put("prop2", "b");
expectedProperties.put("prop3", "c");
assertEquals(expectedProperties, schema.properties());
} finally {
FileUtils.deleteQuietly(schemaFile);
}
}
@Test
public void testAlterAddForTable() throws Exception {
String tableName = "table_for_alter_add";
String table = String.format("dfs.tmp.%s", tableName);
try {
run("create table %s as select 'a' as c from (values(1))", table);
File schemaPath = Paths.get(dirTestWatcher.getDfsTestTmpDir().getPath(),
tableName, SchemaProvider.DEFAULT_SCHEMA_NAME).toFile();
run("create schema (col int) for table %s properties ('prop1' = 'a')", table);
testBuilder()
.sqlQuery("alter schema for table %s add or replace " +
"columns (col2 varchar, col3 boolean) " +
"properties ('prop2' = 'd', 'prop3' = 'c')", table)
.unOrdered()
.baselineColumns("ok", "summary")
.baselineValues(true, String.format("Schema for [%s] was updated", table))
.go();
SchemaProvider schemaProvider = new PathSchemaProvider(new Path(schemaPath.getPath()));
assertTrue(schemaProvider.exists());
TupleMetadata schema = schemaProvider.read().getSchema();
assertEquals(3, schema.size());
assertEquals(3, schema.properties().size());
} finally {
run("drop table if exists %s", table);
}
}
@Test
public void testAlterReplace() throws Exception {
File tmpDir = dirTestWatcher.getTmpDir();
File schemaFile = new File(tmpDir, "alter_schema_replace_success.schema");
assertFalse(schemaFile.exists());
try {
run("create schema (col1 int, col2 int) path '%s' " +
"properties ('prop1' = 'a', 'prop2' = 'b')", schemaFile.getPath());
testBuilder()
.sqlQuery("alter schema path '%s' add or replace " +
"columns (col2 varchar, col3 boolean) " +
"properties ('prop2' = 'd', 'prop3' = 'c')", schemaFile.getPath())
.unOrdered()
.baselineColumns("ok", "summary")
.baselineValues(true, String.format("Schema for [%s] was updated", schemaFile.getPath()))
.go();
SchemaProvider schemaProvider = new PathSchemaProvider(new Path(schemaFile.getPath()));
TupleMetadata schema = schemaProvider.read().getSchema();
assertEquals(3, schema.size());
assertEquals("col1", schema.fullName(0));
assertEquals("col2", schema.fullName(1));
assertEquals(TypeProtos.MinorType.VARCHAR, schema.metadata("col2").type());
assertEquals("col3", schema.fullName(2));
Map<String, String> expectedProperties = new HashMap<>();
expectedProperties.put("prop1", "a");
expectedProperties.put("prop2", "d");
expectedProperties.put("prop3", "c");
assertEquals(expectedProperties, schema.properties());
} finally {
FileUtils.deleteQuietly(schemaFile);
}
}
@Test
public void testAlterRemoveAbsentKeywords() throws Exception {
thrown.expect(UserException.class);
thrown.expectMessage("PARSE ERROR");
run("alter schema for table abc remove");
}
@Test
public void testAlterRemoveAbsentSchemaForTable() throws Exception {
String tableName = "table_alter_schema_remove_absent_schema";
String table = String.format("dfs.tmp.%s", tableName);
try {
run("create table %s as select 'a' as c from (values(1))", table);
thrown.expect(UserException.class);
thrown.expectMessage("RESOURCE ERROR: Schema does not exist");
run("alter schema for table %s remove columns (col)", table);
} finally {
run("drop table if exists %s", table);
}
}
@Test
public void testAlterRemoveAbsentSchemaPath() throws Exception {
thrown.expect(UserException.class);
thrown.expectMessage("RESOURCE ERROR: Schema does not exist");
run("alter schema path '%s' remove columns (col)",
new File(dirTestWatcher.getTmpDir(), "absent.schema").getPath());
}
@Test
public void testAlterRemoveColumns() throws Exception {
File tmpDir = dirTestWatcher.getTmpDir();
File schemaFile = new File(tmpDir, "alter_schema_remove_columns.schema");
assertFalse(schemaFile.exists());
try {
run("create schema (col1 int, col2 varchar, col3 boolean, col4 int) path '%s' " +
"properties ('prop1' = 'a', 'prop2' = 'b', 'prop3' = 'c', 'prop4' = 'd')", schemaFile.getPath());
testBuilder()
.sqlQuery("alter schema path '%s' remove " +
"columns (col2, col4) ", schemaFile.getPath())
.unOrdered()
.baselineColumns("ok", "summary")
.baselineValues(true, String.format("Schema for [%s] was updated", schemaFile.getPath()))
.go();
SchemaProvider schemaProvider = new PathSchemaProvider(new Path(schemaFile.getPath()));
TupleMetadata schema = schemaProvider.read().getSchema();
assertEquals(2, schema.size());
assertEquals("col1", schema.fullName(0));
assertEquals("col3", schema.fullName(1));
assertEquals(4, schema.properties().size());
} finally {
FileUtils.deleteQuietly(schemaFile);
}
}
@Test
public void testAlterRemoveProperties() throws Exception {
File tmpDir = dirTestWatcher.getTmpDir();
File schemaFile = new File(tmpDir, "alter_schema_remove_success.schema");
assertFalse(schemaFile.exists());
try {
run("create schema (col1 int, col2 varchar, col3 boolean, col4 int) path '%s' " +
"properties ('prop1' = 'a', 'prop2' = 'b', 'prop3' = 'c', 'prop4' = 'd')", schemaFile.getPath());
testBuilder()
.sqlQuery("alter schema path '%s' remove " +
"properties ('prop2', 'prop4')", schemaFile.getPath())
.unOrdered()
.baselineColumns("ok", "summary")
.baselineValues(true, String.format("Schema for [%s] was updated", schemaFile.getPath()))
.go();
SchemaProvider schemaProvider = new PathSchemaProvider(new Path(schemaFile.getPath()));
TupleMetadata schema = schemaProvider.read().getSchema();
assertEquals(4, schema.size());
Map<String, String> expectedProperties = new HashMap<>();
expectedProperties.put("prop1", "a");
expectedProperties.put("prop3", "c");
assertEquals(expectedProperties, schema.properties());
} finally {
FileUtils.deleteQuietly(schemaFile);
}
}
@Test
public void testAlterRemoveSuccess() throws Exception {
File tmpDir = dirTestWatcher.getTmpDir();
File schemaFile = new File(tmpDir, "alter_schema_remove_success.schema");
assertFalse(schemaFile.exists());
try {
run("create schema (col1 int, col2 varchar, col3 boolean, col4 int) path '%s' " +
"properties ('prop1' = 'a', 'prop2' = 'b', 'prop3' = 'c', 'prop4' = 'd')", schemaFile.getPath());
testBuilder()
.sqlQuery("alter schema path '%s' remove " +
"columns (col2, col4) " +
"properties ('prop2', 'prop4')", schemaFile.getPath())
.unOrdered()
.baselineColumns("ok", "summary")
.baselineValues(true, String.format("Schema for [%s] was updated", schemaFile.getPath()))
.go();
SchemaProvider schemaProvider = new PathSchemaProvider(new Path(schemaFile.getPath()));
TupleMetadata schema = schemaProvider.read().getSchema();
assertEquals(2, schema.size());
assertEquals("col1", schema.fullName(0));
assertEquals("col3", schema.fullName(1));
Map<String, String> expectedProperties = new HashMap<>();
expectedProperties.put("prop1", "a");
expectedProperties.put("prop3", "c");
assertEquals(expectedProperties, schema.properties());
} finally {
FileUtils.deleteQuietly(schemaFile);
}
}
@Test
public void testAlterRemoveForTable() throws Exception {
String tableName = "table_for_alter_add";
String table = String.format("dfs.tmp.%s", tableName);
try {
run("create table %s as select 'a' as c from (values(1))", table);
File schemaPath = Paths.get(dirTestWatcher.getDfsTestTmpDir().getPath(),
tableName, SchemaProvider.DEFAULT_SCHEMA_NAME).toFile();
run("create schema (col1 int, col2 varchar, col3 boolean, col4 int) for table %s " +
"properties ('prop1' = 'a', 'prop2' = 'b', 'prop3' = 'c', 'prop4' = 'd')", table);
testBuilder()
.sqlQuery("alter schema for table %s remove " +
"columns (col2, col4) " +
"properties ('prop2', 'prop4')", table)
.unOrdered()
.baselineColumns("ok", "summary")
.baselineValues(true, String.format("Schema for [%s] was updated", table))
.go();
SchemaProvider schemaProvider = new PathSchemaProvider(new Path(schemaPath.getPath()));
assertTrue(schemaProvider.exists());
TupleMetadata schema = schemaProvider.read().getSchema();
assertEquals(2, schema.size());
assertEquals(2, schema.properties().size());
} finally {
run("drop table if exists %s", table);
}
}
}