use of org.apache.geode.cache.query.internal.CompiledPath in project geode by apache.
the class FunctionalIndexCreationHelper method getModifiedDependentCompiledValue.
/**
* This function is used to correct the complied value's dependency , in case the compiledValue is
* dependent on the 0th RuntimeIterator in some way. Thus the dependent compiled value is prefixed
* with the missing link so that it is derivable from the 0th iterator.
*/
private CompiledValue getModifiedDependentCompiledValue(ExecutionContext context, int currItrID, CompiledValue cv, boolean isDependent) throws AmbiguousNameException, TypeMismatchException, NameResolutionException {
if (cv instanceof CompiledIteratorDef) {
CompiledIteratorDef iterDef = (CompiledIteratorDef) cv;
RuntimeIterator rItr = (RuntimeIterator) context.getCurrentIterators().get(currItrID);
String canonFrmClause = rItr.getDefinition();
// TODO: original value of isDependent is always ignored
isDependent = canonFrmClause.startsWith(this.canonicalizedIteratorNames[0]);
return new CompiledIteratorDef(iterDef.getName(), rItr.getElementType(), getModifiedDependentCompiledValue(context, currItrID, iterDef.getCollectionExpr(), isDependent));
} else if (cv instanceof CompiledPath) {
CompiledPath path = (CompiledPath) cv;
return new CompiledPath(getModifiedDependentCompiledValue(context, currItrID, path.getReceiver(), isDependent), path.getTailID());
} else if (cv instanceof CompiledOperation) {
CompiledOperation oper = (CompiledOperation) cv;
List list = oper.getArguments();
List newList = new ArrayList();
for (Object aList : list) {
CompiledValue cv1 = (CompiledValue) aList;
StringBuilder sb = new StringBuilder();
cv1.generateCanonicalizedExpression(sb, context);
if (sb.toString().startsWith(this.canonicalizedIteratorNames[0])) {
newList.add(getModifiedDependentCompiledValue(context, currItrID, cv1, true));
} else {
newList.add(getModifiedDependentCompiledValue(context, currItrID, cv1, false));
}
}
// What if the receiver is null?
CompiledValue rec = oper.getReceiver(context);
if (rec == null) {
if (isDependent) {
rec = this.missingLink;
}
return new CompiledOperation(rec, oper.getMethodName(), newList);
} else {
return new CompiledOperation(getModifiedDependentCompiledValue(context, currItrID, rec, isDependent), oper.getMethodName(), newList);
}
} else if (cv instanceof CompiledFunction) {
CompiledFunction cf = (CompiledFunction) cv;
CompiledValue[] cvArray = cf.getArguments();
int function = cf.getFunction();
int len = cvArray.length;
CompiledValue[] newCvArray = new CompiledValue[len];
for (int i = 0; i < len; ++i) {
CompiledValue cv1 = cvArray[i];
StringBuilder sb = new StringBuilder();
cv1.generateCanonicalizedExpression(sb, context);
if (sb.toString().startsWith(this.canonicalizedIteratorNames[0])) {
newCvArray[i] = getModifiedDependentCompiledValue(context, currItrID, cv1, true);
} else {
newCvArray[i] = getModifiedDependentCompiledValue(context, currItrID, cv1, false);
}
}
return new CompiledFunction(newCvArray, function);
} else if (cv instanceof CompiledID) {
CompiledID id = (CompiledID) cv;
RuntimeIterator rItr0 = (RuntimeIterator) context.getCurrentIterators().get(0);
if (isDependent) {
String name;
if ((name = rItr0.getName()) != null && name.equals(id.getId())) {
// The CompiledID is a RuneTimeIterator & so it needs to be replaced by the missing link
return this.missingLink;
} else {
// The compiledID is a compiledPath
return new CompiledPath(this.missingLink, id.getId());
}
} else {
return cv;
}
} else if (cv instanceof CompiledIndexOperation) {
CompiledIndexOperation co = (CompiledIndexOperation) cv;
CompiledValue cv1 = co.getExpression();
StringBuilder sb = new StringBuilder();
cv1.generateCanonicalizedExpression(sb, context);
if (sb.toString().startsWith(this.canonicalizedIteratorNames[0])) {
cv1 = getModifiedDependentCompiledValue(context, currItrID, cv1, true);
} else {
cv1 = getModifiedDependentCompiledValue(context, currItrID, cv1, false);
}
return new CompiledIndexOperation(getModifiedDependentCompiledValue(context, currItrID, co.getReceiver(), isDependent), cv1);
} else {
return cv;
}
}
use of org.apache.geode.cache.query.internal.CompiledPath in project geode by apache.
the class FunctionalIndexCreationHelper method modifyIterDefToSuiteIMQ.
private Object[] modifyIterDefToSuiteIMQ(CompiledIteratorDef iterDef) throws IndexInvalidException {
Object[] retValues = { null, null };
try {
CompiledValue def = iterDef.getCollectionExpr();
if (def instanceof CompiledRegion) {
CompiledBindArgument bindArg = new CompiledBindArgument(1);
CompiledIteratorDef newDef = new CompiledIteratorDef(iterDef.getName(), null, bindArg);
retValues[0] = def.evaluate(this.context);
retValues[1] = newDef;
return retValues;
}
if (def instanceof CompiledPath || def instanceof CompiledOperation || def instanceof CompiledIndexOperation) {
CompiledValue cv = def;
List reconstruct = new ArrayList();
while (!(cv instanceof CompiledRegion)) {
CompiledValue prevCV = cv;
if (cv instanceof CompiledOperation) {
reconstruct.add(0, ((CompiledOperation) cv).getArguments());
reconstruct.add(0, ((CompiledOperation) cv).getMethodName());
cv = ((CompiledOperation) cv).getReceiver(this.context);
} else if (cv instanceof CompiledPath) {
reconstruct.add(0, ((CompiledPath) cv).getTailID());
cv = ((CompiledPath) cv).getReceiver();
} else if (cv instanceof CompiledIndexOperation) {
reconstruct.add(0, ((CompiledIndexOperation) cv).getExpression());
cv = ((CompiledIndexOperation) cv).getReceiver();
} else {
throw new IndexInvalidException(LocalizedStrings.FunctionalIndexCreationHelper_FUNCTIONALINDEXCREATIONHELPERPREPAREFROMCLAUSEFROM_CLAUSE_IS_NEITHER_A_COMPILEDPATH_NOR_COMPILEDOPERATION.toLocalizedString());
}
reconstruct.add(0, prevCV.getType());
}
CompiledValue v = cv;
cv = new CompiledBindArgument(1);
int len = reconstruct.size();
for (int j = 0; j < len; ++j) {
Object obj = reconstruct.get(j);
if (obj instanceof Integer) {
int tokenType = (Integer) obj;
if (tokenType == CompiledValue.PATH) {
cv = new CompiledPath(cv, (String) reconstruct.get(++j));
} else if (tokenType == OQLLexerTokenTypes.TOK_LBRACK) {
cv = new CompiledIndexOperation(cv, (CompiledValue) reconstruct.get(++j));
} else if (tokenType == OQLLexerTokenTypes.METHOD_INV) {
cv = new CompiledOperation(cv, (String) reconstruct.get(++j), (List) reconstruct.get(++j));
}
}
}
CompiledIteratorDef newDef = new CompiledIteratorDef(iterDef.getName(), null, cv);
retValues[0] = v.evaluate(this.context);
retValues[1] = newDef;
return retValues;
}
} catch (Exception e) {
throw new IndexInvalidException(e);
}
return retValues;
}
use of org.apache.geode.cache.query.internal.CompiledPath in project geode by apache.
the class IndexCreationInternalsJUnitTest method testLoneFromClause.
@Test
public void testLoneFromClause() throws Exception {
// compileFromClause returns a List<CompiledIteratorDef>
QCompiler compiler = new QCompiler();
List list = compiler.compileFromClause("/pos p, p.positions");
assertEquals(2, list.size());
CompiledIteratorDef first = (CompiledIteratorDef) list.get(0);
assertEquals("p", first.getName());
assertEquals("/pos", ((CompiledRegion) first.getCollectionExpr()).getRegionPath());
assertEquals(TypeUtils.OBJECT_TYPE, first.getElementType());
CompiledIteratorDef second = (CompiledIteratorDef) list.get(1);
assertNull(second.getName());
CompiledPath path = (CompiledPath) second.getCollectionExpr();
assertEquals("p", ((CompiledID) path.getReceiver()).getId());
assertEquals("positions", path.getTailID());
assertEquals(TypeUtils.OBJECT_TYPE, second.getElementType());
}
use of org.apache.geode.cache.query.internal.CompiledPath in project geode by apache.
the class FunctionalIndexCreationHelper method prepareFromClause.
/**
* The function is modified to optimize the index creation code. If the 0th iterator of from
* clause is not on Entries, then the 0th iterator is replaced with that of entries & the value
* corresponding to original iterator is derived from the 0th iterator as additional projection
* attribute. All the other iterators & index expression if were dependent on 0th iterator are
* also appropriately modified such that they are correctly derived on the modified 0th iterator.
* <p>
* TODO: method is too complex for IDE to analyze -- refactor prepareFromClause
*/
private void prepareFromClause(IndexManager imgr) throws IndexInvalidException {
if (this.imports != null) {
this.compiler.compileImports(this.imports);
}
List list = this.compiler.compileFromClause(this.fromClause);
if (list == null) {
throw new IndexInvalidException(LocalizedStrings.FunctionalIndexCreationHelper_INVALID_FROM_CLAUSE_0.toLocalizedString(this.fromClause));
}
int size = list.size();
this.canonicalizedIteratorNames = new String[size];
this.canonicalizedIteratorDefinitions = new String[size];
StringBuilder tempBuff = new StringBuilder();
boolean isFromClauseNull = true;
try {
PartitionedRegion pr = this.context.getPartitionedRegion();
for (int i = 0; i < size; i++) {
CompiledIteratorDef iterDef = (CompiledIteratorDef) list.get(i);
iterDef.computeDependencies(this.context);
RuntimeIterator rIter = iterDef.getRuntimeIterator(this.context);
this.context.addToIndependentRuntimeItrMapForIndexCreation(iterDef);
this.context.bindIterator(rIter);
if (i != 0 && !iterDef.isDependentOnCurrentScope(this.context)) {
throw new IndexInvalidException(LocalizedStrings.FunctionalIndexCreationHelper_INVALID_FROM_CLAUSE_0_SUBSEQUENT_ITERATOR_EXPRESSIONS_IN_FROM_CLAUSE_MUST_BE_DEPENDENT_ON_PREVIOUS_ITERATORS.toLocalizedString(this.fromClause));
}
String definition = rIter.getDefinition();
this.canonicalizedIteratorDefinitions[i] = definition;
// Bind the Index_Internal_ID to the RuntimeIterator
this.canonicalizedIteratorNames[i] = imgr.putCanonicalizedIteratorNameIfAbsent(definition);
if (pr != null) {
this.canonicalizedIteratorNames[i] = pr.getIndexManager().putCanonicalizedIteratorNameIfAbsent(definition);
} else {
this.canonicalizedIteratorNames[i] = imgr.putCanonicalizedIteratorNameIfAbsent(definition);
}
rIter.setIndexInternalID(this.canonicalizedIteratorNames[i]);
tempBuff.append(definition).append(' ').append(this.canonicalizedIteratorNames[i]).append(", ");
isFromClauseNull = false;
CompiledIteratorDef newItr;
if (i == 0) {
CompiledValue cv = iterDef.getCollectionExpr();
this.addnlProjType = rIter.getElementType();
String name = iterDef.getName();
if (isEmpty(name)) {
// In case the name of iterator is null or blank set it to index_internal_id
name = this.canonicalizedIteratorNames[i];
}
CompiledValue newCollExpr = new CompiledPath(new CompiledBindArgument(1), "entries");
// TODO: What if cv is not an instance of CompiledRegion
if (cv instanceof CompiledRegion) {
this.missingLink = new CompiledPath(new CompiledID(name), "value");
this.additionalProj = this.missingLink;
} else if (cv instanceof CompiledOperation || cv instanceof CompiledPath || cv instanceof CompiledIndexOperation) {
CompiledValue prevCV;
List reconstruct = new ArrayList();
while (!(cv instanceof CompiledRegion)) {
prevCV = cv;
if (cv instanceof CompiledOperation) {
reconstruct.add(0, ((CompiledOperation) cv).getArguments());
reconstruct.add(0, ((CompiledOperation) cv).getMethodName());
cv = ((CompiledOperation) cv).getReceiver(this.context);
} else if (cv instanceof CompiledPath) {
reconstruct.add(0, ((CompiledPath) cv).getTailID());
cv = cv.getReceiver();
} else if (cv instanceof CompiledIndexOperation) {
reconstruct.add(0, ((CompiledIndexOperation) cv).getExpression());
cv = cv.getReceiver();
} else {
throw new IndexInvalidException(LocalizedStrings.FunctionalIndexCreationHelper_FUNCTIONALINDEXCREATIONHELPERPREPAREFROMCLAUSEFROM_CLAUSE_IS_NEITHER_A_COMPILEDPATH_NOR_COMPILEDOPERATION.toLocalizedString());
}
reconstruct.add(0, prevCV.getType());
}
int firstTokenType = (Integer) reconstruct.get(0);
if (firstTokenType == CompiledValue.PATH) {
String tailID = (String) reconstruct.get(1);
if (tailID.equals("asList") || tailID.equals("asSet") || tailID.equals("values") || tailID.equals("toArray") || tailID.equals("getValues")) {
this.missingLink = new CompiledPath(new CompiledID(name), "value");
} else if (tailID.equals("keys") || tailID.equals("getKeys") || tailID.equals("keySet")) {
this.missingLink = new CompiledPath(new CompiledID(name), "key");
this.isFirstIteratorRegionKey = true;
} else if (tailID.equals("entries") || tailID.equals("getEntries") || tailID.equals("entrySet")) {
this.isFirstIteratorRegionEntry = true;
} else {
throw new IndexInvalidException(LocalizedStrings.FunctionalIndexCreationHelper_FUNCTIONALINDEXCREATIONHELPERPREPAREFROMCLAUSEFROM_CLAUSE_DOES_NOT_EVALUATE_TO_VALID_COLLECTION.toLocalizedString());
}
remove(reconstruct, 2, 0);
int secondTokenType = reconstruct.size() > 1 ? (Integer) reconstruct.get(0) : -1;
if (!this.isFirstIteratorRegionEntry && secondTokenType == OQLLexerTokenTypes.TOK_LBRACK) {
// should be thrown as IndexOpn on set is not defined.
if (tailID.equals("values") || tailID.equals("getValues")) {
boolean returnEntryForRegionCollection = true;
this.additionalProj = new CompiledIndexOperation(new CompiledBindArgument(1), (CompiledValue) reconstruct.get(1), returnEntryForRegionCollection);
this.isFirstIteratorRegionEntry = true;
} else if (tailID.equals("toList") || tailID.equals("toArray")) {
// TODO: add support for toList and toArray
throw new IndexInvalidException(LocalizedStrings.FunctionalIndexCreationHelper_FUNCTIONALINDEXCREATIONHELPERPREPAREFROMCLAUSETOLIST_TOARRAY_NOT_SUPPORTED.toLocalizedString());
} else {
throw new IndexInvalidException(LocalizedStrings.FunctionalIndexCreationHelper_FUNCTIONALINDEXCREATIONHELPERPREPAREFROMCLAUSETOLIST_TOARRAY_NOT_SUPPORTED.toLocalizedString());
}
remove(reconstruct, 2, 0);
} else if (!this.isFirstIteratorRegionEntry && (secondTokenType == OQLLexerTokenTypes.METHOD_INV || secondTokenType == CompiledValue.PATH) && (tailID.equals("values") || tailID.equals("getValues") || tailID.equals("keySet") || tailID.equals("keys") || tailID.equals("getKeys"))) {
// Check if the second token name is toList or toArray or asSet.We need to remove
// those
String secTokName = (String) reconstruct.get(1);
if (secTokName.equals("asList") || secTokName.equals("asSet") || secTokName.equals("toArray")) {
remove(reconstruct, secondTokenType == OQLLexerTokenTypes.METHOD_INV ? 3 : 2, 0);
}
}
} else if (firstTokenType == OQLLexerTokenTypes.TOK_LBRACK) {
boolean returnEntryForRegionCollection = true;
this.additionalProj = new CompiledIndexOperation(new CompiledBindArgument(1), (CompiledValue) reconstruct.get(1), returnEntryForRegionCollection);
this.isFirstIteratorRegionEntry = true;
} else if (firstTokenType == OQLLexerTokenTypes.METHOD_INV) {
String methodName = (String) reconstruct.get(1);
if (methodName.equals("asList") || methodName.equals("asSet") || methodName.equals("values") || methodName.equals("toArray") || methodName.equals("getValues")) {
this.missingLink = new CompiledPath(new CompiledID(name), "value");
} else if (methodName.equals("keys") || methodName.equals("getKeys") || methodName.equals("keySet")) {
this.missingLink = new CompiledPath(new CompiledID(name), "key");
this.isFirstIteratorRegionKey = true;
} else if (methodName.equals("entries") || methodName.equals("getEntries") || methodName.equals("entrySet")) {
this.isFirstIteratorRegionEntry = true;
List args = (List) reconstruct.get(2);
if (args != null && args.size() == 1) {
Object obj = args.get(0);
if (obj instanceof CompiledBindArgument) {
throw new IndexInvalidException(LocalizedStrings.FunctionalIndexCreationHelper_FUNCTIONALINDEXCREATIONHELPERPREPAREFROMCLAUSEENTRIES_METHOD_CALLED_WITH_COMPILEDBINDARGUMENT.toLocalizedString());
}
}
}
remove(reconstruct, 3, 0);
int secondTokenType = reconstruct.size() > 1 ? (Integer) reconstruct.get(0) : -1;
if (!this.isFirstIteratorRegionEntry && secondTokenType == OQLLexerTokenTypes.TOK_LBRACK) {
if (methodName.equals("values") || methodName.equals("getValues")) {
boolean returnEntryForRegionCollection = true;
newCollExpr = new CompiledIndexOperation(new CompiledBindArgument(1), (CompiledValue) reconstruct.get(1), returnEntryForRegionCollection);
} else if (methodName.equals("toList") || methodName.equals("toArray")) {
// TODO: add support for toList and toArray
throw new IndexInvalidException(LocalizedStrings.FunctionalIndexCreationHelper_FUNCTIONALINDEXCREATIONHELPERPREPAREFROMCLAUSETOLIST_TOARRAY_NOT_SUPPORTED_YET.toLocalizedString());
} else {
throw new IndexInvalidException(LocalizedStrings.FunctionalIndexCreationHelper_FUNCTIONALINDEXCREATIONHELPERPREPAREFROMCLAUSETOLIST_TOARRAY_NOT_SUPPORTED_YET.toLocalizedString());
}
remove(reconstruct, 2, 0);
} else if (!this.isFirstIteratorRegionEntry && (secondTokenType == OQLLexerTokenTypes.METHOD_INV || secondTokenType == CompiledValue.PATH) && (methodName.equals("values") || methodName.equals("getValues") || methodName.equals("keys") || methodName.equals("getKeys") || methodName.equals("keySet"))) {
// Check if the second token name is toList or toArray or asSet.We need to remove
// those
String secTokName = (String) reconstruct.get(1);
if (secTokName.equals("asList") || secTokName.equals("asSet") || secTokName.equals("toArray")) {
remove(reconstruct, secondTokenType == OQLLexerTokenTypes.METHOD_INV ? 3 : 2, 0);
}
}
}
if (!this.isFirstIteratorRegionEntry) {
this.additionalProj = this.missingLink;
int len = reconstruct.size();
for (int j = 0; j < len; ++j) {
Object obj = reconstruct.get(j);
if (obj instanceof Integer) {
int tokenType = (Integer) obj;
if (tokenType == CompiledValue.PATH) {
this.additionalProj = new CompiledPath(this.additionalProj, (String) reconstruct.get(++j));
} else if (tokenType == OQLLexerTokenTypes.TOK_LBRACK) {
this.additionalProj = new CompiledIndexOperation(this.additionalProj, (CompiledValue) reconstruct.get(++j));
} else if (tokenType == OQLLexerTokenTypes.METHOD_INV) {
this.additionalProj = new CompiledOperation(this.additionalProj, (String) reconstruct.get(++j), (List) reconstruct.get(++j));
}
}
}
}
} else {
throw new IndexInvalidException(LocalizedStrings.FunctionalIndexCreationHelper_FUNCTIONALINDEXCREATIONHELPERPREPAREFROMCLAUSEFROM_CLAUSE_IS_NEITHER_A_COMPILEDPATH_NOR_COMPILEDOPERATION.toLocalizedString());
}
if (!this.isFirstIteratorRegionEntry) {
newItr = new CompiledIteratorDef(name, null, newCollExpr);
this.indexInitIterators = new ArrayList();
this.indexInitIterators.add(newItr);
}
} else if (!this.isFirstIteratorRegionEntry) {
newItr = iterDef;
if (rIter.getDefinition().contains(this.canonicalizedIteratorNames[0])) {
newItr = (CompiledIteratorDef) getModifiedDependentCompiledValue(this.context, i, iterDef, true);
}
this.indexInitIterators.add(newItr);
}
}
} catch (IndexInvalidException e) {
throw e;
} catch (Exception e) {
throw new IndexInvalidException(e);
}
if (isFromClauseNull)
throw new IndexInvalidException(LocalizedStrings.FunctionalIndexCreationHelper_INVALID_FROM_CLAUSE_0.toLocalizedString(this.fromClause));
this.fromClause = tempBuff.substring(0, tempBuff.length() - 2);
this.fromClauseIterators = list;
}
use of org.apache.geode.cache.query.internal.CompiledPath 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