Search in sources :

Example 16 with PageProcessor

use of io.trino.operator.project.PageProcessor in project trino by trinodb.

the class TestScanFilterAndProjectOperator method testRecordCursorYield.

@Test
public void testRecordCursorYield() {
    // create a generic long function that yields for projection on every row
    // verify we will yield #row times totally
    // create a table with 15 rows
    int length = 15;
    Page input = SequencePageBuilder.createSequencePage(ImmutableList.of(BIGINT), length, 0);
    DriverContext driverContext = newDriverContext();
    // set up generic long function with a callback to force yield
    functionAssertions.addFunctions(new InternalFunctionBundle(new GenericLongFunction("record_cursor", value -> {
        driverContext.getYieldSignal().forceYieldForTesting();
        return value;
    })));
    FunctionManager functionManager = functionAssertions.getFunctionManager();
    ExpressionCompiler expressionCompiler = new ExpressionCompiler(functionManager, new PageFunctionCompiler(functionManager, 0));
    List<RowExpression> projections = ImmutableList.of(call(functionAssertions.getMetadata().resolveFunction(session, QualifiedName.of("generic_long_record_cursor"), fromTypes(BIGINT)), field(0, BIGINT)));
    Supplier<CursorProcessor> cursorProcessor = expressionCompiler.compileCursorProcessor(Optional.empty(), projections, "key");
    Supplier<PageProcessor> pageProcessor = expressionCompiler.compilePageProcessor(Optional.empty(), projections);
    ScanFilterAndProjectOperator.ScanFilterAndProjectOperatorFactory factory = new ScanFilterAndProjectOperator.ScanFilterAndProjectOperatorFactory(0, new PlanNodeId("test"), new PlanNodeId("0"), (session, split, table, columns, dynamicFilter) -> new RecordPageSource(new PageRecordSet(ImmutableList.of(BIGINT), input)), cursorProcessor, pageProcessor, TEST_TABLE_HANDLE, ImmutableList.of(), DynamicFilter.EMPTY, ImmutableList.of(BIGINT), DataSize.ofBytes(0), 0);
    SourceOperator operator = factory.createOperator(driverContext);
    operator.addSplit(new Split(new CatalogName("test"), TestingSplit.createLocalSplit(), Lifespan.taskWide()));
    operator.noMoreSplits();
    // start driver; get null value due to yield for the first 15 times
    for (int i = 0; i < length; i++) {
        driverContext.getYieldSignal().setWithDelay(SECONDS.toNanos(1000), driverContext.getYieldExecutor());
        assertNull(operator.getOutput());
        driverContext.getYieldSignal().reset();
    }
    // the 16th yield is not going to prevent the operator from producing a page
    driverContext.getYieldSignal().setWithDelay(SECONDS.toNanos(1000), driverContext.getYieldExecutor());
    Page output = operator.getOutput();
    driverContext.getYieldSignal().reset();
    assertNotNull(output);
    assertEquals(toValues(BIGINT, output.getBlock(0)), toValues(BIGINT, input.getBlock(0)));
}
Also used : PageFunctionCompiler(io.trino.sql.gen.PageFunctionCompiler) CursorProcessor(io.trino.operator.project.CursorProcessor) RowExpression(io.trino.sql.relational.RowExpression) Page(io.trino.spi.Page) PageRecordSet(io.trino.operator.index.PageRecordSet) RecordPageSource(io.trino.spi.connector.RecordPageSource) PlanNodeId(io.trino.sql.planner.plan.PlanNodeId) PageProcessor(io.trino.operator.project.PageProcessor) InternalFunctionBundle(io.trino.metadata.InternalFunctionBundle) ExpressionCompiler(io.trino.sql.gen.ExpressionCompiler) CatalogName(io.trino.connector.CatalogName) Split(io.trino.metadata.Split) TestingSplit(io.trino.testing.TestingSplit) FunctionManager(io.trino.metadata.FunctionManager) Test(org.testng.annotations.Test)

Example 17 with PageProcessor

use of io.trino.operator.project.PageProcessor in project trino by trinodb.

the class FunctionAssertions method assertCachedInstanceHasBoundedRetainedSizeInTx.

