summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--config-model/src/main/java/com/yahoo/searchdefinition/derived/AttributeFields.java48
-rw-r--r--config-model/src/main/java/com/yahoo/searchdefinition/document/Attribute.java7
-rw-r--r--config-model/src/test/derived/array_of_struct_attribute/attributes.cfg40
-rw-r--r--config-model/src/test/derived/array_of_struct_attribute/summary.cfg11
-rw-r--r--config-model/src/test/derived/array_of_struct_attribute/summarymap.cfg7
-rw-r--r--config-model/src/test/derived/array_of_struct_attribute/test.sd17
-rw-r--r--config-model/src/test/java/com/yahoo/searchdefinition/AttributeSettingsTestCase.java48
-rw-r--r--config-model/src/test/java/com/yahoo/searchdefinition/derived/AttributeListTestCase.java33
-rw-r--r--config-model/src/test/java/com/yahoo/searchdefinition/derived/ExportingTestCase.java5
-rw-r--r--container-search/src/main/java/com/yahoo/prelude/query/SameElementItem.java42
-rw-r--r--container-search/src/main/java/com/yahoo/prelude/query/WeakAndItem.java13
-rw-r--r--container-search/src/main/java/com/yahoo/search/yql/VespaSerializer.java22
-rw-r--r--container-search/src/main/java/com/yahoo/search/yql/YqlParser.java2
-rw-r--r--container-search/src/test/java/com/yahoo/prelude/query/test/SameElementItemTestCase.java13
-rw-r--r--node-repository/src/main/java/com/yahoo/vespa/hosted/provision/maintenance/NodeRepositoryMaintenance.java8
-rw-r--r--searchcore/src/tests/proton/documentdb/feedhandler/feedhandler_test.cpp50
-rw-r--r--searchcore/src/tests/proton/matching/query_test.cpp71
-rw-r--r--searchcore/src/tests/proton/matching/querynodes_test.cpp21
-rw-r--r--searchcore/src/vespa/searchcore/proton/feedoperation/putoperation.cpp9
-rw-r--r--searchcore/src/vespa/searchcore/proton/feedoperation/putoperation.h1
-rw-r--r--searchcore/src/vespa/searchcore/proton/feedoperation/updateoperation.cpp40
-rw-r--r--searchcore/src/vespa/searchcore/proton/feedoperation/updateoperation.h8
-rw-r--r--searchcore/src/vespa/searchcore/proton/matching/blueprintbuilder.cpp54
-rw-r--r--searchcore/src/vespa/searchcore/proton/matching/matchdatareservevisitor.h3
-rw-r--r--searchcore/src/vespa/searchcore/proton/matching/query.cpp4
-rw-r--r--searchcore/src/vespa/searchcore/proton/matching/querynodes.cpp8
-rw-r--r--searchcore/src/vespa/searchcore/proton/matching/querynodes.h18
-rw-r--r--searchcore/src/vespa/searchcore/proton/matching/termdatafromnode.cpp53
-rw-r--r--searchcore/src/vespa/searchcore/proton/matching/termdatafromnode.h7
-rw-r--r--searchcore/src/vespa/searchcore/proton/server/feedhandler.cpp37
-rw-r--r--searchcore/src/vespa/searchcore/proton/server/feedhandler.h8
-rw-r--r--searchcorespi/src/vespa/searchcorespi/index/indexcollection.cpp46
-rw-r--r--searchlib/src/tests/query/customtypevisitor_test.cpp51
-rw-r--r--searchlib/src/tests/query/query_visitor_test.cpp74
-rw-r--r--searchlib/src/tests/query/querybuilder_test.cpp86
-rw-r--r--searchlib/src/tests/stackdumpiterator/stackdumpiteratortest.cpp1
-rw-r--r--searchlib/src/vespa/searchlib/features/distancetopathfeature.cpp10
-rw-r--r--searchlib/src/vespa/searchlib/features/distancetopathfeature.h9
-rw-r--r--searchlib/src/vespa/searchlib/parsequery/parse.cpp31
-rw-r--r--searchlib/src/vespa/searchlib/parsequery/parse.h2
-rw-r--r--searchlib/src/vespa/searchlib/parsequery/simplequerystack.cpp156
-rw-r--r--searchlib/src/vespa/searchlib/parsequery/stackdumpiterator.cpp18
-rw-r--r--searchlib/src/vespa/searchlib/query/query.cpp3
-rw-r--r--searchlib/src/vespa/searchlib/query/querynode.cpp1
-rw-r--r--searchlib/src/vespa/searchlib/query/tree/customtypetermvisitor.h7
-rw-r--r--searchlib/src/vespa/searchlib/query/tree/customtypevisitor.h9
-rw-r--r--searchlib/src/vespa/searchlib/query/tree/intermediate.cpp6
-rw-r--r--searchlib/src/vespa/searchlib/query/tree/intermediate.h9
-rw-r--r--searchlib/src/vespa/searchlib/query/tree/intermediatenodes.cpp46
-rw-r--r--searchlib/src/vespa/searchlib/query/tree/intermediatenodes.h17
-rw-r--r--searchlib/src/vespa/searchlib/query/tree/location.cpp6
-rw-r--r--searchlib/src/vespa/searchlib/query/tree/location.h11
-rw-r--r--searchlib/src/vespa/searchlib/query/tree/point.h9
-rw-r--r--searchlib/src/vespa/searchlib/query/tree/predicate_query_term.h7
-rw-r--r--searchlib/src/vespa/searchlib/query/tree/querybuilder.h19
-rw-r--r--searchlib/src/vespa/searchlib/query/tree/querynodemixin.h9
-rw-r--r--searchlib/src/vespa/searchlib/query/tree/queryreplicator.h20
-rw-r--r--searchlib/src/vespa/searchlib/query/tree/querytreecreator.h7
-rw-r--r--searchlib/src/vespa/searchlib/query/tree/queryvisitor.h8
-rw-r--r--searchlib/src/vespa/searchlib/query/tree/range.cpp6
-rw-r--r--searchlib/src/vespa/searchlib/query/tree/range.h11
-rw-r--r--searchlib/src/vespa/searchlib/query/tree/rectangle.h6
-rw-r--r--searchlib/src/vespa/searchlib/query/tree/simplequery.h12
-rw-r--r--searchlib/src/vespa/searchlib/query/tree/stackdumpcreator.cpp63
-rw-r--r--searchlib/src/vespa/searchlib/query/tree/stackdumpcreator.h7
-rw-r--r--searchlib/src/vespa/searchlib/query/tree/stackdumpquerycreator.h11
-rw-r--r--searchlib/src/vespa/searchlib/query/tree/templatetermvisitor.h6
-rw-r--r--searchlib/src/vespa/searchlib/query/tree/term.cpp19
-rw-r--r--searchlib/src/vespa/searchlib/query/tree/term.h36
-rw-r--r--searchlib/src/vespa/searchlib/query/tree/termnodes.cpp22
-rw-r--r--searchlib/src/vespa/searchlib/query/tree/termnodes.h7
-rw-r--r--searchlib/src/vespa/searchlib/query/weight.h6
-rw-r--r--searchlib/src/vespa/searchlib/queryeval/create_blueprint_visitor_helper.cpp14
-rw-r--r--searchlib/src/vespa/searchlib/queryeval/create_blueprint_visitor_helper.h57
-rw-r--r--searchlib/src/vespa/searchlib/queryeval/get_weight_from_node.cpp3
-rw-r--r--searchlib/src/vespa/searchlib/queryeval/termasstring.cpp2
-rw-r--r--searchsummary/src/tests/extractkeywords/extractkeywordstest.cpp8
-rw-r--r--searchsummary/src/vespa/searchsummary/docsummary/dynamicteaserdfw.cpp1
-rw-r--r--searchsummary/src/vespa/searchsummary/docsummary/keywordextractor.cpp2
-rw-r--r--valgrind-suppressions.txt8
80 files changed, 999 insertions, 694 deletions
diff --git a/config-model/src/main/java/com/yahoo/searchdefinition/derived/AttributeFields.java b/config-model/src/main/java/com/yahoo/searchdefinition/derived/AttributeFields.java
index 72ba6de7022..c7ca1a33ff2 100644
--- a/config-model/src/main/java/com/yahoo/searchdefinition/derived/AttributeFields.java
+++ b/config-model/src/main/java/com/yahoo/searchdefinition/derived/AttributeFields.java
@@ -2,8 +2,11 @@
package com.yahoo.searchdefinition.derived;
import com.yahoo.config.subscription.ConfigInstanceUtil;
+import com.yahoo.document.ArrayDataType;
import com.yahoo.document.DataType;
+import com.yahoo.document.Field;
import com.yahoo.document.PositionDataType;
+import com.yahoo.document.StructDataType;
import com.yahoo.searchdefinition.Search;
import com.yahoo.searchdefinition.document.Attribute;
import com.yahoo.searchdefinition.document.ImmutableSDField;
@@ -41,18 +44,53 @@ public class AttributeFields extends Derived implements AttributesConfig.Produce
/** Derives everything from a field */
@Override
protected void derive(ImmutableSDField field, Search search) {
+ boolean fieldIsArrayOfSimpleStruct = isArrayOfSimpleStruct(field);
if (field.usesStructOrMap() &&
+ !fieldIsArrayOfSimpleStruct &&
!field.getDataType().equals(PositionDataType.INSTANCE) &&
!field.getDataType().equals(DataType.getArray(PositionDataType.INSTANCE))) {
return; // Ignore struct fields for indexed search (only implemented for streaming search)
}
if (field.isImportedField()) {
deriveImportedAttributes(field);
+ } else if (fieldIsArrayOfSimpleStruct) {
+ deriveArrayOfSimpleStruct(field);
} else {
deriveAttributes(field);
}
}
+ private static boolean isArrayOfSimpleStruct(ImmutableSDField field) {
+ DataType fieldType = field.getDataType();
+ if (fieldType instanceof ArrayDataType) {
+ ArrayDataType arrayType = (ArrayDataType)fieldType;
+ DataType nestedType = arrayType.getNestedType();
+ if (nestedType instanceof StructDataType &&
+ !(nestedType.equals(PositionDataType.INSTANCE))) {
+ StructDataType structType = (StructDataType)nestedType;
+ for (Field innerField : structType.getFields()) {
+ if (!isPrimitiveType(innerField.getDataType())) {
+ return false;
+ }
+ }
+ return true;
+ } else {
+ return false;
+ }
+ } else {
+ return false;
+ }
+ }
+
+ private static boolean isPrimitiveType(DataType dataType) {
+ return dataType.equals(DataType.BYTE) ||
+ dataType.equals(DataType.INT) ||
+ dataType.equals(DataType.LONG) ||
+ dataType.equals(DataType.FLOAT) ||
+ dataType.equals(DataType.DOUBLE) ||
+ dataType.equals(DataType.STRING);
+ }
+
/** Returns an attribute by name, or null if it doesn't exist */
public Attribute getAttribute(String attributeName) {
return attributes.get(attributeName);
@@ -98,6 +136,16 @@ public class AttributeFields extends Derived implements AttributesConfig.Produce
}
}
+ private void deriveArrayOfSimpleStruct(ImmutableSDField field) {
+ for (ImmutableSDField structField : field.getStructFields()) {
+ for (Attribute attribute : structField.getAttributes().values()) {
+ if (structField.getName().equals(attribute.getName())) {
+ attributes.put(attribute.getName(), attribute.convertToArray());
+ }
+ }
+ }
+ }
+
/** Returns a read only attribute iterator */
public Iterator attributeIterator() {
return attributes().iterator();
diff --git a/config-model/src/main/java/com/yahoo/searchdefinition/document/Attribute.java b/config-model/src/main/java/com/yahoo/searchdefinition/document/Attribute.java
index f932265cb93..81e44850e71 100644
--- a/config-model/src/main/java/com/yahoo/searchdefinition/document/Attribute.java
+++ b/config-model/src/main/java/com/yahoo/searchdefinition/document/Attribute.java
@@ -147,6 +147,12 @@ public final class Attribute implements Cloneable, Serializable {
this.referenceDocumentType = referenceDocumentType;
}
+ public Attribute convertToArray() {
+ Attribute result = clone();
+ result.collectionType = CollectionType.ARRAY;
+ return result;
+ }
+
/**
* <p>Returns whether this attribute should be included in the "attributeprefetch" summary
* which is returned to the Qrs by prefetchAttributes, used by blending, uniquing etc.
@@ -181,6 +187,7 @@ public final class Attribute implements Cloneable, Serializable {
public long upperBound() { return upperBound; }
public double densePostingListThreshold() { return densePostingListThreshold; }
public Optional<TensorType> tensorType() { return tensorType; }
+ public Optional<StructuredDataType> referenceDocumentType() { return referenceDocumentType; }
public Sorting getSorting() { return sorting; }
diff --git a/config-model/src/test/derived/array_of_struct_attribute/attributes.cfg b/config-model/src/test/derived/array_of_struct_attribute/attributes.cfg
new file mode 100644
index 00000000000..9e6b5cea55e
--- /dev/null
+++ b/config-model/src/test/derived/array_of_struct_attribute/attributes.cfg
@@ -0,0 +1,40 @@
+attribute[].name "elem_array.name"
+attribute[].datatype STRING
+attribute[].collectiontype ARRAY
+attribute[].removeifzero false
+attribute[].createifnonexistent false
+attribute[].fastsearch false
+attribute[].huge false
+attribute[].sortascending true
+attribute[].sortfunction UCA
+attribute[].sortstrength PRIMARY
+attribute[].sortlocale ""
+attribute[].enablebitvectors false
+attribute[].enableonlybitvector false
+attribute[].fastaccess false
+attribute[].arity 8
+attribute[].lowerbound -9223372036854775808
+attribute[].upperbound 9223372036854775807
+attribute[].densepostinglistthreshold 0.4
+attribute[].tensortype ""
+attribute[].imported false
+attribute[].name "elem_array.weight"
+attribute[].datatype INT32
+attribute[].collectiontype ARRAY
+attribute[].removeifzero false
+attribute[].createifnonexistent false
+attribute[].fastsearch false
+attribute[].huge false
+attribute[].sortascending true
+attribute[].sortfunction UCA
+attribute[].sortstrength PRIMARY
+attribute[].sortlocale ""
+attribute[].enablebitvectors false
+attribute[].enableonlybitvector false
+attribute[].fastaccess false
+attribute[].arity 8
+attribute[].lowerbound -9223372036854775808
+attribute[].upperbound 9223372036854775807
+attribute[].densepostinglistthreshold 0.4
+attribute[].tensortype ""
+attribute[].imported false
diff --git a/config-model/src/test/derived/array_of_struct_attribute/summary.cfg b/config-model/src/test/derived/array_of_struct_attribute/summary.cfg
new file mode 100644
index 00000000000..c1679c57d1a
--- /dev/null
+++ b/config-model/src/test/derived/array_of_struct_attribute/summary.cfg
@@ -0,0 +1,11 @@
+defaultsummaryid 252850086
+classes[].id 252850086
+classes[].name "default"
+classes[].fields[].name "elem_array"
+classes[].fields[].type "jsonstring"
+classes[].fields[].name "rankfeatures"
+classes[].fields[].type "featuredata"
+classes[].fields[].name "summaryfeatures"
+classes[].fields[].type "featuredata"
+classes[].fields[].name "documentid"
+classes[].fields[].type "longstring"
diff --git a/config-model/src/test/derived/array_of_struct_attribute/summarymap.cfg b/config-model/src/test/derived/array_of_struct_attribute/summarymap.cfg
new file mode 100644
index 00000000000..8956a146b74
--- /dev/null
+++ b/config-model/src/test/derived/array_of_struct_attribute/summarymap.cfg
@@ -0,0 +1,7 @@
+defaultoutputclass -1
+override[].field "rankfeatures"
+override[].command "rankfeatures"
+override[].arguments ""
+override[].field "summaryfeatures"
+override[].command "summaryfeatures"
+override[].arguments ""
diff --git a/config-model/src/test/derived/array_of_struct_attribute/test.sd b/config-model/src/test/derived/array_of_struct_attribute/test.sd
new file mode 100644
index 00000000000..5b2d50cbdba
--- /dev/null
+++ b/config-model/src/test/derived/array_of_struct_attribute/test.sd
@@ -0,0 +1,17 @@
+search test {
+ document test {
+ struct elem {
+ field name type string {}
+ field weight type int {}
+ }
+ field elem_array type array<elem> {
+ indexing: summary
+ struct-field name {
+ indexing: attribute
+ }
+ struct-field weight {
+ indexing: attribute
+ }
+ }
+ }
+}
diff --git a/config-model/src/test/java/com/yahoo/searchdefinition/AttributeSettingsTestCase.java b/config-model/src/test/java/com/yahoo/searchdefinition/AttributeSettingsTestCase.java
index 95d5832b70d..4ee33abfc08 100644
--- a/config-model/src/test/java/com/yahoo/searchdefinition/AttributeSettingsTestCase.java
+++ b/config-model/src/test/java/com/yahoo/searchdefinition/AttributeSettingsTestCase.java
@@ -1,12 +1,16 @@
// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
package com.yahoo.searchdefinition;
+import com.yahoo.document.StructDataType;
import com.yahoo.searchdefinition.document.Attribute;
import com.yahoo.searchdefinition.document.SDField;
+import com.yahoo.searchdefinition.document.Sorting;
import com.yahoo.searchdefinition.parser.ParseException;
+import com.yahoo.tensor.TensorType;
import org.junit.Test;
import java.io.IOException;
+import java.util.Optional;
import static org.hamcrest.core.Is.is;
import static org.junit.Assert.*;
@@ -88,4 +92,48 @@ public class AttributeSettingsTestCase extends SearchDefinitionTestCase {
assertTrue(attr.isFastAccess());
}
+ @Test
+ public void attribute_convert_to_array_copies_internal_state() {
+ StructDataType refType = new StructDataType("my_struct");
+ Attribute single = new Attribute("foo", Attribute.Type.STRING, Attribute.CollectionType.SINGLE,
+ Optional.of(TensorType.fromSpec("tensor(x{})")), Optional.of(refType));
+ single.setRemoveIfZero(true);
+ single.setCreateIfNonExistent(true);
+ single.setPrefetch(Boolean.TRUE);
+ single.setEnableBitVectors(true);
+ single.setEnableOnlyBitVector(true);
+ single.setFastSearch(true);
+ single.setHuge(true);
+ single.setFastAccess(true);
+ single.setPosition(true);
+ single.setArity(5);
+ single.setLowerBound(7);
+ single.setUpperBound(11);
+ single.setDensePostingListThreshold(13.3);
+ single.getSorting().setAscending();
+ single.getAliases().add("foo");
+
+ Attribute array = single.convertToArray();
+ assertEquals("foo", array.getName());
+ assertEquals(Attribute.Type.STRING, array.getType());
+ assertEquals(Attribute.CollectionType.ARRAY, array.getCollectionType());
+ assertEquals(Optional.of(TensorType.fromSpec("tensor(x{})")), array.tensorType());
+ assertSame(single.referenceDocumentType(), array.referenceDocumentType());
+ assertTrue(array.isRemoveIfZero());
+ assertTrue(array.isCreateIfNonExistent());
+ assertTrue(array.isPrefetch());
+ assertTrue(array.isEnabledBitVectors());
+ assertTrue(array.isEnabledOnlyBitVector());
+ assertTrue(array.isFastSearch());
+ assertTrue(array.isHuge());
+ assertTrue(array.isFastAccess());
+ assertTrue(array.isPosition());
+ assertEquals(5, array.arity());
+ assertEquals(7, array.lowerBound());
+ assertEquals(11, array.upperBound());
+ assertEquals(13.3, array.densePostingListThreshold(), 0.00001);
+ assertSame(single.getSorting(), array.getSorting());
+ assertSame(single.getAliases(), array.getAliases());
+ }
+
}
diff --git a/config-model/src/test/java/com/yahoo/searchdefinition/derived/AttributeListTestCase.java b/config-model/src/test/java/com/yahoo/searchdefinition/derived/AttributeListTestCase.java
index 86f30ba3c11..990ebe7f993 100644
--- a/config-model/src/test/java/com/yahoo/searchdefinition/derived/AttributeListTestCase.java
+++ b/config-model/src/test/java/com/yahoo/searchdefinition/derived/AttributeListTestCase.java
@@ -11,6 +11,7 @@ import org.junit.Test;
import java.io.IOException;
import java.util.Iterator;
+import static com.yahoo.config.model.test.TestUtil.joinLines;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
@@ -68,4 +69,36 @@ public class AttributeListTestCase extends SearchDefinitionTestCase {
assertTrue(!attributes.hasNext());
}
+ @Test
+ public void array_of_struct_field_is_derived_into_array_attributes() throws IOException, ParseException {
+ Search search = SearchBuilder.buildFromFile("src/test/derived/array_of_struct_attribute/test.sd");
+ Iterator<Attribute> attributes = new AttributeFields(search).attributeIterator();
+
+ assertAttribute("elem_array.name", Attribute.Type.STRING, Attribute.CollectionType.ARRAY, attributes.next());
+ assertAttribute("elem_array.weight", Attribute.Type.INTEGER, Attribute.CollectionType.ARRAY, attributes.next());
+ assertTrue(!attributes.hasNext());
+ }
+
+ private static void assertAttribute(String name, Attribute.Type type, Attribute.CollectionType collection, Attribute attr) {
+ assertEquals(name, attr.getName());
+ assertEquals(type, attr.getType());
+ assertEquals(collection, attr.getCollectionType());
+ }
+
+ @Test
+ public void only_zcurve_attribute_is_derived_from_array_of_position_field() throws ParseException {
+ Search search = SearchBuilder.createFromString(
+ joinLines("search test {",
+ " document test {",
+ " field pos_array type array<position> {",
+ " indexing: attribute",
+ " }",
+ " }",
+ "}")).getSearch();
+ Iterator<Attribute> attributes = new AttributeFields(search).attributeIterator();
+
+ assertAttribute("pos_array_zcurve", Attribute.Type.LONG, Attribute.CollectionType.ARRAY, attributes.next());
+ assertTrue(!attributes.hasNext());
+ }
+
}
diff --git a/config-model/src/test/java/com/yahoo/searchdefinition/derived/ExportingTestCase.java b/config-model/src/test/java/com/yahoo/searchdefinition/derived/ExportingTestCase.java
index 4600f6ae4c6..dc2d3b7cea1 100644
--- a/config-model/src/test/java/com/yahoo/searchdefinition/derived/ExportingTestCase.java
+++ b/config-model/src/test/java/com/yahoo/searchdefinition/derived/ExportingTestCase.java
@@ -139,4 +139,9 @@ public class ExportingTestCase extends AbstractExportingTestCase {
assertCorrectDeriving("tensor");
}
+ @Test
+ public void testArrayOfStructAttribute() throws IOException, ParseException {
+ assertCorrectDeriving("array_of_struct_attribute");
+ }
+
}
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 e1b5842529f..70e9357e7cf 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
@@ -1,10 +1,10 @@
// Copyright 2018 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
package com.yahoo.prelude.query;
-
import com.google.common.annotations.Beta;
import com.yahoo.protect.Validator;
+import java.nio.ByteBuffer;
import java.util.Iterator;
/**
@@ -14,34 +14,30 @@ import java.util.Iterator;
* @author baldersheim
*/
@Beta
-public class SameElementItem extends CompositeIndexedItem {
+public class SameElementItem extends CompositeItem {
+
+ private final String fieldName;
public SameElementItem(String commonPath) {
- setIndexName(commonPath);
+ Validator.ensureNonEmpty("Field name", commonPath);
+ this.fieldName = commonPath;
}
@Override
- public String getIndexedString() {
- StringBuilder buf = new StringBuilder();
-
- for (Iterator<Item> i = getItemIterator(); i.hasNext();) {
- IndexedItem indexedItem = (IndexedItem) i.next();
-
- buf.append(indexedItem.getIndexedString());
- if (i.hasNext()) {
- buf.append(' ');
- }
- }
- return buf.toString();
+ protected void encodeThis(ByteBuffer buffer) {
+ super.encodeThis(buffer);
+ putString(fieldName, buffer);
}
+ @Override
protected void appendHeadingString(StringBuilder buffer) { }
+ @Override
protected void appendBodyString(StringBuilder buffer) {
- appendIndexString(buffer);
+ buffer.append(fieldName).append(':');
buffer.append('{');
for (Iterator<Item> i = getItemIterator(); i.hasNext();) {
TermItem term = (TermItem) i.next();
- buffer.append(term.getIndexName()).append(':').append(term.getIndexedString());
+ buffer.append(extractSubFieldName(term)).append(':').append(term.getIndexedString());
if (i.hasNext()) {
buffer.append(' ');
}
@@ -50,16 +46,14 @@ public class SameElementItem extends CompositeIndexedItem {
}
@Override
- public int getNumWords() {
- return getItemCount();
- }
-
- @Override
protected void adding(Item item) {
Validator.ensureInstanceOf("Child item", item, TermItem.class);
TermItem asTerm = (TermItem) item;
Validator.ensureNonEmpty("Struct fieldname", asTerm.getIndexName());
Validator.ensureNonEmpty("Query term", asTerm.getIndexedString());
+ Validator.ensure("Struct fieldname starts with '" + getFieldName() + ".'",
+ !asTerm.getIndexName().startsWith(fieldName+"."));
+ item.setIndexName(fieldName + '.' + asTerm.getIndexName());
}
@Override
public ItemType getItemType() {
@@ -70,4 +64,8 @@ public class SameElementItem extends CompositeIndexedItem {
public String getName() {
return getItemType().toString();
}
+ public String getFieldName() { return fieldName; }
+ public String extractSubFieldName(TermItem full) {
+ return full.getIndexName().substring(getFieldName().length()+1);
+ }
}
diff --git a/container-search/src/main/java/com/yahoo/prelude/query/WeakAndItem.java b/container-search/src/main/java/com/yahoo/prelude/query/WeakAndItem.java
index 0384dfdca12..708c48f0954 100644
--- a/container-search/src/main/java/com/yahoo/prelude/query/WeakAndItem.java
+++ b/container-search/src/main/java/com/yahoo/prelude/query/WeakAndItem.java
@@ -42,11 +42,7 @@ public final class WeakAndItem extends NonReducibleCompositeItem {
**/
public WeakAndItem(String index, int N) {
this.N = N;
- if (index == null) {
- this.index = "";
- } else {
- this.index = index;
- }
+ this.index = (index == null) ? "" : index;
}
public WeakAndItem(int N) {
this("", N);
@@ -54,12 +50,7 @@ public final class WeakAndItem extends NonReducibleCompositeItem {
/** Sets the index name of all subitems of this */
public void setIndexName(String index) {
- String toSet;
- if (index == null) {
- toSet = "";
- } else {
- toSet = index;
- }
+ String toSet = (index == null) ? "" : index;
super.setIndexName(toSet);
this.index = toSet;
}
diff --git a/container-search/src/main/java/com/yahoo/search/yql/VespaSerializer.java b/container-search/src/main/java/com/yahoo/search/yql/VespaSerializer.java
index 4c5dfaabed7..12aec81a5f8 100644
--- a/container-search/src/main/java/com/yahoo/search/yql/VespaSerializer.java
+++ b/container-search/src/main/java/com/yahoo/search/yql/VespaSerializer.java
@@ -594,26 +594,22 @@ public class VespaSerializer {
static boolean serialize(StringBuilder destination, Item item, boolean includeField) {
- SameElementItem phrase = (SameElementItem) item;
- String annotations = leafAnnotations(phrase);
+ SameElementItem sameElement = (SameElementItem) item;
if (includeField) {
- destination.append(normalizeIndexName(phrase.getIndexName())).append(" contains ");
-
- }
- if (annotations.length() > 0) {
- destination.append("([{").append(annotations).append("}]");
+ destination.append(normalizeIndexName(sameElement.getFieldName())).append(" contains ");
}
destination.append(SAME_ELEMENT).append('(');
- for (int i = 0; i < phrase.getItemCount(); ++i) {
+ for (int i = 0; i < sameElement.getItemCount(); ++i) {
if (i > 0) {
destination.append(", ");
}
- Item current = phrase.getItem(i);
+ Item current = sameElement.getItem(i);
if (current instanceof WordItem) {
- new WordSerializer().serialize(destination, current);
-
+ WordItem modified = (WordItem)current.clone();
+ modified.setIndexName(sameElement.extractSubFieldName(modified));
+ new WordSerializer().serialize(destination, modified);
} else {
throw new IllegalArgumentException(
"Serializing of " + current.getClass().getSimpleName()
@@ -621,9 +617,7 @@ public class VespaSerializer {
}
}
destination.append(')');
- if (annotations.length() > 0) {
- destination.append(')');
- }
+
return false;
}
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 292bb6d0f5a..c6097b1bc73 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
@@ -542,7 +542,7 @@ public class YqlParser implements Parser {
for (OperatorNode<ExpressionOperator> word : ast.<List<OperatorNode<ExpressionOperator>>> getArgument(1)) {
sameElement.addItem(buildTermSearch(word));
}
- return leafStyleSettings(ast, sameElement);
+ return sameElement;
}
@NonNull
diff --git a/container-search/src/test/java/com/yahoo/prelude/query/test/SameElementItemTestCase.java b/container-search/src/test/java/com/yahoo/prelude/query/test/SameElementItemTestCase.java
index ff3ca53319f..01c03fcd802 100644
--- a/container-search/src/test/java/com/yahoo/prelude/query/test/SameElementItemTestCase.java
+++ b/container-search/src/test/java/com/yahoo/prelude/query/test/SameElementItemTestCase.java
@@ -22,6 +22,19 @@ public class SameElementItemTestCase {
s.addItem(new WordItem("b", "f1"));
s.addItem(new WordItem("c"));
}
+ @Test
+ public void requireAllowCommonPrefix() {
+ SameElementItem s = new SameElementItem("structa");
+ s.addItem(new WordItem("b", "f1"));
+ s.addItem(new WordItem("c", "structaf2"));
+ assertEquals("structa:{f1:b structaf2:c}", s.toString());
+ }
+ @Test(expected = IllegalArgumentException.class)
+ public void requireNoChildrenHasCommonPrefixWithDot() {
+ SameElementItem s = new SameElementItem("structa");
+ s.addItem(new WordItem("b", "f1"));
+ s.addItem(new WordItem("c", "structa.f2"));
+ }
@Test(expected = IllegalArgumentException.class)
public void requireAllChildrenHaveNonEmptyTerm() {
SameElementItem s = new SameElementItem("structa");
diff --git a/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/maintenance/NodeRepositoryMaintenance.java b/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/maintenance/NodeRepositoryMaintenance.java
index 4497f55cb85..62e954afba3 100644
--- a/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/maintenance/NodeRepositoryMaintenance.java
+++ b/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/maintenance/NodeRepositoryMaintenance.java
@@ -8,6 +8,7 @@ import com.yahoo.config.provision.Deployer;
import com.yahoo.config.provision.Environment;
import com.yahoo.config.provision.HostLivenessTracker;
import com.yahoo.config.provision.Provisioner;
+import com.yahoo.config.provision.SystemName;
import com.yahoo.config.provision.Zone;
import com.yahoo.jdisc.Metric;
import com.yahoo.vespa.hosted.provision.NodeRepository;
@@ -65,7 +66,7 @@ public class NodeRepositoryMaintenance extends AbstractComponent {
HostLivenessTracker hostLivenessTracker, ServiceMonitor serviceMonitor,
Zone zone, Clock clock, Orchestrator orchestrator, Metric metric,
ConfigserverConfig configserverConfig) {
- DefaultTimes defaults = new DefaultTimes(zone.environment());
+ DefaultTimes defaults = new DefaultTimes(zone);
jobControl = new JobControl(nodeRepository.database());
infrastructureVersions = new InfrastructureVersions(nodeRepository.database());
@@ -151,7 +152,7 @@ public class NodeRepositoryMaintenance extends AbstractComponent {
private final NodeFailer.ThrottlePolicy throttlePolicy;
- DefaultTimes(Environment environment) {
+ DefaultTimes(Zone zone) {
failGrace = Duration.ofMinutes(60);
periodicRedeployInterval = Duration.ofMinutes(30);
operatorChangeRedeployInterval = Duration.ofMinutes(1);
@@ -164,13 +165,14 @@ public class NodeRepositoryMaintenance extends AbstractComponent {
infrastructureProvisionInterval = Duration.ofMinutes(3);
throttlePolicy = NodeFailer.ThrottlePolicy.hosted;
+ Environment environment = zone.environment();
if (environment.isTest())
retiredExpiry = Duration.ofMinutes(1); // fast turnaround as test envs don't have persistent data
else
retiredExpiry = Duration.ofDays(4); // give up migrating data after 4 days
- if (environment.equals(Environment.prod)) {
+ if (environment.equals(Environment.prod) && zone.system() == SystemName.main) {
inactiveExpiry = Duration.ofHours(4); // enough time for the application owner to discover and redeploy
retiredInterval = Duration.ofMinutes(29);
dirtyExpiry = Duration.ofHours(2); // enough time to clean the node
diff --git a/searchcore/src/tests/proton/documentdb/feedhandler/feedhandler_test.cpp b/searchcore/src/tests/proton/documentdb/feedhandler/feedhandler_test.cpp
index 5c0edce0b94..153b1ae2867 100644
--- a/searchcore/src/tests/proton/documentdb/feedhandler/feedhandler_test.cpp
+++ b/searchcore/src/tests/proton/documentdb/feedhandler/feedhandler_test.cpp
@@ -2,6 +2,7 @@
#include <vespa/persistence/spi/result.h>
#include <vespa/document/update/assignvalueupdate.h>
+#include <vespa/document/repo/documenttyperepo.h>
#include <vespa/searchcore/proton/bucketdb/bucketdbhandler.h>
#include <vespa/searchcore/proton/test/bucketfactory.h>
#include <vespa/searchcore/proton/common/feedtoken.h>
@@ -35,6 +36,7 @@ LOG_SETUP("feedhandler_test");
using document::BucketId;
using document::Document;
using document::DocumentId;
+using document::DocumentType;
using document::DocumentTypeRepo;
using document::DocumentUpdate;
using document::GlobalId;
@@ -181,7 +183,9 @@ struct MyFeedView : public test::DummyFeedView {
int prune_removed_count;
int update_count;
SerialNum update_serial;
- MyFeedView(const std::shared_ptr<const DocumentTypeRepo> &dtr);
+ const DocumentType *documentType;
+ MyFeedView(const std::shared_ptr<const DocumentTypeRepo> &dtr,
+ const DocTypeName &docTypeName);
~MyFeedView() override;
void resetPutLatch(uint32_t count) { putLatch.reset(new vespalib::CountDownLatch(count)); }
void preparePut(PutOperation &op) override {
@@ -203,6 +207,8 @@ struct MyFeedView : public test::DummyFeedView {
if (usePutRdz) {
putRdz.run();
}
+ EXPECT_EQUAL(_docTypeRepo.get(), putOp.getDocument()->getRepo());
+ EXPECT_EQUAL(documentType, &putOp.getDocument()->getType());
++put_count;
put_serial = putOp.getSerialNum();
metaStore.allocate(putOp.getDocument()->getId().getGlobalId());
@@ -216,6 +222,7 @@ struct MyFeedView : public test::DummyFeedView {
void handleUpdate(FeedToken token, const UpdateOperation &op) override {
(void) token;
+ EXPECT_EQUAL(documentType, &op.getUpdate()->getType());
++update_count;
update_serial = op.getSerialNum();
}
@@ -237,7 +244,7 @@ struct MyFeedView : public test::DummyFeedView {
}
};
-MyFeedView::MyFeedView(const std::shared_ptr<const DocumentTypeRepo> &dtr)
+MyFeedView::MyFeedView(const std::shared_ptr<const DocumentTypeRepo> &dtr, const DocTypeName &docTypeName)
: test::DummyFeedView(dtr),
putRdz(),
usePutRdz(false),
@@ -250,7 +257,8 @@ MyFeedView::MyFeedView(const std::shared_ptr<const DocumentTypeRepo> &dtr)
move_count(0),
prune_removed_count(0),
update_count(0),
- update_serial(0)
+ update_serial(0),
+ documentType(dtr->getDocumentType(docTypeName.getName()))
{}
MyFeedView::~MyFeedView() {}
@@ -294,6 +302,13 @@ struct DocumentContext {
}
};
+struct TwoFieldsSchemaContext : public SchemaContext {
+ TwoFieldsSchemaContext()
+ : SchemaContext()
+ {
+ addField("i2");
+ }
+};
struct UpdateContext {
DocumentUpdate::SP update;
@@ -433,7 +448,7 @@ struct FeedHandlerFixture
owner(),
_state(),
replayConfig(),
- feedView(schema.getRepo()),
+ feedView(schema.getRepo(), schema.getDocType()),
_bucketDB(),
_bucketDBHandler(_bucketDB),
handler(writeService, tlsSpec, schema.getDocType(), _state, owner,
@@ -714,15 +729,13 @@ TEST_F("require that update with same document type repo is ok", FeedHandlerFixt
TEST_F("require that update with different document type repo can be ok", FeedHandlerFixture)
{
- SchemaContext schema;
- schema.addField("i2");
+ TwoFieldsSchemaContext schema;
checkUpdate(f, schema, "i1", false, true);
}
TEST_F("require that update with different document type repo can be rejected", FeedHandlerFixture)
{
- SchemaContext schema;
- schema.addField("i2");
+ TwoFieldsSchemaContext schema;
checkUpdate(f, schema, "i2", true, true);
}
@@ -733,18 +746,31 @@ TEST_F("require that update with same document type repo is ok, fallback to crea
TEST_F("require that update with different document type repo can be ok, fallback to create document", FeedHandlerFixture)
{
- SchemaContext schema;
- schema.addField("i2");
+ TwoFieldsSchemaContext schema;
checkUpdate(f, schema, "i1", false, false);
}
TEST_F("require that update with different document type repo can be rejected, preventing fallback to create document", FeedHandlerFixture)
{
- SchemaContext schema;
- schema.addField("i2");
+ TwoFieldsSchemaContext schema;
checkUpdate(f, schema, "i2", true, false);
}
+TEST_F("require that put with different document type repo is ok", FeedHandlerFixture)
+{
+ TwoFieldsSchemaContext schema;
+ DocumentContext doc_context("doc:test:foo", *schema.builder);
+ auto op = std::make_unique<PutOperation>(doc_context.bucketId,
+ Timestamp(10), doc_context.doc);
+ FeedTokenContext token_context;
+ EXPECT_EQUAL(schema.getRepo().get(), op->getDocument()->getRepo());
+ EXPECT_NOT_EQUAL(f.schema.getRepo().get(), op->getDocument()->getRepo());
+ EXPECT_NOT_EQUAL(f.feedView.documentType, &op->getDocument()->getType());
+ f.handler.performOperation(std::move(token_context.token), std::move(op));
+ EXPECT_EQUAL(1, f.feedView.put_count);
+ EXPECT_EQUAL(1, f.tls_writer.store_count);
+}
+
} // namespace
TEST_MAIN()
diff --git a/searchcore/src/tests/proton/matching/query_test.cpp b/searchcore/src/tests/proton/matching/query_test.cpp
index eb49603f71d..7875e7ec4aa 100644
--- a/searchcore/src/tests/proton/matching/query_test.cpp
+++ b/searchcore/src/tests/proton/matching/query_test.cpp
@@ -1,7 +1,6 @@
// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
// Unit tests for query.
-#include <vespa/document/datatype/positiondatatype.h>
#include <vespa/searchcore/proton/matching/fakesearchcontext.h>
#include <vespa/searchcore/proton/matching/matchdatareservevisitor.h>
#include <vespa/searchcore/proton/matching/blueprintbuilder.h>
@@ -26,8 +25,9 @@
#include <vespa/searchlib/queryeval/simpleresult.h>
#include <vespa/searchlib/queryeval/fake_requestcontext.h>
#include <vespa/searchlib/queryeval/termasstring.h>
+#include <vespa/document/datatype/positiondatatype.h>
+
#include <vespa/vespalib/testkit/testapp.h>
-#include <vector>
using document::PositionDataType;
using search::fef::FieldInfo;
@@ -62,8 +62,7 @@ using std::vector;
namespace fef_test = search::fef::test;
using CollectionType = FieldInfo::CollectionType;
-namespace proton {
-namespace matching {
+namespace proton::matching {
namespace {
class Test : public vespalib::TestApp {
@@ -175,6 +174,12 @@ Node::UP buildQueryTree(const ViewResolver &resolver,
query_builder.addPhrase(2, field, 7, Weight(0));
query_builder.addStringTerm(phrase_term, field, 8, Weight(0));
query_builder.addStringTerm(phrase_term, field, 9, Weight(0));
+#if 0
+ //Todo add testing when SameElement blueprints are ready
+ query_builder.addSameElement(2, field);
+ query_builder.addStringTerm(string_term, field, 10, Weight(0));
+ query_builder.addStringTerm(prefix_term, field, 11, Weight(0));
+#endif
Node::UP node = query_builder.build();
ResolveViewVisitor visitor(resolver, idxEnv);
@@ -222,19 +227,19 @@ public:
EXPECT_EQUAL((double)estimatedHitCount / doc_count, n.field(0).getDocFreq());
}
- virtual void visit(ProtonNumberTerm &n) override { checkNode(n, 1, false); }
- virtual void visit(ProtonLocationTerm &n) override { checkNode(n, 0, true); }
- virtual void visit(ProtonPrefixTerm &n) override { checkNode(n, 1, false); }
- virtual void visit(ProtonRangeTerm &n) override { checkNode(n, 2, false); }
- virtual void visit(ProtonStringTerm &n) override { checkNode(n, 2, false); }
- virtual void visit(ProtonSubstringTerm &n) override { checkNode(n, 0, true); }
- virtual void visit(ProtonSuffixTerm &n) override { checkNode(n, 2, false); }
- virtual void visit(ProtonPhrase &n) override { checkNode(n, 0, true); }
- virtual void visit(ProtonWeightedSetTerm &) override {}
- virtual void visit(ProtonDotProduct &) override {}
- virtual void visit(ProtonWandTerm &) override {}
- virtual void visit(ProtonPredicateQuery &) override {}
- virtual void visit(ProtonRegExpTerm &) override {}
+ void visit(ProtonNumberTerm &n) override { checkNode(n, 1, false); }
+ void visit(ProtonLocationTerm &n) override { checkNode(n, 0, true); }
+ void visit(ProtonPrefixTerm &n) override { checkNode(n, 1, false); }
+ void visit(ProtonRangeTerm &n) override { checkNode(n, 2, false); }
+ void visit(ProtonStringTerm &n) override { checkNode(n, 2, false); }
+ void visit(ProtonSubstringTerm &n) override { checkNode(n, 0, true); }
+ void visit(ProtonSuffixTerm &n) override { checkNode(n, 2, false); }
+ void visit(ProtonPhrase &n) override { checkNode(n, 0, true); }
+ void visit(ProtonWeightedSetTerm &) override {}
+ void visit(ProtonDotProduct &) override {}
+ void visit(ProtonWandTerm &) override {}
+ void visit(ProtonPredicateQuery &) override {}
+ void visit(ProtonRegExpTerm &) override {}
};
void Test::requireThatTermsAreLookedUp() {
@@ -354,12 +359,12 @@ class SetUpTermDataTestCheckerVisitor
int Main() { return 0; }
public:
- virtual void visit(ProtonNumberTerm &) override {}
- virtual void visit(ProtonLocationTerm &) override {}
- virtual void visit(ProtonPrefixTerm &) override {}
- virtual void visit(ProtonRangeTerm &) override {}
+ void visit(ProtonNumberTerm &) override {}
+ void visit(ProtonLocationTerm &) override {}
+ void visit(ProtonPrefixTerm &) override {}
+ void visit(ProtonRangeTerm &) override {}
- virtual void visit(ProtonStringTerm &n) override {
+ void visit(ProtonStringTerm &n) override {
const ITermData &term_data = n;
EXPECT_EQUAL(string_weight.percent(),
term_data.getWeight().percent());
@@ -375,17 +380,17 @@ public:
}
}
- virtual void visit(ProtonSubstringTerm &) override {}
- virtual void visit(ProtonSuffixTerm &) override {}
- virtual void visit(ProtonPhrase &n) override {
+ void visit(ProtonSubstringTerm &) override {}
+ void visit(ProtonSuffixTerm &) override {}
+ void visit(ProtonPhrase &n) override {
const ITermData &term_data = n;
EXPECT_EQUAL(2u, term_data.getPhraseLength());
}
- virtual void visit(ProtonWeightedSetTerm &) override {}
- virtual void visit(ProtonDotProduct &) override {}
- virtual void visit(ProtonWandTerm &) override {}
- virtual void visit(ProtonPredicateQuery &) override {}
- virtual void visit(ProtonRegExpTerm &) override {}
+ void visit(ProtonWeightedSetTerm &) override {}
+ void visit(ProtonDotProduct &) override {}
+ void visit(ProtonWandTerm &) override {}
+ void visit(ProtonPredicateQuery &) override {}
+ void visit(ProtonRegExpTerm &) override {}
};
void Test::requireThatTermDataIsFilledIn() {
@@ -855,7 +860,7 @@ Test::requireThatWhiteListBlueprintCanBeUsed()
EXPECT_EQUAL(exp, act);
}
-Test::~Test() {}
+Test::~Test() = default;
int
Test::Main()
@@ -877,6 +882,7 @@ Test::Main()
TEST_CALL(requireThatNearIteratorsCanBeBuilt);
TEST_CALL(requireThatONearIteratorsCanBeBuilt);
TEST_CALL(requireThatPhraseIteratorsCanBeBuilt);
+ //TODO Add SameElement testing
TEST_CALL(requireThatUnknownFieldActsEmpty);
TEST_CALL(requireThatIllegalFieldsAreIgnored);
TEST_CALL(requireThatQueryGluesEverythingTogether);
@@ -893,7 +899,6 @@ Test::Main()
} // namespace
-} // namespace matching
-} // namespace proton
+} // namespace proton::matching
TEST_APPHOOK(proton::matching::Test);
diff --git a/searchcore/src/tests/proton/matching/querynodes_test.cpp b/searchcore/src/tests/proton/matching/querynodes_test.cpp
index f8a419ba15b..7b6fdd1ae88 100644
--- a/searchcore/src/tests/proton/matching/querynodes_test.cpp
+++ b/searchcore/src/tests/proton/matching/querynodes_test.cpp
@@ -1,11 +1,7 @@
// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
// Unit tests for querynodes.
-#include <vespa/log/log.h>
-LOG_SETUP("querynodes_test");
-
#include <vespa/searchcore/proton/matching/querynodes.h>
-
#include <vespa/searchcore/proton/matching/fakesearchcontext.h>
#include <vespa/searchcore/proton/matching/blueprintbuilder.h>
#include <vespa/searchcore/proton/matching/matchdatareservevisitor.h>
@@ -33,11 +29,12 @@ LOG_SETUP("querynodes_test");
#include <vespa/searchlib/queryeval/fake_search.h>
#include <vespa/searchlib/queryeval/fake_requestcontext.h>
#include <vespa/vespalib/testkit/testapp.h>
-#include <cstdarg>
-#include <string>
-#include <vector>
+
#include <vespa/searchlib/attribute/singlenumericattribute.hpp>
+#include <vespa/log/log.h>
+LOG_SETUP("querynodes_test");
+
using search::fef::FieldInfo;
using search::fef::FieldType;
using search::fef::MatchData;
@@ -210,9 +207,8 @@ public:
};
typedef QueryBuilder<ProtonNodeTypes> QB;
-struct Phrase {
- void addToBuilder(QB& b) { b.addPhrase(2, view, id, weight); }
-};
+struct Phrase { void addToBuilder(QB& b) { b.addPhrase(2, view, id, weight); }};
+struct SameElement { void addToBuilder(QB& b) { b.addSameElement(2, view); }};
struct Near { void addToBuilder(QB& b) { b.addNear(2, distance); } };
struct ONear { void addToBuilder(QB& b) { b.addONear(2, distance); } };
struct Or { void addToBuilder(QB& b) { b.addOr(2); } };
@@ -466,6 +462,11 @@ TEST("requireThatPhrasesGetProperBlending") {
TEST_DO(checkProperBlending<Phrase>());
}
+TEST("requireThatSameElementGetProperBlending") {
+ //TODO SameEelement needs proper testing/implementation
+ //TEST_DO(checkProperBlending<SameElement>());
+}
+
TEST("requireThatNearGetProperBlending") {
TEST_DO(checkProperBlendingWithParent<Near>());
}
diff --git a/searchcore/src/vespa/searchcore/proton/feedoperation/putoperation.cpp b/searchcore/src/vespa/searchcore/proton/feedoperation/putoperation.cpp
index a6d34b696ca..efac7297c67 100644
--- a/searchcore/src/vespa/searchcore/proton/feedoperation/putoperation.cpp
+++ b/searchcore/src/vespa/searchcore/proton/feedoperation/putoperation.cpp
@@ -49,6 +49,15 @@ PutOperation::deserialize(vespalib::nbostream &is,
_serializedDocSize = oldSize - is.size();
}
+void
+PutOperation::deserializeDocument(const DocumentTypeRepo &repo)
+{
+ vespalib::nbostream stream;
+ _doc->serialize(stream);
+ auto fixedDoc = std::make_shared<Document>(repo, stream);
+ _doc = std::move(fixedDoc);
+}
+
vespalib::string
PutOperation::toString() const
{
diff --git a/searchcore/src/vespa/searchcore/proton/feedoperation/putoperation.h b/searchcore/src/vespa/searchcore/proton/feedoperation/putoperation.h
index 7e9dee2cbc0..33330692fab 100644
--- a/searchcore/src/vespa/searchcore/proton/feedoperation/putoperation.h
+++ b/searchcore/src/vespa/searchcore/proton/feedoperation/putoperation.h
@@ -21,6 +21,7 @@ public:
virtual void serialize(vespalib::nbostream &os) const override;
virtual void deserialize(vespalib::nbostream &is,
const document::DocumentTypeRepo &repo) override;
+ void deserializeDocument(const document::DocumentTypeRepo &repo);
virtual vespalib::string toString() const override;
};
diff --git a/searchcore/src/vespa/searchcore/proton/feedoperation/updateoperation.cpp b/searchcore/src/vespa/searchcore/proton/feedoperation/updateoperation.cpp
index fa5bbee8e6d..beaf719dc5c 100644
--- a/searchcore/src/vespa/searchcore/proton/feedoperation/updateoperation.cpp
+++ b/searchcore/src/vespa/searchcore/proton/feedoperation/updateoperation.cpp
@@ -8,6 +8,7 @@ LOG_SETUP(".proton.feedoperation.updateoperation");
using document::BucketId;
+using document::DocumentType;
using document::DocumentTypeRepo;
using document::DocumentUpdate;
using storage::spi::Timestamp;
@@ -46,12 +47,9 @@ UpdateOperation::UpdateOperation(const BucketId &bucketId,
{
}
-
void
-UpdateOperation::serialize(vespalib::nbostream &os) const
+UpdateOperation::serializeUpdate(vespalib::nbostream &os) const
{
- assertValidBucketId(_upd->getId());
- DocumentOperation::serialize(os);
if (getType() == FeedOperation::UPDATE_42) {
_upd->serialize42(os);
} else {
@@ -59,19 +57,33 @@ UpdateOperation::serialize(vespalib::nbostream &os) const
}
}
+void
+UpdateOperation::deserializeUpdate(vespalib::nbostream &is, const document::DocumentTypeRepo &repo)
+{
+ document::ByteBuffer buf(is.peek(), is.size());
+ using Version = DocumentUpdate::SerializeVersion;
+ Version version = ((getType() == FeedOperation::UPDATE_42) ? Version::SERIALIZE_42 : Version::SERIALIZE_HEAD);
+ DocumentUpdate::SP update(std::make_shared<DocumentUpdate>(repo, buf, version));
+ is.adjustReadPos(buf.getPos());
+ _upd = std::move(update);
+}
+
+void
+UpdateOperation::serialize(vespalib::nbostream &os) const
+{
+ assertValidBucketId(_upd->getId());
+ DocumentOperation::serialize(os);
+ serializeUpdate(os);
+}
+
void
UpdateOperation::deserialize(vespalib::nbostream &is,
const DocumentTypeRepo &repo)
{
DocumentOperation::deserialize(is, repo);
- document::ByteBuffer buf(is.peek(), is.size());
- using Version = DocumentUpdate::SerializeVersion;
- Version version = ((getType() == FeedOperation::UPDATE_42) ? Version::SERIALIZE_42 : Version::SERIALIZE_HEAD);
try {
- DocumentUpdate::SP update(std::make_shared<DocumentUpdate>(repo, buf, version));
- is.adjustReadPos(buf.getPos());
- _upd = update;
+ deserializeUpdate(is, repo);
} catch (document::DocumentTypeNotFoundException &e) {
LOG(warning, "Failed deserialize update operation using unknown document type '%s'",
e.getDocumentTypeName().c_str());
@@ -80,6 +92,14 @@ UpdateOperation::deserialize(vespalib::nbostream &is,
}
}
+void
+UpdateOperation::deserializeUpdate(const DocumentTypeRepo &repo)
+{
+ vespalib::nbostream stream;
+ serializeUpdate(stream);
+ deserializeUpdate(stream, repo);
+}
+
vespalib::string UpdateOperation::toString() const {
return make_string("%s(%s, %s)",
((getType() == FeedOperation::UPDATE_42) ? "Update42" : "Update"),
diff --git a/searchcore/src/vespa/searchcore/proton/feedoperation/updateoperation.h b/searchcore/src/vespa/searchcore/proton/feedoperation/updateoperation.h
index 6e061f79f30..7886231af82 100644
--- a/searchcore/src/vespa/searchcore/proton/feedoperation/updateoperation.h
+++ b/searchcore/src/vespa/searchcore/proton/feedoperation/updateoperation.h
@@ -3,7 +3,10 @@
#include "documentoperation.h"
-namespace document { class DocumentUpdate; }
+namespace document {
+class DocumentTypeRepo;
+class DocumentUpdate;
+}
namespace proton {
@@ -16,6 +19,8 @@ private:
const document::BucketId &bucketId,
const storage::spi::Timestamp &timestamp,
const DocumentUpdateSP &upd);
+ void serializeUpdate(vespalib::nbostream &os) const;
+ void deserializeUpdate(vespalib::nbostream &is, const document::DocumentTypeRepo &repo);
public:
UpdateOperation();
UpdateOperation(Type type);
@@ -26,6 +31,7 @@ public:
const DocumentUpdateSP &getUpdate() const { return _upd; }
void serialize(vespalib::nbostream &os) const override;
void deserialize(vespalib::nbostream &is, const document::DocumentTypeRepo &repo) override;
+ void deserializeUpdate(const document::DocumentTypeRepo &repo);
virtual vespalib::string toString() const override;
static UpdateOperation makeOldUpdate(const document::BucketId &bucketId,
const storage::spi::Timestamp &timestamp,
diff --git a/searchcore/src/vespa/searchcore/proton/matching/blueprintbuilder.cpp b/searchcore/src/vespa/searchcore/proton/matching/blueprintbuilder.cpp
index 97fc1905f50..165fc67179a 100644
--- a/searchcore/src/vespa/searchcore/proton/matching/blueprintbuilder.cpp
+++ b/searchcore/src/vespa/searchcore/proton/matching/blueprintbuilder.cpp
@@ -10,8 +10,7 @@
using namespace search::queryeval;
-namespace proton {
-namespace matching {
+namespace proton::matching {
namespace {
@@ -124,29 +123,31 @@ private:
}
protected:
- virtual void visit(ProtonAnd &n) override { buildIntermediate(new AndBlueprint(), n); }
- virtual void visit(ProtonAndNot &n) override { buildIntermediate(new AndNotBlueprint(), n); }
- virtual void visit(ProtonOr &n) override { buildIntermediate(new OrBlueprint(), n); }
- virtual void visit(ProtonWeakAnd &n) override { buildWeakAnd(n); }
- virtual void visit(ProtonEquiv &n) override { buildEquiv(n); }
- virtual void visit(ProtonRank &n) override { buildIntermediate(new RankBlueprint(), n); }
- virtual void visit(ProtonNear &n) override { buildIntermediate(new NearBlueprint(n.getDistance()), n); }
- virtual void visit(ProtonONear &n) override { buildIntermediate(new ONearBlueprint(n.getDistance()), n); }
-
- virtual void visit(ProtonWeightedSetTerm &n) override { buildTerm(n); }
- virtual void visit(ProtonDotProduct &n) override { buildTerm(n); }
- virtual void visit(ProtonWandTerm &n) override { buildTerm(n); }
-
- virtual void visit(ProtonPhrase &n) override { buildTerm(n); }
- virtual void visit(ProtonNumberTerm &n) override { buildTerm(n); }
- virtual void visit(ProtonLocationTerm &n) override { buildTerm(n); }
- virtual void visit(ProtonPrefixTerm &n) override { buildTerm(n); }
- virtual void visit(ProtonRangeTerm &n) override { buildTerm(n); }
- virtual void visit(ProtonStringTerm &n) override { buildTerm(n); }
- virtual void visit(ProtonSubstringTerm &n) override { buildTerm(n); }
- virtual void visit(ProtonSuffixTerm &n) override { buildTerm(n); }
- virtual void visit(ProtonPredicateQuery &n) override { buildTerm(n); }
- virtual void visit(ProtonRegExpTerm &n) override { buildTerm(n); }
+ void visit(ProtonAnd &n) override { buildIntermediate(new AndBlueprint(), n); }
+ void visit(ProtonAndNot &n) override { buildIntermediate(new AndNotBlueprint(), n); }
+ void visit(ProtonOr &n) override { buildIntermediate(new OrBlueprint(), n); }
+ void visit(ProtonWeakAnd &n) override { buildWeakAnd(n); }
+ void visit(ProtonEquiv &n) override { buildEquiv(n); }
+ void visit(ProtonRank &n) override { buildIntermediate(new RankBlueprint(), n); }
+ void visit(ProtonNear &n) override { buildIntermediate(new NearBlueprint(n.getDistance()), n); }
+ void visit(ProtonONear &n) override { buildIntermediate(new ONearBlueprint(n.getDistance()), n); }
+ void visit(ProtonSameElement &n) override { buildIntermediate(nullptr /*new SameElementBlueprint())*/, n); }
+
+
+ void visit(ProtonWeightedSetTerm &n) override { buildTerm(n); }
+ void visit(ProtonDotProduct &n) override { buildTerm(n); }
+ void visit(ProtonWandTerm &n) override { buildTerm(n); }
+
+ void visit(ProtonPhrase &n) override { buildTerm(n); }
+ void visit(ProtonNumberTerm &n) override { buildTerm(n); }
+ void visit(ProtonLocationTerm &n) override { buildTerm(n); }
+ void visit(ProtonPrefixTerm &n) override { buildTerm(n); }
+ void visit(ProtonRangeTerm &n) override { buildTerm(n); }
+ void visit(ProtonStringTerm &n) override { buildTerm(n); }
+ void visit(ProtonSubstringTerm &n) override { buildTerm(n); }
+ void visit(ProtonSuffixTerm &n) override { buildTerm(n); }
+ void visit(ProtonPredicateQuery &n) override { buildTerm(n); }
+ void visit(ProtonRegExpTerm &n) override { buildTerm(n); }
public:
BlueprintBuilderVisitor(const IRequestContext & requestContext, ISearchContext &context) :
@@ -174,5 +175,4 @@ BlueprintBuilder::build(const IRequestContext & requestContext,
return result;
}
-} // namespace matching
-} // namespace proton
+}
diff --git a/searchcore/src/vespa/searchcore/proton/matching/matchdatareservevisitor.h b/searchcore/src/vespa/searchcore/proton/matching/matchdatareservevisitor.h
index ebe4e9b2ad7..a20f648ca1c 100644
--- a/searchcore/src/vespa/searchcore/proton/matching/matchdatareservevisitor.h
+++ b/searchcore/src/vespa/searchcore/proton/matching/matchdatareservevisitor.h
@@ -22,13 +22,14 @@ public:
template <class TermNode>
void visitTerm(TermNode &n) { n.allocateTerms(_mdl); }
- virtual void visit(ProtonNodeTypes::Equiv &n) override {
+ void visit(ProtonNodeTypes::Equiv &n) override {
MatchDataReserveVisitor subAllocator(n.children_mdl);
for (size_t i = 0; i < n.getChildren().size(); ++i) {
n.getChildren()[i]->accept(subAllocator);
}
n.allocateTerms(_mdl);
}
+ void visit(ProtonNodeTypes::SameElement &) override { }
MatchDataReserveVisitor(search::fef::MatchDataLayout &mdl) : _mdl(mdl) {}
};
diff --git a/searchcore/src/vespa/searchcore/proton/matching/query.cpp b/searchcore/src/vespa/searchcore/proton/matching/query.cpp
index 9181205bb19..8896e4d35c8 100644
--- a/searchcore/src/vespa/searchcore/proton/matching/query.cpp
+++ b/searchcore/src/vespa/searchcore/proton/matching/query.cpp
@@ -78,8 +78,8 @@ void AddLocationNode(const string &location_str, Node::UP &query_tree, Location
}
} // namespace
-Query::Query() {}
-Query::~Query() {}
+Query::Query() = default;
+Query::~Query() = default;
bool
Query::buildTree(const vespalib::stringref &stack, const string &location,
diff --git a/searchcore/src/vespa/searchcore/proton/matching/querynodes.cpp b/searchcore/src/vespa/searchcore/proton/matching/querynodes.cpp
index 63302424db6..b0d45ee0684 100644
--- a/searchcore/src/vespa/searchcore/proton/matching/querynodes.cpp
+++ b/searchcore/src/vespa/searchcore/proton/matching/querynodes.cpp
@@ -30,7 +30,7 @@ namespace proton::matching {
ProtonTermData::ProtonTermData() = default;
ProtonTermData::ProtonTermData(const ProtonTermData &) = default;
ProtonTermData & ProtonTermData::operator = (const ProtonTermData &) = default;
-ProtonTermData::~ProtonTermData() { }
+ProtonTermData::~ProtonTermData() = default;
void
ProtonTermData::setDocumentFrequency(double freq)
@@ -42,9 +42,9 @@ ProtonTermData::setDocumentFrequency(double freq)
void
ProtonTermData::resolve(const ViewResolver &resolver,
- const IIndexEnvironment &idxEnv,
- const string &view,
- bool forceFilter)
+ const IIndexEnvironment &idxEnv,
+ const string &view,
+ bool forceFilter)
{
std::vector<string> fields;
resolver.resolve(((view == "") ? "default" : view), fields);
diff --git a/searchcore/src/vespa/searchcore/proton/matching/querynodes.h b/searchcore/src/vespa/searchcore/proton/matching/querynodes.h
index ca6c8c75310..986c5d2dde9 100644
--- a/searchcore/src/vespa/searchcore/proton/matching/querynodes.h
+++ b/searchcore/src/vespa/searchcore/proton/matching/querynodes.h
@@ -104,13 +104,15 @@ struct ProtonTerm : public ProtonTermBase<Base> {
~ProtonTerm() {}
};
-typedef search::query::SimpleAnd ProtonAnd;
-typedef search::query::SimpleAndNot ProtonAndNot;
-typedef search::query::SimpleNear ProtonNear;
-typedef search::query::SimpleONear ProtonONear;
-typedef search::query::SimpleOr ProtonOr;
-typedef search::query::SimpleRank ProtonRank;
-typedef search::query::SimpleWeakAnd ProtonWeakAnd;
+typedef search::query::SimpleAnd ProtonAnd;
+typedef search::query::SimpleAndNot ProtonAndNot;
+typedef search::query::SimpleNear ProtonNear;
+typedef search::query::SimpleONear ProtonONear;
+typedef search::query::SimpleOr ProtonOr;
+typedef search::query::SimpleRank ProtonRank;
+typedef search::query::SimpleWeakAnd ProtonWeakAnd;
+typedef search::query::SimpleSameElement ProtonSameElement;
+
struct ProtonEquiv final : public ProtonTermBase<search::query::Equiv>
{
@@ -121,6 +123,7 @@ struct ProtonEquiv final : public ProtonTermBase<search::query::Equiv>
typedef ProtonTerm<search::query::LocationTerm> ProtonLocationTerm;
typedef ProtonTerm<search::query::NumberTerm> ProtonNumberTerm;
typedef ProtonTerm<search::query::Phrase> ProtonPhrase;
+
typedef ProtonTerm<search::query::PrefixTerm> ProtonPrefixTerm;
typedef ProtonTerm<search::query::RangeTerm> ProtonRangeTerm;
typedef ProtonTerm<search::query::StringTerm> ProtonStringTerm;
@@ -142,6 +145,7 @@ struct ProtonNodeTypes {
typedef ProtonONear ONear;
typedef ProtonOr Or;
typedef ProtonPhrase Phrase;
+ typedef ProtonSameElement SameElement;
typedef ProtonPrefixTerm PrefixTerm;
typedef ProtonRangeTerm RangeTerm;
typedef ProtonRank Rank;
diff --git a/searchcore/src/vespa/searchcore/proton/matching/termdatafromnode.cpp b/searchcore/src/vespa/searchcore/proton/matching/termdatafromnode.cpp
index 26b765cf3cf..3fd4000bf9f 100644
--- a/searchcore/src/vespa/searchcore/proton/matching/termdatafromnode.cpp
+++ b/searchcore/src/vespa/searchcore/proton/matching/termdatafromnode.cpp
@@ -4,8 +4,7 @@
#include "querynodes.h"
#include <vespa/searchlib/query/tree/customtypevisitor.h>
-namespace proton {
-namespace matching {
+namespace proton::matching {
namespace {
struct TermDataFromTermVisitor
@@ -19,29 +18,30 @@ struct TermDataFromTermVisitor
data = &n;
}
- virtual void visit(ProtonAnd &) override {}
- virtual void visit(ProtonAndNot &) override {}
- virtual void visit(ProtonNear &) override {}
- virtual void visit(ProtonONear &) override {}
- virtual void visit(ProtonOr &) override {}
- virtual void visit(ProtonRank &) override {}
- virtual void visit(ProtonWeakAnd &) override {}
-
- virtual void visit(ProtonWeightedSetTerm &n) override { visitTerm(n); }
- virtual void visit(ProtonDotProduct &n) override { visitTerm(n); }
- virtual void visit(ProtonWandTerm &n) override { visitTerm(n); }
- virtual void visit(ProtonPhrase &n) override { visitTerm(n); }
- virtual void visit(ProtonEquiv &n) override { visitTerm(n); }
-
- virtual void visit(ProtonNumberTerm &n) override { visitTerm(n); }
- virtual void visit(ProtonLocationTerm &n) override { visitTerm(n); }
- virtual void visit(ProtonPrefixTerm &n) override { visitTerm(n); }
- virtual void visit(ProtonRangeTerm &n) override { visitTerm(n); }
- virtual void visit(ProtonStringTerm &n) override { visitTerm(n); }
- virtual void visit(ProtonSubstringTerm &n) override { visitTerm(n); }
- virtual void visit(ProtonSuffixTerm &n) override { visitTerm(n); }
- virtual void visit(ProtonPredicateQuery &) override { }
- virtual void visit(ProtonRegExpTerm &n) override { visitTerm(n); }
+ void visit(ProtonAnd &) override {}
+ void visit(ProtonAndNot &) override {}
+ void visit(ProtonNear &) override {}
+ void visit(ProtonONear &) override {}
+ void visit(ProtonOr &) override {}
+ void visit(ProtonRank &) override {}
+ void visit(ProtonWeakAnd &) override {}
+ void visit(ProtonSameElement &) override { }
+
+ void visit(ProtonWeightedSetTerm &n) override { visitTerm(n); }
+ void visit(ProtonDotProduct &n) override { visitTerm(n); }
+ void visit(ProtonWandTerm &n) override { visitTerm(n); }
+ void visit(ProtonPhrase &n) override { visitTerm(n); }
+ void visit(ProtonEquiv &n) override { visitTerm(n); }
+
+ void visit(ProtonNumberTerm &n) override { visitTerm(n); }
+ void visit(ProtonLocationTerm &n) override { visitTerm(n); }
+ void visit(ProtonPrefixTerm &n) override { visitTerm(n); }
+ void visit(ProtonRangeTerm &n) override { visitTerm(n); }
+ void visit(ProtonStringTerm &n) override { visitTerm(n); }
+ void visit(ProtonSubstringTerm &n) override { visitTerm(n); }
+ void visit(ProtonSuffixTerm &n) override { visitTerm(n); }
+ void visit(ProtonPredicateQuery &) override { }
+ void visit(ProtonRegExpTerm &n) override { visitTerm(n); }
};
} // namespace
@@ -53,5 +53,4 @@ termDataFromNode(const search::query::Node &node)
return visitor.data;
}
-} // namespace matching
-} // namespace proton
+}
diff --git a/searchcore/src/vespa/searchcore/proton/matching/termdatafromnode.h b/searchcore/src/vespa/searchcore/proton/matching/termdatafromnode.h
index 3e78ace1900..e445dbcfc50 100644
--- a/searchcore/src/vespa/searchcore/proton/matching/termdatafromnode.h
+++ b/searchcore/src/vespa/searchcore/proton/matching/termdatafromnode.h
@@ -2,16 +2,13 @@
#pragma once
-
namespace search { namespace query { class Node; } }
-namespace proton {
-namespace matching {
+namespace proton::matching {
class ProtonTermData;
const ProtonTermData *termDataFromNode(const search::query::Node &node);
-} // namespace matching
-} // namespace proton
+}
diff --git a/searchcore/src/vespa/searchcore/proton/server/feedhandler.cpp b/searchcore/src/vespa/searchcore/proton/server/feedhandler.cpp
index ad5372b4af6..90b9bbc7f34 100644
--- a/searchcore/src/vespa/searchcore/proton/server/feedhandler.cpp
+++ b/searchcore/src/vespa/searchcore/proton/server/feedhandler.cpp
@@ -96,6 +96,14 @@ void FeedHandler::performPut(FeedToken token, PutOperation &op) {
}
return;
}
+ /*
+ * Check if document type repos are equal. DocumentTypeRepoFactory::make
+ * returns the same document type repo if document type configs are equal,
+ * thus we can just perform a cheaper identity check here.
+ */
+ if (_repo != op.getDocument()->getRepo()) {
+ op.deserializeDocument(*_repo);
+ }
storeOperation(op, token);
if (token) {
token->setResult(make_unique<Result>(), false);
@@ -344,6 +352,8 @@ FeedHandler::FeedHandler(IThreadingService &writeService,
_feedLock(),
_feedState(make_shared<InitState>(getDocTypeName())),
_activeFeedView(nullptr),
+ _repo(nullptr),
+ _documentType(nullptr),
_bucketDBHandler(nullptr),
_syncLock(),
_syncedSerialNum(0),
@@ -408,6 +418,14 @@ void FeedHandler::changeToNormalFeedState() {
changeFeedState(make_shared<NormalState>(*this));
}
+void
+FeedHandler::setActiveFeedView(IFeedView *feedView)
+{
+ _activeFeedView = feedView;
+ _repo = feedView->getDocumentTypeRepo().get();
+ _documentType = _repo->getDocumentType(_docTypeName.getName());
+}
+
bool
FeedHandler::isDoingReplay() const {
return _tlsMgr.isDoingReplay();
@@ -492,22 +510,17 @@ FeedHandler::considerWriteOperationForRejection(FeedToken & token, const FeedOpe
}
bool
-FeedHandler::considerUpdateOperationForRejection(FeedToken &token, const UpdateOperation &op)
+FeedHandler::considerUpdateOperationForRejection(FeedToken &token, UpdateOperation &op)
{
- const auto *repo = _activeFeedView->getDocumentTypeRepo().get();
const auto &update = *op.getUpdate();
/*
* Check if document types are equal. DocumentTypeRepoFactory::make returns
* the same document type repo if document type configs are equal, thus we
* can just perform a cheaper identity check here.
*/
- if (repo->getDocumentType(_docTypeName.getName()) != &update.getType()) {
+ if (_documentType != &update.getType()) {
try {
- vespalib::nbostream stream;
- op.serialize(stream);
- UpdateOperation checkOp(op.getType());
- vespalib::nbostream checkStream(stream.peek(), stream.size());
- checkOp.deserialize(stream, *repo);
+ op.deserializeUpdate(*_repo);
} catch (document::FieldNotFoundException &e) {
if (token) {
auto message = make_string("Update operation rejected for document '%s' of type '%s': 'Field not found'",
@@ -516,6 +529,14 @@ FeedHandler::considerUpdateOperationForRejection(FeedToken &token, const UpdateO
token->fail();
}
return true;
+ } catch (document::DocumentTypeNotFoundException &e) {
+ auto message = make_string("Update operation rejected for document '%s' of type '%s': 'Uknown document type', expected '%s'",
+ update.getId().toString().c_str(),
+ e.getDocumentTypeName().c_str(),
+ _docTypeName.toString().c_str());
+ token->setResult(make_unique<UpdateResult>(Result::TRANSIENT_ERROR, message), false);
+ token->fail();
+ return true;
}
}
return false;
diff --git a/searchcore/src/vespa/searchcore/proton/server/feedhandler.h b/searchcore/src/vespa/searchcore/proton/server/feedhandler.h
index faf909080d9..34f979b7115 100644
--- a/searchcore/src/vespa/searchcore/proton/server/feedhandler.h
+++ b/searchcore/src/vespa/searchcore/proton/server/feedhandler.h
@@ -90,6 +90,8 @@ private:
FeedStateSP _feedState;
// used by master write thread tasks
IFeedView *_activeFeedView;
+ const document::DocumentTypeRepo *_repo;
+ const document::DocumentType *_documentType;
bucketdb::IBucketDBHandler *_bucketDBHandler;
std::mutex _syncLock;
SerialNum _syncedSerialNum;
@@ -102,7 +104,7 @@ private:
void doHandleOperation(FeedToken token, FeedOperationUP op);
bool considerWriteOperationForRejection(FeedToken & token, const FeedOperation &op);
- bool considerUpdateOperationForRejection(FeedToken &token, const UpdateOperation &op);
+ bool considerUpdateOperationForRejection(FeedToken &token, UpdateOperation &op);
/**
* Delayed execution of feed operations against feed view, in
@@ -203,9 +205,7 @@ public:
* Update the active feed view.
* Always called by the master write thread so locking is not needed.
*/
- void setActiveFeedView(IFeedView *feedView) {
- _activeFeedView = feedView;
- }
+ void setActiveFeedView(IFeedView *feedView);
void setBucketDBHandler(bucketdb::IBucketDBHandler *bucketDBHandler) {
_bucketDBHandler = bucketDBHandler;
diff --git a/searchcorespi/src/vespa/searchcorespi/index/indexcollection.cpp b/searchcorespi/src/vespa/searchcorespi/index/indexcollection.cpp
index 8c8ea8e6f28..de4cde956d0 100644
--- a/searchcorespi/src/vespa/searchcorespi/index/indexcollection.cpp
+++ b/searchcorespi/src/vespa/searchcorespi/index/indexcollection.cpp
@@ -179,28 +179,30 @@ private:
_result = mixer.mix();
}
- virtual void visit(And &) override { }
- virtual void visit(AndNot &) override { }
- virtual void visit(Or &) override { }
- virtual void visit(WeakAnd &) override { }
- virtual void visit(Equiv &) override { }
- virtual void visit(Rank &) override { }
- virtual void visit(Near &) override { }
- virtual void visit(ONear &) override { }
-
- virtual void visit(WeightedSetTerm &n) override { visitTerm(n); }
- virtual void visit(DotProduct &n) override { visitTerm(n); }
- virtual void visit(WandTerm &n) override { visitTerm(n); }
- virtual void visit(Phrase &n) override { visitTerm(n); }
- virtual void visit(NumberTerm &n) override { visitTerm(n); }
- virtual void visit(LocationTerm &n) override { visitTerm(n); }
- virtual void visit(PrefixTerm &n) override { visitTerm(n); }
- virtual void visit(RangeTerm &n) override { visitTerm(n); }
- virtual void visit(StringTerm &n) override { visitTerm(n); }
- virtual void visit(SubstringTerm &n) override { visitTerm(n); }
- virtual void visit(SuffixTerm &n) override { visitTerm(n); }
- virtual void visit(PredicateQuery &n) override { visitTerm(n); }
- virtual void visit(RegExpTerm &n) override { visitTerm(n); }
+ void visit(And &) override { }
+ void visit(AndNot &) override { }
+ void visit(Or &) override { }
+ void visit(WeakAnd &) override { }
+ void visit(Equiv &) override { }
+ void visit(Rank &) override { }
+ void visit(Near &) override { }
+ void visit(ONear &) override { }
+ void visit(SameElement &) override { }
+
+
+ void visit(WeightedSetTerm &n) override { visitTerm(n); }
+ void visit(DotProduct &n) override { visitTerm(n); }
+ void visit(WandTerm &n) override { visitTerm(n); }
+ void visit(Phrase &n) override { visitTerm(n); }
+ void visit(NumberTerm &n) override { visitTerm(n); }
+ void visit(LocationTerm &n) override { visitTerm(n); }
+ void visit(PrefixTerm &n) override { visitTerm(n); }
+ void visit(RangeTerm &n) override { visitTerm(n); }
+ void visit(StringTerm &n) override { visitTerm(n); }
+ void visit(SubstringTerm &n) override { visitTerm(n); }
+ void visit(SuffixTerm &n) override { visitTerm(n); }
+ void visit(PredicateQuery &n) override { visitTerm(n); }
+ void visit(RegExpTerm &n) override { visitTerm(n); }
public:
CreateBlueprintVisitor(const IIndexCollection &indexes,
diff --git a/searchlib/src/tests/query/customtypevisitor_test.cpp b/searchlib/src/tests/query/customtypevisitor_test.cpp
index 5aabb328354..a941694d375 100644
--- a/searchlib/src/tests/query/customtypevisitor_test.cpp
+++ b/searchlib/src/tests/query/customtypevisitor_test.cpp
@@ -1,14 +1,14 @@
// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
// Unit tests for customtypevisitor.
-#include <vespa/log/log.h>
-LOG_SETUP("customtypevisitor_test");
-
#include <vespa/searchlib/query/tree/customtypevisitor.h>
#include <vespa/searchlib/query/tree/intermediatenodes.h>
#include <vespa/searchlib/query/tree/termnodes.h>
#include <vespa/vespalib/testkit/testapp.h>
+#include <vespa/log/log.h>
+LOG_SETUP("customtypevisitor_test");
+
using std::string;
using namespace search::query;
@@ -39,6 +39,7 @@ struct MyNear : Near { MyNear() : Near(1) {} };
struct MyONear : ONear { MyONear() : ONear(1) {} };
struct MyOr : Or {};
struct MyPhrase : Phrase { MyPhrase() : Phrase("view", 0, Weight(42)) {} };
+struct MySameElement : SameElement { MySameElement() : SameElement("view") {} };
struct MyRank : Rank {};
struct MyNumberTerm : InitTerm<NumberTerm> {};
struct MyLocationTerm : InitTerm<LocationTerm> {};
@@ -64,6 +65,7 @@ struct MyQueryNodeTypes {
typedef MyONear ONear;
typedef MyOr Or;
typedef MyPhrase Phrase;
+ typedef MySameElement SameElement;
typedef MyPrefixTerm PrefixTerm;
typedef MyRangeTerm RangeTerm;
typedef MyRank Rank;
@@ -89,27 +91,28 @@ public:
template <typename T> void setVisited() { isVisited<T>() = true; }
- virtual void visit(MyAnd &) override { setVisited<MyAnd>(); }
- virtual void visit(MyAndNot &) override { setVisited<MyAndNot>(); }
- virtual void visit(MyEquiv &) override { setVisited<MyEquiv>(); }
- virtual void visit(MyNumberTerm &) override { setVisited<MyNumberTerm>(); }
- virtual void visit(MyLocationTerm &) override { setVisited<MyLocationTerm>(); }
- virtual void visit(MyNear &) override { setVisited<MyNear>(); }
- virtual void visit(MyONear &) override { setVisited<MyONear>(); }
- virtual void visit(MyOr &) override { setVisited<MyOr>(); }
- virtual void visit(MyPhrase &) override { setVisited<MyPhrase>(); }
- virtual void visit(MyPrefixTerm &) override { setVisited<MyPrefixTerm>(); }
- virtual void visit(MyRangeTerm &) override { setVisited<MyRangeTerm>(); }
- virtual void visit(MyRank &) override { setVisited<MyRank>(); }
- virtual void visit(MyStringTerm &) override { setVisited<MyStringTerm>(); }
- virtual void visit(MySubstrTerm &) override { setVisited<MySubstrTerm>(); }
- virtual void visit(MySuffixTerm &) override { setVisited<MySuffixTerm>(); }
- virtual void visit(MyWeakAnd &) override { setVisited<MyWeakAnd>(); }
- virtual void visit(MyWeightedSetTerm &) override { setVisited<MyWeightedSetTerm>(); }
- virtual void visit(MyDotProduct &) override { setVisited<MyDotProduct>(); }
- virtual void visit(MyWandTerm &) override { setVisited<MyWandTerm>(); }
- virtual void visit(MyPredicateQuery &) override { setVisited<MyPredicateQuery>(); }
- virtual void visit(MyRegExpTerm &) override { setVisited<MyRegExpTerm>(); }
+ void visit(MyAnd &) override { setVisited<MyAnd>(); }
+ void visit(MyAndNot &) override { setVisited<MyAndNot>(); }
+ void visit(MyEquiv &) override { setVisited<MyEquiv>(); }
+ void visit(MyNumberTerm &) override { setVisited<MyNumberTerm>(); }
+ void visit(MyLocationTerm &) override { setVisited<MyLocationTerm>(); }
+ void visit(MyNear &) override { setVisited<MyNear>(); }
+ void visit(MyONear &) override { setVisited<MyONear>(); }
+ void visit(MyOr &) override { setVisited<MyOr>(); }
+ void visit(MyPhrase &) override { setVisited<MyPhrase>(); }
+ void visit(MySameElement &) override { setVisited<MySameElement>(); }
+ void visit(MyPrefixTerm &) override { setVisited<MyPrefixTerm>(); }
+ void visit(MyRangeTerm &) override { setVisited<MyRangeTerm>(); }
+ void visit(MyRank &) override { setVisited<MyRank>(); }
+ void visit(MyStringTerm &) override { setVisited<MyStringTerm>(); }
+ void visit(MySubstrTerm &) override { setVisited<MySubstrTerm>(); }
+ void visit(MySuffixTerm &) override { setVisited<MySuffixTerm>(); }
+ void visit(MyWeakAnd &) override { setVisited<MyWeakAnd>(); }
+ void visit(MyWeightedSetTerm &) override { setVisited<MyWeightedSetTerm>(); }
+ void visit(MyDotProduct &) override { setVisited<MyDotProduct>(); }
+ void visit(MyWandTerm &) override { setVisited<MyWandTerm>(); }
+ void visit(MyPredicateQuery &) override { setVisited<MyPredicateQuery>(); }
+ void visit(MyRegExpTerm &) override { setVisited<MyRegExpTerm>(); }
};
template <class T>
diff --git a/searchlib/src/tests/query/query_visitor_test.cpp b/searchlib/src/tests/query/query_visitor_test.cpp
index 9e82c6ea5ec..f8922c54a4e 100644
--- a/searchlib/src/tests/query/query_visitor_test.cpp
+++ b/searchlib/src/tests/query/query_visitor_test.cpp
@@ -1,9 +1,6 @@
// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
// Unit tests for query_visitor.
-#include <vespa/log/log.h>
-LOG_SETUP("query_visitor_test");
-
#include <vespa/searchlib/query/tree/intermediatenodes.h>
#include <vespa/searchlib/query/tree/point.h>
#include <vespa/searchlib/query/tree/queryvisitor.h>
@@ -11,6 +8,9 @@ LOG_SETUP("query_visitor_test");
#include <vespa/searchlib/query/tree/termnodes.h>
#include <vespa/vespalib/testkit/testapp.h>
+#include <vespa/log/log.h>
+LOG_SETUP("query_visitor_test");
+
using namespace search::query;
namespace {
@@ -43,29 +43,28 @@ public:
return b;
}
- virtual void visit(And &) override { isVisited<And>() = true; }
- virtual void visit(AndNot &) override { isVisited<AndNot>() = true; }
- virtual void visit(Equiv &) override { isVisited<Equiv>() = true; }
- virtual void visit(NumberTerm &) override { isVisited<NumberTerm>() = true; }
- virtual void visit(LocationTerm &) override { isVisited<LocationTerm>() = true; }
- virtual void visit(Near &) override { isVisited<Near>() = true; }
- virtual void visit(ONear &) override { isVisited<ONear>() = true; }
- virtual void visit(Or &) override { isVisited<Or>() = true; }
- virtual void visit(Phrase &) override { isVisited<Phrase>() = true; }
- virtual void visit(PrefixTerm &) override { isVisited<PrefixTerm>() = true; }
- virtual void visit(RangeTerm &) override { isVisited<RangeTerm>() = true; }
- virtual void visit(Rank &) override { isVisited<Rank>() = true; }
- virtual void visit(StringTerm &) override { isVisited<StringTerm>() = true; }
- virtual void visit(SubstringTerm &) override { isVisited<SubstringTerm>() = true; }
- virtual void visit(SuffixTerm &) override { isVisited<SuffixTerm>() = true; }
- virtual void visit(WeakAnd &) override { isVisited<WeakAnd>() = true; }
- virtual void visit(WeightedSetTerm &) override
- { isVisited<WeightedSetTerm>() = true; }
- virtual void visit(DotProduct &) override { isVisited<DotProduct>() = true; }
- virtual void visit(WandTerm &) override { isVisited<WandTerm>() = true; }
- virtual void visit(PredicateQuery &) override
- { isVisited<PredicateQuery>() = true; }
- virtual void visit(RegExpTerm &) override { isVisited<RegExpTerm>() = true; }
+ void visit(And &) override { isVisited<And>() = true; }
+ void visit(AndNot &) override { isVisited<AndNot>() = true; }
+ void visit(Equiv &) override { isVisited<Equiv>() = true; }
+ void visit(NumberTerm &) override { isVisited<NumberTerm>() = true; }
+ void visit(LocationTerm &) override { isVisited<LocationTerm>() = true; }
+ void visit(Near &) override { isVisited<Near>() = true; }
+ void visit(ONear &) override { isVisited<ONear>() = true; }
+ void visit(Or &) override { isVisited<Or>() = true; }
+ void visit(Phrase &) override { isVisited<Phrase>() = true; }
+ void visit(SameElement &) override { isVisited<SameElement>() = true; }
+ void visit(PrefixTerm &) override { isVisited<PrefixTerm>() = true; }
+ void visit(RangeTerm &) override { isVisited<RangeTerm>() = true; }
+ void visit(Rank &) override { isVisited<Rank>() = true; }
+ void visit(StringTerm &) override { isVisited<StringTerm>() = true; }
+ void visit(SubstringTerm &) override { isVisited<SubstringTerm>() = true; }
+ void visit(SuffixTerm &) override { isVisited<SuffixTerm>() = true; }
+ void visit(WeakAnd &) override { isVisited<WeakAnd>() = true; }
+ void visit(WeightedSetTerm &) override { isVisited<WeightedSetTerm>() = true; }
+ void visit(DotProduct &) override { isVisited<DotProduct>() = true; }
+ void visit(WandTerm &) override { isVisited<WandTerm>() = true; }
+ void visit(PredicateQuery &) override { isVisited<PredicateQuery>() = true; }
+ void visit(RegExpTerm &) override { isVisited<RegExpTerm>() = true; }
};
template <class T>
@@ -84,27 +83,20 @@ void Test::requireThatAllNodesCanBeVisited() {
checkVisit<ONear>(new SimpleONear(0));
checkVisit<Or>(new SimpleOr);
checkVisit<Phrase>(new SimplePhrase("field", 0, Weight(42)));
- checkVisit<WeightedSetTerm>(
- new SimpleWeightedSetTerm("field", 0, Weight(42)));
+ checkVisit<SameElement>(new SimpleSameElement("field"));
+ checkVisit<WeightedSetTerm>(new SimpleWeightedSetTerm("field", 0, Weight(42)));
checkVisit<DotProduct>(new SimpleDotProduct("field", 0, Weight(42)));
- checkVisit<WandTerm>(
- new SimpleWandTerm("field", 0, Weight(42), 57, 67, 77.7));
+ checkVisit<WandTerm>(new SimpleWandTerm("field", 0, Weight(42), 57, 67, 77.7));
checkVisit<Rank>(new SimpleRank);
- checkVisit<NumberTerm>(
- new SimpleNumberTerm("0.42", "field", 0, Weight(0)));
+ checkVisit<NumberTerm>(new SimpleNumberTerm("0.42", "field", 0, Weight(0)));
const Location location(Point(10, 10), 20, 0);
- checkVisit<LocationTerm>(
- new SimpleLocationTerm(location, "field", 0, Weight(0)));
+ checkVisit<LocationTerm>(new SimpleLocationTerm(location, "field", 0, Weight(0)));
checkVisit<PrefixTerm>(new SimplePrefixTerm("t", "field", 0, Weight(0)));
- checkVisit<RangeTerm>(
- new SimpleRangeTerm(Range(0, 1), "field", 0, Weight(0)));
+ checkVisit<RangeTerm>(new SimpleRangeTerm(Range(0, 1), "field", 0, Weight(0)));
checkVisit<StringTerm>(new SimpleStringTerm("t", "field", 0, Weight(0)));
- checkVisit<SubstringTerm>(
- new SimpleSubstringTerm("t", "field", 0, Weight(0)));
+ checkVisit<SubstringTerm>(new SimpleSubstringTerm("t", "field", 0, Weight(0)));
checkVisit<SuffixTerm>(new SimpleSuffixTerm("t", "field", 0, Weight(0)));
- checkVisit<PredicateQuery>(
- new SimplePredicateQuery(PredicateQueryTerm::UP(),
- "field", 0, Weight(0)));
+ checkVisit<PredicateQuery>(new SimplePredicateQuery(PredicateQueryTerm::UP(), "field", 0, Weight(0)));
checkVisit<RegExpTerm>(new SimpleRegExpTerm("t", "field", 0, Weight(0)));
}
diff --git a/searchlib/src/tests/query/querybuilder_test.cpp b/searchlib/src/tests/query/querybuilder_test.cpp
index b968f794833..0f05419c4e5 100644
--- a/searchlib/src/tests/query/querybuilder_test.cpp
+++ b/searchlib/src/tests/query/querybuilder_test.cpp
@@ -1,22 +1,18 @@
// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
// Unit tests for querybuilder.
-#include <vespa/log/log.h>
-LOG_SETUP("querybuilder_test");
-
#include <vespa/searchlib/parsequery/parse.h>
#include <vespa/searchlib/parsequery/simplequerystack.h>
#include <vespa/searchlib/query/tree/customtypevisitor.h>
-#include <vespa/searchlib/query/tree/intermediatenodes.h>
#include <vespa/searchlib/query/tree/point.h>
#include <vespa/searchlib/query/tree/querybuilder.h>
-#include <vespa/searchlib/query/tree/querytreecreator.h>
#include <vespa/searchlib/query/tree/simplequery.h>
#include <vespa/searchlib/query/tree/stackdumpcreator.h>
-#include <vespa/searchlib/query/tree/termnodes.h>
-#include <vespa/searchlib/util/rawbuf.h>
#include <vespa/vespalib/testkit/test_kit.h>
-#include <string>
+
+#include <vespa/log/log.h>
+LOG_SETUP("querybuilder_test");
+#include <vespa/searchlib/query/tree/querytreecreator.h>
using std::string;
using search::SimpleQueryStackDumpIterator;
@@ -52,7 +48,7 @@ PredicateQueryTerm::UP getPredicateQueryTerm() {
template <class NodeTypes>
Node::UP createQueryTree() {
QueryBuilder<NodeTypes> builder;
- builder.addAnd(9);
+ builder.addAnd(10);
{
builder.addRank(2);
{
@@ -109,6 +105,12 @@ Node::UP createQueryTree() {
builder.addStringTerm(str[2], view[2], id[2], weight[2]);
}
builder.addRegExpTerm(str[5], view[5], id[5], weight[5]);
+ builder.addSameElement(3, view[4]);
+ {
+ builder.addStringTerm(str[4], view[4], id[4], weight[5]);
+ builder.addStringTerm(str[5], view[5], id[5], weight[6]);
+ builder.addStringTerm(str[6], view[6], id[6], weight[7]);
+ }
}
Node::UP node = builder.build();
ASSERT_TRUE(node.get());
@@ -146,6 +148,7 @@ void checkQueryTreeTypes(Node *node) {
//typedef typename NodeTypes::NumberTerm FloatTrm;
typedef typename NodeTypes::Near Near;
typedef typename NodeTypes::ONear ONear;
+ typedef typename NodeTypes::SameElement SameElement;
typedef typename NodeTypes::Or Or;
typedef typename NodeTypes::Phrase Phrase;
typedef typename NodeTypes::PrefixTerm PrefixTerm;
@@ -165,7 +168,7 @@ void checkQueryTreeTypes(Node *node) {
ASSERT_TRUE(node);
And *and_node = dynamic_cast<And *>(node);
ASSERT_TRUE(and_node);
- EXPECT_EQUAL(9u, and_node->getChildren().size());
+ EXPECT_EQUAL(10u, and_node->getChildren().size());
Rank *rank = dynamic_cast<Rank *>(and_node->getChildren()[0]);
@@ -176,22 +179,18 @@ void checkQueryTreeTypes(Node *node) {
ASSERT_TRUE(near);
EXPECT_EQUAL(2u, near->getChildren().size());
EXPECT_EQUAL(distance, near->getDistance());
- StringTerm *string_term =
- dynamic_cast<StringTerm *>(near->getChildren()[0]);
+ StringTerm *string_term = dynamic_cast<StringTerm *>(near->getChildren()[0]);
EXPECT_TRUE(checkTerm(string_term, str[0], view[0], id[0], weight[0]));
- SubstringTerm *substring_term =
- dynamic_cast<SubstringTerm *>(near->getChildren()[1]);
+ SubstringTerm *substring_term = dynamic_cast<SubstringTerm *>(near->getChildren()[1]);
EXPECT_TRUE(checkTerm(substring_term, str[1], view[1], id[1], weight[1]));
ONear *onear = dynamic_cast<ONear *>(rank->getChildren()[1]);
ASSERT_TRUE(onear);
EXPECT_EQUAL(2u, onear->getChildren().size());
EXPECT_EQUAL(distance, onear->getDistance());
- SuffixTerm *suffix_term =
- dynamic_cast<SuffixTerm *>(onear->getChildren()[0]);
+ SuffixTerm *suffix_term = dynamic_cast<SuffixTerm *>(onear->getChildren()[0]);
EXPECT_TRUE(checkTerm(suffix_term, str[2], view[2], id[2], weight[2]));
- PrefixTerm *prefix_term =
- dynamic_cast<PrefixTerm *>(onear->getChildren()[1]);
+ PrefixTerm *prefix_term = dynamic_cast<PrefixTerm *>(onear->getChildren()[1]);
EXPECT_TRUE(checkTerm(prefix_term, str[3], view[3], id[3], weight[3]));
@@ -224,26 +223,20 @@ void checkQueryTreeTypes(Node *node) {
AndNot *and_not = dynamic_cast<AndNot *>(or_node->getChildren()[2]);
ASSERT_TRUE(and_not);
EXPECT_EQUAL(2u, and_not->getChildren().size());
- NumberTerm *integer_term =
- dynamic_cast<NumberTerm *>(and_not->getChildren()[0]);
+ NumberTerm *integer_term = dynamic_cast<NumberTerm *>(and_not->getChildren()[0]);
EXPECT_TRUE(checkTerm(integer_term, int1, view[7], id[7], weight[7]));
- NumberTerm *float_term =
- dynamic_cast<NumberTerm *>(and_not->getChildren()[1]);
- EXPECT_TRUE(checkTerm(float_term, float1, view[8], id[8], weight[8],
- false));
+ NumberTerm *float_term = dynamic_cast<NumberTerm *>(and_not->getChildren()[1]);
+ EXPECT_TRUE(checkTerm(float_term, float1, view[8], id[8], weight[8], false));
- RangeTerm *range_term =
- dynamic_cast<RangeTerm *>(and_node->getChildren()[2]);
+ RangeTerm *range_term = dynamic_cast<RangeTerm *>(and_node->getChildren()[2]);
ASSERT_TRUE(range_term);
EXPECT_TRUE(checkTerm(range_term, range, view[9], id[9], weight[9]));
- LocationTerm *loc_term =
- dynamic_cast<LocationTerm *>(and_node->getChildren()[3]);
+ LocationTerm *loc_term = dynamic_cast<LocationTerm *>(and_node->getChildren()[3]);
ASSERT_TRUE(loc_term);
EXPECT_TRUE(checkTerm(loc_term, location, view[10], id[10], weight[10]));
-
WeakAnd *wand = dynamic_cast<WeakAnd *>(and_node->getChildren()[4]);
ASSERT_TRUE(wand != 0);
EXPECT_EQUAL(123u, wand->getMinHits());
@@ -253,15 +246,12 @@ void checkQueryTreeTypes(Node *node) {
string_term = dynamic_cast<StringTerm *>(wand->getChildren()[1]);
EXPECT_TRUE(checkTerm(string_term, str[5], view[5], id[5], weight[5]));
- PredicateQuery *predicateQuery =
- dynamic_cast<PredicateQuery *>(and_node->getChildren()[5]);
+ PredicateQuery *predicateQuery = dynamic_cast<PredicateQuery *>(and_node->getChildren()[5]);
ASSERT_TRUE(predicateQuery);
PredicateQueryTerm::UP pqt(new PredicateQueryTerm);
- EXPECT_TRUE(checkTerm(predicateQuery, getPredicateQueryTerm(),
- view[3], id[3], weight[3]));
+ EXPECT_TRUE(checkTerm(predicateQuery, getPredicateQueryTerm(), view[3], id[3], weight[3]));
- DotProduct *dotProduct =
- dynamic_cast<DotProduct *>(and_node->getChildren()[6]);
+ DotProduct *dotProduct = dynamic_cast<DotProduct *>(and_node->getChildren()[6]);
ASSERT_TRUE(dotProduct);
EXPECT_EQUAL(3u, dotProduct->getChildren().size());
string_term = dynamic_cast<StringTerm *>(dotProduct->getChildren()[0]);
@@ -282,9 +272,20 @@ void checkQueryTreeTypes(Node *node) {
string_term = dynamic_cast<StringTerm *>(wandTerm->getChildren()[1]);
EXPECT_TRUE(checkTerm(string_term, str[2], view[2], id[2], weight[2]));
- RegExpTerm *regexp_term =
- dynamic_cast<RegExpTerm *>(and_node->getChildren()[8]);
+ RegExpTerm *regexp_term = dynamic_cast<RegExpTerm *>(and_node->getChildren()[8]);
EXPECT_TRUE(checkTerm(regexp_term, str[5], view[5], id[5], weight[5]));
+
+ SameElement *same = dynamic_cast<SameElement *>(and_node->getChildren()[9]);
+ ASSERT_TRUE(same != nullptr);
+ EXPECT_EQUAL(view[4], same->getView());
+ EXPECT_EQUAL(3u, same->getChildren().size());
+ string_term = dynamic_cast<StringTerm *>(same->getChildren()[0]);
+ EXPECT_TRUE(checkTerm(string_term, str[4], view[4], id[4], weight[5]));
+ string_term = dynamic_cast<StringTerm *>(same->getChildren()[1]);
+ EXPECT_TRUE(checkTerm(string_term, str[5], view[5], id[5], weight[6]));
+ string_term = dynamic_cast<StringTerm *>(same->getChildren()[2]);
+ EXPECT_TRUE(checkTerm(string_term, str[6], view[6], id[6], weight[7]));
+
}
struct AbstractTypes {
@@ -294,6 +295,7 @@ struct AbstractTypes {
typedef search::query::LocationTerm LocationTerm;
typedef search::query::Near Near;
typedef search::query::ONear ONear;
+ typedef search::query::SameElement SameElement;
typedef search::query::Or Or;
typedef search::query::Phrase Phrase;
typedef search::query::PrefixTerm PrefixTerm;
@@ -333,9 +335,9 @@ struct MyNear : Near { MyNear(size_t dist) : Near(dist) {} };
struct MyONear : ONear { MyONear(size_t dist) : ONear(dist) {} };
struct MyWeakAnd : WeakAnd { MyWeakAnd(uint32_t minHits, const vespalib::string & v) : WeakAnd(minHits, v) {} };
struct MyOr : Or {};
-struct MyPhrase : Phrase {
- MyPhrase(const string &f, int32_t i, Weight w) : Phrase(f, i, w) {}
-};
+struct MyPhrase : Phrase { MyPhrase(const string &f, int32_t i, Weight w) : Phrase(f, i, w) {}};
+struct MySameElement : SameElement { MySameElement(const string &f) : SameElement(f) {}};
+
struct MyWeightedSetTerm : WeightedSetTerm {
MyWeightedSetTerm(const string &f, int32_t i, Weight w) : WeightedSetTerm(f, i, w) {}
};
@@ -404,6 +406,7 @@ struct MyQueryNodeTypes {
typedef MyONear ONear;
typedef MyOr Or;
typedef MyPhrase Phrase;
+ typedef MySameElement SameElement;
typedef MyPrefixTerm PrefixTerm;
typedef MyRangeTerm RangeTerm;
typedef MyRank Rank;
@@ -556,8 +559,7 @@ TEST("require that Query Tree Creator Can Create Queries From Stack") {
string stackDump = StackDumpCreator::create(*node);
SimpleQueryStackDumpIterator iterator(stackDump);
- Node::UP new_node =
- QueryTreeCreator<SimpleQueryNodeTypes>::create(iterator);
+ Node::UP new_node = QueryTreeCreator<SimpleQueryNodeTypes>::create(iterator);
checkQueryTreeTypes<SimpleQueryNodeTypes>(new_node.get());
}
diff --git a/searchlib/src/tests/stackdumpiterator/stackdumpiteratortest.cpp b/searchlib/src/tests/stackdumpiterator/stackdumpiteratortest.cpp
index d3a99dc439a..8ad4578b6c1 100644
--- a/searchlib/src/tests/stackdumpiterator/stackdumpiteratortest.cpp
+++ b/searchlib/src/tests/stackdumpiterator/stackdumpiteratortest.cpp
@@ -244,6 +244,7 @@ StackDumpIteratorTest::RunTest(int testno, bool verify)
stack.Push(new search::ParseItem(search::ParseItem::ITEM_NUMTERM, "foo", "[0;22]"));
stack.Push(new search::ParseItem(search::ParseItem::ITEM_PREFIXTERM, "bar", "baz"));
stack.Push(new search::ParseItem(search::ParseItem::ITEM_PHRASE, 3, "bar"));
+ stack.Push(new search::ParseItem(search::ParseItem::ITEM_SAME_ELEMENT, 3, "bar"));
stack.Push(new search::ParseItem(search::ParseItem::ITEM_OR, 2));
stack.Push(new search::ParseItem(search::ParseItem::ITEM_AND, 3));
stack.Push(new search::ParseItem(search::ParseItem::ITEM_RANK, 5));
diff --git a/searchlib/src/vespa/searchlib/features/distancetopathfeature.cpp b/searchlib/src/vespa/searchlib/features/distancetopathfeature.cpp
index 4f4491327e7..834f5913af9 100644
--- a/searchlib/src/vespa/searchlib/features/distancetopathfeature.cpp
+++ b/searchlib/src/vespa/searchlib/features/distancetopathfeature.cpp
@@ -14,8 +14,7 @@
#include <vespa/log/log.h>
LOG_SETUP(".features.distancetopathfeature");
-namespace search {
-namespace features {
+namespace search::features {
const feature_t DistanceToPathExecutor::DEFAULT_DISTANCE(6400000000.0);
@@ -96,9 +95,7 @@ DistanceToPathBlueprint::DistanceToPathBlueprint() :
{
}
-DistanceToPathBlueprint::~DistanceToPathBlueprint()
-{
-}
+DistanceToPathBlueprint::~DistanceToPathBlueprint() = default;
void
DistanceToPathBlueprint::visitDumpFeatures(const search::fef::IIndexEnvironment &,
@@ -175,5 +172,4 @@ DistanceToPathBlueprint::createExecutor(const search::fef::IQueryEnvironment &en
return stash.create<DistanceToPathExecutor>(path, pos);
}
-} // namespace features
-} // namespace search
+}
diff --git a/searchlib/src/vespa/searchlib/features/distancetopathfeature.h b/searchlib/src/vespa/searchlib/features/distancetopathfeature.h
index cf268c59a2e..442f1ba3b28 100644
--- a/searchlib/src/vespa/searchlib/features/distancetopathfeature.h
+++ b/searchlib/src/vespa/searchlib/features/distancetopathfeature.h
@@ -6,8 +6,7 @@
#include <vespa/searchlib/fef/featureexecutor.h>
#include <vespa/searchlib/common/feature.h>
-namespace search {
-namespace features {
+namespace search::features {
/**
* Define the point type that makes up the end-points in our path.
@@ -52,7 +51,7 @@ private:
public:
DistanceToPathBlueprint();
- ~DistanceToPathBlueprint();
+ ~DistanceToPathBlueprint() override;
void visitDumpFeatures(const fef::IIndexEnvironment &env, fef::IDumpFeatureVisitor &visitor) const override;
fef::Blueprint::UP createInstance() const override;
fef::ParameterDescriptions getDescriptions() const override {
@@ -64,6 +63,4 @@ public:
};
-} // namespace features
-} // namespace search
-
+}
diff --git a/searchlib/src/vespa/searchlib/parsequery/parse.cpp b/searchlib/src/vespa/searchlib/parsequery/parse.cpp
index b189331878c..cba69ea474a 100644
--- a/searchlib/src/vespa/searchlib/parsequery/parse.cpp
+++ b/searchlib/src/vespa/searchlib/parsequery/parse.cpp
@@ -24,9 +24,8 @@ namespace search {
ParseItem::ParseItem(ItemType type, int arity)
: PARSEITEM_DEFAULT_CONSTRUCTOR_LIST
{
- assert(type==ITEM_OR || type==ITEM_WEAK_AND || type==ITEM_EQUIV ||
- type==ITEM_AND || type==ITEM_NOT || type==ITEM_RANK ||
- type==ITEM_PHRASE || type==ITEM_ANY || type==ITEM_NEAR || type==ITEM_ONEAR);
+ assert(type==ITEM_OR || type==ITEM_WEAK_AND || type==ITEM_EQUIV || type==ITEM_AND || type==ITEM_NOT
+ || type==ITEM_RANK || type==ITEM_ANY || type==ITEM_NEAR || type==ITEM_ONEAR);
SetType(type);
_arity = arity;
}
@@ -34,7 +33,8 @@ ParseItem::ParseItem(ItemType type, int arity)
ParseItem::ParseItem(ItemType type, int arity, const char *idx)
: PARSEITEM_DEFAULT_CONSTRUCTOR_LIST
{
- assert(type == ITEM_PHRASE || type==ITEM_WEIGHTED_SET || type==ITEM_DOT_PRODUCT || type==ITEM_WAND);
+ assert(type==ITEM_PHRASE || type==ITEM_SAME_ELEMENT || type==ITEM_WEIGHTED_SET
+ || type==ITEM_DOT_PRODUCT || type==ITEM_WAND);
SetType(type);
_arity = arity;
SetIndex(idx);
@@ -108,16 +108,24 @@ ParseItem::AppendBuffer(RawBuf *buf) const
case ITEM_ANY:
buf->appendCompressedPositiveNumber(_arity);
break;
- case ITEM_WEAK_AND:
case ITEM_NEAR:
case ITEM_ONEAR:
buf->appendCompressedPositiveNumber(_arity);
buf->appendCompressedPositiveNumber(_arg1);
- if (Type() == ITEM_WEAK_AND) {
- buf->appendCompressedPositiveNumber(indexLen);
- if (indexLen != 0) {
- buf->append(_indexName.c_str(), indexLen);
- }
+ break;
+ case ITEM_SAME_ELEMENT:
+ buf->appendCompressedPositiveNumber(_arity);
+ buf->appendCompressedPositiveNumber(indexLen);
+ if (indexLen != 0) {
+ buf->append(_indexName.c_str(), indexLen);
+ }
+ break;
+ case ITEM_WEAK_AND:
+ buf->appendCompressedPositiveNumber(_arity);
+ buf->appendCompressedPositiveNumber(_arg1);
+ buf->appendCompressedPositiveNumber(indexLen);
+ if (indexLen != 0) {
+ buf->append(_indexName.c_str(), indexLen);
}
break;
case ITEM_WEIGHTED_SET:
@@ -199,6 +207,9 @@ ParseItem::GetBufferLen() const
case ITEM_PHRASE:
len += sizeof(uint32_t) * 2 + indexLen;
break;
+ case ITEM_SAME_ELEMENT:
+ len += sizeof(uint32_t) * 2 + indexLen;
+ break;
case ITEM_WAND:
len += sizeof(uint32_t) * 4 + indexLen;
break;
diff --git a/searchlib/src/vespa/searchlib/parsequery/parse.h b/searchlib/src/vespa/searchlib/parsequery/parse.h
index 3d5a1a5e2bb..d8cbdc696a5 100644
--- a/searchlib/src/vespa/searchlib/parsequery/parse.h
+++ b/searchlib/src/vespa/searchlib/parsequery/parse.h
@@ -52,7 +52,7 @@ public:
ITEM_WEIGHTED_SET = 15,
ITEM_WEAK_AND = 16,
ITEM_EXACTSTRINGTERM = 17,
- UNUSED_LEGACY_ITEM_RISE_QUERY = 18,
+ ITEM_SAME_ELEMENT = 18,
ITEM_PURE_WEIGHTED_STRING = 19,
ITEM_PURE_WEIGHTED_LONG = 20,
ITEM_DOT_PRODUCT = 21,
diff --git a/searchlib/src/vespa/searchlib/parsequery/simplequerystack.cpp b/searchlib/src/vespa/searchlib/parsequery/simplequerystack.cpp
index a7b41476ec6..6f49dc62686 100644
--- a/searchlib/src/vespa/searchlib/parsequery/simplequerystack.cpp
+++ b/searchlib/src/vespa/searchlib/parsequery/simplequerystack.cpp
@@ -25,12 +25,12 @@ SimpleQueryStack::~SimpleQueryStack()
}
void
-SimpleQueryStack::Push(search::ParseItem *item)
+SimpleQueryStack::Push(ParseItem *item)
{
// Check if query OK for FirstPage
_FP_queryOK &=
- ( item->Type() != search::ParseItem::ITEM_UNDEF
- && item->Type() != search::ParseItem::ITEM_PAREN
+ ( item->Type() != ParseItem::ITEM_UNDEF
+ && item->Type() != ParseItem::ITEM_PAREN
);
@@ -40,10 +40,10 @@ SimpleQueryStack::Push(search::ParseItem *item)
_numItems++;
}
-search::ParseItem *
+ParseItem *
SimpleQueryStack::Pop()
{
- search::ParseItem *item = _stack;
+ ParseItem *item = _stack;
if (_stack != NULL) {
_numItems--;
_stack = _stack->_next;
@@ -53,9 +53,9 @@ SimpleQueryStack::Pop()
}
void
-SimpleQueryStack::AppendBuffer(search::RawBuf *buf) const
+SimpleQueryStack::AppendBuffer(RawBuf *buf) const
{
- for (search::ParseItem *item = _stack; item != NULL; item = item->_next) {
+ for (ParseItem *item = _stack; item != NULL; item = item->_next) {
item->AppendBuffer(buf);
}
}
@@ -66,7 +66,7 @@ SimpleQueryStack::GetBufferLen() const
size_t result;
result = 0;
- for (const search::ParseItem *item = _stack;
+ for (const ParseItem *item = _stack;
item != NULL; item = item->_next) {
result += item->GetBufferLen();
}
@@ -90,34 +90,35 @@ class ItemName {
public:
ItemName() {
memset(_name, 'X', sizeof(_name));
- _name[search::ParseItem::ITEM_OR] = '|';
- _name[search::ParseItem::ITEM_WEAK_AND] = 'w';
- _name[search::ParseItem::ITEM_EQUIV] = 'E';
- _name[search::ParseItem::ITEM_AND] = '&';
- _name[search::ParseItem::ITEM_NOT] = '-';
- _name[search::ParseItem::ITEM_ANY] = '?';
- _name[search::ParseItem::ITEM_RANK] = '%';
- _name[search::ParseItem::ITEM_NEAR] = 'N';
- _name[search::ParseItem::ITEM_ONEAR] = 'O';
- _name[search::ParseItem::ITEM_NUMTERM] = '#';
- _name[search::ParseItem::ITEM_TERM] = 't';
- _name[search::ParseItem::ITEM_PURE_WEIGHTED_STRING] = 'T';
- _name[search::ParseItem::ITEM_PURE_WEIGHTED_LONG] = 'L';
- _name[search::ParseItem::ITEM_PREFIXTERM] = '*';
- _name[search::ParseItem::ITEM_SUBSTRINGTERM] = 's';
- _name[search::ParseItem::ITEM_EXACTSTRINGTERM] = 'e';
- _name[search::ParseItem::ITEM_SUFFIXTERM] = 'S';
- _name[search::ParseItem::ITEM_PHRASE] = '"';
- _name[search::ParseItem::ITEM_WEIGHTED_SET] = 'W';
- _name[search::ParseItem::ITEM_DOT_PRODUCT] = 'D';
- _name[search::ParseItem::ITEM_WAND] = 'A';
- _name[search::ParseItem::ITEM_PREDICATE_QUERY] = 'P';
- _name[search::ParseItem::ITEM_REGEXP] = '^';
+ _name[ParseItem::ITEM_OR] = '|';
+ _name[ParseItem::ITEM_WEAK_AND] = 'w';
+ _name[ParseItem::ITEM_EQUIV] = 'E';
+ _name[ParseItem::ITEM_AND] = '&';
+ _name[ParseItem::ITEM_NOT] = '-';
+ _name[ParseItem::ITEM_ANY] = '?';
+ _name[ParseItem::ITEM_RANK] = '%';
+ _name[ParseItem::ITEM_NEAR] = 'N';
+ _name[ParseItem::ITEM_ONEAR] = 'O';
+ _name[ParseItem::ITEM_NUMTERM] = '#';
+ _name[ParseItem::ITEM_TERM] = 't';
+ _name[ParseItem::ITEM_PURE_WEIGHTED_STRING] = 'T';
+ _name[ParseItem::ITEM_PURE_WEIGHTED_LONG] = 'L';
+ _name[ParseItem::ITEM_PREFIXTERM] = '*';
+ _name[ParseItem::ITEM_SUBSTRINGTERM] = 's';
+ _name[ParseItem::ITEM_EXACTSTRINGTERM] = 'e';
+ _name[ParseItem::ITEM_SUFFIXTERM] = 'S';
+ _name[ParseItem::ITEM_PHRASE] = '"';
+ _name[ParseItem::ITEM_SAME_ELEMENT] = 'M';
+ _name[ParseItem::ITEM_WEIGHTED_SET] = 'W';
+ _name[ParseItem::ITEM_DOT_PRODUCT] = 'D';
+ _name[ParseItem::ITEM_WAND] = 'A';
+ _name[ParseItem::ITEM_PREDICATE_QUERY] = 'P';
+ _name[ParseItem::ITEM_REGEXP] = '^';
}
- char operator[] (search::ParseItem::ItemType i) const { return _name[i]; }
+ char operator[] (ParseItem::ItemType i) const { return _name[i]; }
char operator[] (size_t i) const { return _name[i]; }
private:
- char _name[search::ParseItem::ITEM_MAX];
+ char _name[ParseItem::ITEM_MAX];
};
static ItemName _G_ItemName;
@@ -162,29 +163,29 @@ SimpleQueryStack::StackbufToString(const vespalib::stringref &theBuf)
while (p < ep) {
vespalib::string metaStr;
rawtype = *p++;
- type = search::ParseItem::GetType(rawtype);
- if (search::ParseItem::GetFeature_Weight(rawtype)) {
+ type = ParseItem::GetType(rawtype);
+ if (ParseItem::GetFeature_Weight(rawtype)) {
int64_t tmpLong(0);
p += vespalib::compress::Integer::decompress(tmpLong, p);
metaStr.append("(w:");
metaStr.append(make_string("%ld", tmpLong));
metaStr.append(")");
}
- if (search::ParseItem::getFeature_UniqueId(rawtype)) {
+ if (ParseItem::getFeature_UniqueId(rawtype)) {
p += vespalib::compress::Integer::decompressPositive(tmp, p);
metaStr.append("(u:");
metaStr.append(make_string("%ld", tmp));
metaStr.append(")");
}
- if (search::ParseItem::getFeature_Flags(rawtype)) {
+ if (ParseItem::getFeature_Flags(rawtype)) {
flags = *p++;
metaStr.append("(f:");
metaStr.append(make_string("%d", flags));
metaStr.append(")");
}
- if (search::ParseItem::GetCreator(flags) != search::ParseItem::CREA_ORIG) {
+ if (ParseItem::GetCreator(flags) != ParseItem::CREA_ORIG) {
metaStr.append("(c:");
- metaStr.append(make_string("%d", search::ParseItem::GetCreator(flags)));
+ metaStr.append(make_string("%d", ParseItem::GetCreator(flags)));
metaStr.append(")");
}
@@ -192,41 +193,52 @@ SimpleQueryStack::StackbufToString(const vespalib::stringref &theBuf)
result.append(metaStr);
switch (type) {
- case search::ParseItem::ITEM_OR:
- case search::ParseItem::ITEM_AND:
- case search::ParseItem::ITEM_EQUIV:
- case search::ParseItem::ITEM_NOT:
- case search::ParseItem::ITEM_RANK:
- case search::ParseItem::ITEM_ANY:
+ case ParseItem::ITEM_OR:
+ case ParseItem::ITEM_AND:
+ case ParseItem::ITEM_EQUIV:
+ case ParseItem::ITEM_NOT:
+ case ParseItem::ITEM_RANK:
+ case ParseItem::ITEM_ANY:
p += vespalib::compress::Integer::decompressPositive(tmp, p);
arity = tmp;
result.append(make_string("%c/%d~", _G_ItemName[type], arity));
break;
- case search::ParseItem::ITEM_WEAK_AND:
- case search::ParseItem::ITEM_NEAR:
- case search::ParseItem::ITEM_ONEAR:
+ case ParseItem::ITEM_NEAR:
+ case ParseItem::ITEM_ONEAR:
p += vespalib::compress::Integer::decompressPositive(tmp, p);
arity = tmp;
p += vespalib::compress::Integer::decompressPositive(tmp, p);
arg1 = tmp;
- if (type == search::ParseItem::ITEM_WEAK_AND) {
- p += vespalib::compress::Integer::decompressPositive(tmp, p);
- idxRefLen = tmp;
- idxRef = p;
- p += idxRefLen;
- result.append(make_string("%c/%d/%d/%d:%.*s~", _G_ItemName[type], arity, arg1, idxRefLen, idxRefLen, idxRef));
- } else {
- result.append(make_string("%c/%d/%d~", _G_ItemName[type], arity, arg1));
- }
+ result.append(make_string("%c/%d/%d~", _G_ItemName[type], arity, arg1));
+ break;
+ case ParseItem::ITEM_WEAK_AND:
+ p += vespalib::compress::Integer::decompressPositive(tmp, p);
+ arity = tmp;
+ p += vespalib::compress::Integer::decompressPositive(tmp, p);
+ arg1 = tmp;
+ p += vespalib::compress::Integer::decompressPositive(tmp, p);
+ idxRefLen = tmp;
+ idxRef = p;
+ p += idxRefLen;
+ result.append(make_string("%c/%d/%d/%d:%.*s~", _G_ItemName[type], arity, arg1, idxRefLen, idxRefLen, idxRef));
+ break;
+ case ParseItem::ITEM_SAME_ELEMENT:
+ p += vespalib::compress::Integer::decompressPositive(tmp, p);
+ arity = tmp;
+ p += vespalib::compress::Integer::decompressPositive(tmp, p);
+ idxRefLen = tmp;
+ idxRef = p;
+ p += idxRefLen;
+ result.append(make_string("%c/%d/%d:%.*s~", _G_ItemName[type], arity, idxRefLen, idxRefLen, idxRef));
break;
- case search::ParseItem::ITEM_NUMTERM:
- case search::ParseItem::ITEM_TERM:
- case search::ParseItem::ITEM_PREFIXTERM:
- case search::ParseItem::ITEM_SUBSTRINGTERM:
- case search::ParseItem::ITEM_EXACTSTRINGTERM:
- case search::ParseItem::ITEM_SUFFIXTERM:
- case search::ParseItem::ITEM_REGEXP:
+ case ParseItem::ITEM_NUMTERM:
+ case ParseItem::ITEM_TERM:
+ case ParseItem::ITEM_PREFIXTERM:
+ case ParseItem::ITEM_SUBSTRINGTERM:
+ case ParseItem::ITEM_EXACTSTRINGTERM:
+ case ParseItem::ITEM_SUFFIXTERM:
+ case ParseItem::ITEM_REGEXP:
p += vespalib::compress::Integer::decompressPositive(tmp, p);
idxRefLen = tmp;
idxRef = p;
@@ -239,7 +251,7 @@ SimpleQueryStack::StackbufToString(const vespalib::stringref &theBuf)
idxRefLen, idxRefLen, idxRef,
termRefLen, termRefLen, termRef));
break;
- case search::ParseItem::ITEM_PURE_WEIGHTED_STRING:
+ case ParseItem::ITEM_PURE_WEIGHTED_STRING:
p += vespalib::compress::Integer::decompressPositive(tmp, p);
termRefLen = tmp;
termRef = p;
@@ -248,23 +260,23 @@ SimpleQueryStack::StackbufToString(const vespalib::stringref &theBuf)
termRefLen, termRefLen, termRef));
break;
- case search::ParseItem::ITEM_PURE_WEIGHTED_LONG:
+ case ParseItem::ITEM_PURE_WEIGHTED_LONG:
tmp = vespalib::nbo::n2h(*reinterpret_cast<const uint64_t *>(p));
p += sizeof(uint64_t);
result.append(make_string("%c/%lu", _G_ItemName[type], tmp));
break;
- case search::ParseItem::ITEM_PHRASE:
- case search::ParseItem::ITEM_WEIGHTED_SET:
- case search::ParseItem::ITEM_DOT_PRODUCT:
- case search::ParseItem::ITEM_WAND:
+ case ParseItem::ITEM_PHRASE:
+ case ParseItem::ITEM_WEIGHTED_SET:
+ case ParseItem::ITEM_DOT_PRODUCT:
+ case ParseItem::ITEM_WAND:
p += vespalib::compress::Integer::decompressPositive(tmp, p);
arity = tmp;
p += vespalib::compress::Integer::decompressPositive(tmp, p);
idxRefLen = tmp;
idxRef = p;
p += idxRefLen;
- if (type == search::ParseItem::ITEM_WAND) {
+ if (type == ParseItem::ITEM_WAND) {
p += vespalib::compress::Integer::decompressPositive(tmp, p);
uint32_t targetNumHits = tmp;
double scoreThreshold = vespalib::nbo::n2h(*reinterpret_cast<const double *>(p));
@@ -279,7 +291,7 @@ SimpleQueryStack::StackbufToString(const vespalib::stringref &theBuf)
}
break;
- case search::ParseItem::ITEM_PREDICATE_QUERY:
+ case ParseItem::ITEM_PREDICATE_QUERY:
{
idxRefLen = static_cast<uint32_t>(ReadCompressedPositiveInt(p));
idxRef = p;
diff --git a/searchlib/src/vespa/searchlib/parsequery/stackdumpiterator.cpp b/searchlib/src/vespa/searchlib/parsequery/stackdumpiterator.cpp
index ec34b2d3a84..542e7990c1e 100644
--- a/searchlib/src/vespa/searchlib/parsequery/stackdumpiterator.cpp
+++ b/searchlib/src/vespa/searchlib/parsequery/stackdumpiterator.cpp
@@ -34,9 +34,7 @@ SimpleQueryStackDumpIterator::SimpleQueryStackDumpIterator(const vespalib::strin
{
}
-SimpleQueryStackDumpIterator::~SimpleQueryStackDumpIterator()
-{
-}
+SimpleQueryStackDumpIterator::~SimpleQueryStackDumpIterator() = default;
vespalib::string SimpleQueryStackDumpIterator::readString(const char *&p) {
if (p >= _bufEnd) throw false;
@@ -154,6 +152,20 @@ SimpleQueryStackDumpIterator::next()
_currTerm = NULL;
_currTermLen = 0;
break;
+ case ParseItem::ITEM_SAME_ELEMENT:
+ if (p >= _bufEnd) return false;
+ p += vespalib::compress::Integer::decompressPositive(tmp, p);
+ _currArity = tmp;
+ _currArg1 = 0;
+ p += vespalib::compress::Integer::decompressPositive(tmp, p);
+ _currIndexNameLen = tmp;
+ if (p > _bufEnd) return false;
+ _currIndexName = p;
+ p += _currIndexNameLen;
+ if (p > _bufEnd) return false;
+ _currTerm = NULL;
+ _currTermLen = 0;
+ break;
case ParseItem::ITEM_PURE_WEIGHTED_STRING:
if (p >= _bufEnd) return false;
diff --git a/searchlib/src/vespa/searchlib/query/query.cpp b/searchlib/src/vespa/searchlib/query/query.cpp
index d380c273d02..984337f40ba 100644
--- a/searchlib/src/vespa/searchlib/query/query.cpp
+++ b/searchlib/src/vespa/searchlib/query/query.cpp
@@ -102,10 +102,11 @@ QueryConnector::create(ParseItem::ItemType type)
case search::ParseItem::ITEM_WAND: return new OrQueryNode();
case search::ParseItem::ITEM_NOT: return new AndNotQueryNode();
case search::ParseItem::ITEM_PHRASE: return new PhraseQueryNode();
+ case search::ParseItem::ITEM_SAME_ELEMENT: return new AndQueryNode(); // TODO: This needs a same element operation to work for streaming search too.
case search::ParseItem::ITEM_NEAR: return new NearQueryNode();
case search::ParseItem::ITEM_ONEAR: return new ONearQueryNode();
default:
- return NULL;
+ return nullptr;
}
}
diff --git a/searchlib/src/vespa/searchlib/query/querynode.cpp b/searchlib/src/vespa/searchlib/query/querynode.cpp
index 2e9d8be95f4..0d0a06de7af 100644
--- a/searchlib/src/vespa/searchlib/query/querynode.cpp
+++ b/searchlib/src/vespa/searchlib/query/querynode.cpp
@@ -26,6 +26,7 @@ QueryNode::UP QueryNode::Build(const QueryNode * parent, const QueryNodeResultFa
case search::ParseItem::ITEM_WAND:
case search::ParseItem::ITEM_NOT:
case search::ParseItem::ITEM_PHRASE:
+ case search::ParseItem::ITEM_SAME_ELEMENT:
case search::ParseItem::ITEM_NEAR:
case search::ParseItem::ITEM_ONEAR:
{
diff --git a/searchlib/src/vespa/searchlib/query/tree/customtypetermvisitor.h b/searchlib/src/vespa/searchlib/query/tree/customtypetermvisitor.h
index 72763839b95..611406e6ea3 100644
--- a/searchlib/src/vespa/searchlib/query/tree/customtypetermvisitor.h
+++ b/searchlib/src/vespa/searchlib/query/tree/customtypetermvisitor.h
@@ -5,8 +5,7 @@
#include "customtypevisitor.h"
#include "intermediate.h"
-namespace search {
-namespace query {
+namespace search::query {
template <class NodeTypes>
class CustomTypeTermVisitor : public CustomTypeVisitor<NodeTypes>
@@ -27,10 +26,10 @@ private:
void visit(typename NodeTypes::Or &n) override { visitChildren(n); }
void visit(typename NodeTypes::Rank &n) override { visitChildren(n); }
void visit(typename NodeTypes::WeakAnd &n) override { visitChildren(n); }
+ void visit(typename NodeTypes::SameElement &n) override { visitChildren(n); }
// phrases and weighted set terms are conceptual leaf nodes and
// should be handled that way.
};
-} // namespace query
-} // namespace search
+}
diff --git a/searchlib/src/vespa/searchlib/query/tree/customtypevisitor.h b/searchlib/src/vespa/searchlib/query/tree/customtypevisitor.h
index 83e6343e223..cdeebcaf9e5 100644
--- a/searchlib/src/vespa/searchlib/query/tree/customtypevisitor.h
+++ b/searchlib/src/vespa/searchlib/query/tree/customtypevisitor.h
@@ -4,8 +4,7 @@
#include "queryvisitor.h"
-namespace search {
-namespace query {
+namespace search::query {
/**
* By typedefing a (complete) set of subclasses to the query nodes in
@@ -37,6 +36,7 @@ public:
virtual void visit(typename NodeTypes::ONear &) = 0;
virtual void visit(typename NodeTypes::Or &) = 0;
virtual void visit(typename NodeTypes::Phrase &) = 0;
+ virtual void visit(typename NodeTypes::SameElement &) = 0;
virtual void visit(typename NodeTypes::PrefixTerm &) = 0;
virtual void visit(typename NodeTypes::RangeTerm &) = 0;
virtual void visit(typename NodeTypes::Rank &) = 0;
@@ -62,6 +62,7 @@ private:
typedef typename NodeTypes::ONear TONear;
typedef typename NodeTypes::Or TOr;
typedef typename NodeTypes::Phrase TPhrase;
+ typedef typename NodeTypes::SameElement TSameElement;
typedef typename NodeTypes::PrefixTerm TPrefixTerm;
typedef typename NodeTypes::RangeTerm TRangeTerm;
typedef typename NodeTypes::Rank TRank;
@@ -84,6 +85,7 @@ private:
void visit(ONear &n) override { visit(static_cast<TONear&>(n)); }
void visit(Or &n) override { visit(static_cast<TOr&>(n)); }
void visit(Phrase &n) override { visit(static_cast<TPhrase&>(n)); }
+ void visit(SameElement &n) override { visit(static_cast<TSameElement &>(n)); }
void visit(PrefixTerm &n) override { visit(static_cast<TPrefixTerm&>(n)); }
void visit(RangeTerm &n) override { visit(static_cast<TRangeTerm&>(n)); }
void visit(Rank &n) override { visit(static_cast<TRank&>(n)); }
@@ -98,5 +100,4 @@ private:
void visit(RegExpTerm &n) override { visit(static_cast<TRegExpTerm&>(n)); }
};
-} // namespace query
-} // namespace search
+}
diff --git a/searchlib/src/vespa/searchlib/query/tree/intermediate.cpp b/searchlib/src/vespa/searchlib/query/tree/intermediate.cpp
index 1274777dc74..f56da9c2cf9 100644
--- a/searchlib/src/vespa/searchlib/query/tree/intermediate.cpp
+++ b/searchlib/src/vespa/searchlib/query/tree/intermediate.cpp
@@ -1,8 +1,7 @@
// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
#include "intermediate.h"
-namespace search {
-namespace query {
+namespace search::query {
Intermediate::~Intermediate() {
for (size_t i = 0; i < _children.size(); ++i) {
@@ -16,5 +15,4 @@ Intermediate &Intermediate::append(Node::UP child)
return *this;
}
-} // namespace query
-} // namespace search
+}
diff --git a/searchlib/src/vespa/searchlib/query/tree/intermediate.h b/searchlib/src/vespa/searchlib/query/tree/intermediate.h
index c28ab8241e0..052dc1db269 100644
--- a/searchlib/src/vespa/searchlib/query/tree/intermediate.h
+++ b/searchlib/src/vespa/searchlib/query/tree/intermediate.h
@@ -1,11 +1,10 @@
// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
#pragma once
+#include "node.h"
#include <vector>
-#include <vespa/searchlib/query/tree/node.h>
-namespace search {
-namespace query {
+namespace search::query {
class Intermediate : public Node
{
@@ -24,6 +23,4 @@ class Intermediate : public Node
Intermediate &append(Node::UP child);
};
-} // namespace query
-} // namespace search
-
+}
diff --git a/searchlib/src/vespa/searchlib/query/tree/intermediatenodes.cpp b/searchlib/src/vespa/searchlib/query/tree/intermediatenodes.cpp
index 9fabbe58a19..4a4b606ef8f 100644
--- a/searchlib/src/vespa/searchlib/query/tree/intermediatenodes.cpp
+++ b/searchlib/src/vespa/searchlib/query/tree/intermediatenodes.cpp
@@ -1,32 +1,20 @@
// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
#include "intermediatenodes.h"
-namespace search {
-namespace query {
-
-And::~And() {}
-
-AndNot::~AndNot() {}
-
-Or::~Or() {}
-
-WeakAnd::~WeakAnd() {}
-
-Equiv::~Equiv() {}
-
-Rank::~Rank() {}
-
-Near::~Near() {}
-
-ONear::~ONear() {}
-
-Phrase::~Phrase() {}
-
-WeightedSetTerm::~WeightedSetTerm() {}
-
-DotProduct::~DotProduct() {}
-
-WandTerm::~WandTerm() {}
-
-} // namespace query
-} // namespace search
+namespace search::query {
+
+And::~And() = default;
+AndNot::~AndNot() = default;
+Or::~Or() = default;
+WeakAnd::~WeakAnd() = default;
+Equiv::~Equiv() = default;
+Rank::~Rank() = default;
+Near::~Near() = default;
+ONear::~ONear() = default;
+Phrase::~Phrase() = default;
+SameElement::~SameElement() = default;
+WeightedSetTerm::~WeightedSetTerm() = default;
+DotProduct::~DotProduct() = default;
+WandTerm::~WandTerm() = default;
+
+}
diff --git a/searchlib/src/vespa/searchlib/query/tree/intermediatenodes.h b/searchlib/src/vespa/searchlib/query/tree/intermediatenodes.h
index e358c7d7bef..6d643d951f0 100644
--- a/searchlib/src/vespa/searchlib/query/tree/intermediatenodes.h
+++ b/searchlib/src/vespa/searchlib/query/tree/intermediatenodes.h
@@ -5,10 +5,8 @@
#include "intermediate.h"
#include "querynodemixin.h"
#include "term.h"
-#include <vespa/searchlib/query/weight.h>
-namespace search {
-namespace query {
+namespace search::query {
class And : public QueryNodeMixin<And, Intermediate> {
public:
@@ -105,6 +103,15 @@ public:
virtual ~Phrase() = 0;
};
+class SameElement : public QueryNodeMixin<SameElement, Intermediate> {
+public:
+ SameElement(const vespalib::string &view) : _view(view) {}
+ virtual ~SameElement() = 0;
+ const vespalib::string & getView() const { return _view; }
+private:
+ vespalib::string _view;
+};
+
class WeightedSetTerm : public QueryNodeMixin<WeightedSetTerm, Intermediate>, public Term {
public:
WeightedSetTerm(const vespalib::string &view, int32_t id, Weight weight)
@@ -137,6 +144,4 @@ public:
double getThresholdBoostFactor() const { return _thresholdBoostFactor; }
};
-} // namespace query
-} // namespace search
-
+}
diff --git a/searchlib/src/vespa/searchlib/query/tree/location.cpp b/searchlib/src/vespa/searchlib/query/tree/location.cpp
index 5817b93a2fb..216c5ec5ad0 100644
--- a/searchlib/src/vespa/searchlib/query/tree/location.cpp
+++ b/searchlib/src/vespa/searchlib/query/tree/location.cpp
@@ -7,8 +7,7 @@
using vespalib::asciistream;
-namespace search {
-namespace query {
+namespace search::query {
Location::Location(const Point &point, uint32_t max_dist, uint32_t x_aspect) {
asciistream loc;
@@ -61,5 +60,4 @@ vespalib::asciistream &operator<<(vespalib::asciistream &out, const Location &lo
return out << loc.getLocationString();
}
-} // namespace query
-} // namespace search
+}
diff --git a/searchlib/src/vespa/searchlib/query/tree/location.h b/searchlib/src/vespa/searchlib/query/tree/location.h
index 0abad19b696..5ed717c87d6 100644
--- a/searchlib/src/vespa/searchlib/query/tree/location.h
+++ b/searchlib/src/vespa/searchlib/query/tree/location.h
@@ -4,11 +4,8 @@
#include <vespa/vespalib/stllike/string.h>
-namespace vespalib {
- class asciistream;
-}
-namespace search {
-namespace query {
+namespace vespalib { class asciistream; }
+namespace search::query {
class Point;
class Rectangle;
@@ -32,6 +29,4 @@ public:
vespalib::asciistream &operator<<(vespalib::asciistream &out, const Location &loc);
-} // namespace query
-} // namespace search
-
+}
diff --git a/searchlib/src/vespa/searchlib/query/tree/point.h b/searchlib/src/vespa/searchlib/query/tree/point.h
index af9b958a474..89d0bc1db44 100644
--- a/searchlib/src/vespa/searchlib/query/tree/point.h
+++ b/searchlib/src/vespa/searchlib/query/tree/point.h
@@ -2,10 +2,9 @@
#pragma once
-#include <stdint.h>
+#include <cstdint>
-namespace search {
-namespace query {
+namespace search::query {
struct Point {
int64_t x;
@@ -18,6 +17,4 @@ inline bool operator==(const Point &p1, const Point &p2) {
return p1.x == p2.x && p1.y == p2.y;
}
-} // namespace query
-} // namespace search
-
+}
diff --git a/searchlib/src/vespa/searchlib/query/tree/predicate_query_term.h b/searchlib/src/vespa/searchlib/query/tree/predicate_query_term.h
index b851563e198..0a92546e414 100644
--- a/searchlib/src/vespa/searchlib/query/tree/predicate_query_term.h
+++ b/searchlib/src/vespa/searchlib/query/tree/predicate_query_term.h
@@ -6,8 +6,7 @@
#include <memory>
#include <vector>
-namespace search {
-namespace query {
+namespace search::query {
/**
* Represents a predicate query, with features and range features.
@@ -71,6 +70,4 @@ public:
}
};
-} // namespace query
-} // namespace search
-
+}
diff --git a/searchlib/src/vespa/searchlib/query/tree/querybuilder.h b/searchlib/src/vespa/searchlib/query/tree/querybuilder.h
index 2732d7895a5..3c6ff93457d 100644
--- a/searchlib/src/vespa/searchlib/query/tree/querybuilder.h
+++ b/searchlib/src/vespa/searchlib/query/tree/querybuilder.h
@@ -20,13 +20,11 @@
#pragma once
#include "predicate_query_term.h"
-#include <stack>
-#include <vespa/vespalib/stllike/string.h>
-#include <vespa/searchlib/query/weight.h>
#include "node.h"
+#include <vespa/searchlib/query/weight.h>
+#include <stack>
-namespace search {
-namespace query {
+namespace search::query {
class Intermediate;
class Location;
@@ -124,6 +122,10 @@ typename NodeTypes::Phrase *createPhrase(const vespalib::stringref &view, int32_
return new typename NodeTypes::Phrase(view, id, weight);
}
template <class NodeTypes>
+typename NodeTypes::SameElement *createSameElement(const vespalib::stringref &view) {
+ return new typename NodeTypes::SameElement(view);
+}
+template <class NodeTypes>
typename NodeTypes::WeightedSetTerm *createWeightedSetTerm(const vespalib::stringref &view, int32_t id, Weight weight) {
return new typename NodeTypes::WeightedSetTerm(view, id, weight);
}
@@ -243,6 +245,9 @@ public:
setWeightOverride(weight);
return node;
}
+ typename NodeTypes::SameElement &addSameElement(int child_count, const stringref &view) {
+ return addIntermediate(createSameElement<NodeTypes>(view), child_count);
+ }
typename NodeTypes::WeightedSetTerm &addWeightedSetTerm( int child_count, const stringref &view, int32_t id, Weight weight) {
adjustWeight(weight);
typename NodeTypes::WeightedSetTerm &node = addIntermediate(createWeightedSetTerm<NodeTypes>(view, id, weight), child_count);
@@ -306,6 +311,4 @@ public:
}
};
-} // namespace query
-} // namespace search
-
+}
diff --git a/searchlib/src/vespa/searchlib/query/tree/querynodemixin.h b/searchlib/src/vespa/searchlib/query/tree/querynodemixin.h
index d6e0950dea2..9e8c97cff94 100644
--- a/searchlib/src/vespa/searchlib/query/tree/querynodemixin.h
+++ b/searchlib/src/vespa/searchlib/query/tree/querynodemixin.h
@@ -4,8 +4,7 @@
#include "queryvisitor.h"
-namespace search {
-namespace query {
+namespace search::query {
template <typename T, typename Base>
struct QueryNodeMixin : Base {
@@ -21,8 +20,6 @@ protected:
};
template <typename T, typename Base>
-QueryNodeMixin<T, Base>::~QueryNodeMixin() {}
-
-} // namespace query
-} // namespace search
+QueryNodeMixin<T, Base>::~QueryNodeMixin() = default;
+}
diff --git a/searchlib/src/vespa/searchlib/query/tree/queryreplicator.h b/searchlib/src/vespa/searchlib/query/tree/queryreplicator.h
index aad85d9b28c..7bf6c17f136 100644
--- a/searchlib/src/vespa/searchlib/query/tree/queryreplicator.h
+++ b/searchlib/src/vespa/searchlib/query/tree/queryreplicator.h
@@ -7,8 +7,7 @@
#include "queryvisitor.h"
#include "termnodes.h"
-namespace search {
-namespace query {
+namespace search::query {
/**
* Creates a new query tree based on an existing one. The traits class
@@ -70,22 +69,24 @@ private:
}
void visit(Phrase &node) override {
- replicate(node, _builder.addPhrase(node.getChildren().size(),
- node.getView(),
+ replicate(node, _builder.addPhrase(node.getChildren().size(), node.getView(),
node.getId(), node.getWeight()));
visitNodes(node.getChildren());
}
+ void visit(SameElement &node) override {
+ _builder.addSameElement(node.getChildren().size(), node.getView());
+ visitNodes(node.getChildren());
+ }
+
void visit(WeightedSetTerm &node) override {
- replicate(node, _builder.addWeightedSetTerm(node.getChildren().size(),
- node.getView(),
+ replicate(node, _builder.addWeightedSetTerm(node.getChildren().size(), node.getView(),
node.getId(), node.getWeight()));
visitNodes(node.getChildren());
}
void visit(DotProduct &node) override {
- replicate(node, _builder.addDotProduct(node.getChildren().size(),
- node.getView(),
+ replicate(node, _builder.addDotProduct(node.getChildren().size(), node.getView(),
node.getId(), node.getWeight()));
visitNodes(node.getChildren());
}
@@ -165,5 +166,4 @@ private:
}
};
-} // namespace query
-} // namespace search
+}
diff --git a/searchlib/src/vespa/searchlib/query/tree/querytreecreator.h b/searchlib/src/vespa/searchlib/query/tree/querytreecreator.h
index a3e6ac523ae..c42a16d8ab3 100644
--- a/searchlib/src/vespa/searchlib/query/tree/querytreecreator.h
+++ b/searchlib/src/vespa/searchlib/query/tree/querytreecreator.h
@@ -5,8 +5,7 @@
#include "queryreplicator.h"
#include "stackdumpquerycreator.h"
-namespace search {
-namespace query {
+namespace search::query {
/**
* Holds functions for creating query trees, either from a stack dump
@@ -27,6 +26,4 @@ private:
QueryTreeCreator();
};
-} // namespace query
-} // namespace search
-
+}
diff --git a/searchlib/src/vespa/searchlib/query/tree/queryvisitor.h b/searchlib/src/vespa/searchlib/query/tree/queryvisitor.h
index 4596359201b..0cb56f9127a 100644
--- a/searchlib/src/vespa/searchlib/query/tree/queryvisitor.h
+++ b/searchlib/src/vespa/searchlib/query/tree/queryvisitor.h
@@ -2,8 +2,7 @@
#pragma once
-namespace search {
-namespace query {
+namespace search::query {
class And;
class AndNot;
@@ -26,6 +25,7 @@ class DotProduct;
class WandTerm;
class PredicateQuery;
class RegExpTerm;
+class SameElement;
struct QueryVisitor {
virtual ~QueryVisitor() {}
@@ -39,6 +39,7 @@ struct QueryVisitor {
virtual void visit(ONear &) = 0;
virtual void visit(Or &) = 0;
virtual void visit(Phrase &) = 0;
+ virtual void visit(SameElement &node) = 0;
virtual void visit(PrefixTerm &) = 0;
virtual void visit(RangeTerm &) = 0;
virtual void visit(Rank &) = 0;
@@ -53,6 +54,5 @@ struct QueryVisitor {
virtual void visit(RegExpTerm &) = 0;
};
-} // namespace query
-} // namespace search
+}
diff --git a/searchlib/src/vespa/searchlib/query/tree/range.cpp b/searchlib/src/vespa/searchlib/query/tree/range.cpp
index 583d57bb74d..202b80d98a2 100644
--- a/searchlib/src/vespa/searchlib/query/tree/range.cpp
+++ b/searchlib/src/vespa/searchlib/query/tree/range.cpp
@@ -3,8 +3,7 @@
#include "range.h"
#include <vespa/vespalib/stllike/asciistream.h>
-namespace search {
-namespace query {
+namespace search::query {
Range::Range(int64_t f, int64_t t)
{
@@ -18,5 +17,4 @@ vespalib::asciistream &operator<<(vespalib::asciistream &out, const Range &range
return out << range.getRangeString();
}
-} // namespace query
-} // namespace search
+}
diff --git a/searchlib/src/vespa/searchlib/query/tree/range.h b/searchlib/src/vespa/searchlib/query/tree/range.h
index 862258873e6..e55ddf7f14b 100644
--- a/searchlib/src/vespa/searchlib/query/tree/range.h
+++ b/searchlib/src/vespa/searchlib/query/tree/range.h
@@ -3,12 +3,9 @@
#pragma once
#include <vespa/vespalib/stllike/string.h>
-namespace vespalib {
- class asciistream;
-}
+namespace vespalib { class asciistream; }
-namespace search {
-namespace query {
+namespace search::query {
class Range {
vespalib::string _range;
@@ -27,6 +24,4 @@ inline bool operator==(const Range &r1, const Range &r2) {
vespalib::asciistream &operator<<(vespalib::asciistream &out, const Range &range);
-} // namespace query
-} // namespace search
-
+}
diff --git a/searchlib/src/vespa/searchlib/query/tree/rectangle.h b/searchlib/src/vespa/searchlib/query/tree/rectangle.h
index 29b144ac5dc..97be9ddeb32 100644
--- a/searchlib/src/vespa/searchlib/query/tree/rectangle.h
+++ b/searchlib/src/vespa/searchlib/query/tree/rectangle.h
@@ -2,8 +2,7 @@
#pragma once
-namespace search {
-namespace query {
+namespace search::query {
struct Rectangle {
int64_t left;
@@ -21,6 +20,5 @@ inline bool operator==(const Rectangle &r1, const Rectangle &r2) {
&& r1.top == r2.top && r1.bottom == r2.bottom;
}
-} // namespace query
-} // namespace search
+}
diff --git a/searchlib/src/vespa/searchlib/query/tree/simplequery.h b/searchlib/src/vespa/searchlib/query/tree/simplequery.h
index 28791dafe53..557d0964bcb 100644
--- a/searchlib/src/vespa/searchlib/query/tree/simplequery.h
+++ b/searchlib/src/vespa/searchlib/query/tree/simplequery.h
@@ -10,8 +10,7 @@
#include "intermediatenodes.h"
#include "termnodes.h"
-namespace search {
-namespace query {
+namespace search::query {
struct SimpleAnd : And {};
struct SimpleAndNot : AndNot {};
@@ -31,6 +30,10 @@ struct SimplePhrase : Phrase {
SimplePhrase(const vespalib::stringref &view, int32_t id, Weight weight)
: Phrase(view, id, weight) {}
};
+
+struct SimpleSameElement : SameElement {
+ SimpleSameElement(const vespalib::stringref &view) : SameElement(view) {}
+};
struct SimpleWeightedSetTerm : WeightedSetTerm {
SimpleWeightedSetTerm(const vespalib::stringref &view, int32_t id, Weight weight)
: WeightedSetTerm(view, id, weight) {}
@@ -112,6 +115,7 @@ struct SimpleQueryNodeTypes {
typedef SimpleONear ONear;
typedef SimpleOr Or;
typedef SimplePhrase Phrase;
+ typedef SimpleSameElement SameElement;
typedef SimplePrefixTerm PrefixTerm;
typedef SimpleRangeTerm RangeTerm;
typedef SimpleRank Rank;
@@ -126,6 +130,4 @@ struct SimpleQueryNodeTypes {
typedef SimpleRegExpTerm RegExpTerm;
};
-} // namespace query
-} // namespace search
-
+}
diff --git a/searchlib/src/vespa/searchlib/query/tree/stackdumpcreator.cpp b/searchlib/src/vespa/searchlib/query/tree/stackdumpcreator.cpp
index 771830c0b03..645750b8576 100644
--- a/searchlib/src/vespa/searchlib/query/tree/stackdumpcreator.cpp
+++ b/searchlib/src/vespa/searchlib/query/tree/stackdumpcreator.cpp
@@ -64,23 +64,48 @@ class QueryNodeConverter : public QueryVisitor {
template <typename V>
void appendPredicateQueryTermVector(const V& v);
+ void createComplexIntermediate(const Term &node, const std::vector<Node *> & children, size_t type) {
+ uint8_t flags = 0;
+ if (!node.isRanked()) {
+ flags |= ParseItem::IFLAG_NORANK;
+ }
+ if (!node.usePositionData()) {
+ flags |= ParseItem::IFLAG_NOPOSITIONDATA;
+ }
+ if (flags != 0) {
+ type |= ParseItem::IF_FLAGS;
+ }
+ appendByte(type);
+ appendCompressedNumber(node.getWeight().percent());
+ if (type & ParseItem::IF_FLAGS) {
+ appendByte(flags);
+ }
+ appendCompressedPositiveNumber(children.size());
+ appendString(node.getView());
+ visitNodes(children);
+ }
+
void createIntermediate(const Intermediate &node, size_t type) {
appendByte(type);
appendCompressedPositiveNumber(node.getChildren().size());
visitNodes(node.getChildren());
}
- void createIntermediate(const Intermediate &node, size_t type,
- size_t distance) {
+ void createIntermediate(const Intermediate &node, size_t type, size_t distance) {
appendByte(type);
appendCompressedPositiveNumber(node.getChildren().size());
appendCompressedPositiveNumber(distance);
visitNodes(node.getChildren());
}
- void createIntermediate(const Intermediate &node, size_t type,
- size_t distance,
- const vespalib::string & view) {
+ void createIntermediate(const Intermediate &node, size_t type, const vespalib::string & view) {
+ appendByte(type);
+ appendCompressedPositiveNumber(node.getChildren().size());
+ appendString(view);
+ visitNodes(node.getChildren());
+ }
+
+ void createIntermediate(const Intermediate &node, size_t type, size_t distance, const vespalib::string & view) {
appendByte(type);
appendCompressedPositiveNumber(node.getChildren().size());
appendCompressedPositiveNumber(distance);
@@ -116,26 +141,12 @@ class QueryNodeConverter : public QueryVisitor {
createIntermediate(node, ParseItem::ITEM_EQUIV);
}
+ void visit(SameElement &node) override {
+ createIntermediate(node, ParseItem::ITEM_SAME_ELEMENT, node.getView());
+ }
+
void visit(Phrase &node) override {
- uint8_t typefield = (ParseItem::ITEM_PHRASE | ParseItem::IF_WEIGHT);
- uint8_t flags = 0;
- if (!node.isRanked()) {
- flags |= ParseItem::IFLAG_NORANK;
- }
- if (!node.usePositionData()) {
- flags |= ParseItem::IFLAG_NOPOSITIONDATA;
- }
- if (flags != 0) {
- typefield |= ParseItem::IF_FLAGS;
- }
- appendByte(typefield);
- appendCompressedNumber(node.getWeight().percent());
- if (typefield & ParseItem::IF_FLAGS) {
- appendByte(flags);
- }
- appendCompressedPositiveNumber(node.getChildren().size());
- appendString(node.getView());
- visitNodes(node.getChildren());
+ createComplexIntermediate(node, node.getChildren(), (ParseItem::ITEM_PHRASE | ParseItem::IF_WEIGHT));
}
template <typename NODE>
@@ -187,9 +198,7 @@ class QueryNodeConverter : public QueryVisitor {
template <class Term>
void createTerm(const Term &node, size_t type) {
- uint8_t typefield = type |
- ParseItem::IF_WEIGHT |
- ParseItem::IF_UNIQUEID;
+ uint8_t typefield = type | ParseItem::IF_WEIGHT | ParseItem::IF_UNIQUEID;
uint8_t flags = 0;
if (!node.isRanked()) {
flags |= ParseItem::IFLAG_NORANK;
diff --git a/searchlib/src/vespa/searchlib/query/tree/stackdumpcreator.h b/searchlib/src/vespa/searchlib/query/tree/stackdumpcreator.h
index 448f1c9bd08..4e1556d05e6 100644
--- a/searchlib/src/vespa/searchlib/query/tree/stackdumpcreator.h
+++ b/searchlib/src/vespa/searchlib/query/tree/stackdumpcreator.h
@@ -4,8 +4,7 @@
#include <vespa/vespalib/stllike/string.h>
-namespace search {
-namespace query {
+namespace search::query {
class Node;
@@ -14,6 +13,4 @@ struct StackDumpCreator {
static vespalib::string create(const Node &node);
};
-} // namespace query
-} // namespace search
-
+}
diff --git a/searchlib/src/vespa/searchlib/query/tree/stackdumpquerycreator.h b/searchlib/src/vespa/searchlib/query/tree/stackdumpquerycreator.h
index f9c66965cc4..fa42cdac1c0 100644
--- a/searchlib/src/vespa/searchlib/query/tree/stackdumpquerycreator.h
+++ b/searchlib/src/vespa/searchlib/query/tree/stackdumpquerycreator.h
@@ -9,8 +9,7 @@
#include <vespa/searchlib/parsequery/simplequerystack.h>
#include <vespa/vespalib/objects/hexdump.h>
-namespace search {
-namespace query {
+namespace search::query {
/**
* Creates a query tree from a stack dump.
@@ -90,6 +89,10 @@ private:
Weight weight = queryStack.GetWeight();
t = &builder.addPhrase(arity, view, id, weight);
pureTermView = view;
+ } else if (type == ParseItem::ITEM_SAME_ELEMENT) {
+ vespalib::stringref view = queryStack.getIndexName();
+ builder.addSameElement(arity, view);
+ pureTermView = view;
} else if (type == ParseItem::ITEM_WEIGHTED_SET) {
vespalib::stringref view = queryStack.getIndexName();
int32_t id = queryStack.getUniqueId();
@@ -152,6 +155,4 @@ private:
}
};
-} // namespace query
-} // namespace search
-
+}
diff --git a/searchlib/src/vespa/searchlib/query/tree/templatetermvisitor.h b/searchlib/src/vespa/searchlib/query/tree/templatetermvisitor.h
index e4ce4ccf807..0cdaca82572 100644
--- a/searchlib/src/vespa/searchlib/query/tree/templatetermvisitor.h
+++ b/searchlib/src/vespa/searchlib/query/tree/templatetermvisitor.h
@@ -4,8 +4,7 @@
#include "customtypetermvisitor.h"
-namespace search {
-namespace query {
+namespace search::query {
/**
* Use this class to visit all term nodes by deriving from this class
@@ -54,5 +53,4 @@ class TemplateTermVisitor : public CustomTypeTermVisitor<NodeTypes> {
void visit(typename NodeTypes::WandTerm &n) override { myVisit(n); }
};
-} // namespace query
-} // namespace search
+}
diff --git a/searchlib/src/vespa/searchlib/query/tree/term.cpp b/searchlib/src/vespa/searchlib/query/tree/term.cpp
index 54def08afe8..de59752aa10 100644
--- a/searchlib/src/vespa/searchlib/query/tree/term.cpp
+++ b/searchlib/src/vespa/searchlib/query/tree/term.cpp
@@ -1,11 +1,11 @@
// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
#include "term.h"
+#include <cassert>
-namespace search {
-namespace query {
+namespace search::query {
-Term::~Term() { }
+Term::~Term() = default;
Term::Term(const vespalib::stringref &view, int32_t id, Weight weight) :
_view(view),
@@ -16,5 +16,14 @@ Term::Term(const vespalib::stringref &view, int32_t id, Weight weight) :
_position_data(true)
{ }
-} // namespace query
-} // namespace search
+void Term::setStateFrom(const Term& other) {
+ setTermIndex(other.getTermIndex());
+ setRanked(other.isRanked());
+ setPositionData(other.usePositionData());
+ // too late to copy this state:
+ assert(_view == other.getView());
+ assert(_id == other.getId());
+ assert(_weight == other.getWeight());
+}
+
+}
diff --git a/searchlib/src/vespa/searchlib/query/tree/term.h b/searchlib/src/vespa/searchlib/query/tree/term.h
index f8c0d98ac22..8e9b9897e9d 100644
--- a/searchlib/src/vespa/searchlib/query/tree/term.h
+++ b/searchlib/src/vespa/searchlib/query/tree/term.h
@@ -1,13 +1,11 @@
// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
#pragma once
-#include <vespa/vespalib/stllike/string.h>
-#include <vespa/searchlib/query/tree/node.h>
+#include "node.h"
#include <vespa/searchlib/query/weight.h>
-#include <cassert>
+#include <vespa/vespalib/stllike/string.h>
-namespace search {
-namespace query {
+namespace search::query {
/**
* This is a leaf in the Query tree. Sort of. Phrases are both terms
@@ -16,11 +14,11 @@ namespace query {
class Term
{
vespalib::string _view;
- int32_t _id;
- Weight _weight;
- int32_t _term_index;
- bool _ranked;
- bool _position_data;
+ int32_t _id;
+ Weight _weight;
+ int32_t _term_index;
+ bool _ranked;
+ bool _position_data;
public:
virtual ~Term() = 0;
@@ -29,15 +27,7 @@ public:
void setRanked(bool ranked) { _ranked = ranked; }
void setPositionData(bool position_data) { _position_data = position_data; }
- void setStateFrom(const Term& other) {
- setTermIndex(other.getTermIndex());
- setRanked(other.isRanked());
- setPositionData(other.usePositionData());
- // too late to copy this state:
- assert(_view == other.getView());
- assert(_id == other.getId());
- assert(_weight == other.getWeight());
- }
+ void setStateFrom(const Term& other);
const vespalib::string & getView() const { return _view; }
Weight getWeight() const { return _weight; }
@@ -60,7 +50,7 @@ class TermBase : public Node, public Term {
public:
typedef T Type;
- virtual ~TermBase() = 0;
+ ~TermBase() override = 0;
const T &getTerm() const { return _term; }
protected:
@@ -71,8 +61,6 @@ protected:
};
template <typename T>
-TermBase<T>::~TermBase() {}
-
-} // namespace query
-} // namespace search
+TermBase<T>::~TermBase() = default;
+}
diff --git a/searchlib/src/vespa/searchlib/query/tree/termnodes.cpp b/searchlib/src/vespa/searchlib/query/tree/termnodes.cpp
index 8e8ae16827b..0a6a6af62b5 100644
--- a/searchlib/src/vespa/searchlib/query/tree/termnodes.cpp
+++ b/searchlib/src/vespa/searchlib/query/tree/termnodes.cpp
@@ -2,27 +2,25 @@
#include "termnodes.h"
-namespace search {
-namespace query {
+namespace search::query {
-NumberTerm::~NumberTerm() {}
+NumberTerm::~NumberTerm() = default;
-PrefixTerm::~PrefixTerm() {}
+PrefixTerm::~PrefixTerm() = default;
-RangeTerm::~RangeTerm() {}
+RangeTerm::~RangeTerm() = default;
StringTerm::StringTerm(const Type &term, const vespalib::stringref &view, int32_t id, Weight weight)
: QueryNodeMixinType(term, view, id, weight)
{}
-StringTerm::~StringTerm() {}
+StringTerm::~StringTerm() = default;
-SubstringTerm::~SubstringTerm() {}
+SubstringTerm::~SubstringTerm() = default;
-SuffixTerm::~SuffixTerm() {}
+SuffixTerm::~SuffixTerm() = default;
-LocationTerm::~LocationTerm() {}
+LocationTerm::~LocationTerm() = default;
-RegExpTerm::~RegExpTerm() {}
+RegExpTerm::~RegExpTerm() = default;
-} // namespace query
-} // namespace search
+}
diff --git a/searchlib/src/vespa/searchlib/query/tree/termnodes.h b/searchlib/src/vespa/searchlib/query/tree/termnodes.h
index 4c98ba92ff5..8d4882fb393 100644
--- a/searchlib/src/vespa/searchlib/query/tree/termnodes.h
+++ b/searchlib/src/vespa/searchlib/query/tree/termnodes.h
@@ -8,8 +8,7 @@
#include "range.h"
#include "term.h"
-namespace search {
-namespace query {
+namespace search::query {
typedef TermBase<vespalib::string> StringBase;
@@ -117,6 +116,4 @@ public:
};
-} // namespace query
-} // namespace search
-
+}
diff --git a/searchlib/src/vespa/searchlib/query/weight.h b/searchlib/src/vespa/searchlib/query/weight.h
index 1b4168231c5..51596642cd2 100644
--- a/searchlib/src/vespa/searchlib/query/weight.h
+++ b/searchlib/src/vespa/searchlib/query/weight.h
@@ -3,8 +3,7 @@
#include <cstdint>
-namespace search {
-namespace query {
+namespace search::query {
/**
* Represents the weight given on a query item such as a term, phrase, or equiv.
@@ -44,8 +43,7 @@ public:
bool operator== (const Weight& other) const { return _weight == other._weight; }
};
-} // namespace query
-} // namespace search
+}
inline search::query::Weight operator+(const search::query::Weight& a, const search::query::Weight& b)
{
diff --git a/searchlib/src/vespa/searchlib/queryeval/create_blueprint_visitor_helper.cpp b/searchlib/src/vespa/searchlib/queryeval/create_blueprint_visitor_helper.cpp
index 8e6429aaa90..e3dac98e588 100644
--- a/searchlib/src/vespa/searchlib/queryeval/create_blueprint_visitor_helper.cpp
+++ b/searchlib/src/vespa/searchlib/queryeval/create_blueprint_visitor_helper.cpp
@@ -19,7 +19,7 @@ CreateBlueprintVisitorHelper::CreateBlueprintVisitorHelper(Searchable &searchabl
_result()
{}
-CreateBlueprintVisitorHelper::~CreateBlueprintVisitorHelper() {}
+CreateBlueprintVisitorHelper::~CreateBlueprintVisitorHelper() = default;
Blueprint::UP
CreateBlueprintVisitorHelper::getResult()
@@ -30,7 +30,7 @@ CreateBlueprintVisitorHelper::getResult()
}
void
-CreateBlueprintVisitorHelper::visitPhrase(search::query::Phrase &n) {
+CreateBlueprintVisitorHelper::visitPhrase(query::Phrase &n) {
SimplePhraseBlueprint *phrase = new SimplePhraseBlueprint(_field, _requestContext);
Blueprint::UP result(phrase);
for (size_t i = 0; i < n.getChildren().size(); ++i) {
@@ -42,7 +42,7 @@ CreateBlueprintVisitorHelper::visitPhrase(search::query::Phrase &n) {
}
void
-CreateBlueprintVisitorHelper::handleNumberTermAsText(search::query::NumberTerm &n)
+CreateBlueprintVisitorHelper::handleNumberTermAsText(query::NumberTerm &n)
{
vespalib::string termStr = termAsString(n);
queryeval::SplitFloat splitter(termStr);
@@ -73,24 +73,24 @@ CreateBlueprintVisitorHelper::createWeightedSet(WS *bp, NODE &n) {
for (size_t i = 0; i < n.getChildren().size(); ++i) {
fields.clear();
fields.add(bp->getNextChildField(_field));
- const search::query::Node &node = *n.getChildren()[i];
+ const query::Node &node = *n.getChildren()[i];
uint32_t weight = getWeightFromNode(node).percent();
bp->addTerm(_searchable.createBlueprint(_requestContext, fields, node), weight);
}
setResult(std::move(result));
}
void
-CreateBlueprintVisitorHelper::visitWeightedSetTerm(search::query::WeightedSetTerm &n) {
+CreateBlueprintVisitorHelper::visitWeightedSetTerm(query::WeightedSetTerm &n) {
WeightedSetTermBlueprint *bp = new WeightedSetTermBlueprint(_field);
createWeightedSet(bp, n);
}
void
-CreateBlueprintVisitorHelper::visitDotProduct(search::query::DotProduct &n) {
+CreateBlueprintVisitorHelper::visitDotProduct(query::DotProduct &n) {
DotProductBlueprint *bp = new DotProductBlueprint(_field);
createWeightedSet(bp, n);
}
void
-CreateBlueprintVisitorHelper::visitWandTerm(search::query::WandTerm &n) {
+CreateBlueprintVisitorHelper::visitWandTerm(query::WandTerm &n) {
ParallelWeakAndBlueprint *bp = new ParallelWeakAndBlueprint(_field,
n.getTargetNumHits(),
n.getScoreThreshold(),
diff --git a/searchlib/src/vespa/searchlib/queryeval/create_blueprint_visitor_helper.h b/searchlib/src/vespa/searchlib/queryeval/create_blueprint_visitor_helper.h
index cded9c103dc..5bcc4f4c4c5 100644
--- a/searchlib/src/vespa/searchlib/queryeval/create_blueprint_visitor_helper.h
+++ b/searchlib/src/vespa/searchlib/queryeval/create_blueprint_visitor_helper.h
@@ -12,7 +12,7 @@
namespace search::queryeval {
-class CreateBlueprintVisitorHelper : public search::query::QueryVisitor
+class CreateBlueprintVisitorHelper : public query::QueryVisitor
{
private:
const IRequestContext & _requestContext;
@@ -37,42 +37,43 @@ public:
const FieldSpec &getField() const { return _field; }
- void visitPhrase(search::query::Phrase &n);
+ void visitPhrase(query::Phrase &n);
template <typename WS, typename NODE>
void createWeightedSet(WS *bp, NODE &n);
- void visitWeightedSetTerm(search::query::WeightedSetTerm &n);
- void visitDotProduct(search::query::DotProduct &n);
- void visitWandTerm(search::query::WandTerm &n);
+ void visitWeightedSetTerm(query::WeightedSetTerm &n);
+ void visitDotProduct(query::DotProduct &n);
+ void visitWandTerm(query::WandTerm &n);
- void handleNumberTermAsText(search::query::NumberTerm &n);
+ void handleNumberTermAsText(query::NumberTerm &n);
void illegalVisit() {}
- void visit(search::query::And &) override { illegalVisit(); }
- void visit(search::query::AndNot &) override { illegalVisit(); }
- void visit(search::query::Equiv &) override { illegalVisit(); }
- void visit(search::query::Near &) override { illegalVisit(); }
- void visit(search::query::ONear &) override { illegalVisit(); }
- void visit(search::query::Or &) override { illegalVisit(); }
- void visit(search::query::Rank &) override { illegalVisit(); }
- void visit(search::query::WeakAnd &) override { illegalVisit(); }
-
- void visit(search::query::Phrase &n) override {
+ void visit(query::And &) override { illegalVisit(); }
+ void visit(query::AndNot &) override { illegalVisit(); }
+ void visit(query::Equiv &) override { illegalVisit(); }
+ void visit(query::Near &) override { illegalVisit(); }
+ void visit(query::ONear &) override { illegalVisit(); }
+ void visit(query::Or &) override { illegalVisit(); }
+ void visit(query::Rank &) override { illegalVisit(); }
+ void visit(query::WeakAnd &) override { illegalVisit(); }
+ void visit(query::SameElement &) override { illegalVisit(); }
+
+ void visit(query::Phrase &n) override {
visitPhrase(n);
}
- void visit(search::query::WeightedSetTerm &n) override { visitWeightedSetTerm(n); }
- void visit(search::query::DotProduct &n) override { visitDotProduct(n); }
- void visit(search::query::WandTerm &n) override { visitWandTerm(n); }
-
- void visit(search::query::NumberTerm &n) override = 0;
- void visit(search::query::LocationTerm &n) override = 0;
- void visit(search::query::PrefixTerm &n) override = 0;
- void visit(search::query::RangeTerm &n) override = 0;
- void visit(search::query::StringTerm &n) override = 0;
- void visit(search::query::SubstringTerm &n) override = 0;
- void visit(search::query::SuffixTerm &n) override = 0;
- void visit(search::query::RegExpTerm &n) override = 0;
+ void visit(query::WeightedSetTerm &n) override { visitWeightedSetTerm(n); }
+ void visit(query::DotProduct &n) override { visitDotProduct(n); }
+ void visit(query::WandTerm &n) override { visitWandTerm(n); }
+
+ void visit(query::NumberTerm &n) override = 0;
+ void visit(query::LocationTerm &n) override = 0;
+ void visit(query::PrefixTerm &n) override = 0;
+ void visit(query::RangeTerm &n) override = 0;
+ void visit(query::StringTerm &n) override = 0;
+ void visit(query::SubstringTerm &n) override = 0;
+ void visit(query::SuffixTerm &n) override = 0;
+ void visit(query::RegExpTerm &n) override = 0;
};
}
diff --git a/searchlib/src/vespa/searchlib/queryeval/get_weight_from_node.cpp b/searchlib/src/vespa/searchlib/queryeval/get_weight_from_node.cpp
index 8fa6af74ae2..bd9de0a1762 100644
--- a/searchlib/src/vespa/searchlib/queryeval/get_weight_from_node.cpp
+++ b/searchlib/src/vespa/searchlib/queryeval/get_weight_from_node.cpp
@@ -13,8 +13,7 @@ using search::query::Weight;
namespace search::queryeval {
namespace {
-struct WeightExtractor : public TemplateTermVisitor<WeightExtractor,
- SimpleQueryNodeTypes> {
+struct WeightExtractor : public TemplateTermVisitor<WeightExtractor, SimpleQueryNodeTypes> {
Weight weight;
WeightExtractor() : weight(0) {}
diff --git a/searchlib/src/vespa/searchlib/queryeval/termasstring.cpp b/searchlib/src/vespa/searchlib/queryeval/termasstring.cpp
index 14a6cefaf1b..3829ea45e2b 100644
--- a/searchlib/src/vespa/searchlib/queryeval/termasstring.cpp
+++ b/searchlib/src/vespa/searchlib/queryeval/termasstring.cpp
@@ -22,6 +22,7 @@ using search::query::Node;
using search::query::ONear;
using search::query::Or;
using search::query::Phrase;
+using search::query::SameElement;
using search::query::PredicateQuery;
using search::query::PrefixTerm;
using search::query::QueryVisitor;
@@ -84,6 +85,7 @@ struct TermAsStringVisitor : public QueryVisitor {
void visit(ONear &) override {illegalVisit(); }
void visit(Or &) override {illegalVisit(); }
void visit(Phrase &) override {illegalVisit(); }
+ void visit(SameElement &) override {illegalVisit(); }
void visit(Rank &) override {illegalVisit(); }
void visit(WeakAnd &) override {illegalVisit(); }
void visit(WeightedSetTerm &) override {illegalVisit(); }
diff --git a/searchsummary/src/tests/extractkeywords/extractkeywordstest.cpp b/searchsummary/src/tests/extractkeywords/extractkeywordstest.cpp
index eac6f65a48e..b2920b39eaf 100644
--- a/searchsummary/src/tests/extractkeywords/extractkeywordstest.cpp
+++ b/searchsummary/src/tests/extractkeywords/extractkeywordstest.cpp
@@ -200,7 +200,7 @@ ExtractKeywordsTest::RunTest(int testno, bool verify)
stack.Push(new search::ParseItem(search::ParseItem::ITEM_TERM, "foobar"));
stack.Push(new search::ParseItem(search::ParseItem::ITEM_TERM, "foo"));
stack.Push(new search::ParseItem(search::ParseItem::ITEM_TERM, "bar"));
- stack.Push(new search::ParseItem(search::ParseItem::ITEM_PHRASE, 3));
+ stack.Push(new search::ParseItem(search::ParseItem::ITEM_PHRASE, 3, "index"));
stack.AppendBuffer(&buf);
keywords = _extractor->ExtractKeywords(vespalib::stringref(buf.GetDrainPos(), buf.GetUsedLen()));
@@ -216,11 +216,11 @@ ExtractKeywordsTest::RunTest(int testno, bool verify)
// multiple phrase and term query
stack.Push(new search::ParseItem(search::ParseItem::ITEM_TERM, "xyzzy"));
stack.Push(new search::ParseItem(search::ParseItem::ITEM_TERM, "xyz"));
- stack.Push(new search::ParseItem(search::ParseItem::ITEM_PHRASE, 2));
+ stack.Push(new search::ParseItem(search::ParseItem::ITEM_PHRASE, 2, "index"));
stack.Push(new search::ParseItem(search::ParseItem::ITEM_TERM, "foobar"));
stack.Push(new search::ParseItem(search::ParseItem::ITEM_TERM, "foo"));
stack.Push(new search::ParseItem(search::ParseItem::ITEM_TERM, "bar"));
- stack.Push(new search::ParseItem(search::ParseItem::ITEM_PHRASE, 3));
+ stack.Push(new search::ParseItem(search::ParseItem::ITEM_PHRASE, 3, "index"));
stack.Push(new search::ParseItem(search::ParseItem::ITEM_TERM, "baz"));
stack.Push(new search::ParseItem(search::ParseItem::ITEM_TERM, "zog"));
stack.Push(new search::ParseItem(search::ParseItem::ITEM_AND, 3));
@@ -241,7 +241,7 @@ ExtractKeywordsTest::RunTest(int testno, bool verify)
stack.Push(new search::ParseItem(search::ParseItem::ITEM_TERM, "foo"));
stack.Push(new search::ParseItem(search::ParseItem::ITEM_AND, 2));
stack.Push(new search::ParseItem(search::ParseItem::ITEM_TERM, "bar"));
- stack.Push(new search::ParseItem(search::ParseItem::ITEM_PHRASE, 2));
+ stack.Push(new search::ParseItem(search::ParseItem::ITEM_PHRASE, 2, "index"));
stack.AppendBuffer(&buf);
keywords = _extractor->ExtractKeywords(vespalib::stringref(buf.GetDrainPos(), buf.GetUsedLen()));
diff --git a/searchsummary/src/vespa/searchsummary/docsummary/dynamicteaserdfw.cpp b/searchsummary/src/vespa/searchsummary/docsummary/dynamicteaserdfw.cpp
index e535eef660c..c7eb63a4480 100644
--- a/searchsummary/src/vespa/searchsummary/docsummary/dynamicteaserdfw.cpp
+++ b/searchsummary/src/vespa/searchsummary/docsummary/dynamicteaserdfw.cpp
@@ -280,6 +280,7 @@ JuniperQueryAdapter::Traverse(juniper::IQueryVisitor *v) const
case search::ParseItem::ITEM_SUFFIXTERM:
case search::ParseItem::ITEM_REGEXP:
case search::ParseItem::ITEM_PREDICATE_QUERY:
+ case search::ParseItem::ITEM_SAME_ELEMENT:
if (!v->VisitOther(&item, iterator.getArity())) {
rc = SkipItem(&iterator);
}
diff --git a/searchsummary/src/vespa/searchsummary/docsummary/keywordextractor.cpp b/searchsummary/src/vespa/searchsummary/docsummary/keywordextractor.cpp
index e153a898f6a..3a60db52cf3 100644
--- a/searchsummary/src/vespa/searchsummary/docsummary/keywordextractor.cpp
+++ b/searchsummary/src/vespa/searchsummary/docsummary/keywordextractor.cpp
@@ -165,7 +165,7 @@ KeywordExtractor::ExtractKeywords(vespalib::stringref buf) const
break;
case search::ParseItem::ITEM_PHRASE:
- {
+ {
// Must take the next arity TERMS and put together
bool phraseterms_was_added = false;
int phraseterms = si.getArity();
diff --git a/valgrind-suppressions.txt b/valgrind-suppressions.txt
index baef981a3f9..2df6c9c5691 100644
--- a/valgrind-suppressions.txt
+++ b/valgrind-suppressions.txt
@@ -6,6 +6,14 @@
fun:pthread_create@@GLIBC_2.2.5
}
{
+ NPTL keeps a cache of thread stacks, and metadata for thread local storage is not freed for threads in that cache
+ Memcheck:Leak
+ fun:calloc
+ fun:allocate_dtv
+ fun:_dl_allocate_tls
+ fun:pthread_create@@GLIBC_2.2.5
+}
+{
This is a bug in glibc. We can not suffer for that.
Memcheck:Free
fun:free