Search in sources :

Example 1 with Constant

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));
}
Also used : TpchColumnHandle(io.trino.plugin.tpch.TpchColumnHandle) ColumnHandle(io.trino.spi.connector.ColumnHandle) FunctionCall(io.trino.sql.tree.FunctionCall) Call(io.trino.spi.expression.Call) Variable(io.trino.spi.expression.Variable) TpchColumnHandle(io.trino.plugin.tpch.TpchColumnHandle) ImmutableList.toImmutableList(com.google.common.collect.ImmutableList.toImmutableList) ImmutableList(com.google.common.collect.ImmutableList) ConnectorExpression(io.trino.spi.expression.ConnectorExpression) Constant(io.trino.spi.expression.Constant) SchemaTableName(io.trino.spi.connector.SchemaTableName) Assignment(io.trino.spi.connector.Assignment) FieldDereference(io.trino.spi.expression.FieldDereference) MockConnectorTableHandle(io.trino.connector.MockConnectorTableHandle)

Example 2 with Constant

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));
}
Also used : ColumnHandle(io.trino.spi.connector.ColumnHandle) Call(io.trino.spi.expression.Call) Variable(io.trino.spi.expression.Variable) HashMap(java.util.HashMap) ConnectorExpression(io.trino.spi.expression.ConnectorExpression) Constant(io.trino.spi.expression.Constant) ArrayList(java.util.ArrayList) Slice(io.airlift.slice.Slice) PrimitiveType(io.trino.plugin.elasticsearch.client.IndexMetadata.PrimitiveType) Domain(io.trino.spi.predicate.Domain) TupleDomain(io.trino.spi.predicate.TupleDomain) IndexMetadata(io.trino.plugin.elasticsearch.client.IndexMetadata) Map(java.util.Map) ImmutableMap(com.google.common.collect.ImmutableMap) ImmutableMap.toImmutableMap(com.google.common.collect.ImmutableMap.toImmutableMap) HashMap(java.util.HashMap)

Example 3 with Constant

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())))));
}
Also used : Call(io.trino.spi.expression.Call) Variable(io.trino.spi.expression.Variable) StringLiteral(io.trino.sql.tree.StringLiteral) SymbolReference(io.trino.sql.tree.SymbolReference) Constant(io.trino.spi.expression.Constant) LikePredicate(io.trino.sql.tree.LikePredicate) Test(org.testng.annotations.Test)

