Search in sources :

Example 1 with Identifier

use of io.trino.sql.tree.Identifier 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 2 with Identifier

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

the class PatternRecognitionAnalyzer method analyze.

public static PatternRecognitionAnalysis analyze(List<SubsetDefinition> subsets, List<VariableDefinition> variableDefinitions, List<MeasureDefinition> measures, RowPattern pattern, Optional<SkipTo> skipTo) {
    // extract label names (Identifiers) from PATTERN and SUBSET clauses. create labels respecting SQL identifier semantics
    Set<String> primaryLabels = extractExpressions(ImmutableList.of(pattern), Identifier.class).stream().map(PatternRecognitionAnalyzer::label).collect(toImmutableSet());
    List<String> unionLabels = subsets.stream().map(SubsetDefinition::getName).map(PatternRecognitionAnalyzer::label).collect(toImmutableList());
    // analyze SUBSET
    Set<String> unique = new HashSet<>();
    for (SubsetDefinition subset : subsets) {
        String label = label(subset.getName());
        if (primaryLabels.contains(label)) {
            throw semanticException(INVALID_LABEL, subset.getName(), "union pattern variable name: %s is a duplicate of primary pattern variable name", subset.getName());
        }
        if (!unique.add(label)) {
            throw semanticException(INVALID_LABEL, subset.getName(), "union pattern variable name: %s is declared twice", subset.getName());
        }
        for (Identifier element : subset.getIdentifiers()) {
            // TODO can there be repetitions in the list of subset elements? (currently repetitions are supported)
            if (!primaryLabels.contains(label(element))) {
                throw semanticException(INVALID_LABEL, element, "subset element: %s is not a primary pattern variable", element);
            }
        }
    }
    // analyze DEFINE
    unique = new HashSet<>();
    for (VariableDefinition definition : variableDefinitions) {
        String label = label(definition.getName());
        if (!primaryLabels.contains(label)) {
            throw semanticException(INVALID_LABEL, definition.getName(), "defined variable: %s is not a primary pattern variable", definition.getName());
        }
        if (!unique.add(label)) {
            throw semanticException(INVALID_LABEL, definition.getName(), "pattern variable with name: %s is defined twice", definition.getName());
        }
        // DEFINE clause only supports RUNNING semantics which is default
        Expression expression = definition.getExpression();
        extractExpressions(ImmutableList.of(expression), FunctionCall.class).stream().filter(functionCall -> functionCall.getProcessingMode().map(mode -> mode.getMode() == FINAL).orElse(false)).findFirst().ifPresent(functionCall -> {
            throw semanticException(INVALID_PROCESSING_MODE, functionCall.getProcessingMode().get(), "FINAL semantics is not supported in DEFINE clause");
        });
    }
    // record primary labels without definitions. they are implicitly associated with `true` condition
    Set<String> undefinedLabels = Sets.difference(primaryLabels, unique);
    // validate pattern quantifiers
    ImmutableMap.Builder<NodeRef<RangeQuantifier>, Range> ranges = ImmutableMap.builder();
    preOrder(pattern).filter(RangeQuantifier.class::isInstance).map(RangeQuantifier.class::cast).forEach(quantifier -> {
        Optional<Long> atLeast = quantifier.getAtLeast().map(LongLiteral::getValue);
        atLeast.ifPresent(value -> {
            if (value < 0) {
                throw semanticException(NUMERIC_VALUE_OUT_OF_RANGE, quantifier, "Pattern quantifier lower bound must be greater than or equal to 0");
            }
            if (value > Integer.MAX_VALUE) {
                throw semanticException(NUMERIC_VALUE_OUT_OF_RANGE, quantifier, "Pattern quantifier lower bound must not exceed " + Integer.MAX_VALUE);
            }
        });
        Optional<Long> atMost = quantifier.getAtMost().map(LongLiteral::getValue);
        atMost.ifPresent(value -> {
            if (value < 1) {
                throw semanticException(NUMERIC_VALUE_OUT_OF_RANGE, quantifier, "Pattern quantifier upper bound must be greater than or equal to 1");
            }
            if (value > Integer.MAX_VALUE) {
                throw semanticException(NUMERIC_VALUE_OUT_OF_RANGE, quantifier, "Pattern quantifier upper bound must not exceed " + Integer.MAX_VALUE);
            }
        });
        if (atLeast.isPresent() && atMost.isPresent()) {
            if (atLeast.get() > atMost.get()) {
                throw semanticException(INVALID_RANGE, quantifier, "Pattern quantifier lower bound must not exceed upper bound");
            }
        }
        ranges.put(NodeRef.of(quantifier), new Range(atLeast.map(Math::toIntExact), atMost.map(Math::toIntExact)));
    });
    // validate AFTER MATCH SKIP
    Set<String> allLabels = ImmutableSet.<String>builder().addAll(primaryLabels).addAll(unionLabels).build();
    skipTo.flatMap(SkipTo::getIdentifier).ifPresent(identifier -> {
        String label = label(identifier);
        if (!allLabels.contains(label)) {
            throw semanticException(INVALID_LABEL, identifier, "%s is not a primary or union pattern variable", identifier);
        }
    });
    // check no prohibited nesting: cannot nest one row pattern recognition within another
    List<Expression> expressions = Streams.concat(measures.stream().map(MeasureDefinition::getExpression), variableDefinitions.stream().map(VariableDefinition::getExpression)).collect(toImmutableList());
    expressions.forEach(expression -> preOrder(expression).filter(child -> child instanceof PatternRecognitionRelation || child instanceof RowPattern).findFirst().ifPresent(nested -> {
        throw semanticException(NESTED_ROW_PATTERN_RECOGNITION, nested, "nested row pattern recognition in row pattern recognition");
    }));
    return new PatternRecognitionAnalysis(allLabels, undefinedLabels, ranges.buildOrThrow());
}
Also used : AnchorPattern(io.trino.sql.tree.AnchorPattern) ExpressionTreeUtils.extractExpressions(io.trino.sql.analyzer.ExpressionTreeUtils.extractExpressions) MeasureDefinition(io.trino.sql.tree.MeasureDefinition) INVALID_ROW_PATTERN(io.trino.spi.StandardErrorCode.INVALID_ROW_PATTERN) SkipTo(io.trino.sql.tree.SkipTo) INVALID_LABEL(io.trino.spi.StandardErrorCode.INVALID_LABEL) Range(io.trino.sql.analyzer.Analysis.Range) SubsetDefinition(io.trino.sql.tree.SubsetDefinition) RangeQuantifier(io.trino.sql.tree.RangeQuantifier) HashSet(java.util.HashSet) NOT_SUPPORTED(io.trino.spi.StandardErrorCode.NOT_SUPPORTED) ImmutableList(com.google.common.collect.ImmutableList) LongLiteral(io.trino.sql.tree.LongLiteral) ExcludedPattern(io.trino.sql.tree.ExcludedPattern) NodeRef(io.trino.sql.tree.NodeRef) Map(java.util.Map) Objects.requireNonNull(java.util.Objects.requireNonNull) ImmutableSet.toImmutableSet(com.google.common.collect.ImmutableSet.toImmutableSet) RowPattern(io.trino.sql.tree.RowPattern) FunctionCall(io.trino.sql.tree.FunctionCall) SemanticExceptions.semanticException(io.trino.sql.analyzer.SemanticExceptions.semanticException) Identifier(io.trino.sql.tree.Identifier) NUMERIC_VALUE_OUT_OF_RANGE(io.trino.spi.StandardErrorCode.NUMERIC_VALUE_OUT_OF_RANGE) ImmutableSet(com.google.common.collect.ImmutableSet) RowsPerMatch(io.trino.sql.tree.PatternRecognitionRelation.RowsPerMatch) ImmutableMap(com.google.common.collect.ImmutableMap) ImmutableList.toImmutableList(com.google.common.collect.ImmutableList.toImmutableList) PatternRecognitionRelation(io.trino.sql.tree.PatternRecognitionRelation) Set(java.util.Set) NESTED_ROW_PATTERN_RECOGNITION(io.trino.spi.StandardErrorCode.NESTED_ROW_PATTERN_RECOGNITION) VariableDefinition(io.trino.sql.tree.VariableDefinition) Streams(com.google.common.collect.Streams) AstUtils.preOrder(io.trino.sql.util.AstUtils.preOrder) Sets(com.google.common.collect.Sets) INVALID_PATTERN_RECOGNITION_FUNCTION(io.trino.spi.StandardErrorCode.INVALID_PATTERN_RECOGNITION_FUNCTION) List(java.util.List) INVALID_RANGE(io.trino.spi.StandardErrorCode.INVALID_RANGE) INVALID_PROCESSING_MODE(io.trino.spi.StandardErrorCode.INVALID_PROCESSING_MODE) PatternSearchMode(io.trino.sql.tree.PatternSearchMode) Optional(java.util.Optional) Expression(io.trino.sql.tree.Expression) FINAL(io.trino.sql.tree.ProcessingMode.Mode.FINAL) VariableDefinition(io.trino.sql.tree.VariableDefinition) LongLiteral(io.trino.sql.tree.LongLiteral) Range(io.trino.sql.analyzer.Analysis.Range) RangeQuantifier(io.trino.sql.tree.RangeQuantifier) MeasureDefinition(io.trino.sql.tree.MeasureDefinition) ImmutableMap(com.google.common.collect.ImmutableMap) PatternRecognitionRelation(io.trino.sql.tree.PatternRecognitionRelation) NodeRef(io.trino.sql.tree.NodeRef) SubsetDefinition(io.trino.sql.tree.SubsetDefinition) Identifier(io.trino.sql.tree.Identifier) Expression(io.trino.sql.tree.Expression) RowPattern(io.trino.sql.tree.RowPattern) HashSet(java.util.HashSet)

