diff options
author | Henrik <henrik.hoiness@online.no> | 2018-08-02 17:55:41 +0200 |
---|---|---|
committer | Henrik <henrik.hoiness@online.no> | 2018-08-02 17:55:41 +0200 |
commit | b91884508dce92a35415de9c5bb85f1b691c69a7 (patch) | |
tree | 6367cf19cdfb1c9795e7dccb61295f6c3a5294fb | |
parent | 6f49b45153e0ff1d49928d063314cca2859750fc (diff) |
Added parsing of Grouping from JSON to String. Now parsing grouping-parameter and setting the query's groupingrequest when parameter is present
5 files changed, 69 insertions, 54 deletions
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 ec747440246..a234b81c1be 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 @@ -1,20 +1,15 @@ // Copyright 2018 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. package com.yahoo.search.query; - -import com.yahoo.document.select.rule.AttributeNode; import com.yahoo.processing.request.CompoundName; import com.yahoo.search.Query; -import com.yahoo.search.Result; -import com.yahoo.search.query.parser.Parsable; +import com.yahoo.search.grouping.GroupingRequest; import com.yahoo.search.query.parser.ParserEnvironment; import com.yahoo.search.query.parser.ParserFactory; import com.yahoo.search.query.profile.types.FieldDescription; import com.yahoo.search.query.profile.types.QueryProfileType; -import com.yahoo.search.result.ErrorMessage; -import com.yahoo.search.yql.YqlParser; +import com.yahoo.search.yql.VespaGroupingStep; -import static com.yahoo.fs4.PacketDumper.PacketType.query; /** @@ -35,6 +30,8 @@ public class Select implements Cloneable { private static Model model; private Query parent; + private String where = ""; + private String grouping = ""; static { argumentType = new QueryProfileType(SELECT); @@ -58,19 +55,18 @@ public class Select implements Cloneable { model = query.getModel(); } - private String where = ""; - private String grouping = ""; - /** returns the query owning this, never null */ public Query getParent() { return parent; } + /** Assigns the query owning this */ public void setParent(Query parent) { if (parent==null) throw new NullPointerException("A query models owner cannot be null"); this.parent = parent; } + public static Select getFrom(Query q) { return (Select) q.properties().get(argumentTypeName); } @@ -80,53 +76,40 @@ public class Select implements Cloneable { model.setQueryString(queryString); } + /** Set the where-clause for the query. Must be a JSON-string. */ - public void setWhere(String where){ + public void setWhere(String where) { this.where = where; - //QueryTree newTree = getParsedQueryTree(); - - //if (newTree != null){ - // parent.getModel().getQueryTree().setRoot(newTree.getRoot()); - //} } - public QueryTree getParsedQueryTree(){ - SelectParser parser = (SelectParser) ParserFactory.newInstance(Query.Type.SELECT, new ParserEnvironment()); - QueryTree newTree = null; - try { - System.out.println(parent.properties().getString(Select.WHERE)); - QueryTree ewTree = parser.parse(Parsable.fromQueryModel(parent.getModel()).setQuery(parent.properties().getString(Select.WHERE))); - System.out.println(ewTree.toString()); - - } catch (RuntimeException e) { - throw new RuntimeException("Could not instantiate query from YQL", e); - } - return newTree; - } - - - - - - - - /** Returns the where-clause in the query */ public String getWhere(){ return this.where; } + /** Set the grouping-string for the query. Must be a JSON-string. */ public void setGrouping(String grouping){ + this.grouping = grouping; + SelectParser parser = (SelectParser) ParserFactory.newInstance(Query.Type.SELECT, new ParserEnvironment()); + + for (VespaGroupingStep step : parser.getGroupingSteps(grouping)) { + GroupingRequest.newInstance(parent) + .setRootOperation(step.getOperation()) + .continuations().addAll(step.continuations()); + } + } + /** Returns the grouping in the query */ public String getGrouping(){ return this.grouping; } + @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 df4d3fb98e3..66beda53804 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 @@ -37,9 +37,11 @@ import com.yahoo.prelude.query.WeakAndItem; import com.yahoo.prelude.query.WeightedSetItem; import com.yahoo.prelude.query.WordAlternativesItem; import com.yahoo.prelude.query.WordItem; +import com.yahoo.search.grouping.request.GroupingOperation; import com.yahoo.search.query.parser.Parsable; import com.yahoo.search.query.parser.Parser; import com.yahoo.search.query.parser.ParserEnvironment; +import com.yahoo.search.yql.VespaGroupingStep; import com.yahoo.slime.ArrayTraverser; import com.yahoo.slime.Inspector; import com.yahoo.slime.ObjectTraverser; @@ -148,12 +150,12 @@ public class SelectParser implements Parser { this.query = query; return buildTree(); - } - public QueryTree buildTree() { - Inspector inspector = SlimeUtils.jsonToSlime(this.query.getSelect().getBytes()).get(); + + private QueryTree buildTree() { + Inspector inspector = SlimeUtils.jsonToSlime(this.query.getSelect().getWhere().getBytes()).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)); } @@ -166,12 +168,13 @@ public class SelectParser implements Parser { } - public Item walkJson(Inspector inspector){ + private Item walkJson(Inspector inspector){ final 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; @@ -204,6 +207,20 @@ public class SelectParser implements Parser { } + public List<VespaGroupingStep> getGroupingSteps(String grouping){ + List<VespaGroupingStep> groupingSteps = new ArrayList<>(); + GroupingOperation groupingOperation = GroupingOperation.fromString(transformGrouping(grouping)); + VespaGroupingStep groupingStep = new VespaGroupingStep(groupingOperation); + groupingSteps.add(groupingStep); + return groupingSteps; + } + + private String transformGrouping(String grouping){ + String groupingString = grouping.replace(" ", "").replace("\"", "").replace("\'", "").replace(":{", "(").replace(":", "(").replace("}", ")").replace(",", ")"); + return groupingString.substring(2, groupingString.length()-1); + } + + @NonNull private Item buildFunctionCall(String key, Inspector value) { switch (key) { diff --git a/container-search/src/main/java/com/yahoo/search/query/parser/Parsable.java b/container-search/src/main/java/com/yahoo/search/query/parser/Parsable.java index 4802e627f4d..64fb201fe21 100644 --- a/container-search/src/main/java/com/yahoo/search/query/parser/Parsable.java +++ b/container-search/src/main/java/com/yahoo/search/query/parser/Parsable.java @@ -37,7 +37,7 @@ public final class Parsable { private String defaultIndexName; private Language language; // TODO: Initialize to UNKNOWN private Optional<Language> explicitLanguage = Optional.empty(); - private String where; + private Select select; /** If this is set it will be used to determine the language, if not set explicitly */ private Optional<Model> model = Optional.empty(); @@ -136,12 +136,12 @@ public final class Parsable { } public Parsable setSelect(Select select){ - this.where = select.getWhere(); + this.select = select; return this; } - public String getSelect(){ - return this.where; + public Select getSelect(){ + return this.select; } public static Parsable fromQueryModel(Model model) { diff --git a/container-search/src/main/java/com/yahoo/search/yql/YqlParser.java b/container-search/src/main/java/com/yahoo/search/yql/YqlParser.java index 6bad032600c..e0e9042e1a3 100644 --- a/container-search/src/main/java/com/yahoo/search/yql/YqlParser.java +++ b/container-search/src/main/java/com/yahoo/search/yql/YqlParser.java @@ -789,7 +789,7 @@ public class YqlParser implements Parser { OperatorNode<ExpressionOperator> groupingAst = ast.<List<OperatorNode<ExpressionOperator>>> getArgument(2).get(0); GroupingOperation groupingOperation = GroupingOperation.fromString(groupingAst.<String> getArgument(0)); VespaGroupingStep groupingStep = new VespaGroupingStep(groupingOperation); - List<String> continuations = getAnnotation(groupingAst, "continuations", List.class, + List<String> continuations = getAnnotation(groupingAst, "continuations", List.class, Collections.emptyList(), "grouping continuations"); for (String continuation : continuations) { groupingStep.continuations().add(Continuation.fromString(continuation)); diff --git a/container-search/src/test/java/com/yahoo/select/SelectParserTestCase.java b/container-search/src/test/java/com/yahoo/select/SelectParserTestCase.java index 78a52acbedf..46a66c904bf 100644 --- a/container-search/src/test/java/com/yahoo/select/SelectParserTestCase.java +++ b/container-search/src/test/java/com/yahoo/select/SelectParserTestCase.java @@ -19,9 +19,12 @@ import com.yahoo.search.query.Select; import com.yahoo.search.query.SelectParser; import com.yahoo.search.query.parser.Parsable; import com.yahoo.search.query.parser.ParserEnvironment; +import com.yahoo.search.yql.VespaGroupingStep; import org.json.JSONException; import org.json.JSONObject; import org.junit.Test; + +import java.util.ArrayList; import java.util.Arrays; import java.util.List; @@ -43,6 +46,8 @@ public class SelectParserTestCase { private final SelectParser parser = new SelectParser(new ParserEnvironment()); + /** WHERE TESTS */ + @Test public void test_contains() throws Exception { JSONObject json = new JSONObject(); @@ -632,12 +637,14 @@ public class SelectParserTestCase { checkWordAlternativesContent(alternatives); } + /** GROUPING TESTS */ - - - - - + @Test + public void testGrouping(){ + String grouping = "[ { \"all\" : { \"group\" : \"time.year(a)\", \"each\" : { \"output\" : \"count()\" } } } ]"; + String expected = "[[]all(group(time.year(a)) each(output(count())))]"; + assertGrouping(expected, parseGrouping(grouping)); + } @@ -664,6 +671,15 @@ public class SelectParserTestCase { assertEquals(expectedRootClass, parseWhere(where).getRoot().getClass()); } + private void assertGrouping(String expected, List<VespaGroupingStep> steps) { + List<String> actual = new ArrayList<>(steps.size()); + for (VespaGroupingStep step : steps) { + actual.add(step.continuations().toString() + + step.getOperation()); + } + assertEquals(expected, actual.toString()); + } + @@ -675,10 +691,9 @@ public class SelectParserTestCase { return parser.parse(new Parsable().setSelect(select)); } - private QueryTree parseGrouping(String grouping) { - Select select = new Select("", grouping); + private List<VespaGroupingStep> parseGrouping(String grouping) { - return parser.parse(new Parsable().setSelect(select)); + return parser.getGroupingSteps(grouping); } private QueryTree parse(String where, String grouping) { |