package annis.sqlgen;
import annis.model.QueryNode;
import annis.ql.parser.QueryData;
import static annis.sqlgen.TableAccessStrategy.NODE_TABLE;
import annis.sqlgen.extensions.AnnotateQueryData;
import java.util.ArrayList;
import java.util.List;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.Validate;
public class AnnotateInnerQuerySqlGenerator extends AbstractUnionSqlGenerator
implements SelectClauseSqlGenerator<QueryData>,
OrderByClauseSqlGenerator<QueryData>
{
// sort solutions
private boolean sortSolutions;
// annotation graph key generation
private SolutionKey<?> solutionKey;
@Override
public String toSql(QueryData queryData, String indent)
{
StringBuilder sb = new StringBuilder();
sb.append(indent).append("SELECT row_number() OVER () as n, inn.*\n");
sb.append(indent).append("FROM (\n");
sb.append(super.toSql(queryData, indent + TABSTOP)).append("\n");
sb.append(indent).append(") AS inn\n");
return sb.toString();
}
@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);
// only set the context directly if we are doing a context search on the
// 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, ", ");
}
@Override
protected void appendOrderByClause(StringBuffer sb, QueryData queryData,
List<QueryNode> alternative, String indent)
{
// only use ORDER BY clause if result has to be sorted
if (!sortSolutions)
{
return;
}
super.appendOrderByClause(sb, queryData, alternative, indent);
}
@Override
public String orderByClause(QueryData queryData, List<QueryNode> alternative,
String indent)
{
List<String> ids = new ArrayList<>();
for (int i = 1; i <= queryData.getMaxWidth(); ++i)
{
ids.add("id" + i);
}
return StringUtils.join(ids, ", ");
}
public boolean isSortSolutions()
{
return sortSolutions;
}
public void setSortSolutions(boolean sortSolutions)
{
this.sortSolutions = sortSolutions;
}
public SolutionKey<?> getSolutionKey()
{
return solutionKey;
}
public void setSolutionKey(SolutionKey<?> solutionKey)
{
this.solutionKey = solutionKey;
}
}