use of org.apache.geode.cache.query.internal.MapIndexable in project geode by apache.
the class FunctionalIndexCreationHelper method prepareIndexExpression.
/**
* This function is modified so that if the indexed expression has any dependency on the 0th
* iterator, then it needs to modified by using the missing link so that it is derivable from the
* 0th iterator.
* <p>
* TODO: refactor large method prepareIndexExpression
*/
private void prepareIndexExpression(String indexedExpression) throws IndexInvalidException {
CompiledValue expr = this.compiler.compileQuery(indexedExpression);
if (expr == null) {
throw new IndexInvalidException(LocalizedStrings.FunctionalIndexCreationHelper_INVALID_INDEXED_EXPRESSION_0.toLocalizedString(indexedExpression));
}
if (expr instanceof CompiledUndefined || expr instanceof CompiledLiteral || expr instanceof CompiledComparison || expr instanceof CompiledBindArgument || expr instanceof CompiledNegation) {
throw new IndexInvalidException(LocalizedStrings.FunctionalIndexCreationHelper_INVALID_INDEXED_EXPRESSION_0.toLocalizedString(indexedExpression));
}
try {
StringBuilder sb = new StringBuilder();
if (expr instanceof MapIndexable) {
MapIndexable mi = (MapIndexable) expr;
List<CompiledValue> indexingKeys = mi.getIndexingKeys();
if (indexingKeys.size() == 1 && indexingKeys.get(0) == CompiledValue.MAP_INDEX_ALL_KEYS) {
this.isMapTypeIndex = true;
this.isAllKeys = true;
// Strip the index operator
expr = mi.getRecieverSansIndexArgs();
expr.generateCanonicalizedExpression(sb, this.context);
sb.append('[').append('*').append(']');
} else if (indexingKeys.size() == 1) {
expr.generateCanonicalizedExpression(sb, this.context);
} else {
this.isMapTypeIndex = true;
this.multiIndexKeysPattern = new String[indexingKeys.size()];
this.mapKeys = new Object[indexingKeys.size()];
expr = mi.getRecieverSansIndexArgs();
expr.generateCanonicalizedExpression(sb, this.context);
sb.append('[');
String prefixStr = sb.toString();
StringBuilder sb2 = new StringBuilder();
int size = indexingKeys.size();
for (int j = 0; j < size; ++j) {
CompiledValue cv = indexingKeys.get(size - j - 1);
this.mapKeys[size - j - 1] = cv.evaluate(this.context);
StringBuilder sb3 = new StringBuilder();
cv.generateCanonicalizedExpression(sb3, this.context);
sb3.insert(0, prefixStr);
sb3.append(']');
this.multiIndexKeysPattern[j] = sb3.toString();
cv.generateCanonicalizedExpression(sb2, this.context);
sb2.insert(0, ',');
}
sb2.deleteCharAt(0);
sb.append(sb2);
sb.append(']');
}
} else {
expr.generateCanonicalizedExpression(sb, this.context);
}
this.indexedExpression = sb.toString();
this.modifiedIndexExpr = expr;
if (!this.isFirstIteratorRegionEntry && this.indexedExpression.contains(this.canonicalizedIteratorNames[0])) {
this.modifiedIndexExpr = getModifiedDependentCompiledValue(this.context, -1, expr, true);
}
} catch (Exception e) {
throw new IndexInvalidException(LocalizedStrings.FunctionalIndexCreationHelper_INVALID_INDEXED_EXPRESSION_0.toLocalizedString(indexedExpression), e);
}
this.indexedExpr = expr;
}
use of org.apache.geode.cache.query.internal.MapIndexable in project geode by apache.
the class AbstractMapIndex method isMatchingWithIndexExpression.
@Override
public boolean isMatchingWithIndexExpression(CompiledValue condnExpr, String conditionExprStr, ExecutionContext context) throws AmbiguousNameException, TypeMismatchException, NameResolutionException {
if (this.isAllKeys) {
// stripped of the index arg & see if it matches.
if (condnExpr instanceof MapIndexable) {
MapIndexable mi = (MapIndexable) condnExpr;
CompiledValue recvr = mi.getRecieverSansIndexArgs();
StringBuilder sb = new StringBuilder();
recvr.generateCanonicalizedExpression(sb, context);
sb.append('[').append(']');
return sb.toString().equals(this.patternStr[0]);
} else {
return false;
}
} else {
for (String expr : this.patternStr) {
if (expr.equals(conditionExprStr)) {
return true;
}
}
return false;
}
}
use of org.apache.geode.cache.query.internal.MapIndexable in project geode by apache.
the class IndexManager method shouldCreateCompactIndex.
/**
* Return true if we should create CompactRangeIndex Required conditions: indexedExpression is a
* path expression, fromClause has only one iterator and it is directly on the region values.
* Currently we have to use the "fat" implementation when asynchronous index updates are on.
*/
private boolean shouldCreateCompactIndex(FunctionalIndexCreationHelper helper) {
if (RANGEINDEX_ONLY || TEST_RANGEINDEX_ONLY) {
return false;
}
// gemfire.index.acquireCompactIndexLocksWithRegionEntryLocks
if (!getRegion().getAttributes().getIndexMaintenanceSynchronous()) {
return false;
}
// indexedExpression requirement
CompiledValue cv = helper.getCompiledIndexedExpression();
int nodeType;
do {
nodeType = cv.getType();
if (nodeType == CompiledValue.PATH) {
cv = ((CompiledPath) cv).getReceiver();
}
} while (nodeType == CompiledValue.PATH);
// end of path, nodeType at this point should be an Identifier
if (nodeType != OQLLexerTokenTypes.Identifier && nodeType != OQLLexerTokenTypes.METHOD_INV) {
if (nodeType == OQLLexerTokenTypes.TOK_LBRACK && !helper.isMapTypeIndex() && helper.modifiedIndexExpr instanceof MapIndexable) {
if (((MapIndexable) helper.modifiedIndexExpr).getIndexingKeys().size() == 1) {
} else {
return false;
}
} else {
return false;
}
}
// fromClause requirement
List iterators = helper.getIterators();
if (iterators.size() != 1) {
return false;
}
// "missing link" must be "value". Later to support key, entry, etc.
CompiledValue missingLink = helper.missingLink;
if (helper.isFirstIteratorRegionEntry) {
return true;
} else if (!(missingLink instanceof CompiledPath)) {
return false;
}
String tailId = ((CompiledPath) missingLink).getTailID();
if (!(tailId.equals("value") || tailId.equals("key"))) {
return false;
}
return true;
}
Aggregations