use of com.facebook.presto.spi.function.FunctionHandle in project presto by prestodb.
the class AggregatedParquetPageSource method getNextPage.
@Override
public Page getNextPage() {
if (completed) {
return null;
}
long start = System.nanoTime();
Block[] blocks = new Block[columnHandles.size()];
for (int fieldId = 0; fieldId < blocks.length; fieldId++) {
HiveColumnHandle columnHandle = columnHandles.get(fieldId);
Aggregation aggregation = columnHandle.getPartialAggregation().get();
Type type = typeManager.getType(columnHandle.getTypeSignature());
BlockBuilder blockBuilder = type.createBlockBuilder(null, batchSize, 0);
int columnIndex = columnHandle.getHiveColumnIndex();
FunctionHandle functionHandle = aggregation.getFunctionHandle();
if (functionResolution.isCountFunction(functionHandle)) {
long rowCount = getRowCountFromParquetMetadata(parquetMetadata);
if (!aggregation.getArguments().isEmpty()) {
rowCount -= getNumNulls(parquetMetadata, columnIndex);
}
blockBuilder = blockBuilder.writeLong(rowCount);
} else if (functionResolution.isMaxFunction(functionHandle)) {
writeMinMax(parquetMetadata, columnIndex, blockBuilder, type, columnHandle.getHiveType(), false);
} else if (functionResolution.isMinFunction(functionHandle)) {
writeMinMax(parquetMetadata, columnIndex, blockBuilder, type, columnHandle.getHiveType(), true);
} else {
throw new UnsupportedOperationException(aggregation.getFunctionHandle().toString() + " is not supported");
}
blocks[fieldId] = blockBuilder.build();
}
completed = true;
readTimeNanos += System.nanoTime() - start;
return new Page(batchSize, blocks);
}
use of com.facebook.presto.spi.function.FunctionHandle in project presto by prestodb.
the class ExtractSpatialJoins method addPartitioningNodes.
private static PlanNode addPartitioningNodes(Context context, FunctionAndTypeManager functionAndTypeManager, PlanNode node, VariableReferenceExpression partitionVariable, KdbTree kdbTree, RowExpression geometry, Optional<RowExpression> radius) {
Assignments.Builder projections = Assignments.builder();
for (VariableReferenceExpression outputVariable : node.getOutputVariables()) {
projections.put(outputVariable, outputVariable);
}
FunctionHandle castFunctionHandle = functionAndTypeManager.lookupCast(CAST, VARCHAR.getTypeSignature(), KDB_TREE.getTypeSignature());
ImmutableList.Builder partitioningArgumentsBuilder = ImmutableList.builder().add(new CallExpression(partitionVariable.getSourceLocation(), CAST.name(), castFunctionHandle, KDB_TREE, ImmutableList.of(Expressions.constant(utf8Slice(KdbTreeUtils.toJson(kdbTree)), VARCHAR)))).add(geometry);
radius.map(partitioningArgumentsBuilder::add);
List<RowExpression> partitioningArguments = partitioningArgumentsBuilder.build();
String spatialPartitionsFunctionName = "spatial_partitions";
FunctionHandle functionHandle = functionAndTypeManager.lookupFunction(spatialPartitionsFunctionName, fromTypes(partitioningArguments.stream().map(RowExpression::getType).collect(toImmutableList())));
CallExpression partitioningFunction = new CallExpression(partitionVariable.getSourceLocation(), spatialPartitionsFunctionName, functionHandle, new ArrayType(INTEGER), partitioningArguments);
VariableReferenceExpression partitionsVariable = context.getVariableAllocator().newVariable(partitioningFunction);
projections.put(partitionsVariable, partitioningFunction);
return new UnnestNode(node.getSourceLocation(), context.getIdAllocator().getNextId(), new ProjectNode(node.getSourceLocation(), context.getIdAllocator().getNextId(), node, projections.build(), LOCAL), node.getOutputVariables(), ImmutableMap.of(partitionsVariable, ImmutableList.of(partitionVariable)), Optional.empty());
}
use of com.facebook.presto.spi.function.FunctionHandle in project presto by prestodb.
the class RowToRowCast method generateRowCast.
private static Class<?> generateRowCast(Type fromType, Type toType, FunctionAndTypeManager functionAndTypeManager) {
List<Type> toTypes = toType.getTypeParameters();
List<Type> fromTypes = fromType.getTypeParameters();
CallSiteBinder binder = new CallSiteBinder();
// Embed the MD5 hash code of input and output types into the generated class name instead of the raw type names,
// which could prevent the class name from hitting the length limitation and invalid characters.
byte[] md5Suffix = Hashing.md5().hashBytes((fromType + "$" + toType).getBytes()).asBytes();
ClassDefinition definition = new ClassDefinition(a(PUBLIC, FINAL), makeClassName(Joiner.on("$").join("RowCast", BaseEncoding.base16().encode(md5Suffix))), type(Object.class));
Parameter properties = arg("properties", SqlFunctionProperties.class);
Parameter value = arg("value", Block.class);
MethodDefinition method = definition.declareMethod(a(PUBLIC, STATIC), "castRow", type(Block.class), properties, value);
Scope scope = method.getScope();
BytecodeBlock body = method.getBody();
Variable wasNull = scope.declareVariable(boolean.class, "wasNull");
Variable blockBuilder = scope.createTempVariable(BlockBuilder.class);
Variable singleRowBlockWriter = scope.createTempVariable(BlockBuilder.class);
body.append(wasNull.set(constantBoolean(false)));
CachedInstanceBinder cachedInstanceBinder = new CachedInstanceBinder(definition, binder);
// create the row block builder
body.append(blockBuilder.set(constantType(binder, toType).invoke("createBlockBuilder", BlockBuilder.class, constantNull(BlockBuilderStatus.class), constantInt(1))));
body.append(singleRowBlockWriter.set(blockBuilder.invoke("beginBlockEntry", BlockBuilder.class)));
// loop through to append member blocks
for (int i = 0; i < toTypes.size(); i++) {
FunctionHandle functionHandle = functionAndTypeManager.lookupCast(CastType.CAST, fromTypes.get(i).getTypeSignature(), toTypes.get(i).getTypeSignature());
JavaScalarFunctionImplementation function = functionAndTypeManager.getJavaScalarFunctionImplementation(functionHandle);
Type currentFromType = fromTypes.get(i);
if (currentFromType.equals(UNKNOWN)) {
body.append(singleRowBlockWriter.invoke("appendNull", BlockBuilder.class).pop());
continue;
}
BytecodeExpression fromElement = constantType(binder, currentFromType).getValue(value, constantInt(i));
BytecodeExpression toElement = invokeFunction(scope, cachedInstanceBinder, CAST.name(), function, fromElement);
IfStatement ifElementNull = new IfStatement("if the element in the row type is null...");
ifElementNull.condition(value.invoke("isNull", boolean.class, constantInt(i))).ifTrue(singleRowBlockWriter.invoke("appendNull", BlockBuilder.class).pop()).ifFalse(constantType(binder, toTypes.get(i)).writeValue(singleRowBlockWriter, toElement));
body.append(ifElementNull);
}
// call blockBuilder.closeEntry() and return the single row block
body.append(blockBuilder.invoke("closeEntry", BlockBuilder.class).pop());
body.append(constantType(binder, toType).invoke("getObject", Object.class, blockBuilder.cast(Block.class), constantInt(0)).cast(Block.class).ret());
// create constructor
MethodDefinition constructorDefinition = definition.declareConstructor(a(PUBLIC));
BytecodeBlock constructorBody = constructorDefinition.getBody();
Variable thisVariable = constructorDefinition.getThis();
constructorBody.comment("super();").append(thisVariable).invokeConstructor(Object.class);
cachedInstanceBinder.generateInitializations(thisVariable, constructorBody);
constructorBody.ret();
return defineClass(definition, Object.class, binder.getBindings(), RowToRowCast.class.getClassLoader());
}
use of com.facebook.presto.spi.function.FunctionHandle in project presto by prestodb.
the class TryCastFunction method specialize.
@Override
public BuiltInScalarFunctionImplementation specialize(BoundVariables boundVariables, int arity, FunctionAndTypeManager functionAndTypeManager) {
Type fromType = boundVariables.getTypeVariable("F");
Type toType = boundVariables.getTypeVariable("T");
Class<?> returnType = Primitives.wrap(toType.getJavaType());
List<ArgumentProperty> argumentProperties;
MethodHandle tryCastHandle;
// the resulting method needs to return a boxed type
FunctionHandle functionHandle = functionAndTypeManager.lookupCast(CAST, fromType.getTypeSignature(), toType.getTypeSignature());
ScalarFunctionImplementationChoice implementation = getAllScalarFunctionImplementationChoices(functionAndTypeManager.getJavaScalarFunctionImplementation(functionHandle)).get(0);
argumentProperties = ImmutableList.of(implementation.getArgumentProperty(0));
MethodHandle coercion = implementation.getMethodHandle();
coercion = coercion.asType(methodType(returnType, coercion.type()));
MethodHandle exceptionHandler = dropArguments(constant(returnType, null), 0, RuntimeException.class);
tryCastHandle = catchException(coercion, RuntimeException.class, exceptionHandler);
return new BuiltInScalarFunctionImplementation(true, argumentProperties, tryCastHandle);
}
use of com.facebook.presto.spi.function.FunctionHandle 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 spatialComparison, Metadata metadata, SplitManager splitManager, PageSourceManager pageSourceManager) {
FunctionMetadata spatialComparisonMetadata = metadata.getFunctionAndTypeManager().getFunctionMetadata(spatialComparison.getFunctionHandle());
checkArgument(spatialComparison.getArguments().size() == 2 && spatialComparisonMetadata.getOperatorType().isPresent());
PlanNode leftNode = joinNode.getLeft();
PlanNode rightNode = joinNode.getRight();
List<VariableReferenceExpression> leftVariables = leftNode.getOutputVariables();
List<VariableReferenceExpression> rightVariables = rightNode.getOutputVariables();
RowExpression radius;
Optional<VariableReferenceExpression> newRadiusVariable;
CallExpression newComparison;
if (spatialComparisonMetadata.getOperatorType().get() == OperatorType.LESS_THAN || spatialComparisonMetadata.getOperatorType().get() == OperatorType.LESS_THAN_OR_EQUAL) {
// ST_Distance(a, b) <= r
radius = spatialComparison.getArguments().get(1);
Set<VariableReferenceExpression> radiusVariables = extractUnique(radius);
if (radiusVariables.isEmpty() || (rightVariables.containsAll(radiusVariables) && containsNone(leftVariables, radiusVariables))) {
newRadiusVariable = newRadiusVariable(context, radius);
newComparison = new CallExpression(spatialComparison.getSourceLocation(), spatialComparison.getDisplayName(), spatialComparison.getFunctionHandle(), spatialComparison.getType(), ImmutableList.of(spatialComparison.getArguments().get(0), mapToExpression(newRadiusVariable, radius)));
} else {
return Result.empty();
}
} else {
// r >= ST_Distance(a, b)
radius = spatialComparison.getArguments().get(0);
Set<VariableReferenceExpression> radiusVariables = extractUnique(radius);
if (radiusVariables.isEmpty() || (rightVariables.containsAll(radiusVariables) && containsNone(leftVariables, radiusVariables))) {
newRadiusVariable = newRadiusVariable(context, radius);
OperatorType flippedOperatorType = flip(spatialComparisonMetadata.getOperatorType().get());
FunctionHandle flippedHandle = getFlippedFunctionHandle(spatialComparison, metadata.getFunctionAndTypeManager());
newComparison = new CallExpression(spatialComparison.getSourceLocation(), // TODO verify if this is the correct function displayName
flippedOperatorType.getOperator(), flippedHandle, spatialComparison.getType(), ImmutableList.of(spatialComparison.getArguments().get(1), mapToExpression(newRadiusVariable, radius)));
} else {
return Result.empty();
}
}
RowExpression newFilter = replaceExpression(filter, ImmutableMap.of(spatialComparison, newComparison));
PlanNode newRightNode = newRadiusVariable.map(variable -> addProjection(context, rightNode, variable, radius)).orElse(rightNode);
JoinNode newJoinNode = new JoinNode(joinNode.getSourceLocation(), joinNode.getId(), joinNode.getType(), leftNode, newRightNode, joinNode.getCriteria(), joinNode.getOutputVariables(), Optional.of(newFilter), joinNode.getLeftHashVariable(), joinNode.getRightHashVariable(), joinNode.getDistributionType(), joinNode.getDynamicFilters());
return tryCreateSpatialJoin(context, newJoinNode, newFilter, nodeId, outputVariables, (CallExpression) newComparison.getArguments().get(0), Optional.of(newComparison.getArguments().get(1)), metadata, splitManager, pageSourceManager);
}
Aggregations