use of io.trino.spi.expression.ConnectorExpression in project trino by trinodb.
the class TestExpressionMatching method testExpressionCapture.
@Test
public void testExpressionCapture() {
ConnectorExpression expression = new Call(createDecimalType(21, 2), new FunctionName("add"), List.of(new Variable("first", createDecimalType(10, 2)), new Variable("second", BIGINT)));
ExpressionPattern pattern = expressionPattern("foo: decimal(p, s)");
Match match = pattern.getPattern().match(expression).collect(onlyElement());
MatchContext matchContext = new MatchContext();
pattern.resolve(match.captures(), matchContext);
assertThat(matchContext.keys()).containsExactlyInAnyOrder("p", "s", "foo");
assertThat(matchContext.get("p")).isEqualTo(21L);
assertThat(matchContext.get("s")).isEqualTo(2L);
assertThat(matchContext.get("foo")).isSameAs(expression);
}
use of io.trino.spi.expression.ConnectorExpression in project trino by trinodb.
the class TestPruneTableScanColumns method mockApplyProjection.
private Optional<ProjectionApplicationResult<ConnectorTableHandle>> mockApplyProjection(ConnectorSession session, ConnectorTableHandle tableHandle, List<ConnectorExpression> projections, Map<String, ColumnHandle> assignments) {
MockConnectorTableHandle handle = (MockConnectorTableHandle) tableHandle;
List<Variable> variables = projections.stream().map(Variable.class::cast).collect(toImmutableList());
List<ColumnHandle> newColumns = variables.stream().map(variable -> assignments.get(variable.getName())).collect(toImmutableList());
if (handle.getColumns().isPresent() && newColumns.equals(handle.getColumns().get())) {
return Optional.empty();
}
return Optional.of(new ProjectionApplicationResult<>(new MockConnectorTableHandle(handle.getTableName(), handle.getConstraint(), Optional.of(newColumns)), projections, variables.stream().map(variable -> new Assignment(variable.getName(), assignments.get(variable.getName()), ((MockConnectorColumnHandle) assignments.get(variable.getName())).getType())).collect(toImmutableList()), false));
}
use of io.trino.spi.expression.ConnectorExpression in project trino by trinodb.
the class DefaultJdbcMetadata method applyFilter.
@Override
public Optional<ConstraintApplicationResult<ConnectorTableHandle>> applyFilter(ConnectorSession session, ConnectorTableHandle table, Constraint constraint) {
JdbcTableHandle handle = (JdbcTableHandle) table;
if (handle.getSortOrder().isPresent() && handle.getLimit().isPresent()) {
handle = flushAttributesAsQuery(session, handle);
}
TupleDomain<ColumnHandle> oldDomain = handle.getConstraint();
TupleDomain<ColumnHandle> newDomain = oldDomain.intersect(constraint.getSummary());
List<String> newConstraintExpressions;
TupleDomain<ColumnHandle> remainingFilter;
Optional<ConnectorExpression> remainingExpression;
if (newDomain.isNone()) {
newConstraintExpressions = ImmutableList.of();
remainingFilter = TupleDomain.all();
remainingExpression = Optional.of(Constant.TRUE);
} else {
Map<ColumnHandle, Domain> domains = newDomain.getDomains().orElseThrow();
List<JdbcColumnHandle> columnHandles = domains.keySet().stream().map(JdbcColumnHandle.class::cast).collect(toImmutableList());
List<ColumnMapping> columnMappings = jdbcClient.toColumnMappings(session, columnHandles.stream().map(JdbcColumnHandle::getJdbcTypeHandle).collect(toImmutableList()));
Map<ColumnHandle, Domain> supported = new HashMap<>();
Map<ColumnHandle, Domain> unsupported = new HashMap<>();
for (int i = 0; i < columnHandles.size(); i++) {
JdbcColumnHandle column = columnHandles.get(i);
ColumnMapping mapping = columnMappings.get(i);
DomainPushdownResult pushdownResult = mapping.getPredicatePushdownController().apply(session, domains.get(column));
supported.put(column, pushdownResult.getPushedDown());
unsupported.put(column, pushdownResult.getRemainingFilter());
}
newDomain = TupleDomain.withColumnDomains(supported);
remainingFilter = TupleDomain.withColumnDomains(unsupported);
if (isComplexExpressionPushdown(session)) {
List<String> newExpressions = new ArrayList<>();
List<ConnectorExpression> remainingExpressions = new ArrayList<>();
for (ConnectorExpression expression : extractConjuncts(constraint.getExpression())) {
Optional<String> converted = jdbcClient.convertPredicate(session, expression, constraint.getAssignments());
if (converted.isPresent()) {
newExpressions.add(converted.get());
} else {
remainingExpressions.add(expression);
}
}
newConstraintExpressions = ImmutableSet.<String>builder().addAll(handle.getConstraintExpressions()).addAll(newExpressions).build().asList();
remainingExpression = Optional.of(and(remainingExpressions));
} else {
newConstraintExpressions = ImmutableList.of();
remainingExpression = Optional.empty();
}
}
if (oldDomain.equals(newDomain) && handle.getConstraintExpressions().equals(newConstraintExpressions)) {
return Optional.empty();
}
handle = new JdbcTableHandle(handle.getRelationHandle(), newDomain, newConstraintExpressions, handle.getSortOrder(), handle.getLimit(), handle.getColumns(), handle.getOtherReferencedTables(), handle.getNextSyntheticColumnId());
return Optional.of(remainingExpression.isPresent() ? new ConstraintApplicationResult<>(handle, remainingFilter, remainingExpression.get(), false) : new ConstraintApplicationResult<>(handle, remainingFilter, false));
}
use of io.trino.spi.expression.ConnectorExpression in project trino by trinodb.
the class GenericRewrite method rewrite.
@Override
public Optional<String> rewrite(ConnectorExpression expression, Captures captures, RewriteContext<String> context) {
MatchContext matchContext = new MatchContext();
expressionPattern.resolve(captures, matchContext);
StringBuilder rewritten = new StringBuilder();
Matcher matcher = REWRITE_TOKENS.matcher(rewritePattern);
while (matcher.find()) {
String identifier = matcher.group(0);
Optional<Object> capture = matchContext.getIfPresent(identifier);
String replacement;
if (capture.isPresent()) {
Object value = capture.get();
if (value instanceof Long) {
replacement = Long.toString((Long) value);
} else if (value instanceof ConnectorExpression) {
Optional<String> rewrittenExpression = context.defaultRewrite((ConnectorExpression) value);
if (rewrittenExpression.isEmpty()) {
return Optional.empty();
}
replacement = format("(%s)", rewrittenExpression.get());
} else {
throw new UnsupportedOperationException(format("Unsupported value: %s (%s)", value, value.getClass()));
}
} else {
replacement = identifier;
}
matcher.appendReplacement(rewritten, quoteReplacement(replacement));
}
matcher.appendTail(rewritten);
return Optional.of(rewritten.toString());
}
use of io.trino.spi.expression.ConnectorExpression in project trino by trinodb.
the class RewriteOr method rewrite.
@Override
public Optional<String> rewrite(Call call, Captures captures, RewriteContext<String> context) {
List<ConnectorExpression> arguments = call.getArguments();
verify(!arguments.isEmpty(), "no arguments");
List<String> terms = new ArrayList<>(arguments.size());
for (ConnectorExpression argument : arguments) {
verify(argument.getType() == BOOLEAN, "Unexpected type of OR argument: %s", argument.getType());
Optional<String> rewritten = context.defaultRewrite(argument);
if (rewritten.isEmpty()) {
return Optional.empty();
}
terms.add(rewritten.get());
}
return Optional.of(terms.stream().collect(Collectors.joining(") OR (", "(", ")")));
}
Aggregations