You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@lucene.apache.org by dw...@apache.org on 2021/03/10 09:58:33 UTC
[lucene] 18/49: SOLR-14950: fix regenerating of copyfield with
explicit src/dest matching dyn rule
This is an automated email from the ASF dual-hosted git repository.
dweiss pushed a commit to branch jira/solr-13105-toMerge
in repository https://gitbox.apache.org/repos/asf/lucene.git
commit 0bed4364aed6379199a687de9e438a16045aee0e
Author: Munendra S N <mu...@apache.org>
AuthorDate: Wed Nov 25 08:52:38 2020 +0530
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
---
solr/CHANGES.txt | 6 +-
.../org/apache/solr/schema/ManagedIndexSchema.java | 5 +-
.../apache/solr/rest/schema/TestBulkSchemaAPI.java | 102 +++++++++++++++++++++
3 files changed, 110 insertions(+), 3 deletions(-)
diff --git a/solr/CHANGES.txt b/solr/CHANGES.txt
index edc6b22..e9d54f1 100644
--- a/solr/CHANGES.txt
+++ b/solr/CHANGES.txt
@@ -301,7 +301,11 @@ Bug Fixes
* SOLR-15047: Fix collapse parser behavior when collapsing on numeric fields to differentiate '0' group from null group (hossman)
- * 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
---------------------
diff --git a/solr/core/src/java/org/apache/solr/schema/ManagedIndexSchema.java b/solr/core/src/java/org/apache/solr/schema/ManagedIndexSchema.java
index dd17c5b..ddabd25 100644
--- a/solr/core/src/java/org/apache/solr/schema/ManagedIndexSchema.java
+++ b/solr/core/src/java/org/apache/solr/schema/ManagedIndexSchema.java
@@ -936,8 +936,9 @@ public final class ManagedIndexSchema extends IndexSchema {
private void rebuildCopyFields(List<CopyField> oldCopyFields) {
if (oldCopyFields.size() > 0) {
for (CopyField copyField : oldCopyFields) {
- SchemaField source = fields.get(copyField.getSource().getName());
- SchemaField destination = fields.get(copyField.getDestination().getName());
+ // source or destination either could be explicit field which matches dynamic rule
+ SchemaField source = getFieldOrNull(copyField.getSource().getName());
+ SchemaField destination = getFieldOrNull(copyField.getDestination().getName());
registerExplicitSrcAndDestFields
(copyField.getSource().getName(), copyField.getMaxChars(), destination, source);
}
diff --git a/solr/core/src/test/org/apache/solr/rest/schema/TestBulkSchemaAPI.java b/solr/core/src/test/org/apache/solr/rest/schema/TestBulkSchemaAPI.java
index 6cef7cd..32795f4 100644
--- a/solr/core/src/test/org/apache/solr/rest/schema/TestBulkSchemaAPI.java
+++ b/solr/core/src/test/org/apache/solr/rest/schema/TestBulkSchemaAPI.java
@@ -773,6 +773,108 @@ public class TestBulkSchemaAPI extends RestTestBase {
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"})
public void testDeleteAndReplace() throws Exception {
RestTestHarness harness = restTestHarness;