You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@jackrabbit.apache.org by mr...@apache.org on 2008/02/22 13:46:26 UTC
svn commit: r630183 - in /jackrabbit/branches/1.4/jackrabbit-core/src:
main/java/org/apache/jackrabbit/core/query/lucene/WildcardTermEnum.java
test/java/org/apache/jackrabbit/core/query/UpperLowerCaseQueryTest.java
Author: mreutegg
Date: Fri Feb 22 04:46:23 2008
New Revision: 630183
URL: http://svn.apache.org/viewvc?rev=630183&view=rev
Log:
JCR-1408: Invalid query results when using jcr:like with a case transform function and a pattern not starting with a wildcard
Modified:
jackrabbit/branches/1.4/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/WildcardTermEnum.java
jackrabbit/branches/1.4/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/query/UpperLowerCaseQueryTest.java
Modified: jackrabbit/branches/1.4/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/WildcardTermEnum.java
URL: http://svn.apache.org/viewvc/jackrabbit/branches/1.4/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/WildcardTermEnum.java?rev=630183&r1=630182&r2=630183&view=diff
==============================================================================
--- jackrabbit/branches/1.4/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/WildcardTermEnum.java (original)
+++ jackrabbit/branches/1.4/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/WildcardTermEnum.java Fri Feb 22 04:46:23 2008
@@ -93,15 +93,22 @@
this.transform = transform;
int idx = 0;
- while (idx < pattern.length()
- && Character.isLetterOrDigit(pattern.charAt(idx))) {
- idx++;
- }
- if (propName == null) {
- prefix = pattern.substring(0, idx);
+ if (transform == TRANSFORM_NONE) {
+ // optimize the term comparison by removing the prefix from the pattern
+ // and therefore use a more precise range scan
+ while (idx < pattern.length()
+ && Character.isLetterOrDigit(pattern.charAt(idx))) {
+ idx++;
+ }
+
+ if (propName == null) {
+ prefix = pattern.substring(0, idx);
+ } else {
+ prefix = FieldNames.createNamedValue(propName, pattern.substring(0, idx));
+ }
} else {
- prefix = FieldNames.createNamedValue(propName, pattern.substring(0, idx));
+ prefix = FieldNames.createNamedValue(propName, "");
}
// initialize with prefix as dummy value
@@ -271,19 +278,14 @@
new Term(field, prefix), new Term(field, limit)));
}
- String prefix = FieldNames.createNamedValue(propName, patternPrefix);
- // initialize with prefix as dummy value
- OffsetCharSequence input = new OffsetCharSequence(prefix.length(), prefix, transform);
- Matcher matcher = createRegexp(pattern.substring(idx)).matcher(input);
-
- // do range scans with patter matcher
+ // do range scans with pattern matcher
for (Iterator it = rangeScans.iterator(); it.hasNext(); ) {
RangeScan scan = (RangeScan) it.next();
do {
Term t = scan.term();
if (t != null) {
input.setBase(t.text());
- if (matcher.reset().matches()) {
+ if (WildcardTermEnum.this.pattern.reset().matches()) {
orderedTerms.put(t, new Integer(scan.docFreq()));
}
}
Modified: jackrabbit/branches/1.4/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/query/UpperLowerCaseQueryTest.java
URL: http://svn.apache.org/viewvc/jackrabbit/branches/1.4/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/query/UpperLowerCaseQueryTest.java?rev=630183&r1=630182&r2=630183&view=diff
==============================================================================
--- jackrabbit/branches/1.4/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/query/UpperLowerCaseQueryTest.java (original)
+++ jackrabbit/branches/1.4/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/query/UpperLowerCaseQueryTest.java Fri Feb 22 04:46:23 2008
@@ -22,6 +22,7 @@
import javax.jcr.query.InvalidQueryException;
import java.util.HashSet;
import java.util.Set;
+import java.util.Random;
/**
* <code>UpperLowerCaseQueryTest</code> tests the functions fn:lower-case() and
@@ -136,10 +137,39 @@
"like",
"_oo",
new boolean[]{true, true, true, true});
- check(new String[]{"foo", "Foa", "fOO", "FO", "foRm"},
+ check(new String[]{"foo", "Foa", "fOO", "FO", "foRm", "fPo", "fno", "FPo", "Fno"},
"like",
"fo%",
- new boolean[]{true, true, true, true, true});
+ new boolean[]{true, true, true, true, true, false, false, false, false});
+ }
+
+ public void testLikeComparisonRandom() throws RepositoryException {
+ String abcd = "abcd";
+ Random random = new Random();
+ for (int i = 0; i < 50; i++) {
+ String pattern = "";
+ pattern += getRandomChar(abcd, random);
+ pattern += getRandomChar(abcd, random);
+
+ // create 10 random values with 4 characters
+ String[] values = new String[10];
+ boolean[] matches = new boolean[10];
+ for (int n = 0; n < 10; n++) {
+ // at least the first character always matches
+ String value = String.valueOf(pattern.charAt(0));
+ for (int r = 1; r < 4; r++) {
+ char c = getRandomChar(abcd, random);
+ if (random.nextBoolean()) {
+ c = Character.toUpperCase(c);
+ }
+ value += c;
+ }
+ matches[n] = value.toLowerCase().startsWith(pattern);
+ values[n] = value;
+ }
+ pattern += "%";
+ check(values, "like", pattern, matches);
+ }
}
public void testRangeWithEmptyString() throws RepositoryException {
@@ -191,6 +221,23 @@
if (values.length != matches.length) {
throw new IllegalArgumentException("values and matches must have same length");
}
+ // create log message
+ StringBuffer logMsg = new StringBuffer();
+ logMsg.append("queryTerm: ").append(queryTerm);
+ logMsg.append(" values: ");
+ String separator = "";
+ for (int i = 0; i < values.length; i++) {
+ logMsg.append(separator);
+ separator = ", ";
+ if (matches[i]) {
+ logMsg.append("+");
+ } else {
+ logMsg.append("-");
+ }
+ logMsg.append(values[i]);
+ }
+ log.write(logMsg.toString());
+ log.flush();
for (NodeIterator it = testRootNode.getNodes(); it.hasNext();) {
it.nextNode().remove();
}
@@ -241,5 +288,9 @@
testRoot + "/%' and UPPER(" + propertyName1 + ") " +
sqlOperation + " '" + queryTerm.toUpperCase() + "'";
executeSQLQuery(sql, nodes);
+ }
+
+ private char getRandomChar(String pool, Random random) {
+ return pool.charAt(random.nextInt(pool.length()));
}
}