Example 4 with Constant

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)));
    }
}
Also used : Test(org.testng.annotations.Test) CatalogName(io.trino.connector.CatalogName) MockConnectorFactory(io.trino.connector.MockConnectorFactory) LongLiteral(io.trino.sql.tree.LongLiteral) Arrays.asList(java.util.Arrays.asList) ConnectorTableHandle(io.trino.spi.connector.ConnectorTableHandle) Map(java.util.Map) ProjectionApplicationResult(io.trino.spi.connector.ProjectionApplicationResult) FunctionCall(io.trino.sql.tree.FunctionCall) ENGLISH(java.util.Locale.ENGLISH) PlanNodeStatsEstimate(io.trino.cost.PlanNodeStatsEstimate) PlanMatchPattern.expression(io.trino.sql.planner.assertions.PlanMatchPattern.expression) TpchColumnHandle(io.trino.plugin.tpch.TpchColumnHandle) RowType(io.trino.spi.type.RowType) ImmutableMap(com.google.common.collect.ImmutableMap) Call(io.trino.spi.expression.Call) ImmutableList.toImmutableList(com.google.common.collect.ImmutableList.toImmutableList) Assignments(io.trino.sql.planner.plan.Assignments) ScalarStatsCalculator(io.trino.cost.ScalarStatsCalculator) Collectors(java.util.stream.Collectors) SchemaTableName(io.trino.spi.connector.SchemaTableName) List(java.util.List) ImmutableMap.toImmutableMap(com.google.common.collect.ImmutableMap.toImmutableMap) TestingSession.testSessionBuilder(io.trino.testing.TestingSession.testSessionBuilder) PlanMatchPattern.anyTree(io.trino.sql.planner.assertions.PlanMatchPattern.anyTree) BIGINT(io.trino.spi.type.BigintType.BIGINT) ConnectorPartitioningHandle(io.trino.spi.connector.ConnectorPartitioningHandle) SymbolReference(io.trino.sql.tree.SymbolReference) Assignment(io.trino.spi.connector.Assignment) Optional(java.util.Optional) Expression(io.trino.sql.tree.Expression) RowType.field(io.trino.spi.type.RowType.field) ConnectorTablePartitioning(io.trino.spi.connector.ConnectorTablePartitioning) ConnectorExpressionTranslator.translate(io.trino.sql.planner.ConnectorExpressionTranslator.translate) Session(io.trino.Session) PlannerContext(io.trino.sql.PlannerContext) TypeAnalyzer.createTestingTypeAnalyzer(io.trino.sql.planner.TypeAnalyzer.createTestingTypeAnalyzer) ColumnMetadata(io.trino.spi.connector.ColumnMetadata) Type(io.trino.spi.type.Type) Variable(io.trino.spi.expression.Variable) Function(java.util.function.Function) SubscriptExpression(io.trino.sql.tree.SubscriptExpression) VARCHAR(io.trino.spi.type.VarcharType.VARCHAR) ImmutableList(com.google.common.collect.ImmutableList) Assertions.assertThatThrownBy(org.assertj.core.api.Assertions.assertThatThrownBy) ColumnHandle(io.trino.spi.connector.ColumnHandle) Constant(io.trino.spi.expression.Constant) TypeProvider.viewOf(io.trino.sql.planner.TypeProvider.viewOf) Symbol(io.trino.sql.planner.Symbol) SymbolStatsEstimate(io.trino.cost.SymbolStatsEstimate) StringLiteral(io.trino.sql.tree.StringLiteral) RuleTester.defaultRuleTester(io.trino.sql.planner.iterative.rule.test.RuleTester.defaultRuleTester) FieldDereference(io.trino.spi.expression.FieldDereference) TestingTransactionHandle(io.trino.testing.TestingTransactionHandle) ConnectorSession(io.trino.spi.connector.ConnectorSession) RuleTester(io.trino.sql.planner.iterative.rule.test.RuleTester) TupleDomain(io.trino.spi.predicate.TupleDomain) QualifiedName(io.trino.sql.tree.QualifiedName) MockConnectorTableHandle(io.trino.connector.MockConnectorTableHandle) TableHandle(io.trino.metadata.TableHandle) ConnectorTableProperties(io.trino.spi.connector.ConnectorTableProperties) ConnectorExpression(io.trino.spi.expression.ConnectorExpression) TypeAnalyzer(io.trino.sql.planner.TypeAnalyzer) PlanMatchPattern.project(io.trino.sql.planner.assertions.PlanMatchPattern.project) TransactionId(io.trino.transaction.TransactionId) PlanMatchPattern.tableScan(io.trino.sql.planner.assertions.PlanMatchPattern.tableScan) MockConnectorFactory(io.trino.connector.MockConnectorFactory) TpchColumnHandle(io.trino.plugin.tpch.TpchColumnHandle) RuleTester.defaultRuleTester(io.trino.sql.planner.iterative.rule.test.RuleTester.defaultRuleTester) RuleTester(io.trino.sql.planner.iterative.rule.test.RuleTester) Symbol(io.trino.sql.planner.Symbol) Assignments(io.trino.sql.planner.plan.Assignments) SubscriptExpression(io.trino.sql.tree.SubscriptExpression) FunctionCall(io.trino.sql.tree.FunctionCall) TpchColumnHandle(io.trino.plugin.tpch.TpchColumnHandle) ColumnHandle(io.trino.spi.connector.ColumnHandle) LongLiteral(io.trino.sql.tree.LongLiteral) SchemaTableName(io.trino.spi.connector.SchemaTableName) TypeAnalyzer.createTestingTypeAnalyzer(io.trino.sql.planner.TypeAnalyzer.createTestingTypeAnalyzer) TypeAnalyzer(io.trino.sql.planner.TypeAnalyzer) TransactionId(io.trino.transaction.TransactionId) RowType(io.trino.spi.type.RowType) Type(io.trino.spi.type.Type) StringLiteral(io.trino.sql.tree.StringLiteral) Expression(io.trino.sql.tree.Expression) SubscriptExpression(io.trino.sql.tree.SubscriptExpression) ConnectorExpression(io.trino.spi.expression.ConnectorExpression) MockConnectorTableHandle(io.trino.connector.MockConnectorTableHandle) Map(java.util.Map) ImmutableMap(com.google.common.collect.ImmutableMap) ImmutableMap.toImmutableMap(com.google.common.collect.ImmutableMap.toImmutableMap) Session(io.trino.Session) ConnectorSession(io.trino.spi.connector.ConnectorSession) Test(org.testng.annotations.Test)

Aggregations

Call (io.trino.spi.expression.Call)4 Constant (io.trino.spi.expression.Constant)4 Variable (io.trino.spi.expression.Variable)4 ColumnHandle (io.trino.spi.connector.ColumnHandle)3 ConnectorExpression (io.trino.spi.expression.ConnectorExpression)3 ImmutableList (com.google.common.collect.ImmutableList)2 ImmutableList.toImmutableList (com.google.common.collect.ImmutableList.toImmutableList)2 ImmutableMap (com.google.common.collect.ImmutableMap)2 ImmutableMap.toImmutableMap (com.google.common.collect.ImmutableMap.toImmutableMap)2 MockConnectorTableHandle (io.trino.connector.MockConnectorTableHandle)2 TpchColumnHandle (io.trino.plugin.tpch.TpchColumnHandle)2 Assignment (io.trino.spi.connector.Assignment)2 SchemaTableName (io.trino.spi.connector.SchemaTableName)2 FieldDereference (io.trino.spi.expression.FieldDereference)2 TupleDomain (io.trino.spi.predicate.TupleDomain)2 StringLiteral (io.trino.sql.tree.StringLiteral)2 SymbolReference (io.trino.sql.tree.SymbolReference)2 Map (java.util.Map)2 Test (org.testng.annotations.Test)2 Slice (io.airlift.slice.Slice)1