Search in sources :

Example 1 with OSQLQuery

use of com.orientechnologies.orient.core.sql.query.OSQLQuery in project orientdb by orientechnologies.

the class OSQLFilterCondition method evaluate.

public Object evaluate(final OIdentifiable iCurrentRecord, final ODocument iCurrentResult, final OCommandContext iContext) {
    boolean binaryEvaluation = operator != null && operator.isSupportingBinaryEvaluate() && iCurrentRecord != null && iCurrentRecord.getIdentity().isPersistent();
    if (left instanceof OSQLQuery<?>)
        // EXECUTE SUB QUERIES ONLY ONCE
        left = ((OSQLQuery<?>) left).setContext(iContext).execute();
    Object l = evaluate(iCurrentRecord, iCurrentResult, left, iContext, binaryEvaluation);
    if (operator == null || operator.canShortCircuit(l))
        return l;
    if (right instanceof OSQLQuery<?>)
        // EXECUTE SUB QUERIES ONLY ONCE
        right = ((OSQLQuery<?>) right).setContext(iContext).execute();
    Object r = evaluate(iCurrentRecord, iCurrentResult, right, iContext, binaryEvaluation);
    if (binaryEvaluation && l instanceof OBinaryField) {
        if (r != null && !(r instanceof OBinaryField)) {
            final OType type = OType.getTypeByValue(r);
            if (ORecordSerializerBinary.INSTANCE.getCurrentSerializer().getComparator().isBinaryComparable(type)) {
                final BytesContainer bytes = new BytesContainer();
                ORecordSerializerBinary.INSTANCE.getCurrentSerializer().serializeValue(bytes, r, type, null);
                bytes.offset = 0;
                final OCollate collate = r instanceof OSQLFilterItemField ? ((OSQLFilterItemField) r).getCollate(iCurrentRecord) : null;
                r = new OBinaryField(null, type, bytes, collate);
                if (!(right instanceof OSQLFilterItem || right instanceof OSQLFilterCondition))
                    // FIXED VALUE, REPLACE IT
                    right = r;
            }
        } else if (r instanceof OBinaryField)
            // GET THE COPY OR MT REASONS
            r = ((OBinaryField) r).copy();
    }
    if (binaryEvaluation && r instanceof OBinaryField) {
        if (l != null && !(l instanceof OBinaryField)) {
            final OType type = OType.getTypeByValue(l);
            if (ORecordSerializerBinary.INSTANCE.getCurrentSerializer().getComparator().isBinaryComparable(type)) {
                final BytesContainer bytes = new BytesContainer();
                ORecordSerializerBinary.INSTANCE.getCurrentSerializer().serializeValue(bytes, l, type, null);
                bytes.offset = 0;
                final OCollate collate = l instanceof OSQLFilterItemField ? ((OSQLFilterItemField) l).getCollate(iCurrentRecord) : null;
                l = new OBinaryField(null, type, bytes, collate);
                if (!(left instanceof OSQLFilterItem || left instanceof OSQLFilterCondition))
                    // FIXED VALUE, REPLACE IT
                    left = l;
            }
        } else if (l instanceof OBinaryField)
            // GET THE COPY OR MT REASONS
            l = ((OBinaryField) l).copy();
    }
    if (binaryEvaluation)
        binaryEvaluation = l instanceof OBinaryField && r instanceof OBinaryField;
    if (!binaryEvaluation) {
        // no collate for regular expressions, otherwise quotes will result in no match
        final OCollate collate = operator instanceof OQueryOperatorMatches ? null : getCollate(iCurrentRecord);
        final Object[] convertedValues = checkForConversion(iCurrentRecord, l, r, collate);
        if (convertedValues != null) {
            l = convertedValues[0];
            r = convertedValues[1];
        }
    }
    Object result;
    try {
        result = operator.evaluateRecord(iCurrentRecord, iCurrentResult, this, l, r, iContext);
    } catch (OCommandExecutionException e) {
        throw e;
    } catch (Exception e) {
        if (OLogManager.instance().isDebugEnabled())
            OLogManager.instance().debug(this, "Error on evaluating expression (%s)", e, toString());
        result = Boolean.FALSE;
    }
    return result;
}
Also used : OBinaryField(com.orientechnologies.orient.core.serialization.serializer.record.binary.OBinaryField) OType(com.orientechnologies.orient.core.metadata.schema.OType) OException(com.orientechnologies.common.exception.OException) ORecordNotFoundException(com.orientechnologies.orient.core.exception.ORecordNotFoundException) ParseException(java.text.ParseException) OCommandExecutionException(com.orientechnologies.orient.core.exception.OCommandExecutionException) OQueryParsingException(com.orientechnologies.orient.core.exception.OQueryParsingException) BytesContainer(com.orientechnologies.orient.core.serialization.serializer.record.binary.BytesContainer) OQueryOperatorMatches(com.orientechnologies.orient.core.sql.operator.OQueryOperatorMatches) OCommandExecutionException(com.orientechnologies.orient.core.exception.OCommandExecutionException) OCollate(com.orientechnologies.orient.core.collate.OCollate) OSQLQuery(com.orientechnologies.orient.core.sql.query.OSQLQuery)

