use of com.facebook.presto.spi.PrestoException in project presto by prestodb.
the class FunctionRegistry method resolveFunction.
public Signature resolveFunction(QualifiedName name, List<TypeSignatureProvider> parameterTypes) {
Collection<SqlFunction> allCandidates = functions.get(name);
List<SqlFunction> exactCandidates = allCandidates.stream().filter(function -> function.getSignature().getTypeVariableConstraints().isEmpty()).collect(Collectors.toList());
Optional<Signature> match = matchFunctionExact(exactCandidates, parameterTypes);
if (match.isPresent()) {
return match.get();
}
List<SqlFunction> genericCandidates = allCandidates.stream().filter(function -> !function.getSignature().getTypeVariableConstraints().isEmpty()).collect(Collectors.toList());
match = matchFunctionExact(genericCandidates, parameterTypes);
if (match.isPresent()) {
return match.get();
}
match = matchFunctionWithCoercion(allCandidates, parameterTypes);
if (match.isPresent()) {
return match.get();
}
List<String> expectedParameters = new ArrayList<>();
for (SqlFunction function : allCandidates) {
expectedParameters.add(format("%s(%s) %s", name, Joiner.on(", ").join(function.getSignature().getArgumentTypes()), Joiner.on(", ").join(function.getSignature().getTypeVariableConstraints())));
}
String parameters = Joiner.on(", ").join(parameterTypes);
String message = format("Function %s not registered", name);
if (!expectedParameters.isEmpty()) {
String expected = Joiner.on(", ").join(expectedParameters);
message = format("Unexpected parameters (%s) for function %s. Expected: %s", parameters, name, expected);
}
if (name.getSuffix().startsWith(MAGIC_LITERAL_FUNCTION_PREFIX)) {
// extract type from function name
String typeName = name.getSuffix().substring(MAGIC_LITERAL_FUNCTION_PREFIX.length());
// lookup the type
Type type = typeManager.getType(parseTypeSignature(typeName));
requireNonNull(type, format("Type %s not registered", typeName));
// verify we have one parameter of the proper type
checkArgument(parameterTypes.size() == 1, "Expected one argument to literal function, but got %s", parameterTypes);
Type parameterType = typeManager.getType(parameterTypes.get(0).getTypeSignature());
requireNonNull(parameterType, format("Type %s not found", parameterTypes.get(0)));
return getMagicLiteralFunctionSignature(type);
}
throw new PrestoException(FUNCTION_NOT_FOUND, message);
}
use of com.facebook.presto.spi.PrestoException in project presto by prestodb.
the class SimpleNodeSelector method computeAssignments.
@Override
public SplitPlacementResult computeAssignments(Set<Split> splits, List<RemoteTask> existingTasks) {
Multimap<Node, Split> assignment = HashMultimap.create();
NodeMap nodeMap = this.nodeMap.get().get();
NodeAssignmentStats assignmentStats = new NodeAssignmentStats(nodeTaskMap, nodeMap, existingTasks);
ResettableRandomizedIterator<Node> randomCandidates = randomizedNodes(nodeMap, includeCoordinator);
Set<Node> blockedExactNodes = new HashSet<>();
boolean splitWaitingForAnyNode = false;
for (Split split : splits) {
randomCandidates.reset();
List<Node> candidateNodes;
if (!split.isRemotelyAccessible()) {
candidateNodes = selectExactNodes(nodeMap, split.getAddresses(), includeCoordinator);
} else {
candidateNodes = selectNodes(minCandidates, randomCandidates);
}
if (candidateNodes.isEmpty()) {
log.debug("No nodes available to schedule %s. Available nodes %s", split, nodeMap.getNodesByHost().keys());
throw new PrestoException(NO_NODES_AVAILABLE, "No nodes available to run query");
}
Node chosenNode = null;
int min = Integer.MAX_VALUE;
for (Node node : candidateNodes) {
int totalSplitCount = assignmentStats.getTotalSplitCount(node);
if (totalSplitCount < min && totalSplitCount < maxSplitsPerNode) {
chosenNode = node;
min = totalSplitCount;
}
}
if (chosenNode == null) {
// min is guaranteed to be MAX_VALUE at this line
for (Node node : candidateNodes) {
int totalSplitCount = assignmentStats.getQueuedSplitCountForStage(node);
if (totalSplitCount < min && totalSplitCount < maxPendingSplitsPerTask) {
chosenNode = node;
min = totalSplitCount;
}
}
}
if (chosenNode != null) {
assignment.put(chosenNode, split);
assignmentStats.addAssignedSplit(chosenNode);
} else {
if (split.isRemotelyAccessible()) {
splitWaitingForAnyNode = true;
} else // Exact node set won't matter, if a split is waiting for any node
if (!splitWaitingForAnyNode) {
blockedExactNodes.addAll(candidateNodes);
}
}
}
ListenableFuture<?> blocked;
if (splitWaitingForAnyNode) {
blocked = toWhenHasSplitQueueSpaceFuture(existingTasks, calculateLowWatermark(maxPendingSplitsPerTask));
} else {
blocked = toWhenHasSplitQueueSpaceFuture(blockedExactNodes, existingTasks, calculateLowWatermark(maxPendingSplitsPerTask));
}
return new SplitPlacementResult(blocked, assignment);
}
use of com.facebook.presto.spi.PrestoException in project presto by prestodb.
the class ClusterMemoryManager method process.
public synchronized void process(Iterable<QueryExecution> queries) {
if (!enabled) {
return;
}
boolean outOfMemory = isClusterOutOfMemory();
if (!outOfMemory) {
lastTimeNotOutOfMemory = System.nanoTime();
}
boolean queryKilled = false;
long totalBytes = 0;
for (QueryExecution query : queries) {
long bytes = query.getTotalMemoryReservation();
DataSize sessionMaxQueryMemory = getQueryMaxMemory(query.getSession());
long queryMemoryLimit = Math.min(maxQueryMemory.toBytes(), sessionMaxQueryMemory.toBytes());
totalBytes += bytes;
if (resourceOvercommit(query.getSession()) && outOfMemory) {
// If a query has requested resource overcommit, only kill it if the cluster has run out of memory
DataSize memory = succinctBytes(bytes);
query.fail(new PrestoException(CLUSTER_OUT_OF_MEMORY, format("The cluster is out of memory and %s=true, so this query was killed. It was using %s of memory", RESOURCE_OVERCOMMIT, memory)));
queryKilled = true;
}
if (!resourceOvercommit(query.getSession()) && bytes > queryMemoryLimit) {
DataSize maxMemory = succinctBytes(queryMemoryLimit);
query.fail(exceededGlobalLimit(maxMemory));
queryKilled = true;
}
}
clusterMemoryUsageBytes.set(totalBytes);
if (killOnOutOfMemory) {
boolean shouldKillQuery = nanosSince(lastTimeNotOutOfMemory).compareTo(killOnOutOfMemoryDelay) > 0 && outOfMemory;
boolean lastKilledQueryIsGone = (lastKilledQuery == null);
if (!lastKilledQueryIsGone) {
ClusterMemoryPool generalPool = pools.get(GENERAL_POOL);
if (generalPool != null) {
lastKilledQueryIsGone = generalPool.getQueryMemoryReservations().containsKey(lastKilledQuery);
}
}
if (shouldKillQuery && lastKilledQueryIsGone && !queryKilled) {
// Kill the biggest query in the general pool
QueryExecution biggestQuery = null;
long maxMemory = -1;
for (QueryExecution query : queries) {
long bytesUsed = query.getTotalMemoryReservation();
if (bytesUsed > maxMemory && query.getMemoryPool().getId().equals(GENERAL_POOL)) {
biggestQuery = query;
maxMemory = bytesUsed;
}
}
if (biggestQuery != null) {
biggestQuery.fail(new PrestoException(CLUSTER_OUT_OF_MEMORY, "The cluster is out of memory, and your query was killed. Please try again in a few minutes."));
queriesKilledDueToOutOfMemory.incrementAndGet();
lastKilledQuery = biggestQuery.getQueryId();
}
}
}
Map<MemoryPoolId, Integer> countByPool = new HashMap<>();
for (QueryExecution query : queries) {
MemoryPoolId id = query.getMemoryPool().getId();
countByPool.put(id, countByPool.getOrDefault(id, 0) + 1);
}
updatePools(countByPool);
updateNodes(updateAssignments(queries));
// check if CPU usage is over limit
for (QueryExecution query : queries) {
Duration cpuTime = query.getTotalCpuTime();
Duration sessionLimit = getQueryMaxCpuTime(query.getSession());
Duration limit = maxQueryCpuTime.compareTo(sessionLimit) < 0 ? maxQueryCpuTime : sessionLimit;
if (cpuTime.compareTo(limit) > 0) {
query.fail(new ExceededCpuLimitException(limit));
}
}
}
use of com.facebook.presto.spi.PrestoException in project presto by prestodb.
the class SqlQueryManager method failAbandonedQueries.
public void failAbandonedQueries() {
for (QueryExecution queryExecution : queries.values()) {
QueryInfo queryInfo = queryExecution.getQueryInfo();
if (queryInfo.getState().isDone()) {
continue;
}
if (isAbandoned(queryInfo)) {
log.info("Failing abandoned query %s", queryExecution.getQueryId());
queryExecution.fail(new PrestoException(ABANDONED_QUERY, format("Query %s has not been accessed since %s: currentTime %s", queryInfo.getQueryId(), queryInfo.getQueryStats().getLastHeartbeat(), DateTime.now())));
}
}
}
use of com.facebook.presto.spi.PrestoException in project presto by prestodb.
the class SqlQueryQueueManager method submit.
@Override
public void submit(Statement statement, QueryExecution queryExecution, Executor executor) {
List<QueryQueue> queues;
try {
queues = selectQueues(queryExecution.getSession(), executor);
} catch (PrestoException e) {
queryExecution.fail(e);
return;
}
for (QueryQueue queue : queues) {
if (!queue.reserve(queryExecution)) {
// Reject query if we couldn't acquire a permit to enter the queue.
// The permits will be released when this query fails.
queryExecution.fail(new PrestoException(QUERY_QUEUE_FULL, "Too many queued queries"));
return;
}
}
queues.get(0).enqueue(createQueuedExecution(queryExecution, queues.subList(1, queues.size()), executor));
}
Aggregations