SOLR-4650: copyField doesn't work with source globs that don't match any explicit or dynamic fields

git-svn-id: https://svn.apache.org/repos/asf/lucene/dev/trunk@1462396 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Steven Rowe 2013-03-29 04:33:34 +00:00
parent 33c3778360
commit 167a4b84c3
10 changed files with 293 additions and 8 deletions

View File

@ -114,6 +114,10 @@ Bug Fixes
* SOLR-3956: Fixed group.facet=true to work with negative facet.limit
(Chris van der Merwe, hossman)
* SOLR-4650: copyField doesn't work with source globs that don't match any
explicit or dynamic fields. This regression was introduced in Solr 4.2.
(Daniel Collins, Steve Rowe)
Optimizations
----------------------

View File

@ -740,8 +740,21 @@ public final class IndexSchema {
boolean sourceIsDynamicFieldReference = false;
boolean sourceIsExplicitFieldGlob = false;
if (null == sourceSchemaField && isValidFieldGlob(source)) {
final String invalidGlobMessage = "is an invalid glob: either it contains more than one asterisk,"
+ " or the asterisk occurs neither at the start nor at the end.";
final boolean sourceIsGlob = isValidFieldGlob(source);
if (source.contains("*") && ! sourceIsGlob) {
String msg = "copyField source :'" + source + "' " + invalidGlobMessage;
throw new SolrException(ErrorCode.SERVER_ERROR, msg);
}
if (dest.contains("*") && ! isValidFieldGlob(dest)) {
String msg = "copyField dest :'" + dest + "' " + invalidGlobMessage;
throw new SolrException(ErrorCode.SERVER_ERROR, msg);
}
if (null == sourceSchemaField && sourceIsGlob) {
Pattern pattern = Pattern.compile(source.replace("*", ".*")); // glob->regex
for (String field : fields.keySet()) {
if (pattern.matcher(field).matches()) {
@ -778,19 +791,19 @@ public final class IndexSchema {
}
}
}
if (null == sourceSchemaField && ! sourceIsDynamicFieldReference && ! sourceIsExplicitFieldGlob) {
String msg = "copyField source :'" + source + "' doesn't match any explicit field or dynamicField.";
if (null == sourceSchemaField && ! sourceIsGlob && ! sourceIsDynamicFieldReference) {
String msg = "copyField source :'" + source + "' is not a glob and doesn't match any explicit field or dynamicField.";
throw new SolrException(ErrorCode.SERVER_ERROR, msg);
}
if (null == destSchemaField) {
String msg = "copyField dest :'" + dest + "' is not an explicit field and doesn't match a dynamicField.";
throw new SolrException(ErrorCode.SERVER_ERROR, msg);
}
if (sourceIsDynamicFieldReference || sourceIsExplicitFieldGlob) {
if (null != destDynamicField) { // source: dynamic field ref or explicit field glob; dest: dynamic field ref
if (sourceIsDynamicFieldReference || sourceIsGlob) {
if (null != destDynamicField) { // source: glob or no-asterisk dynamic field ref; dest: dynamic field ref
registerDynamicCopyField(new DynamicCopy(source, destDynamicField, maxChars, sourceDynamicBase, destDynamicBase));
incrementCopyFieldTargetCount(destSchemaField);
} else { // source: dynamic field reference; dest: explicit field
} else { // source: glob or no-asterisk dynamic field ref; dest: explicit field
destDynamicField = new DynamicField(destSchemaField);
registerDynamicCopyField(new DynamicCopy(source, destDynamicField, maxChars, sourceDynamicBase, null));
incrementCopyFieldTargetCount(destSchemaField);

View File

@ -0,0 +1,31 @@
<?xml version="1.0" ?>
<!--
Licensed to the Apache Software Foundation (ASF) under one or more
contributor license agreements. See the NOTICE file distributed with
this work for additional information regarding copyright ownership.
The ASF licenses this file to You under the Apache License, Version 2.0
(the "License"); you may not use this file except in compliance with
the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<schema name="test" version="1.5">
<types>
<fieldtype name="string" class="solr.StrField" sortMissingLast="true"/>
</types>
<fields>
<field name="text" type="string" indexed="true" stored="true"/>
</fields>
<!-- This should cause an exception, since the copyField dest contains an asterisk at a position
that is neither the start or the end.
-->
<copyField source="text" dest="misplaced_*_asterisk"/>
</schema>

View File

@ -0,0 +1,31 @@
<?xml version="1.0" ?>
<!--
Licensed to the Apache Software Foundation (ASF) under one or more
contributor license agreements. See the NOTICE file distributed with
this work for additional information regarding copyright ownership.
The ASF licenses this file to You under the Apache License, Version 2.0
(the "License"); you may not use this file except in compliance with
the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<schema name="test" version="1.5">
<types>
<fieldtype name="string" class="solr.StrField" sortMissingLast="true"/>
</types>
<fields>
<field name="text" type="string" indexed="true" stored="true"/>
</fields>
<!-- This should cause an exception, since the copyField source contains an asterisk at a position
that is neither the start or the end.
-->
<copyField source="misplaced_*_asterisk" dest="text"/>
</schema>

View File

@ -0,0 +1,29 @@
<?xml version="1.0" ?>
<!--
Licensed to the Apache Software Foundation (ASF) under one or more
contributor license agreements. See the NOTICE file distributed with
this work for additional information regarding copyright ownership.
The ASF licenses this file to You under the Apache License, Version 2.0
(the "License"); you may not use this file except in compliance with
the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<schema name="test" version="1.5">
<types>
<fieldtype name="string" class="solr.StrField" sortMissingLast="true"/>
</types>
<fields>
<field name="text" type="string" indexed="true" stored="true"/>
</fields>
<!-- This should cause an exception, since the copyField dest contains more than one asterisk -->
<copyField source="text" dest="*too_many_asterisks*"/>
</schema>

View File

@ -0,0 +1,29 @@
<?xml version="1.0" ?>
<!--
Licensed to the Apache Software Foundation (ASF) under one or more
contributor license agreements. See the NOTICE file distributed with
this work for additional information regarding copyright ownership.
The ASF licenses this file to You under the Apache License, Version 2.0
(the "License"); you may not use this file except in compliance with
the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<schema name="test" version="1.5">
<types>
<fieldtype name="string" class="solr.StrField" sortMissingLast="true"/>
</types>
<fields>
<field name="text" type="string" indexed="true" stored="true"/>
</fields>
<!-- This should cause an exception, since the copyField source contains more than one asterisk -->
<copyField source="*too_many_asterisks*" dest="text"/>
</schema>

View File

@ -0,0 +1,36 @@
<?xml version="1.0" ?>
<!--
Licensed to the Apache Software Foundation (ASF) under one or more
contributor license agreements. See the NOTICE file distributed with
this work for additional information regarding copyright ownership.
The ASF licenses this file to You under the Apache License, Version 2.0
(the "License"); you may not use this file except in compliance with
the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<schema name="test" version="1.5">
<types>
<fieldtype name="string" class="solr.StrField" sortMissingLast="true"/>
</types>
<fields>
<field name="id" type="string" indexed="true" stored="true" required="true"/>
<field name="text" type="string" indexed="true" stored="true"/>
<dynamicField name="*_s" type="string" indexed="true" stored="true"/>
</fields>
<!-- This should cause an exception, since the copyField source is not a glob
and doesn't match any explicit or dynamic field
-->
<copyField source="matches_nothing" dest="text"/>
</schema>

View File

@ -466,7 +466,10 @@
<copyField source="sku*" dest="*_s"/>
<copyField source="sku*" dest="*_dest_sub_s"/>
<copyField source="sku*" dest="dest_sub_no_ast_s"/>
<!-- test source glob that doesn't match any explicit or dynamic field -->
<copyField source="testing123_*" dest="text"/>
<!-- Similarity is the scoring routine for each document vs a query.
A custom similarity may be specified here, but the default is fine
for most applications.

View File

@ -0,0 +1,85 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.solr.schema;
import org.apache.solr.SolrTestCaseJ4;
import org.junit.Test;
/**
* SOLR-4650: copyField source with no asterisk should trigger an error if it doesn't match an explicit or dynamic field
*/
public class BadCopyFieldTest extends SolrTestCaseJ4 {
@Test
public void testNonGlobCopyFieldSourceMatchingNothingShouldFail() {
try {
initCore("solrconfig.xml","bad-schema-non-glob-copyfield-source-matching-nothing-should-fail-test.xml");
} catch (Exception e) {
assertEquals
("copyField source :'matches_nothing' is not a glob and doesn't match any explicit field or dynamicField.",
e.getMessage());
}
}
@Test
public void testMultipleAsteriskCopyFieldSourceShouldFail() {
try {
initCore("solrconfig.xml","bad-schema-multiple-asterisk-copyfield-source-should-fail-test.xml");
} catch (Exception e) {
assertEquals
("copyField source :'*too_many_asterisks*' is an invalid glob: either it contains more than one asterisk,"
+" or the asterisk occurs neither at the start nor at the end.",
e.getMessage());
}
}
@Test
public void testMisplacedAsteriskCopyFieldSourceShouldFail() {
try {
initCore("solrconfig.xml","bad-schema-misplaced-asterisk-copyfield-source-should-fail-test.xml");
} catch (Exception e) {
assertEquals
("copyField source :'misplaced_*_asterisk' is an invalid glob: either it contains more than one asterisk,"
+" or the asterisk occurs neither at the start nor at the end.",
e.getMessage());
}
}
public void testMultipleAsteriskCopyFieldDestShouldFail() {
try {
initCore("solrconfig.xml","bad-schema-multiple-asterisk-copyfield-dest-should-fail-test.xml");
} catch (Exception e) {
assertEquals
("copyField dest :'*too_many_asterisks*' is an invalid glob: either it contains more than one asterisk,"
+" or the asterisk occurs neither at the start nor at the end.",
e.getMessage());
}
}
@Test
public void testMisplacedAsteriskCopyFieldDestShouldFail() {
try {
initCore("solrconfig.xml","bad-schema-misplaced-asterisk-copyfield-dest-should-fail-test.xml");
} catch (Exception e) {
assertEquals
("copyField dest :'misplaced_*_asterisk' is an invalid glob: either it contains more than one asterisk,"
+" or the asterisk occurs neither at the start nor at the end.",
e.getMessage());
}
}
}

View File

@ -222,4 +222,28 @@ public class CopyFieldTest extends SolrTestCaseJ4 {
assertQ("sku2 copied to dest_sub_no_ast_s (*_s subset pattern no asterisk)", req
,"//*[@numFound='1']");
}
@Test
public void testSourceGlobMatchesNoDynamicOrExplicitField()
{
// SOLR-4650: copyField source globs should not have to match an explicit or dynamic field
SolrCore core = h.getCore();
IndexSchema schema = core.getSchema();
assertNull("'testing123_*' should not be (or match) a dynamic or explicit field", schema.getFieldOrNull("testing123_*"));
assertTrue("schema should contain dynamic field '*_s'", schema.getDynamicPattern("*_s").equals("*_s"));
assertU(adoc("id", "A5", "sku1", "10-1839ACX-93", "testing123_s", "AAM46"));
assertU(commit());
Map<String,String> args = new HashMap<String, String>();
args.put( CommonParams.Q, "text:AAM46" );
args.put( "indent", "true" );
SolrQueryRequest req = new LocalSolrQueryRequest( core, new MapSolrParams( args) );
assertQ("sku2 copied to text", req
,"//*[@numFound='1']"
,"//result/doc[1]/str[@name='id'][.='A5']"
);
}
}