summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJon Bratseth <bratseth@oath.com>2019-01-09 15:28:33 +0100
committerJon Bratseth <bratseth@oath.com>2019-01-09 15:28:33 +0100
commitf2b63fe7c6bb414645bcb41fb6e91a11efd68e17 (patch)
tree078cef621edf91f4f7ffa7a5e88d9f0e30e01cd4
parent3187143c1b774684b5668fecd665a4452003ca32 (diff)
Parse USE_POSITION_DATA correctly
-rw-r--r--container-search/src/main/java/com/yahoo/prelude/query/textualrepresentation/Discloser.java2
-rw-r--r--container-search/src/main/java/com/yahoo/prelude/query/textualrepresentation/TextualQueryRepresentation.java4
-rw-r--r--container-search/src/main/java/com/yahoo/search/Query.java6
-rw-r--r--container-search/src/main/java/com/yahoo/search/handler/SearchHandler.java5
-rw-r--r--container-search/src/main/java/com/yahoo/search/query/Select.java4
-rw-r--r--container-search/src/main/java/com/yahoo/search/query/SelectParser.java130
-rw-r--r--container-search/src/test/java/com/yahoo/search/handler/test/JSONSearchHandlerTestCase.java65
-rw-r--r--container-search/src/test/java/com/yahoo/search/handler/test/SearchHandlerTestCase.java13
-rw-r--r--container-search/src/test/java/com/yahoo/search/handler/test/config/chains.cfg10
-rw-r--r--jdisc_core/src/main/java/com/yahoo/jdisc/Request.java2
10 files changed, 101 insertions, 140 deletions
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<Item, Integer> 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<String, String> 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<GroupingRequest> 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<Integer, TaggableItem> identifiedItems = LazyMap.newHashMap();
private final List<ConnectedItem> 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<String> 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<VespaGroupingStep> getGroupingSteps(String grouping){
List<VespaGroupingStep> groupingSteps = new ArrayList<>();
List<String> 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<Integer, Inspector> getChildrenMap(Inspector inspector){
HashMap<Integer, Inspector> 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<String, Inspector> getAnnotationMapFromAnnotationInspector(Inspector annotation){
HashMap<String, Inspector> attributes = new HashMap<>();
if (annotation.type() == OBJECT){
@@ -336,7 +311,6 @@ public class SelectParser implements Parser {
return attributes;
}
-
private HashMap<String, Inspector> getAnnotationMap(Inspector inspector){
HashMap<String, Inspector> attributes = new HashMap<>();
if (inspector.type() == OBJECT && inspector.field("attributes").valid()){
@@ -347,12 +321,10 @@ public class SelectParser implements Parser {
return attributes;
}
-
private <T> T getAnnotation(String annotationName, HashMap<String, Inspector> annotations, Class<T> expectedClass, T defaultValue) {
return (annotations.get(annotationName) == null) ? defaultValue : expectedClass.cast(annotations.get(annotationName).asString());
}
-
private Boolean getBoolAnnotation(String annotationName, HashMap<String, Inspector> 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<String, Inspector> 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<String, Inspector> 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<String, Inspector> 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 extends TaggableItem> 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<Integer, Inspector> 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<String, Inspector> annotations = getAnnotationMap(value);
@@ -699,7 +656,6 @@ public class SelectParser implements Parser {
return fillWeightedSet(value, children, out);
}
-
@NonNull
private WeightedSetItem fillWeightedSet(Inspector value, HashMap<Integer, Inspector> children, @NonNull WeightedSetItem out) {
addItems(children, out);
@@ -721,7 +677,6 @@ public class SelectParser implements Parser {
}
}
-
private static void addStringItems(HashMap<Integer, Inspector> 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<Integer, Inspector> children, WeightedSetItem out) {
- //[[11,1], [37,2]]
children.get(1).traverse((ArrayTraverser) (index, pair) -> {
List<Integer> 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<Integer, Inspector> 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<Integer, Inspector> 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<Integer, Inspector> 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<Integer, Inspector> 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<Inspector> 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<String, Inspector> 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<String, Inspector> annotations = getAnnotationMap(value);
PhraseItem phrase = new PhraseItem();
phrase.setIndexName(field);
HashMap<Integer, Inspector> 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<Integer, Inspector> 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<Inspector> valueListFromInspector(Inspector inspector){
List<Inspector> 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 {
"</result>\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 =
"<?xml version=\"1.0\" encoding=\"utf-8\" ?>\n" +
"<result total-hit-count=\"0\">\n" +
@@ -273,18 +269,17 @@ public class JSONSearchHandlerTestCase {
" </hit>\n" +
"</result>\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" +
"</result>\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" +
"</page>\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<String, String> 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<String, String> 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<String, String> 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
@@ -406,6 +406,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 {
private final SearchHandler searchHandler;
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
diff --git a/jdisc_core/src/main/java/com/yahoo/jdisc/Request.java b/jdisc_core/src/main/java/com/yahoo/jdisc/Request.java
index 65aafee0060..2a1967abd13 100644
--- a/jdisc_core/src/main/java/com/yahoo/jdisc/Request.java
+++ b/jdisc_core/src/main/java/com/yahoo/jdisc/Request.java
@@ -389,7 +389,7 @@ public class Request extends AbstractResource {
* @throws BindingNotFoundException If the corresponding call to {@link Container#resolveHandler(Request)} returns
* null.
*/
- public ContentChannel connect(final ResponseHandler responseHandler) {
+ public ContentChannel connect(ResponseHandler responseHandler) {
try {
Objects.requireNonNull(responseHandler, "responseHandler");
RequestHandler requestHandler = container().resolveHandler(this);