Search in sources :

Example 6 with Expression

use of io.trino.sql.tree.Expression in project trino by trinodb.

the class InlineProjections method extractInliningTargets.

private static Set<Symbol> extractInliningTargets(PlannerContext plannerContext, ProjectNode parent, ProjectNode child, Session session, TypeAnalyzer typeAnalyzer, TypeProvider types) {
    // candidates for inlining are
    // 1. references to simple constants or symbol references
    // 2. references to complex expressions that
    // a. are not inputs to try() expressions
    // b. appear only once across all expressions
    // c. are not identity projections
    // which come from the child, as opposed to an enclosing scope.
    Set<Symbol> childOutputSet = ImmutableSet.copyOf(child.getOutputSymbols());
    Map<Symbol, Long> dependencies = parent.getAssignments().getExpressions().stream().flatMap(expression -> SymbolsExtractor.extractAll(expression).stream()).filter(childOutputSet::contains).collect(Collectors.groupingBy(Function.identity(), Collectors.counting()));
    // find references to simple constants or symbol references
    Set<Symbol> basicReferences = dependencies.keySet().stream().filter(input -> isEffectivelyLiteral(plannerContext, session, child.getAssignments().get(input)) || child.getAssignments().get(input) instanceof SymbolReference).filter(// skip identities, otherwise, this rule will keep firing forever
    input -> !child.getAssignments().isIdentity(input)).collect(toSet());
    // exclude any complex inputs to TRY expressions. Inlining them would potentially
    // change the semantics of those expressions
    Set<Symbol> tryArguments = parent.getAssignments().getExpressions().stream().flatMap(expression -> extractTryArguments(expression).stream()).collect(toSet());
    Set<Symbol> singletons = dependencies.entrySet().stream().filter(// reference appears just once across all expressions in parent project node
    entry -> entry.getValue() == 1).filter(// they are not inputs to TRY. Otherwise, inlining might change semantics
    entry -> !tryArguments.contains(entry.getKey())).filter(// skip identities, otherwise, this rule will keep firing forever
    entry -> !child.getAssignments().isIdentity(entry.getKey())).filter(entry -> {
        // skip dereferences, otherwise, inlining can cause conflicts with PushdownDereferences
        Expression assignment = child.getAssignments().get(entry.getKey());
        if (assignment instanceof SubscriptExpression) {
            if (typeAnalyzer.getType(session, types, ((SubscriptExpression) assignment).getBase()) instanceof RowType) {
                return false;
            }
        }
        return true;
    }).map(Map.Entry::getKey).collect(toSet());
    return Sets.union(singletons, basicReferences);
}
Also used : Function(java.util.function.Function) Capture.newCapture(io.trino.matching.Capture.newCapture) PlanNode(io.trino.sql.planner.plan.PlanNode) SubscriptExpression(io.trino.sql.tree.SubscriptExpression) ExpressionSymbolInliner.inlineSymbols(io.trino.sql.planner.ExpressionSymbolInliner.inlineSymbols) ImmutableList(com.google.common.collect.ImmutableList) Map(java.util.Map) Objects.requireNonNull(java.util.Objects.requireNonNull) Rule(io.trino.sql.planner.iterative.Rule) SymbolsExtractor(io.trino.sql.planner.SymbolsExtractor) TryExpression(io.trino.sql.tree.TryExpression) ProjectNode(io.trino.sql.planner.plan.ProjectNode) Collectors.toSet(java.util.stream.Collectors.toSet) Symbol(io.trino.sql.planner.Symbol) RowType(io.trino.spi.type.RowType) ImmutableSet(com.google.common.collect.ImmutableSet) Assignments(io.trino.sql.planner.plan.Assignments) Set(java.util.Set) Collectors(java.util.stream.Collectors) Sets(com.google.common.collect.Sets) Capture(io.trino.matching.Capture) ExpressionUtils.isEffectivelyLiteral(io.trino.sql.ExpressionUtils.isEffectivelyLiteral) Pattern(io.trino.matching.Pattern) TypeAnalyzer(io.trino.sql.planner.TypeAnalyzer) AstUtils(io.trino.sql.util.AstUtils) Patterns.source(io.trino.sql.planner.plan.Patterns.source) SymbolReference(io.trino.sql.tree.SymbolReference) Captures(io.trino.matching.Captures) TypeProvider(io.trino.sql.planner.TypeProvider) Optional(java.util.Optional) Expression(io.trino.sql.tree.Expression) Patterns.project(io.trino.sql.planner.plan.Patterns.project) Session(io.trino.Session) PlannerContext(io.trino.sql.PlannerContext) SubscriptExpression(io.trino.sql.tree.SubscriptExpression) TryExpression(io.trino.sql.tree.TryExpression) Expression(io.trino.sql.tree.Expression) Symbol(io.trino.sql.planner.Symbol) SymbolReference(io.trino.sql.tree.SymbolReference) SubscriptExpression(io.trino.sql.tree.SubscriptExpression) RowType(io.trino.spi.type.RowType) Map(java.util.Map)