private void assertCachedInstanceHasBoundedRetainedSizeInTx(String projection, Session session) {
    requireNonNull(projection, "projection is null");
    Expression projectionExpression = createExpression(session, projection, getPlannerContext(), INPUT_TYPES);
    RowExpression projectionRowExpression = toRowExpression(session, projectionExpression);
    PageProcessor processor = runner.getExpressionCompiler().compilePageProcessor(Optional.empty(), ImmutableList.of(projectionRowExpression)).get();
    // This is a heuristic to detect whether the retained size of cachedInstance is bounded.
    // * The test runs at least 1000 iterations.
    // * The test passes if max retained size doesn't refresh after
    // 4x the number of iterations when max was last updated.
    // * The test fails if retained size reaches 1MB.
    // Note that 1MB is arbitrarily chosen and may be increased if a function implementation
    // legitimately needs more.
    long maxRetainedSize = 0;
    int maxIterationCount = 0;
    for (int iterationCount = 0; iterationCount < Math.max(1000, maxIterationCount * 4); iterationCount++) {
        Iterator<Optional<Page>> output = processor.process(session.toConnectorSession(), new DriverYieldSignal(), newSimpleAggregatedMemoryContext().newLocalMemoryContext(PageProcessor.class.getSimpleName()), SOURCE_PAGE);
        // consume the iterator
        @SuppressWarnings("unused") Optional<Page> ignored = Iterators.getOnlyElement(output);
        long retainedSize = processor.getProjections().stream().mapToLong(this::getRetainedSizeOfCachedInstance).sum();
        if (retainedSize > maxRetainedSize) {
            maxRetainedSize = retainedSize;
            maxIterationCount = iterationCount;
        }
        if (maxRetainedSize >= 1048576) {
            fail(format("The retained size of cached instance of function invocation is likely unbounded: %s", projection));
        }
    }
}
Also used : PageProcessor(io.trino.operator.project.PageProcessor) Optional(java.util.Optional) ExpressionTestUtils.createExpression(io.trino.sql.ExpressionTestUtils.createExpression) Expression(io.trino.sql.tree.Expression) RowExpression(io.trino.sql.relational.RowExpression) RowExpression(io.trino.sql.relational.RowExpression) DriverYieldSignal(io.trino.operator.DriverYieldSignal) Page(io.trino.spi.Page)

Example 18 with PageProcessor

use of io.trino.operator.project.PageProcessor in project trino by trinodb.

the class ExpressionCompiler method compilePageProcessor.

private Supplier<PageProcessor> compilePageProcessor(Optional<RowExpression> filter, List<? extends RowExpression> projections, Optional<String> classNameSuffix, OptionalInt initialBatchSize) {
    Optional<Supplier<PageFilter>> filterFunctionSupplier = filter.map(expression -> pageFunctionCompiler.compileFilter(expression, classNameSuffix));
    List<Supplier<PageProjection>> pageProjectionSuppliers = projections.stream().map(projection -> pageFunctionCompiler.compileProjection(projection, classNameSuffix)).collect(toImmutableList());
    return () -> {
        Optional<PageFilter> filterFunction = filterFunctionSupplier.map(Supplier::get);
        List<PageProjection> pageProjections = pageProjectionSuppliers.stream().map(Supplier::get).collect(toImmutableList());
        return new PageProcessor(filterFunction, pageProjections, initialBatchSize);
    };
}
Also used : CacheStatsMBean(io.airlift.jmx.CacheStatsMBean) ParameterizedType.type(io.airlift.bytecode.ParameterizedType.type) Nested(org.weakref.jmx.Nested) BOOLEAN(io.trino.spi.type.BooleanType.BOOLEAN) OptionalInt(java.util.OptionalInt) Supplier(java.util.function.Supplier) Access.a(io.airlift.bytecode.Access.a) NonEvictableLoadingCache(io.trino.collect.cache.NonEvictableLoadingCache) PageFilter(io.trino.operator.project.PageFilter) Inject(javax.inject.Inject) ImmutableList(com.google.common.collect.ImmutableList) Managed(org.weakref.jmx.Managed) CursorProcessor(io.trino.operator.project.CursorProcessor) Objects.requireNonNull(java.util.Objects.requireNonNull) PageProcessor(io.trino.operator.project.PageProcessor) CompilerUtils.makeClassName(io.trino.util.CompilerUtils.makeClassName) FINAL(io.airlift.bytecode.Access.FINAL) ImmutableList.toImmutableList(com.google.common.collect.ImmutableList.toImmutableList) BytecodeUtils.invoke(io.trino.sql.gen.BytecodeUtils.invoke) Expressions.constant(io.trino.sql.relational.Expressions.constant) TrinoException(io.trino.spi.TrinoException) PageProjection(io.trino.operator.project.PageProjection) FunctionManager(io.trino.metadata.FunctionManager) CompilerUtils.defineClass(io.trino.util.CompilerUtils.defineClass) CacheLoader(com.google.common.cache.CacheLoader) Objects(java.util.Objects) SafeCaches.buildNonEvictableCache(io.trino.collect.cache.SafeCaches.buildNonEvictableCache) COMPILER_ERROR(io.trino.spi.StandardErrorCode.COMPILER_ERROR) CompilationException(io.airlift.bytecode.CompilationException) List(java.util.List) RowExpression(io.trino.sql.relational.RowExpression) PUBLIC(io.airlift.bytecode.Access.PUBLIC) Optional(java.util.Optional) VisibleForTesting(com.google.common.annotations.VisibleForTesting) CacheBuilder(com.google.common.cache.CacheBuilder) ClassDefinition(io.airlift.bytecode.ClassDefinition) MoreObjects.toStringHelper(com.google.common.base.MoreObjects.toStringHelper) PageProcessor(io.trino.operator.project.PageProcessor) Optional(java.util.Optional) Supplier(java.util.function.Supplier) ImmutableList(com.google.common.collect.ImmutableList) ImmutableList.toImmutableList(com.google.common.collect.ImmutableList.toImmutableList) List(java.util.List)

