selectVariables.add(v);
}
if(justifications) {
// project also the ids of triples that have matched; we use it for building justifications
for(Iterator<Pattern> it = patterns.iterator(); it.hasNext(); ) {
Pattern p = it.next();
if(selectClause.length() > 0) {
selectClause.append(", ");
}
selectClause.append(patternNames.get(p));
selectClause.append(".id as ");
selectClause.append(patternNames.get(p));
}
}
// build the from-clause of the query; the from clause is constructed as follows:
// 1. for each pattern P, there will be a "KiWiTriple P" in the from clause
// 2. for each variable V in P occurring in
// - subject, there will be a "inner join P.subject as P_S_V" or "left outer join P.subject as P_S_V",
// depending on whether the "optional" parameter is false or true
// - property, there will be a "inner join P.property as P_P_V" or "left outer join p.property as P_P_V"
// - object, there will be a "inner join P.object as P_O_V" or "left outer join p.object as P_O_V"
// - context, there will be a "inner join P.context as P_C_V" or "left outer join p.context as P_C_V"
StringBuilder fromClause = new StringBuilder();
for(Iterator<Pattern> it = patterns.iterator(); it.hasNext(); ) {
Pattern p = it.next();
String pName = patternNames.get(p);
fromClause.append("triples "+pName);
Field[] fields = new Field[] {
p.getSubject(),
p.getProperty(),
p.getObject(),
p.getContext()
};
for(int i = 0; i<fields.length; i++) {
if(fields[i] != null && fields[i].isVariableField()) {
String vName = variableNames.get(fields[i]);
fromClause.append(" INNER JOIN nodes AS ");
fromClause.append(pName + "_"+positions[i]+"_" + vName);
fromClause.append(" ON " + pName + "." + positions[i] + " = ");
fromClause.append(pName + "_"+positions[i]+"_" + vName + ".id ");
}
}
if(it.hasNext()) {
fromClause.append(",\n ");
}
}
// build the where clause as follows:
// 1. iterate over all patterns and for each resource and literal field in subject,
// property, object, or context, and set a query condition according to the
// nodes given in the pattern
// 2. for each variable that has more than one occurrences, add a join condition
// 3. for each variable in the initialBindings, add a condition to the where clause
// list of where conditions that will later be connected by AND
List<String> whereConditions = new LinkedList<String>();
// 1. iterate over all patterns and for each resource and literal field in subject,
// property, object, or context, and set a query condition according to the
// nodes given in the pattern
for(Pattern p : patterns) {
String pName = patternNames.get(p);
Field[] fields = new Field[] {
p.getSubject(),
p.getProperty(),
p.getObject(),
p.getContext()
};
for(int i = 0; i<fields.length; i++) {
// find node id of the resource or literal field and use it in the where clause
// in this way we can avoid setting too many query parameters
Long nodeId = null;