package org.aksw.sparqlify.core.sql.algebra.transform;
import java.util.ArrayList;
import java.util.List;
import org.aksw.commons.util.reflect.MultiMethod;
import org.aksw.sparqlify.algebra.sql.nodes.SqlOp;
import org.aksw.sparqlify.algebra.sql.nodes.SqlOpDistinct;
import org.aksw.sparqlify.algebra.sql.nodes.SqlOpEmpty;
import org.aksw.sparqlify.algebra.sql.nodes.SqlOpFilter;
import org.aksw.sparqlify.algebra.sql.nodes.SqlOpJoin;
import org.aksw.sparqlify.algebra.sql.nodes.SqlOpProject;
import org.aksw.sparqlify.algebra.sql.nodes.SqlOpQuery;
import org.aksw.sparqlify.algebra.sql.nodes.SqlOpSelectBlock;
import org.aksw.sparqlify.algebra.sql.nodes.SqlOpSlice;
import org.aksw.sparqlify.algebra.sql.nodes.SqlOpTable;
import org.aksw.sparqlify.algebra.sql.nodes.SqlOpUnionN;
/**
* Pitfalls:
* (distinct (project ...)) -> First project then make distinct
* -> Select Distinct [project]
* But
* (project (distinct ...)) -> First make distinct (with potentially some different projection),
* then project:
* Select [projection] FROM (Select Distinct * From ...)
*
*
* @author Claus Stadler <cstadler@informatik.uni-leipzig.de>
*
*/
public class SqlOpSelectBlockCollectorOps {
public static SqlOpSelectBlock _makeSelect(SqlOp sqlOp) {
SqlOpSelectBlock result = MultiMethod.invokeStatic(SqlOpSelectBlockCollectorOps.class, "makeSelect", sqlOp);
return result;
}
/*
public static SqlOpSelectBlock makeSelect(SqlGroup sqlOp) {
SqlOpSelectBlock result;
if(sqlOp.getSubOp() instanceof SqlOpSlice) {
SqlOpSelectBlock tmp = _makeSelect(sqlOp.getSubOp());
result = new SqlOpSelectBlock(tmp.getAliasName(), tmp);
copyProjection(result, result);
}
else {
result = _makeSelect(sqlOp.getSubOp());
}
System.err.println("TODO Handle group by vars if present");
return result;
}
*/
public static SqlOpSelectBlock makeSelect(SqlOpTable sqlOp) {
return new SqlOpSelectBlock(sqlOp);
}
public static SqlOpSelectBlock makeSelect(SqlOpQuery sqlOp) {
return new SqlOpSelectBlock(sqlOp);
}
public static SqlOpSelectBlock makeSelect(SqlOpFilter sqlOp) {
SqlOpSelectBlock result = _makeSelect(sqlOp.getSubOp());
result.getConditions().addAll(sqlOp.getExprs());
return result;
}
public static SqlOpSelectBlock makeSelect(SqlOpSlice sqlOp) {
SqlOpSelectBlock result = _makeSelect(sqlOp.getSubOp());
SqlOpSelectBlock.slice(result, sqlOp.getOffset(), sqlOp.getLimit());
return result;
}
public static SqlOpSelectBlock makeSelect(SqlOpDistinct sqlOp) {
SqlOpSelectBlock result = _makeSelect(sqlOp.getSubOp());
result.setDistinct(true);
return result;
}
/*
public static SqlOpSelectBlock makeSelect(SqlAlias sqlOp) {
if(true) {
SqlOpSelectBlock result = _makeSelect(sqlOp.getSubOp());
//result.setAliasName(sqlOp.getAliasName());
SqlOpSelectBlock wrap = new SqlOpSelectBlock(sqlOp.getAliasName(), result);
copyProjection(wrap, result);
return wrap;
/*
copyProjection(result, sqlOp);
result.setAliasName(sqlOp.getAliasName());
return result;
* /
}
//throw new RuntimeException("Should not come here");
SqlOp result = _makeSelectOrTable(sqlOp.getSubOp());
SqlOpSelectBlock wrap = new SqlOpSelectBlock(sqlOp.getAliasName(), result);
copyProjection(wrap, result);
return wrap;
/*
wrap.getSparqlVarToExprs().putAll(sqlOp.getSparqlVarToExprs());
wrap.getAliasToColumn().putAll(sqlOp.getAliasToColumn());
result.setAliasName(sqlOp.getAliasName());
return result;
* /
}
*/
/*
public static SqlOpSelectBlock makeSelect(SqlOpOrder sqlOp) {
SqlOpSelectBlock result = _makeSelect(sqlOp.getSubOp());
result.getSortConditions().addAll(sqlOp.getConditions());
copyProjection(result, sqlOp);
return result;
}
*/
public static SqlOpSelectBlock makeSelect(SqlOpProject sqlOp) {
SqlOpSelectBlock result = _makeSelect(sqlOp.getSubOp());
return result;
// If the sqlOp is distinct, or if it already has a projection set,
// we must create a subselect
/*
if(result.isDistinct()) { // || result.isResultStar()
//SqlOpSelectBlock wrapped = new
}
*/
/*
SqlOpSelectBlock wrap = new SqlOpSelectBlock(sqlOp.getAliasName(), result);
wrap.getSparqlVarToExprs().putAll(sqlOp.getSparqlVarToExprs());
wrap.getAliasToColumn().putAll(sqlOp.getAliasToColumn());
return wrap;
*/
}
public static SqlOpSelectBlock makeSelect(SqlOpJoin sqlOp) {
SqlOp join = makeSelectOrTable(sqlOp);
return new SqlOpSelectBlock(join);
}
public static SqlOpSelectBlock makeSelect(SqlOpUnionN sqlOp) {
// Wrap all elements of the union
List<SqlOp> wrapped = new ArrayList<SqlOp>();
for(SqlOp arg : sqlOp.getSubOps()) {
SqlOpSelectBlock argSelect = _makeSelect(arg);
/*
argSelect.getSparqlVarToExprs().clear();
argSelect.getAliasToColumn().clear();
argSelect.getSparqlVarToExprs().putAll(arg.getSparqlVarToExprs());
argSelect.getAliasToColumn().putAll(arg.getAliasToColumn());
*/
wrapped.add(argSelect);
}
SqlOpUnionN union = SqlOpUnionN.create(wrapped); //, sqlOp.getAliasName());
SqlOpSelectBlock result = new SqlOpSelectBlock(union);
//copyProjection(result, union);
return result;
}
public static SqlOp _makeSelectOrTable(SqlOp sqlOp) {
return MultiMethod.invokeStatic(SqlOpSelectBlockCollectorImpl.class, "makeSelectOrTable", sqlOp);
}
public static SqlOp makeSelectOrTable(SqlOpEmpty sqlOp) {
// Should never come here
return sqlOp;
}
public static SqlOp makeSelectOrTable(SqlOpProject sqlOp) {
return _makeSelect(sqlOp);
}
public static SqlOp makeSelectOrTable(SqlOpTable sqlOp) {
return sqlOp;
}
public static SqlOp makeSelectOrTable(SqlOpQuery sqlOp) {
return sqlOp;
}
/*
public static SqlOp makeSelectOrTable(SqlAlias sqlOp) {
SqlOp tmp = _makeSelectOrTable(sqlOp.getSubOp());
SqlAlias result = new SqlAlias(sqlOp.getAliasName(), tmp);
copyProjection(result, sqlOp);
return result;
}
*/
public static SqlOp makeSelectOrTable(SqlOpFilter sqlOp) {
return _makeSelect(sqlOp);
}
public static SqlOp makeSelectOrTable(SqlOpSlice sqlOp) {
return _makeSelect(sqlOp);
}
public static SqlOp makeSelectOrTable(SqlOpDistinct sqlOp) {
return _makeSelect(sqlOp);
}
public static SqlOp makeSelectOrTable(SqlOpJoin sqlOp) {
SqlOp left = _makeSelectOrTable(sqlOp.getLeft());
SqlOp right = _makeSelectOrTable(sqlOp.getRight());
SqlOpJoin join = SqlOpJoin.create(sqlOp.getJoinType(), left, right);
join.getConditions().addAll(sqlOp.getConditions());
//copyProjection(join, sqlOp);
return join;
}
public static SqlOp makeSelectOrTable(SqlOpUnionN sqlOp) {
return makeSelect(sqlOp);
}
}