Search in sources :

Example 1 with DriverYieldSignal

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

the class MeasureComputation method computeEmpty.

public Block computeEmpty(long matchNumber) {
    // prepare input for the projection as an array of single-value blocks. for empty match:
    // - match_number() is the sequential number of the match
    // - classifier() is null
    // - all value references are null
    Block[] blocks = new Block[expectedLayout.size()];
    for (int i = 0; i < expectedLayout.size(); i++) {
        PhysicalValueAccessor accessor = expectedLayout.get(i);
        if (accessor instanceof PhysicalValuePointer) {
            PhysicalValuePointer pointer = (PhysicalValuePointer) accessor;
            if (pointer.getSourceChannel() == MATCH_NUMBER) {
                blocks[i] = nativeValueToBlock(BIGINT, matchNumber);
            } else {
                blocks[i] = nativeValueToBlock(pointer.getType(), null);
            }
        } else {
            MatchAggregation aggregation = aggregations[((MatchAggregationPointer) accessor).getIndex()];
            blocks[i] = aggregation.aggregateEmpty();
        }
    }
    // wrap block array into a single-row page
    Page page = new Page(1, blocks);
    // evaluate expression
    Work<Block> work = projection.project(session, new DriverYieldSignal(), projection.getInputChannels().getInputChannels(page), positionsRange(0, 1));
    boolean done = false;
    while (!done) {
        done = work.process();
    }
    return work.getResult();
}
Also used : Utils.nativeValueToBlock(io.trino.spi.predicate.Utils.nativeValueToBlock) Block(io.trino.spi.block.Block) DriverYieldSignal(io.trino.operator.DriverYieldSignal) Page(io.trino.spi.Page)

Example 2 with DriverYieldSignal

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

the class MeasureComputation method compute.

// TODO This method allocates an intermediate block and passes it as the input to the pre-compiled expression.
// Instead, the expression should be compiled directly against the row navigations.
public static Block compute(int currentRow, ArrayView matchedLabels, MatchAggregation[] aggregations, int partitionStart, int searchStart, int searchEnd, int patternStart, long matchNumber, ProjectingPagesWindowIndex windowIndex, PageProjection projection, List<PhysicalValueAccessor> expectedLayout, Block[] nulls, List<String> labelNames, ConnectorSession session) {
    // get values at appropriate positions and prepare input for the projection as an array of single-value blocks
    Block[] blocks = new Block[expectedLayout.size()];
    for (int i = 0; i < expectedLayout.size(); i++) {
        PhysicalValueAccessor accessor = expectedLayout.get(i);
        if (accessor instanceof PhysicalValuePointer) {
            PhysicalValuePointer pointer = (PhysicalValuePointer) accessor;
            int channel = pointer.getSourceChannel();
            if (channel == MATCH_NUMBER) {
                blocks[i] = nativeValueToBlock(BIGINT, matchNumber);
            } else {
                int position = pointer.getLogicalIndexNavigation().resolvePosition(currentRow, matchedLabels, searchStart, searchEnd, patternStart);
                if (position >= 0) {
                    if (channel == CLASSIFIER) {
                        Type type = VARCHAR;
                        if (position < patternStart || position >= patternStart + matchedLabels.length()) {
                            // position out of match. classifier() function returns null.
                            blocks[i] = nativeValueToBlock(type, null);
                        } else {
                            // position within match. get the assigned label from matchedLabels.
                            // note: when computing measures, all labels of the match can be accessed (even those exceeding the current running position), both in RUNNING and FINAL semantics
                            blocks[i] = nativeValueToBlock(type, utf8Slice(labelNames.get(matchedLabels.get(position - patternStart))));
                        }
                    } else {
                        // TODO Block#getRegion
                        blocks[i] = windowIndex.getSingleValueBlock(channel, position - partitionStart);
                    }
                } else {
                    blocks[i] = nulls[i];
                }
            }
        } else {
            MatchAggregation aggregation = aggregations[((MatchAggregationPointer) accessor).getIndex()];
            blocks[i] = aggregation.aggregate(currentRow, matchedLabels, matchNumber, windowIndex, partitionStart, patternStart);
        }
    }
    // wrap block array into a single-row page
    Page page = new Page(1, blocks);
    // evaluate expression
    Work<Block> work = projection.project(session, new DriverYieldSignal(), projection.getInputChannels().getInputChannels(page), positionsRange(0, 1));
    boolean done = false;
    while (!done) {
        done = work.process();
    }
    return work.getResult();
}
Also used : Type(io.trino.spi.type.Type) Utils.nativeValueToBlock(io.trino.spi.predicate.Utils.nativeValueToBlock) Block(io.trino.spi.block.Block) DriverYieldSignal(io.trino.operator.DriverYieldSignal) Page(io.trino.spi.Page)

