Search in sources :

Example 61 with QueryNode

use of annis.model.QueryNode in project ANNIS by korpling.

the class SemanticValidator method checkAlternative.

public void checkAlternative(QueryData data, List<QueryNode> alternative, int alternativeIndex, boolean queryWasNormalized) {
    // check if there is at least one search expression
    if (alternative.isEmpty()) {
        throw new AnnisQLSemanticsException("Missing search expression.");
    }
    // there are not linguistic binary relations allowed if there is only one node
    if (alternative.size() == 1) {
        QueryNode n = alternative.get(0);
        for (Join j : n.getOutgoingJoins()) {
            if (j.getTarget() != null) {
                throw new AnnisQLSemanticsException(j.getParseLocation(), "No binary linguistic relations allowed if there is only one node in query.");
            }
        }
    }
    // get all nodes connected to the first one
    Multimap<Long, QueryNode> connected = calculateConnected(alternative);
    Set<Long> transitiveHull = new HashSet<>();
    transitiveHull.add(alternative.get(0).getId());
    createTransitiveHull(alternative.get(0), connected, transitiveHull);
    Multiset<String> variableNames = TreeMultiset.create();
    Set<Long> unconnectedNodes = new HashSet<>();
    for (QueryNode n : alternative) {
        unconnectedNodes.add(n.getId());
        variableNames.add(n.getVariable());
    }
    unconnectedNodes.removeAll(transitiveHull);
    // check if each node is contained in the connected nodes
    if (!unconnectedNodes.isEmpty()) {
        List<AqlParseError> errors = new LinkedList<>();
        for (QueryNode n : alternative) {
            if (unconnectedNodes.contains(n.getId())) {
                errors.add(new AqlParseError(n, "variable \"" + n.getVariable() + "\" not bound (use linguistic operators)"));
            }
        }
        if (!errors.isEmpty()) {
            if (queryWasNormalized) {
                // add the normalized query as "error" so the user is able to see it
                errors.add(new AqlParseError("Normalized query is: \n" + data.toAQL()));
            }
            throw new AnnisQLSemanticsException("Not all variables bound", errors);
        }
    }
    // check if any variable name was given more than once
    List<String> invalidNames = new LinkedList<>();
    for (Multiset.Entry<String> e : variableNames.entrySet()) {
        if (e.getCount() > 1) {
            invalidNames.add(e.getElement());
        }
    }
    if (!invalidNames.isEmpty()) {
        throw new AnnisQLSemanticsException("The following variable names are " + "used for more than one node: " + Joiner.on(", ").join(invalidNames) + "\nNormalized Query is: \n" + data.toAQL());
    }
    // check no non-reflexive operator is used with the same operands
    for (QueryNode source : alternative) {
        for (Join join : source.getOutgoingJoins()) {
            if (join instanceof Inclusion || join instanceof SameSpan || join instanceof Overlap || join instanceof RightOverlap || join instanceof LeftOverlap || join instanceof RightAlignment || join instanceof LeftAlignment) {
                if (source.equals(join.getTarget())) {
                    throw new AnnisQLSemanticsException(join, "Not-reflexive operator used with the same node as argument.");
                }
            }
        }
    }
}
Also used : Inclusion(annis.sqlgen.model.Inclusion) SameSpan(annis.sqlgen.model.SameSpan) RightAlignment(annis.sqlgen.model.RightAlignment) AqlParseError(annis.model.AqlParseError) RightOverlap(annis.sqlgen.model.RightOverlap) LeftAlignment(annis.sqlgen.model.LeftAlignment) AnnisQLSemanticsException(annis.exceptions.AnnisQLSemanticsException) NonBindingJoin(annis.sqlgen.model.NonBindingJoin) Join(annis.model.Join) RightOverlap(annis.sqlgen.model.RightOverlap) Overlap(annis.sqlgen.model.Overlap) LeftOverlap(annis.sqlgen.model.LeftOverlap) LinkedList(java.util.LinkedList) QueryNode(annis.model.QueryNode) LeftOverlap(annis.sqlgen.model.LeftOverlap) Multiset(com.google.common.collect.Multiset) TreeMultiset(com.google.common.collect.TreeMultiset) HashSet(java.util.HashSet)

Example 62 with QueryNode

use of annis.model.QueryNode in project ANNIS by korpling.

the class SemanticValidator method calculateConnected.

private Multimap<Long, QueryNode> calculateConnected(List<QueryNode> nodes) {
    Multimap<Long, QueryNode> result = HashMultimap.create();
    for (QueryNode n : nodes) {
        for (Join j : n.getOutgoingJoins()) {
            if (j.getTarget() != null && !(j instanceof NonBindingJoin)) {
                long left = n.getId();
                long right = j.getTarget().getId();
                result.put(left, j.getTarget());
                result.put(right, n);
            }
        }
    }
    return result;
}
Also used : QueryNode(annis.model.QueryNode) NonBindingJoin(annis.sqlgen.model.NonBindingJoin) Join(annis.model.Join) NonBindingJoin(annis.sqlgen.model.NonBindingJoin)

Example 63 with QueryNode

use of annis.model.QueryNode in project ANNIS by korpling.

the class DefaultWhereClauseGenerator method addNodeArityConditions.

