use of annis.model.QueryNode in project ANNIS by korpling.
the class TestDefaultWhereClauseGenerator method checkWhereConditions.
private void checkWhereConditions(QueryNode node, String... expected) {
List<QueryNode> alternative = new ArrayList<>();
alternative.add(node);
Set<String> actual = generator.whereConditions(queryData, alternative, "");
for (String item : expected) {
assertThat(actual, hasItem(item));
}
assertThat(actual, is(size(expected.length)));
}
use of annis.model.QueryNode in project ANNIS by korpling.
the class SolutionSqlGenerator 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<String> cols = new ArrayList<>();
int i = 0;
boolean needsDistinct = isDistinctNeeded(alternative);
for (QueryNode node : alternative) {
++i;
TableAccessStrategy tblAccessStr = tables(node);
cols.add(tblAccessStr.aliasedColumn(NODE_TABLE, "id") + " AS id" + i);
if (annoCondition != null) {
if (node.getNodeAnnotations().isEmpty()) {
// If a query node is not using annotations, fallback to NULL as the value.
// This is important for the DISTINCT clause, since we don't want to match
// the annotation itself but the node.
cols.add("NULL::int AS cat" + i);
} else {
cols.add(tblAccessStr.aliasedColumn("node_annotation", "category") + " AS cat" + i);
}
}
if (outputNodeName) {
if (needsDistinct) {
cols.add("min(" + tblAccessStr.aliasedColumn(NODE_TABLE, "salt_id") + ") AS salt_id" + i);
} else {
cols.add(tblAccessStr.aliasedColumn(NODE_TABLE, "salt_id") + " AS salt_id" + i);
}
}
}
// add additional empty columns in or clauses with different node sizes
for (i = alternative.size() + 1; i <= maxWidth; ++i) {
cols.add("NULL::bigint AS id" + i);
cols.add("NULL::integer AS cat" + i);
if (outputNodeName) {
cols.add("NULL::varchar AS salt_id" + i);
}
}
if (!alternative.isEmpty() && outputNodeName) {
TableAccessStrategy tblAccessStr = tables(alternative.get(0));
String corpusRefAlias = tblAccessStr.aliasedColumn(NODE_TABLE, "corpus_ref");
if (needsDistinct) {
cols.add("(SELECT c.path_name FROM corpus AS c WHERE c.id = min(" + corpusRefAlias + ") LIMIT 1) AS path_name");
} else {
cols.add("(SELECT c.path_name FROM corpus AS c WHERE c.id = " + corpusRefAlias + " LIMIT 1) AS path_name");
}
}
if (outputToplevelCorpus) {
if (needsDistinct) {
cols.add("min(" + tables(alternative.get(0)).aliasedColumn(NODE_TABLE, "toplevel_corpus") + ") AS toplevel_corpus");
} else {
cols.add(tables(alternative.get(0)).aliasedColumn(NODE_TABLE, "toplevel_corpus") + " AS toplevel_corpus");
}
}
if (needsDistinct) {
cols.add("min(" + tables(alternative.get(0)).aliasedColumn(NODE_TABLE, "corpus_ref") + ") AS corpus_ref");
} else {
cols.add(tables(alternative.get(0)).aliasedColumn(NODE_TABLE, "corpus_ref") + " AS corpus_ref");
}
if (queryData.getCorpusList().size() > 1) {
if (needsDistinct) {
cols.add("min(" + tables(alternative.get(0)).aliasedColumn(TableAccessStrategy.FACTS_TABLE, "sourceIdx") + ") AS sourceIdx");
} else {
cols.add(tables(alternative.get(0)).aliasedColumn(TableAccessStrategy.FACTS_TABLE, "sourceIdx") + " AS sourceIdx");
}
}
String colIndent = indent + TABSTOP + TABSTOP;
return "\n" + colIndent + StringUtils.join(cols, ",\n" + colIndent);
}
use of annis.model.QueryNode in project ANNIS by korpling.
the class QueryServiceImpl method parseNodes.
/**
* Return the list of the query nodes if this is a valid query
* or throw exception when invalid
*
* @param query Query to get the query nodes for
* @param rawCorpusNames
* @return
*/
@GET
@Path("parse/nodes")
@Produces("application/xml")
public Response parseNodes(@QueryParam("q") String query, @DefaultValue("") @QueryParam("corpora") String rawCorpusNames) {
Subject user = SecurityUtils.getSubject();
List<String> corpusNames = splitCorpusNamesFromRaw(rawCorpusNames);
for (String c : corpusNames) {
user.checkPermission("query:parse:" + c);
}
Collections.sort(corpusNames);
List<Long> corpusIDs = queryDao.mapCorpusNamesToIds(corpusNames);
QueryData data = queryDao.parseAQL(query, corpusIDs);
List<QueryNode> nodes = new LinkedList<>();
int i = 0;
for (List<QueryNode> alternative : data.getAlternatives()) {
for (QueryNode n : alternative) {
n.setAlternativeNumber(i);
nodes.add(n);
}
i++;
}
return Response.ok(new GenericEntity<List<QueryNode>>(nodes) {
}).build();
}
use of annis.model.QueryNode in project ANNIS by korpling.
the class AbstractWhereClauseGenerator method whereConditions.
@Override
public Set<String> whereConditions(QueryData queryData, List<QueryNode> alternative, String indent) {
List<String> conditions = new ArrayList<>();
for (QueryNode node : alternative) {
// node constraints
if (node.getSpannedText() != null) {
addSpanConditions(conditions, queryData, node);
}
if (node.isToken()) {
addIsTokenConditions(conditions, queryData, node);
}
if (node.isRoot()) {
addIsRootConditions(conditions, queryData, node);
}
if (node.getArity() != null) {
addNodeArityConditions(conditions, queryData, node);
}
if (node.getTokenArity() != null) {
addTokenArityConditions(conditions, queryData, node);
}
// node joins
for (Join join : node.getOutgoingJoins()) {
QueryNode target = join.getTarget();
if (join instanceof SameSpan) {
addSameSpanConditions(conditions, node, target, (SameSpan) join, queryData);
} else if (join instanceof Identical) {
addIdenticalConditions(conditions, node, target, (Identical) join, queryData);
} else if (join instanceof LeftAlignment) {
addLeftAlignmentConditions(conditions, node, target, (LeftAlignment) join, queryData);
} else if (join instanceof RightAlignment) {
addRightAlignmentConditions(conditions, node, target, (RightAlignment) join, queryData);
} else if (join instanceof Inclusion) {
addInclusionConditions(conditions, node, target, (Inclusion) join, queryData);
} else if (join instanceof Overlap) {
addOverlapConditions(conditions, node, target, (Overlap) join, queryData);
} else if (join instanceof LeftOverlap) {
addLeftOverlapConditions(conditions, target, node, (LeftOverlap) join, queryData);
} else if (join instanceof RightOverlap) {
addRightOverlapConditions(conditions, target, node, (RightOverlap) join, queryData);
} else if (join instanceof Precedence) {
addPrecedenceConditions(conditions, node, target, (Precedence) join, queryData);
} else if (join instanceof Near) {
addNearConditions(conditions, node, target, (Near) join, queryData);
} else if (join instanceof Sibling) {
addSiblingConditions(conditions, node, target, (Sibling) join, queryData);
} else if (join instanceof CommonAncestor) {
addCommonAncestorConditions(conditions, node, target, (CommonAncestor) join, queryData);
} else if (join instanceof LeftDominance) {
addLeftDominanceConditions(conditions, node, target, (LeftDominance) join, queryData);
} else if (join instanceof RightDominance) {
addRightDominanceConditions(conditions, node, target, (RightDominance) join, queryData);
} else if (join instanceof Dominance) {
addDominanceConditions(conditions, node, target, (Dominance) join, queryData);
} else if (join instanceof PointingRelation) {
addPointingRelationConditions(conditions, node, target, (PointingRelation) join, queryData);
} else if (join instanceof EqualValue) {
addEqualValueConditions(conditions, node, target, (EqualValue) join, queryData);
} else if (join instanceof NotEqualValue) {
addNotEqualValueConditions(conditions, node, target, (NotEqualValue) join, queryData);
}
}
// node annotations
int i = 0;
for (QueryAnnotation annotation : node.getNodeAnnotations()) {
++i;
addAnnotationConditions(conditions, node, i, annotation, NODE_ANNOTATION_TABLE, queryData);
}
// relation annotations
int j = 0;
for (QueryAnnotation annotation : node.getEdgeAnnotations()) {
++j;
addAnnotationConditions(conditions, node, j, annotation, EDGE_ANNOTATION_TABLE, queryData);
}
}
return new HashSet<>(conditions);
}
use of annis.model.QueryNode 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