Search in sources :

Example 1 with OCommandExecutionException

use of com.orientechnologies.orient.core.exception.OCommandExecutionException in project orientdb by orientechnologies.

the class OMatchStatement method expandCartesianProduct.

private boolean expandCartesianProduct(Pattern pattern, MatchContext matchContext, Map<String, String> aliasClasses, Map<String, OWhereClause> aliasFilters, OCommandContext iCommandContext, OSQLAsynchQuery<ODocument> request) {
    for (String alias : pattern.aliasToNode.keySet()) {
        if (!matchContext.matched.containsKey(alias)) {
            String target = aliasClasses.get(alias);
            if (target == null) {
                throw new OCommandExecutionException("Cannot execute MATCH statement on alias " + alias + ": class not defined");
            }
            Iterable<OIdentifiable> values = fetchAliasCandidates(alias, aliasFilters, iCommandContext, aliasClasses);
            for (OIdentifiable id : values) {
                MatchContext childContext = matchContext.copy(alias, id);
                if (allNodesCalculated(childContext, pattern)) {
                    // false if limit reached
                    boolean added = addResult(childContext, request, iCommandContext);
                    if (!added) {
                        return false;
                    }
                } else {
                    // false if limit reached
                    boolean added = expandCartesianProduct(pattern, childContext, aliasClasses, aliasFilters, iCommandContext, request);
                    if (!added) {
                        return false;
                    }
                }
            }
            break;
        }
    }
    return true;
}
Also used : OCommandExecutionException(com.orientechnologies.orient.core.exception.OCommandExecutionException) OIdentifiable(com.orientechnologies.orient.core.db.record.OIdentifiable)

Example 2 with OCommandExecutionException

use of com.orientechnologies.orient.core.exception.OCommandExecutionException in project orientdb by orientechnologies.

the class OMatchStatement method estimateRootEntries.

private Map<String, Long> estimateRootEntries(Map<String, String> aliasClasses, Map<String, OWhereClause> aliasFilters, OCommandContext ctx) {
    Set<String> allAliases = new LinkedHashSet<String>();
    allAliases.addAll(aliasClasses.keySet());
    allAliases.addAll(aliasFilters.keySet());
    OSchema schema = getDatabase().getMetadata().getSchema();
    Map<String, Long> result = new LinkedHashMap<String, Long>();
    for (String alias : allAliases) {
        if (this.pattern.aliasToNode.get(alias).isOptionalNode()) {
            continue;
        }
        String className = aliasClasses.get(alias);
        if (className == null) {
            continue;
        }
        if (!schema.existsClass(className)) {
            throw new OCommandExecutionException("class not defined: " + className);
        }
        OClass oClass = schema.getClass(className);
        long upperBound;
        OWhereClause filter = aliasFilters.get(alias);
        if (filter != null) {
            List<String> aliasesOnPattern = filter.baseExpression.getMatchPatternInvolvedAliases();
            if (aliasesOnPattern != null && aliasesOnPattern.size() > 0) {
                //skip root nodes that have a condition on $matched, because they have to be calculated as downstream
                continue;
            }
            upperBound = filter.estimate(oClass, this.threshold, ctx);
        } else {
            upperBound = oClass.count();
        }
        result.put(alias, upperBound);
    }
    return result;
}
Also used : OSchema(com.orientechnologies.orient.core.metadata.schema.OSchema) OClass(com.orientechnologies.orient.core.metadata.schema.OClass) OCommandExecutionException(com.orientechnologies.orient.core.exception.OCommandExecutionException)

Example 3 with OCommandExecutionException

use of com.orientechnologies.orient.core.exception.OCommandExecutionException in project orientdb by orientechnologies.

the class OCommandExecutorSQLSelect method applyExpand.

/**
 * Extract the content of collections and/or links and put it as result
 */