Example 3 with DriverYieldSignal

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

the class TestPageProcessor method testSelectAllFilterLazyBlock.

@Test
public void testSelectAllFilterLazyBlock() {
    PageProcessor pageProcessor = new PageProcessor(Optional.of(new SelectAllFilter()), ImmutableList.of(new InputPageProjection(0, BIGINT), new InputPageProjection(1, BIGINT)), OptionalInt.of(100));
    LazyBlock inputFilterBlock = lazyWrapper(createLongSequenceBlock(0, 100));
    LazyBlock inputProjectionBlock = lazyWrapper(createLongSequenceBlock(100, 200));
    Page inputPage = new Page(inputFilterBlock, inputProjectionBlock);
    Iterator<Optional<Page>> output = processAndAssertRetainedPageSize(pageProcessor, new DriverYieldSignal(), newSimpleAggregatedMemoryContext(), inputPage, true);
    List<Optional<Page>> outputPages = ImmutableList.copyOf(output);
    assertTrue(inputFilterBlock.isLoaded());
    assertFalse(inputProjectionBlock.isLoaded());
    assertEquals(outputPages.size(), 1);
    inputFilterBlock = lazyWrapper(createLongSequenceBlock(0, 200));
    inputProjectionBlock = lazyWrapper(createLongSequenceBlock(100, 300));
    inputPage = new Page(inputFilterBlock, inputProjectionBlock);
    // batch size should increase because filter block was materialized
    output = processAndAssertRetainedPageSize(pageProcessor, new DriverYieldSignal(), newSimpleAggregatedMemoryContext(), inputPage, true);
    outputPages = ImmutableList.copyOf(output);
    assertEquals(outputPages.size(), 1);
    assertTrue(inputFilterBlock.isLoaded());
    assertFalse(inputProjectionBlock.isLoaded());
    assertPageEquals(ImmutableList.of(BIGINT, BIGINT), outputPages.get(0).get(), new Page(createLongSequenceBlock(0, 200), createLongSequenceBlock(100, 300)));
    assertTrue(inputProjectionBlock.isLoaded());
}
Also used : LazyBlock(io.trino.spi.block.LazyBlock) Optional(java.util.Optional) DriverYieldSignal(io.trino.operator.DriverYieldSignal) Page(io.trino.spi.Page) Test(org.testng.annotations.Test)

Example 4 with DriverYieldSignal

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

the class TestPageProcessor method testExpressionProfiler.

@Test
public void testExpressionProfiler() {
    TestingFunctionResolution functionResolution = new TestingFunctionResolution();
    CallExpression add10Expression = call(functionResolution.resolveOperator(ADD, ImmutableList.of(BIGINT, BIGINT)), field(0, BIGINT), constant(10L, BIGINT));
    TestingTicker testingTicker = new TestingTicker();
    PageFunctionCompiler functionCompiler = functionResolution.getPageFunctionCompiler();
    Supplier<PageProjection> projectionSupplier = functionCompiler.compileProjection(add10Expression, Optional.empty());
    PageProjection projection = projectionSupplier.get();
    Page page = new Page(createLongSequenceBlock(1, 11));
    ExpressionProfiler profiler = new ExpressionProfiler(testingTicker, SPLIT_RUN_QUANTA);
    for (int i = 0; i < 100; i++) {
        profiler.start();
        Work<Block> work = projection.project(SESSION, new DriverYieldSignal(), page, SelectedPositions.positionsRange(0, page.getPositionCount()));
        if (i < 10) {
            // increment the ticker with a large value to mark the expression as expensive
            testingTicker.increment(10, SECONDS);
            profiler.stop(page.getPositionCount());
            assertTrue(profiler.isExpressionExpensive());
        } else {
            testingTicker.increment(0, NANOSECONDS);
            profiler.stop(page.getPositionCount());
            assertFalse(profiler.isExpressionExpensive());
        }
        work.process();
    }
}
Also used : TestingFunctionResolution(io.trino.metadata.TestingFunctionResolution) TestingTicker(io.airlift.testing.TestingTicker) PageFunctionCompiler(io.trino.sql.gen.PageFunctionCompiler) LazyBlock(io.trino.spi.block.LazyBlock) Block(io.trino.spi.block.Block) BlockAssertions.createLongSequenceBlock(io.trino.block.BlockAssertions.createLongSequenceBlock) BlockAssertions.createStringsBlock(io.trino.block.BlockAssertions.createStringsBlock) BlockAssertions.createSlicesBlock(io.trino.block.BlockAssertions.createSlicesBlock) VariableWidthBlock(io.trino.spi.block.VariableWidthBlock) DriverYieldSignal(io.trino.operator.DriverYieldSignal) Page(io.trino.spi.Page) CallExpression(io.trino.sql.relational.CallExpression) ExpressionProfiler(io.trino.sql.gen.ExpressionProfiler) Test(org.testng.annotations.Test)