Example 7 with Expression

use of io.trino.sql.tree.Expression in project trino by trinodb.

the class PruneApplyColumns method pushDownProjectOff.

@Override
protected Optional<PlanNode> pushDownProjectOff(Context context, ApplyNode applyNode, Set<Symbol> referencedOutputs) {
    // remove unused apply node
    if (intersection(applyNode.getSubqueryAssignments().getSymbols(), referencedOutputs).isEmpty()) {
        return Optional.of(applyNode.getInput());
    }
    // extract referenced assignments
    ImmutableSet.Builder<Symbol> requiredAssignmentsSymbols = ImmutableSet.builder();
    Assignments.Builder newSubqueryAssignments = Assignments.builder();
    for (Map.Entry<Symbol, Expression> entry : applyNode.getSubqueryAssignments().entrySet()) {
        if (referencedOutputs.contains(entry.getKey())) {
            requiredAssignmentsSymbols.addAll(extractUnique(entry.getValue()));
            newSubqueryAssignments.put(entry);
        }
    }
    // prune subquery symbols
    Optional<PlanNode> newSubquery = restrictOutputs(context.getIdAllocator(), applyNode.getSubquery(), requiredAssignmentsSymbols.build());
    // prune input symbols
    Set<Symbol> requiredInputSymbols = ImmutableSet.<Symbol>builder().addAll(referencedOutputs).addAll(applyNode.getCorrelation()).addAll(requiredAssignmentsSymbols.build()).build();
    Optional<PlanNode> newInput = restrictOutputs(context.getIdAllocator(), applyNode.getInput(), requiredInputSymbols);
    boolean pruned = newSubquery.isPresent() || newInput.isPresent() || newSubqueryAssignments.build().size() < applyNode.getSubqueryAssignments().size();
    if (pruned) {
        return Optional.of(new ApplyNode(applyNode.getId(), newInput.orElse(applyNode.getInput()), newSubquery.orElse(applyNode.getSubquery()), newSubqueryAssignments.build(), applyNode.getCorrelation(), applyNode.getOriginSubquery()));
    }
    return Optional.empty();
}
Also used : Symbol(io.trino.sql.planner.Symbol) ApplyNode(io.trino.sql.planner.plan.ApplyNode) Assignments(io.trino.sql.planner.plan.Assignments) PlanNode(io.trino.sql.planner.plan.PlanNode) ImmutableSet(com.google.common.collect.ImmutableSet) Expression(io.trino.sql.tree.Expression) Map(java.util.Map)

Example 8 with Expression

use of io.trino.sql.tree.Expression in project trino by trinodb.

the class RevokeRolesTask method execute.

