*/
private Relation processSubqueryInCondition(Relation formula, Proposition p, ColumnIndexes interprets)
throws TranslationException
{
List<Proposition> subqueryFreeLiterals = new ArrayList<>();
Relation newFormula = formula;
for (Proposition literal : p.literals())
{
if (checkContainsSubquery(literal)) {
boolean positive = true;
if (literal instanceof DnfExcludable) {
literal = ((DnfExcludable)literal).delegate();
}
if (literal instanceof PropositionalLogic.Not) {
positive = false;
literal = ((PropositionalLogic.Not)literal).operand();
}
checkState(literal instanceof ExistsLiteral);
Relation nextTablesFormula = newFormula;
if (!positive) {
/* {@code !positive} means it's a WHERE NOT EXISTS condition. We will emit
* diffSet(<current value of {@code newFormula}>, subquery) thus
* subquery should not use {@code newFormula}'s value as tablesFormula,
* but its alias instead*/
Term[] ref = new Term[1];
nextTablesFormula = newFormula.makeRef(ref);
}
/* translate the subquery */
ExistsLiteral existsLiteral = (ExistsLiteral) literal;
TableSubqueryContext ctx = existsLiteral.ctx();
QueryExpressionContext queryExpressionContext = ctx.subquery().queryExpression();
TranslationVisitor subqueryTranslator = subqueryTranslationVisitor.apply(nextTablesFormula);
Relation subqueryFormula = subqueryTranslator.visitQueryExpression(queryExpressionContext);
Relation prevNewFormula = newFormula;
newFormula = subqueryFormula;
/* project the results on the outer query, ie. drop the subquery's attributes */
ColumnIndexesImpl ec = new ColumnIndexesImpl();
for (int i = 0; i < state.rela.expandedColumns().size(); ++i) {
ec.add(newFormula.expandedColumns().get(i));
}
newFormula = newFormula.select(tablesRelation.value.columns(), false);
newFormula = newFormula.withExpandedColumns(ec);
if (!positive) {
newFormula = prevNewFormula.except(newFormula, false); // TODO removeDuplicates?
}
} else {
subqueryFreeLiterals.add(literal);
}
}