summaryrefslogtreecommitdiffstats
path: root/container-search
diff options
context:
space:
mode:
authorJon Bratseth <bratseth@gmail.com>2022-10-13 11:20:55 +0200
committerJon Bratseth <bratseth@gmail.com>2022-10-13 11:20:55 +0200
commitc517cc62133063c088f9e68a28a065dc5e24abd1 (patch)
tree37e69aa4a951093464a9009de166598b12d3bbdf /container-search
parent9259007b603c4f5ec98597a4e1bf63e23cb660a6 (diff)
No functional changes
Diffstat (limited to 'container-search')
-rw-r--r--container-search/src/main/java/com/yahoo/prelude/query/RegExpItem.java40
-rw-r--r--container-search/src/main/java/com/yahoo/search/yql/ProgramParser.java92
-rw-r--r--container-search/src/main/java/com/yahoo/search/yql/VespaSerializer.java1
-rw-r--r--container-search/src/main/java/com/yahoo/search/yql/YqlParser.java2
-rw-r--r--container-search/src/test/java/com/yahoo/search/yql/YqlParserTestCase.java19
5 files changed, 69 insertions, 85 deletions
diff --git a/container-search/src/main/java/com/yahoo/prelude/query/RegExpItem.java b/container-search/src/main/java/com/yahoo/prelude/query/RegExpItem.java
index 29cf7803d61..79fbeb99119 100644
--- a/container-search/src/main/java/com/yahoo/prelude/query/RegExpItem.java
+++ b/container-search/src/main/java/com/yahoo/prelude/query/RegExpItem.java
@@ -2,6 +2,7 @@
package com.yahoo.prelude.query;
import java.nio.ByteBuffer;
+import java.util.Objects;
import java.util.regex.Pattern;
/**
@@ -70,43 +71,26 @@ public class RegExpItem extends TermItem {
putString(getIndexedString(), buffer);
}
+ public Pattern getRegexp() { return regexp; }
+
@Override
public String toString() {
- StringBuilder builder = new StringBuilder();
- builder.append("RegExpItem [expression=").append(expression).append("]");
- return builder.toString();
+ return "RegExpItem [expression=" + expression + "]";
}
@Override
public int hashCode() {
- final int prime = 31;
- int result = super.hashCode();
- result = prime * result + ((expression == null) ? 0 : expression.hashCode());
- return result;
+ return Objects.hash(super.hashCode(), expression);
}
@Override
- public boolean equals(Object obj) {
- if (this == obj) {
- return true;
- }
- if (!super.equals(obj)) {
- return false;
- }
- if (getClass() != obj.getClass()) {
- return false;
- }
- RegExpItem other = (RegExpItem) obj;
- if (expression == null) {
- if (other.expression != null) {
- return false;
- }
- } else if (!expression.equals(other.expression)) {
- return false;
- }
- return true;
- }
+ public boolean equals(Object o) {
+ if (this == o) return true;
+ if ( ! super.equals(o)) return false;
+ if (getClass() != o.getClass()) return false;
- public Pattern getRegexp() { return regexp; }
+ RegExpItem other = (RegExpItem)o;
+ return Objects.equals(this.expression, other.expression);
+ }
}
diff --git a/container-search/src/main/java/com/yahoo/search/yql/ProgramParser.java b/container-search/src/main/java/com/yahoo/search/yql/ProgramParser.java
index 5258087eb44..32880f9b1a8 100644
--- a/container-search/src/main/java/com/yahoo/search/yql/ProgramParser.java
+++ b/container-search/src/main/java/com/yahoo/search/yql/ProgramParser.java
@@ -277,29 +277,28 @@ final class ProgramParser {
switch (getParseTreeIndex(sourceNode)) {
// ALL_SOURCE and MULTI_SOURCE are how FROM SOURCES
// *|source_name,... are parsed
- case yqlplusParser.RULE_select_source_all:
- Location location = toLocation(scope, sourceNode.getChild(2));
+ case yqlplusParser.RULE_select_source_all -> {
+ Location location = toLocation(scope, sourceNode.getChild(2));
source = OperatorNode.create(location, SequenceOperator.ALL);
source.putAnnotation("alias", "row");
scope.defineDataSource(location, "row");
- break;
- case yqlplusParser.RULE_select_source_multi:
- Source_listContext multiSourceContext = ((Select_source_multiContext) sourceNode).source_list();
+ }
+ case yqlplusParser.RULE_select_source_multi -> {
+ Source_listContext multiSourceContext = ((Select_source_multiContext) sourceNode).source_list();
source = readMultiSource(scope, multiSourceContext);
source.putAnnotation("alias", "row");
scope.defineDataSource(toLocation(scope, multiSourceContext), "row");
- break;
- case yqlplusParser.RULE_select_source_from:
- source = convertSource((ParserRuleContext) sourceNode.getChild(1), scope);
- break;
}
- } else {
- source = OperatorNode.create(SequenceOperator.EMPTY);
+ case yqlplusParser.RULE_select_source_from ->
+ source = convertSource((ParserRuleContext) sourceNode.getChild(1), scope);
}
+ } else {
+ source = OperatorNode.create(SequenceOperator.EMPTY);
+ }
- for (int i = 1; i < node.getChildCount(); ++i) {
- ParseTree child = node.getChild(i);
- switch (getParseTreeIndex(child)) {
+ for (int i = 1; i < node.getChildCount(); ++i) {
+ ParseTree child = node.getChild(i);
+ switch (getParseTreeIndex(child)) {
case yqlplusParser.RULE_select_field_spec:
if (getParseTreeIndex(child.getChild(0)) == yqlplusParser.RULE_project_spec) {
proj = readProjection(((Project_specContext) child.getChild(0)).field_def(), scope);
@@ -311,7 +310,7 @@ final class ProgramParser {
case yqlplusParser.RULE_orderby:
// OrderbyContext orderby()
List<Orderby_fieldContext> orderFieds = ((OrderbyContext) child)
- .orderby_fields().orderby_field();
+ .orderby_fields().orderby_field();
orderby = Lists.newArrayListWithExpectedSize(orderFieds.size());
for (var field: orderFieds) {
orderby.add(convertSortKey(field, scope));
@@ -326,8 +325,8 @@ final class ProgramParser {
case yqlplusParser.RULE_timeout:
timeout = convertExpr(((TimeoutContext) child).fixed_or_parameter(), scope);
break;
- }
}
+ }
// now assemble the logical plan
OperatorNode<SequenceOperator> result = source;
// filter
@@ -415,8 +414,7 @@ final class ProgramParser {
private OperatorNode<SequenceOperator> convertQuery(ParseTree node, Scope scope) {
if (node instanceof Select_statementContext) {
return convertSelect(node, scope.getRoot());
- } else if (node instanceof Source_statementContext) { // for pipe
- Source_statementContext sourceStatementContext = (Source_statementContext)node;
+ } else if (node instanceof Source_statementContext sourceStatementContext) { // for pipe
return convertPipe(sourceStatementContext.query_statement(), sourceStatementContext.pipeline_step(), scope);
} else {
throw new IllegalArgumentException("Unexpected argument type to convertQueryStatement: " + node.toStringTree());
@@ -469,47 +467,44 @@ final class ProgramParser {
dataSourceNode = (ParserRuleContext)dataSourceNode.getChild(1);
}
}
- switch (getParseTreeIndex(dataSourceNode)) {
- case yqlplusParser.RULE_call_source: {
- List<String> names = readName(dataSourceNode.getChild(Namespaced_nameContext.class, 0));
- alias = assignAlias(names.get(names.size() - 1), aliasContext, scope);
- List<OperatorNode<ExpressionOperator>> arguments = ImmutableList.of();
- ArgumentsContext argumentsContext = dataSourceNode.getRuleContext(ArgumentsContext.class,0);
- if ( argumentsContext != null) {
- List<ArgumentContext> argumentContexts = argumentsContext.argument();
- arguments = Lists.newArrayListWithExpectedSize(argumentContexts.size());
- for (ArgumentContext argumentContext:argumentContexts) {
- arguments.add(convertExpr(argumentContext, scope));
- }
- }
- if (names.size() == 1 && scope.isVariable(names.get(0))) {
- String ident = names.get(0);
- if (arguments.size() > 0) {
- throw new ProgramCompileException(toLocation(scope, argumentsContext), "Invalid call-with-arguments on local source '%s'", ident);
- }
- result = OperatorNode.create(toLocation(scope, dataSourceNode), SequenceOperator.EVALUATE, OperatorNode.create(toLocation(scope, dataSourceNode), ExpressionOperator.VARREF, ident));
+ switch (getParseTreeIndex(dataSourceNode)) {
+ case yqlplusParser.RULE_call_source -> {
+ List<String> names = readName(dataSourceNode.getChild(Namespaced_nameContext.class, 0));
+ alias = assignAlias(names.get(names.size() - 1), aliasContext, scope);
+ List<OperatorNode<ExpressionOperator>> arguments = ImmutableList.of();
+ ArgumentsContext argumentsContext = dataSourceNode.getRuleContext(ArgumentsContext.class, 0);
+ if (argumentsContext != null) {
+ List<ArgumentContext> argumentContexts = argumentsContext.argument();
+ arguments = Lists.newArrayListWithExpectedSize(argumentContexts.size());
+ for (ArgumentContext argumentContext : argumentContexts) {
+ arguments.add(convertExpr(argumentContext, scope));
+ }
+ }
+ if (names.size() == 1 && scope.isVariable(names.get(0))) {
+ String ident = names.get(0);
+ if (arguments.size() > 0) {
+ throw new ProgramCompileException(toLocation(scope, argumentsContext), "Invalid call-with-arguments on local source '%s'", ident);
+ }
+ result = OperatorNode.create(toLocation(scope, dataSourceNode), SequenceOperator.EVALUATE, OperatorNode.create(toLocation(scope, dataSourceNode), ExpressionOperator.VARREF, ident));
} else {
- result = OperatorNode.create(toLocation(scope, dataSourceNode), SequenceOperator.SCAN, scope.resolvePath(names), arguments);
+ result = OperatorNode.create(toLocation(scope, dataSourceNode), SequenceOperator.SCAN, scope.resolvePath(names), arguments);
}
- break;
}
- case yqlplusParser.RULE_sequence_source: {
- IdentContext identContext = dataSourceNode.getRuleContext(IdentContext.class,0);
+ case yqlplusParser.RULE_sequence_source -> {
+ IdentContext identContext = dataSourceNode.getRuleContext(IdentContext.class, 0);
String ident = identContext.getText();
if (!scope.isVariable(ident)) {
throw new ProgramCompileException(toLocation(scope, identContext), "Unknown variable reference '%s'", ident);
}
alias = assignAlias(ident, aliasContext, scope);
result = OperatorNode.create(toLocation(scope, dataSourceNode), SequenceOperator.EVALUATE, OperatorNode.create(toLocation(scope, dataSourceNode), ExpressionOperator.VARREF, ident));
- break;
}
- case yqlplusParser.RULE_source_statement: {
+ case yqlplusParser.RULE_source_statement -> {
alias = assignAlias(null, dataSourceNode, scope);
result = convertQuery(dataSourceNode, scope);
- break;
}
- default:
- throw new IllegalArgumentException("Unexpected argument type to convertSource: " + dataSourceNode.getText());
+ default ->
+ throw new IllegalArgumentException("Unexpected argument type to convertSource: " + dataSourceNode.getText());
}
result.putAnnotation("alias", alias);
return result;
@@ -522,10 +517,7 @@ final class ProgramParser {
List<OperatorNode<StatementOperator>> stmts = Lists.newArrayList();
int output = 0;
for (ParseTree node : program.children) {
- if (!(node instanceof ParserRuleContext)) {
- continue;
- }
- ParserRuleContext ruleContext = (ParserRuleContext) node;
+ if (!(node instanceof ParserRuleContext ruleContext)) continue;
if (ruleContext.getRuleIndex() != yqlplusParser.RULE_statement)
throw new ProgramCompileException("Unknown program element: " + node.getText());
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 cab989d4466..4b035e0ccc5 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
@@ -121,7 +121,6 @@ import com.yahoo.search.query.QueryTree;
public class VespaSerializer {
// TODO: Refactor, too much copy/paste
-
private static abstract class Serializer<ITEM extends Item> {
abstract void onExit(StringBuilder destination, ITEM item);
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 72cb102760a..9d47f7cef9f 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
@@ -90,11 +90,9 @@ import com.yahoo.search.query.parser.ParserFactory;
/**
* The YQL query language.
*
- * <p>
* This class <em>must</em> be kept in lockstep with {@link VespaSerializer}.
* Adding anything here will usually require a corresponding addition in
* VespaSerializer.
- * </p>
*
* @author Steinar Knutsen
* @author Stian Kristoffersen
diff --git a/container-search/src/test/java/com/yahoo/search/yql/YqlParserTestCase.java b/container-search/src/test/java/com/yahoo/search/yql/YqlParserTestCase.java
index 5beea5352aa..807681e1d7b 100644
--- a/container-search/src/test/java/com/yahoo/search/yql/YqlParserTestCase.java
+++ b/container-search/src/test/java/com/yahoo/search/yql/YqlParserTestCase.java
@@ -1002,10 +1002,21 @@ public class YqlParserTestCase {
@Test
void testRegexp() {
- QueryTree x = parse("select * from sources * where foo matches \"a b\"");
- Item root = x.getRoot();
- assertSame(RegExpItem.class, root.getClass());
- assertEquals("a b", ((RegExpItem) root).stringValue());
+ {
+ QueryTree x = parse("select * from sources * where foo matches \"a b\"");
+ Item root = x.getRoot();
+ assertSame(RegExpItem.class, root.getClass());
+ assertEquals("a b", ((RegExpItem) root).stringValue());
+ }
+
+ {
+ String expression = "a\\\\.b\\\\.c";
+ QueryTree query = parse("select * from sources * where foo matches \"" + expression + "\"");
+ var regExpItem = (RegExpItem) query.getRoot();
+ assertEquals("a\\.b\\.c", regExpItem.stringValue());
+ assertTrue(regExpItem.getRegexp().matcher("a.b.c").matches(), "a.b.c is matched");
+ assertFalse(regExpItem.getRegexp().matcher("a,b,c").matches(), "a,b,c is matched?");
+ }
}
@Test