Example 2 with OSQLQuery

use of com.orientechnologies.orient.core.sql.query.OSQLQuery in project orientdb by orientechnologies.

the class OCommandExecutorSQLSelect method getIndexCursors.

@SuppressWarnings("rawtypes")
private List<OIndexCursor> getIndexCursors(final OClass iSchemaClass) {
    final ODatabaseDocument database = getDatabase();
    // fetch all possible variants of subqueries that can be used in indexes.
    if (compiledFilter == null) {
        OIndexCursor cursor = tryGetOptimizedSortCursor(iSchemaClass);
        if (cursor == null) {
            return null;
        }
        List<OIndexCursor> result = new ArrayList<OIndexCursor>();
        result.add(cursor);
        return result;
    }
    // the main condition is a set of sub-conditions separated by OR operators
    final List<List<OIndexSearchResult>> conditionHierarchy = filterAnalyzer.analyzeMainCondition(compiledFilter.getRootCondition(), iSchemaClass, context);
    if (conditionHierarchy == null)
        return null;
    List<OIndexCursor> cursors = new ArrayList<OIndexCursor>();
    boolean indexIsUsedInOrderBy = false;
    List<IndexUsageLog> indexUseAttempts = new ArrayList<IndexUsageLog>();
    // try {
    OIndexSearchResult lastSearchResult = null;
    for (List<OIndexSearchResult> indexSearchResults : conditionHierarchy) {
        // go through all variants to choose which one can be used for index search.
        boolean indexUsed = false;
        for (final OIndexSearchResult searchResult : indexSearchResults) {
            lastSearchResult = searchResult;
            final List<OIndex<?>> involvedIndexes = filterAnalyzer.getInvolvedIndexes(iSchemaClass, searchResult);
            Collections.sort(involvedIndexes, new IndexComparator());
            // go through all possible index for given set of fields.
            for (final OIndex index : involvedIndexes) {
                final long indexRebuildVersion = index.getRebuildVersion();
                if (index.isRebuilding()) {
                    continue;
                }
                final OIndexDefinition indexDefinition = index.getDefinition();
                if (searchResult.containsNullValues && indexDefinition.isNullValuesIgnored()) {
                    continue;
                }
                final OQueryOperator operator = searchResult.lastOperator;
                // are equals.
                if (!OIndexSearchResult.isIndexEqualityOperator(operator)) {
                    final String lastFiled = searchResult.lastField.getItemName(searchResult.lastField.getItemCount() - 1);
                    final String relatedIndexField = indexDefinition.getFields().get(searchResult.fieldValuePairs.size());
                    if (!lastFiled.equals(relatedIndexField)) {
                        continue;
                    }
                }
                final int searchResultFieldsCount = searchResult.fields().size();
                final List<Object> keyParams = new ArrayList<Object>(searchResultFieldsCount);
                // We get only subset contained in processed sub query.
                for (final String fieldName : indexDefinition.getFields().subList(0, searchResultFieldsCount)) {
                    final Object fieldValue = searchResult.fieldValuePairs.get(fieldName);
                    if (fieldValue instanceof OSQLQuery<?>) {
                        return null;
                    }
                    if (fieldValue != null) {
                        keyParams.add(fieldValue);
                    } else {
                        if (searchResult.lastValue instanceof OSQLQuery<?>) {
                            return null;
                        }
                        keyParams.add(searchResult.lastValue);
                    }
                }
                metricRecorder.recordInvolvedIndexesMetric(index);
                OIndexCursor cursor;
                indexIsUsedInOrderBy = orderByOptimizer.canBeUsedByOrderBy(index, orderedFields) && !(index.getInternal() instanceof OChainedIndexProxy);
                try {
                    boolean ascSortOrder = !indexIsUsedInOrderBy || orderedFields.get(0).getValue().equals(KEYWORD_ASC);
                    if (indexIsUsedInOrderBy) {
                        fullySortedByIndex = expandTarget == null && indexDefinition.getFields().size() >= orderedFields.size() && conditionHierarchy.size() == 1;
                    }
                    context.setVariable("$limit", limit);
                    cursor = operator.executeIndexQuery(context, index, keyParams, ascSortOrder);
                } catch (OIndexEngineException e) {
                    throw e;
                } catch (Exception e) {
                    OLogManager.instance().error(this, "Error on using index %s in query '%s'. Probably you need to rebuild indexes. Now executing query using cluster scan", e, index.getName(), request != null && request.getText() != null ? request.getText() : "");
                    fullySortedByIndex = false;
                    cursors.clear();
                    return null;
                }
                if (cursor == null) {
                    continue;
                }
                if (indexRebuildVersion == index.getRebuildVersion()) {
                    cursors.add(OIndexChangesWrapper.wrap(index, cursor, indexRebuildVersion));
                    indexUseAttempts.add(new IndexUsageLog(index, keyParams, indexDefinition));
                    indexUsed = true;
                    break;
                }
            }
            if (indexUsed) {
                break;
            }
        }
        if (!indexUsed) {
            OIndexCursor cursor = tryGetOptimizedSortCursor(iSchemaClass);
            if (cursor == null) {
                return null;
            }
            List<OIndexCursor> result = new ArrayList<OIndexCursor>();
            result.add(cursor);
            return result;
        }
    }
    if (cursors.size() == 0 || lastSearchResult == null) {
        return null;
    }
    metricRecorder.recordOrderByOptimizationMetric(indexIsUsedInOrderBy, this.fullySortedByIndex);
    indexUseAttempts.clear();
    return cursors;
}
Also used : OSQLQuery(com.orientechnologies.orient.core.sql.query.OSQLQuery) OException(com.orientechnologies.common.exception.OException) OQueryParsingException(com.orientechnologies.orient.core.exception.OQueryParsingException) OCommandExecutionException(com.orientechnologies.orient.core.exception.OCommandExecutionException) IOException(java.io.IOException) ExecutionException(java.util.concurrent.ExecutionException) ODatabaseDocument(com.orientechnologies.orient.core.db.document.ODatabaseDocument)

Aggregations

OException (com.orientechnologies.common.exception.OException)2 OCommandExecutionException (com.orientechnologies.orient.core.exception.OCommandExecutionException)2 OQueryParsingException (com.orientechnologies.orient.core.exception.OQueryParsingException)2 OSQLQuery (com.orientechnologies.orient.core.sql.query.OSQLQuery)2 OCollate (com.orientechnologies.orient.core.collate.OCollate)1 ODatabaseDocument (com.orientechnologies.orient.core.db.document.ODatabaseDocument)1 ORecordNotFoundException (com.orientechnologies.orient.core.exception.ORecordNotFoundException)1 OType (com.orientechnologies.orient.core.metadata.schema.OType)1 BytesContainer (com.orientechnologies.orient.core.serialization.serializer.record.binary.BytesContainer)1 OBinaryField (com.orientechnologies.orient.core.serialization.serializer.record.binary.OBinaryField)1 OQueryOperatorMatches (com.orientechnologies.orient.core.sql.operator.OQueryOperatorMatches)1 IOException (java.io.IOException)1 ParseException (java.text.ParseException)1 ExecutionException (java.util.concurrent.ExecutionException)1