Example 19 with PageProcessor

use of io.trino.operator.project.PageProcessor in project trino by trinodb.

the class TestColumnarPageProcessor method testProcess.

@Test
public void testProcess() {
    PageProcessor processor = newPageProcessor();
    Page page = createPage(types, false);
    Page outputPage = getOnlyElement(processor.process(SESSION, new DriverYieldSignal(), newSimpleAggregatedMemoryContext().newLocalMemoryContext(PageProcessor.class.getSimpleName()), page)).orElseThrow(() -> new AssertionError("page is not present"));
    assertPageEquals(types, outputPage, page);
}
Also used : PageProcessor(io.trino.operator.project.PageProcessor) Page(io.trino.spi.Page) SequencePageBuilder.createSequencePage(io.trino.SequencePageBuilder.createSequencePage) Test(org.testng.annotations.Test)

Example 20 with PageProcessor

use of io.trino.operator.project.PageProcessor in project trino by trinodb.

the class TestColumnarPageProcessor method testProcessWithDictionary.

@Test
public void testProcessWithDictionary() {
    PageProcessor processor = newPageProcessor();
    Page page = createPage(types, true);
    Page outputPage = getOnlyElement(processor.process(SESSION, new DriverYieldSignal(), newSimpleAggregatedMemoryContext().newLocalMemoryContext(PageProcessor.class.getSimpleName()), page)).orElseThrow(() -> new AssertionError("page is not present"));
    assertPageEquals(types, outputPage, page);
}
Also used : PageProcessor(io.trino.operator.project.PageProcessor) Page(io.trino.spi.Page) SequencePageBuilder.createSequencePage(io.trino.SequencePageBuilder.createSequencePage) Test(org.testng.annotations.Test)

Aggregations

PageProcessor (io.trino.operator.project.PageProcessor)23 Page (io.trino.spi.Page)17 Test (org.testng.annotations.Test)17 RowExpression (io.trino.sql.relational.RowExpression)13 PlanNodeId (io.trino.sql.planner.plan.PlanNodeId)12 CursorProcessor (io.trino.operator.project.CursorProcessor)8 DriverYieldSignal (io.trino.operator.DriverYieldSignal)7 CatalogName (io.trino.connector.CatalogName)6 Split (io.trino.metadata.Split)6 PageFunctionCompiler (io.trino.sql.gen.PageFunctionCompiler)6 TestingSplit (io.trino.testing.TestingSplit)6 ExpressionCompiler (io.trino.sql.gen.ExpressionCompiler)5 MaterializedResult (io.trino.testing.MaterializedResult)5 ImmutableList (com.google.common.collect.ImmutableList)4 FunctionManager (io.trino.metadata.FunctionManager)4 ResolvedFunction (io.trino.metadata.ResolvedFunction)4 OperatorAssertion.toMaterializedResult (io.trino.operator.OperatorAssertion.toMaterializedResult)4 CallExpression (io.trino.sql.relational.CallExpression)4 BlockAssertions.createLongDictionaryBlock (io.trino.block.BlockAssertions.createLongDictionaryBlock)3 PageRecordSet (io.trino.operator.index.PageRecordSet)3