use of com.facebook.presto.spi.TableHandle in project presto by prestodb.
the class GrantTask method execute.
@Override
public ListenableFuture<?> execute(Grant statement, TransactionManager transactionManager, Metadata metadata, AccessControl accessControl, Session session, List<Expression> parameters, WarningCollector warningCollector) {
QualifiedObjectName tableName = createQualifiedObjectName(session, statement, statement.getTableName());
Optional<TableHandle> tableHandle = metadata.getTableHandle(session, tableName);
if (!tableHandle.isPresent()) {
throw new SemanticException(MISSING_TABLE, statement, "Table '%s' does not exist", tableName);
}
Set<Privilege> privileges;
if (statement.getPrivileges().isPresent()) {
privileges = statement.getPrivileges().get().stream().map(privilege -> parsePrivilege(statement, privilege)).collect(toImmutableSet());
} else {
// All privileges
privileges = EnumSet.allOf(Privilege.class);
}
// verify current identity has permissions to grant permissions
for (Privilege privilege : privileges) {
accessControl.checkCanGrantTablePrivilege(session.getRequiredTransactionId(), session.getIdentity(), session.getAccessControlContext(), privilege, tableName, createPrincipal(statement.getGrantee()), statement.isWithGrantOption());
}
metadata.grantTablePrivileges(session, tableName, privileges, createPrincipal(statement.getGrantee()), statement.isWithGrantOption());
return immediateFuture(null);
}
use of com.facebook.presto.spi.TableHandle in project presto by prestodb.
the class ColumnReference method getAssignedVariable.
@Override
public Optional<VariableReferenceExpression> getAssignedVariable(PlanNode node, Session session, Metadata metadata, SymbolAliases symbolAliases) {
TableHandle tableHandle;
Map<VariableReferenceExpression, ColumnHandle> assignments;
if (node instanceof TableScanNode) {
TableScanNode tableScanNode = (TableScanNode) node;
tableHandle = tableScanNode.getTable();
assignments = tableScanNode.getAssignments();
} else if (node instanceof IndexSourceNode) {
IndexSourceNode indexSourceNode = (IndexSourceNode) node;
tableHandle = indexSourceNode.getTableHandle();
assignments = indexSourceNode.getAssignments();
} else {
return Optional.empty();
}
TableMetadata tableMetadata = metadata.getTableMetadata(session, tableHandle);
String actualTableName = tableMetadata.getTable().getTableName();
// Wrong table -> doesn't match.
if (!tableName.equalsIgnoreCase(actualTableName)) {
return Optional.empty();
}
Optional<ColumnHandle> columnHandle = getColumnHandle(tableHandle, session, metadata);
checkState(columnHandle.isPresent(), format("Table %s doesn't have column %s. Typo in test?", tableName, columnName));
return getAssignedVariable(assignments, columnHandle.get());
}
use of com.facebook.presto.spi.TableHandle in project presto by prestodb.
the class CreateMaterializedViewTask method execute.
@Override
public ListenableFuture<?> execute(CreateMaterializedView statement, TransactionManager transactionManager, Metadata metadata, AccessControl accessControl, Session session, List<Expression> parameters, WarningCollector warningCollector) {
QualifiedObjectName viewName = createQualifiedObjectName(session, statement, statement.getName());
Optional<TableHandle> viewHandle = metadata.getTableHandle(session, viewName);
if (viewHandle.isPresent()) {
if (!statement.isNotExists()) {
throw new SemanticException(MATERIALIZED_VIEW_ALREADY_EXISTS, statement, "Materialized view '%s' already exists", viewName);
}
return immediateFuture(null);
}
accessControl.checkCanCreateTable(session.getRequiredTransactionId(), session.getIdentity(), session.getAccessControlContext(), viewName);
accessControl.checkCanCreateView(session.getRequiredTransactionId(), session.getIdentity(), session.getAccessControlContext(), viewName);
Analyzer analyzer = new Analyzer(session, metadata, sqlParser, accessControl, Optional.empty(), parameters, warningCollector);
Analysis analysis = analyzer.analyze(statement);
ConnectorId connectorId = metadata.getCatalogHandle(session, viewName.getCatalogName()).orElseThrow(() -> new PrestoException(NOT_FOUND, "Catalog does not exist: " + viewName.getCatalogName()));
List<ColumnMetadata> columnMetadata = analysis.getOutputDescriptor(statement.getQuery()).getVisibleFields().stream().map(field -> new ColumnMetadata(field.getName().get(), field.getType())).collect(toImmutableList());
Map<String, Expression> sqlProperties = mapFromProperties(statement.getProperties());
Map<String, Object> properties = metadata.getTablePropertyManager().getProperties(connectorId, viewName.getCatalogName(), sqlProperties, session, metadata, parameters);
ConnectorTableMetadata viewMetadata = new ConnectorTableMetadata(toSchemaTableName(viewName), columnMetadata, properties, statement.getComment());
String sql = getFormattedSql(statement.getQuery(), sqlParser, Optional.of(parameters));
List<SchemaTableName> baseTables = analysis.getTableNodes().stream().map(table -> {
QualifiedObjectName tableName = createQualifiedObjectName(session, table, table.getName());
if (!viewName.getCatalogName().equals(tableName.getCatalogName())) {
throw new SemanticException(NOT_SUPPORTED, statement, "Materialized view %s created from a base table in a different catalog %s is not supported.", viewName, tableName);
}
return toSchemaTableName(tableName);
}).distinct().collect(toImmutableList());
MaterializedViewColumnMappingExtractor extractor = new MaterializedViewColumnMappingExtractor(analysis, session);
ConnectorMaterializedViewDefinition viewDefinition = new ConnectorMaterializedViewDefinition(sql, viewName.getSchemaName(), viewName.getObjectName(), baseTables, Optional.of(session.getUser()), extractor.getMaterializedViewColumnMappings(), extractor.getMaterializedViewDirectColumnMappings(), extractor.getBaseTablesOnOuterJoinSide(), Optional.empty());
try {
metadata.createMaterializedView(session, viewName.getCatalogName(), viewMetadata, viewDefinition, 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);
}
use of com.facebook.presto.spi.TableHandle in project presto by prestodb.
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);
}
ConnectorId connectorId = 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 (IllegalArgumentException 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, connectorId).contains(NOT_NULL_COLUMN_CONSTRAINT)) {
throw new SemanticException(NOT_SUPPORTED, column, "Catalog '%s' does not support non-null column for column name '%s'", connectorId.getCatalogName(), column.getName());
}
Map<String, Expression> sqlProperties = mapFromProperties(column.getProperties());
Map<String, Object> columnProperties = metadata.getColumnPropertyManager().getProperties(connectorId, 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;
inheritedProperties = likeTableMetadata.getMetadata().getProperties();
}
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(), session.getAccessControlContext(), tableName);
Map<String, Expression> sqlProperties = mapFromProperties(statement.getProperties());
Map<String, Object> properties = metadata.getTablePropertyManager().getProperties(connectorId, 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);
}
use of com.facebook.presto.spi.TableHandle in project presto by prestodb.
the class WarnOnScanWithoutPartitionPredicate method validate.
@Override
public void validate(PlanNode plan, Session session, Metadata metadata, SqlParser sqlParser, TypeProvider types, WarningCollector warningCollector) {
for (TableScanNode scan : searchFrom(plan).where(TableScanNode.class::isInstance).<TableScanNode>findAll()) {
TableHandle tableHandle = scan.getTable();
TableLayoutFilterCoverage partitioningFilterCoverage = metadata.getTableLayoutFilterCoverage(session, tableHandle, warnOnNoTableLayoutFilter);
if (partitioningFilterCoverage == NOT_COVERED) {
String warningMessage = String.format("No partition filter for scan of table %s", scan.getTable().getConnectorHandle());
warningCollector.add(new PrestoWarning(PERFORMANCE_WARNING, warningMessage));
}
}
}
Aggregations