Throw error for optionality in distances
Change-Id: Ib555eef2cf512ce4bf443779096175c3009cc431
diff --git a/src/main/java/de/ids_mannheim/korap/Krill.java b/src/main/java/de/ids_mannheim/korap/Krill.java
index de55528..437e1e9 100644
--- a/src/main/java/de/ids_mannheim/korap/Krill.java
+++ b/src/main/java/de/ids_mannheim/korap/Krill.java
@@ -178,10 +178,10 @@
// Throw an error, in case the query matches everywhere
if (qw.isEmpty()) {
this.addError(780, "This query matches everywhere");
- }
- else if (qw.isNull()) {
- this.addError(783, "This query can't match anywhere");
- }
+ }
+ else if (qw.isNull()) {
+ this.addError(783, "This query can't match anywhere");
+ }
else {
diff --git a/src/main/java/de/ids_mannheim/korap/KrillQuery.java b/src/main/java/de/ids_mannheim/korap/KrillQuery.java
index 3185603..3d70505 100644
--- a/src/main/java/de/ids_mannheim/korap/KrillQuery.java
+++ b/src/main/java/de/ids_mannheim/korap/KrillQuery.java
@@ -115,7 +115,7 @@
// Set max boundary
this.max = json.has("max") ? json.get("max").asInt(defaultMax)
: defaultMax;
-
+
if (DEBUG)
log.trace("Found koral:boundary with {}:{}", min, max);
};
@@ -723,12 +723,12 @@
// Check relation between min and max
if (min > max)
max = max;
-
+
SpanQueryWrapper sqw = this._fromKoral(operands.get(0));
if (sqw.maybeExtension())
return sqw.setMin(min).setMax(max);
-
+
return new SpanRepetitionQueryWrapper(sqw, min, max);
};
diff --git a/src/main/java/de/ids_mannheim/korap/query/wrap/SpanQueryWrapper.java b/src/main/java/de/ids_mannheim/korap/query/wrap/SpanQueryWrapper.java
index 82349b2..f31006d 100644
--- a/src/main/java/de/ids_mannheim/korap/query/wrap/SpanQueryWrapper.java
+++ b/src/main/java/de/ids_mannheim/korap/query/wrap/SpanQueryWrapper.java
@@ -36,7 +36,7 @@
protected boolean hasClass = false, isNull = true, isOptional = false,
isNegative = false, isEmpty = false, isExtended = false,
isExtendedToTheRight = false, maybeUnsorted = false,
- retrieveNode = false;
+ retrieveNode = false, isProblematic = false;
/**
@@ -47,7 +47,6 @@
* @throws QueryException
*/
public SpanQuery toFragmentQuery () throws QueryException {
- System.err.println("||||||||||||||||||||||||||");
return (SpanQuery) null;
};
@@ -62,8 +61,9 @@
*/
public SpanQuery toQuery () throws QueryException {
- if (this.isNull() || this.isEmpty())
+ if (this.isNull() || this.isEmpty()) {
return null;
+ };
// Wrap the query in a <base/s=t>, if it's extended to the right
if (this.isExtendedToTheRight()) {
diff --git a/src/main/java/de/ids_mannheim/korap/query/wrap/SpanSequenceQueryWrapper.java b/src/main/java/de/ids_mannheim/korap/query/wrap/SpanSequenceQueryWrapper.java
index 72fadb2..f100853 100644
--- a/src/main/java/de/ids_mannheim/korap/query/wrap/SpanSequenceQueryWrapper.java
+++ b/src/main/java/de/ids_mannheim/korap/query/wrap/SpanSequenceQueryWrapper.java
@@ -612,6 +612,7 @@
public boolean isEmpty () {
+
if (this.segments.size() == 1)
return this.segments.get(0).isEmpty();
@@ -741,6 +742,11 @@
return (SpanQuery) query;
};
+ if (this.hasConstraints() && this.isProblematic) {
+ throw new QueryException(613,
+ "Distance constraints not supported with empty, optional or negative operands");
+ };
+
// DistanceQueries
if (this.constraints.size() == 1) {
DistanceConstraint constraint = this.constraints.get(0);
@@ -753,6 +759,11 @@
if (this.segments.get(i).isExtended())
throw new QueryException(613, limitationError);
+ /* Maybe important
+ if (this.segments.get(i).isOptional())
+ throw new QueryException(613, limitationError);
+ */
+
SpanQuery sq = (SpanQuery) this.segments.get(i)
.retrieveNode(this.retrieveNode).toFragmentQuery();
if (sq == null)
@@ -772,6 +783,11 @@
if (this.segments.get(i).isExtended())
throw new QueryException(613, limitationError);
+ /* May be necessary
+ if (this.segments.get(i).isOptional())
+ throw new QueryException(613, limitationError);
+ */
+
SpanQuery sq = (SpanQuery) this.segments.get(i)
.retrieveNode(this.retrieveNode).toFragmentQuery();
if (sq == null)
@@ -817,6 +833,8 @@
- look for an anchor next to it
- merge the problematic segment with the anchor
- go on
+
+ - This does not work for distance constraints!
*/
private boolean _solveProblematicSequence () {
int size = this.segments.size();
@@ -838,6 +856,18 @@
if (DEBUG)
log.trace("segment {} is problematic", i);
+ // Sequences with distance constraints do not support empty or optional
+ // elemets
+ if (this.hasConstraints()) {
+ if (DEBUG) {
+ log.trace("Sequence has constraints, "
+ + "that do not allow empty or optional elements");
+ };
+ this.isSolved = true;
+ this.isProblematic = true;
+ return false;
+ };
+
// [problem][anchor]
if (i < (size - 1) && this.segments.get(i + 1).maybeAnchor()) {
if (DEBUG)
@@ -853,6 +883,8 @@
// An error occurred while solving the problem
catch (QueryException e) {
+ this.isSolved = true;
+ this.isProblematic = true;
return false;
};
@@ -880,6 +912,8 @@
true));
}
catch (QueryException e) {
+ this.isSolved = true;
+ this.isProblematic = true;
return false;
};
@@ -916,10 +950,12 @@
return _solveProblematicSequence();
this.isSolved = true;
- return true;
+ this.isProblematic = true;
+ return false; // true;
};
this.isSolved = true;
+ this.isProblematic = false;
return false;
};
diff --git a/src/test/java/de/ids_mannheim/korap/index/TestMatchIdentifier.java b/src/test/java/de/ids_mannheim/korap/index/TestMatchIdentifier.java
index 8a0ac45..072a633 100644
--- a/src/test/java/de/ids_mannheim/korap/index/TestMatchIdentifier.java
+++ b/src/test/java/de/ids_mannheim/korap/index/TestMatchIdentifier.java
@@ -277,10 +277,10 @@
/*
km = ki.getMatchInfo(
- "match-GOE!GOE_AGX.00002-p10-20",
- "tokens", true, (String) null, (String) null, true, true, false);
+ "match-GOE!GOE_AGX.00002-p10-20",
+ "tokens", true, (String) null, (String) null, true, true, false);
assertEquals("", km.toJsonString());
- */
+ */
};
diff --git a/src/test/java/de/ids_mannheim/korap/index/TestRepetitionIndex.java b/src/test/java/de/ids_mannheim/korap/index/TestRepetitionIndex.java
index cedb868..131ae70 100644
--- a/src/test/java/de/ids_mannheim/korap/index/TestRepetitionIndex.java
+++ b/src/test/java/de/ids_mannheim/korap/index/TestRepetitionIndex.java
@@ -204,6 +204,7 @@
// }
}
+
@Test
public void testCase5 () throws IOException {
ki = new KrillIndex();
diff --git a/src/test/java/de/ids_mannheim/korap/query/TestKrillQueryJSON.java b/src/test/java/de/ids_mannheim/korap/query/TestKrillQueryJSON.java
index 31a3612..f11a5da 100644
--- a/src/test/java/de/ids_mannheim/korap/query/TestKrillQueryJSON.java
+++ b/src/test/java/de/ids_mannheim/korap/query/TestKrillQueryJSON.java
@@ -571,15 +571,17 @@
};
};
- @Test
+
+ @Test
public void queryJSONdistancesWithRegexes () throws QueryException {
- // "der" []{2,3} [opennlp/p="NN"]
+ // "der" []{2,3} [opennlp/p="NN"]
try {
String json = getString(getClass().getResource(
"/queries/bugs/distances_with_regex_bug.jsonld").getFile());
KrillQuery kq = new KrillQuery("tokens");
- assertEquals(kq.fromKoral(json).toQuery().toString(),
+ assertEquals(
+ kq.fromKoral(json).toQuery().toString(),
"spanDistance(SpanMultiTermQueryWrapper(tokens:/s:der/), SpanMultiTermQueryWrapper(tokens:/opennlp/p:NN/), [(w[3:4], ordered, notExcluded)])");
}
catch (QueryException e) {
@@ -587,6 +589,7 @@
};
};
+
public static String getString (String path) {
StringBuilder contentBuilder = new StringBuilder();
try {
diff --git a/src/test/java/de/ids_mannheim/korap/query/TestSpanSequenceQueryJSON.java b/src/test/java/de/ids_mannheim/korap/query/TestSpanSequenceQueryJSON.java
index e5030f8..97a9eb2 100644
--- a/src/test/java/de/ids_mannheim/korap/query/TestSpanSequenceQueryJSON.java
+++ b/src/test/java/de/ids_mannheim/korap/query/TestSpanSequenceQueryJSON.java
@@ -283,7 +283,7 @@
}
catch (QueryException qe) {
assertEquals(
- "Distance constraints not supported with empty or negative operands",
+ "Distance constraints not supported with empty, optional or negative operands",
qe.getMessage());
};
};
@@ -351,27 +351,34 @@
sqwi.toQuery().toString());
};
+
@Test
- public void queryJSONkoralOptionalityInDistanceBug () throws QueryException {
- // Sonne [] Mond?
- SpanQueryWrapper sqwi = jsonQueryFile("distance-with-optionality.jsonld");
- assertEquals(
- "focus(254: spanContain(<tokens:base/s:t />, {254: spanOr([spanExpansion(tokens:s:Sonne, []{1, 1}, right), spanNext(spanExpansion(tokens:s:Sonne, []{1, 1}, right), tokens:s:Mond)])}))",
- sqwi.toQuery().toString());
- // Could also be a distance at the end ... that's a query planner thing.
+ public void queryJSONkoralOptionalityInDistanceBug () {
+ try {
+ // Sonne [] Mond?
+ SpanQueryWrapper sqwi = jsonQueryFile("distance-with-optionality.jsonld");
+ sqwi.toQuery().toString();
+ }
+ catch (QueryException qe) {
+ assertEquals(
+ "Distance constraints not supported with empty, optional or negative operands",
+ qe.getMessage());
+ }
+ // Could also be a distance at the end ... that's a query planner thing.
};
- @Test
+
+ @Test
public void queryJSONkoralOptionalityAfterEmptyBug () throws QueryException {
- // Sonne [] Mond?
+ // Sonne [] Mond?
SpanQueryWrapper sqwi = jsonQueryFile("empty-followed-by-optionality.jsonld");
assertEquals(
- "focus(254: spanContain(<tokens:base/s:t />, {254: spanOr([spanExpansion(tokens:s:Sonne, []{1, 1}, right), spanNext(spanExpansion(tokens:s:Sonne, []{1, 1}, right), tokens:s:Mond)])}))",
- sqwi.toQuery().toString());
- // Could also be a distance at the end ... that's a query planner thing.
+ "focus(254: spanContain(<tokens:base/s:t />, {254: spanOr([spanExpansion(tokens:s:Sonne, []{1, 1}, right), spanNext(spanExpansion(tokens:s:Sonne, []{1, 1}, right), tokens:s:Mond)])}))",
+ sqwi.toQuery().toString());
+ // Could also be a distance at the end ... that's a query planner thing.
};
-
+
// get query wrapper based on json file
public SpanQueryWrapper jsonQueryFile (String filename) {
diff --git a/src/test/java/de/ids_mannheim/korap/search/TestKrill.java b/src/test/java/de/ids_mannheim/korap/search/TestKrill.java
index 1fb1f2b..7ecf1c2 100644
--- a/src/test/java/de/ids_mannheim/korap/search/TestKrill.java
+++ b/src/test/java/de/ids_mannheim/korap/search/TestKrill.java
@@ -1019,28 +1019,29 @@
"Operation needs operand list");
};
-
- @Test
+
+ @Test
public void searchJSONdistanceWithRegexesBug () throws IOException {
// Construct index
KrillIndex ki = new KrillIndex();
// Indexing test files
for (String i : new String[] { "00001" }) {
- // , "00002", "00003", "00004", "00005", "00006", "02439"
+ // , "00002", "00003", "00004", "00005", "00006", "02439"
ki.addDoc(
getClass().getResourceAsStream("/wiki/" + i + ".json.gz"),
true);
};
ki.commit();
- // "der" []{2,3} [opennlp/p="NN"]
- String json = getString(getClass().getResource(
+ // "der" []{2,3} [opennlp/p="NN"]
+ String json = getString(getClass().getResource(
"/queries/bugs/distances_with_regex_bug.jsonld").getFile());
Result kr = new Krill(json).apply(ki);
- assertEquals(kr.getMatch(0).getSnippetBrackets(),
- "Mit Ausnahme von Fremdwörtern und Namen ist das A der einzige Buchstabe im Deutschen, [[der zweifach am Anfang]] eines Wortes stehen darf, etwa im Wort Aal.");
+ assertEquals(
+ kr.getMatch(0).getSnippetBrackets(),
+ "Mit Ausnahme von Fremdwörtern und Namen ist das A der einzige Buchstabe im Deutschen, [[der zweifach am Anfang]] eines Wortes stehen darf, etwa im Wort Aal.");
};
@@ -1128,22 +1129,24 @@
assertEquals(kr.getTotalResults(), 1);
};
-
- @Test
+
+ @Test
public void queryJSONzeroRepetitionBug () throws IOException {
- // der{0}
- KrillIndex ki = new KrillIndex();
- ki.addDoc(getClass().getResourceAsStream("/wiki/00001.json.gz"), true);
- ki.commit();
-
- String json = getString(getClass().getResource(
- "/queries/bugs/zero_repetition_bug.jsonld").getFile());
+ // der{0}
+ KrillIndex ki = new KrillIndex();
+ ki.addDoc(getClass().getResourceAsStream("/wiki/00001.json.gz"), true);
+ ki.commit();
- Result kr = new Krill(json).apply(ki);
+ String json = getString(getClass().getResource(
+ "/queries/bugs/zero_repetition_bug.jsonld").getFile());
- assertEquals(783, kr.getError(0).getCode());
- assertEquals("This query can't match anywhere", kr.getError(0).getMessage());
- };
+ Result kr = new Krill(json).apply(ki);
+
+ assertEquals(783, kr.getError(0).getCode());
+ assertEquals("This query can't match anywhere", kr.getError(0)
+ .getMessage());
+ };
+
/**
* This is a Schreibgebrauch ressource that didn't work for