SOLR-3610: after reloading a core, indexing failed on any newly added fields to the schema

git-svn-id: https://svn.apache.org/repos/asf/lucene/dev/trunk@1359449 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Robert Muir 2012-07-10 00:35:28 +00:00
parent 160eac52ca
commit 4db783ca86
9 changed files with 86 additions and 19 deletions

View File

@ -65,6 +65,8 @@ Bug Fixes
* LUCENE-4185: Fix a bug where CharFilters were wrongly being applied twice. (Michael Froh, rmuir)
* SOLR-3610: After reloading a core, indexing would fail on any newly added fields to the schema. (Brent Mills, rmuir)
Other Changes
* SOLR-1770: Move the default core instance directory into a collection1 folder.

View File

@ -19,7 +19,6 @@ package org.apache.solr.core;
import org.apache.lucene.codecs.Codec;
import org.apache.solr.common.util.NamedList;
import org.apache.solr.schema.IndexSchema;
import org.apache.solr.util.plugin.NamedListInitializedPlugin;
/**
@ -29,5 +28,5 @@ public abstract class CodecFactory implements NamedListInitializedPlugin {
public void init(NamedList args) {
}
public abstract Codec create(IndexSchema Schema);
public abstract Codec getCodec();
}

View File

@ -1,5 +1,12 @@
package org.apache.solr.core;
import org.apache.lucene.codecs.Codec;
import org.apache.lucene.codecs.PostingsFormat;
import org.apache.lucene.codecs.lucene40.Lucene40Codec;
import org.apache.solr.schema.IndexSchema;
import org.apache.solr.schema.SchemaAware;
import org.apache.solr.schema.SchemaField;
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
@ -17,20 +24,14 @@ package org.apache.solr.core;
* limitations under the License.
*/
import org.apache.lucene.codecs.Codec;
import org.apache.lucene.codecs.PostingsFormat;
import org.apache.lucene.codecs.lucene40.Lucene40Codec;
import org.apache.solr.schema.IndexSchema;
import org.apache.solr.schema.SchemaField;
/**
* Default CodecFactory implementation, extends Lucene's
* Per-field CodecFactory implementation, extends Lucene's
* and returns postings format implementations according to the
* schema configuration.
* @lucene.experimental
*/
public class DefaultCodecFactory extends CodecFactory {
public class SchemaCodecFactory extends CodecFactory implements SchemaAware {
private Codec codec;
// TODO: we need to change how solr does this?
// rather than a string like "Pulsing" you need to be able to pass parameters
// and everything to a field in the schema, e.g. we should provide factories for
@ -40,8 +41,8 @@ public class DefaultCodecFactory extends CodecFactory {
// how it constructs this from the XML... i don't care.
@Override
public Codec create(final IndexSchema schema) {
return new Lucene40Codec() {
public void inform(final IndexSchema schema) {
codec = new Lucene40Codec() {
@Override
public PostingsFormat getPostingsFormatForField(String field) {
final SchemaField fieldOrNull = schema.getFieldOrNull(field);
@ -56,4 +57,10 @@ public class DefaultCodecFactory extends CodecFactory {
}
};
}
@Override
public Codec getCodec() {
assert codec != null : "inform must be called first";
return codec;
}
}

View File

@ -221,7 +221,7 @@ public class SolrConfig extends Config {
loadPluginInfo(DirectoryFactory.class,"directoryFactory",false, true);
loadPluginInfo(IndexDeletionPolicy.class,indexConfigPrefix+"/deletionPolicy",false, true);
loadPluginInfo(CodecFactory.class,"mainIndex/codecFactory",false, false);
loadPluginInfo(CodecFactory.class,"codecFactory",false, false);
loadPluginInfo(IndexReaderFactory.class,"indexReaderFactory",false, true);
loadPluginInfo(UpdateRequestProcessorChain.class,"updateRequestProcessorChain",false, false);
loadPluginInfo(UpdateLog.class,"updateHandler/updateLog",false, false);

View File

@ -55,7 +55,9 @@ import org.apache.solr.response.RubyResponseWriter;
import org.apache.solr.response.SolrQueryResponse;
import org.apache.solr.response.XMLResponseWriter;
import org.apache.solr.response.transform.TransformerFactory;
import org.apache.solr.schema.FieldType;
import org.apache.solr.schema.IndexSchema;
import org.apache.solr.schema.SchemaAware;
import org.apache.solr.search.QParserPlugin;
import org.apache.solr.search.SolrFieldCacheMBean;
import org.apache.solr.search.SolrIndexSearcher;
@ -690,9 +692,25 @@ public final class SolrCore implements SolrInfoMBean {
factory = schema.getResourceLoader().newInstance(info.className, CodecFactory.class);
factory.init(info.initArgs);
} else {
factory = new DefaultCodecFactory();
factory = new CodecFactory() {
@Override
public Codec getCodec() {
return Codec.getDefault();
}
};
}
return factory.create(schema);
if (factory instanceof SchemaAware) {
((SchemaAware)factory).inform(schema);
} else {
for (FieldType ft : schema.getFieldTypes().values()) {
if (null != ft.getPostingsFormat()) {
String msg = "FieldType '" + ft.getTypeName() + "' is configured with a postings format, but the codec does not support it: " + factory.getClass();
log.error(msg);
throw new SolrException(SolrException.ErrorCode.SERVER_ERROR, msg);
}
}
}
return factory.getCodec();
}
/**

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="bad-schema-codec-global-vs-ft-mismatch" version="1.0">
<types>
<!-- BAD: postingsFormat here but no codec that allows it -->
<fieldType name="pulsing1" class="solr.TextField" postingsFormat="Pulsing">
<analyzer>
<tokenizer class="solr.MockTokenizerFactory"/>
</analyzer>
</fieldType>
</types>
<fields>
<field name="pulsing1text" type="pulsing1" indexed="true" stored="true"/>
<dynamicField name="*" type="pulsing1" />
</fields>
<defaultSearchField>pulsing1text</defaultSearchField>
</schema>

View File

@ -19,5 +19,6 @@
<config>
<luceneMatchVersion>${tests.luceneMatchVersion:LUCENE_CURRENT}</luceneMatchVersion>
<directoryFactory name="DirectoryFactory" class="${solr.directoryFactory:solr.RAMDirectoryFactory}"/>
<requestHandler name="standard" class="solr.StandardRequestHandler"></requestHandler>
<requestHandler name="standard" class="solr.StandardRequestHandler"></requestHandler>
<codecFactory class="solr.SchemaCodecFactory"/>
</config>

View File

@ -29,7 +29,7 @@ public class TestCodecSupport extends SolrTestCaseJ4 {
@BeforeClass
public static void beforeClass() throws Exception {
initCore("solrconfig-basic.xml", "schema_codec.xml");
initCore("solrconfig_codec.xml", "schema_codec.xml");
}
public void testPostingsFormats() {

View File

@ -34,7 +34,7 @@ public class BadIndexSchemaTest extends SolrTestCaseJ4 {
ignoreException(Pattern.quote(errString));
try {
initCore( "solrconfig.xml", schema );
} catch (SolrException e) {
} catch (Exception e) {
// short circuit out if we found what we expected
if (-1 != e.getMessage().indexOf(errString)) return;
// Test the cause too in case the expected error is wrapped
@ -89,6 +89,10 @@ public class BadIndexSchemaTest extends SolrTestCaseJ4 {
public void testPerFieldtypeSimButNoSchemaSimFactory() throws Exception {
doTest("bad-schema-sim-global-vs-ft-mismatch.xml", "global similarity does not support it");
}
public void testPerFieldtypePostingsFormatButNoSchemaCodecFactory() throws Exception {
doTest("bad-schema-codec-global-vs-ft-mismatch.xml", "codec does not support");
}
}