diff options
author | Jon Bratseth <bratseth@gmail.com> | 2022-10-13 11:20:55 +0200 |
---|---|---|
committer | Jon Bratseth <bratseth@gmail.com> | 2022-10-13 11:20:55 +0200 |
commit | c517cc62133063c088f9e68a28a065dc5e24abd1 (patch) | |
tree | 37e69aa4a951093464a9009de166598b12d3bbdf /container-search | |
parent | 9259007b603c4f5ec98597a4e1bf63e23cb660a6 (diff) |
No functional changes
Diffstat (limited to 'container-search')
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 |