use of io.prestosql.sql.tree.TableElement in project hetu-core by openlookeng.
the class TestCreateTableTask method testCreateWithUnsupportedConnectorThrowsWhenNotNull.
@Test(expectedExceptions = SemanticException.class, expectedExceptionsMessageRegExp = ".*does not support non-null column for column name 'b'")
public void testCreateWithUnsupportedConnectorThrowsWhenNotNull() {
List<TableElement> inputColumns = ImmutableList.of(new ColumnDefinition(identifier("a"), "DATE", true, emptyList(), Optional.empty()), new ColumnDefinition(identifier("b"), "VARCHAR", false, emptyList(), Optional.empty()), new ColumnDefinition(identifier("c"), "VARBINARY", false, emptyList(), Optional.empty()));
CreateTable statement = new CreateTable(QualifiedName.of("test_table"), inputColumns, true, ImmutableList.of(), Optional.empty());
getFutureValue(new CreateTableTask().internalExecute(statement, metadata, new AllowAllAccessControl(), testSession, emptyList()));
}
use of io.prestosql.sql.tree.TableElement in project hetu-core by openlookeng.
the class HiveAstBuilder method visitCreateTableLike.
@Override
public Node visitCreateTableLike(HiveSqlParser.CreateTableLikeContext context) {
List<TableElement> elements = new ArrayList<>();
LikeClause likeClause = new LikeClause(getQualifiedName(context.likeTableName), Optional.of(LikeClause.PropertiesOption.EXCLUDING));
elements.add(likeClause);
addDiff(DiffType.INSERTED, null, "EXCLUDING PROPERTIES", "add keyword [EXCLUDING PROPERTIES]");
List<Property> properties = new ArrayList<>();
if (context.EXTERNAL() != null) {
if (context.LOCATION() == null) {
addDiff(DiffType.UNSUPPORTED, context.EXTERNAL().getText(), "[EXTERNAL] should be used with location");
throw unsupportedError(ErrorType.UNSUPPORTED_STATEMENT, "External attribute should be used with location", context);
}
Identifier name = new Identifier("external");
Expression value = new Identifier("true");
properties.add(new Property(name, value));
addDiff(DiffType.MODIFIED, context.EXTERNAL().getText(), "external = true", "[EXTERNAL] is formatted");
}
if (context.LOCATION() != null) {
Identifier name = new Identifier("location");
Expression value = (StringLiteral) visit(context.location);
properties.add(new Property(name, value));
addDiff(DiffType.MODIFIED, context.LOCATION().getText(), LOCATION + " = " + value, "[LOCATION] is formatted");
}
return new CreateTable(getLocation(context), getQualifiedName(context.tableName), elements, context.EXISTS() != null, properties, Optional.empty());
}
use of io.prestosql.sql.tree.TableElement in project hetu-core by openlookeng.
the class HiveAstBuilder method visitCreateTable.
@Override
public Node visitCreateTable(HiveSqlParser.CreateTableContext context) {
if (context.TEMPORARY() != null) {
addDiff(DiffType.UNSUPPORTED, context.TEMPORARY().getText(), "[TEMPORARY] is not supported");
throw unsupportedError(ErrorType.UNSUPPORTED_STATEMENT, "Unsupported statement: CREATE TEMPORARY TABLE", context);
}
if (context.constraintSpecification() != null) {
HiveSqlParser.ConstraintSpecificationContext constraintContext = context.constraintSpecification();
if (constraintContext.PRIMARY() != null) {
addDiff(DiffType.UNSUPPORTED, constraintContext.PRIMARY().getText(), "[PRIMARY KEY] is not supported");
addDiff(DiffType.UNSUPPORTED, constraintContext.KEY().getText(), null);
}
if (constraintContext.CONSTRAINT() != null) {
addDiff(DiffType.UNSUPPORTED, constraintContext.CONSTRAINT().getText(), "[CONSTRAINT] is not supported");
}
throw unsupportedError(ErrorType.UNSUPPORTED_STATEMENT, "Unsupported constraint statement", context.constraintSpecification());
}
Optional<String> comment = Optional.empty();
if (context.COMMENT() != null) {
comment = Optional.of(((StringLiteral) visit(context.string(0))).getValue());
}
List<Property> properties = new ArrayList<>();
if (context.TRANSACTIONAL() != null) {
Identifier name = new Identifier("transactional");
Expression value = new Identifier("true");
properties.add(new Property(name, value));
addDiff(DiffType.MODIFIED, context.TRANSACTIONAL().getText(), "transactional = true", "[TRANSACTIONAL] is formatted");
}
List<TableElement> elements = getTableElements(context.tableElement());
if (context.PARTITIONED() != null) {
Identifier name = new Identifier("partitioned_by");
List<ColumnDefinition> columnDefinitions = getColumnDefinitions(context.partitionedBy().columnDefinition());
List<Expression> expressions = new ArrayList<>();
Iterator<ColumnDefinition> iterator = columnDefinitions.iterator();
while (iterator.hasNext()) {
ColumnDefinition iter = iterator.next();
expressions.add(new StringLiteral(iter.getName().getValue()));
elements.add(new ColumnDefinition(iter.getName(), iter.getType(), true, emptyList(), Optional.empty()));
}
Expression value = new ArrayConstructor(expressions);
properties.add(new Property(name, value));
addDiff(DiffType.MODIFIED, context.PARTITIONED().getText(), PARTITIONED_BY, "[PARTITIONED BY] is formatted");
}
if (context.CLUSTERED() != null) {
Identifier name = new Identifier("bucketed_by");
List<Expression> quotedExpressions = new ArrayList<>();
List<Expression> expressions = getExpressions(context.clusteredBy().expression());
for (int i = 0; i < expressions.size(); i++) {
quotedExpressions.add(new StringLiteral(expressions.get(i).toString()));
}
Expression value = new ArrayConstructor(quotedExpressions);
properties.add(new Property(name, value));
addDiff(DiffType.MODIFIED, context.CLUSTERED().getText(), "bucketed_by", "[CLUSTERED BY] is formatted");
}
if (context.SORTED() != null) {
Identifier name = new Identifier("sorted_by");
List<Expression> expressions = new ArrayList<>();
List<HiveSqlParser.SortItemContext> sortItemContexts = context.sortedBy().sortItem();
for (int i = 0; i < sortItemContexts.size(); i++) {
HiveSqlParser.SortItemContext sortItemContext = sortItemContexts.get(i);
String sortedBy = sortItemContext.expression().getText();
if (sortItemContext.ordering != null) {
sortedBy += " " + sortItemContext.ordering.getText();
}
expressions.add(new StringLiteral(sortedBy));
}
Expression value = new ArrayConstructor(expressions);
properties.add(new Property(name, value));
addDiff(DiffType.MODIFIED, context.SORTED().getText(), SORTED_BY, "[SORTED BY] is formatted");
}
if (context.INTO() != null) {
Identifier name = new Identifier("bucket_count");
Expression value = (Expression) visit(context.bucketcount);
properties.add(new Property(name, value));
addDiff(DiffType.MODIFIED, context.INTO().getText(), "bucket_count", "[INTO BUCKETS] is formatted");
}
if (context.SKEWED() != null) {
addDiff(DiffType.UNSUPPORTED, context.SKEWED().getText(), "[SKEWED] is not supported");
throw unsupportedError(ErrorType.UNSUPPORTED_STATEMENT, "Unsupported statement: SKEWED", context.columnAliases());
}
if (context.ROW() != null) {
addDiff(DiffType.UNSUPPORTED, context.ROW().getText(), "[ROW FORMAT] is not supported");
throw unsupportedError(ErrorType.UNSUPPORTED_STATEMENT, "Unsupported statement: ROW FORMAT", context.rowFormat());
}
if (context.STORED() != null) {
addDiff(DiffType.UNSUPPORTED, context.STORED().getText(), "[STORED BY] is not supported");
throw unsupportedError(ErrorType.UNSUPPORTED_STATEMENT, "Unsupported statement: STORED BY", context.storedBy);
}
if (context.stored_as != null) {
Identifier name = new Identifier("format");
String storedAsString = ((Identifier) visit(context.stored_as)).getValue();
Expression value = new StringLiteral(getFileFormat(storedAsString));
properties.add(new Property(name, value));
addDiff(DiffType.MODIFIED, context.STORED_AS(0).getText(), FORMAT, "[STORED AS] is formatted");
}
if (context.EXTERNAL() != null) {
if (context.LOCATION() == null) {
addDiff(DiffType.UNSUPPORTED, context.EXTERNAL().getText(), "[EXTERNAL] should be used with location");
throw unsupportedError(ErrorType.UNSUPPORTED_STATEMENT, "Unsupported statement: External attribute should be used with location", context);
}
Identifier name = new Identifier("external");
Expression value = new Identifier("true");
properties.add(new Property(name, value));
addDiff(DiffType.MODIFIED, context.EXTERNAL().getText(), "external = true", "[EXTERNAL] is formatted");
}
if (context.LOCATION() != null) {
Identifier name = new Identifier("location");
Expression value = (StringLiteral) visit(context.location);
properties.add(new Property(name, value));
addDiff(DiffType.MODIFIED, context.LOCATION().getText(), LOCATION + " = " + value, "[LOCATION] is formatted");
}
if (context.TBLPROPERTIES() != null) {
List<Property> tblProperties = visit(context.tableProperties.property(), Property.class);
for (int i = 0; i < tblProperties.size(); i++) {
Property property = tblProperties.get(i);
if (property.getName().getValue().equalsIgnoreCase("transactional")) {
Identifier name = new Identifier("transactional");
Expression value = new Identifier(unquote(property.getValue().toString()));
properties.add(new Property(name, value));
addDiff(DiffType.MODIFIED, property.getName().getValue(), "transactional = ", "[TRANSACTIONAL] is formatted");
} else {
addDiff(DiffType.UNSUPPORTED, property.getName().getValue(), "[TBLPROPERTIES] has unsupported properties");
throw unsupportedError(ErrorType.UNSUPPORTED_STATEMENT, format("Unsupported attribute: %s", property.getName().getValue()), context.tableProperties);
}
}
}
return new CreateTable(getLocation(context), getQualifiedName(context.qualifiedName()), elements, context.EXISTS() != null, properties, comment);
}
use of io.prestosql.sql.tree.TableElement in project hetu-core by openlookeng.
the class ImpalaAstBuilder method visitCreateTable.
@Override
public Node visitCreateTable(ImpalaSqlParser.CreateTableContext context) {
Optional<String> comment = Optional.empty();
if (context.COMMENT() != null) {
comment = Optional.of(((StringLiteral) visit(context.comment)).getValue());
}
List<Property> properties = new ArrayList<>();
// external table
if (context.EXTERNAL() != null) {
if (context.LOCATION() == null) {
throw unsupportedError(ErrorType.SYNTAX_ERROR, "External attribute should be used with location", context);
}
Identifier name = new Identifier("external");
Expression value = new Identifier("true");
properties.add(new Property(name, value));
addDiff(DiffType.MODIFIED, context.EXTERNAL().getText(), "external = true", "[external] is formatted");
}
// handle partitioned by
List<TableElement> elements = getTableElements(context.tableElement());
if (context.AS() == null && elements.size() == 0) {
throw unsupportedError(ErrorType.SYNTAX_ERROR, "Create table should specify at least one column.", context);
}
if (context.PARTITIONED() != null) {
List<ColumnDefinition> columnDefinitions = getColumnDefinitions(context.partitionedBy().columnDefinition());
List<Expression> expressions = new ArrayList<>();
Iterator<ColumnDefinition> iterator = columnDefinitions.iterator();
while (iterator.hasNext()) {
ColumnDefinition iter = iterator.next();
expressions.add(new StringLiteral(iter.getName().getValue()));
// add the partitioned_by column to table columns
elements.add(new ColumnDefinition(iter.getName(), iter.getType(), true, emptyList(), Optional.empty()));
}
Expression value = new ArrayConstructor(expressions);
properties.add(new Property(new Identifier(PARTITIONED_BY), value));
addDiff(DiffType.MODIFIED, context.PARTITIONED().getText(), PARTITIONED_BY, "[partitioned by] is formatted");
}
// handle sort by
if (context.SORT() != null) {
List<Expression> quotedExpressions = new ArrayList<>();
List<Expression> expressions = getExpressions(context.sortedBy().expression());
for (int i = 0; i < expressions.size(); i++) {
quotedExpressions.add(new StringLiteral(expressions.get(i).toString()));
}
Expression value = new ArrayConstructor(quotedExpressions);
properties.add(new Property(new Identifier(SORTED_BY), value));
addDiff(DiffType.MODIFIED, context.SORT().getText(), SORTED_BY, "[sorted by] is formatted");
}
// row format
if (context.ROW() != null && context.FORMAT() != null) {
addDiff(DiffType.UNSUPPORTED, context.ROW().getText(), "[ROW FORMAT] is not supported");
addDiff(DiffType.UNSUPPORTED, context.FORMAT().getText(), null);
throw unsupportedError(ErrorType.UNSUPPORTED_KEYWORDS, "ROW FORMAT", context);
}
// serde properties
if (context.SERDEPROPERTIES() != null) {
addDiff(DiffType.UNSUPPORTED, context.SERDEPROPERTIES().getText(), "[WITH SERDEPROPERTIES] is not supported");
throw unsupportedError(ErrorType.UNSUPPORTED_KEYWORDS, "WITH SERDEPROPERTIES", context);
}
// stored as
if (context.STORED_AS() != null) {
String storedAsString = ((Identifier) visit(context.stored_as)).getValue();
Expression value = new StringLiteral(getFileFormat(storedAsString));
properties.add(new Property(new Identifier(FORMAT), value));
addDiff(DiffType.MODIFIED, context.STORED_AS().getText(), FORMAT, "[stored as] is formatted");
}
// location
if (context.LOCATION() != null) {
Expression value = (StringLiteral) visit(context.location);
properties.add(new Property(new Identifier(LOCATION), value));
addDiff(DiffType.MODIFIED, context.LOCATION().getText(), LOCATION + " = " + value, "[location] is formatted");
}
// cached in
if (context.CACHED() != null) {
addDiff(DiffType.UNSUPPORTED, context.CACHED().getText(), "[CACHED IN] is not supported");
throw unsupportedError(ErrorType.UNSUPPORTED_KEYWORDS, "CACHED IN", context);
}
// table properties
if (context.TBLPROPERTIES() != null) {
List<Property> tblProperties = visit(context.tblProp.property(), Property.class);
for (int i = 0; i < tblProperties.size(); i++) {
Property property = tblProperties.get(i);
if (property.getName().getValue().equalsIgnoreCase(TRANSACTIONAL)) {
Identifier name = new Identifier(TRANSACTIONAL);
Expression value = new Identifier(unquote(property.getValue().toString()));
properties.add(new Property(name, value));
addDiff(DiffType.MODIFIED, property.getName().getValue(), "transactional = ", "[transactional] is formatted");
} else {
addDiff(DiffType.UNSUPPORTED, property.getName().getValue(), "[TBLPROPERTIES] has unsupported properties");
throw unsupportedError(ErrorType.UNSUPPORTED_ATTRIBUTE, property.getName().getValue(), context.tblProp);
}
}
}
// create table as
if (context.AS() != null) {
return new CreateTableAsSelect(getLocation(context), getQualifiedName(context.tblName), (Query) visit(context.query()), context.EXISTS() != null, properties, true, Optional.empty(), comment);
}
return new CreateTable(getLocation(context), getQualifiedName(context.tblName), elements, context.EXISTS() != null, properties, comment);
}
use of io.prestosql.sql.tree.TableElement in project hetu-core by openlookeng.
the class CreateTableTask method internalExecute.
@VisibleForTesting
public ListenableFuture<?> internalExecute(CreateTable statement, Metadata metadata, AccessControl accessControl, Session session, List<Expression> parameters) {
checkArgument(!statement.getElements().isEmpty(), "no columns for table");
QualifiedObjectName tableName = createQualifiedObjectName(session, statement, statement.getName());
Optional<TableHandle> tableHandle = metadata.getTableHandle(session, tableName);
if (tableHandle.isPresent()) {
if (!statement.isNotExists()) {
throw new SemanticException(TABLE_ALREADY_EXISTS, statement, "Table '%s' already exists", tableName);
}
return immediateFuture(null);
}
CatalogName catalogName = metadata.getCatalogHandle(session, tableName.getCatalogName()).orElseThrow(() -> new PrestoException(NOT_FOUND, "Catalog does not exist: " + tableName.getCatalogName()));
LinkedHashMap<String, ColumnMetadata> columns = new LinkedHashMap<>();
Map<String, Object> inheritedProperties = ImmutableMap.of();
boolean includingProperties = false;
for (TableElement element : statement.getElements()) {
if (element instanceof ColumnDefinition) {
ColumnDefinition column = (ColumnDefinition) element;
String name = column.getName().getValue().toLowerCase(Locale.ENGLISH);
Type type;
try {
type = metadata.getType(parseTypeSignature(column.getType()));
} catch (TypeNotFoundException e) {
throw new SemanticException(TYPE_MISMATCH, element, "Unknown type '%s' for column '%s'", column.getType(), column.getName());
}
if (type.equals(UNKNOWN)) {
throw new SemanticException(TYPE_MISMATCH, element, "Unknown type '%s' for column '%s'", column.getType(), column.getName());
}
if (columns.containsKey(name)) {
throw new SemanticException(DUPLICATE_COLUMN_NAME, column, "Column name '%s' specified more than once", column.getName());
}
if (!column.isNullable() && !metadata.getConnectorCapabilities(session, catalogName).contains(NOT_NULL_COLUMN_CONSTRAINT)) {
throw new SemanticException(NOT_SUPPORTED, column, "Catalog '%s' does not support non-null column for column name '%s'", catalogName.getCatalogName(), column.getName());
}
Map<String, Expression> sqlProperties = mapFromProperties(column.getProperties());
Map<String, Object> columnProperties = metadata.getColumnPropertyManager().getProperties(catalogName, tableName.getCatalogName(), sqlProperties, session, metadata, parameters);
columns.put(name, new ColumnMetadata(name, type, column.isNullable(), column.getComment().orElse(null), null, false, columnProperties));
} else if (element instanceof LikeClause) {
LikeClause likeClause = (LikeClause) element;
QualifiedObjectName likeTableName = createQualifiedObjectName(session, statement, likeClause.getTableName());
if (!metadata.getCatalogHandle(session, likeTableName.getCatalogName()).isPresent()) {
throw new SemanticException(MISSING_CATALOG, statement, "LIKE table catalog '%s' does not exist", likeTableName.getCatalogName());
}
if (!tableName.getCatalogName().equals(likeTableName.getCatalogName())) {
throw new SemanticException(NOT_SUPPORTED, statement, "LIKE table across catalogs is not supported");
}
TableHandle likeTable = metadata.getTableHandle(session, likeTableName).orElseThrow(() -> new SemanticException(MISSING_TABLE, statement, "LIKE table '%s' does not exist", likeTableName));
TableMetadata likeTableMetadata = metadata.getTableMetadata(session, likeTable);
Optional<LikeClause.PropertiesOption> propertiesOption = likeClause.getPropertiesOption();
if (propertiesOption.isPresent() && propertiesOption.get().equals(LikeClause.PropertiesOption.INCLUDING)) {
if (includingProperties) {
throw new SemanticException(NOT_SUPPORTED, statement, "Only one LIKE clause can specify INCLUDING PROPERTIES");
}
includingProperties = true;
// Don't inherit location property for sql statement "create table like"
inheritedProperties = likeTableMetadata.getMetadata().getInheritableProperties();
}
likeTableMetadata.getColumns().stream().filter(column -> !column.isHidden()).forEach(column -> {
if (columns.containsKey(column.getName().toLowerCase(Locale.ENGLISH))) {
throw new SemanticException(DUPLICATE_COLUMN_NAME, element, "Column name '%s' specified more than once", column.getName());
}
columns.put(column.getName().toLowerCase(Locale.ENGLISH), column);
});
} else {
throw new PrestoException(GENERIC_INTERNAL_ERROR, "Invalid TableElement: " + element.getClass().getName());
}
}
accessControl.checkCanCreateTable(session.getRequiredTransactionId(), session.getIdentity(), tableName);
Map<String, Expression> sqlProperties = mapFromProperties(statement.getProperties());
Map<String, Object> properties = metadata.getTablePropertyManager().getProperties(catalogName, tableName.getCatalogName(), sqlProperties, session, metadata, parameters);
Map<String, Object> finalProperties = combineProperties(sqlProperties.keySet(), properties, inheritedProperties);
ConnectorTableMetadata tableMetadata = new ConnectorTableMetadata(toSchemaTableName(tableName), ImmutableList.copyOf(columns.values()), finalProperties, statement.getComment());
try {
metadata.createTable(session, tableName.getCatalogName(), tableMetadata, statement.isNotExists());
} catch (PrestoException e) {
// connectors are not required to handle the ignoreExisting flag
if (!e.getErrorCode().equals(ALREADY_EXISTS.toErrorCode()) || !statement.isNotExists()) {
throw e;
}
}
return immediateFuture(null);
}
Aggregations