use of io.trino.spi.expression.Call in project trino by trinodb.
the class TestPushProjectionIntoTableScan method mockApplyProjection.
private Optional<ProjectionApplicationResult<ConnectorTableHandle>> mockApplyProjection(ConnectorSession session, ConnectorTableHandle tableHandle, List<ConnectorExpression> projections, Map<String, ColumnHandle> assignments) {
// Prepare new table handle
SchemaTableName inputSchemaTableName = ((MockConnectorTableHandle) tableHandle).getTableName();
SchemaTableName projectedTableName = new SchemaTableName(inputSchemaTableName.getSchemaName(), "projected_" + inputSchemaTableName.getTableName());
// Prepare new column handles
ImmutableList.Builder<ConnectorExpression> outputExpressions = ImmutableList.builder();
ImmutableList.Builder<Assignment> outputAssignments = ImmutableList.builder();
ImmutableList.Builder<ColumnHandle> projectedColumnsBuilder = ImmutableList.builder();
for (ConnectorExpression projection : projections) {
String variablePrefix;
if (projection instanceof Variable) {
variablePrefix = "projected_variable_";
} else if (projection instanceof FieldDereference) {
variablePrefix = "projected_dereference_";
} else if (projection instanceof Constant) {
variablePrefix = "projected_constant_";
} else if (projection instanceof Call) {
variablePrefix = "projected_call_";
} else {
throw new UnsupportedOperationException();
}
String newVariableName = variablePrefix + projection.toString();
Variable newVariable = new Variable(newVariableName, projection.getType());
ColumnHandle newColumnHandle = new TpchColumnHandle(newVariableName, projection.getType());
outputExpressions.add(newVariable);
outputAssignments.add(new Assignment(newVariableName, newColumnHandle, projection.getType()));
projectedColumnsBuilder.add(newColumnHandle);
}
return Optional.of(new ProjectionApplicationResult<>(new MockConnectorTableHandle(projectedTableName, TupleDomain.all(), Optional.of(projectedColumnsBuilder.build())), outputExpressions.build(), outputAssignments.build(), false));
}
use of io.trino.spi.expression.Call in project trino by trinodb.
the class TestExpressionMatching method testMatchCall.
@Test
public void testMatchCall() {
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("add(foo: decimal(p, s), bar: bigint)");
Match match = pattern.getPattern().match(expression).collect(onlyElement());
MatchContext matchContext = new MatchContext();
pattern.resolve(match.captures(), matchContext);
assertThat(matchContext.keys()).containsExactlyInAnyOrder("p", "s", "foo", "bar");
assertThat(matchContext.get("p")).isEqualTo(10L);
assertThat(matchContext.get("s")).isEqualTo(2L);
assertThat(matchContext.get("foo")).isEqualTo(new Variable("first", createDecimalType(10, 2)));
assertThat(matchContext.get("bar")).isEqualTo(new Variable("second", BIGINT));
}
use of io.trino.spi.expression.Call 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.Call in project trino by trinodb.
the class TestGenericRewrite method testRewriteCall.
@Test
public void testRewriteCall() {
GenericRewrite rewrite = new GenericRewrite("add(foo: decimal(p, s), bar: bigint): decimal(rp, rs)", "foo + bar::decimal(rp,rs)");
ConnectorExpression expression = new Call(createDecimalType(21, 2), new FunctionName("add"), List.of(new Variable("first", createDecimalType(10, 2)), new Variable("second", BIGINT)));
Match match = rewrite.getPattern().match(expression).collect(onlyElement());
Optional<String> rewritten = rewrite.rewrite(expression, match.captures(), new RewriteContext<>() {
@Override
public Map<String, ColumnHandle> getAssignments() {
throw new UnsupportedOperationException();
}
@Override
public ConnectorSession getSession() {
throw new UnsupportedOperationException();
}
@Override
public Optional<String> defaultRewrite(ConnectorExpression expression) {
if (expression instanceof Variable) {
return Optional.of("\"" + ((Variable) expression).getName().replace("\"", "\"\"") + "\"");
}
return Optional.empty();
}
});
assertThat(rewritten).hasValue("(\"first\") + (\"second\")::decimal(21,2)");
}
use of io.trino.spi.expression.Call in project trino by trinodb.
the class ElasticsearchMetadata method applyFilter.
@Override
public Optional<ConstraintApplicationResult<ConnectorTableHandle>> applyFilter(ConnectorSession session, ConnectorTableHandle table, Constraint constraint) {
ElasticsearchTableHandle handle = (ElasticsearchTableHandle) table;
if (isPassthroughQuery(handle)) {
// filter pushdown currently not supported for passthrough query
return Optional.empty();
}
Map<ColumnHandle, Domain> supported = new HashMap<>();
Map<ColumnHandle, Domain> unsupported = new HashMap<>();
if (constraint.getSummary().getDomains().isPresent()) {
for (Map.Entry<ColumnHandle, Domain> entry : constraint.getSummary().getDomains().get().entrySet()) {
ElasticsearchColumnHandle column = (ElasticsearchColumnHandle) entry.getKey();
if (column.isSupportsPredicates()) {
supported.put(column, entry.getValue());
} else {
unsupported.put(column, entry.getValue());
}
}
}
TupleDomain<ColumnHandle> oldDomain = handle.getConstraint();
TupleDomain<ColumnHandle> newDomain = oldDomain.intersect(TupleDomain.withColumnDomains(supported));
ConnectorExpression oldExpression = constraint.getExpression();
Map<String, String> newRegexes = new HashMap<>(handle.getRegexes());
List<ConnectorExpression> expressions = ConnectorExpressions.extractConjuncts(constraint.getExpression());
List<ConnectorExpression> notHandledExpressions = new ArrayList<>();
for (ConnectorExpression expression : expressions) {
if (expression instanceof Call) {
Call call = (Call) expression;
if (isSupportedLikeCall(call)) {
List<ConnectorExpression> arguments = call.getArguments();
String variableName = ((Variable) arguments.get(0)).getName();
ElasticsearchColumnHandle column = (ElasticsearchColumnHandle) constraint.getAssignments().get(variableName);
verifyNotNull(column, "No assignment for %s", variableName);
String columnName = column.getName();
Object pattern = ((Constant) arguments.get(1)).getValue();
Optional<Slice> escape = Optional.empty();
if (arguments.size() == 3) {
escape = Optional.of((Slice) (((Constant) arguments.get(2)).getValue()));
}
if (!newRegexes.containsKey(columnName) && pattern instanceof Slice) {
IndexMetadata metadata = client.getIndexMetadata(handle.getIndex());
if (metadata.getSchema().getFields().stream().anyMatch(field -> columnName.equals(field.getName()) && field.getType() instanceof PrimitiveType && "keyword".equals(((PrimitiveType) field.getType()).getName()))) {
newRegexes.put(columnName, likeToRegexp(((Slice) pattern), escape));
continue;
}
}
}
}
notHandledExpressions.add(expression);
}
ConnectorExpression newExpression = ConnectorExpressions.and(notHandledExpressions);
if (oldDomain.equals(newDomain) && oldExpression.equals(newExpression)) {
return Optional.empty();
}
handle = new ElasticsearchTableHandle(handle.getType(), handle.getSchema(), handle.getIndex(), newDomain, newRegexes, handle.getQuery(), handle.getLimit());
return Optional.of(new ConstraintApplicationResult<>(handle, TupleDomain.withColumnDomains(unsupported), newExpression, false));
}
Aggregations