Search in sources :

Example 1 with CreateIndex

use of io.prestosql.sql.tree.CreateIndex in project hetu-core by openlookeng.

the class QueryPlanner method createIndex.

/**
 * CREATE INDEX statements are rewritten as SELECT statements,
 * if the original statement was CREATE INDEX, create the necessary plan nodes
 * to create the index
 */
private PlanBuilder createIndex(PlanBuilder subPlan, Statement originalStatement) {
    if (!(originalStatement instanceof CreateIndex)) {
        return subPlan;
    }
    // rewrite sub queries
    CreateIndex createIndex = (CreateIndex) originalStatement;
    String tableName = MetadataUtil.createQualifiedObjectName(session, originalStatement, createIndex.getTableName()).toString();
    List<String> partitions = new ArrayList<>();
    if (createIndex.getExpression().isPresent()) {
        partitions = HeuristicIndexUtils.extractPartitions(createIndex.getExpression().get());
    }
    Map<String, Type> columnTypes = new HashMap<>();
    for (Field field : analysis.getRootScope().getRelationType().getAllFields()) {
        if (INDEX_SUPPORTED_TYPES.get(createIndex.getIndexType().toLowerCase(Locale.ENGLISH)).stream().noneMatch(supportType -> field.getType().getDisplayName().contains(supportType))) {
            throw new UnsupportedOperationException("Index creation on " + field.getType().getDisplayName() + " column is not supported");
        }
        columnTypes.put(field.getOriginColumnName().get(), field.getType());
    }
    Properties indexProperties = new Properties();
    CreateIndexMetadata.Level indexCreationLevel = CreateIndexMetadata.Level.UNDEFINED;
    indexProperties.setProperty(LEVEL_PROP_KEY, indexCreationLevel.toString());
    boolean autoLoadFound = false;
    for (Property property : createIndex.getProperties()) {
        String key = extractPropertyValue(property.getName());
        String val = extractPropertyValue(property.getValue()).toUpperCase(Locale.ENGLISH);
        if (key.equals(LEVEL_PROP_KEY)) {
            indexCreationLevel = CreateIndexMetadata.Level.valueOf(val);
            continue;
        }
        if (key.equals(AUTOLOAD_PROP_KEY)) {
            autoLoadFound = true;
            String valInLowerCase = val.toLowerCase(Locale.ROOT);
            if (valInLowerCase.equals("true") || valInLowerCase.equals("false")) {
                indexProperties.setProperty(key, valInLowerCase);
            } else {
                throw new IllegalArgumentException("Unrecognized value for key '" + AUTOLOAD_PROP_KEY + "', only 'true' or 'false' are allowed");
            }
            continue;
        }
        indexProperties.setProperty(key, val);
    }
    if (!autoLoadFound) {
        boolean defaultAutoloadProp = PropertyService.getBooleanProperty(HetuConstant.FILTER_CACHE_AUTOLOAD_DEFAULT);
        indexProperties.setProperty(AUTOLOAD_PROP_KEY, String.valueOf(defaultAutoloadProp));
    }
    return subPlan.withNewRoot(new CreateIndexNode(idAllocator.getNextId(), ExchangeNode.gatheringExchange(idAllocator.getNextId(), ExchangeNode.Scope.REMOTE, subPlan.getRoot()), new CreateIndexMetadata(createIndex.getIndexName().toString(), tableName, createIndex.getIndexType(), 0L, createIndex.getColumnAliases().stream().map(identifier -> new Pair<>(identifier.toString(), columnTypes.get(identifier.toString().toLowerCase(Locale.ROOT)))).collect(Collectors.toList()), partitions, indexProperties, session.getUser(), indexCreationLevel)));
}
Also used : CreateIndexNode(io.prestosql.sql.planner.plan.CreateIndexNode) CreateIndexMetadata(io.prestosql.spi.connector.CreateIndexMetadata) LinkedHashMap(java.util.LinkedHashMap) HashMap(java.util.HashMap) ArrayList(java.util.ArrayList) Properties(java.util.Properties) Field(io.prestosql.sql.analyzer.Field) FrameBoundType(io.prestosql.spi.sql.expression.Types.FrameBoundType) Type(io.prestosql.spi.type.Type) WindowFrameType(io.prestosql.spi.sql.expression.Types.WindowFrameType) RelationType(io.prestosql.sql.analyzer.RelationType) CreateIndex(io.prestosql.sql.tree.CreateIndex) Property(io.prestosql.sql.tree.Property)

Example 2 with CreateIndex

use of io.prestosql.sql.tree.CreateIndex in project hetu-core by openlookeng.

the class StatementAnalyzer method validateCreateIndex.

