use of com.actiontech.dble.plan.common.item.Item in project dble by actiontech.
the class SelectedProcessor method mergePushSelected.
// union's push is different , when toPushColumn.isEmpty, merge's select can't be change
private static PlanNode mergePushSelected(MergeNode merge, Collection<Item> toPushColumns) {
if (toPushColumns.isEmpty() && merge.getOrderBys().isEmpty()) {
for (PlanNode child : merge.getChildren()) {
pushSelected(child, new HashSet<Item>());
}
return merge;
}
boolean canOverload = mergeNodeChildsCheck(merge) && !toPushColumns.isEmpty();
final Map<String, Integer> colIndexs = merge.getColIndexs();
List<Item> mergeSelects = null;
if (toPushColumns.isEmpty()) {
// merge's select can't be change
mergeSelects = new ArrayList<>();
merge.setComeInFields(mergeSelects);
mergeSelects.addAll(merge.getColumnsSelected());
} else {
mergeSelects = merge.getColumnsSelected();
}
if (canOverload) {
mergeSelects.clear();
mergeSelects.addAll(toPushColumns);
} else {
for (Item toPush : toPushColumns) {
if (!mergeSelects.contains(toPush)) {
mergeSelects.add(toPush);
}
}
}
// add order by
for (Order orderby : merge.getOrderBys()) {
Item orderSel = orderby.getItem();
mergePushOrderBy(orderSel, mergeSelects);
}
// push down the merge's select
List<List<Item>> allChildPushs = new ArrayList<>(toPushColumns.size());
for (Item toPush : mergeSelects) {
// union's order by must be found in selects
if (toPush.getPushDownName() == null && !toPush.type().equals(Item.ItemType.FIELD_ITEM))
toPush.setPushDownName(toPush.getItemName());
List<Item> childPushs = PlanUtil.getPushItemsToUnionChild(merge, toPush, colIndexs);
allChildPushs.add(childPushs);
}
// make all child's count of pushing down is equal
for (int index = 0; index < merge.getChildren().size(); index++) {
List<Item> colSels = merge.getChildren().get(index).getColumnsSelected();
colSels.clear();
for (List<Item> childPushs : allChildPushs) {
colSels.add(childPushs.get(index));
}
pushSelected(merge.getChildren().get(index), new HashSet<Item>());
}
return merge;
}
use of com.actiontech.dble.plan.common.item.Item in project dble by actiontech.
the class SubQueryPreProcessor method findComparisonsSubQueryToJoinNode.
/**
* http://dev.mysql.com/doc/refman/5.0/en/comparisons-using-subqueries.html
*/
private static PlanNode findComparisonsSubQueryToJoinNode(PlanNode qtn, BoolPtr childTransform) {
for (int i = 0; i < qtn.getChildren().size(); i++) {
PlanNode child = qtn.getChildren().get(i);
qtn.getChildren().set(i, findComparisonsSubQueryToJoinNode(child, childTransform));
}
for (Item itemSelect : qtn.getColumnsSelected()) {
if (itemSelect instanceof ItemScalarSubQuery) {
ItemScalarSubQuery scalarSubQuery = (ItemScalarSubQuery) itemSelect;
findComparisonsSubQueryToJoinNode(scalarSubQuery.getPlanNode(), childTransform);
}
}
// having contains sub query
buildSubQuery(qtn, new SubQueryFilter(), qtn.getHavingFilter(), false, childTransform);
SubQueryFilter find = new SubQueryFilter();
find.query = qtn;
find.filter = null;
Item where = qtn.getWhereFilter();
SubQueryFilter result = buildSubQuery(qtn, find, where, false, childTransform);
if (result != find) {
// that means where filter only contains sub query,just replace it
result.query.query(result.filter);
qtn.query(null);
// change result.filter and rebuild
result.query.setUpFields();
childTransform.set(true);
return result.query;
} else {
if (childTransform.get()) {
qtn.setUpFields();
}
return qtn;
}
}
use of com.actiontech.dble.plan.common.item.Item in project dble by actiontech.
the class SubQueryProcessor method mergeWhere.
// fixme: parent's alias set to where item's table
private static void mergeWhere(PlanNode parent, PlanNode child) {
Item pWhere = parent.getWhereFilter();
Item pWhere0 = PlanUtil.pushDownItem(parent, pWhere, true);
Item childWhere = PlanUtil.pushDownItem(child, child.getWhereFilter(), true);
Item mWhere = FilterUtils.and(pWhere0, childWhere);
child.setWhereFilter(mWhere);
}
use of com.actiontech.dble.plan.common.item.Item in project dble by actiontech.
the class FilterUtils method splitFilter.
/**
* split the filter until filter is 'boolean filer' or 'orfilter'
*
* @param filter
* @return
*/
public static List<Item> splitFilter(Item filter) {
if (filter == null)
throw new RuntimeException("check filter before split");
List<Item> filterList = new ArrayList<>();
if (filter.type() == Item.ItemType.COND_ITEM) {
ItemCond cond = (ItemCond) filter;
if (cond.functype() == Functype.COND_AND_FUNC) {
for (int index = 0; index < cond.getArgCount(); index++) {
Item subFilter = cond.arguments().get(index);
if (subFilter == null)
continue;
List<Item> subSplits = splitFilter(subFilter);
filterList.addAll(subSplits);
}
} else if (cond.functype() == Functype.COND_OR_FUNC) {
// step1 divide the args into base part
Set<List<Item>> saveSet = new HashSet<List<Item>>();
for (int index = 0; index < cond.getArgCount(); index++) {
Item subFilter = cond.arguments().get(index);
if (subFilter == null)
continue;
List<Item> subSplits = splitFilter(subFilter);
saveSet.add(subSplits);
}
Map<String, List<Item>> itemMap = gourpByRefertTable(filter, saveSet);
for (Map.Entry<String, List<Item>> entry : itemMap.entrySet()) {
ItemCondOr x = new ItemCondOr(entry.getValue());
x.getReferTables().addAll(entry.getValue().get(0).getReferTables());
filterList.add(x);
}
filterList.add(cond);
} else {
filterList.add(cond);
}
} else {
filterList.add(filter);
}
return filterList;
}
use of com.actiontech.dble.plan.common.item.Item in project dble by actiontech.
the class MySQLPlanNodeVisitor method handleHavingCondition.
private void handleHavingCondition(SQLExpr havingExpr) {
MySQLItemVisitor mev = new MySQLItemVisitor(currentDb, this.charsetIndex, this.metaManager);
havingExpr.accept(mev);
Item havingFilter = mev.getItem();
if (this.tableNode == null) {
throw new IllegalArgumentException("from expression is null,check the sql!");
}
if (havingFilter.isWithSubQuery()) {
tableNode.setSubQuery(true);
tableNode.setCorrelatedSubQuery(havingFilter.isCorrelatedSubQuery());
}
this.tableNode = this.tableNode.having(havingFilter);
}
Aggregations