use of com.orientechnologies.orient.core.exception.OCommandExecutionException in project orientdb by orientechnologies.
the class OCommandExecutorSQLSelect method execParallelWithPool.
private boolean execParallelWithPool(final ORecordIteratorClusters iTarget, final ODatabaseDocumentTx db) {
final int[] clusterIds = iTarget.getClusterIds();
// CREATE ONE THREAD PER CLUSTER
final int jobNumbers = clusterIds.length;
final List<Future<?>> jobs = new ArrayList<Future<?>>();
OLogManager.instance().debug(this, "Executing parallel query with strategy executors. clusterIds=%d, jobs=%d", clusterIds.length, jobNumbers);
final boolean[] results = new boolean[jobNumbers];
final OCommandContext[] contexts = new OCommandContext[jobNumbers];
final RuntimeException[] exceptions = new RuntimeException[jobNumbers];
parallelRunning = true;
final AtomicInteger runningJobs = new AtomicInteger(jobNumbers);
for (int i = 0; i < jobNumbers; ++i) {
final int current = i;
final Runnable job = new Runnable() {
@Override
public void run() {
try {
ODatabaseDocumentInternal localDatabase = null;
try {
exceptions[current] = null;
results[current] = true;
final OCommandContext threadContext = context.copy();
contexts[current] = threadContext;
localDatabase = db.copy();
localDatabase.activateOnCurrentThread();
// CREATE A SNAPSHOT TO AVOID DEADLOCKS
db.getMetadata().getSchema().makeSnapshot();
scanClusterWithIterator(localDatabase, threadContext, clusterIds[current], current, results);
} catch (RuntimeException t) {
exceptions[current] = t;
} finally {
runningJobs.decrementAndGet();
resultQueue.offer(PARALLEL_END_EXECUTION_THREAD);
if (localDatabase != null)
localDatabase.close();
}
} catch (Exception e) {
if (exceptions[current] == null) {
exceptions[current] = new RuntimeException(e);
}
e.printStackTrace();
}
}
};
jobs.add(Orient.instance().submit(job));
}
final int maxQueueSize = OGlobalConfiguration.QUERY_PARALLEL_RESULT_QUEUE_SIZE.getValueAsInteger() - 1;
boolean cancelQuery = false;
boolean tipProvided = false;
while (runningJobs.get() > 0 || !resultQueue.isEmpty()) {
try {
final AsyncResult result = resultQueue.take();
final int qSize = resultQueue.size();
if (!tipProvided && qSize >= maxQueueSize) {
OLogManager.instance().debug(this, "Parallel query '%s' has result queue full (size=%d), this could reduce concurrency level. Consider increasing queue size with setting: %s=<size>", parserText, maxQueueSize + 1, OGlobalConfiguration.QUERY_PARALLEL_RESULT_QUEUE_SIZE.getKey());
tipProvided = true;
}
if (OExecutionThreadLocal.isInterruptCurrentOperation())
throw new InterruptedException("Operation has been interrupted");
if (result != PARALLEL_END_EXECUTION_THREAD) {
if (!handleResult(result.record, result.context)) {
// STOP EXECUTORS
parallelRunning = false;
break;
}
}
} catch (InterruptedException e) {
Thread.interrupted();
cancelQuery = true;
break;
}
}
parallelRunning = false;
if (cancelQuery) {
// CANCEL ALL THE RUNNING JOBS
for (int i = 0; i < jobs.size(); ++i) {
jobs.get(i).cancel(true);
}
} else {
// JOIN ALL THE JOBS
for (int i = 0; i < jobs.size(); ++i) {
try {
jobs.get(i).get();
context.merge(contexts[i]);
} catch (InterruptedException e) {
break;
} catch (final ExecutionException e) {
OLogManager.instance().error(this, "Error on executing parallel query", e);
throw OException.wrapException(new OCommandExecutionException("Error on executing parallel query"), e);
}
}
}
// CHECK FOR ANY EXCEPTION
for (int i = 0; i < jobNumbers; ++i) if (exceptions[i] != null)
throw exceptions[i];
for (int i = 0; i < jobNumbers; ++i) {
if (!results[i])
return false;
}
return true;
}
use of com.orientechnologies.orient.core.exception.OCommandExecutionException in project orientdb by orientechnologies.
the class OCommandExecutorSQLSelect method searchInIndex.
private void searchInIndex() {
final OIndex<Object> index = (OIndex<Object>) getDatabase().getMetadata().getIndexManager().getIndex(parsedTarget.getTargetIndex());
if (index == null) {
throw new OCommandExecutionException("Target index '" + parsedTarget.getTargetIndex() + "' not found");
}
boolean ascOrder = true;
if (!orderedFields.isEmpty()) {
if (orderedFields.size() != 1) {
throw new OCommandExecutionException("Index can be ordered only by key field");
}
final String fieldName = orderedFields.get(0).getKey();
if (!fieldName.equalsIgnoreCase("key")) {
throw new OCommandExecutionException("Index can be ordered only by key field");
}
final String order = orderedFields.get(0).getValue();
ascOrder = order.equalsIgnoreCase(KEYWORD_ASC);
}
// nothing was added yet, so index definition for manual index was not calculated
if (index.getDefinition() == null) {
return;
}
if (compiledFilter != null && compiledFilter.getRootCondition() != null) {
if (!"KEY".equalsIgnoreCase(compiledFilter.getRootCondition().getLeft().toString())) {
throw new OCommandExecutionException("'Key' field is required for queries against indexes");
}
final OQueryOperator indexOperator = compiledFilter.getRootCondition().getOperator();
if (indexOperator instanceof OQueryOperatorBetween) {
final Object[] values = (Object[]) compiledFilter.getRootCondition().getRight();
final OIndexCursor cursor = index.iterateEntriesBetween(getIndexKey(index.getDefinition(), values[0], context), true, getIndexKey(index.getDefinition(), values[2], context), true, ascOrder);
fetchEntriesFromIndexCursor(cursor);
} else if (indexOperator instanceof OQueryOperatorMajor) {
final Object value = compiledFilter.getRootCondition().getRight();
final OIndexCursor cursor = index.iterateEntriesMajor(getIndexKey(index.getDefinition(), value, context), false, ascOrder);
fetchEntriesFromIndexCursor(cursor);
} else if (indexOperator instanceof OQueryOperatorMajorEquals) {
final Object value = compiledFilter.getRootCondition().getRight();
final OIndexCursor cursor = index.iterateEntriesMajor(getIndexKey(index.getDefinition(), value, context), true, ascOrder);
fetchEntriesFromIndexCursor(cursor);
} else if (indexOperator instanceof OQueryOperatorMinor) {
final Object value = compiledFilter.getRootCondition().getRight();
OIndexCursor cursor = index.iterateEntriesMinor(getIndexKey(index.getDefinition(), value, context), false, ascOrder);
fetchEntriesFromIndexCursor(cursor);
} else if (indexOperator instanceof OQueryOperatorMinorEquals) {
final Object value = compiledFilter.getRootCondition().getRight();
OIndexCursor cursor = index.iterateEntriesMinor(getIndexKey(index.getDefinition(), value, context), true, ascOrder);
fetchEntriesFromIndexCursor(cursor);
} else if (indexOperator instanceof OQueryOperatorIn) {
final List<Object> origValues = (List<Object>) compiledFilter.getRootCondition().getRight();
final List<Object> values = new ArrayList<Object>(origValues.size());
for (Object val : origValues) {
if (index.getDefinition() instanceof OCompositeIndexDefinition) {
throw new OCommandExecutionException("Operator IN not supported yet.");
}
val = getIndexKey(index.getDefinition(), val, context);
values.add(val);
}
OIndexCursor cursor = index.iterateEntries(values, true);
fetchEntriesFromIndexCursor(cursor);
} else {
final Object right = compiledFilter.getRootCondition().getRight();
Object keyValue = getIndexKey(index.getDefinition(), right, context);
if (keyValue == null) {
return;
}
final Object res;
if (index.getDefinition().getParamCount() == 1) {
// CONVERT BEFORE SEARCH IF NEEDED
final OType type = index.getDefinition().getTypes()[0];
keyValue = OType.convert(keyValue, type.getDefaultJavaType());
res = index.get(keyValue);
} else {
final Object secondKey = getIndexKey(index.getDefinition(), right, context);
if (keyValue instanceof OCompositeKey && secondKey instanceof OCompositeKey && ((OCompositeKey) keyValue).getKeys().size() == index.getDefinition().getParamCount() && ((OCompositeKey) secondKey).getKeys().size() == index.getDefinition().getParamCount()) {
res = index.get(keyValue);
} else {
OIndexCursor cursor = index.iterateEntriesBetween(keyValue, true, secondKey, true, true);
fetchEntriesFromIndexCursor(cursor);
return;
}
}
if (res != null) {
if (res instanceof Collection<?>) {
// MULTI VALUES INDEX
for (final OIdentifiable r : (Collection<OIdentifiable>) res) {
final ODocument record = createIndexEntryAsDocument(keyValue, r.getIdentity());
applyGroupBy(record, context);
if (!handleResult(record, context)) // LIMIT REACHED
{
break;
}
}
} else {
// SINGLE VALUE INDEX
final ODocument record = createIndexEntryAsDocument(keyValue, ((OIdentifiable) res).getIdentity());
applyGroupBy(record, context);
handleResult(record, context);
}
}
}
} else {
if (isIndexSizeQuery()) {
getProjectionGroup(null, context).applyValue(projections.keySet().iterator().next(), index.getSize());
return;
}
if (isIndexKeySizeQuery()) {
getProjectionGroup(null, context).applyValue(projections.keySet().iterator().next(), index.getKeySize());
return;
}
final OIndexInternal<?> indexInternal = index.getInternal();
if (indexInternal instanceof OSharedResource) {
((OSharedResource) indexInternal).acquireExclusiveLock();
}
try {
// ADD ALL THE ITEMS AS RESULT
if (ascOrder) {
final OIndexCursor cursor = index.cursor();
fetchEntriesFromIndexCursor(cursor);
} else {
final OIndexCursor cursor = index.descCursor();
fetchEntriesFromIndexCursor(cursor);
}
} finally {
if (indexInternal instanceof OSharedResource) {
((OSharedResource) indexInternal).releaseExclusiveLock();
}
}
}
}
use of com.orientechnologies.orient.core.exception.OCommandExecutionException in project orientdb by orientechnologies.
the class OCommandExecutorSQLGrant method execute.
/**
* Execute the GRANT.
*/
public Object execute(final Map<Object, Object> iArgs) {
if (role == null)
throw new OCommandExecutionException("Cannot execute the command because it has not been parsed yet");
role.grant(resource, privilege);
role.save();
return role;
}
use of com.orientechnologies.orient.core.exception.OCommandExecutionException in project orientdb by orientechnologies.
the class OCommandExecutorSQLInsert method parse.
@SuppressWarnings("unchecked")
public OCommandExecutorSQLInsert parse(final OCommandRequest iRequest) {
final OCommandRequestText textRequest = (OCommandRequestText) iRequest;
String queryText = textRequest.getText();
String originalQuery = queryText;
try {
// System.out.println("NEW PARSER FROM: " + queryText);
queryText = preParse(queryText, iRequest);
// System.out.println("NEW PARSER TO: " + queryText);
textRequest.setText(queryText);
final ODatabaseDocument database = getDatabase();
init((OCommandRequestText) iRequest);
className = null;
newRecords = null;
content = null;
if (parserTextUpperCase.endsWith(KEYWORD_UNSAFE)) {
unsafe = true;
parserText = parserText.substring(0, parserText.length() - KEYWORD_UNSAFE.length() - 1);
parserTextUpperCase = parserTextUpperCase.substring(0, parserTextUpperCase.length() - KEYWORD_UNSAFE.length() - 1);
}
parserRequiredKeyword("INSERT");
parserRequiredKeyword("INTO");
String subjectName = parserRequiredWord(true, "Invalid subject name. Expected cluster, class or index");
if (subjectName.startsWith(OCommandExecutorSQLAbstract.CLUSTER_PREFIX)) {
// CLUSTER
clusterName = subjectName.substring(OCommandExecutorSQLAbstract.CLUSTER_PREFIX.length());
try {
int clusterId = Integer.parseInt(clusterName);
clusterName = database.getClusterNameById(clusterId);
} catch (Exception e) {
//not an integer
}
} else if (subjectName.startsWith(OCommandExecutorSQLAbstract.INDEX_PREFIX))
// INDEX
indexName = subjectName.substring(OCommandExecutorSQLAbstract.INDEX_PREFIX.length());
else {
// CLASS
if (subjectName.startsWith(OCommandExecutorSQLAbstract.CLASS_PREFIX))
subjectName = subjectName.substring(OCommandExecutorSQLAbstract.CLASS_PREFIX.length());
final OClass cls = ((OMetadataInternal) database.getMetadata()).getImmutableSchemaSnapshot().getClass(subjectName);
if (cls == null)
throwParsingException("Class " + subjectName + " not found in database");
if (!unsafe && cls.isSubClassOf("E"))
// FOUND EDGE
throw new OCommandExecutionException("'INSERT' command cannot create Edges. Use 'CREATE EDGE' command instead, or apply the 'UNSAFE' keyword to force it");
className = cls.getName();
clazz = database.getMetadata().getSchema().getClass(className);
if (clazz == null)
throw new OQueryParsingException("Class '" + className + "' was not found");
}
if (clusterName != null && className == null) {
ODatabaseDocumentInternal db = getDatabase();
OCluster cluster = db.getStorage().getClusterByName(clusterName);
if (cluster != null) {
clazz = db.getMetadata().getSchema().getClassByClusterId(cluster.getId());
if (clazz != null) {
className = clazz.getName();
}
}
}
parserSkipWhiteSpaces();
if (parserIsEnded())
throwSyntaxErrorException("Set of fields is missed. Example: (name, surname) or SET name = 'Bill'");
final String temp = parseOptionalWord(true);
if (parserGetLastWord().equalsIgnoreCase("cluster")) {
clusterName = parserRequiredWord(false);
parserSkipWhiteSpaces();
if (parserIsEnded())
throwSyntaxErrorException("Set of fields is missed. Example: (name, surname) or SET name = 'Bill'");
} else
parserGoBack();
newRecords = new ArrayList<Map<String, Object>>();
Boolean sourceClauseProcessed = false;
if (parserGetCurrentChar() == '(') {
parseValues();
parserNextWord(true, " \r\n");
sourceClauseProcessed = true;
} else {
parserNextWord(true, " ,\r\n");
if (parserGetLastWord().equals(KEYWORD_CONTENT)) {
newRecords = null;
parseContent();
sourceClauseProcessed = true;
} else if (parserGetLastWord().equals(KEYWORD_SET)) {
final List<OPair<String, Object>> fields = new ArrayList<OPair<String, Object>>();
parseSetFields(clazz, fields);
newRecords.add(OPair.convertToMap(fields));
sourceClauseProcessed = true;
}
}
if (sourceClauseProcessed)
parserNextWord(true, " \r\n");
// it has to be processed before KEYWORD_FROM in order to not be taken as part of SELECT
if (parserGetLastWord().equals(KEYWORD_RETURN)) {
parseReturn(!sourceClauseProcessed);
parserNextWord(true, " \r\n");
}
if (!sourceClauseProcessed) {
if (parserGetLastWord().equals(KEYWORD_FROM)) {
newRecords = null;
subQuery = new OSQLAsynchQuery<OIdentifiable>(parserText.substring(parserGetCurrentPosition()), this);
}
}
} finally {
textRequest.setText(originalQuery);
}
return this;
}
use of com.orientechnologies.orient.core.exception.OCommandExecutionException in project orientdb by orientechnologies.
the class OCommandExecutorSQLInsert method execute.
/**
* Execute the INSERT and return the ODocument object created.
*/
public Object execute(final Map<Object, Object> iArgs) {
if (newRecords == null && content == null && subQuery == null)
throw new OCommandExecutionException("Cannot execute the command because it has not been parsed yet");
final OCommandParameters commandParameters = new OCommandParameters(iArgs);
if (indexName != null) {
if (newRecords == null)
throw new OCommandExecutionException("No key/value found");
final OIndex<?> index = getDatabase().getMetadata().getIndexManager().getIndex(indexName);
if (index == null)
throw new OCommandExecutionException("Target index '" + indexName + "' not found");
// BIND VALUES
Map<String, Object> result = new HashMap<String, Object>();
for (Map<String, Object> candidate : newRecords) {
Object indexKey = getIndexKeyValue(commandParameters, candidate);
OIdentifiable indexValue = getIndexValue(commandParameters, candidate);
index.put(indexKey, indexValue);
result.put(KEYWORD_KEY, indexKey);
result.put(KEYWORD_RID, indexValue);
}
// RETURN LAST ENTRY
return prepareReturnItem(new ODocument(result));
} else {
// CREATE NEW DOCUMENTS
final List<ODocument> docs = new ArrayList<ODocument>();
if (newRecords != null) {
for (Map<String, Object> candidate : newRecords) {
final ODocument doc = className != null ? new ODocument(className) : new ODocument();
OSQLHelper.bindParameters(doc, candidate, commandParameters, context);
saveRecord(doc);
docs.add(doc);
}
if (docs.size() == 1)
return prepareReturnItem(docs.get(0));
else
return prepareReturnResult(docs);
} else if (content != null) {
final ODocument doc = className != null ? new ODocument(className) : new ODocument();
doc.merge(content, true, false);
saveRecord(doc);
return prepareReturnItem(doc);
} else if (subQuery != null) {
subQuery.execute();
if (queryResult != null)
return prepareReturnResult(queryResult);
return saved.longValue();
}
}
return null;
}
Aggregations