private void validateCreateIndex(Table table, Optional<Scope> scope) {
    CreateIndex createIndex = (CreateIndex) analysis.getOriginalStatement();
    QualifiedObjectName tableFullName = createQualifiedObjectName(session, createIndex, createIndex.getTableName());
    accessControl.checkCanCreateIndex(session.getRequiredTransactionId(), session.getIdentity(), tableFullName);
    String tableName = tableFullName.toString();
    // check whether catalog support create index
    if (!metadata.isHeuristicIndexSupported(session, tableFullName)) {
        throw new SemanticException(NOT_SUPPORTED, createIndex, "CREATE INDEX is not supported in catalog '%s'", tableFullName.getCatalogName());
    }
    List<String> partitions = new ArrayList<>();
    String partitionColumn = null;
    if (createIndex.getExpression().isPresent()) {
        partitions = HeuristicIndexUtils.extractPartitions(createIndex.getExpression().get());
        // check partition name validate, create index …… where pt_d = xxx;
        // pt_d must be partition column
        Set<String> partitionColumns = partitions.stream().map(k -> k.substring(0, k.indexOf("="))).collect(Collectors.toSet());
        if (partitionColumns.size() > 1) {
            // currently only support one partition column
            throw new IllegalArgumentException("Heuristic index only supports predicates on one column");
        }
        // The only entry in set should be the only partition column name
        partitionColumn = partitionColumns.iterator().next();
    }
    Optional<TableHandle> tableHandle = metadata.getTableHandle(session, tableFullName);
    if (tableHandle.isPresent()) {
        if (!tableHandle.get().getConnectorHandle().isHeuristicIndexSupported()) {
            throw new SemanticException(NOT_SUPPORTED, table, "Catalog supported, but table storage format is not supported by heuristic index");
        }
        TableMetadata tableMetadata = metadata.getTableMetadata(session, tableHandle.get());
        List<String> availableColumns = tableMetadata.getColumns().stream().map(ColumnMetadata::getName).collect(Collectors.toList());
        for (Identifier column : createIndex.getColumnAliases()) {
            if (!availableColumns.contains(column.getValue().toLowerCase(Locale.ROOT))) {
                throw new SemanticException(MISSING_ATTRIBUTE, table, "Column '%s' cannot be resolved", column.getValue());
            }
        }
        if (partitionColumn != null && !tableHandle.get().getConnectorHandle().isPartitionColumn(partitionColumn)) {
            throw new SemanticException(NOT_SUPPORTED, table, "Heuristic index creation is only supported for predicates on partition columns");
        }
    } else {
        throw new SemanticException(MISSING_ATTRIBUTE, table, "Table '%s' is invalid", tableFullName);
    }
    List<Pair<String, Type>> indexColumns = new LinkedList<>();
    for (Identifier i : createIndex.getColumnAliases()) {
        indexColumns.add(new Pair<>(i.toString(), UNKNOWN));
    }
    // For now, creating index for multiple columns is not supported
    if (indexColumns.size() > 1) {
        throw new SemanticException(NOT_SUPPORTED, table, "Multi-column indexes are currently not supported");
    }
    try {
        // Use this place holder to check the existence of index and lock the place
        Properties properties = new Properties();
        properties.setProperty(INPROGRESS_PROPERTY_KEY, "TRUE");
        CreateIndexMetadata placeHolder = new CreateIndexMetadata(createIndex.getIndexName().toString(), tableName, createIndex.getIndexType(), 0L, indexColumns, partitions, properties, session.getUser(), UNDEFINED);
        synchronized (StatementAnalyzer.class) {
            IndexClient.RecordStatus recordStatus = heuristicIndexerManager.getIndexClient().lookUpIndexRecord(placeHolder);
            switch(recordStatus) {
                case SAME_NAME:
                    throw new SemanticException(INDEX_ALREADY_EXISTS, createIndex, "Index '%s' already exists", createIndex.getIndexName().toString());
                case SAME_CONTENT:
                    throw new SemanticException(INDEX_ALREADY_EXISTS, createIndex, "Index with same (table,column,indexType) already exists");
                case SAME_INDEX_PART_CONFLICT:
                    throw new SemanticException(INDEX_ALREADY_EXISTS, createIndex, "Index with same (table,column,indexType) already exists and partition(s) contain conflicts");
                case IN_PROGRESS_SAME_NAME:
                    throw new SemanticException(INDEX_ALREADY_EXISTS, createIndex, "Index '%s' is being created by another user. Check running queries for details. If there is no running query for this index, " + "the index may be in an unexpected error state and should be dropped using 'DROP INDEX %s'", createIndex.getIndexName().toString(), createIndex.getIndexName().toString());
                case IN_PROGRESS_SAME_CONTENT:
                    throw new SemanticException(INDEX_ALREADY_EXISTS, createIndex, "Index with same (table,column,indexType) is being created by another user. Check running queries for details. " + "If there is no running query for this index, the index may be in an unexpected error state and should be dropped using 'DROP INDEX'");
                case IN_PROGRESS_SAME_INDEX_PART_CONFLICT:
                    if (partitions.isEmpty()) {
                        throw new SemanticException(INDEX_ALREADY_EXISTS, createIndex, "Index with same (table,column,indexType) is being created by another user. Check running queries for details. " + "If there is no running query for this index, the index may be in an unexpected error state and should be dropped using 'DROP INDEX %s'", createIndex.getIndexName().toString());
                    }
                // allow different queries to run with explicitly same partitions
                case SAME_INDEX_PART_CAN_MERGE:
                case IN_PROGRESS_SAME_INDEX_PART_CAN_MERGE:
                    break;
                case NOT_FOUND:
                    heuristicIndexerManager.getIndexClient().addIndexRecord(placeHolder);
            }
        }
    } catch (IOException e) {
        throw new UncheckedIOException(e);
    }
}
Also used : CreateSchema(io.prestosql.sql.tree.CreateSchema) AggregationAnalyzer.verifyOrderByAggregations(io.prestosql.sql.analyzer.AggregationAnalyzer.verifyOrderByAggregations) OperatorNotFoundException(io.prestosql.metadata.OperatorNotFoundException) INVALID_FUNCTION_ARGUMENT(io.prestosql.spi.StandardErrorCode.INVALID_FUNCTION_ARGUMENT) Prepare(io.prestosql.sql.tree.Prepare) HeuristicIndexUtils(io.prestosql.utils.HeuristicIndexUtils) Statement(io.prestosql.sql.tree.Statement) INDEX_ALREADY_EXISTS(io.prestosql.sql.analyzer.SemanticErrorCode.INDEX_ALREADY_EXISTS) WarningCollector(io.prestosql.execution.warnings.WarningCollector) Execute(io.prestosql.sql.tree.Execute) Map(java.util.Map) RowType(io.prestosql.spi.type.RowType) ArrayConstructor(io.prestosql.sql.tree.ArrayConstructor) FetchFirst(io.prestosql.sql.tree.FetchFirst) TOO_MANY_ARGUMENTS(io.prestosql.sql.analyzer.SemanticErrorCode.TOO_MANY_ARGUMENTS) ENGLISH(java.util.Locale.ENGLISH) Identifier(io.prestosql.sql.tree.Identifier) Cube(io.prestosql.sql.tree.Cube) RenameColumn(io.prestosql.sql.tree.RenameColumn) HeuristicIndexerManager(io.prestosql.heuristicindex.HeuristicIndexerManager) INPROGRESS_PROPERTY_KEY(io.prestosql.spi.heuristicindex.IndexRecord.INPROGRESS_PROPERTY_KEY) AccessControl(io.prestosql.security.AccessControl) Delete(io.prestosql.sql.tree.Delete) SystemSessionProperties.getMaxGroupingSets(io.prestosql.SystemSessionProperties.getMaxGroupingSets) GroupingElement(io.prestosql.sql.tree.GroupingElement) Collectors.joining(java.util.stream.Collectors.joining) Insert(io.prestosql.sql.tree.Insert) DropView(io.prestosql.sql.tree.DropView) ExpressionUtils(io.prestosql.sql.ExpressionUtils) ParsingException(io.prestosql.sql.parser.ParsingException) LongLiteral(io.prestosql.sql.tree.LongLiteral) Call(io.prestosql.sql.tree.Call) ScopeReferenceExtractor.hasReferencesToScope(io.prestosql.sql.analyzer.ScopeReferenceExtractor.hasReferencesToScope) SqlPath(io.prestosql.sql.SqlPath) NodeUtils.mapFromProperties(io.prestosql.sql.NodeUtils.mapFromProperties) Joiner(com.google.common.base.Joiner) ExpressionInterpreter.expressionOptimizer(io.prestosql.sql.planner.ExpressionInterpreter.expressionOptimizer) FunctionKind(io.prestosql.spi.function.FunctionKind) INVALID_WINDOW_FRAME(io.prestosql.sql.analyzer.SemanticErrorCode.INVALID_WINDOW_FRAME) ExpressionInterpreter(io.prestosql.sql.planner.ExpressionInterpreter) COLUMN_NAME_NOT_SPECIFIED(io.prestosql.sql.analyzer.SemanticErrorCode.COLUMN_NAME_NOT_SPECIFIED) VacuumTable(io.prestosql.sql.tree.VacuumTable) DropTable(io.prestosql.sql.tree.DropTable) AllColumns(io.prestosql.sql.tree.AllColumns) Node(io.prestosql.sql.tree.Node) ResetSession(io.prestosql.sql.tree.ResetSession) QualifiedObjectName(io.prestosql.spi.connector.QualifiedObjectName) MISSING_SCHEMA(io.prestosql.sql.analyzer.SemanticErrorCode.MISSING_SCHEMA) OptionalLong(java.util.OptionalLong) Deallocate(io.prestosql.sql.tree.Deallocate) MISSING_INDEX(io.prestosql.sql.analyzer.SemanticErrorCode.MISSING_INDEX) INVALID_PROCEDURE_ARGUMENTS(io.prestosql.sql.analyzer.SemanticErrorCode.INVALID_PROCEDURE_ARGUMENTS) ParsingUtil.createParsingOptions(io.prestosql.sql.ParsingUtil.createParsingOptions) ImmutableSet.toImmutableSet(com.google.common.collect.ImmutableSet.toImmutableSet) Comment(io.prestosql.sql.tree.Comment) SelectItem(io.prestosql.sql.tree.SelectItem) ImmutableMultimap(com.google.common.collect.ImmutableMultimap) MISSING_COLUMN(io.prestosql.sql.analyzer.SemanticErrorCode.MISSING_COLUMN) RenameTable(io.prestosql.sql.tree.RenameTable) DUPLICATE_RELATION(io.prestosql.sql.analyzer.SemanticErrorCode.DUPLICATE_RELATION) Query(io.prestosql.sql.tree.Query) ComparisonExpression(io.prestosql.sql.tree.ComparisonExpression) IOException(java.io.IOException) INVALID_COLUMN_MASK(io.prestosql.spi.StandardErrorCode.INVALID_COLUMN_MASK) Lateral(io.prestosql.sql.tree.Lateral) AGGREGATE(io.prestosql.spi.function.FunctionKind.AGGREGATE) COLUMN_TYPE_UNKNOWN(io.prestosql.sql.analyzer.SemanticErrorCode.COLUMN_TYPE_UNKNOWN) Expression(io.prestosql.sql.tree.Expression) TableSubquery(io.prestosql.sql.tree.TableSubquery) SystemSessionProperties(io.prestosql.SystemSessionProperties) Intersect(io.prestosql.sql.tree.Intersect) Analyzer.verifyNoAggregateWindowOrGroupingFunctions(io.prestosql.sql.analyzer.Analyzer.verifyNoAggregateWindowOrGroupingFunctions) SqlParser(io.prestosql.sql.parser.SqlParser) CreateCube(io.prestosql.sql.tree.CreateCube) AMBIGUOUS_ATTRIBUTE(io.prestosql.sql.analyzer.SemanticErrorCode.AMBIGUOUS_ATTRIBUTE) FieldReference(io.prestosql.sql.tree.FieldReference) DropSchema(io.prestosql.sql.tree.DropSchema) Preconditions.checkArgument(com.google.common.base.Preconditions.checkArgument) Locale(java.util.Locale) StartTransaction(io.prestosql.sql.tree.StartTransaction) NON_NUMERIC_SAMPLE_PERCENTAGE(io.prestosql.sql.analyzer.SemanticErrorCode.NON_NUMERIC_SAMPLE_PERCENTAGE) VIEW_IS_RECURSIVE(io.prestosql.sql.analyzer.SemanticErrorCode.VIEW_IS_RECURSIVE) BOOLEAN(io.prestosql.spi.type.BooleanType.BOOLEAN) Type(io.prestosql.spi.type.Type) QuerySpecification(io.prestosql.sql.tree.QuerySpecification) Except(io.prestosql.sql.tree.Except) BIGINT(io.prestosql.spi.type.BigintType.BIGINT) CubeMetaStore(io.hetu.core.spi.cube.io.CubeMetaStore) PrestoException(io.prestosql.spi.PrestoException) ImmutableSet(com.google.common.collect.ImmutableSet) RANGE(io.prestosql.spi.sql.expression.Types.WindowFrameType.RANGE) Collection(java.util.Collection) CatalogName(io.prestosql.spi.connector.CatalogName) CubeAggregateFunction(io.hetu.core.spi.cube.CubeAggregateFunction) ExpressionTreeUtils.extractLocation(io.prestosql.sql.analyzer.ExpressionTreeUtils.extractLocation) Iterables.getLast(com.google.common.collect.Iterables.getLast) DropCache(io.prestosql.sql.tree.DropCache) Collectors(java.util.stream.Collectors) Pair(io.prestosql.spi.heuristicindex.Pair) Rollback(io.prestosql.sql.tree.Rollback) AstUtils(io.prestosql.sql.util.AstUtils) ExpressionAnalyzer.createConstantAnalyzer(io.prestosql.sql.analyzer.ExpressionAnalyzer.createConstantAnalyzer) SingleColumn(io.prestosql.sql.tree.SingleColumn) With(io.prestosql.sql.tree.With) ExplainType(io.prestosql.sql.tree.ExplainType) TypeSignature(io.prestosql.spi.type.TypeSignature) DropCube(io.prestosql.sql.tree.DropCube) DataCenterUtility(io.prestosql.connector.DataCenterUtility) UNKNOWN(io.prestosql.spi.type.UnknownType.UNKNOWN) INVALID_OFFSET_ROW_COUNT(io.prestosql.sql.analyzer.SemanticErrorCode.INVALID_OFFSET_ROW_COUNT) MISSING_CATALOG(io.prestosql.sql.analyzer.SemanticErrorCode.MISSING_CATALOG) TOO_MANY_GROUPING_SETS(io.prestosql.sql.analyzer.SemanticErrorCode.TOO_MANY_GROUPING_SETS) INVALID_ROW_FILTER(io.prestosql.spi.StandardErrorCode.INVALID_ROW_FILTER) ConnectorViewDefinition(io.prestosql.spi.connector.ConnectorViewDefinition) NOT_FOUND(io.prestosql.spi.StandardErrorCode.NOT_FOUND) TableHandle(io.prestosql.spi.metadata.TableHandle) ViewAccessControl(io.prestosql.security.ViewAccessControl) HashSet(java.util.HashSet) CubeStatus(io.hetu.core.spi.cube.CubeStatus) Values(io.prestosql.sql.tree.Values) ExpressionTreeUtils.extractWindowFunctions(io.prestosql.sql.analyzer.ExpressionTreeUtils.extractWindowFunctions) ImmutableList(com.google.common.collect.ImmutableList) FunctionCall(io.prestosql.sql.tree.FunctionCall) JoinUsing(io.prestosql.sql.tree.JoinUsing) ViewColumn(io.prestosql.spi.connector.ConnectorViewDefinition.ViewColumn) ExpressionTreeUtils.extractExpressions(io.prestosql.sql.analyzer.ExpressionTreeUtils.extractExpressions) Math.toIntExact(java.lang.Math.toIntExact) LinkedList(java.util.LinkedList) Limit(io.prestosql.sql.tree.Limit) DereferenceExpression(io.prestosql.sql.tree.DereferenceExpression) DUPLICATE_PROPERTY(io.prestosql.sql.analyzer.SemanticErrorCode.DUPLICATE_PROPERTY) ColumnMetadata(io.prestosql.spi.connector.ColumnMetadata) SystemSessionProperties.isEnableStarTreeIndex(io.prestosql.SystemSessionProperties.isEnableStarTreeIndex) WithQuery(io.prestosql.sql.tree.WithQuery) Offset(io.prestosql.sql.tree.Offset) INVALID_ORDINAL(io.prestosql.sql.analyzer.SemanticErrorCode.INVALID_ORDINAL) DropIndex(io.prestosql.sql.tree.DropIndex) INVALID_FUNCTION_NAME(io.prestosql.sql.analyzer.SemanticErrorCode.INVALID_FUNCTION_NAME) Use(io.prestosql.sql.tree.Use) DISTRIBUTED(io.prestosql.sql.tree.ExplainType.Type.DISTRIBUTED) JoinOn(io.prestosql.sql.tree.JoinOn) TABLE_STATE_INCORRECT(io.prestosql.sql.analyzer.SemanticErrorCode.TABLE_STATE_INCORRECT) Table(io.prestosql.sql.tree.Table) SampledRelation(io.prestosql.sql.tree.SampledRelation) LongSupplier(java.util.function.LongSupplier) PrestoWarning(io.prestosql.spi.PrestoWarning) Relation(io.prestosql.sql.tree.Relation) TypeProvider(io.prestosql.sql.planner.TypeProvider) Property(io.prestosql.sql.tree.Property) AliasedRelation(io.prestosql.sql.tree.AliasedRelation) AccessDeniedException(io.prestosql.spi.security.AccessDeniedException) CreateTable(io.prestosql.sql.tree.CreateTable) INVALID_FETCH_FIRST_ROW_COUNT(io.prestosql.sql.analyzer.SemanticErrorCode.INVALID_FETCH_FIRST_ROW_COUNT) Join(io.prestosql.sql.tree.Join) MISMATCHED_COLUMN_ALIASES(io.prestosql.sql.analyzer.SemanticErrorCode.MISMATCHED_COLUMN_ALIASES) Row(io.prestosql.sql.tree.Row) AssignmentItem(io.prestosql.sql.tree.AssignmentItem) ImmutableList.toImmutableList(com.google.common.collect.ImmutableList.toImmutableList) Set(java.util.Set) Identity(io.prestosql.spi.security.Identity) DUPLICATE_COLUMN_NAME(io.prestosql.sql.analyzer.SemanticErrorCode.DUPLICATE_COLUMN_NAME) Metadata(io.prestosql.metadata.Metadata) SetSession(io.prestosql.sql.tree.SetSession) NodeRef(io.prestosql.sql.tree.NodeRef) MISSING_CUBE(io.prestosql.sql.analyzer.SemanticErrorCode.MISSING_CUBE) UncheckedIOException(java.io.UncheckedIOException) ImmutableMap.toImmutableMap(com.google.common.collect.ImmutableMap.toImmutableMap) CreateView(io.prestosql.sql.tree.CreateView) ExpressionTreeUtils.extractAggregateFunctions(io.prestosql.sql.analyzer.ExpressionTreeUtils.extractAggregateFunctions) DropColumn(io.prestosql.sql.tree.DropColumn) MoreLists.mappedCopy(io.prestosql.util.MoreLists.mappedCopy) StandardErrorCode(io.prestosql.spi.StandardErrorCode) STAR_TREE(io.prestosql.cube.CubeManager.STAR_TREE) Grant(io.prestosql.sql.tree.Grant) GroupingSets(io.prestosql.sql.tree.GroupingSets) INSERT_INTO_CUBE(io.prestosql.sql.analyzer.SemanticErrorCode.INSERT_INTO_CUBE) Analyze(io.prestosql.sql.tree.Analyze) Iterables(com.google.common.collect.Iterables) TableMetadata(io.prestosql.metadata.TableMetadata) MUST_BE_WINDOW_FUNCTION(io.prestosql.sql.analyzer.SemanticErrorCode.MUST_BE_WINDOW_FUNCTION) VIEW_PARSE_ERROR(io.prestosql.sql.analyzer.SemanticErrorCode.VIEW_PARSE_ERROR) CharType(io.prestosql.spi.type.CharType) TypeNotFoundException(io.prestosql.spi.type.TypeNotFoundException) NodeUtils.getSortItemsFromOrderBy(io.prestosql.sql.NodeUtils.getSortItemsFromOrderBy) ExpressionTreeRewriter(io.prestosql.sql.tree.ExpressionTreeRewriter) Types(io.prestosql.spi.sql.expression.Types) ArrayList(java.util.ArrayList) MapType(io.prestosql.spi.type.MapType) WILDCARD_WITHOUT_FROM(io.prestosql.sql.analyzer.SemanticErrorCode.WILDCARD_WITHOUT_FROM) PRECEDING(io.prestosql.spi.sql.expression.Types.FrameBoundType.PRECEDING) VARCHAR(io.prestosql.spi.type.VarcharType.VARCHAR) CreateTableAsSelect(io.prestosql.sql.tree.CreateTableAsSelect) FOLLOWING(io.prestosql.spi.sql.expression.Types.FrameBoundType.FOLLOWING) Session(io.prestosql.Session) ExpressionDeterminismEvaluator.isDeterministic(io.prestosql.sql.planner.ExpressionDeterminismEvaluator.isDeterministic) MISSING_ATTRIBUTE(io.prestosql.sql.analyzer.SemanticErrorCode.MISSING_ATTRIBUTE) CatalogSchemaName(io.prestosql.spi.connector.CatalogSchemaName) IndexRecord(io.prestosql.spi.heuristicindex.IndexRecord) REDUNDANT_ORDER_BY(io.prestosql.spi.connector.StandardWarningCode.REDUNDANT_ORDER_BY) VIEW_IS_STALE(io.prestosql.sql.analyzer.SemanticErrorCode.VIEW_IS_STALE) SetOperation(io.prestosql.sql.tree.SetOperation) Properties(java.util.Properties) WINDOW(io.prestosql.spi.function.FunctionKind.WINDOW) TYPE_MISMATCH(io.prestosql.sql.analyzer.SemanticErrorCode.TYPE_MISMATCH) Throwables.throwIfInstanceOf(com.google.common.base.Throwables.throwIfInstanceOf) CubeManager(io.prestosql.cube.CubeManager) Explain(io.prestosql.sql.tree.Explain) ColumnHandle(io.prestosql.spi.connector.ColumnHandle) CreateIndexMetadata(io.prestosql.spi.connector.CreateIndexMetadata) MISMATCHED_SET_COLUMN_TYPES(io.prestosql.sql.analyzer.SemanticErrorCode.MISMATCHED_SET_COLUMN_TYPES) CubeMetadata(io.hetu.core.spi.cube.CubeMetadata) AddColumn(io.prestosql.sql.tree.AddColumn) VarcharType(io.prestosql.spi.type.VarcharType) JoinCriteria(io.prestosql.sql.tree.JoinCriteria) Unnest(io.prestosql.sql.tree.Unnest) CURRENT_ROW(io.prestosql.spi.sql.expression.Types.FrameBoundType.CURRENT_ROW) AggregationAnalyzer.verifySourceAggregations(io.prestosql.sql.analyzer.AggregationAnalyzer.verifySourceAggregations) AllowAllAccessControl(io.prestosql.security.AllowAllAccessControl) Iterables.transform(com.google.common.collect.Iterables.transform) UNBOUNDED_PRECEDING(io.prestosql.spi.sql.expression.Types.FrameBoundType.UNBOUNDED_PRECEDING) QualifiedName(io.prestosql.sql.tree.QualifiedName) FunctionProperty(io.prestosql.sql.tree.FunctionProperty) DefaultTraversalVisitor(io.prestosql.sql.tree.DefaultTraversalVisitor) NOT_SUPPORTED(io.prestosql.sql.analyzer.SemanticErrorCode.NOT_SUPPORTED) RenameSchema(io.prestosql.sql.tree.RenameSchema) UNDEFINED(io.prestosql.spi.connector.CreateIndexMetadata.Level.UNDEFINED) Select(io.prestosql.sql.tree.Select) Rollup(io.prestosql.sql.tree.Rollup) WindowFrame(io.prestosql.sql.tree.WindowFrame) OperatorType(io.prestosql.spi.function.OperatorType) IndexClient(io.prestosql.spi.heuristicindex.IndexClient) Window(io.prestosql.sql.tree.Window) TABLE_ALREADY_EXISTS(io.prestosql.sql.analyzer.SemanticErrorCode.TABLE_ALREADY_EXISTS) TypeCoercion(io.prestosql.type.TypeCoercion) Commit(io.prestosql.sql.tree.Commit) UNBOUNDED_FOLLOWING(io.prestosql.spi.sql.expression.Types.FrameBoundType.UNBOUNDED_FOLLOWING) SymbolsExtractor(io.prestosql.sql.planner.SymbolsExtractor) ImmutableMap(com.google.common.collect.ImmutableMap) GroupingOperation(io.prestosql.sql.tree.GroupingOperation) Collections.emptyList(java.util.Collections.emptyList) ArrayType(io.prestosql.spi.type.ArrayType) CreateIndex(io.prestosql.sql.tree.CreateIndex) GroupBy(io.prestosql.sql.tree.GroupBy) ViewExpression(io.prestosql.spi.security.ViewExpression) NESTED_WINDOW(io.prestosql.sql.analyzer.SemanticErrorCode.NESTED_WINDOW) NaturalJoin(io.prestosql.sql.tree.NaturalJoin) Sets(com.google.common.collect.Sets) String.format(java.lang.String.format) Preconditions.checkState(com.google.common.base.Preconditions.checkState) List(java.util.List) INVALID_LIMIT_ROW_COUNT(io.prestosql.sql.analyzer.SemanticErrorCode.INVALID_LIMIT_ROW_COUNT) NONDETERMINISTIC_ORDER_BY_EXPRESSION_WITH_SELECT_DISTINCT(io.prestosql.sql.analyzer.SemanticErrorCode.NONDETERMINISTIC_ORDER_BY_EXPRESSION_WITH_SELECT_DISTINCT) SimpleGroupBy(io.prestosql.sql.tree.SimpleGroupBy) Optional(java.util.Optional) FrameBound(io.prestosql.sql.tree.FrameBound) MetadataUtil.createQualifiedObjectName(io.prestosql.metadata.MetadataUtil.createQualifiedObjectName) UpdateIndex(io.prestosql.sql.tree.UpdateIndex) MISSING_ORDER_BY(io.prestosql.sql.analyzer.SemanticErrorCode.MISSING_ORDER_BY) CUBE_NOT_FOUND(io.prestosql.spi.connector.StandardWarningCode.CUBE_NOT_FOUND) ORDER_BY_MUST_BE_IN_SELECT(io.prestosql.sql.analyzer.SemanticErrorCode.ORDER_BY_MUST_BE_IN_SELECT) HashMap(java.util.HashMap) Multimap(com.google.common.collect.Multimap) Objects.requireNonNull(java.util.Objects.requireNonNull) ExpressionRewriter(io.prestosql.sql.tree.ExpressionRewriter) SortItem(io.prestosql.sql.tree.SortItem) VerifyException(com.google.common.base.VerifyException) Iterator(java.util.Iterator) OrderBy(io.prestosql.sql.tree.OrderBy) MISSING_TABLE(io.prestosql.sql.analyzer.SemanticErrorCode.MISSING_TABLE) VIEW_ANALYSIS_ERROR(io.prestosql.sql.analyzer.SemanticErrorCode.VIEW_ANALYSIS_ERROR) Update(io.prestosql.sql.tree.Update) InsertCube(io.prestosql.sql.tree.InsertCube) Revoke(io.prestosql.sql.tree.Revoke) TableMetadata(io.prestosql.metadata.TableMetadata) CreateIndexMetadata(io.prestosql.spi.connector.CreateIndexMetadata) IndexClient(io.prestosql.spi.heuristicindex.IndexClient) ArrayList(java.util.ArrayList) UncheckedIOException(java.io.UncheckedIOException) IOException(java.io.IOException) UncheckedIOException(java.io.UncheckedIOException) NodeUtils.mapFromProperties(io.prestosql.sql.NodeUtils.mapFromProperties) SystemSessionProperties(io.prestosql.SystemSessionProperties) Properties(java.util.Properties) QualifiedObjectName(io.prestosql.spi.connector.QualifiedObjectName) MetadataUtil.createQualifiedObjectName(io.prestosql.metadata.MetadataUtil.createQualifiedObjectName) LinkedList(java.util.LinkedList) CreateIndex(io.prestosql.sql.tree.CreateIndex) Identifier(io.prestosql.sql.tree.Identifier) TableHandle(io.prestosql.spi.metadata.TableHandle) Pair(io.prestosql.spi.heuristicindex.Pair)

