From f2b63fe7c6bb414645bcb41fb6e91a11efd68e17 Mon Sep 17 00:00:00 2001 From: Jon Bratseth Date: Wed, 9 Jan 2019 15:28:33 +0100 Subject: Parse USE_POSITION_DATA correctly --- .../query/textualrepresentation/Discloser.java | 2 + .../TextualQueryRepresentation.java | 4 +- .../src/main/java/com/yahoo/search/Query.java | 6 +- .../com/yahoo/search/handler/SearchHandler.java | 5 +- .../main/java/com/yahoo/search/query/Select.java | 4 +- .../java/com/yahoo/search/query/SelectParser.java | 130 +++++---------------- .../handler/test/JSONSearchHandlerTestCase.java | 65 +++++++---- .../search/handler/test/SearchHandlerTestCase.java | 13 +++ .../yahoo/search/handler/test/config/chains.cfg | 10 +- 9 files changed, 100 insertions(+), 139 deletions(-) (limited to 'container-search') diff --git a/container-search/src/main/java/com/yahoo/prelude/query/textualrepresentation/Discloser.java b/container-search/src/main/java/com/yahoo/prelude/query/textualrepresentation/Discloser.java index 1d7372a2497..cbe1c0f8ab9 100644 --- a/container-search/src/main/java/com/yahoo/prelude/query/textualrepresentation/Discloser.java +++ b/container-search/src/main/java/com/yahoo/prelude/query/textualrepresentation/Discloser.java @@ -9,9 +9,11 @@ import com.yahoo.prelude.query.Item; * @author Tony Vaagenes */ public interface Discloser { + void addProperty(String key, Object value); //A given item should either call setValue or addChild, not both. void setValue(Object value); void addChild(Item item); + } diff --git a/container-search/src/main/java/com/yahoo/prelude/query/textualrepresentation/TextualQueryRepresentation.java b/container-search/src/main/java/com/yahoo/prelude/query/textualrepresentation/TextualQueryRepresentation.java index 56f106a43f4..e299ccb5674 100644 --- a/container-search/src/main/java/com/yahoo/prelude/query/textualrepresentation/TextualQueryRepresentation.java +++ b/container-search/src/main/java/com/yahoo/prelude/query/textualrepresentation/TextualQueryRepresentation.java @@ -8,11 +8,12 @@ import java.util.*; import java.util.regex.Pattern; /** - * Creates a detailed, QED inspired representation of a query tree. + * Creates a detailed representation of a query tree. * * @author Tony Vaagenes */ public class TextualQueryRepresentation { + private Map itemReferences = new IdentityHashMap<>(); private int nextItemReference = 0; @@ -207,4 +208,5 @@ public class TextualQueryRepresentation { public String toString() { return rootDiscloser.toString(); } + } diff --git a/container-search/src/main/java/com/yahoo/search/Query.java b/container-search/src/main/java/com/yahoo/search/Query.java index 8e5e14a3aac..2e106dc62f4 100644 --- a/container-search/src/main/java/com/yahoo/search/Query.java +++ b/container-search/src/main/java/com/yahoo/search/Query.java @@ -107,14 +107,14 @@ public class Query extends com.yahoo.processing.Request implements Cloneable { private final int intValue; private final String stringValue; - Type(int intValue,String stringValue) { + Type(int intValue, String stringValue) { this.intValue = intValue; this.stringValue = stringValue; } /** Converts a type argument value into a query type */ public static Type getType(String typeString) { - for (Type type:Type.values()) + for (Type type : Type.values()) if (type.stringValue.equals(typeString)) return type; return ALL; @@ -329,8 +329,6 @@ public class Query extends com.yahoo.processing.Request implements Cloneable { init(requestMap, queryProfile); } - - private void init(Map requestMap, CompiledQueryProfile queryProfile) { startTime = System.currentTimeMillis(); if (queryProfile != null) { diff --git a/container-search/src/main/java/com/yahoo/search/handler/SearchHandler.java b/container-search/src/main/java/com/yahoo/search/handler/SearchHandler.java index fc1da407ae7..6f965944bdf 100644 --- a/container-search/src/main/java/com/yahoo/search/handler/SearchHandler.java +++ b/container-search/src/main/java/com/yahoo/search/handler/SearchHandler.java @@ -579,7 +579,8 @@ public class SearchHandler extends LoggingRequestHandler { byte[] byteArray = IOUtils.readBytes(request.getData(), 1 << 20); inspector = SlimeUtils.jsonToSlime(byteArray).get(); if (inspector.field("error_message").valid()){ - throw new QueryException("Illegal query: "+inspector.field("error_message").asString() + ", at: "+ new String(inspector.field("offending_input").asData(), StandardCharsets.UTF_8)); + throw new QueryException("Illegal query: " + inspector.field("error_message").asString() + ", at: " + + new String(inspector.field("offending_input").asData(), StandardCharsets.UTF_8)); } } catch (IOException e) { @@ -631,7 +632,7 @@ public class SearchHandler extends LoggingRequestHandler { map.put(qualifiedKey, value.asString()); break; case OBJECT: - if (qualifiedKey.equals("select.where") || qualifiedKey.equals("select.grouping")){ + if (qualifiedKey.equals("select.where") || qualifiedKey.equals("select.grouping")) { map.put(qualifiedKey, value.toString()); break; } diff --git a/container-search/src/main/java/com/yahoo/search/query/Select.java b/container-search/src/main/java/com/yahoo/search/query/Select.java index bbc152c6391..f2a534a014e 100644 --- a/container-search/src/main/java/com/yahoo/search/query/Select.java +++ b/container-search/src/main/java/com/yahoo/search/query/Select.java @@ -88,8 +88,7 @@ public class Select implements Cloneable { } /** Returns the where clause string previously assigned, or an empty string if none */ - public String getWhereString(){ return where; } - + public String getWhereString() { return where; } /** * Sets the grouping operation of the query. @@ -120,7 +119,6 @@ public class Select implements Cloneable { */ public List getGrouping() { return groupingRequests; } - @Override public String toString() { return "where: [" + where + "], grouping: [" + grouping+ "]"; diff --git a/container-search/src/main/java/com/yahoo/search/query/SelectParser.java b/container-search/src/main/java/com/yahoo/search/query/SelectParser.java index 13ebacb62ef..e4e44985b53 100644 --- a/container-search/src/main/java/com/yahoo/search/query/SelectParser.java +++ b/container-search/src/main/java/com/yahoo/search/query/SelectParser.java @@ -68,8 +68,6 @@ import static com.yahoo.slime.Type.STRING; * * @author henrhoi */ - - public class SelectParser implements Parser { Parsable query; @@ -77,13 +75,9 @@ public class SelectParser implements Parser { private final Map identifiedItems = LazyMap.newHashMap(); private final List connectedItems = new ArrayList<>(); private final Normalizer normalizer; - private final ParserEnvironment environment; private IndexFacts.Session indexFactsSession; - - - /** YQL parameters and functions */ - + // YQL parameters and functions private static final String DESCENDING_HITS_ORDER = "descending"; private static final String ASCENDING_HITS_ORDER = "ascending"; private static final Integer DEFAULT_TARGET_NUM_HITS = 10; @@ -139,18 +133,11 @@ public class SelectParser implements Parser { private static final String CALL = "call"; private static final List FUNCTION_CALLS = Arrays.asList(WAND, WEIGHTED_SET, DOT_PRODUCT, PREDICATE, RANK, WEAK_AND); - /**************************************/ - - - public SelectParser(ParserEnvironment environment) { indexFacts = environment.getIndexFacts(); normalizer = environment.getLinguistics().getNormalizer(); - - this.environment = environment; } - @Override public QueryTree parse(Parsable query) { indexFactsSession = indexFacts.newSession(query.getSources(), query.getRestrict()); @@ -161,8 +148,6 @@ public class SelectParser implements Parser { return buildTree(); } - - private QueryTree buildTree() { Inspector inspector = SlimeUtils.jsonToSlime(this.query.getSelect().getWhereString().getBytes()).get(); if (inspector.field("error_message").valid()){ @@ -176,14 +161,12 @@ public class SelectParser implements Parser { return newTree; } - private Item walkJson(Inspector inspector){ - final Item[] item = {null}; + Item[] item = {null}; inspector.traverse((ObjectTraverser) (key, value) -> { String type = (FUNCTION_CALLS.contains(key)) ? CALL : key; switch (type) { - case AND: item[0] = buildAnd(key, value); break; @@ -215,7 +198,6 @@ public class SelectParser implements Parser { return item[0]; } - public List getGroupingSteps(String grouping){ List groupingSteps = new ArrayList<>(); List groupingOperations = getOperations(grouping); @@ -242,10 +224,8 @@ public class SelectParser implements Parser { }); return operations; - } - @NonNull private Item buildFunctionCall(String key, Inspector value) { switch (key) { @@ -266,7 +246,6 @@ public class SelectParser implements Parser { } } - private void addItemsFromInspector(CompositeItem item, Inspector inspector){ if (inspector.type() == ARRAY){ inspector.traverse((ArrayTraverser) (index, new_value) -> { @@ -283,7 +262,6 @@ public class SelectParser implements Parser { } } - private Inspector getChildren(Inspector inspector){ if (inspector.type() == ARRAY){ return inspector; @@ -299,25 +277,23 @@ public class SelectParser implements Parser { return null; } - private HashMap getChildrenMap(Inspector inspector){ HashMap children = new HashMap<>(); - if (inspector.type() == ARRAY){ - inspector.traverse((ArrayTraverser) (index, new_value) -> { + if (inspector.type() == ARRAY){ + inspector.traverse((ArrayTraverser) (index, new_value) -> { + children.put(index, new_value); + }); + + } else if (inspector.type() == OBJECT){ + if (inspector.field("children").valid()){ + inspector.field("children").traverse((ArrayTraverser) (index, new_value) -> { children.put(index, new_value); }); - - } else if (inspector.type() == OBJECT){ - if (inspector.field("children").valid()){ - inspector.field("children").traverse((ArrayTraverser) (index, new_value) -> { - children.put(index, new_value); - }); - } } + } return children; } - private Inspector getAnnotations(Inspector inspector){ if (inspector.type() == OBJECT && inspector.field("attributes").valid()){ return inspector.field("attributes"); @@ -325,7 +301,6 @@ public class SelectParser implements Parser { return null; } - private HashMap getAnnotationMapFromAnnotationInspector(Inspector annotation){ HashMap attributes = new HashMap<>(); if (annotation.type() == OBJECT){ @@ -336,7 +311,6 @@ public class SelectParser implements Parser { return attributes; } - private HashMap getAnnotationMap(Inspector inspector){ HashMap attributes = new HashMap<>(); if (inspector.type() == OBJECT && inspector.field("attributes").valid()){ @@ -347,12 +321,10 @@ public class SelectParser implements Parser { return attributes; } - private T getAnnotation(String annotationName, HashMap annotations, Class expectedClass, T defaultValue) { return (annotations.get(annotationName) == null) ? defaultValue : expectedClass.cast(annotations.get(annotationName).asString()); } - private Boolean getBoolAnnotation(String annotationName, HashMap annotations, Boolean defaultValue) { if (annotations != null){ Inspector annotation = annotations.getOrDefault(annotationName, null); @@ -363,7 +335,6 @@ public class SelectParser implements Parser { return defaultValue; } - private Integer getIntegerAnnotation(String annotationName, HashMap annotations, Integer defaultValue) { if (annotations != null){ Inspector annotation = annotations.getOrDefault(annotationName, null); @@ -374,7 +345,6 @@ public class SelectParser implements Parser { return defaultValue; } - private Double getDoubleAnnotation(String annotationName, HashMap annotations, Double defaultValue) { if (annotations != null){ Inspector annotation = annotations.getOrDefault(annotationName, null); @@ -385,12 +355,10 @@ public class SelectParser implements Parser { return defaultValue; } - private Inspector getAnnotationAsInspectorOrNull(String annotationName, HashMap annotations) { return annotations.get(annotationName); } - @NonNull private CompositeItem buildAnd(String key, Inspector value) { AndItem andItem = new AndItem(); @@ -399,7 +367,6 @@ public class SelectParser implements Parser { return andItem; } - @NonNull private CompositeItem buildNotAnd(String key, Inspector value) { NotItem notItem = new NotItem(); @@ -408,7 +375,6 @@ public class SelectParser implements Parser { return notItem; } - @NonNull private CompositeItem buildOr(String key, Inspector value) { OrItem orItem = new OrItem(); @@ -416,7 +382,6 @@ public class SelectParser implements Parser { return orItem; } - @NonNull private CompositeItem buildWeakAnd(String key, Inspector value) { WeakAndItem weakAnd = new WeakAndItem(); @@ -437,7 +402,6 @@ public class SelectParser implements Parser { return weakAnd; } - @NonNull private T leafStyleSettings(Inspector annotations, @NonNull T out) { { @@ -521,9 +485,8 @@ public class SelectParser implements Parser { return out; } - private Integer getCappedRangeSearchParameter(Inspector annotations) { - final Integer[] hitLimit = {null}; + Integer[] hitLimit = {null}; annotations.traverse((ObjectTraverser) (annotation_name, annotation_value) -> { if (HIT_LIMIT.equals(annotation_name)) { if (annotation_value != null) { @@ -531,8 +494,8 @@ public class SelectParser implements Parser { } } }); - final Boolean[] ascending = {null}; - final Boolean[] descending = {null}; + Boolean[] ascending = {null}; + Boolean[] descending = {null}; if (hitLimit[0] != null) { annotations.traverse((ObjectTraverser) (annotation_name, annotation_value) -> { @@ -554,13 +517,12 @@ public class SelectParser implements Parser { return hitLimit[0]; } - @NonNull private Item buildRange(String key, Inspector value) { HashMap children = getChildrenMap(value); Inspector annotations = getAnnotations(value); - final boolean[] equals = {false}; + boolean[] equals = {false}; String field; Inspector boundInspector; @@ -572,8 +534,8 @@ public class SelectParser implements Parser { boundInspector = children.get(0); } - final Number[] bounds = {null, null}; - final String[] operators = {null, null}; + Number[] bounds = {null, null}; + String[] operators = {null, null}; boundInspector.traverse((ObjectTraverser) (operator, bound) -> { if (bound.type() == STRING) { throw new IllegalArgumentException("Expected operator LITERAL, got READ_FIELD."); @@ -625,26 +587,22 @@ public class SelectParser implements Parser { } - @NonNull private IntItem buildLessThanOrEquals(String field, String bound) { return new IntItem("[;" + bound + "]", field); } - @NonNull private IntItem buildGreaterThan(String field, String bound) { return new IntItem(">" + bound, field); } - @NonNull private IntItem buildLessThan(String field, String bound) { return new IntItem("<" + bound, field); } - @NonNull private IntItem instantiateRangeItem(Number lowerBound, Number upperBound, String field, boolean bounds_left_open, boolean bounds_right_open) { Preconditions.checkArgument(lowerBound != null && upperBound != null && field != null, @@ -675,7 +633,6 @@ public class SelectParser implements Parser { return buildRange(key, value); } - @NonNull private Item buildWand(String key, Inspector value) { HashMap annotations = getAnnotationMap(value); @@ -699,7 +656,6 @@ public class SelectParser implements Parser { return fillWeightedSet(value, children, out); } - @NonNull private WeightedSetItem fillWeightedSet(Inspector value, HashMap children, @NonNull WeightedSetItem out) { addItems(children, out); @@ -721,7 +677,6 @@ public class SelectParser implements Parser { } } - private static void addStringItems(HashMap children, WeightedSetItem out) { //{"a":1, "b":2} children.get(1).traverse((ObjectTraverser) (key, value) -> { @@ -732,9 +687,7 @@ public class SelectParser implements Parser { }); } - private static void addLongItems(HashMap children, WeightedSetItem out) { - //[[11,1], [37,2]] children.get(1).traverse((ArrayTraverser) (index, pair) -> { List pairValues = new ArrayList<>(); pair.traverse((ArrayTraverser) (pairIndex, pairValue) -> { @@ -746,7 +699,6 @@ public class SelectParser implements Parser { }); } - @NonNull private Item buildRegExpSearch(String key, Inspector value) { assertHasOperator(key, MATCHES); @@ -757,7 +709,6 @@ public class SelectParser implements Parser { return leafStyleSettings(getAnnotations(value), regExp); } - @NonNull private Item buildWeightedSet(String key, Inspector value) { HashMap children = getChildrenMap(value); @@ -766,7 +717,6 @@ public class SelectParser implements Parser { return fillWeightedSet(value, children, new WeightedSetItem(field)); } - @NonNull private Item buildDotProduct(String key, Inspector value) { HashMap children = getChildrenMap(value); @@ -775,7 +725,6 @@ public class SelectParser implements Parser { return fillWeightedSet(value, children, new DotProductItem(field)); } - @NonNull private Item buildPredicate(String key, Inspector value) { HashMap children = getChildrenMap(value); @@ -805,7 +754,6 @@ public class SelectParser implements Parser { return leafStyleSettings(getAnnotations(value), item); } - @NonNull private CompositeItem buildRank(String key, Inspector value) { RankItem rankItem = new RankItem(); @@ -813,7 +761,6 @@ public class SelectParser implements Parser { return rankItem; } - @NonNull private Item buildTermSearch(String key, Inspector value) { HashMap children = getChildrenMap(value); @@ -822,7 +769,6 @@ public class SelectParser implements Parser { return instantiateLeafItem(field, key, value); } - private String getInspectorKey(Inspector inspector){ String[] actualKey = {""}; if (inspector.type() == OBJECT){ @@ -834,7 +780,6 @@ public class SelectParser implements Parser { return actualKey[0]; } - @NonNull private Item instantiateLeafItem(String field, String key, Inspector value) { List possibleLeafFunction = valueListFromInspector(value); @@ -848,7 +793,6 @@ public class SelectParser implements Parser { } } - @NonNull private Item instantiateCompositeLeaf(String field, String key, Inspector value) { switch (key) { @@ -869,14 +813,12 @@ public class SelectParser implements Parser { } } - @NonNull private Item instantiateWordItem(String field, String key, Inspector value) { String wordData = getChildrenMap(value).get(1).asString(); return instantiateWordItem(field, wordData, key, value, false, decideParsingLanguage(value, wordData)); } - @NonNull private Item instantiateWordItem(String field, String rawWord, String key, Inspector value, boolean exactMatch, Language language) { String wordData = rawWord; @@ -919,7 +861,6 @@ public class SelectParser implements Parser { return (Item) leafStyleSettings(getAnnotations(value), wordItem); } - private Language decideParsingLanguage(Inspector value, String wordData) { String languageTag = getAnnotation(USER_INPUT_LANGUAGE, getAnnotationMap(value), String.class, null); @@ -932,13 +873,11 @@ public class SelectParser implements Parser { return Language.ENGLISH; } - private void prepareWord(String field, Inspector value, WordItem wordItem) { wordItem.setIndexName(field); wordStyleSettings(value, wordItem); } - private void wordStyleSettings(Inspector value, WordItem out) { HashMap annotations = getAnnotationMap(value); @@ -947,7 +886,7 @@ public class SelectParser implements Parser { out.setOrigin(origin); } if (annotations != null){ - Boolean usePositionData = Boolean.getBoolean(getAnnotation(USE_POSITION_DATA, annotations, String.class, null)); + Boolean usePositionData = getBoolAnnotation(USE_POSITION_DATA, annotations, null); if (usePositionData != null) { out.setPositionData(usePositionData); } @@ -975,16 +914,15 @@ public class SelectParser implements Parser { } } - private Substring getOrigin(Inspector annotations) { if (annotations != null) { Inspector origin = getAnnotationAsInspectorOrNull(ORIGIN, getAnnotationMapFromAnnotationInspector(annotations)); if (origin == null) { return null; } - final String[] original = {null}; - final Integer[] offset = {null}; - final Integer[] length = {null}; + String[] original = {null}; + Integer[] offset = {null}; + Integer[] length = {null}; origin.traverse((ObjectTraverser) (key, value) -> { switch (key) { @@ -1020,25 +958,23 @@ public class SelectParser implements Parser { return sameElement; } - @NonNull private Item instantiatePhraseItem(String field, String key, Inspector value) { assertHasOperator(key, PHRASE); - HashMap annotations = getAnnotationMap(value); PhraseItem phrase = new PhraseItem(); phrase.setIndexName(field); HashMap children = getChildrenMap(value); - for (Inspector word : children.values()) - if (word.type() == STRING) phrase.addItem(new WordItem(word.asString())); - else if (word.type() == OBJECT && word.field(PHRASE).valid()) { - phrase.addItem(instantiatePhraseItem(field, key, getChildren(word))); - } + for (Inspector word : children.values()) { + if (word.type() == STRING) + phrase.addItem(new WordItem(word.asString())); + else if (word.type() == OBJECT && word.field(PHRASE).valid()) + phrase.addItem(instantiatePhraseItem(field, key, getChildren(word))); + } return leafStyleSettings(getAnnotations(value), phrase); } - @NonNull private Item instantiateNearItem(String field, String key, Inspector value) { assertHasOperator(key, NEAR); @@ -1060,7 +996,6 @@ public class SelectParser implements Parser { return near; } - @NonNull private Item instantiateONearItem(String field, String key, Inspector value) { assertHasOperator(key, ONEAR); @@ -1105,7 +1040,6 @@ public class SelectParser implements Parser { return leafStyleSettings(getAnnotations(value), equiv); } - private Item instantiateWordAlternativesItem(String field, String key, Inspector value) { HashMap children = getChildrenMap(value); Preconditions.checkArgument(children.size() >= 1, "Expected 1 or more arguments, got %s.", children.size()); @@ -1119,7 +1053,6 @@ public class SelectParser implements Parser { return leafStyleSettings(getAnnotations(value), new WordAlternativesItem(field, Boolean.TRUE, null, terms)); } - // Not in use yet @NonNull private String getIndex(String field) { @@ -1128,12 +1061,10 @@ public class SelectParser implements Parser { return field; } - private static void assertHasOperator(String key, String expectedKey) { Preconditions.checkArgument(key.equals(expectedKey), "Expected operator %s, got %s.", expectedKey, key); } - private static IllegalArgumentException newUnexpectedArgumentException(Object actual, Object... expected) { StringBuilder out = new StringBuilder("Expected "); for (int i = 0, len = expected.length; i < len; ++i) { @@ -1148,26 +1079,22 @@ public class SelectParser implements Parser { return new IllegalArgumentException(out.toString()); } - private List valueListFromInspector(Inspector inspector){ List inspectorList = new ArrayList<>(); inspector.traverse((ArrayTraverser) (key, value) -> inspectorList.add(value)); return inspectorList; } - private void connectItems() { for (ConnectedItem entry : connectedItems) { TaggableItem to = identifiedItems.get(entry.toId); Preconditions.checkNotNull(to, "Item '%s' was specified to connect to item with ID %s, which does not " - + "exist in the query.", entry.fromItem, - entry.toId); + + "exist in the query.", entry.fromItem, entry.toId); entry.fromItem.setConnectivity((Item) to, entry.weight); } } - private static final class ConnectedItem { final double weight; @@ -1181,5 +1108,4 @@ public class SelectParser implements Parser { } } - } diff --git a/container-search/src/test/java/com/yahoo/search/handler/test/JSONSearchHandlerTestCase.java b/container-search/src/test/java/com/yahoo/search/handler/test/JSONSearchHandlerTestCase.java index e0fef7fc3b4..fa398efd293 100644 --- a/container-search/src/test/java/com/yahoo/search/handler/test/JSONSearchHandlerTestCase.java +++ b/container-search/src/test/java/com/yahoo/search/handler/test/JSONSearchHandlerTestCase.java @@ -13,6 +13,7 @@ import com.yahoo.search.handler.SearchHandler; import com.yahoo.search.searchchain.config.test.SearchChainConfigurerTestCase; import com.yahoo.slime.Inspector; import com.yahoo.vespa.config.SlimeUtils; +import org.json.JSONArray; import org.json.JSONObject; import org.junit.After; import org.junit.Before; @@ -30,7 +31,11 @@ import static org.hamcrest.CoreMatchers.containsString; import static org.hamcrest.CoreMatchers.is; import static org.junit.Assert.*; - +/** + * Tests submitting the query as JSON. + * + * @author henrhoi + */ public class JSONSearchHandlerTestCase { private static final String testDir = "src/test/java/com/yahoo/search/handler/test/config"; @@ -154,7 +159,7 @@ public class JSONSearchHandlerTestCase { } } - private void testInvalidQueryParam(final RequestHandlerTestDriver testDriver) throws Exception{ + private void testInvalidQueryParam(final RequestHandlerTestDriver testDriver) throws Exception { JSONObject json = new JSONObject(); json.put("query", "status_code:0"); json.put("hits", 20); @@ -167,9 +172,6 @@ public class JSONSearchHandlerTestCase { assertThat(response, containsString("\"code\":" + com.yahoo.container.protect.Error.INVALID_QUERY_PARAMETER.code)); } - - - @Test public void testNormalResultJsonAliasRendering() throws Exception { JSONObject json = new JSONObject(); @@ -178,8 +180,6 @@ public class JSONSearchHandlerTestCase { assertJsonResult(json, driver); } - - @Test public void testNullQuery() throws Exception { JSONObject json = new JSONObject(); @@ -194,8 +194,6 @@ public class JSONSearchHandlerTestCase { "\n", driver.sendRequest(uri, com.yahoo.jdisc.http.HttpRequest.Method.POST, json.toString(), JSON_CONTENT_TYPE).readAll()); } - - @Test public void testWebServiceStatus() throws Exception { JSONObject json = new JSONObject(); @@ -230,7 +228,6 @@ public class JSONSearchHandlerTestCase { assertXmlResult(json, driver); } - @Test public void testNormalResultExplicitDefaultRenderingFullRendererName1() throws Exception { JSONObject json = new JSONObject(); @@ -263,7 +260,6 @@ public class JSONSearchHandlerTestCase { assertPageResult(json, driver); } - private static final String xmlResult = "\n" + "\n" + @@ -273,18 +269,17 @@ public class JSONSearchHandlerTestCase { " \n" + "\n"; - private void assertXmlResult(JSONObject json, RequestHandlerTestDriver driver) throws Exception { + private void assertXmlResult(JSONObject json, RequestHandlerTestDriver driver) { assertOkResult(driver.sendRequest(uri, com.yahoo.jdisc.http.HttpRequest.Method.POST, json.toString(), JSON_CONTENT_TYPE), xmlResult); } - private static final String jsonResult = "{\"root\":{" + "\"id\":\"toplevel\",\"relevance\":1.0,\"fields\":{\"totalCount\":0}," + "\"children\":[" + "{\"id\":\"testHit\",\"relevance\":1.0,\"fields\":{\"uri\":\"testHit\"}}" + "]}}"; - private void assertJsonResult(JSONObject json, RequestHandlerTestDriver driver) throws Exception { + private void assertJsonResult(JSONObject json, RequestHandlerTestDriver driver) { assertOkResult(driver.sendRequest(uri, com.yahoo.jdisc.http.HttpRequest.Method.POST, json.toString(), JSON_CONTENT_TYPE), jsonResult); } @@ -300,7 +295,7 @@ public class JSONSearchHandlerTestCase { "\n" + "\n"; - private void assertTiledResult(JSONObject json, RequestHandlerTestDriver driver) throws Exception { + private void assertTiledResult(JSONObject json, RequestHandlerTestDriver driver) { assertOkResult(driver.sendRequest(uri, com.yahoo.jdisc.http.HttpRequest.Method.POST, json.toString(), JSON_CONTENT_TYPE), tiledResult); } @@ -317,7 +312,7 @@ public class JSONSearchHandlerTestCase { "\n" + "\n"; - private void assertPageResult(JSONObject json, RequestHandlerTestDriver driver) throws Exception { + private void assertPageResult(JSONObject json, RequestHandlerTestDriver driver) { assertOkResult(driver.sendRequest(uri, com.yahoo.jdisc.http.HttpRequest.Method.POST, json.toString(), JSON_CONTENT_TYPE), pageResult); } @@ -338,9 +333,8 @@ public class JSONSearchHandlerTestCase { return new RequestHandlerTestDriver(newSearchHandler); } - @Test - public void testSelectParameter() throws Exception { + public void testSelectParameters() throws Exception { JSONObject json = new JSONObject(); JSONObject select = new JSONObject(); @@ -356,8 +350,6 @@ public class JSONSearchHandlerTestCase { json.put("select", select); - - // Create mapping Inspector inspector = SlimeUtils.jsonToSlime(json.toString().getBytes("utf-8")).get(); Map map = new HashMap<>(); searchHandler.createRequestMapping(inspector, map, ""); @@ -369,7 +361,34 @@ public class JSONSearchHandlerTestCase { assertEquals(grouping.toString(), processedGrouping.toString()); } + @Test + public void testJsonQueryWithSelectWhere() throws Exception { + JSONObject root = new JSONObject(); + JSONObject select = new JSONObject(); + JSONObject where = new JSONObject(); + JSONArray term = new JSONArray(); + term.put("default"); + term.put("bad"); + where.put("contains", term); + select.put("where", where); + root.put("select", select); + + // Run query + String result = driver.sendRequest(uri + "searchChain=echoingQuery", com.yahoo.jdisc.http.HttpRequest.Method.POST, root.toString(), JSON_CONTENT_TYPE).readAll(); + assertEquals("{\"root\":{\"id\":\"toplevel\",\"relevance\":1.0,\"fields\":{\"totalCount\":0},\"children\":[{\"id\":\"Query\",\"relevance\":1.0,\"fields\":{\"query\":\"select * from sources * where default contains \\\"bad\\\";\"}}]}}", + result); + } + @Test + public void testJsonQueryWithYQL() throws Exception { + JSONObject root = new JSONObject(); + root.put("yql", "select * from sources * where default contains 'bad';"); + + // Run query + String result = driver.sendRequest(uri + "searchChain=echoingQuery", com.yahoo.jdisc.http.HttpRequest.Method.POST, root.toString(), JSON_CONTENT_TYPE).readAll(); + assertEquals("{\"root\":{\"id\":\"toplevel\",\"relevance\":1.0,\"fields\":{\"totalCount\":0},\"children\":[{\"id\":\"Query\",\"relevance\":1.0,\"fields\":{\"query\":\"select * from sources * where default contains \\\"bad\\\";\"}}]}}", + result); + } @Test public void testRequestMapping() throws Exception { @@ -468,8 +487,6 @@ public class JSONSearchHandlerTestCase { json.put("nocachewrite", false); json.put("hitcountestimate", true); - - // Create mapping Inspector inspector = SlimeUtils.jsonToSlime(json.toString().getBytes("utf-8")).get(); Map map = new HashMap<>(); @@ -484,9 +501,7 @@ public class JSONSearchHandlerTestCase { "&queryProfile=foo&presentation.bolding=true&model.encoding=json&model.queryString=abc&streaming.selection=none&trace.timestamps=false&collapse.size=2&streaming.priority=10&ranking.matchPhase.diversity.attribute=title" + "&ranking.matchPhase.attribute=title&hits=10&streaming.userid=123&pos.bb=1237123W%3B123218N&model.restrict=_doc%2Cjson%2Cxml&ranking.freshness=0.05&user=123"; - - - final HttpRequest request = HttpRequest.createTestRequest(url, GET); + HttpRequest request = HttpRequest.createTestRequest(url, GET); // Get mapping Map propertyMap = request.propertyMap(); diff --git a/container-search/src/test/java/com/yahoo/search/handler/test/SearchHandlerTestCase.java b/container-search/src/test/java/com/yahoo/search/handler/test/SearchHandlerTestCase.java index 6dcb34ec3e9..5ef13eba2ed 100644 --- a/container-search/src/test/java/com/yahoo/search/handler/test/SearchHandlerTestCase.java +++ b/container-search/src/test/java/com/yahoo/search/handler/test/SearchHandlerTestCase.java @@ -405,6 +405,19 @@ public class SearchHandlerTestCase { } } + /** Referenced from config */ + public static class EchoingQuerySearcher extends Searcher { + + @Override + public Result search(Query query, Execution execution) { + Result result = execution.search(query); + Hit hit = new Hit("Query"); + hit.setField("query", query.yqlRepresentation()); + result.hits().add(hit); + return result; + } + } + /** Referenced from config */ public static class ForwardingHandler extends ThreadedHttpRequestHandler { diff --git a/container-search/src/test/java/com/yahoo/search/handler/test/config/chains.cfg b/container-search/src/test/java/com/yahoo/search/handler/test/config/chains.cfg index 0336e06f54b..9a16c6ed1e7 100644 --- a/container-search/src/test/java/com/yahoo/search/handler/test/config/chains.cfg +++ b/container-search/src/test/java/com/yahoo/search/handler/test/config/chains.cfg @@ -1,4 +1,4 @@ -chains[3] +chains[4] chains[0].id default chains[0].components[1] chains[0].components[0] com.yahoo.search.handler.test.SearchHandlerTestCase$TestSearcher @@ -8,7 +8,13 @@ chains[1].components[0] com.yahoo.search.handler.test.SearchHandlerTestCase$Clas chains[2].id exceptionInPlugin chains[2].components[1] chains[2].components[0] com.yahoo.search.handler.test.SearchHandlerTestCase$ExceptionInPluginSearcher -components[3] +chains[3].id echoingQuery +chains[3].components[2] +chains[3].components[0] com.yahoo.search.yql.MinimalQueryInserter +chains[3].components[1] com.yahoo.search.handler.test.SearchHandlerTestCase$EchoingQuerySearcher +components[5] components[0].id com.yahoo.search.handler.test.SearchHandlerTestCase$TestSearcher components[1].id com.yahoo.search.handler.test.SearchHandlerTestCase$ClassLoadingErrorSearcher components[2].id com.yahoo.search.handler.test.SearchHandlerTestCase$ExceptionInPluginSearcher +components[3].id com.yahoo.search.handler.test.SearchHandlerTestCase$EchoingQuerySearcher +components[4].id com.yahoo.search.yql.MinimalQueryInserter -- cgit v1.2.3