use of io.trino.spi.type.Type in project trino by trinodb.
the class ExtractSpatialJoins method tryCreateSpatialJoin.
private static Result tryCreateSpatialJoin(Context context, JoinNode joinNode, Expression filter, PlanNodeId nodeId, List<Symbol> outputSymbols, FunctionCall spatialFunction, Optional<Expression> radius, PlannerContext plannerContext, SplitManager splitManager, PageSourceManager pageSourceManager, TypeAnalyzer typeAnalyzer) {
// TODO Add support for distributed left spatial joins
Optional<String> spatialPartitioningTableName = joinNode.getType() == INNER ? getSpatialPartitioningTableName(context.getSession()) : Optional.empty();
Optional<KdbTree> kdbTree = spatialPartitioningTableName.map(tableName -> loadKdbTree(tableName, context.getSession(), plannerContext.getMetadata(), splitManager, pageSourceManager));
List<Expression> arguments = spatialFunction.getArguments();
verify(arguments.size() == 2);
Expression firstArgument = arguments.get(0);
Expression secondArgument = arguments.get(1);
Type sphericalGeographyType = plannerContext.getTypeManager().getType(SPHERICAL_GEOGRAPHY_TYPE_SIGNATURE);
if (typeAnalyzer.getType(context.getSession(), context.getSymbolAllocator().getTypes(), firstArgument).equals(sphericalGeographyType) || typeAnalyzer.getType(context.getSession(), context.getSymbolAllocator().getTypes(), secondArgument).equals(sphericalGeographyType)) {
return Result.empty();
}
Set<Symbol> firstSymbols = extractUnique(firstArgument);
Set<Symbol> secondSymbols = extractUnique(secondArgument);
if (firstSymbols.isEmpty() || secondSymbols.isEmpty()) {
return Result.empty();
}
Optional<Symbol> newFirstSymbol = newGeometrySymbol(context, firstArgument, plannerContext.getTypeManager());
Optional<Symbol> newSecondSymbol = newGeometrySymbol(context, secondArgument, plannerContext.getTypeManager());
PlanNode leftNode = joinNode.getLeft();
PlanNode rightNode = joinNode.getRight();
PlanNode newLeftNode;
PlanNode newRightNode;
// Check if the order of arguments of the spatial function matches the order of join sides
int alignment = checkAlignment(joinNode, firstSymbols, secondSymbols);
if (alignment > 0) {
newLeftNode = newFirstSymbol.map(symbol -> addProjection(context, leftNode, symbol, firstArgument)).orElse(leftNode);
newRightNode = newSecondSymbol.map(symbol -> addProjection(context, rightNode, symbol, secondArgument)).orElse(rightNode);
} else if (alignment < 0) {
newLeftNode = newSecondSymbol.map(symbol -> addProjection(context, leftNode, symbol, secondArgument)).orElse(leftNode);
newRightNode = newFirstSymbol.map(symbol -> addProjection(context, rightNode, symbol, firstArgument)).orElse(rightNode);
} else {
return Result.empty();
}
Expression newFirstArgument = toExpression(newFirstSymbol, firstArgument);
Expression newSecondArgument = toExpression(newSecondSymbol, secondArgument);
Optional<Symbol> leftPartitionSymbol = Optional.empty();
Optional<Symbol> rightPartitionSymbol = Optional.empty();
if (kdbTree.isPresent()) {
leftPartitionSymbol = Optional.of(context.getSymbolAllocator().newSymbol("pid", INTEGER));
rightPartitionSymbol = Optional.of(context.getSymbolAllocator().newSymbol("pid", INTEGER));
if (alignment > 0) {
newLeftNode = addPartitioningNodes(plannerContext, context, newLeftNode, leftPartitionSymbol.get(), kdbTree.get(), newFirstArgument, Optional.empty());
newRightNode = addPartitioningNodes(plannerContext, context, newRightNode, rightPartitionSymbol.get(), kdbTree.get(), newSecondArgument, radius);
} else {
newLeftNode = addPartitioningNodes(plannerContext, context, newLeftNode, leftPartitionSymbol.get(), kdbTree.get(), newSecondArgument, Optional.empty());
newRightNode = addPartitioningNodes(plannerContext, context, newRightNode, rightPartitionSymbol.get(), kdbTree.get(), newFirstArgument, radius);
}
}
Expression newSpatialFunction = FunctionCallBuilder.resolve(context.getSession(), plannerContext.getMetadata()).setName(spatialFunction.getName()).addArgument(GEOMETRY_TYPE_SIGNATURE, newFirstArgument).addArgument(GEOMETRY_TYPE_SIGNATURE, newSecondArgument).build();
Expression newFilter = replaceExpression(filter, ImmutableMap.of(spatialFunction, newSpatialFunction));
return Result.ofPlanNode(new SpatialJoinNode(nodeId, SpatialJoinNode.Type.fromJoinNodeType(joinNode.getType()), newLeftNode, newRightNode, outputSymbols, newFilter, leftPartitionSymbol, rightPartitionSymbol, kdbTree.map(KdbTreeUtils::toJson)));
}
use of io.trino.spi.type.Type in project trino by trinodb.
the class DynamicFilterSourceOperator method finish.
@Override
public void finish() {
if (finished) {
// NOTE: finish() may be called multiple times (see comment at Driver::processInternal).
return;
}
finished = true;
ImmutableMap.Builder<DynamicFilterId, Domain> domainsBuilder = ImmutableMap.builder();
if (valueSets == null) {
if (minValues == null) {
// else it was notified with 'all' in handleMinMaxCollectionLimitExceeded
return;
}
// valueSets became too large, create TupleDomain from min/max values
for (Integer channelIndex : minMaxChannels) {
Type type = channels.get(channelIndex).type;
if (minValues[channelIndex] == null) {
// all values were null
domainsBuilder.put(channels.get(channelIndex).filterId, Domain.none(type));
continue;
}
Object min = readNativeValue(type, minValues[channelIndex], 0);
Object max = readNativeValue(type, maxValues[channelIndex], 0);
Domain domain = Domain.create(ValueSet.ofRanges(range(type, min, true, max, true)), false);
domainsBuilder.put(channels.get(channelIndex).filterId, domain);
}
minValues = null;
maxValues = null;
dynamicPredicateConsumer.accept(TupleDomain.withColumnDomains(domainsBuilder.buildOrThrow()));
return;
}
for (int channelIndex = 0; channelIndex < channels.size(); ++channelIndex) {
Block block = blockBuilders[channelIndex].build();
Type type = channels.get(channelIndex).type;
domainsBuilder.put(channels.get(channelIndex).filterId, convertToDomain(type, block));
}
valueSets = null;
blockBuilders = null;
dynamicPredicateConsumer.accept(TupleDomain.withColumnDomains(domainsBuilder.buildOrThrow()));
}
use of io.trino.spi.type.Type in project trino by trinodb.
the class TypeRegistry method addType.
public void addType(Type type) {
requireNonNull(type, "type is null");
Type existingType = types.putIfAbsent(type.getTypeSignature(), type);
checkState(existingType == null || existingType.equals(type), "Type %s is already registered", type);
}
use of io.trino.spi.type.Type in project trino by trinodb.
the class SessionPropertyManager method getJsonCodecForType.
private static <T> JsonCodec<T> getJsonCodecForType(Type type) {
if (VarcharType.VARCHAR.equals(type)) {
return (JsonCodec<T>) JSON_CODEC_FACTORY.jsonCodec(String.class);
}
if (BooleanType.BOOLEAN.equals(type)) {
return (JsonCodec<T>) JSON_CODEC_FACTORY.jsonCodec(Boolean.class);
}
if (BigintType.BIGINT.equals(type)) {
return (JsonCodec<T>) JSON_CODEC_FACTORY.jsonCodec(Long.class);
}
if (IntegerType.INTEGER.equals(type)) {
return (JsonCodec<T>) JSON_CODEC_FACTORY.jsonCodec(Integer.class);
}
if (DoubleType.DOUBLE.equals(type)) {
return (JsonCodec<T>) JSON_CODEC_FACTORY.jsonCodec(Double.class);
}
if (type instanceof ArrayType) {
Type elementType = ((ArrayType) type).getElementType();
return (JsonCodec<T>) JSON_CODEC_FACTORY.listJsonCodec(getJsonCodecForType(elementType));
}
if (type instanceof MapType) {
Type keyType = ((MapType) type).getKeyType();
Type valueType = ((MapType) type).getValueType();
return (JsonCodec<T>) JSON_CODEC_FACTORY.mapJsonCodec(getMapKeyType(keyType), getJsonCodecForType(valueType));
}
throw new TrinoException(INVALID_SESSION_PROPERTY, format("Session property type %s is not supported", type));
}
use of io.trino.spi.type.Type in project trino by trinodb.
the class PropertyUtil method evaluateProperty.
private static Object evaluateProperty(Expression expression, PropertyMetadata<?> property, Session session, PlannerContext plannerContext, AccessControl accessControl, Map<NodeRef<Parameter>, Expression> parameters, ErrorCodeSupplier errorCode, String propertyTypeDescription) {
Object sqlObjectValue;
try {
Type expectedType = property.getSqlType();
Expression rewritten = ExpressionTreeRewriter.rewriteWith(new ParameterRewriter(parameters), expression);
Object value = evaluateConstantExpression(rewritten, expectedType, plannerContext, session, accessControl, parameters);
// convert to object value type of SQL type
BlockBuilder blockBuilder = expectedType.createBlockBuilder(null, 1);
writeNativeValue(expectedType, blockBuilder, value);
sqlObjectValue = expectedType.getObjectValue(session.toConnectorSession(), blockBuilder, 0);
} catch (TrinoException e) {
throw new TrinoException(errorCode, format("Invalid value for %s '%s': Cannot convert [%s] to %s", propertyTypeDescription, property.getName(), expression, property.getSqlType()), e);
}
if (sqlObjectValue == null) {
throw new TrinoException(errorCode, format("Invalid null value for %s '%s' from [%s]", propertyTypeDescription, property.getName(), expression));
}
try {
return property.decode(sqlObjectValue);
} catch (Exception e) {
throw new TrinoException(errorCode, format("Unable to set %s '%s' to [%s]: %s", propertyTypeDescription, property.getName(), expression, e.getMessage()), e);
}
}
Aggregations