All Downloads are FREE. Search and download functionalities are using the official Maven repository.

io.trino.operator.ChangeOnlyUpdatedColumnsMergeProcessor Maven / Gradle / Ivy

There is a newer version: 465
Show newest version
/*
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package io.trino.operator;

import io.trino.spi.Page;
import io.trino.spi.block.Block;
import io.trino.spi.block.ColumnarRow;
import io.trino.spi.block.RunLengthEncodedBlock;

import java.util.ArrayList;
import java.util.List;

import static com.google.common.base.Preconditions.checkArgument;
import static io.trino.spi.block.ColumnarRow.toColumnarRow;
import static io.trino.spi.predicate.Utils.nativeValueToBlock;
import static io.trino.spi.type.TinyintType.TINYINT;
import static java.util.Objects.requireNonNull;

/**
 * The transformPage() method in this class does two things:
 * 
    *
  • Transform the input page into an "update" page format
  • *
  • Removes all rows whose operation number is DEFAULT_CASE_OPERATION_NUMBER
  • *
*/ public class ChangeOnlyUpdatedColumnsMergeProcessor implements MergeRowChangeProcessor { private static final Block INSERT_FROM_UPDATE_BLOCK = nativeValueToBlock(TINYINT, 0L); private final int rowIdChannel; private final int mergeRowChannel; private final List dataColumnChannels; private final int writeRedistributionColumnCount; public ChangeOnlyUpdatedColumnsMergeProcessor( int rowIdChannel, int mergeRowChannel, List dataColumnChannels, List redistributionColumnChannels) { this.rowIdChannel = rowIdChannel; this.mergeRowChannel = mergeRowChannel; this.dataColumnChannels = requireNonNull(dataColumnChannels, "dataColumnChannels is null"); this.writeRedistributionColumnCount = redistributionColumnChannels.size(); } @Override public Page transformPage(Page inputPage) { requireNonNull(inputPage, "inputPage is null"); int inputChannelCount = inputPage.getChannelCount(); checkArgument(inputChannelCount >= 2 + writeRedistributionColumnCount, "inputPage channelCount (%s) should be >= 2 + %s", inputChannelCount, writeRedistributionColumnCount); int positionCount = inputPage.getPositionCount(); // TODO: Check with Karol to see if we can get empty pages checkArgument(positionCount > 0, "positionCount should be > 0, but is %s", positionCount); ColumnarRow mergeRow = toColumnarRow(inputPage.getBlock(mergeRowChannel)); if (mergeRow.mayHaveNull()) { for (int position = 0; position < positionCount; position++) { checkArgument(!mergeRow.isNull(position), "The mergeRow may not have null rows"); } } // We've verified that the mergeRow block has no null rows, so it's okay to get the field blocks List builder = new ArrayList<>(dataColumnChannels.size() + 3); for (int channel : dataColumnChannels) { builder.add(mergeRow.getField(channel)); } Block operationChannelBlock = mergeRow.getField(mergeRow.getFieldCount() - 2); builder.add(operationChannelBlock); builder.add(inputPage.getBlock(rowIdChannel)); builder.add(RunLengthEncodedBlock.create(INSERT_FROM_UPDATE_BLOCK, positionCount)); Page result = new Page(builder.toArray(Block[]::new)); int defaultCaseCount = 0; for (int position = 0; position < positionCount; position++) { if (TINYINT.getByte(operationChannelBlock, position) == DEFAULT_CASE_OPERATION_NUMBER) { defaultCaseCount++; } } if (defaultCaseCount == 0) { return result; } int usedCases = 0; int[] positions = new int[positionCount - defaultCaseCount]; for (int position = 0; position < positionCount; position++) { if (TINYINT.getByte(operationChannelBlock, position) != DEFAULT_CASE_OPERATION_NUMBER) { positions[usedCases] = position; usedCases++; } } checkArgument(usedCases + defaultCaseCount == positionCount, "usedCases (%s) + defaultCaseCount (%s) != positionCount (%s)", usedCases, defaultCaseCount, positionCount); return result.getPositions(positions, 0, usedCases); } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy