use of io.prestosql.sql.tree.Statement in project hetu-core by openlookeng.
the class CreateCubeTask method internalExecute.
@VisibleForTesting
public ListenableFuture<?> internalExecute(CreateCube statement, Metadata metadata, AccessControl accessControl, Session session, QueryStateMachine stateMachine, List<Expression> parameters) {
Optional<CubeMetaStore> optionalCubeMetaStore = cubeManager.getMetaStore(STAR_TREE);
if (!optionalCubeMetaStore.isPresent()) {
throw new RuntimeException("HetuMetaStore is not initialized");
}
QualifiedObjectName cubeName = createQualifiedObjectName(session, statement, statement.getCubeName());
QualifiedObjectName tableName = createQualifiedObjectName(session, statement, statement.getSourceTableName());
Optional<TableHandle> cubeHandle = metadata.getTableHandle(session, cubeName);
Optional<TableHandle> tableHandle = metadata.getTableHandle(session, tableName);
if (optionalCubeMetaStore.get().getMetadataFromCubeName(cubeName.toString()).isPresent()) {
if (!statement.isNotExists()) {
throw new SemanticException(CUBE_ALREADY_EXISTS, statement, "Cube '%s' already exists", cubeName);
}
return immediateFuture(null);
}
if (cubeHandle.isPresent()) {
if (!statement.isNotExists()) {
throw new SemanticException(CUBE_OR_TABLE_ALREADY_EXISTS, statement, "Cube or Table '%s' already exists", cubeName);
}
return immediateFuture(null);
}
CatalogName catalogName = metadata.getCatalogHandle(session, cubeName.getCatalogName()).orElseThrow(() -> new PrestoException(NOT_FOUND, "Catalog not found: " + cubeName.getCatalogName()));
if (!metadata.isPreAggregationSupported(session, catalogName)) {
throw new PrestoException(StandardErrorCode.NOT_SUPPORTED, String.format("Cube cannot be created on catalog '%s'", catalogName.toString()));
}
if (!tableHandle.isPresent()) {
throw new SemanticException(MISSING_TABLE, statement, "Table '%s' does not exist", tableName);
}
TableMetadata tableMetadata = metadata.getTableMetadata(session, tableHandle.get());
List<String> groupingSet = statement.getGroupingSet().stream().map(s -> s.getValue().toLowerCase(ENGLISH)).collect(Collectors.toList());
Map<String, ColumnMetadata> sourceTableColumns = tableMetadata.getColumns().stream().collect(Collectors.toMap(ColumnMetadata::getName, col -> col));
List<ColumnMetadata> cubeColumns = new ArrayList<>();
Map<String, AggregationSignature> aggregations = new HashMap<>();
Analysis analysis = analyzeStatement(statement, session, metadata, accessControl, parameters, stateMachine.getWarningCollector());
Map<String, Field> fields = analysis.getOutputDescriptor().getAllFields().stream().collect(Collectors.toMap(col -> col.getName().map(String::toLowerCase).get(), col -> col));
for (FunctionCall aggFunction : statement.getAggregations()) {
String aggFunctionName = aggFunction.getName().toString().toLowerCase(ENGLISH);
String argument = aggFunction.getArguments().isEmpty() || aggFunction.getArguments().get(0) instanceof LongLiteral ? null : ((Identifier) aggFunction.getArguments().get(0)).getValue().toLowerCase(ENGLISH);
boolean distinct = aggFunction.isDistinct();
String cubeColumnName = aggFunctionName + "_" + (argument == null ? "all" : argument) + (aggFunction.isDistinct() ? "_distinct" : "");
CubeAggregateFunction cubeAggregateFunction = CubeAggregateFunction.valueOf(aggFunctionName.toUpperCase(ENGLISH));
switch(cubeAggregateFunction) {
case SUM:
aggregations.put(cubeColumnName, AggregationSignature.sum(argument, distinct));
break;
case COUNT:
AggregationSignature aggregationSignature = argument == null ? AggregationSignature.count() : AggregationSignature.count(argument, distinct);
aggregations.put(cubeColumnName, aggregationSignature);
break;
case AVG:
aggregations.put(cubeColumnName, AggregationSignature.avg(argument, distinct));
break;
case MAX:
aggregations.put(cubeColumnName, AggregationSignature.max(argument, distinct));
break;
case MIN:
aggregations.put(cubeColumnName, AggregationSignature.min(argument, distinct));
break;
default:
throw new PrestoException(NOT_SUPPORTED, format("Unsupported aggregation function : %s", aggFunctionName));
}
Field tableField = fields.get(cubeColumnName);
ColumnMetadata cubeCol = new ColumnMetadata(cubeColumnName, tableField.getType(), true, null, null, false, Collections.emptyMap());
cubeColumns.add(cubeCol);
}
accessControl.checkCanCreateTable(session.getRequiredTransactionId(), session.getIdentity(), tableName);
Map<String, Expression> sqlProperties = mapFromProperties(statement.getProperties());
Map<String, Object> properties = metadata.getTablePropertyManager().getProperties(catalogName, cubeName.getCatalogName(), sqlProperties, session, metadata, parameters);
if (properties.containsKey("partitioned_by")) {
List<String> partitionCols = new ArrayList<>(((List<String>) properties.get("partitioned_by")));
// put all partition columns at the end of the list
groupingSet.removeAll(partitionCols);
groupingSet.addAll(partitionCols);
}
for (String dimension : groupingSet) {
if (!sourceTableColumns.containsKey(dimension)) {
throw new SemanticException(MISSING_COLUMN, statement, "Column %s does not exist", dimension);
}
ColumnMetadata tableCol = sourceTableColumns.get(dimension);
ColumnMetadata cubeCol = new ColumnMetadata(dimension, tableCol.getType(), tableCol.isNullable(), null, null, false, tableCol.getProperties());
cubeColumns.add(cubeCol);
}
ConnectorTableMetadata cubeTableMetadata = new ConnectorTableMetadata(cubeName.asSchemaTableName(), ImmutableList.copyOf(cubeColumns), properties);
try {
metadata.createTable(session, cubeName.getCatalogName(), cubeTableMetadata, 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;
}
}
CubeMetadataBuilder builder = optionalCubeMetaStore.get().getBuilder(cubeName.toString(), tableName.toString());
groupingSet.forEach(dimension -> builder.addDimensionColumn(dimension, dimension));
aggregations.forEach((column, aggregationSignature) -> builder.addAggregationColumn(column, aggregationSignature.getFunction(), aggregationSignature.getDimension(), aggregationSignature.isDistinct()));
builder.addGroup(new HashSet<>(groupingSet));
// Status and Table modified time will be updated on the first insert into the cube
builder.setCubeStatus(CubeStatus.INACTIVE);
builder.setTableLastUpdatedTime(-1L);
statement.getSourceFilter().ifPresent(sourceTablePredicate -> {
sourceTablePredicate = Coercer.addCoercions(sourceTablePredicate, analysis);
builder.withCubeFilter(new CubeFilter(ExpressionFormatter.formatExpression(sourceTablePredicate, Optional.empty())));
});
builder.setCubeLastUpdatedTime(System.currentTimeMillis());
optionalCubeMetaStore.get().persist(builder.build());
return immediateFuture(null);
}
use of io.prestosql.sql.tree.Statement in project hetu-core by openlookeng.
the class CreateViewTask method execute.
@Override
public ListenableFuture<?> execute(CreateView statement, TransactionManager transactionManager, Metadata metadata, AccessControl accessControl, QueryStateMachine stateMachine, List<Expression> parameters, HeuristicIndexerManager heuristicIndexerManager) {
Session session = stateMachine.getSession();
QualifiedObjectName name = createQualifiedObjectName(session, statement, statement.getName());
accessControl.checkCanCreateView(session.getRequiredTransactionId(), session.getIdentity(), name);
String sql = getFormattedSql(statement.getQuery(), sqlParser, Optional.of(parameters));
Analysis analysis = analyzeStatement(statement, session, metadata, accessControl, parameters, stateMachine.getWarningCollector());
List<ViewColumn> columns = analysis.getOutputDescriptor(statement.getQuery()).getVisibleFields().stream().map(field -> new ViewColumn(field.getName().get(), field.getType().getTypeSignature())).collect(toImmutableList());
// use DEFINER security by default
Optional<String> owner = Optional.of(session.getUser());
if (statement.getSecurity().orElse(null) == INVOKER) {
owner = Optional.empty();
}
ConnectorViewDefinition definition = new ConnectorViewDefinition(sql, session.getCatalog(), session.getSchema(), columns, owner, !owner.isPresent());
metadata.createView(session, name, definition, statement.isReplace());
return immediateFuture(null);
}
use of io.prestosql.sql.tree.Statement in project hetu-core by openlookeng.
the class PrepareTask method execute.
@Override
public ListenableFuture<?> execute(Prepare prepare, TransactionManager transactionManager, Metadata metadata, AccessControl accessControl, QueryStateMachine stateMachine, List<Expression> parameters, HeuristicIndexerManager heuristicIndexerManager) {
Statement statement = prepare.getStatement();
if ((statement instanceof Prepare) || (statement instanceof Execute) || (statement instanceof Deallocate)) {
String type = statement.getClass().getSimpleName().toUpperCase(ENGLISH);
throw new PrestoException(NOT_SUPPORTED, "Invalid statement type for prepared statement: " + type);
}
String sql = getFormattedSql(statement, sqlParser, Optional.empty());
stateMachine.addPreparedStatement(prepare.getName().getValue(), sql);
return immediateFuture(null);
}
use of io.prestosql.sql.tree.Statement in project hetu-core by openlookeng.
the class SqlQueryExecution method checkSnapshotSupport.
// Check if snapshot feature conflict with other aspects of the query.
// If any requirement is not met, then proceed as if snapshot was not enabled,
// i.e. session.isSnapshotEnabled() and SystemSessionProperties.isSnapshotEnabled(session) return false
private void checkSnapshotSupport(Session session) {
List<String> reasons = new ArrayList<>();
// Only support create-table-as-select and insert statements
Statement statement = analysis.getStatement();
if (statement instanceof CreateTableAsSelect) {
if (analysis.isCreateTableAsSelectNoOp()) {
// Table already exists. Ask catalog if target table supports snapshot
if (!metadata.isSnapshotSupportedAsOutput(session, analysis.getCreateTableAsSelectNoOpTarget())) {
reasons.add("Only support inserting into tables in Hive with ORC format");
}
} else {
// Ask catalog if new table supports snapshot
Map<String, Object> tableProperties = analysis.getCreateTableMetadata().getProperties();
if (!metadata.isSnapshotSupportedAsNewTable(session, analysis.getTarget().get().getCatalogName(), tableProperties)) {
reasons.add("Only support creating tables in Hive with ORC format");
}
}
} else if (statement instanceof Insert) {
// Ask catalog if target table supports snapshot
if (!metadata.isSnapshotSupportedAsOutput(session, analysis.getInsert().get().getTarget())) {
reasons.add("Only support inserting into tables in Hive with ORC format");
}
} else if (statement instanceof InsertCube) {
reasons.add("INSERT INTO CUBE is not supported, only support CTAS (create table as select) and INSERT INTO (tables) statements");
} else {
reasons.add("Only support CTAS (create table as select) and INSERT INTO (tables) statements");
}
// Doesn't work with the following features
if (SystemSessionProperties.isReuseTableScanEnabled(session) || SystemSessionProperties.isCTEReuseEnabled(session)) {
reasons.add("No support along with reuse_table_scan or cte_reuse_enabled features");
}
// All input tables must support snapshotting
for (TableHandle tableHandle : analysis.getTables()) {
if (!metadata.isSnapshotSupportedAsInput(session, tableHandle)) {
reasons.add("Only support reading from Hive, TPCDS, and TPCH source tables");
break;
}
}
// Must have more than 1 worker
if (nodeScheduler.createNodeSelector(null, false, null).selectableNodeCount() == 1) {
reasons.add("Requires more than 1 worker nodes");
}
if (!snapshotManager.getSnapshotUtils().hasStoreClient()) {
String snapshotProfile = snapshotManager.getSnapshotUtils().getSnapshotProfile();
if (snapshotProfile == null) {
reasons.add("Property hetu.experimental.snapshot.profile is not specified");
} else {
reasons.add("Specified value '" + snapshotProfile + "' for property hetu.experimental.snapshot.profile is not valid");
}
}
if (!reasons.isEmpty()) {
// Disable snapshot support in the session. If this value has been used before this point,
// then we may need to remedy those places to disable snapshot as well. Fortunately,
// most accesses occur before this point, except for classes like ExecutingStatementResource,
// where the "snapshot enabled" info is retrieved and set in ExchangeClient. This is harmless.
// The ExchangeClient may still have snapshotEnabled=true while it's disabled in the session.
// This does not alter ExchangeClient's behavior, because this instance (in coordinator)
// will never receive any marker.
session.disableSnapshot();
String reasonsMessage = "Snapshot feature is disabled: \n" + String.join(". \n", reasons);
warningCollector.add(new PrestoWarning(StandardWarningCode.SNAPSHOT_NOT_SUPPORTED, reasonsMessage));
}
}
use of io.prestosql.sql.tree.Statement in project hetu-core by openlookeng.
the class QueryPreparer method prepareQuery.
public PreparedQuery prepareQuery(Session session, Statement wrappedStatement) throws ParsingException, PrestoException, SemanticException {
Statement statement = wrappedStatement;
Optional<String> prepareSql = Optional.empty();
if (statement instanceof Execute) {
prepareSql = Optional.of(session.getPreparedStatementFromExecute((Execute) statement));
statement = sqlParser.createStatement(prepareSql.get(), createParsingOptions(session));
}
if (statement instanceof Explain && ((Explain) statement).isAnalyze()) {
Statement innerStatement = ((Explain) statement).getStatement();
Optional<QueryType> innerQueryType = StatementUtils.getQueryType(innerStatement.getClass());
if (!innerQueryType.isPresent() || innerQueryType.get() == QueryType.DATA_DEFINITION) {
throw new PrestoException(NOT_SUPPORTED, "EXPLAIN ANALYZE doesn't support statement type: " + innerStatement.getClass().getSimpleName());
}
}
List<Expression> parameters = ImmutableList.of();
if (wrappedStatement instanceof Execute) {
parameters = ((Execute) wrappedStatement).getParameters();
}
validateParameters(statement, parameters);
return new PreparedQuery(statement, parameters, prepareSql);
}
Aggregations