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();
}
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());
}
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;
}
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");
}
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");
}
Aggregations