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;
}
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;
}
Aggregations