use of com.hazelcast.sql.impl.QueryException in project hazelcast by hazelcast.
the class QueryClientStateRegistry method update.
public void update(Set<UUID> activeClientIds) {
long currentTimeNano = System.nanoTime();
List<QueryClientState> victims = new ArrayList<>();
for (QueryClientState clientCursor : clientCursors.values()) {
// Close cursors that were opened by disconnected clients.
if (!activeClientIds.contains(clientCursor.getClientId())) {
victims.add(clientCursor);
}
// condition between the query cancellation on a client and the query completion on a server.
if (clientCursor.isClosed() && clientCursor.getCreatedAtNano() + closedCursorCleanupTimeoutNs < currentTimeNano) {
victims.add(clientCursor);
}
}
for (QueryClientState victim : victims) {
QueryException error = QueryException.clientMemberConnection(victim.getClientId());
AbstractSqlResult result = victim.getSqlResult();
if (result != null) {
result.close(error);
}
deleteClientCursor(victim.getQueryId());
}
}
use of com.hazelcast.sql.impl.QueryException in project hazelcast by hazelcast.
the class QueryClientStateRegistry method registerAndFetch.
public SqlPage registerAndFetch(UUID clientId, AbstractSqlResult result, int cursorBufferSize, InternalSerializationService serializationService) {
QueryId queryId = result.getQueryId();
QueryClientState clientCursor = new QueryClientState(clientId, queryId, result, false);
boolean delete = false;
try {
// Register the cursor.
QueryClientState previousClientCursor = clientCursors.putIfAbsent(queryId, clientCursor);
// Check if the cursor is already closed.
if (previousClientCursor != null) {
assert previousClientCursor.isClosed();
delete = true;
QueryException error = QueryException.cancelledByUser();
result.close(error);
throw error;
}
// Fetch the next page.
SqlPage page = fetchInternal(clientCursor, cursorBufferSize, serializationService, result.isInfiniteRows());
delete = page.isLast();
return page;
} catch (Exception e) {
delete = true;
throw e;
} finally {
if (delete) {
deleteClientCursor(queryId);
}
}
}
use of com.hazelcast.sql.impl.QueryException in project hazelcast by hazelcast.
the class IndexFilterValueTest method testNonComparable.
@Test
public void testNonComparable() {
ExpressionEvalContext evalContext = createExpressionEvalContext();
IndexFilterValue value = new IndexFilterValue(singletonList(constant(new Object(), QueryDataType.OBJECT)), singletonList(true));
try {
value.getValue(evalContext);
fail("Must fail");
} catch (QueryException e) {
assertEquals(SqlErrorCode.DATA_EXCEPTION, e.getCode());
assertTrue(e.getMessage().contains("Values used in index lookups must be Comparable"));
}
}
use of com.hazelcast.sql.impl.QueryException in project hazelcast by hazelcast.
the class HazelcastSqlToRelConverter method convertCall.
/**
* This method overcomes a bug in Apache Calcite that ignores previously resolved return types of the expression
* and instead attempts to infer them again using a different logic. Without this fix, we will get type resolution
* errors after a SQL-to-rel conversion.
* <p>
* The method relies on the fact that all operators use {@link HazelcastReturnTypeInference} as a top-level return type
* inference method.
* <ul>
* <li>When a call node is observed for the first time, get its return type and save it to a thread-local variable
* <li>Then delegate back to original converter code
* <li>When converter attempts to resolve the return type of a call, it will get the previously saved type from
* the thread-local variable
* </ul>
*/
private RexNode convertCall(SqlNode node, Blackboard blackboard) {
// for DEFAULT node, it will fail.
if (node.getKind() == SqlKind.DEFAULT) {
return null;
}
if (((SqlCall) node).getOperator() instanceof HazelcastJsonValueFunction) {
return convertJsonValueCall((SqlCall) node, blackboard);
}
if (callSet.add(node)) {
try {
RelDataType type = validator.getValidatedNodeType(node);
HazelcastReturnTypeInference.push(type);
try {
return blackboard.convertExpression(node);
} catch (RuntimeException e) {
// For some operators Calcite does reflective call to validate the AST
if (e.getCause() instanceof InvocationTargetException && e.getCause().getCause() instanceof QueryException) {
throw (QueryException) e.getCause().getCause();
} else {
throw e;
}
} finally {
HazelcastReturnTypeInference.pop();
}
} finally {
callSet.remove(node);
}
}
return null;
}
use of com.hazelcast.sql.impl.QueryException in project hazelcast by hazelcast.
the class QueryClientStateRegistry method fetchInternal.
private SqlPage fetchInternal(QueryClientState clientCursor, int cursorBufferSize, InternalSerializationService serializationService, boolean respondImmediately) {
List<SqlColumnMetadata> columns = clientCursor.getSqlResult().getRowMetadata().getColumns();
List<SqlColumnType> columnTypes = new ArrayList<>(columns.size());
for (SqlColumnMetadata column : columns) {
columnTypes.add(column.getType());
}
if (respondImmediately) {
return SqlPage.fromRows(columnTypes, Collections.emptyList(), false, serializationService);
}
ResultIterator<SqlRow> iterator = clientCursor.getIterator();
try {
List<SqlRow> rows = new ArrayList<>(cursorBufferSize);
boolean last = fetchPage(iterator, rows, cursorBufferSize);
return SqlPage.fromRows(columnTypes, rows, last, serializationService);
} catch (HazelcastSqlException e) {
// it happens, the cursor is already closed with the error, so we just re-throw.
throw e;
} catch (Exception e) {
// Any other exception indicates that something has happened outside of the internal query state. For example,
// we may fail to serialize a specific column value to Data. We have to close the cursor in this case.
AbstractSqlResult result = clientCursor.getSqlResult();
QueryException error = QueryException.error("Failed to prepare the SQL result for the client: " + e.getMessage(), e);
result.close(error);
throw error;
}
}
Aggregations