Fix for SOLR-5418, merge after altering schema produces error

git-svn-id: https://svn.apache.org/repos/asf/lucene/dev/trunk@1538802 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Erick Erickson 2013-11-04 23:21:12 +00:00
parent 04fed2814b
commit 5b372bd1cd
5 changed files with 164 additions and 27 deletions

View File

@ -148,6 +148,9 @@ Bug Fixes
work as intended for an alias spanning more than 1 collection.
(Thomas Egense, Shawn Heisey, Mark Miller)
* SOLR-5418: Background merge after field removed from solr.xml causes error.
(Reported on user's list, Robert M's patch via Erick Erickson)
Optimizations
----------------------

View File

@ -54,25 +54,23 @@ public class SchemaCodecFactory extends CodecFactory implements SolrCoreAware {
codec = new Lucene46Codec() {
@Override
public PostingsFormat getPostingsFormatForField(String field) {
final SchemaField fieldOrNull = core.getLatestSchema().getFieldOrNull(field);
if (fieldOrNull == null) {
throw new IllegalArgumentException("no such field " + field);
}
String postingsFormatName = fieldOrNull.getType().getPostingsFormat();
if (postingsFormatName != null) {
return PostingsFormat.forName(postingsFormatName);
final SchemaField schemaField = core.getLatestSchema().getFieldOrNull(field);
if (schemaField != null) {
String postingsFormatName = schemaField.getType().getPostingsFormat();
if (postingsFormatName != null) {
return PostingsFormat.forName(postingsFormatName);
}
}
return super.getPostingsFormatForField(field);
}
@Override
public DocValuesFormat getDocValuesFormatForField(String field) {
final SchemaField fieldOrNull = core.getLatestSchema().getFieldOrNull(field);
if (fieldOrNull == null) {
throw new IllegalArgumentException("no such field " + field);
}
String docValuesFormatName = fieldOrNull.getType().getDocValuesFormat();
if (docValuesFormatName != null) {
return DocValuesFormat.forName(docValuesFormatName);
final SchemaField schemaField = core.getLatestSchema().getFieldOrNull(field);
if (schemaField != null) {
String docValuesFormatName = schemaField.getType().getDocValuesFormat();
if (docValuesFormatName != null) {
return DocValuesFormat.forName(docValuesFormatName);
}
}
return super.getDocValuesFormatForField(field);
}

View File

@ -29,7 +29,7 @@
class="${solr.directoryFactory:solr.NRTCachingDirectoryFactory}"/>
<xi:include href="./solrconfig.snippet.randomindexconfig.xml" xmlns:xi="http://www.w3.org/2001/XInclude"/>
<codecFactory class="solr.SchemaCodecFactory"/>
<jmx/>
<updateHandler class="solr.DirectUpdateHandler2">
<!--updateLog>

View File

@ -83,16 +83,4 @@ public class TestCodecSupport extends SolrTestCaseJ4 {
assertEquals("Lucene45", format.getDocValuesFormatForField("foo_memory").getName());
assertEquals("Lucene45", format.getDocValuesFormatForField("bar_memory").getName());
}
public void testUnknownField() {
Codec codec = h.getCore().getCodec();
PerFieldPostingsFormat format = (PerFieldPostingsFormat) codec.postingsFormat();
try {
format.getPostingsFormatForField("notexisting");
fail("field is not existing");
} catch (IllegalArgumentException e) {
//
}
}
}

View File

@ -0,0 +1,148 @@
/*
* 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.commons.codec.Charsets;
import org.apache.commons.io.FileUtils;
import org.apache.solr.SolrTestCaseJ4;
import org.apache.solr.common.util.NamedList;
import org.apache.solr.core.CoreContainer;
import org.apache.solr.core.SolrCore;
import org.apache.solr.request.LocalSolrQueryRequest;
import org.apache.solr.request.SolrQueryRequest;
import org.apache.solr.update.AddUpdateCommand;
import org.apache.solr.update.CommitUpdateCommand;
import org.apache.solr.update.UpdateHandler;
import org.junit.BeforeClass;
import org.junit.Test;
import java.io.File;
import java.io.IOException;
public class ChangedSchemaMergeTest extends SolrTestCaseJ4 {
@BeforeClass
public static void beforeClass() throws Exception {
initCore();
}
private final File solrHomeDirectory = new File(TEMP_DIR, getSimpleClassName());
private File schemaFile = null;
private void addDoc(SolrCore core, String... fieldValues) throws IOException {
UpdateHandler updater = core.getUpdateHandler();
AddUpdateCommand cmd = new AddUpdateCommand(new LocalSolrQueryRequest(core, new NamedList<Object>()));
cmd.solrDoc = sdoc((Object[]) fieldValues);
updater.addDoc(cmd);
}
private CoreContainer init() throws Exception {
if (solrHomeDirectory.exists()) {
FileUtils.deleteDirectory(solrHomeDirectory);
}
assertTrue("Failed to mkdirs workDir", solrHomeDirectory.mkdirs());
File changed = new File(solrHomeDirectory, "changed");
copyMinConf(changed, "name=changed");
// Overlay with my local schema
schemaFile = new File(new File(changed, "conf"), "schema.xml");
FileUtils.writeStringToFile(schemaFile, withWhich, Charsets.UTF_8.toString());
String discoveryXml = "<solr></solr>";
File solrXml = new File(solrHomeDirectory, "solr.xml");
FileUtils.write(solrXml, discoveryXml, Charsets.UTF_8.toString());
final CoreContainer cores = new CoreContainer(solrHomeDirectory.getAbsolutePath());
cores.load();
return cores;
}
@Test
public void testOptimizeDiffSchemas() throws Exception {
// load up a core (why not put it on disk?)
CoreContainer cc = init();
SolrCore changed = cc.getCore("changed");
try {
// add some documents
addDoc(changed, "id", "1", "which", "15", "text", "some stuff with which");
addDoc(changed, "id", "2", "which", "15", "text", "some stuff with which");
addDoc(changed, "id", "3", "which", "15", "text", "some stuff with which");
addDoc(changed, "id", "4", "which", "15", "text", "some stuff with which");
SolrQueryRequest req = new LocalSolrQueryRequest(changed, new NamedList<Object>());
changed.getUpdateHandler().commit(new CommitUpdateCommand(req, false));
// write the new schema out and make it current
FileUtils.writeStringToFile(schemaFile, withoutWhich, Charsets.UTF_8.toString());
IndexSchema iSchema = IndexSchemaFactory.buildIndexSchema("schema.xml", changed.getSolrConfig());
changed.setLatestSchema(iSchema);
addDoc(changed, "id", "1", "text", "some stuff without which");
addDoc(changed, "id", "5", "text", "some stuff without which");
changed.getUpdateHandler().commit(new CommitUpdateCommand(req, false));
changed.getUpdateHandler().commit(new CommitUpdateCommand(req, true));
} finally {
if (changed != null) changed.close();
if (cc != null) cc.shutdown();
}
}
private static String withWhich = "<schema name=\"tiny\" version=\"1.1\">\n" +
" <fields>\n" +
" <field name=\"id\" type=\"string\" indexed=\"true\" stored=\"true\" required=\"true\"/>\n" +
" <field name=\"text\" type=\"text\" indexed=\"true\" stored=\"true\"/>\n" +
" <field name=\"which\" type=\"int\" indexed=\"true\" stored=\"true\"/>\n" +
" </fields>\n" +
" <uniqueKey>id</uniqueKey>\n" +
"\n" +
" <types>\n" +
" <fieldtype name=\"text\" class=\"solr.TextField\">\n" +
" <analyzer>\n" +
" <tokenizer class=\"solr.WhitespaceTokenizerFactory\"/>\n" +
" <filter class=\"solr.LowerCaseFilterFactory\"/>\n" +
" </analyzer>\n" +
" </fieldtype>\n" +
" <fieldType name=\"string\" class=\"solr.StrField\"/>\n" +
" <fieldType name=\"int\" class=\"solr.TrieIntField\" precisionStep=\"0\" positionIncrementGap=\"0\"/>" +
" </types>\n" +
"</schema>";
private static String withoutWhich = "<schema name=\"tiny\" version=\"1.1\">\n" +
" <fields>\n" +
" <field name=\"id\" type=\"string\" indexed=\"true\" stored=\"true\" required=\"true\"/>\n" +
" <field name=\"text\" type=\"text\" indexed=\"true\" stored=\"true\"/>\n" +
" </fields>\n" +
" <uniqueKey>id</uniqueKey>\n" +
"\n" +
" <types>\n" +
" <fieldtype name=\"text\" class=\"solr.TextField\">\n" +
" <analyzer>\n" +
" <tokenizer class=\"solr.WhitespaceTokenizerFactory\"/>\n" +
" <filter class=\"solr.LowerCaseFilterFactory\"/>\n" +
" </analyzer>\n" +
" </fieldtype>\n" +
" <fieldType name=\"string\" class=\"solr.StrField\"/>\n" +
" <fieldType name=\"int\" class=\"solr.TrieIntField\" precisionStep=\"0\" positionIncrementGap=\"0\"/>" +
" </types>\n" +
"</schema>";
}