private void applyExpand() {
    if (expandTarget == null) {
        return;
    }
    final long startExpand = System.currentTimeMillis();
    try {
        if (tempResult == null) {
            tempResult = new ArrayList<OIdentifiable>();
            if (expandTarget instanceof OSQLFilterItemVariable) {
                Object r = ((OSQLFilterItemVariable) expandTarget).getValue(null, null, context);
                if (r != null) {
                    if (r instanceof OIdentifiable) {
                        ((Collection<OIdentifiable>) tempResult).add((OIdentifiable) r);
                    } else if (r instanceof Iterator || OMultiValue.isMultiValue(r)) {
                        for (Object o : OMultiValue.getMultiValueIterable(r)) {
                            ((Collection<OIdentifiable>) tempResult).add((OIdentifiable) o);
                        }
                    }
                }
            } else if (expandTarget instanceof OSQLFunctionRuntime && !hasFieldItemParams((OSQLFunctionRuntime) expandTarget)) {
                if (((OSQLFunctionRuntime) expandTarget).aggregateResults()) {
                    throw new OCommandExecutionException("Unsupported operation: aggregate function in expand(" + expandTarget + ")");
                } else {
                    Object r = ((OSQLFunctionRuntime) expandTarget).execute(null, null, null, context);
                    if (r instanceof OIdentifiable) {
                        ((Collection<OIdentifiable>) tempResult).add((OIdentifiable) r);
                    } else if (r instanceof Iterator || OMultiValue.isMultiValue(r)) {
                        int i = 0;
                        for (Object o : OMultiValue.getMultiValueIterable(r)) {
                            if ((++i) % 100 == 0 && !checkInterruption()) {
                                return;
                            }
                            ((Collection<OIdentifiable>) tempResult).add((OIdentifiable) o);
                        }
                    }
                }
            }
        } else {
            if (tempResult == null) {
                tempResult = new ArrayList<OIdentifiable>();
            }
            final OMultiCollectionIterator<OIdentifiable> finalResult = new OMultiCollectionIterator<OIdentifiable>();
            if (orderedFields == null || orderedFields.size() == 0) {
                // expand is applied before sorting, so limiting the result set here would give wrong results
                int iteratorLimit = 0;
                if (limit < 0) {
                    iteratorLimit = -1;
                } else {
                    iteratorLimit += limit;
                }
                finalResult.setLimit(iteratorLimit);
                finalResult.setSkip(skip);
            }
            for (OIdentifiable id : tempResult) {
                if (!checkInterruption()) {
                    return;
                }
                final Object fieldValue;
                if (expandTarget instanceof OSQLFilterItem) {
                    fieldValue = ((OSQLFilterItem) expandTarget).getValue(id.getRecord(), null, context);
                } else if (expandTarget instanceof OSQLFunctionRuntime) {
                    fieldValue = ((OSQLFunctionRuntime) expandTarget).getResult();
                } else {
                    fieldValue = expandTarget.toString();
                }
                if (fieldValue != null) {
                    if (fieldValue instanceof ODocument) {
                        ArrayList<ODocument> partial = new ArrayList<ODocument>();
                        partial.add((ODocument) fieldValue);
                        finalResult.add(partial);
                    } else if (fieldValue instanceof Collection<?> || fieldValue.getClass().isArray() || fieldValue instanceof Iterator<?> || fieldValue instanceof OIdentifiable || fieldValue instanceof ORidBag) {
                        finalResult.add(fieldValue);
                    } else if (fieldValue instanceof Map<?, ?>) {
                        finalResult.add(((Map<?, OIdentifiable>) fieldValue).values());
                    }
                }
            }
            tempResult = finalResult;
        }
    } finally {
        context.setVariable("expandElapsed", (System.currentTimeMillis() - startExpand));
    }
}
Also used : OSQLFunctionRuntime(com.orientechnologies.orient.core.sql.functions.OSQLFunctionRuntime) ORidBag(com.orientechnologies.orient.core.db.record.ridbag.ORidBag) OIdentifiable(com.orientechnologies.orient.core.db.record.OIdentifiable) OMultiCollectionIterator(com.orientechnologies.common.collection.OMultiCollectionIterator) OIdentifiableIterator(com.orientechnologies.orient.core.iterator.OIdentifiableIterator) OMultiCollectionIterator(com.orientechnologies.common.collection.OMultiCollectionIterator) OSortedMultiIterator(com.orientechnologies.common.collection.OSortedMultiIterator) OCommandExecutionException(com.orientechnologies.orient.core.exception.OCommandExecutionException) ConcurrentHashMap(java.util.concurrent.ConcurrentHashMap) ODocument(com.orientechnologies.orient.core.record.impl.ODocument)

