mirror of https://github.com/apache/lucene.git
SOLR-14950: fix regenerating of copyfield with explicit src/dest matching dyn rule
CopyFields are regenerated in case of replace-field or replace-field-type. While regenerating, source and destionation are checked against fields but source/dest could match dynamic rule too. For example, <copyField source="something_s" dest="spellcheck"/> <dynamicField name="*_s" type="string"/> here, something_s is not present in schema but matches the dynamic rule. To handle the above case, need to check dynamicFieldCache too while regenerating the copyFields
This commit is contained in:
parent
4ab5d31832
commit
0846da5c22
|
@ -303,6 +303,10 @@ Bug Fixes
|
||||||
|
|
||||||
* SOLR-10860: Return proper error code for bad input in case of inplace updates (Tomas Eduardo Fernandez Lobbe, Munendra S N)
|
* SOLR-10860: Return proper error code for bad input in case of inplace updates (Tomas Eduardo Fernandez Lobbe, Munendra S N)
|
||||||
|
|
||||||
|
* SOLR-14950: Fix error in copyField regeneration when explicit source/destination is not present in schema but
|
||||||
|
matches the dynamic rule. The copyFields are rebuilt with replace-field and replace-field-type, if required
|
||||||
|
(Andrew Shumway, Munendra S N)
|
||||||
|
|
||||||
Other Changes
|
Other Changes
|
||||||
---------------------
|
---------------------
|
||||||
|
|
||||||
|
|
|
@ -936,8 +936,9 @@ public final class ManagedIndexSchema extends IndexSchema {
|
||||||
private void rebuildCopyFields(List<CopyField> oldCopyFields) {
|
private void rebuildCopyFields(List<CopyField> oldCopyFields) {
|
||||||
if (oldCopyFields.size() > 0) {
|
if (oldCopyFields.size() > 0) {
|
||||||
for (CopyField copyField : oldCopyFields) {
|
for (CopyField copyField : oldCopyFields) {
|
||||||
SchemaField source = fields.get(copyField.getSource().getName());
|
// source or destination either could be explicit field which matches dynamic rule
|
||||||
SchemaField destination = fields.get(copyField.getDestination().getName());
|
SchemaField source = getFieldOrNull(copyField.getSource().getName());
|
||||||
|
SchemaField destination = getFieldOrNull(copyField.getDestination().getName());
|
||||||
registerExplicitSrcAndDestFields
|
registerExplicitSrcAndDestFields
|
||||||
(copyField.getSource().getName(), copyField.getMaxChars(), destination, source);
|
(copyField.getSource().getName(), copyField.getMaxChars(), destination, source);
|
||||||
}
|
}
|
||||||
|
|
|
@ -773,6 +773,108 @@ public class TestBulkSchemaAPI extends RestTestBase {
|
||||||
assertTrue("'bleh_s' copyField rule exists in the schema", l.isEmpty());
|
assertTrue("'bleh_s' copyField rule exists in the schema", l.isEmpty());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings({"rawtypes"})
|
||||||
|
public void testCopyFieldWithReplace() throws Exception {
|
||||||
|
RestTestHarness harness = restTestHarness;
|
||||||
|
String newFieldName = "test_solr_14950";
|
||||||
|
|
||||||
|
// add-field-type
|
||||||
|
String addFieldTypeAnalyzer = "{\n" +
|
||||||
|
"'add-field-type' : {" +
|
||||||
|
" 'name' : 'myNewTextField',\n" +
|
||||||
|
" 'class':'solr.TextField',\n" +
|
||||||
|
" 'analyzer' : {\n" +
|
||||||
|
" 'charFilters' : [{\n" +
|
||||||
|
" 'name':'patternReplace',\n" +
|
||||||
|
" 'replacement':'$1$1',\n" +
|
||||||
|
" 'pattern':'([a-zA-Z])\\\\\\\\1+'\n" +
|
||||||
|
" }],\n" +
|
||||||
|
" 'tokenizer' : { 'name':'whitespace' },\n" +
|
||||||
|
" 'filters' : [{ 'name':'asciiFolding' }]\n" +
|
||||||
|
" }\n"+
|
||||||
|
"}}";
|
||||||
|
|
||||||
|
String response = restTestHarness.post("/schema", json(addFieldTypeAnalyzer));
|
||||||
|
Map map = (Map) fromJSONString(response);
|
||||||
|
assertNull(response, map.get("error"));
|
||||||
|
map = getObj(harness, "myNewTextField", "fieldTypes");
|
||||||
|
assertNotNull("'myNewTextField' field type does not exist in the schema", map);
|
||||||
|
|
||||||
|
// add-field
|
||||||
|
String payload = "{\n" +
|
||||||
|
" 'add-field' : {\n" +
|
||||||
|
" 'name':'" + newFieldName + "',\n" +
|
||||||
|
" 'type':'myNewTextField',\n" +
|
||||||
|
" 'stored':true,\n" +
|
||||||
|
" 'indexed':true\n" +
|
||||||
|
" }\n" +
|
||||||
|
" }";
|
||||||
|
|
||||||
|
response = harness.post("/schema", json(payload));
|
||||||
|
|
||||||
|
map = (Map) fromJSONString(response);
|
||||||
|
assertNull(response, map.get("error"));
|
||||||
|
|
||||||
|
Map m = getObj(harness, newFieldName, "fields");
|
||||||
|
assertNotNull("'"+ newFieldName + "' field does not exist in the schema", m);
|
||||||
|
|
||||||
|
// add copy-field with explicit source and destination
|
||||||
|
List l = getSourceCopyFields(harness, "bleh_s");
|
||||||
|
assertTrue("'bleh_s' copyField rule exists in the schema", l.isEmpty());
|
||||||
|
|
||||||
|
payload = "{\n" +
|
||||||
|
" 'add-copy-field' : {\n" +
|
||||||
|
" 'source' :'bleh_s',\n" +
|
||||||
|
" 'dest':'"+ newFieldName + "'\n" +
|
||||||
|
" }\n" +
|
||||||
|
" }\n";
|
||||||
|
response = harness.post("/schema", json(payload));
|
||||||
|
|
||||||
|
map = (Map) fromJSONString(response);
|
||||||
|
assertNull(response, map.get("error"));
|
||||||
|
|
||||||
|
l = getSourceCopyFields(harness, "bleh_s");
|
||||||
|
assertFalse("'bleh_s' copyField rule doesn't exist", l.isEmpty());
|
||||||
|
assertEquals("bleh_s", ((Map)l.get(0)).get("source"));
|
||||||
|
assertEquals(newFieldName, ((Map)l.get(0)).get("dest"));
|
||||||
|
|
||||||
|
// replace-field-type
|
||||||
|
String replaceFieldTypeAnalyzer = "{\n" +
|
||||||
|
"'replace-field-type' : {" +
|
||||||
|
" 'name' : 'myNewTextField',\n" +
|
||||||
|
" 'class':'solr.TextField',\n" +
|
||||||
|
" 'analyzer' : {\n" +
|
||||||
|
" 'tokenizer' : { 'name':'whitespace' },\n" +
|
||||||
|
" 'filters' : [{ 'name':'asciiFolding' }]\n" +
|
||||||
|
" }\n"+
|
||||||
|
"}}";
|
||||||
|
|
||||||
|
response = restTestHarness.post("/schema", json(replaceFieldTypeAnalyzer));
|
||||||
|
map = (Map) fromJSONString(response);
|
||||||
|
assertNull(response, map.get("error"));
|
||||||
|
|
||||||
|
map = getObj(restTestHarness, "myNewTextField", "fieldTypes");
|
||||||
|
assertNotNull(map);
|
||||||
|
Map analyzer = (Map)map.get("analyzer");
|
||||||
|
assertNull("'myNewTextField' shouldn't contain charFilters", analyzer.get("charFilters"));
|
||||||
|
|
||||||
|
l = getSourceCopyFields(harness, "bleh_s");
|
||||||
|
assertFalse("'bleh_s' copyField rule doesn't exist", l.isEmpty());
|
||||||
|
assertEquals("bleh_s", ((Map)l.get(0)).get("source"));
|
||||||
|
assertEquals(newFieldName, ((Map)l.get(0)).get("dest"));
|
||||||
|
|
||||||
|
// with replace-field
|
||||||
|
String replaceField = "{'replace-field' : {'name':'" + newFieldName + "', 'type':'string'}}";
|
||||||
|
response = harness.post("/schema", json(replaceField));
|
||||||
|
map = (Map) fromJSONString(response);
|
||||||
|
assertNull(map.get("error"));
|
||||||
|
|
||||||
|
l = getSourceCopyFields(harness, "bleh_s");
|
||||||
|
assertFalse("'bleh_s' copyField rule doesn't exist", l.isEmpty());
|
||||||
|
assertEquals("bleh_s", ((Map)l.get(0)).get("source"));
|
||||||
|
assertEquals(newFieldName, ((Map)l.get(0)).get("dest"));
|
||||||
|
}
|
||||||
|
|
||||||
@SuppressWarnings({"unchecked", "rawtypes"})
|
@SuppressWarnings({"unchecked", "rawtypes"})
|
||||||
public void testDeleteAndReplace() throws Exception {
|
public void testDeleteAndReplace() throws Exception {
|
||||||
RestTestHarness harness = restTestHarness;
|
RestTestHarness harness = restTestHarness;
|
||||||
|
|
Loading…
Reference in New Issue