use of com.actiontech.dble.plan.common.item.function.operator.cmpfunc.ItemFuncEqual in project dble by actiontech.
the class OrderByPusher method getJoinColumnOrders.
/**
* generatejoinOnFilters,if joinOn's orderBy can change to match implicitOrders ,return true
*
* @param joinOnFilters in
* @param leftOnOrders out
* @param rightOnOrders out
* @param implicitOrders in
* @return
*/
private static boolean getJoinColumnOrders(List<ItemFuncEqual> joinOnFilters, List<Order> leftOnOrders, List<Order> rightOnOrders, List<Order> implicitOrders) {
List<Item> leftOnSels = new ArrayList<>();
List<Item> rightOnSels = new ArrayList<>();
for (ItemFuncEqual bf : joinOnFilters) {
leftOnSels.add(bf.arguments().get(0));
rightOnSels.add(bf.arguments().get(1));
}
// is on's orderBy can be changed to match implicitOrders
boolean canMatch = false;
if (implicitOrders.size() < leftOnSels.size())
canMatch = false;
else {
Map<Integer, SQLOrderingSpecification> foundOnIndexs = new LinkedHashMap<>();
for (Order orderby : implicitOrders) {
Item orderSel = orderby.getItem();
int index = -1;
if ((index = leftOnSels.indexOf(orderSel)) >= 0) {
foundOnIndexs.put(index, orderby.getSortOrder());
} else if ((index = rightOnSels.indexOf(orderSel)) >= 0) {
foundOnIndexs.put(index, orderby.getSortOrder());
} else {
// neither belong to leftOn nor belong to rightOn
break;
}
}
if (foundOnIndexs.size() == leftOnSels.size()) {
canMatch = true;
for (Map.Entry<Integer, SQLOrderingSpecification> entry : foundOnIndexs.entrySet()) {
int foundOnIndex = entry.getKey();
SQLOrderingSpecification sortOrder = entry.getValue();
Item leftOn = leftOnSels.get(foundOnIndex);
Item rightOn = rightOnSels.get(foundOnIndex);
// add lefton order
Order leftOnOrder = new Order(leftOn, sortOrder);
leftOnOrders.add(leftOnOrder);
// add righton order
Order rightOnOrder = new Order(rightOn, sortOrder);
rightOnOrders.add(rightOnOrder);
}
return canMatch;
}
}
// can not match
for (int index = 0; index < leftOnSels.size(); index++) {
SQLOrderingSpecification sortOrder = SQLOrderingSpecification.ASC;
Item leftOn = leftOnSels.get(index);
Item rightOn = rightOnSels.get(index);
// add lefton order
Order leftOnOrder = new Order(leftOn, sortOrder);
leftOnOrders.add(leftOnOrder);
// add righton order
Order rightOnOrder = new Order(rightOn, sortOrder);
rightOnOrders.add(rightOnOrder);
}
return canMatch;
}
use of com.actiontech.dble.plan.common.item.function.operator.cmpfunc.ItemFuncEqual in project dble by actiontech.
the class SubQueryPreProcessor method transformInSubQuery.
private static SubQueryFilter transformInSubQuery(SubQueryFilter qtn, ItemInSubQuery filter, BoolPtr childTransform) {
Item leftColumn = filter.getLeftOperand();
PlanNode query = filter.getPlanNode();
query = findComparisonsSubQueryToJoinNode(query, childTransform);
QueryNode changeQuery = new QueryNode(query);
String alias = AUTOALIAS + query.getPureName();
changeQuery.setAlias(alias);
if (query.getColumnsSelected().size() != 1)
throw new MySQLOutPutException(ErrorCode.ER_OPTIMIZER, "", "only support subquery of one column");
query.setSubQuery(true).setDistinct(true);
final List<Item> newSelects = qtn.query.getColumnsSelected();
SubQueryFilter result = new SubQueryFilter();
Item rightColumn = query.getColumnsSelected().get(0);
qtn.query.setColumnsSelected(new ArrayList<Item>());
String rightJoinName = rightColumn.getAlias();
if (StringUtils.isEmpty(rightJoinName)) {
if (rightColumn instanceof ItemField) {
rightJoinName = rightColumn.getItemName();
} else {
rightColumn.setAlias(AUTONAME);
rightJoinName = AUTONAME;
}
}
ItemField rightJoinColumn = new ItemField(null, alias, rightJoinName);
// rename the left column's table name
result.query = new JoinNode(qtn.query, changeQuery);
// leave origin sql to new join node
result.query.setSql(qtn.query.getSql());
qtn.query.setSql(null);
result.query.select(newSelects);
qtn.query.setSubQuery(false);
if (!qtn.query.getOrderBys().isEmpty()) {
List<Order> orderBys = new ArrayList<>();
orderBys.addAll(qtn.query.getOrderBys());
result.query.setOrderBys(orderBys);
qtn.query.getOrderBys().clear();
}
if (!qtn.query.getGroupBys().isEmpty()) {
List<Order> groupBys = new ArrayList<>();
groupBys.addAll(qtn.query.getGroupBys());
result.query.setGroupBys(groupBys);
qtn.query.getGroupBys().clear();
result.query.having(qtn.query.getHavingFilter());
qtn.query.having(null);
}
if (qtn.query.getLimitFrom() != -1) {
result.query.setLimitFrom(qtn.query.getLimitFrom());
qtn.query.setLimitFrom(-1);
}
if (qtn.query.getLimitTo() != -1) {
result.query.setLimitTo(qtn.query.getLimitTo());
qtn.query.setLimitTo(-1);
}
if (filter.isNeg()) {
((JoinNode) result.query).setLeftOuterJoin().setNotIn(true);
ItemFuncEqual joinFilter = FilterUtils.equal(leftColumn, rightJoinColumn);
((JoinNode) result.query).addJoinFilter(joinFilter);
result.filter = null;
} else {
Item joinFilter = FilterUtils.equal(leftColumn, rightJoinColumn);
result.query.query(joinFilter);
result.filter = joinFilter;
}
result.query.setUpFields();
return result;
}
use of com.actiontech.dble.plan.common.item.function.operator.cmpfunc.ItemFuncEqual in project dble by actiontech.
the class ERJoinChooser method joinWithGlobal.
private PlanNode joinWithGlobal(PlanNode t, List<PlanNode> globalList) {
PlanNode newT = t;
while (globalList.size() > 0) {
boolean foundJoin = false;
for (int i = 0; i < globalList.size(); i++) {
PlanNode global = globalList.get(i);
// try join
JoinNode joinNode = new JoinNode(newT, global);
List<ItemFuncEqual> jnFilter = makeJoinFilter(joinNode, newT, global, false);
// @if no join column, then the other is cross join
if (jnFilter.size() > 0 || selLists.size() == 0) {
// join
replaceSelListReferedTn(newT, global, joinNode);
foundJoin = true;
joinNode.setJoinFilter(jnFilter);
globalList.remove(i);
newT = joinNode;
break;
}
}
if (// no join can do from t and globals
!foundJoin)
break;
}
return newT;
}
use of com.actiontech.dble.plan.common.item.function.operator.cmpfunc.ItemFuncEqual in project dble by actiontech.
the class ERJoinChooser method makeJoinFilter.
/**
* join t0 and t1, find relation in selLists and make joinfilter
* [if a.id=b.id and a.id = b.name would not appear]
*
* @param join
* @param t0
* @param t1
* @param replaceSelList
* @return
*/
private List<ItemFuncEqual> makeJoinFilter(JoinNode join, PlanNode t0, PlanNode t1, boolean replaceSelList) {
List<ItemFuncEqual> filters = new ArrayList<>();
for (List<JoinKeyInfo> selList : selLists) {
JoinKeyInfo jkit0 = null;
JoinKeyInfo jkit1 = null;
for (JoinKeyInfo jki : selList) {
if (jki.tn == t0) {
jkit0 = jki;
} else if (jki.tn == t1) {
jkit1 = jki;
}
}
// t0and t1 in sel list can make jkit0 jkit1 join
if (jkit0 != null && jkit1 != null) {
JoinKeyInfo newJki = new JoinKeyInfo(jkit0.key);
newJki.tn = join;
if (jkit0.cm != null && jkit1.cm != null && isErRelation(jkit0.cm, jkit1.cm)) {
newJki.cm = jkit0.cm;
join.getERkeys().add(newJki.cm);
}
ItemFuncEqual bf = FilterUtils.equal(jkit0.key, jkit1.key);
filters.add(bf);
selList.remove(jkit0);
selList.remove(jkit1);
selList.add(newJki);
}
}
if (replaceSelList)
replaceSelListReferedTn(t0, t1, join);
return filters;
}
use of com.actiontech.dble.plan.common.item.function.operator.cmpfunc.ItemFuncEqual in project dble by actiontech.
the class ERJoinChooser method makeERJoin.
// generate er join node ,remove jk of rKeyIndexs in selListIndex,replace the other selList's tn
private JoinNode makeERJoin(List<JoinKeyInfo> erKeys) {
PlanNode t0 = erKeys.get(0).tn;
PlanNode t1 = erKeys.get(1).tn;
JoinNode joinNode = new JoinNode(t0, t1);
List<ItemFuncEqual> joinFilter = makeJoinFilter(joinNode, t0, t1, true);
joinNode.setJoinFilter(joinFilter);
for (int index = 2; index < erKeys.size(); index++) {
t0 = joinNode;
t1 = erKeys.get(index).tn;
joinNode = new JoinNode(t0, t1);
joinFilter = makeJoinFilter(joinNode, t0, t1, true);
joinNode.setJoinFilter(joinFilter);
}
for (JoinKeyInfo jki : erKeys) {
// remove join units
for (int index = joinUnits.size() - 1; index > -1; index--) {
PlanNode tn = joinUnits.get(index);
if (tn == jki.tn)
joinUnits.remove(index);
}
}
return joinNode;
}
Aggregations