Example 5 with DriverYieldSignal

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

the class TestPageProcessorCompiler method testSanityFilterOnDictionary.

@Test
public void testSanityFilterOnDictionary() {
    CallExpression lengthVarchar = new CallExpression(functionResolution.resolveFunction(QualifiedName.of("length"), fromTypes(VARCHAR)), ImmutableList.of(field(0, VARCHAR)));
    ResolvedFunction lessThan = functionResolution.resolveOperator(LESS_THAN, ImmutableList.of(BIGINT, BIGINT));
    CallExpression filter = new CallExpression(lessThan, ImmutableList.of(lengthVarchar, constant(10L, BIGINT)));
    PageProcessor processor = compiler.compilePageProcessor(Optional.of(filter), ImmutableList.of(field(0, VARCHAR)), MAX_BATCH_SIZE).get();
    Page page = new Page(createDictionaryBlock(createExpectedValues(10), 100));
    Page outputPage = getOnlyElement(processor.process(null, new DriverYieldSignal(), newSimpleAggregatedMemoryContext().newLocalMemoryContext(PageProcessor.class.getSimpleName()), page)).orElseThrow(() -> new AssertionError("page is not present"));
    assertEquals(outputPage.getPositionCount(), 100);
    assertTrue(outputPage.getBlock(0) instanceof DictionaryBlock);
    DictionaryBlock dictionaryBlock = (DictionaryBlock) outputPage.getBlock(0);
    assertEquals(dictionaryBlock.getDictionary().getPositionCount(), 10);
    // test filter caching
    Page outputPage2 = getOnlyElement(processor.process(null, new DriverYieldSignal(), newSimpleAggregatedMemoryContext().newLocalMemoryContext(PageProcessor.class.getSimpleName()), page)).orElseThrow(() -> new AssertionError("page is not present"));
    assertEquals(outputPage2.getPositionCount(), 100);
    assertTrue(outputPage2.getBlock(0) instanceof DictionaryBlock);
    DictionaryBlock dictionaryBlock2 = (DictionaryBlock) outputPage2.getBlock(0);
    // both output pages must have the same dictionary
    assertEquals(dictionaryBlock2.getDictionary(), dictionaryBlock.getDictionary());
}
Also used : PageProcessor(io.trino.operator.project.PageProcessor) ResolvedFunction(io.trino.metadata.ResolvedFunction) DictionaryBlock(io.trino.spi.block.DictionaryBlock) BlockAssertions.createLongDictionaryBlock(io.trino.block.BlockAssertions.createLongDictionaryBlock) DriverYieldSignal(io.trino.operator.DriverYieldSignal) Page(io.trino.spi.Page) CallExpression(io.trino.sql.relational.CallExpression) Test(org.testng.annotations.Test)

Aggregations

DriverYieldSignal (io.trino.operator.DriverYieldSignal)31 Page (io.trino.spi.Page)29 Test (org.testng.annotations.Test)21 Block (io.trino.spi.block.Block)12 LazyBlock (io.trino.spi.block.LazyBlock)10 Optional (java.util.Optional)10 BlockAssertions.createLongSequenceBlock (io.trino.block.BlockAssertions.createLongSequenceBlock)7 PageProcessor (io.trino.operator.project.PageProcessor)7 DictionaryBlock (io.trino.spi.block.DictionaryBlock)7 RunLengthEncodedBlock (io.trino.spi.block.RunLengthEncodedBlock)6 LocalMemoryContext (io.trino.memory.context.LocalMemoryContext)5 BlockAssertions.createLongsBlock (io.trino.block.BlockAssertions.createLongsBlock)4 LongArrayBlock (io.trino.spi.block.LongArrayBlock)4 Type (io.trino.spi.type.Type)4 CallExpression (io.trino.sql.relational.CallExpression)4 Slice (io.airlift.slice.Slice)3 BlockAssertions.createLongDictionaryBlock (io.trino.block.BlockAssertions.createLongDictionaryBlock)3 ResolvedFunction (io.trino.metadata.ResolvedFunction)3 SimplePageWithPositionComparator (io.trino.operator.SimplePageWithPositionComparator)3 VariableWidthBlock (io.trino.spi.block.VariableWidthBlock)3