@Override
public ListenableFuture<Void> execute(RevokeRoles statement, QueryStateMachine stateMachine, List<Expression> parameters, WarningCollector warningCollector) {
    Session session = stateMachine.getSession();
    Set<String> roles = statement.getRoles().stream().map(role -> role.getValue().toLowerCase(Locale.ENGLISH)).collect(toImmutableSet());
    Set<TrinoPrincipal> grantees = statement.getGrantees().stream().map(MetadataUtil::createPrincipal).collect(toImmutableSet());
    boolean adminOption = statement.isAdminOption();
    Optional<TrinoPrincipal> grantor = statement.getGrantor().map(specification -> createPrincipal(session, specification));
    Optional<String> catalog = processRoleCommandCatalog(metadata, session, statement, statement.getCatalog().map(Identifier::getValue));
    Set<String> specifiedRoles = new LinkedHashSet<>();
    specifiedRoles.addAll(roles);
    grantees.stream().filter(principal -> principal.getType() == ROLE).map(TrinoPrincipal::getName).forEach(specifiedRoles::add);
    if (grantor.isPresent() && grantor.get().getType() == ROLE) {
        specifiedRoles.add(grantor.get().getName());
    }
    for (String role : specifiedRoles) {
        checkRoleExists(session, statement, metadata, role, catalog);
    }
    accessControl.checkCanRevokeRoles(session.toSecurityContext(), roles, grantees, adminOption, grantor, catalog);
    metadata.revokeRoles(session, roles, grantees, adminOption, grantor, catalog);
    return immediateVoidFuture();
}
Also used : Futures.immediateVoidFuture(com.google.common.util.concurrent.Futures.immediateVoidFuture) ListenableFuture(com.google.common.util.concurrent.ListenableFuture) MetadataUtil.checkRoleExists(io.trino.metadata.MetadataUtil.checkRoleExists) MetadataUtil(io.trino.metadata.MetadataUtil) RevokeRoles(io.trino.sql.tree.RevokeRoles) Set(java.util.Set) ROLE(io.trino.spi.security.PrincipalType.ROLE) Inject(javax.inject.Inject) List(java.util.List) AccessControl(io.trino.security.AccessControl) TrinoPrincipal(io.trino.spi.security.TrinoPrincipal) MetadataUtil.createPrincipal(io.trino.metadata.MetadataUtil.createPrincipal) Locale(java.util.Locale) Objects.requireNonNull(java.util.Objects.requireNonNull) WarningCollector(io.trino.execution.warnings.WarningCollector) Metadata(io.trino.metadata.Metadata) Optional(java.util.Optional) ImmutableSet.toImmutableSet(com.google.common.collect.ImmutableSet.toImmutableSet) Expression(io.trino.sql.tree.Expression) MetadataUtil.processRoleCommandCatalog(io.trino.metadata.MetadataUtil.processRoleCommandCatalog) Identifier(io.trino.sql.tree.Identifier) LinkedHashSet(java.util.LinkedHashSet) Session(io.trino.Session) LinkedHashSet(java.util.LinkedHashSet) TrinoPrincipal(io.trino.spi.security.TrinoPrincipal) Session(io.trino.Session)

Example 9 with Expression

use of io.trino.sql.tree.Expression in project trino by trinodb.

the class SetSchemaAuthorizationTask method execute.

@Override
public ListenableFuture<Void> execute(SetSchemaAuthorization statement, QueryStateMachine stateMachine, List<Expression> parameters, WarningCollector warningCollector) {
    Session session = stateMachine.getSession();
    CatalogSchemaName source = createCatalogSchemaName(session, statement, Optional.of(statement.getSource()));
    if (!metadata.schemaExists(session, source)) {
        throw semanticException(SCHEMA_NOT_FOUND, statement, "Schema '%s' does not exist", source);
    }
    TrinoPrincipal principal = createPrincipal(statement.getPrincipal());
    checkRoleExists(session, statement, metadata, principal, Optional.of(source.getCatalogName()).filter(catalog -> metadata.isCatalogManagedSecurity(session, catalog)));
    accessControl.checkCanSetSchemaAuthorization(session.toSecurityContext(), source, principal);
    metadata.setSchemaAuthorization(session, source, principal);
    return immediateVoidFuture();
}
Also used : Futures.immediateVoidFuture(com.google.common.util.concurrent.Futures.immediateVoidFuture) ListenableFuture(com.google.common.util.concurrent.ListenableFuture) MetadataUtil.checkRoleExists(io.trino.metadata.MetadataUtil.checkRoleExists) Inject(javax.inject.Inject) List(java.util.List) AccessControl(io.trino.security.AccessControl) TrinoPrincipal(io.trino.spi.security.TrinoPrincipal) MetadataUtil.createPrincipal(io.trino.metadata.MetadataUtil.createPrincipal) Objects.requireNonNull(java.util.Objects.requireNonNull) WarningCollector(io.trino.execution.warnings.WarningCollector) CatalogSchemaName(io.trino.spi.connector.CatalogSchemaName) Metadata(io.trino.metadata.Metadata) SetSchemaAuthorization(io.trino.sql.tree.SetSchemaAuthorization) Optional(java.util.Optional) Expression(io.trino.sql.tree.Expression) MetadataUtil.createCatalogSchemaName(io.trino.metadata.MetadataUtil.createCatalogSchemaName) SemanticExceptions.semanticException(io.trino.sql.analyzer.SemanticExceptions.semanticException) Session(io.trino.Session) SCHEMA_NOT_FOUND(io.trino.spi.StandardErrorCode.SCHEMA_NOT_FOUND) CatalogSchemaName(io.trino.spi.connector.CatalogSchemaName) MetadataUtil.createCatalogSchemaName(io.trino.metadata.MetadataUtil.createCatalogSchemaName) TrinoPrincipal(io.trino.spi.security.TrinoPrincipal) Session(io.trino.Session)

Example 10 with Expression

use of io.trino.sql.tree.Expression in project trino by trinodb.

the class SetTableAuthorizationTask method execute.

@Override
public ListenableFuture<Void> execute(SetTableAuthorization statement, QueryStateMachine stateMachine, List<Expression> parameters, WarningCollector warningCollector) {
    Session session = stateMachine.getSession();
    QualifiedObjectName tableName = createQualifiedObjectName(session, statement, statement.getSource());
    getRequiredCatalogHandle(metadata, session, statement, tableName.getCatalogName());
    if (metadata.getTableHandle(session, tableName).isEmpty()) {
        throw semanticException(TABLE_NOT_FOUND, statement, "Table '%s' does not exist", tableName);
    }
    TrinoPrincipal principal = createPrincipal(statement.getPrincipal());
    checkRoleExists(session, statement, metadata, principal, Optional.of(tableName.getCatalogName()).filter(catalog -> metadata.isCatalogManagedSecurity(session, catalog)));
    accessControl.checkCanSetTableAuthorization(session.toSecurityContext(), tableName, principal);
    metadata.setTableAuthorization(session, tableName.asCatalogSchemaTableName(), principal);
    return immediateVoidFuture();
}
Also used : Futures.immediateVoidFuture(com.google.common.util.concurrent.Futures.immediateVoidFuture) ListenableFuture(com.google.common.util.concurrent.ListenableFuture) MetadataUtil.checkRoleExists(io.trino.metadata.MetadataUtil.checkRoleExists) MetadataUtil.getRequiredCatalogHandle(io.trino.metadata.MetadataUtil.getRequiredCatalogHandle) Inject(javax.inject.Inject) List(java.util.List) QualifiedObjectName(io.trino.metadata.QualifiedObjectName) AccessControl(io.trino.security.AccessControl) TrinoPrincipal(io.trino.spi.security.TrinoPrincipal) MetadataUtil.createPrincipal(io.trino.metadata.MetadataUtil.createPrincipal) MetadataUtil.createQualifiedObjectName(io.trino.metadata.MetadataUtil.createQualifiedObjectName) TABLE_NOT_FOUND(io.trino.spi.StandardErrorCode.TABLE_NOT_FOUND) Objects.requireNonNull(java.util.Objects.requireNonNull) WarningCollector(io.trino.execution.warnings.WarningCollector) Metadata(io.trino.metadata.Metadata) Optional(java.util.Optional) Expression(io.trino.sql.tree.Expression) SetTableAuthorization(io.trino.sql.tree.SetTableAuthorization) SemanticExceptions.semanticException(io.trino.sql.analyzer.SemanticExceptions.semanticException) Session(io.trino.Session) TrinoPrincipal(io.trino.spi.security.TrinoPrincipal) QualifiedObjectName(io.trino.metadata.QualifiedObjectName) MetadataUtil.createQualifiedObjectName(io.trino.metadata.MetadataUtil.createQualifiedObjectName) Session(io.trino.Session)

Aggregations

Expression (io.trino.sql.tree.Expression)257 ComparisonExpression (io.trino.sql.tree.ComparisonExpression)111 ImmutableList (com.google.common.collect.ImmutableList)88 Symbol (io.trino.sql.planner.Symbol)77 ProjectNode (io.trino.sql.planner.plan.ProjectNode)65 PlanNode (io.trino.sql.planner.plan.PlanNode)63 Map (java.util.Map)63 NotExpression (io.trino.sql.tree.NotExpression)62 Test (org.testng.annotations.Test)58 Objects.requireNonNull (java.util.Objects.requireNonNull)57 Assignments (io.trino.sql.planner.plan.Assignments)55 InListExpression (io.trino.sql.tree.InListExpression)55 ImmutableList.toImmutableList (com.google.common.collect.ImmutableList.toImmutableList)54 SymbolReference (io.trino.sql.tree.SymbolReference)53 Type (io.trino.spi.type.Type)52 List (java.util.List)52 Set (java.util.Set)52 SubscriptExpression (io.trino.sql.tree.SubscriptExpression)48 ImmutableMap (com.google.common.collect.ImmutableMap)47 Optional (java.util.Optional)47