Example 3 with Identifier

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

the class CanonicalizationAware method canonicalizationAwareComparison.

public static Boolean canonicalizationAwareComparison(Node left, Node right) {
    if (left instanceof Identifier && right instanceof Identifier) {
        Identifier leftIdentifier = (Identifier) left;
        Identifier rightIdentifier = (Identifier) right;
        return leftIdentifier.getCanonicalValue().equals(rightIdentifier.getCanonicalValue());
    }
    return null;
}
Also used : Identifier(io.trino.sql.tree.Identifier)

Example 4 with Identifier

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

the class ExpressionAnalyzer method isPatternRecognitionFunction.

public static boolean isPatternRecognitionFunction(FunctionCall node) {
    QualifiedName qualifiedName = node.getName();
    if (qualifiedName.getParts().size() > 1) {
        return false;
    }
    Identifier identifier = qualifiedName.getOriginalParts().get(0);
    if (identifier.isDelimited()) {
        return false;
    }
    String name = identifier.getValue().toUpperCase(ENGLISH);
    return name.equals("FIRST") || name.equals("LAST") || name.equals("PREV") || name.equals("NEXT") || name.equals("CLASSIFIER") || name.equals("MATCH_NUMBER");
}
Also used : Identifier(io.trino.sql.tree.Identifier) QualifiedName(io.trino.sql.tree.QualifiedName)

