use of com.facebook.presto.metadata.FunctionAndTypeManager in project presto by prestodb.
the class AbstractGreatestLeast method specialize.
@Override
public BuiltInScalarFunctionImplementation specialize(BoundVariables boundVariables, int arity, FunctionAndTypeManager functionAndTypeManager) {
Type type = boundVariables.getTypeVariable("E");
checkArgument(type.isOrderable(), "Type must be orderable");
MethodHandle compareMethod = functionAndTypeManager.getJavaScalarFunctionImplementation(functionAndTypeManager.resolveOperator(operatorType, fromTypes(type, type))).getMethodHandle();
List<Class<?>> javaTypes = IntStream.range(0, arity).mapToObj(i -> type.getJavaType()).collect(toImmutableList());
Class<?> clazz = generate(javaTypes, type, compareMethod);
MethodHandle methodHandle = methodHandle(clazz, getSignature().getNameSuffix(), javaTypes.toArray(new Class<?>[javaTypes.size()]));
return new BuiltInScalarFunctionImplementation(false, nCopies(javaTypes.size(), valueTypeArgumentProperty(RETURN_NULL_ON_NULL)), methodHandle);
}
use of com.facebook.presto.metadata.FunctionAndTypeManager in project presto by prestodb.
the class TestFieldSetFilteringRecordSet method test.
@Test
public void test() {
FunctionAndTypeManager functionAndTypeManager = createTestFunctionAndTypeManager();
ArrayType arrayOfBigintType = new ArrayType(BIGINT);
FieldSetFilteringRecordSet fieldSetFilteringRecordSet = new FieldSetFilteringRecordSet(functionAndTypeManager, new InMemoryRecordSet(ImmutableList.of(BIGINT, BIGINT, TIMESTAMP_WITH_TIME_ZONE, TIMESTAMP_WITH_TIME_ZONE, arrayOfBigintType, arrayOfBigintType), ImmutableList.of(ImmutableList.of(100L, 100L, // test same time in different time zone to make sure equal check was done properly
packDateTimeWithZone(100, getTimeZoneKeyForOffset(123)), packDateTimeWithZone(100, getTimeZoneKeyForOffset(234)), // test structural type
arrayBlockOf(BIGINT, 12, 34, 56), arrayBlockOf(BIGINT, 12, 34, 56)))), ImmutableList.of(ImmutableSet.of(0, 1), ImmutableSet.of(2, 3), ImmutableSet.of(4, 5)));
RecordCursor recordCursor = fieldSetFilteringRecordSet.cursor();
assertTrue(recordCursor.advanceNextPosition());
}
use of com.facebook.presto.metadata.FunctionAndTypeManager in project presto by prestodb.
the class DoubleSumAggregationBenchmark method createOperatorFactories.
@Override
protected List<? extends OperatorFactory> createOperatorFactories() {
OperatorFactory tableScanOperator = createTableScanOperator(0, new PlanNodeId("test"), "orders", "totalprice");
FunctionAndTypeManager functionAndTypeManager = MetadataManager.createTestMetadataManager().getFunctionAndTypeManager();
InternalAggregationFunction doubleSum = functionAndTypeManager.getAggregateFunctionImplementation(functionAndTypeManager.lookupFunction("sum", fromTypes(DOUBLE)));
AggregationOperatorFactory aggregationOperator = new AggregationOperatorFactory(1, new PlanNodeId("test"), Step.SINGLE, ImmutableList.of(doubleSum.bind(ImmutableList.of(0), Optional.empty())), false);
return ImmutableList.of(tableScanOperator, aggregationOperator);
}
use of com.facebook.presto.metadata.FunctionAndTypeManager in project presto by prestodb.
the class CodegenScalarFromAnnotationsParser method createSqlScalarFunction.
private static SqlScalarFunction createSqlScalarFunction(Method method) {
CodegenScalarFunction codegenScalarFunction = method.getAnnotation(CodegenScalarFunction.class);
Signature signature = new Signature(QualifiedObjectName.valueOf(DEFAULT_NAMESPACE, codegenScalarFunction.value()), FunctionKind.SCALAR, Arrays.stream(method.getAnnotationsByType(TypeParameter.class)).map(t -> withVariadicBound(t.value(), t.boundedBy().isEmpty() ? null : t.boundedBy())).collect(toImmutableList()), ImmutableList.of(), parseTypeSignature(method.getAnnotation(SqlType.class).value()), Arrays.stream(method.getParameters()).map(p -> parseTypeSignature(p.getAnnotation(SqlType.class).value())).collect(toImmutableList()), false);
return new SqlScalarFunction(signature) {
@Override
public BuiltInScalarFunctionImplementation specialize(BoundVariables boundVariables, int arity, FunctionAndTypeManager functionAndTypeManager) {
Signature boundSignature = applyBoundVariables(signature, boundVariables, arity);
MethodHandle handle;
try {
handle = (MethodHandle) method.invoke(null, boundSignature.getArgumentTypes().stream().map(t -> functionAndTypeManager.getType(t)).toArray());
} catch (Exception e) {
throw new PrestoException(FUNCTION_IMPLEMENTATION_ERROR, format("Method %s does not return valid MethodHandle", method), e);
}
return new BuiltInScalarFunctionImplementation(method.getAnnotation(SqlNullable.class) != null, getArgumentProperties(method), handle, Optional.empty());
}
@Override
public SqlFunctionVisibility getVisibility() {
return codegenScalarFunction.visibility();
}
@Override
public boolean isDeterministic() {
return codegenScalarFunction.deterministic();
}
@Override
public String getDescription() {
Description description = method.getAnnotation(Description.class);
return description == null ? "" : description.value();
}
@Override
public boolean isCalledOnNullInput() {
return codegenScalarFunction.calledOnNullInput();
}
};
}
use of com.facebook.presto.metadata.FunctionAndTypeManager in project presto by prestodb.
the class ExtractSpatialJoins method tryCreateSpatialJoin.
private static Result tryCreateSpatialJoin(Context context, JoinNode joinNode, RowExpression filter, PlanNodeId nodeId, List<VariableReferenceExpression> outputVariables, CallExpression spatialFunction, Optional<RowExpression> radius, Metadata metadata, SplitManager splitManager, PageSourceManager pageSourceManager) {
FunctionAndTypeManager functionAndTypeManager = metadata.getFunctionAndTypeManager();
List<RowExpression> arguments = spatialFunction.getArguments();
verify(arguments.size() == 2);
RowExpression firstArgument = arguments.get(0);
RowExpression secondArgument = arguments.get(1);
// Currently, only inner joins are supported for spherical geometries.
if (joinNode.getType() != INNER && isSphericalJoin(metadata, firstArgument, secondArgument)) {
return Result.empty();
}
Set<VariableReferenceExpression> firstVariables = extractUnique(firstArgument);
Set<VariableReferenceExpression> secondVariables = extractUnique(secondArgument);
if (firstVariables.isEmpty() || secondVariables.isEmpty()) {
return Result.empty();
}
// If either firstArgument or secondArgument is not a
// VariableReferenceExpression, will replace the left/right join node
// with a projection that adds the argument as a variable.
Optional<VariableReferenceExpression> newFirstVariable = newGeometryVariable(context, firstArgument);
Optional<VariableReferenceExpression> newSecondVariable = newGeometryVariable(context, secondArgument);
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, firstVariables, secondVariables);
if (alignment > 0) {
newLeftNode = newFirstVariable.map(variable -> addProjection(context, leftNode, variable, firstArgument)).orElse(leftNode);
newRightNode = newSecondVariable.map(variable -> addProjection(context, rightNode, variable, secondArgument)).orElse(rightNode);
} else if (alignment < 0) {
newLeftNode = newSecondVariable.map(variable -> addProjection(context, leftNode, variable, secondArgument)).orElse(leftNode);
newRightNode = newFirstVariable.map(variable -> addProjection(context, rightNode, variable, firstArgument)).orElse(rightNode);
} else {
return Result.empty();
}
RowExpression newFirstArgument = mapToExpression(newFirstVariable, firstArgument);
RowExpression newSecondArgument = mapToExpression(newSecondVariable, secondArgument);
// Implement partitioned spatial joins:
// If the session parameter points to a valid spatial partitioning, use
// that to assign to each probe and build rows the partitions that the
// geometry intersects. This is a projection that adds an array of ints
// which is subsequently unnested.
Optional<String> spatialPartitioningTableName = canPartitionSpatialJoin(joinNode) ? getSpatialPartitioningTableName(context.getSession()) : Optional.empty();
Optional<KdbTree> kdbTree = spatialPartitioningTableName.map(tableName -> loadKdbTree(tableName, context.getSession(), metadata, splitManager, pageSourceManager));
Optional<VariableReferenceExpression> leftPartitionVariable = Optional.empty();
Optional<VariableReferenceExpression> rightPartitionVariable = Optional.empty();
if (kdbTree.isPresent()) {
leftPartitionVariable = Optional.of(context.getVariableAllocator().newVariable(newFirstArgument.getSourceLocation(), "pid", INTEGER));
rightPartitionVariable = Optional.of(context.getVariableAllocator().newVariable(newSecondArgument.getSourceLocation(), "pid", INTEGER));
if (alignment > 0) {
newLeftNode = addPartitioningNodes(context, functionAndTypeManager, newLeftNode, leftPartitionVariable.get(), kdbTree.get(), newFirstArgument, Optional.empty());
newRightNode = addPartitioningNodes(context, functionAndTypeManager, newRightNode, rightPartitionVariable.get(), kdbTree.get(), newSecondArgument, radius);
} else {
newLeftNode = addPartitioningNodes(context, functionAndTypeManager, newLeftNode, leftPartitionVariable.get(), kdbTree.get(), newSecondArgument, Optional.empty());
newRightNode = addPartitioningNodes(context, functionAndTypeManager, newRightNode, rightPartitionVariable.get(), kdbTree.get(), newFirstArgument, radius);
}
}
CallExpression newSpatialFunction = new CallExpression(spatialFunction.getSourceLocation(), spatialFunction.getDisplayName(), spatialFunction.getFunctionHandle(), spatialFunction.getType(), ImmutableList.of(newFirstArgument, newSecondArgument));
RowExpression newFilter = RowExpressionNodeInliner.replaceExpression(filter, ImmutableMap.of(spatialFunction, newSpatialFunction));
return Result.ofPlanNode(new SpatialJoinNode(joinNode.getSourceLocation(), nodeId, SpatialJoinNode.Type.fromJoinNodeType(joinNode.getType()), newLeftNode, newRightNode, outputVariables, newFilter, leftPartitionVariable, rightPartitionVariable, kdbTree.map(KdbTreeUtils::toJson)));
}
Aggregations