Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance. Project price only 1 $
You can buy this project and download/modify it how often you want.
/*
* 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.sql.planner;
import com.google.common.base.Throwables;
import com.google.common.collect.ImmutableList;
import io.trino.Session;
import io.trino.metadata.FunctionManager;
import io.trino.metadata.Metadata;
import io.trino.metadata.OperatorNotFoundException;
import io.trino.metadata.ResolvedFunction;
import io.trino.spi.TrinoException;
import io.trino.spi.connector.ConnectorSession;
import io.trino.spi.function.InvocationConvention;
import io.trino.spi.predicate.AllOrNoneValueSet;
import io.trino.spi.predicate.Domain;
import io.trino.spi.predicate.Range;
import io.trino.spi.predicate.Ranges;
import io.trino.spi.predicate.SortedRangeSet;
import io.trino.spi.predicate.ValueSet;
import io.trino.spi.type.Type;
import io.trino.spi.type.TypeOperators;
import io.trino.sql.InterpretedFunctionInvoker;
import java.lang.invoke.MethodHandle;
import java.util.Optional;
import static io.trino.spi.StandardErrorCode.GENERIC_INTERNAL_ERROR;
import static io.trino.spi.function.InvocationConvention.InvocationArgumentConvention.NEVER_NULL;
import static io.trino.spi.function.InvocationConvention.InvocationReturnConvention.FAIL_ON_NULL;
import static io.trino.spi.function.OperatorType.SATURATED_FLOOR_CAST;
import static java.lang.String.format;
import static java.util.Objects.requireNonNull;
/**
* Apply saturated floor casts for implicit coercions on TupleDomain.
* This class does not handle Float.NaN and Double.NaN because
* currently it is used only in dynamic filtering where NaNs are not part of TupleDomain.
*/
public final class DomainCoercer
{
private DomainCoercer() {}
public static Domain applySaturatedCasts(
Metadata metadata,
FunctionManager functionManager,
TypeOperators typeOperators,
Session session,
Domain domain,
Type coercedValueType)
{
return new ImplicitCoercer(metadata, functionManager, typeOperators, session, domain, coercedValueType).applySaturatedCasts();
}
private static class ImplicitCoercer
{
private final ConnectorSession connectorSession;
private final InterpretedFunctionInvoker functionInvoker;
private final ResolvedFunction saturatedFloorCastOperator;
private final ResolvedFunction castToOriginalTypeOperator;
private final MethodHandle comparisonOperator;
private final Domain domain;
private final Type coercedValueType;
private ImplicitCoercer(
Metadata metadata,
FunctionManager functionManager,
TypeOperators typeOperators,
Session session,
Domain domain,
Type coercedValueType)
{
this.connectorSession = session.toConnectorSession();
this.functionInvoker = new InterpretedFunctionInvoker(functionManager);
this.domain = requireNonNull(domain, "domain is null");
this.coercedValueType = requireNonNull(coercedValueType, "coercedValueType is null");
Type originalValueType = domain.getType();
try {
this.saturatedFloorCastOperator = metadata.getCoercion(SATURATED_FLOOR_CAST, originalValueType, coercedValueType);
}
catch (OperatorNotFoundException e) {
throw new IllegalStateException(
format("Saturated floor cast operator not found for coercion from %s to %s", originalValueType, coercedValueType));
}
this.castToOriginalTypeOperator = metadata.getCoercion(coercedValueType, originalValueType);
// choice of placing unordered values first or last does not matter for this code
this.comparisonOperator = typeOperators.getComparisonUnorderedLastOperator(originalValueType, InvocationConvention.simpleConvention(FAIL_ON_NULL, NEVER_NULL, NEVER_NULL));
}
public Domain applySaturatedCasts()
{
if (domain.isNone()) {
return Domain.none(coercedValueType);
}
ValueSet saturatedValueSet = domain.getValues().getValuesProcessor().transform(
this::applySaturatedCasts,
discreteValues -> ValueSet.all(coercedValueType),
allOrNone -> new AllOrNoneValueSet(coercedValueType, allOrNone.isAll()));
return Domain.create(saturatedValueSet, domain.isNullAllowed());
}
private ValueSet applySaturatedCasts(Ranges ranges)
{
ImmutableList.Builder builder = ImmutableList.builder();
for (Range range : ranges.getOrderedRanges()) {
Optional coercedRange = applySaturatedCasts(range);
if (coercedRange.isEmpty()) {
continue;
}
if (coercedRange.get().isAll()) {
return ValueSet.all(coercedValueType);
}
builder.add(coercedRange.get());
}
return SortedRangeSet.copyOf(coercedValueType, builder.build());
}
private Optional applySaturatedCasts(Range range)
{
if (range.isSingleValue()) {
Optional