Example 3 with CreateIndex

use of io.prestosql.sql.tree.CreateIndex in project hetu-core by openlookeng.

the class CachedSqlQueryExecution method createPlan.

@Override
protected Plan createPlan(Analysis analysis, Session session, List<PlanOptimizer> planOptimizers, PlanNodeIdAllocator idAllocator, Metadata metadata, TypeAnalyzer typeAnalyzer, StatsCalculator statsCalculator, CostCalculator costCalculator, WarningCollector warningCollector) {
    Statement statement = analysis.getStatement();
    // Get relevant Session properties which may affect the resulting execution plan
    // Property to property value mapping
    Map<String, Object> systemSessionProperties = new HashMap<>();
    SystemSessionProperties sessionProperties = new SystemSessionProperties();
    for (PropertyMetadata<?> property : sessionProperties.getSessionProperties()) {
        systemSessionProperties.put(property.getName(), session.getSystemProperty(property.getName(), property.getJavaType()));
    }
    // if the original statement before rewriting is CreateIndex, set session to let connector know that pageMetadata should be enabled
    if (analysis.getOriginalStatement() instanceof CreateIndex || analysis.getOriginalStatement() instanceof UpdateIndex) {
        session.setPageMetadataEnabled(true);
    }
    // build list of fully qualified table names
    List<String> tableNames = new ArrayList<>();
    Map<String, TableStatistics> tableStatistics = new HashMap<>();
    // Get column name to column type to detect column type changes between queries more easily
    Map<String, Type> columnTypes = new HashMap<>();
    // Cacheable conditions:
    // 1. Caching must be enabled globally
    // 2. Caching must be enabled in the session
    // 3. There must not be any parameters in the query
    // TODO: remove requirement for empty params and implement parameter rewrite
    // 4. Methods in ConnectorTableHandle and ConnectorMetadata must be
    // overwritten to allow access to fully qualified table names and column names
    // 5. Statement must be an instance of Query and not contain CurrentX functions
    boolean cacheable = this.cache.isPresent() && isExecutionPlanCacheEnabled(session) && analysis.getParameters().isEmpty() && validateAndExtractTableAndColumns(analysis, metadata, session, tableNames, tableStatistics, columnTypes) && isCacheable(statement) && // create index and update index should not be cached
    (!(analysis.getOriginalStatement() instanceof CreateIndex || analysis.getOriginalStatement() instanceof UpdateIndex));
    cacheable = cacheable && !tableNames.isEmpty();
    if (!cacheable) {
        return super.createPlan(analysis, session, planOptimizers, idAllocator, metadata, typeAnalyzer, statsCalculator, costCalculator, warningCollector);
    }
    List<String> optimizers = new ArrayList<>();
    // build list of enabled optimizers and rules for cache key
    for (PlanOptimizer planOptimizer : planOptimizers) {
        if (planOptimizer instanceof IterativeOptimizer) {
            IterativeOptimizer iterativeOptimizer = (IterativeOptimizer) planOptimizer;
            Set<Rule<?>> rules = iterativeOptimizer.getRules();
            for (Rule rule : rules) {
                if (OptimizerUtils.isEnabledRule(rule, session)) {
                    optimizers.add(rule.getClass().getSimpleName());
                }
            }
        } else {
            if (OptimizerUtils.isEnabledLegacy(planOptimizer, session)) {
                optimizers.add(planOptimizer.getClass().getSimpleName());
            }
        }
    }
    Set<String> connectors = tableNames.stream().map(table -> table.substring(0, table.indexOf("."))).collect(Collectors.toSet());
    connectors.stream().forEach(connector -> {
        for (Map.Entry<String, String> property : session.getConnectorProperties(new CatalogName(connector)).entrySet()) {
            systemSessionProperties.put(connector + "." + property.getKey(), property.getValue());
        }
    });
    Plan plan;
    // TODO: Traverse the statement to build the key then combine tables/optimizers.. etc
    int key = SqlQueryExecutionCacheKeyGenerator.buildKey((Query) statement, tableNames, optimizers, columnTypes, session.getTimeZoneKey(), systemSessionProperties);
    CachedSqlQueryExecutionPlan cachedPlan = this.cache.get().getIfPresent(key);
    HetuLogicalPlanner logicalPlanner = new HetuLogicalPlanner(session, planOptimizers, idAllocator, metadata, typeAnalyzer, statsCalculator, costCalculator, warningCollector);
    PlanNode root;
    plan = cachedPlan != null ? cachedPlan.getPlan() : null;
    // that rely on system time
    if (plan != null && cachedPlan.getTimeZoneKey().equals(session.getTimeZoneKey()) && cachedPlan.getStatement().equals(statement) && session.getTransactionId().isPresent() && cachedPlan.getIdentity().getUser().equals(session.getIdentity().getUser())) {
        // TODO: traverse the statement and accept partial match
        root = plan.getRoot();
        boolean isValidCachePlan = tablesMatch(root, analysis.getTables());
        try {
            if (!isEqualBasicStatistics(cachedPlan.getTableStatistics(), tableStatistics, tableNames) || !isValidCachePlan) {
                for (TableHandle tableHandle : analysis.getTables()) {
                    tableStatistics.replace(tableHandle.getFullyQualifiedName(), metadata.getTableStatistics(session, tableHandle, Constraint.alwaysTrue(), true));
                }
                if (!cachedPlan.getTableStatistics().equals(tableStatistics) || !isValidCachePlan) {
                    // Table have changed, therfore the cached plan may no longer be applicable
                    throw new NoSuchElementException();
                }
            }
            // TableScanNode may contain the old transaction id.
            // The following logic rewrites the logical plan by replacing the TableScanNode with a new TableScanNode which
            // contains the new transaction id from session.
            root = SimplePlanRewriter.rewriteWith(new TableHandleRewriter(session, analysis, metadata), root);
        } catch (NoSuchElementException e) {
            // Cached plan is outdated
            // invalidate cache
            this.cache.get().invalidateAll();
            // Build a new plan
            plan = createAndCachePlan(key, logicalPlanner, statement, tableNames, tableStatistics, optimizers, analysis, columnTypes, systemSessionProperties);
            root = plan.getRoot();
        }
    } else {
        // Build a new plan
        for (TableHandle tableHandle : analysis.getTables()) {
            tableStatistics.replace(tableHandle.getFullyQualifiedName(), metadata.getTableStatistics(session, tableHandle, Constraint.alwaysTrue(), true));
        }
        plan = createAndCachePlan(key, logicalPlanner, statement, tableNames, tableStatistics, optimizers, analysis, columnTypes, systemSessionProperties);
        root = plan.getRoot();
    }
    // BeginTableWrite optimizer must be run at the end as the last optimization
    // due to a hack Hetu community added which also serves to updates
    // metadata in the nodes
    root = this.beginTableWrite.optimize(root, session, null, null, null, null);
    plan = update(plan, root);
    return plan;
}
Also used : TableStatistics(io.prestosql.spi.statistics.TableStatistics) QueryExplainer(io.prestosql.sql.analyzer.QueryExplainer) CostCalculator(io.prestosql.cost.CostCalculator) SystemSessionProperties(io.prestosql.SystemSessionProperties) DefaultTraversalVisitor(io.prestosql.sql.tree.DefaultTraversalVisitor) Plan(io.prestosql.sql.planner.Plan) SqlParser(io.prestosql.sql.parser.SqlParser) SystemTransactionHandle(io.prestosql.connector.system.SystemTransactionHandle) PartitioningScheme(io.prestosql.sql.planner.PartitioningScheme) TypeAnalyzer(io.prestosql.sql.planner.TypeAnalyzer) ExchangeNode(io.prestosql.sql.planner.plan.ExchangeNode) Statement(io.prestosql.sql.tree.Statement) WarningCollector(io.prestosql.execution.warnings.WarningCollector) CreateTable(io.prestosql.sql.tree.CreateTable) SystemSessionProperties.isExecutionPlanCacheEnabled(io.prestosql.SystemSessionProperties.isExecutionPlanCacheEnabled) Map(java.util.Map) PropertyMetadata(io.prestosql.spi.session.PropertyMetadata) InformationSchemaTransactionHandle(io.prestosql.connector.informationschema.InformationSchemaTransactionHandle) SnapshotUtils(io.prestosql.snapshot.SnapshotUtils) Partitioning(io.prestosql.sql.planner.Partitioning) Type(io.prestosql.spi.type.Type) BeginTableWrite(io.prestosql.sql.planner.optimizations.BeginTableWrite) StatsCalculator(io.prestosql.cost.StatsCalculator) Constraint(io.prestosql.spi.connector.Constraint) HeuristicIndexerManager(io.prestosql.heuristicindex.HeuristicIndexerManager) PrestoException(io.prestosql.spi.PrestoException) AccessControl(io.prestosql.security.AccessControl) Collection(java.util.Collection) CatalogName(io.prestosql.spi.connector.CatalogName) CreateIndex(io.prestosql.sql.tree.CreateIndex) TableScanNode(io.prestosql.spi.plan.TableScanNode) Set(java.util.Set) LocationFactory(io.prestosql.execution.LocationFactory) RemoteTaskFactory(io.prestosql.execution.RemoteTaskFactory) PlanNode(io.prestosql.spi.plan.PlanNode) UUID(java.util.UUID) Collectors(java.util.stream.Collectors) Metadata(io.prestosql.metadata.Metadata) LogicalPlanner(io.prestosql.sql.planner.LogicalPlanner) OptimizerUtils(io.prestosql.utils.OptimizerUtils) ReuseExchangeOperator(io.prestosql.spi.operator.ReuseExchangeOperator) List(java.util.List) SplitSchedulerStats(io.prestosql.execution.scheduler.SplitSchedulerStats) ConnectorTransactionHandle(io.prestosql.spi.connector.ConnectorTransactionHandle) Optional(java.util.Optional) Analysis(io.prestosql.sql.analyzer.Analysis) Queue(java.util.Queue) QueryPreparer(io.prestosql.execution.QueryPreparer) NodePartitioningManager(io.prestosql.sql.planner.NodePartitioningManager) UpdateIndex(io.prestosql.sql.tree.UpdateIndex) HashMap(java.util.HashMap) NodeScheduler(io.prestosql.execution.scheduler.NodeScheduler) CurrentPath(io.prestosql.sql.tree.CurrentPath) TableHandle(io.prestosql.spi.metadata.TableHandle) QueryStateMachine(io.prestosql.execution.QueryStateMachine) PlanFragmenter(io.prestosql.sql.planner.PlanFragmenter) ArrayList(java.util.ArrayList) ExecutionPolicy(io.prestosql.execution.scheduler.ExecutionPolicy) CreateTableAsSelect(io.prestosql.sql.tree.CreateTableAsSelect) SqlQueryExecution(io.prestosql.execution.SqlQueryExecution) Session(io.prestosql.Session) SimplePlanRewriter(io.prestosql.sql.planner.plan.SimplePlanRewriter) ScheduledExecutorService(java.util.concurrent.ScheduledExecutorService) NodeTaskMap(io.prestosql.execution.NodeTaskMap) LinkedList(java.util.LinkedList) NoSuchElementException(java.util.NoSuchElementException) ExecutorService(java.util.concurrent.ExecutorService) Symbol(io.prestosql.spi.plan.Symbol) CurrentTime(io.prestosql.sql.tree.CurrentTime) Query(io.prestosql.sql.tree.Query) Rule(io.prestosql.sql.planner.iterative.Rule) ColumnMetadata(io.prestosql.spi.connector.ColumnMetadata) ConnectorTableHandle(io.prestosql.spi.connector.ConnectorTableHandle) IterativeOptimizer(io.prestosql.sql.planner.iterative.IterativeOptimizer) CurrentUser(io.prestosql.sql.tree.CurrentUser) DynamicFilterService(io.prestosql.dynamicfilter.DynamicFilterService) CubeManager(io.prestosql.cube.CubeManager) TransactionId(io.prestosql.transaction.TransactionId) PartitioningHandle(io.prestosql.sql.planner.PartitioningHandle) ColumnHandle(io.prestosql.spi.connector.ColumnHandle) SplitManager(io.prestosql.split.SplitManager) StateStoreProvider(io.prestosql.statestore.StateStoreProvider) PlanNodeIdAllocator(io.prestosql.spi.plan.PlanNodeIdAllocator) PlanOptimizer(io.prestosql.sql.planner.optimizations.PlanOptimizer) Cache(com.google.common.cache.Cache) GlobalSystemTransactionHandle(io.prestosql.connector.system.GlobalSystemTransactionHandle) FailureDetector(io.prestosql.failuredetector.FailureDetector) PlanOptimizer(io.prestosql.sql.planner.optimizations.PlanOptimizer) HashMap(java.util.HashMap) ArrayList(java.util.ArrayList) CreateIndex(io.prestosql.sql.tree.CreateIndex) PlanNode(io.prestosql.spi.plan.PlanNode) Statement(io.prestosql.sql.tree.Statement) UpdateIndex(io.prestosql.sql.tree.UpdateIndex) Plan(io.prestosql.sql.planner.Plan) Constraint(io.prestosql.spi.connector.Constraint) Type(io.prestosql.spi.type.Type) IterativeOptimizer(io.prestosql.sql.planner.iterative.IterativeOptimizer) TableStatistics(io.prestosql.spi.statistics.TableStatistics) CatalogName(io.prestosql.spi.connector.CatalogName) TableHandle(io.prestosql.spi.metadata.TableHandle) ConnectorTableHandle(io.prestosql.spi.connector.ConnectorTableHandle) Rule(io.prestosql.sql.planner.iterative.Rule) Map(java.util.Map) HashMap(java.util.HashMap) NodeTaskMap(io.prestosql.execution.NodeTaskMap) NoSuchElementException(java.util.NoSuchElementException) SystemSessionProperties(io.prestosql.SystemSessionProperties)

