use of annis.sqlgen.extensions.AnnotateQueryData in project ANNIS by korpling.
the class AnnisRunner method analyzeQuery.
/**
* Does the setup for the QueryData object.
*
* If the query function is "subgraph" or "sql_subgraph" the annisQuery string
* should contain space separated salt ids. In this case the annisQuery is not
* parsed and the {@link QueryData#getAlternatives()} method should return a
* List with dummy QueryNode entries. Instead of parsing the annisQuery it
* extracts the salt ids and put it into the extension's of {@link QueryData}.
*
* @param annisQuery should include a valid annis query
* @param queryFunction should include a method name of {@link AnnisRunner}
* which starts with do.
* @return {@link QueryData} object, which contains a parsed annis query, the
* default context {@link AnnisRunner#left} and {@link AnnisRunner#left}
* values and the default {@link AnnisRunner#limit} and
* {@link AnnisRunner#offset} values
*/
private QueryData analyzeQuery(String annisQuery, String queryFunction) {
QueryData queryData;
log.debug("analyze query for " + queryFunction + " function");
if (queryFunction != null && !queryFunction.matches("(sql_)?subgraph")) {
queryData = queryDao.parseAQL(annisQuery, corpusList);
} else {
queryData = GraphHelper.createQueryData(MatchGroup.parseString(annisQuery), queryDao);
}
queryData.setCorpusConfiguration(queryDao.getCorpusConfiguration());
// filter by meta data
queryData.setDocuments(metaDataFilter.getDocumentsForMetadata(queryData));
if (queryFunction != null && queryFunction.matches("(sql_)?(annotate|find)")) {
queryData.addExtension(new AnnotateQueryData(left, right, segmentationLayer, filter));
queryData.addExtension(new LimitOffsetQueryData(offset, limit, order));
} else if (queryFunction != null && queryFunction.matches("(sql_)?subgraph")) {
queryData.addExtension(new AnnotateQueryData(left, right, segmentationLayer, filter));
} else if (queryFunction != null && queryFunction.matches("(sql_)?frequency")) {
if (frequencyDef == null) {
out.println("You have to set the 'freq-def' property first");
} else {
queryData.addExtension(frequencyDef);
}
}
if (annisQuery != null) {
if (benchmarkName == null) {
benchmarkName = "auto_" + benchmarks.size();
}
Benchmark b = new AnnisRunner.Benchmark(queryFunction + " " + annisQuery, queryData);
b.name = benchmarkName;
benchmarks.add(b);
benchmarkName = null;
}
return queryData;
}
use of annis.sqlgen.extensions.AnnotateQueryData in project ANNIS by korpling.
the class AnnotateSqlGenerator method whereConditions.
@Override
public Set<String> whereConditions(QueryData queryData, List<QueryNode> alternative, String indent) {
HashSet<String> result = new HashSet<>();
TableAccessStrategy tables = tables(null);
List<AnnotateQueryData> annoExtList = queryData.getExtensions(AnnotateQueryData.class);
if (!annoExtList.isEmpty()) {
AnnotateQueryData annoExt = annoExtList.get(0);
if (annoExt.getFilter() == SubgraphFilter.token) {
result.add(tables.aliasedColumn(NODE_TABLE, "is_token") + " IS TRUE");
}
}
StringBuilder sb = new StringBuilder();
// restrict node table to corpus list
List<Long> corpusList = queryData.getCorpusList();
if (corpusList != null && !corpusList.isEmpty()) {
sb.append(indent);
sb.append(tables.aliasedColumn(NODE_TABLE, "toplevel_corpus"));
sb.append(" IN (");
sb.append(StringUtils.join(corpusList, ", "));
sb.append(") AND\n");
if (!tables.isMaterialized(RANK_TABLE, NODE_TABLE)) {
sb.append(indent);
sb.append(tables.aliasedColumn(RANK_TABLE, "toplevel_corpus"));
sb.append(" IN (");
sb.append(StringUtils.join(corpusList, ", "));
sb.append(") AND\n");
}
}
String overlap = CommonAnnotateWithClauseGenerator.overlapForOneRange(indent + TABSTOP, "solutions.\"min\"", "solutions.\"max\"", "solutions.text", "solutions.corpus", tables);
sb.append(overlap);
sb.append("\n");
// corpus constriction
sb.append(" AND\n");
sb.append(indent).append(TABSTOP);
sb.append(tables.aliasedColumn(CORPUS_TABLE, "id"));
sb.append(" = ");
sb.append(tables.aliasedColumn(NODE_TABLE, "corpus_ref"));
result.add(sb.toString());
return result;
}
use of annis.sqlgen.extensions.AnnotateQueryData in project ANNIS by korpling.
the class TestAnnotateInnerQuerySqlGenerator method shouldGenerateSelectClause.
/**
* The SELECT clause consists of the column text_ref, left, right and the
* key columns for each node in the query alternative. Left and right are
* modified by the requested annotation context.
*/
@Test
public void shouldGenerateSelectClause() {
// given
alternative = Collections.nCopies(2, new QueryNode());
int left = uniqueInt(10);
int right = uniqueInt(20);
List<AnnotateQueryData> extensions = new ArrayList<>();
extensions.add(annotateQueryData);
given(annotateQueryData.getLeft()).willReturn(left);
given(annotateQueryData.getRight()).willReturn(right);
given(queryData.getExtensions(AnnotateQueryData.class)).willReturn(extensions);
given(queryData.getMaxWidth()).willReturn(alternative.size());
String key1Column1 = uniqueAlphaString();
String key1Column2 = uniqueAlphaString();
String key2Column1 = uniqueAlphaString();
String key2Column2 = uniqueAlphaString();
given(key.generateInnerQueryColumns(tableAccessStrategy, 1)).willReturn(asList(key1Column1, key1Column2));
given(key.generateInnerQueryColumns(tableAccessStrategy, 2)).willReturn(asList(key2Column1, key2Column2));
String textRefAlias1 = uniqueAlphaString();
String leftTokenAlias1 = uniqueAlphaString();
String rightTokenAlias1 = uniqueAlphaString();
String textRefAlias2 = uniqueAlphaString();
String leftTokenAlias2 = uniqueAlphaString();
String rightTokenAlias2 = uniqueAlphaString();
String corpusRefAlias1 = uniqueAlphaString();
String corpusRefAlias2 = uniqueAlphaString();
String nodeNameAlias1 = uniqueAlphaString();
String nodeNameAlias2 = uniqueAlphaString();
given(tableAccessStrategy.aliasedColumn(NODE_TABLE, "text_ref")).willReturn(textRefAlias1, textRefAlias2);
given(tableAccessStrategy.aliasedColumn(NODE_TABLE, "left_token")).willReturn(leftTokenAlias1, leftTokenAlias2);
given(tableAccessStrategy.aliasedColumn(NODE_TABLE, "right_token")).willReturn(rightTokenAlias1, rightTokenAlias2);
given(tableAccessStrategy.aliasedColumn(NODE_TABLE, "corpus_ref")).willReturn(corpusRefAlias1, corpusRefAlias2);
given(tableAccessStrategy.aliasedColumn(NODE_TABLE, "name")).willReturn(nodeNameAlias1, nodeNameAlias2);
// when
String actual = generator.selectClause(queryData, alternative, INDENT);
// then
String expected = "DISTINCT" + "\n" + INDENT + TABSTOP + key1Column1 + ", " + key1Column2 + ", " + textRefAlias1 + " AS " + "text" + 1 + ", " + leftTokenAlias1 + " - " + left + " AS " + "min" + 1 + ", " + rightTokenAlias1 + " + " + right + " AS " + "max" + 1 + ", " + corpusRefAlias1 + " AS corpus1, " + nodeNameAlias1 + " AS name1, " + "\n" + INDENT + TABSTOP + key2Column1 + ", " + key2Column2 + ", " + textRefAlias2 + " AS " + "text" + 2 + ", " + leftTokenAlias2 + " - " + left + " AS " + "min" + 2 + ", " + rightTokenAlias2 + " + " + right + " AS " + "max" + 2 + ", " + corpusRefAlias2 + " AS corpus2, " + nodeNameAlias2 + " AS name2";
assertThat(actual, is(expected));
}
use of annis.sqlgen.extensions.AnnotateQueryData in project ANNIS by korpling.
the class QueryServiceImpl method basicSubgraph.
protected SaltProject basicSubgraph(MatchGroup matches, @QueryParam("segmentation") String segmentation, @DefaultValue("0") @QueryParam("left") String leftRaw, @DefaultValue("0") @QueryParam("right") String rightRaw, @DefaultValue("all") @QueryParam("filter") String filterRaw) {
Subject user = SecurityUtils.getSubject();
int left = Integer.parseInt(leftRaw);
int right = Integer.parseInt(rightRaw);
SubgraphFilter filter = SubgraphFilter.valueOf(filterRaw);
QueryData data = GraphHelper.createQueryData(matches, queryDao);
data.addExtension(new AnnotateQueryData(left, right, segmentation, filter));
Set<String> corpusNames = new TreeSet<>();
for (Match singleMatch : matches.getMatches()) {
// collect list of used corpora
for (java.net.URI u : singleMatch.getSaltIDs()) {
corpusNames.add(CommonHelper.getCorpusPath(u).get(0));
}
}
for (String c : corpusNames) {
user.checkPermission("query:subgraph:" + c);
}
List<String> corpusNamesList = new LinkedList<>(corpusNames);
if (data.getCorpusList() == null || data.getCorpusList().isEmpty()) {
throw new WebApplicationException(Response.Status.BAD_REQUEST.getStatusCode());
}
long start = new Date().getTime();
SaltProject p = queryDao.graph(data);
long end = new Date().getTime();
String options = "matches: " + matches.toString() + ", seg: " + segmentation + ", left: " + left + ", right: " + right + ", filter: " + filter;
logQuery("SUBGRAPH", "", corpusNamesList, end - start, options);
return p;
}
use of annis.sqlgen.extensions.AnnotateQueryData in project ANNIS by korpling.
the class AnnotateInnerQuerySqlGenerator method selectClause.
@Override
public String selectClause(QueryData queryData, List<QueryNode> alternative, String indent) {
int maxWidth = queryData.getMaxWidth();
Validate.isTrue(alternative.size() <= maxWidth, "BUG: nodes.size() > maxWidth");
List<AnnotateQueryData> extensions = queryData.getExtensions(AnnotateQueryData.class);
AnnotateQueryData annotateQueryData = null;
if (extensions.isEmpty()) {
annotateQueryData = new AnnotateQueryData(5, 5);
} else {
annotateQueryData = extensions.get(0);
}
List<String> selectClauseForNode = new ArrayList<>();
int i = 0;
for (QueryNode node : alternative) {
i++;
TableAccessStrategy tables = tables(node);
List<String> fields = new ArrayList<>();
fields.addAll(solutionKey.generateInnerQueryColumns(tables, i));
fields.add(tables.aliasedColumn(NODE_TABLE, "text_ref") + " AS text" + i);
// token but not any of the other segmentation layers
if (annotateQueryData.getSegmentationLayer() == null) {
fields.add(tables.aliasedColumn(NODE_TABLE, "left_token") + " - " + annotateQueryData.getLeft() + " AS min" + i);
fields.add(tables.aliasedColumn(NODE_TABLE, "right_token") + " + " + annotateQueryData.getRight() + " AS max" + i);
} else {
fields.add(tables.aliasedColumn(NODE_TABLE, "left_token") + " AS min" + i);
fields.add(tables.aliasedColumn(NODE_TABLE, "right_token") + " AS max" + i);
}
fields.add(tables.aliasedColumn(NODE_TABLE, "corpus_ref") + " AS corpus" + i);
fields.add(tables.aliasedColumn(NODE_TABLE, "name") + " AS name" + i);
selectClauseForNode.add("\n" + indent + TABSTOP + StringUtils.join(fields, ", "));
}
for (i = alternative.size() + 1; i <= maxWidth; ++i) {
selectClauseForNode.add("NULL::bigint AS id" + i);
selectClauseForNode.add("NULL::bigint AS text" + i);
selectClauseForNode.add("NULL::int AS min" + i);
selectClauseForNode.add("NULL::int AS max" + i);
selectClauseForNode.add("NULL::bigint AS corpus" + i);
selectClauseForNode.add("NULL::varchar AS name" + i);
}
return "DISTINCT" + StringUtils.join(selectClauseForNode, ", ");
}
Aggregations