diff --git a/solr/CHANGES.txt b/solr/CHANGES.txt index 917f1909e4b..e89851966c2 100644 --- a/solr/CHANGES.txt +++ b/solr/CHANGES.txt @@ -121,6 +121,8 @@ New Features * SOLR-2338: Add support for using in a schema's fieldType, for customizing scoring on a per-field basis. (hossman, yonik, rmuir) +* SOLR-2335: New 'field("...")' function syntax for refering to complex + field names (containing whitespace or special characters) in functions. Optimizations ---------------------- diff --git a/solr/src/java/org/apache/solr/search/ValueSourceParser.java b/solr/src/java/org/apache/solr/search/ValueSourceParser.java index 5b7834b46ea..71ac10c39e3 100755 --- a/solr/src/java/org/apache/solr/search/ValueSourceParser.java +++ b/solr/src/java/org/apache/solr/search/ValueSourceParser.java @@ -335,6 +335,15 @@ public abstract class ValueSourceParser implements NamedListInitializedPlugin { return new StringDistanceFunction(str1, str2, dist); } }); + addParser("field", new ValueSourceParser() { + @Override + public ValueSource parse(FunctionQParser fp) throws ParseException { + + String fieldName = fp.parseArg(); + SchemaField f = fp.getReq().getSchema().getField(fieldName); + return f.getType().getValueSource(f, fp); + } + }); addParser(new DoubleParser("rad") { @Override diff --git a/solr/src/test/org/apache/solr/search/function/TestFunctionQuery.java b/solr/src/test/org/apache/solr/search/function/TestFunctionQuery.java index edb36a2833a..49e6335a740 100755 --- a/solr/src/test/org/apache/solr/search/function/TestFunctionQuery.java +++ b/solr/src/test/org/apache/solr/search/function/TestFunctionQuery.java @@ -71,16 +71,14 @@ public class TestFunctionQuery extends SolrTestCaseJ4 { // replace \0 with the field name and create a parseable string public String func(String field, String template) { - StringBuilder sb = new StringBuilder("_val_:\""); + StringBuilder sb = new StringBuilder("{!func}"); for (char ch : template.toCharArray()) { if (ch=='\0') { sb.append(field); continue; } - if (ch=='"') sb.append('\\'); sb.append(ch); } - sb.append('"'); return sb.toString(); } @@ -520,5 +518,38 @@ public class TestFunctionQuery extends SolrTestCaseJ4 { dofunc("atan2(.25,.5)", Math.atan2(.25,.5)); } + /** + * verify that both the field("...") value source parser as well as + * ExternalFileField work with esoteric field names + */ + @Test + public void testExternalFieldValueSourceParser() { + + String field = "CoMpleX \" fieldName _extf"; + String fieldAsFunc = "field(\"CoMpleX \\\" fieldName _extf\")"; + + float[] ids = {100,-4,0,10,25,5,77,23,55,-78,-45,-24,63,78,94,22,34,54321,261,-627}; + + createIndex(null,ids); + + // Unsorted field, largest first + makeExternalFile(field, "54321=543210\n0=-999\n25=250","UTF-8"); + // test identity (straight field value) + singleTest(fieldAsFunc, "\0", 54321, 543210, 0,-999, 25,250, 100, 1); + Object orig = FileFloatSource.onlyForTesting; + singleTest(fieldAsFunc, "log(\0)"); + // make sure the values were cached + assertTrue(orig == FileFloatSource.onlyForTesting); + singleTest(fieldAsFunc, "sqrt(\0)"); + assertTrue(orig == FileFloatSource.onlyForTesting); + + makeExternalFile(fieldAsFunc, "0=1","UTF-8"); + assertU(adoc("id", "10000")); // will get same reader if no index change + assertU(commit()); + singleTest(fieldAsFunc, "sqrt(\0)"); + assertTrue(orig != FileFloatSource.onlyForTesting); + + purgeFieldCache(FieldCache.DEFAULT); // avoid FC insanity + } }