use of io.trino.sql.tree.Expression in project trino by trinodb.
the class SetViewAuthorizationTask method execute.
@Override
public ListenableFuture<Void> execute(SetViewAuthorization statement, QueryStateMachine stateMachine, List<Expression> parameters, WarningCollector warningCollector) {
Session session = stateMachine.getSession();
QualifiedObjectName viewName = createQualifiedObjectName(session, statement, statement.getSource());
getRequiredCatalogHandle(metadata, session, statement, viewName.getCatalogName());
ViewDefinition view = metadata.getView(session, viewName).orElseThrow(() -> semanticException(TABLE_NOT_FOUND, statement, "View '%s' does not exist", viewName));
TrinoPrincipal principal = createPrincipal(statement.getPrincipal());
checkRoleExists(session, statement, metadata, principal, Optional.of(viewName.getCatalogName()).filter(catalog -> metadata.isCatalogManagedSecurity(session, catalog)));
if (!view.isRunAsInvoker() && !isAllowSetViewAuthorization) {
throw new TrinoException(NOT_SUPPORTED, format("Cannot set authorization for view %s to %s: this feature is disabled", viewName.getCatalogName() + '.' + viewName.getSchemaName() + '.' + viewName.getObjectName(), principal));
}
accessControl.checkCanSetViewAuthorization(session.toSecurityContext(), viewName, principal);
metadata.setViewAuthorization(session, viewName.asCatalogSchemaTableName(), principal);
return immediateVoidFuture();
}
use of io.trino.sql.tree.Expression in project trino by trinodb.
the class PropertyUtil method evaluateProperty.
private static Object evaluateProperty(Expression expression, PropertyMetadata<?> property, Session session, PlannerContext plannerContext, AccessControl accessControl, Map<NodeRef<Parameter>, Expression> parameters, ErrorCodeSupplier errorCode, String propertyTypeDescription) {
Object sqlObjectValue;
try {
Type expectedType = property.getSqlType();
Expression rewritten = ExpressionTreeRewriter.rewriteWith(new ParameterRewriter(parameters), expression);
Object value = evaluateConstantExpression(rewritten, expectedType, plannerContext, session, accessControl, parameters);
// convert to object value type of SQL type
BlockBuilder blockBuilder = expectedType.createBlockBuilder(null, 1);
writeNativeValue(expectedType, blockBuilder, value);
sqlObjectValue = expectedType.getObjectValue(session.toConnectorSession(), blockBuilder, 0);
} catch (TrinoException e) {
throw new TrinoException(errorCode, format("Invalid value for %s '%s': Cannot convert [%s] to %s", propertyTypeDescription, property.getName(), expression, property.getSqlType()), e);
}
if (sqlObjectValue == null) {
throw new TrinoException(errorCode, format("Invalid null value for %s '%s' from [%s]", propertyTypeDescription, property.getName(), expression));
}
try {
return property.decode(sqlObjectValue);
} catch (Exception e) {
throw new TrinoException(errorCode, format("Unable to set %s '%s' to [%s]: %s", propertyTypeDescription, property.getName(), expression, e.getMessage()), e);
}
}
use of io.trino.sql.tree.Expression in project trino by trinodb.
the class EqualityInference method rewrite.
private Expression rewrite(Expression expression, Predicate<Symbol> symbolScope, boolean allowFullReplacement) {
Map<Expression, Expression> expressionRemap = new HashMap<>();
SubExpressionExtractor.extract(expression).filter(allowFullReplacement ? subExpression -> true : subExpression -> !subExpression.equals(expression)).forEach(subExpression -> {
Expression canonical = getScopedCanonical(subExpression, symbolScope);
if (canonical != null) {
expressionRemap.putIfAbsent(subExpression, canonical);
}
});
// Perform a naive single-pass traversal to try to rewrite non-compliant portions of the tree. Prefers to replace
// larger subtrees over smaller subtrees
// TODO: this rewrite can probably be made more sophisticated
Expression rewritten = replaceExpression(expression, expressionRemap);
if (!isScoped(rewritten, symbolScope)) {
// If the rewritten is still not compliant with the symbol scope, just give up
return null;
}
return rewritten;
}
use of io.trino.sql.tree.Expression in project trino by trinodb.
the class EqualityInference method newInstance.
public static EqualityInference newInstance(Metadata metadata, Collection<Expression> expressions) {
DisjointSet<Expression> equalities = new DisjointSet<>();
expressions.stream().flatMap(expression -> extractConjuncts(expression).stream()).filter(expression -> isInferenceCandidate(metadata, expression)).forEach(expression -> {
ComparisonExpression comparison = (ComparisonExpression) expression;
Expression expression1 = comparison.getLeft();
Expression expression2 = comparison.getRight();
equalities.findAndUnion(expression1, expression2);
});
Collection<Set<Expression>> equivalentClasses = equalities.getEquivalentClasses();
// Map every expression to the set of equivalent expressions
Map<Expression, Set<Expression>> byExpression = new HashMap<>();
for (Set<Expression> equivalence : equivalentClasses) {
equivalence.forEach(expression -> byExpression.put(expression, equivalence));
}
// For every non-derived expression, extract the sub-expressions and see if they can be rewritten as other expressions. If so,
// use this new information to update the known equalities.
Set<Expression> derivedExpressions = new LinkedHashSet<>();
for (Expression expression : byExpression.keySet()) {
if (derivedExpressions.contains(expression)) {
continue;
}
SubExpressionExtractor.extract(expression).filter(e -> !e.equals(expression)).forEach(subExpression -> {
byExpression.getOrDefault(subExpression, ImmutableSet.of()).stream().filter(e -> !e.equals(subExpression)).forEach(equivalentSubExpression -> {
Expression rewritten = replaceExpression(expression, ImmutableMap.of(subExpression, equivalentSubExpression));
equalities.findAndUnion(expression, rewritten);
derivedExpressions.add(rewritten);
});
});
}
Multimap<Expression, Expression> equalitySets = makeEqualitySets(equalities);
ImmutableMap.Builder<Expression, Expression> canonicalMappings = ImmutableMap.builder();
for (Map.Entry<Expression, Expression> entry : equalitySets.entries()) {
Expression canonical = entry.getKey();
Expression expression = entry.getValue();
canonicalMappings.put(expression, canonical);
}
return new EqualityInference(equalitySets, canonicalMappings.buildOrThrow(), derivedExpressions);
}
use of io.trino.sql.tree.Expression in project trino by trinodb.
the class EqualityInference method generateEqualitiesPartitionedBy.
/**
* Dumps the inference equalities as equality expressions that are partitioned by the symbolScope.
* All stored equalities are returned in a compact set and will be classified into three groups as determined by the symbol scope:
* <ol>
* <li>equalities that fit entirely within the symbol scope</li>
* <li>equalities that fit entirely outside of the symbol scope</li>
* <li>equalities that straddle the symbol scope</li>
* </ol>
* <pre>
* Example:
* Stored Equalities:
* a = b = c
* d = e = f = g
*
* Symbol Scope:
* a, b, d, e
*
* Output EqualityPartition:
* Scope Equalities:
* a = b
* d = e
* Complement Scope Equalities
* f = g
* Scope Straddling Equalities
* a = c
* d = f
* </pre>
*/
public EqualityPartition generateEqualitiesPartitionedBy(Set<Symbol> scope) {
ImmutableSet.Builder<Expression> scopeEqualities = ImmutableSet.builder();
ImmutableSet.Builder<Expression> scopeComplementEqualities = ImmutableSet.builder();
ImmutableSet.Builder<Expression> scopeStraddlingEqualities = ImmutableSet.builder();
for (Collection<Expression> equalitySet : equalitySets.asMap().values()) {
Set<Expression> scopeExpressions = new LinkedHashSet<>();
Set<Expression> scopeComplementExpressions = new LinkedHashSet<>();
Set<Expression> scopeStraddlingExpressions = new LinkedHashSet<>();
// Try to push each non-derived expression into one side of the scope
equalitySet.stream().filter(candidate -> !derivedExpressions.contains(candidate)).forEach(candidate -> {
Expression scopeRewritten = rewrite(candidate, scope::contains, false);
if (scopeRewritten != null) {
scopeExpressions.add(scopeRewritten);
}
Expression scopeComplementRewritten = rewrite(candidate, expression -> !scope.contains(expression), false);
if (scopeComplementRewritten != null) {
scopeComplementExpressions.add(scopeComplementRewritten);
}
if (scopeRewritten == null && scopeComplementRewritten == null) {
scopeStraddlingExpressions.add(candidate);
}
});
// Compile the equality expressions on each side of the scope
Expression matchingCanonical = getCanonical(scopeExpressions.stream());
if (scopeExpressions.size() >= 2) {
scopeExpressions.stream().filter(expression -> !expression.equals(matchingCanonical)).map(expression -> new ComparisonExpression(ComparisonExpression.Operator.EQUAL, matchingCanonical, expression)).forEach(scopeEqualities::add);
}
Expression complementCanonical = getCanonical(scopeComplementExpressions.stream());
if (scopeComplementExpressions.size() >= 2) {
scopeComplementExpressions.stream().filter(expression -> !expression.equals(complementCanonical)).map(expression -> new ComparisonExpression(ComparisonExpression.Operator.EQUAL, complementCanonical, expression)).forEach(scopeComplementEqualities::add);
}
// Compile the scope straddling equality expressions
List<Expression> connectingExpressions = new ArrayList<>();
connectingExpressions.add(matchingCanonical);
connectingExpressions.add(complementCanonical);
connectingExpressions.addAll(scopeStraddlingExpressions);
connectingExpressions = connectingExpressions.stream().filter(Objects::nonNull).collect(Collectors.toList());
Expression connectingCanonical = getCanonical(connectingExpressions.stream());
if (connectingCanonical != null) {
connectingExpressions.stream().filter(expression -> !expression.equals(connectingCanonical)).map(expression -> new ComparisonExpression(ComparisonExpression.Operator.EQUAL, connectingCanonical, expression)).forEach(scopeStraddlingEqualities::add);
}
}
return new EqualityPartition(scopeEqualities.build(), scopeComplementEqualities.build(), scopeStraddlingEqualities.build());
}
Aggregations