Example 4 with OCommandExecutionException

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.currentThread().interrupt();
            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) {
                Thread.currentThread().interrupt();
                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;
}
Also used : OCommandContext(com.orientechnologies.orient.core.command.OCommandContext) ODatabaseDocumentInternal(com.orientechnologies.orient.core.db.ODatabaseDocumentInternal) OException(com.orientechnologies.common.exception.OException) OQueryParsingException(com.orientechnologies.orient.core.exception.OQueryParsingException) OCommandExecutionException(com.orientechnologies.orient.core.exception.OCommandExecutionException) ExecutionException(java.util.concurrent.ExecutionException) AtomicInteger(java.util.concurrent.atomic.AtomicInteger) Future(java.util.concurrent.Future) OCommandExecutionException(com.orientechnologies.orient.core.exception.OCommandExecutionException) OCommandExecutionException(com.orientechnologies.orient.core.exception.OCommandExecutionException) ExecutionException(java.util.concurrent.ExecutionException)

Example 5 with OCommandExecutionException

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();
            }
        }
    }
}
Also used : OIdentifiable(com.orientechnologies.orient.core.db.record.OIdentifiable) OCommandExecutionException(com.orientechnologies.orient.core.exception.OCommandExecutionException) ODocument(com.orientechnologies.orient.core.record.impl.ODocument) OType(com.orientechnologies.orient.core.metadata.schema.OType) OSharedResource(com.orientechnologies.common.concur.resource.OSharedResource)

Aggregations

OCommandExecutionException (com.orientechnologies.orient.core.exception.OCommandExecutionException)85 ODocument (com.orientechnologies.orient.core.record.impl.ODocument)19 OIdentifiable (com.orientechnologies.orient.core.db.record.OIdentifiable)18 ODatabaseDocumentInternal (com.orientechnologies.orient.core.db.ODatabaseDocumentInternal)17 ODatabaseDocument (com.orientechnologies.orient.core.db.document.ODatabaseDocument)15 OClass (com.orientechnologies.orient.core.metadata.schema.OClass)15 OException (com.orientechnologies.common.exception.OException)9 OCommandSQL (com.orientechnologies.orient.core.sql.OCommandSQL)9 OSQLSynchQuery (com.orientechnologies.orient.core.sql.query.OSQLSynchQuery)6 ORID (com.orientechnologies.orient.core.id.ORID)5 OSchema (com.orientechnologies.orient.core.metadata.schema.OSchema)5 OType (com.orientechnologies.orient.core.metadata.schema.OType)5 ORecord (com.orientechnologies.orient.core.record.ORecord)5 IOException (java.io.IOException)5 OQueryParsingException (com.orientechnologies.orient.core.exception.OQueryParsingException)4 OHazelcastPlugin (com.orientechnologies.orient.server.hazelcast.OHazelcastPlugin)4 OrientVertex (com.tinkerpop.blueprints.impls.orient.OrientVertex)4 ArrayList (java.util.ArrayList)4 OCommandRequestText (com.orientechnologies.orient.core.command.OCommandRequestText)3 ORecordId (com.orientechnologies.orient.core.id.ORecordId)3