Example 5 with Identifier

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

the class TestSetTimeZoneTask method testSetTimeZoneIntervalDayTimeTypeInvalidFunctionCall.

@Test
public void testSetTimeZoneIntervalDayTimeTypeInvalidFunctionCall() {
    QueryStateMachine stateMachine = createQueryStateMachine("SET TIME ZONE parse_duration('3601s')");
    SetTimeZone setTimeZone = new SetTimeZone(new NodeLocation(1, 1), Optional.of(new FunctionCall(new NodeLocation(1, 24), QualifiedName.of(ImmutableList.of(new Identifier(new NodeLocation(1, 24), "parse_duration", false))), ImmutableList.of(new StringLiteral(new NodeLocation(1, 39), "3601s")))));
    assertThatThrownBy(() -> executeSetTimeZone(setTimeZone, stateMachine)).isInstanceOf(TrinoException.class).hasMessage("Invalid time zone offset interval: interval contains seconds");
}
Also used : Identifier(io.trino.sql.tree.Identifier) NodeLocation(io.trino.sql.tree.NodeLocation) StringLiteral(io.trino.sql.tree.StringLiteral) SetTimeZone(io.trino.sql.tree.SetTimeZone) TrinoException(io.trino.spi.TrinoException) FunctionCall(io.trino.sql.tree.FunctionCall) Test(org.testng.annotations.Test)

Aggregations

Identifier (io.trino.sql.tree.Identifier)71 QueryUtil.quotedIdentifier (io.trino.sql.QueryUtil.quotedIdentifier)37 Test (org.junit.jupiter.api.Test)37 FunctionCall (io.trino.sql.tree.FunctionCall)19 StringLiteral (io.trino.sql.tree.StringLiteral)19 LongLiteral (io.trino.sql.tree.LongLiteral)18 Test (org.testng.annotations.Test)15 CreateTable (io.trino.sql.tree.CreateTable)14 Property (io.trino.sql.tree.Property)14 Expression (io.trino.sql.tree.Expression)13 Table (io.trino.sql.tree.Table)12 DropTable (io.trino.sql.tree.DropTable)11 AllColumns (io.trino.sql.tree.AllColumns)9 QualifiedName (io.trino.sql.tree.QualifiedName)9 PrincipalSpecification (io.trino.sql.tree.PrincipalSpecification)8 List (java.util.List)8 ImmutableList (com.google.common.collect.ImmutableList)6 Session (io.trino.Session)6 ComparisonExpression (io.trino.sql.tree.ComparisonExpression)6 ArithmeticBinaryExpression (io.trino.sql.tree.ArithmeticBinaryExpression)5