Skip to content

Commit

Permalink
Fix possible BWC break after upgrading from pre 1.0.0
Browse files Browse the repository at this point in the history
This is happening because of elastic#4074 when we required that the top-level "query" is present to delete-by-query requests, but prior to that we required that it is not present. So the translog has a DBQ without "query" and when we try to parse it we hit this exception.

This commit adds special handling for pre 1.0.0 indices if we hit parse exception, we
try to reparse without a top-level query object to be BWC compatible for these indices.

Closes elastic#10262
  • Loading branch information
s1monw committed Jun 3, 2015
1 parent e1302e2 commit e21d87a
Show file tree
Hide file tree
Showing 2 changed files with 56 additions and 1 deletion.
24 changes: 23 additions & 1 deletion src/main/java/org/elasticsearch/index/shard/IndexShard.java
Expand Up @@ -31,6 +31,7 @@
import org.elasticsearch.ElasticsearchException;
import org.elasticsearch.ElasticsearchIllegalArgumentException;
import org.elasticsearch.ElasticsearchIllegalStateException;
import org.elasticsearch.Version;
import org.elasticsearch.action.WriteFailureException;
import org.elasticsearch.action.admin.indices.flush.FlushRequest;
import org.elasticsearch.action.admin.indices.optimize.OptimizeRequest;
Expand All @@ -56,6 +57,8 @@
import org.elasticsearch.common.unit.TimeValue;
import org.elasticsearch.common.util.concurrent.AbstractRefCounted;
import org.elasticsearch.common.util.concurrent.FutureUtils;
import org.elasticsearch.common.xcontent.XContentHelper;
import org.elasticsearch.common.xcontent.XContentParser;
import org.elasticsearch.index.IndexService;
import org.elasticsearch.index.VersionType;
import org.elasticsearch.index.aliases.IndexAliasesService;
Expand Down Expand Up @@ -87,6 +90,8 @@
import org.elasticsearch.index.percolator.PercolatorQueriesRegistry;
import org.elasticsearch.index.percolator.stats.ShardPercolateService;
import org.elasticsearch.index.query.IndexQueryParserService;
import org.elasticsearch.index.query.ParsedQuery;
import org.elasticsearch.index.query.QueryParsingException;
import org.elasticsearch.index.recovery.RecoveryStats;
import org.elasticsearch.index.refresh.RefreshStats;
import org.elasticsearch.index.search.nested.NonNestedDocsFilter;
Expand Down Expand Up @@ -540,7 +545,24 @@ public Engine.DeleteByQuery prepareDeleteByQuery(BytesReference source, @Nullabl
if (types == null) {
types = Strings.EMPTY_ARRAY;
}
Query query = queryParserService.parseQuery(source).query();
Query query;
try {
query = queryParserService.parseQuery(source).query();
} catch (QueryParsingException ex) {
// for BWC we try to parse directly the query since pre 1.0.0.Beta2 we didn't require a top level query field
if (Version.indexCreated(config.getIndexSettings()).onOrBefore(Version.V_1_0_0_Beta2)) {
try {
XContentParser parser = XContentHelper.createParser(source);
ParsedQuery parse = queryParserService.parse(parser);
query = parse.query();
} catch (Throwable t) {
ex.addSuppressed(t);
throw ex;
}
} else {
throw ex;
}
}
query = filterQueryIfNeeded(query, types);

Filter aliasFilter = indexAliasesService.aliasFilter(filteringAliases);
Expand Down
33 changes: 33 additions & 0 deletions src/test/java/org/elasticsearch/index/shard/IndexShardTests.java
Expand Up @@ -19,10 +19,15 @@
package org.elasticsearch.index.shard;

import org.elasticsearch.ElasticsearchIllegalArgumentException;
import org.elasticsearch.Version;
import org.elasticsearch.action.admin.indices.stats.IndexStats;
import org.elasticsearch.cluster.metadata.IndexMetaData;
import org.elasticsearch.common.bytes.BytesArray;
import org.elasticsearch.common.settings.ImmutableSettings;
import org.elasticsearch.index.IndexService;
import org.elasticsearch.index.engine.Engine;
import org.elasticsearch.index.query.QueryParsingException;
import org.elasticsearch.index.translog.Translog;
import org.elasticsearch.indices.IndicesService;
import org.elasticsearch.test.ElasticsearchSingleNodeTest;
import org.junit.Test;
Expand Down Expand Up @@ -116,4 +121,32 @@ public void run() {
assertNotNull(indexStats.getShards()[0].getCommitStats().getUserData().get(Engine.SYNC_COMMIT_ID));
}

public void testDeleteByQueryBWC() {
Version version = randomVersion();
assertAcked(client().admin().indices().prepareCreate("test")
.setSettings(SETTING_NUMBER_OF_SHARDS, 1, SETTING_NUMBER_OF_REPLICAS, 0, IndexMetaData.SETTING_VERSION_CREATED, version.id));
ensureGreen("test");
client().prepareIndex("test", "person").setSource("{ \"user\" : \"kimchy\" }").get();

IndicesService indicesService = getInstanceFromNode(IndicesService.class);
IndexService test = indicesService.indexService("test");
IndexShard shard = test.shard(0);
int numDocs = 1;
shard.state = IndexShardState.RECOVERING;
try {
shard.performRecoveryOperation(new Translog.DeleteByQuery(new Engine.DeleteByQuery(null, new BytesArray("{\"term\" : { \"user\" : \"kimchy\" }}"), null, null, null, Engine.Operation.Origin.RECOVERY, 0, "person")));
assertTrue(version.onOrBefore(Version.V_1_0_0_Beta2));
numDocs = 0;
} catch (QueryParsingException ex) {
assertTrue(version.after(Version.V_1_0_0_Beta2));
} finally {
shard.state = IndexShardState.STARTED;
}
shard.engine().refresh("foo");

try (Engine.Searcher searcher = shard.engine().acquireSearcher("foo")) {
assertEquals(numDocs, searcher.reader().numDocs());
}
}

}

0 comments on commit e21d87a

Please sign in to comment.