SQL: equality on analyzed through TermQuery on not-analyzed (elastic/x-pack-elasticsearch#3524)
Always use term equality for analyzed terms by falling back (to possible not present) to the not-analyzed field. Add clarifying comment in test Original commit: elastic/x-pack-elasticsearch@9e735d3fef
This commit is contained in:
parent
2870312320
commit
e5e5583bd8
|
@ -621,8 +621,10 @@ abstract class QueryTranslator {
|
|||
if (bc instanceof Equals) {
|
||||
if (bc.left() instanceof FieldAttribute) {
|
||||
FieldAttribute fa = (FieldAttribute) bc.left();
|
||||
// equality should always be against an exact match
|
||||
// (which is important for strings)
|
||||
if (fa.isInexact()) {
|
||||
return new MatchQuery(loc, name, value);
|
||||
name = fa.exactAttribute().name();
|
||||
}
|
||||
}
|
||||
return new TermQuery(loc, name, value);
|
||||
|
|
|
@ -0,0 +1,87 @@
|
|||
/*
|
||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||
* or more contributor license agreements. Licensed under the Elastic License;
|
||||
* you may not use this file except in compliance with the Elastic License.
|
||||
*/
|
||||
package org.elasticsearch.xpack.sql.planner;
|
||||
|
||||
import org.elasticsearch.test.ESTestCase;
|
||||
import org.elasticsearch.xpack.sql.analysis.analyzer.Analyzer;
|
||||
import org.elasticsearch.xpack.sql.analysis.index.EsIndex;
|
||||
import org.elasticsearch.xpack.sql.analysis.index.IndexResolution;
|
||||
import org.elasticsearch.xpack.sql.analysis.index.MappingException;
|
||||
import org.elasticsearch.xpack.sql.expression.Expression;
|
||||
import org.elasticsearch.xpack.sql.expression.function.FunctionRegistry;
|
||||
import org.elasticsearch.xpack.sql.parser.SqlParser;
|
||||
import org.elasticsearch.xpack.sql.plan.logical.Filter;
|
||||
import org.elasticsearch.xpack.sql.plan.logical.LogicalPlan;
|
||||
import org.elasticsearch.xpack.sql.plan.logical.Project;
|
||||
import org.elasticsearch.xpack.sql.planner.QueryTranslator.QueryTranslation;
|
||||
import org.elasticsearch.xpack.sql.querydsl.query.Query;
|
||||
import org.elasticsearch.xpack.sql.querydsl.query.TermQuery;
|
||||
import org.elasticsearch.xpack.sql.type.DataType;
|
||||
import org.elasticsearch.xpack.sql.type.TypesTests;
|
||||
import org.joda.time.DateTimeZone;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
public class QueryTranslatorTests extends ESTestCase {
|
||||
|
||||
private SqlParser parser;
|
||||
private IndexResolution getIndexResult;
|
||||
private FunctionRegistry functionRegistry;
|
||||
private Analyzer analyzer;
|
||||
|
||||
public QueryTranslatorTests() {
|
||||
parser = new SqlParser(DateTimeZone.UTC);
|
||||
functionRegistry = new FunctionRegistry();
|
||||
|
||||
Map<String, DataType> mapping = TypesTests.loadMapping("mapping-multi-field-variation.json");
|
||||
|
||||
EsIndex test = new EsIndex("test", mapping);
|
||||
getIndexResult = IndexResolution.valid(test);
|
||||
analyzer = new Analyzer(functionRegistry, getIndexResult, DateTimeZone.UTC);
|
||||
}
|
||||
|
||||
private LogicalPlan plan(String sql) {
|
||||
return analyzer.analyze(parser.createStatement(sql), true);
|
||||
}
|
||||
|
||||
public void testTermEqualityAnalyzer() {
|
||||
LogicalPlan p = plan("SELECT some.string FROM test WHERE some.string = 'value'");
|
||||
assertTrue(p instanceof Project);
|
||||
p = ((Project) p).child();
|
||||
assertTrue(p instanceof Filter);
|
||||
Expression condition = ((Filter) p).condition();
|
||||
QueryTranslation translation = QueryTranslator.toQuery(condition, false);
|
||||
Query query = translation.query;
|
||||
assertTrue(query instanceof TermQuery);
|
||||
TermQuery tq = (TermQuery) query;
|
||||
assertEquals("some.string.typical", tq.term());
|
||||
assertEquals("value", tq.value());
|
||||
}
|
||||
|
||||
public void testTermEqualityAnalyzerAmbiguous() {
|
||||
LogicalPlan p = plan("SELECT some.string FROM test WHERE some.ambiguous = 'value'");
|
||||
assertTrue(p instanceof Project);
|
||||
p = ((Project) p).child();
|
||||
assertTrue(p instanceof Filter);
|
||||
Expression condition = ((Filter) p).condition();
|
||||
// the message is checked elsewhere (in FieldAttributeTests)
|
||||
expectThrows(MappingException.class, () -> QueryTranslator.toQuery(condition, false));
|
||||
}
|
||||
|
||||
public void testTermEqualityNotAnalyzed() {
|
||||
LogicalPlan p = plan("SELECT some.string FROM test WHERE int = 5");
|
||||
assertTrue(p instanceof Project);
|
||||
p = ((Project) p).child();
|
||||
assertTrue(p instanceof Filter);
|
||||
Expression condition = ((Filter) p).condition();
|
||||
QueryTranslation translation = QueryTranslator.toQuery(condition, false);
|
||||
Query query = translation.query;
|
||||
assertTrue(query instanceof TermQuery);
|
||||
TermQuery tq = (TermQuery) query;
|
||||
assertEquals("int", tq.term());
|
||||
assertEquals(5, tq.value());
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue