Search in sources :

Example 1 with OSharedResource

use of com.orientechnologies.common.concur.resource.OSharedResource 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

OSharedResource (com.orientechnologies.common.concur.resource.OSharedResource)1 OIdentifiable (com.orientechnologies.orient.core.db.record.OIdentifiable)1 OCommandExecutionException (com.orientechnologies.orient.core.exception.OCommandExecutionException)1 OType (com.orientechnologies.orient.core.metadata.schema.OType)1 ODocument (com.orientechnologies.orient.core.record.impl.ODocument)1