use of io.trino.spi.expression.Constant 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.Constant 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));
}
use of io.trino.spi.expression.Constant in project trino by trinodb.
the class TestConnectorExpressionTranslator method testTranslateLike.
@Test
public void testTranslateLike() {
String pattern = "%pattern%";
assertTranslationRoundTrips(new LikePredicate(new SymbolReference("varchar_symbol_1"), new StringLiteral(pattern), Optional.empty()), new Call(BOOLEAN, LIKE_PATTERN_FUNCTION_NAME, List.of(new Variable("varchar_symbol_1", VARCHAR_TYPE), new Constant(Slices.wrappedBuffer(pattern.getBytes(UTF_8)), createVarcharType(pattern.length())))));
String escape = "\\";
assertTranslationRoundTrips(new LikePredicate(new SymbolReference("varchar_symbol_1"), new StringLiteral(pattern), Optional.of(new StringLiteral(escape))), new Call(BOOLEAN, LIKE_PATTERN_FUNCTION_NAME, List.of(new Variable("varchar_symbol_1", VARCHAR_TYPE), new Constant(Slices.wrappedBuffer(pattern.getBytes(UTF_8)), createVarcharType(pattern.length())), new Constant(Slices.wrappedBuffer(escape.getBytes(UTF_8)), createVarcharType(escape.length())))));
}
use of io.trino.spi.expression.Constant in project trino by trinodb.
the class TestPushProjectionIntoTableScan method testPushProjection.
@Test
public void testPushProjection() {
try (RuleTester ruleTester = defaultRuleTester()) {
// Building context for input
String columnName = "col0";
Type columnType = ROW_TYPE;
Symbol baseColumn = new Symbol(columnName);
ColumnHandle columnHandle = new TpchColumnHandle(columnName, columnType);
// Create catalog with applyProjection enabled
MockConnectorFactory factory = createMockFactory(ImmutableMap.of(columnName, columnHandle), Optional.of(this::mockApplyProjection));
ruleTester.getQueryRunner().createCatalog(MOCK_CATALOG, factory, ImmutableMap.of());
TypeAnalyzer typeAnalyzer = createTestingTypeAnalyzer(ruleTester.getPlannerContext());
// Prepare project node symbols and types
Symbol identity = new Symbol("symbol_identity");
Symbol dereference = new Symbol("symbol_dereference");
Symbol constant = new Symbol("symbol_constant");
Symbol call = new Symbol("symbol_call");
ImmutableMap<Symbol, Type> types = ImmutableMap.of(baseColumn, ROW_TYPE, identity, ROW_TYPE, dereference, BIGINT, constant, BIGINT, call, VARCHAR);
// Prepare project node assignments
ImmutableMap<Symbol, Expression> inputProjections = ImmutableMap.of(identity, baseColumn.toSymbolReference(), dereference, new SubscriptExpression(baseColumn.toSymbolReference(), new LongLiteral("1")), constant, new LongLiteral("5"), call, new FunctionCall(QualifiedName.of("STARTS_WITH"), ImmutableList.of(new StringLiteral("abc"), new StringLiteral("ab"))));
// Compute expected symbols after applyProjection
TransactionId transactionId = ruleTester.getQueryRunner().getTransactionManager().beginTransaction(false);
Session session = MOCK_SESSION.beginTransactionId(transactionId, ruleTester.getQueryRunner().getTransactionManager(), ruleTester.getQueryRunner().getAccessControl());
ImmutableMap<Symbol, String> connectorNames = inputProjections.entrySet().stream().collect(toImmutableMap(Map.Entry::getKey, e -> translate(session, e.getValue(), typeAnalyzer, viewOf(types), ruleTester.getPlannerContext()).get().toString()));
ImmutableMap<Symbol, String> newNames = ImmutableMap.of(identity, "projected_variable_" + connectorNames.get(identity), dereference, "projected_dereference_" + connectorNames.get(dereference), constant, "projected_constant_" + connectorNames.get(constant), call, "projected_call_" + connectorNames.get(call));
Map<String, ColumnHandle> expectedColumns = newNames.entrySet().stream().collect(toImmutableMap(Map.Entry::getValue, e -> column(e.getValue(), types.get(e.getKey()))));
ruleTester.assertThat(createRule(ruleTester)).on(p -> {
// Register symbols
types.forEach((symbol, type) -> p.symbol(symbol.getName(), type));
return p.project(new Assignments(inputProjections), p.tableScan(tableScan -> tableScan.setTableHandle(TEST_TABLE_HANDLE).setSymbols(ImmutableList.copyOf(types.keySet())).setAssignments(types.keySet().stream().collect(Collectors.toMap(Function.identity(), v -> columnHandle))).setStatistics(Optional.of(PlanNodeStatsEstimate.builder().setOutputRowCount(42).addSymbolStatistics(baseColumn, SymbolStatsEstimate.builder().setNullsFraction(0).setDistinctValuesCount(33).build()).build()))));
}).withSession(MOCK_SESSION).matches(project(newNames.entrySet().stream().collect(toImmutableMap(e -> e.getKey().getName(), e -> expression(symbolReference(e.getValue())))), tableScan(new MockConnectorTableHandle(new SchemaTableName(TEST_SCHEMA, "projected_" + TEST_TABLE), TupleDomain.all(), Optional.of(ImmutableList.copyOf(expectedColumns.values())))::equals, TupleDomain.all(), expectedColumns.entrySet().stream().collect(toImmutableMap(Map.Entry::getKey, e -> e.getValue()::equals)), Optional.of(PlanNodeStatsEstimate.builder().setOutputRowCount(42).addSymbolStatistics(new Symbol(newNames.get(constant)), SymbolStatsEstimate.builder().setDistinctValuesCount(1).setNullsFraction(0).setLowValue(5).setHighValue(5).build()).addSymbolStatistics(new Symbol(newNames.get(call).toLowerCase(ENGLISH)), SymbolStatsEstimate.builder().setDistinctValuesCount(1).setNullsFraction(0).build()).addSymbolStatistics(new Symbol(newNames.get(identity)), SymbolStatsEstimate.builder().setDistinctValuesCount(33).setNullsFraction(0).build()).addSymbolStatistics(new Symbol(newNames.get(dereference)), SymbolStatsEstimate.unknown()).build())::equals)));
}
}
Aggregations