Aggregations

Session (io.prestosql.Session)2 SystemSessionProperties (io.prestosql.SystemSessionProperties)2 CubeManager (io.prestosql.cube.CubeManager)2 WarningCollector (io.prestosql.execution.warnings.WarningCollector)2 HeuristicIndexerManager (io.prestosql.heuristicindex.HeuristicIndexerManager)2 Metadata (io.prestosql.metadata.Metadata)2 CreateIndexMetadata (io.prestosql.spi.connector.CreateIndexMetadata)2 Type (io.prestosql.spi.type.Type)2 CreateIndex (io.prestosql.sql.tree.CreateIndex)2 Property (io.prestosql.sql.tree.Property)2 ArrayList (java.util.ArrayList)2 HashMap (java.util.HashMap)2 Properties (java.util.Properties)2 Joiner (com.google.common.base.Joiner)1 Preconditions.checkArgument (com.google.common.base.Preconditions.checkArgument)1 Preconditions.checkState (com.google.common.base.Preconditions.checkState)1 Throwables.throwIfInstanceOf (com.google.common.base.Throwables.throwIfInstanceOf)1 VerifyException (com.google.common.base.VerifyException)1 Cache (com.google.common.cache.Cache)1 ImmutableList (com.google.common.collect.ImmutableList)1