@Override
protected void addNodeArityConditions(List<String> conditions, QueryData queryData, QueryNode node) {
    // fugly
    List<Long> corpusList = queryData.getCorpusList();
    TableAccessStrategy tas = tables(null);
    String id1 = tables(node).aliasedColumn(RANK_TABLE, "id");
    String componentID1 = tables(node).aliasedColumn(COMPONENT_TABLE, "id");
    String corpusRef1 = tables(node).aliasedColumn(NODE_TABLE, "corpus_ref");
    String parent = TableAccessStrategy.column("children", tas.columnName(RANK_TABLE, "parent"));
    String id = TableAccessStrategy.column("children", tas.columnName(RANK_TABLE, "id"));
    String componentID = TableAccessStrategy.column("children", tas.columnName(COMPONENT_TABLE, "id"));
    ;
    String corpusRef = TableAccessStrategy.column("children", tas.columnName(NODE_TABLE, "corpus_ref"));
    ;
    String factsTable = SelectedFactsFromClauseGenerator.inheritedFactTables(corpusList, "");
    StringBuffer sb = new StringBuffer();
    sb.append("(SELECT count(DISTINCT " + id + ")\n");
    sb.append("\tFROM " + factsTable + " AS children\n");
    sb.append("\tWHERE " + parent + " = " + id1 + " AND " + componentID1 + " = " + componentID + " AND " + corpusRef1 + " = " + corpusRef + " AND toplevel_corpus IN(" + (corpusList.isEmpty() ? "NULL" : StringUtils.join(corpusList, ",")) + ")" + ")");
    QueryNode.Range arity = node.getArity();
    if (arity.getMin() == arity.getMax()) {
        conditions.add(join("=", sb.toString(), String.valueOf(arity.getMin())));
    } else {
        conditions.add(between(sb.toString(), arity.getMin(), arity.getMax()));
    }
}
Also used : QueryNode(annis.model.QueryNode) SqlConstraints.sqlString(annis.sqlgen.SqlConstraints.sqlString)

Example 64 with QueryNode

use of annis.model.QueryNode in project ANNIS by korpling.

the class FindSqlGenerator method fromClause.

@Override
public String fromClause(QueryData queryData, List<QueryNode> alternative, String indent) {
    StringBuilder sb = new StringBuilder();
    sb.append(indent).append("(\n");
    sb.append(solutionSqlGenerator.toSql(queryData, indent + TABSTOP));
    sb.append(") AS solution \n");
    Preconditions.checkArgument(!alternative.isEmpty(), "There must be at least one query node in the alternative");
    // add the left joins with the annotation category table
    int i = 0;
    Iterator<QueryNode> itNodes = alternative.iterator();
    while (itNodes.hasNext()) {
        i++;
        QueryNode n = itNodes.next();
        sb.append(indent).append("LEFT JOIN annotation_category AS annotation_category").append(n.getId()).append(" ON (solution.toplevel_corpus = annotation_category").append(n.getId()).append(".toplevel_corpus").append(" AND solution.cat").append(i).append(" = annotation_category").append(n.getId()).append(".id").append(")");
        if (!itNodes.hasNext()) {
            sb.append(",");
        }
        sb.append("\n");
    }
    sb.append(indent).append("corpus AS c");
    return sb.toString();
}
Also used : QueryNode(annis.model.QueryNode)

Example 65 with QueryNode

use of annis.model.QueryNode in project ANNIS by korpling.

the class TransitivePrecedenceOptimizer method createInitialJoinMap.

private Map<Long, Set<Precedence>> createInitialJoinMap(List<QueryNode> alternative) {
    Map<Long, Set<Precedence>> result = new HashMap<>();
    for (QueryNode node : alternative) {
        Set<Precedence> joinList = new HashSet<>();
        for (Join j : node.getOutgoingJoins()) {
            if (j instanceof Precedence) {
                joinList.add((Precedence) j);
            }
        }
        result.put(node.getId(), joinList);
    }
    return result;
}
Also used : HashSet(java.util.HashSet) Set(java.util.Set) TreeSet(java.util.TreeSet) HashMap(java.util.HashMap) QueryNode(annis.model.QueryNode) Join(annis.model.Join) Precedence(annis.sqlgen.model.Precedence) HashSet(java.util.HashSet)

Aggregations

QueryNode (annis.model.QueryNode)67 Join (annis.model.Join)12 LinkedList (java.util.LinkedList)11 AnnisQLSemanticsException (annis.exceptions.AnnisQLSemanticsException)10 ArrayList (java.util.ArrayList)8 QueryAnnotation (annis.model.QueryAnnotation)7 Precedence (annis.sqlgen.model.Precedence)7 HashMap (java.util.HashMap)6 HashSet (java.util.HashSet)6 Dominance (annis.sqlgen.model.Dominance)5 PointingRelation (annis.sqlgen.model.PointingRelation)5 TestUtils.uniqueString (annis.test.TestUtils.uniqueString)5 TreeSet (java.util.TreeSet)5 Test (org.junit.Test)5 Identical (annis.sqlgen.model.Identical)4 LeftDominance (annis.sqlgen.model.LeftDominance)4 Near (annis.sqlgen.model.Near)4 RightDominance (annis.sqlgen.model.RightDominance)4 TestUtils.uniqueLong (annis.test.TestUtils.uniqueLong)4 QueryData (annis.ql.parser.QueryData)3