diff options
author | Henning Baldersheim <balder@yahoo-inc.com> | 2019-06-28 13:54:27 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2019-06-28 13:54:27 +0200 |
commit | a71b139ba48f64787d1a37aae636f76b0f0bc550 (patch) | |
tree | 80d711fb3f226f28b04a07481edb47b6fa19d885 /container-search | |
parent | b1f7cfdf97851cdd20c0a00ee26fae0264ea77c2 (diff) | |
parent | e1010883fb684c1e941cf2d49778c86e179ecb9e (diff) |
Merge pull request #9918 from vespa-engine/balder/collapse-single-child-under-sameElement
A single element under sameElement operator can be pulled out to avoi…
Diffstat (limited to 'container-search')
9 files changed, 60 insertions, 11 deletions
diff --git a/container-search/abi-spec.json b/container-search/abi-spec.json index 8f9dc33e944..cc06710480d 100644 --- a/container-search/abi-spec.json +++ b/container-search/abi-spec.json @@ -436,6 +436,7 @@ "public void lock()", "public boolean isLocked()", "public int getTermCount()", + "public java.util.Optional extractSingleChild()", "public bridge synthetic com.yahoo.prelude.query.Item clone()", "public bridge synthetic java.lang.Object clone()" ], @@ -854,7 +855,8 @@ "abstract" ], "methods": [ - "public void <init>()" + "public void <init>()", + "public java.util.Optional extractSingleChild()" ], "fields": [] }, @@ -944,6 +946,7 @@ "public void addItem(com.yahoo.prelude.query.Item)", "public void addItem(int, com.yahoo.prelude.query.Item)", "public com.yahoo.prelude.query.Item setItem(int, com.yahoo.prelude.query.Item)", + "public java.util.Optional extractSingleChild()", "public com.yahoo.prelude.query.WordItem getWordItem(int)", "public com.yahoo.prelude.query.BlockItem getBlockItem(int)", "protected void encodeThis(java.nio.ByteBuffer)", @@ -974,6 +977,7 @@ "public void setIndexName(java.lang.String)", "public void setWeight(int)", "public void addItem(com.yahoo.prelude.query.Item)", + "public java.util.Optional extractSingleChild()", "public com.yahoo.prelude.query.WordItem getWordItem(int)", "protected void encodeThis(java.nio.ByteBuffer)", "public int encode(java.nio.ByteBuffer)", @@ -1239,6 +1243,7 @@ "protected void appendHeadingString(java.lang.StringBuilder)", "protected void appendBodyString(java.lang.StringBuilder)", "protected void adding(com.yahoo.prelude.query.Item)", + "public java.util.Optional extractSingleChild()", "public com.yahoo.prelude.query.Item$ItemType getItemType()", "public java.lang.String getName()", "public java.lang.String getFieldName()" diff --git a/container-search/src/main/java/com/yahoo/prelude/query/CompositeItem.java b/container-search/src/main/java/com/yahoo/prelude/query/CompositeItem.java index 907eabe60ce..64f759dcf9c 100644 --- a/container-search/src/main/java/com/yahoo/prelude/query/CompositeItem.java +++ b/container-search/src/main/java/com/yahoo/prelude/query/CompositeItem.java @@ -13,6 +13,7 @@ import java.util.Collections; import java.util.Iterator; import java.util.List; import java.util.ListIterator; +import java.util.Optional; /** @@ -379,4 +380,13 @@ public abstract class CompositeItem extends Item { return terms; } + /** + * Will return its single child if itself can safely be omitted. + * + * @return a valid Item or empty Optional if it can not be done + */ + public Optional<Item> extractSingleChild() { + return getItemCount() == 1 ? Optional.of(getItem(0)) : Optional.empty(); + } + } diff --git a/container-search/src/main/java/com/yahoo/prelude/query/NonReducibleCompositeItem.java b/container-search/src/main/java/com/yahoo/prelude/query/NonReducibleCompositeItem.java index 84aa177369a..97d724953ea 100644 --- a/container-search/src/main/java/com/yahoo/prelude/query/NonReducibleCompositeItem.java +++ b/container-search/src/main/java/com/yahoo/prelude/query/NonReducibleCompositeItem.java @@ -1,6 +1,8 @@ // Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. package com.yahoo.prelude.query; +import java.util.Optional; + /** * A composite item which specifies semantics which are not maintained * if an instance with a single child is replaced by the single child. @@ -12,4 +14,8 @@ package com.yahoo.prelude.query; * @author bratseth */ public abstract class NonReducibleCompositeItem extends CompositeItem { + @Override + public Optional<Item> extractSingleChild() { + return Optional.empty(); + } } diff --git a/container-search/src/main/java/com/yahoo/prelude/query/PhraseItem.java b/container-search/src/main/java/com/yahoo/prelude/query/PhraseItem.java index 26da5eec7eb..4de0af1f408 100644 --- a/container-search/src/main/java/com/yahoo/prelude/query/PhraseItem.java +++ b/container-search/src/main/java/com/yahoo/prelude/query/PhraseItem.java @@ -5,6 +5,7 @@ import com.yahoo.prelude.query.textualrepresentation.Discloser; import java.nio.ByteBuffer; import java.util.Iterator; +import java.util.Optional; /** * A term which contains a phrase - a collection of word terms @@ -127,6 +128,13 @@ public class PhraseItem extends CompositeIndexedItem { } } + @Override + public Optional<Item> extractSingleChild() { + Optional<Item> extracted = super.extractSingleChild(); + extracted.ifPresent(e -> e.setWeight(this.getWeight())); + return extracted; + } + private void addIndexedItem(IndexedItem word) { word.setIndexName(this.getIndexName()); super.addItem((Item) word); diff --git a/container-search/src/main/java/com/yahoo/prelude/query/PhraseSegmentItem.java b/container-search/src/main/java/com/yahoo/prelude/query/PhraseSegmentItem.java index a19a6e53963..53a57a968f5 100644 --- a/container-search/src/main/java/com/yahoo/prelude/query/PhraseSegmentItem.java +++ b/container-search/src/main/java/com/yahoo/prelude/query/PhraseSegmentItem.java @@ -5,6 +5,7 @@ import com.yahoo.prelude.query.textualrepresentation.Discloser; import java.nio.ByteBuffer; import java.util.Iterator; +import java.util.Optional; /** @@ -55,10 +56,12 @@ public class PhraseSegmentItem extends IndexedSegmentItem { super(rawWord, current, isFromQuery, stemmed, substring); } + @Override public ItemType getItemType() { return ItemType.PHRASE; } + @Override public String getName() { return "SPHRASE"; } @@ -87,6 +90,7 @@ public class PhraseSegmentItem extends IndexedSegmentItem { * * @throws IllegalArgumentException if the given item is not a WordItem or PhraseItem */ + @Override public void addItem(Item item) { if (item instanceof WordItem) { addWordItem((WordItem) item); @@ -95,6 +99,13 @@ public class PhraseSegmentItem extends IndexedSegmentItem { } } + @Override + public Optional<Item> extractSingleChild() { + Optional<Item> extracted = super.extractSingleChild(); + extracted.ifPresent(e -> e.setWeight(this.getWeight())); + return extracted; + } + private void addWordItem(WordItem word) { word.setIndexName(this.getIndexName()); super.addItem(word); diff --git a/container-search/src/main/java/com/yahoo/prelude/query/QueryCanonicalizer.java b/container-search/src/main/java/com/yahoo/prelude/query/QueryCanonicalizer.java index 31e69e5b7cd..88bae76b26d 100644 --- a/container-search/src/main/java/com/yahoo/prelude/query/QueryCanonicalizer.java +++ b/container-search/src/main/java/com/yahoo/prelude/query/QueryCanonicalizer.java @@ -4,7 +4,10 @@ package com.yahoo.prelude.query; import com.yahoo.search.Query; import com.yahoo.search.query.QueryTree; -import java.util.*; +import java.util.HashSet; +import java.util.ListIterator; +import java.util.Optional; +import java.util.Set; /** * Query normalizer and sanity checker. @@ -82,15 +85,11 @@ public class QueryCanonicalizer { if (composite.getItemCount() == 0) parentIterator.remove(); - if (composite.getItemCount() == 1 && ! (composite instanceof NonReducibleCompositeItem)) { - if (composite instanceof PhraseItem || composite instanceof PhraseSegmentItem) - composite.getItem(0).setWeight(composite.getWeight()); - parentIterator.set(composite.getItem(0)); - } + composite.extractSingleChild().ifPresent(extractedChild -> parentIterator.set(extractedChild)); return CanonicalizationResult.success(); } - + private static void collapseLevels(CompositeItem composite) { if (composite instanceof RankItem || composite instanceof NotItem) { collapseLevels(composite, composite.getItemIterator()); // collapse the first item only diff --git a/container-search/src/main/java/com/yahoo/prelude/query/SameElementItem.java b/container-search/src/main/java/com/yahoo/prelude/query/SameElementItem.java index aa446140da0..d2c19339298 100644 --- a/container-search/src/main/java/com/yahoo/prelude/query/SameElementItem.java +++ b/container-search/src/main/java/com/yahoo/prelude/query/SameElementItem.java @@ -6,6 +6,7 @@ import com.yahoo.protect.Validator; import java.nio.ByteBuffer; import java.util.Iterator; +import java.util.Optional; /** * This represents a query where all terms are required to match in the same element id. @@ -54,6 +55,16 @@ public class SameElementItem extends NonReducibleCompositeItem { Validator.ensureNonEmpty("Struct fieldname", asTerm.getIndexName()); Validator.ensureNonEmpty("Query term", asTerm.getIndexedString()); } + + @Override + public Optional<Item> extractSingleChild() { + if (getItemCount() == 1) { + WordItem child = (WordItem) getItem(0); + child.setIndexName(getFieldName() + "." + child.getIndexName()); + return Optional.of(child); + } + return Optional.empty(); + } @Override public ItemType getItemType() { diff --git a/container-search/src/main/java/com/yahoo/prelude/querytransform/QueryRewrite.java b/container-search/src/main/java/com/yahoo/prelude/querytransform/QueryRewrite.java index 2d941681f2a..84c793a6df1 100644 --- a/container-search/src/main/java/com/yahoo/prelude/querytransform/QueryRewrite.java +++ b/container-search/src/main/java/com/yahoo/prelude/querytransform/QueryRewrite.java @@ -6,7 +6,6 @@ import com.yahoo.prelude.query.CompositeItem; import com.yahoo.prelude.query.EquivItem; import com.yahoo.prelude.query.Item; import com.yahoo.prelude.query.NearItem; -import com.yahoo.prelude.query.NonReducibleCompositeItem; import com.yahoo.prelude.query.NotItem; import com.yahoo.prelude.query.NullItem; import com.yahoo.prelude.query.OrItem; @@ -215,7 +214,7 @@ public class QueryRewrite { parent.setItem(i, newChild); } } - return ((numChildren == 1) && !(parent instanceof NonReducibleCompositeItem)) ? parent.getItem(0) : item; + return parent.extractSingleChild().orElse(item); } private static Item rewriteSddocname(Item item) { diff --git a/container-search/src/test/java/com/yahoo/search/yql/YqlParserTestCase.java b/container-search/src/test/java/com/yahoo/search/yql/YqlParserTestCase.java index 70d50b23bed..00a17f963c6 100644 --- a/container-search/src/test/java/com/yahoo/search/yql/YqlParserTestCase.java +++ b/container-search/src/test/java/com/yahoo/search/yql/YqlParserTestCase.java @@ -303,7 +303,7 @@ public class YqlParserTestCase { assertCanonicalParse("select foo from bar where baz contains sameElement(key contains \"a\", value.f2 = 10);", "baz:{key:a value.f2:10}"); assertCanonicalParse("select foo from bar where baz contains sameElement(key contains \"a\");", - "baz:{key:a}"); + "baz.key:a"); } @Test |